sunxi: deprecate 3.12 support

Signed-off-by: Zoltan HERPAI <wigyori@uid0.hu>

SVN-Revision: 39780
This commit is contained in:
Zoltan Herpai 2014-03-05 23:19:25 +00:00
parent 6892ed8193
commit 301baf34dd
74 changed files with 0 additions and 7888 deletions

View file

@ -1,411 +0,0 @@
# CONFIG_AHCI_SUNXI is not set
CONFIG_ALIGNMENT_TRAP=y
# CONFIG_APM_EMULATION is not set
CONFIG_ARCH_BINFMT_ELF_RANDOMIZE_PIE=y
CONFIG_ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE=y
CONFIG_ARCH_HAS_RESET_CONTROLLER=y
CONFIG_ARCH_HAS_TICK_BROADCAST=y
CONFIG_ARCH_HAVE_CUSTOM_GPIO_H=y
CONFIG_ARCH_MULTIPLATFORM=y
# CONFIG_ARCH_MULTI_CPU_AUTO is not set
CONFIG_ARCH_MULTI_V6_V7=y
CONFIG_ARCH_MULTI_V7=y
# CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED is not set
CONFIG_ARCH_NR_GPIO=288
CONFIG_ARCH_REQUIRE_GPIOLIB=y
# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
CONFIG_ARCH_SUNXI=y
CONFIG_ARCH_SUSPEND_POSSIBLE=y
CONFIG_ARCH_WANT_GENERAL_HUGETLB=y
CONFIG_ARCH_WANT_IPC_PARSE_VERSION=y
CONFIG_ARM=y
CONFIG_ARM_APPENDED_DTB=y
CONFIG_ARM_ATAG_DTB_COMPAT=y
# CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_EXTEND is not set
CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_FROM_BOOTLOADER=y
# CONFIG_ARM_CPU_SUSPEND is not set
CONFIG_ARM_ERRATA_430973=y
CONFIG_ARM_ERRATA_720789=y
CONFIG_ARM_ERRATA_754322=y
CONFIG_ARM_ERRATA_775420=y
CONFIG_ARM_GIC=y
CONFIG_ARM_L1_CACHE_SHIFT=6
CONFIG_ARM_L1_CACHE_SHIFT_6=y
# CONFIG_ARM_LPAE is not set
CONFIG_ARM_NR_BANKS=8
CONFIG_ARM_PATCH_PHYS_VIRT=y
CONFIG_ARM_THUMB=y
# CONFIG_ARM_THUMBEE is not set
CONFIG_ARM_VIRT_EXT=y
CONFIG_ATA=y
CONFIG_ATAGS=y
CONFIG_AUDIT=y
# CONFIG_AUDITSYSCALL is not set
CONFIG_AUDIT_GENERIC=y
CONFIG_AUTO_ZRELADDR=y
CONFIG_AVERAGE=y
CONFIG_BINFMT_MISC=y
CONFIG_BLK_CGROUP=y
CONFIG_BLK_DEV_SD=y
CONFIG_BLK_DEV_SR=y
CONFIG_BLK_DEV_SR_VENDOR=y
CONFIG_BOUNCE=y
CONFIG_BRIDGE_IGMP_SNOOPING=y
# CONFIG_CACHE_L2X0 is not set
CONFIG_CFQ_GROUP_IOSCHED=y
CONFIG_CGROUPS=y
CONFIG_CGROUP_CPUACCT=y
CONFIG_CGROUP_DEVICE=y
CONFIG_CGROUP_FREEZER=y
# CONFIG_CGROUP_PERF is not set
# CONFIG_CGROUP_SCHED is not set
# CONFIG_CHARGER_BQ24190 is not set
# CONFIG_CHARGER_MANAGER is not set
CONFIG_CLKDEV_LOOKUP=y
CONFIG_CLKSRC_MMIO=y
CONFIG_CLKSRC_OF=y
CONFIG_CLONE_BACKWARDS=y
CONFIG_CMDLINE="console=ttyS0,115200 earlyprintk rootwait root=/dev/mmcblk0p2"
# CONFIG_CMDLINE_FORCE is not set
CONFIG_COMMON_CLK=y
CONFIG_COMPACTION=y
CONFIG_CONFIGFS_FS=y
CONFIG_CONNECTOR=y
CONFIG_CONSOLE_TRANSLATIONS=y
CONFIG_COREDUMP=y
CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS=y
CONFIG_CPUSETS=y
CONFIG_CPU_32v6K=y
CONFIG_CPU_32v7=y
CONFIG_CPU_ABRT_EV7=y
# CONFIG_CPU_BPREDICT_DISABLE is not set
CONFIG_CPU_CACHE_V7=y
CONFIG_CPU_CACHE_VIPT=y
CONFIG_CPU_COPY_V6=y
CONFIG_CPU_CP15=y
CONFIG_CPU_CP15_MMU=y
CONFIG_CPU_HAS_ASID=y
# CONFIG_CPU_ICACHE_DISABLE is not set
CONFIG_CPU_PABRT_V7=y
CONFIG_CPU_RMAP=y
CONFIG_CPU_TLB_V7=y
CONFIG_CPU_V7=y
CONFIG_CRC_T10DIF=y
CONFIG_CRYPTO_ARC4=y
CONFIG_CRYPTO_BLKCIPHER=y
CONFIG_CRYPTO_BLKCIPHER2=y
CONFIG_CRYPTO_CRCT10DIF=y
CONFIG_CRYPTO_HASH=y
CONFIG_CRYPTO_HASH2=y
CONFIG_CRYPTO_RNG2=y
CONFIG_CRYPTO_WORKQUEUE=y
CONFIG_DCACHE_WORD_ACCESS=y
# CONFIG_DEBUG_BLK_CGROUP is not set
CONFIG_DEBUG_BUGVERBOSE=y
# CONFIG_DEBUG_KERNEL is not set
CONFIG_DEBUG_LL_INCLUDE="mach/debug-macro.S"
CONFIG_DEBUG_MEMORY_INIT=y
# CONFIG_DEBUG_UART_8250 is not set
# CONFIG_DEBUG_UART_PL01X is not set
# CONFIG_DEBUG_USER is not set
CONFIG_DECOMPRESS_BZIP2=y
CONFIG_DECOMPRESS_GZIP=y
CONFIG_DECOMPRESS_LZ4=y
CONFIG_DECOMPRESS_LZMA=y
CONFIG_DECOMPRESS_LZO=y
CONFIG_DECOMPRESS_XZ=y
CONFIG_DEFAULT_CFQ=y
# CONFIG_DEFAULT_DEADLINE is not set
CONFIG_DEFAULT_IOSCHED="cfq"
CONFIG_DIRECT_IO=y
CONFIG_DMADEVICES=y
CONFIG_DMA_OF=y
CONFIG_DNOTIFY=y
CONFIG_DTC=y
CONFIG_DUMMY_CONSOLE=y
# CONFIG_DW_DMAC_CORE is not set
CONFIG_DYNAMIC_DEBUG=y
# CONFIG_EEPROM_SUNXI_SID is not set
CONFIG_ELF_CORE=y
# CONFIG_EMBEDDED is not set
CONFIG_ENABLE_MUST_CHECK=y
# CONFIG_ENABLE_WARN_DEPRECATED is not set
# CONFIG_EXPERT is not set
CONFIG_EXT4_FS=y
CONFIG_FRAME_POINTER=y
CONFIG_FRAME_WARN=2048
CONFIG_FREEZER=y
CONFIG_FS_POSIX_ACL=y
CONFIG_GARP=y
CONFIG_GENERIC_ACL=y
CONFIG_GENERIC_BUG=y
CONFIG_GENERIC_CLOCKEVENTS=y
CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y
CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
CONFIG_GENERIC_IDLE_POLL_SETUP=y
CONFIG_GENERIC_IO=y
CONFIG_GENERIC_IRQ_CHIP=y
CONFIG_GENERIC_IRQ_SHOW=y
CONFIG_GENERIC_NET_UTILS=y
CONFIG_GENERIC_PCI_IOMAP=y
CONFIG_GENERIC_PINCONF=y
CONFIG_GENERIC_SCHED_CLOCK=y
CONFIG_GENERIC_SMP_IDLE_THREAD=y
CONFIG_GENERIC_STRNCPY_FROM_USER=y
CONFIG_GENERIC_STRNLEN_USER=y
CONFIG_GPIOLIB=y
CONFIG_GPIO_DEVRES=y
# CONFIG_HAMRADIO is not set
CONFIG_HARDIRQS_SW_RESEND=y
CONFIG_HAS_DMA=y
CONFIG_HAS_IOMEM=y
CONFIG_HAS_IOPORT=y
# CONFIG_HAVE_64BIT_ALIGNED_ACCESS is not set
CONFIG_HAVE_ARCH_JUMP_LABEL=y
CONFIG_HAVE_ARCH_KGDB=y
CONFIG_HAVE_ARCH_PFN_VALID=y
CONFIG_HAVE_ARCH_SECCOMP_FILTER=y
CONFIG_HAVE_ARCH_TRACEHOOK=y
# CONFIG_HAVE_BOOTMEM_INFO_NODE is not set
CONFIG_HAVE_BPF_JIT=y
CONFIG_HAVE_CLK=y
CONFIG_HAVE_CLK_PREPARE=y
CONFIG_HAVE_CONTEXT_TRACKING=y
CONFIG_HAVE_C_RECORDMCOUNT=y
CONFIG_HAVE_DEBUG_KMEMLEAK=y
CONFIG_HAVE_DMA_API_DEBUG=y
CONFIG_HAVE_DMA_ATTRS=y
CONFIG_HAVE_DMA_CONTIGUOUS=y
CONFIG_HAVE_DYNAMIC_FTRACE=y
CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
CONFIG_HAVE_FUNCTION_TRACER=y
CONFIG_HAVE_GENERIC_DMA_COHERENT=y
CONFIG_HAVE_HW_BREAKPOINT=y
CONFIG_HAVE_IRQ_TIME_ACCOUNTING=y
CONFIG_HAVE_KERNEL_GZIP=y
CONFIG_HAVE_KERNEL_LZ4=y
CONFIG_HAVE_KERNEL_LZMA=y
CONFIG_HAVE_KERNEL_LZO=y
CONFIG_HAVE_KERNEL_XZ=y
CONFIG_HAVE_MEMBLOCK=y
CONFIG_HAVE_NET_DSA=y
CONFIG_HAVE_OPROFILE=y
CONFIG_HAVE_PERF_EVENTS=y
CONFIG_HAVE_PROC_CPU=y
CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y
CONFIG_HAVE_SMP=y
CONFIG_HAVE_SYSCALL_TRACEPOINTS=y
CONFIG_HAVE_UID16=y
CONFIG_HIGHMEM=y
# CONFIG_HIGHPTE is not set
CONFIG_HW_CONSOLE=y
CONFIG_HZ_FIXED=0
CONFIG_I2C=y
CONFIG_I2C_BOARDINFO=y
CONFIG_I2C_MUX=y
# CONFIG_I2C_MUX_GPIO is not set
# CONFIG_I2C_MUX_PCA9541 is not set
# CONFIG_I2C_MUX_PCA954x is not set
CONFIG_I2C_MUX_PINCTRL=y
CONFIG_I2C_MV64XXX=y
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
CONFIG_INITRAMFS_SOURCE=""
CONFIG_INPUT=y
# CONFIG_INPUT_MISC is not set
CONFIG_INPUT_MOUSEDEV=y
CONFIG_INPUT_MOUSEDEV_PSAUX=y
CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
CONFIG_IOSCHED_CFQ=y
CONFIG_IPC_NS=y
# CONFIG_IP_ADVANCED_ROUTER is not set
CONFIG_IP_PNP=y
# CONFIG_IP_PNP_BOOTP is not set
CONFIG_IP_PNP_DHCP=y
# CONFIG_IP_PNP_RARP is not set
CONFIG_IRQCHIP=y
CONFIG_IRQ_DOMAIN=y
CONFIG_IRQ_FORCED_THREADING=y
CONFIG_IRQ_WORK=y
CONFIG_KALLSYMS=y
CONFIG_KERNEL_GZIP=y
# CONFIG_KERNEL_XZ is not set
CONFIG_KSM=y
CONFIG_KTIME_SCALAR=y
CONFIG_LEDS_GPIO=y
# CONFIG_LEDS_REGULATOR is not set
CONFIG_LEGACY_PTYS=y
CONFIG_LEGACY_PTY_COUNT=256
CONFIG_LOG_BUF_SHIFT=19
CONFIG_LZ4_DECOMPRESS=y
CONFIG_LZO_DECOMPRESS=y
CONFIG_MAGIC_SYSRQ=y
CONFIG_MDIO_BOARDINFO=y
CONFIG_MDIO_SUN4I=y
# CONFIG_MEMCG is not set
CONFIG_MIGRATION=y
CONFIG_MMC=y
CONFIG_MMC_BLOCK=y
# CONFIG_MMC_BLOCK_BOUNCE is not set
CONFIG_MMC_SUNXI=y
CONFIG_MMC_UNSAFE_RESUME=y
CONFIG_MODULES_USE_ELF_REL=y
# CONFIG_MTD is not set
CONFIG_MULTI_IRQ_HANDLER=y
CONFIG_MUTEX_SPIN_ON_OWNER=y
# CONFIG_MWIFIEX is not set
CONFIG_NAMESPACES=y
CONFIG_NEED_DMA_MAP_STATE=y
# CONFIG_NEON is not set
# CONFIG_NETPRIO_CGROUP is not set
# CONFIG_NET_CLS_CGROUP is not set
CONFIG_NET_FLOW_LIMIT=y
CONFIG_NET_NS=y
CONFIG_NET_RX_BUSY_POLL=y
CONFIG_NET_VENDOR_ALLWINNER=y
# CONFIG_NL80211_TESTMODE is not set
CONFIG_NLS=y
CONFIG_NO_HZ=y
CONFIG_NO_HZ_COMMON=y
CONFIG_NO_HZ_IDLE=y
CONFIG_NR_CPUS=4
CONFIG_OF=y
CONFIG_OF_ADDRESS=y
CONFIG_OF_EARLY_FLATTREE=y
CONFIG_OF_FLATTREE=y
CONFIG_OF_GPIO=y
CONFIG_OF_IRQ=y
CONFIG_OF_MDIO=y
CONFIG_OF_NET=y
CONFIG_OLD_SIGACTION=y
CONFIG_OLD_SIGSUSPEND3=y
CONFIG_PAGEFLAGS_EXTENDED=y
CONFIG_PAGE_OFFSET=0xC0000000
# CONFIG_PARTITION_ADVANCED is not set
# CONFIG_PCI_SYSCALL is not set
CONFIG_PERF_EVENTS=y
CONFIG_PERF_USE_VMALLOC=y
CONFIG_PHYLIB=y
CONFIG_PID_NS=y
CONFIG_PINCTRL=y
# CONFIG_PINCTRL_SINGLE is not set
CONFIG_PINCTRL_SUNXI=y
CONFIG_PM=y
CONFIG_PM_CLK=y
# CONFIG_PM_DEBUG is not set
CONFIG_PM_RUNTIME=y
CONFIG_POWER_SUPPLY=y
CONFIG_PREEMPT=y
CONFIG_PREEMPT_COUNT=y
# CONFIG_PREEMPT_NONE is not set
CONFIG_PREEMPT_RCU=y
CONFIG_PRINTK_TIME=y
# CONFIG_PRINT_QUOTA_WARNING is not set
CONFIG_PROC_EVENTS=y
CONFIG_PROC_PAGE_MONITOR=y
CONFIG_PROC_PID_CPUSET=y
# CONFIG_QFMT_V1 is not set
# CONFIG_QFMT_V2 is not set
CONFIG_QUOTA=y
CONFIG_QUOTACTL=y
CONFIG_QUOTA_NETLINK_INTERFACE=y
# CONFIG_RCU_BOOST is not set
CONFIG_RCU_CPU_STALL_VERBOSE=y
CONFIG_RCU_STALL_COMMON=y
CONFIG_RD_BZIP2=y
CONFIG_RD_GZIP=y
CONFIG_RD_LZ4=y
CONFIG_RD_LZMA=y
CONFIG_RD_LZO=y
CONFIG_RD_XZ=y
CONFIG_REGULATOR=y
# CONFIG_REGULATOR_DEBUG is not set
# CONFIG_REGULATOR_DUMMY is not set
CONFIG_REGULATOR_FIXED_VOLTAGE=y
# CONFIG_REGULATOR_USERSPACE_CONSUMER is not set
CONFIG_RELAY=y
CONFIG_RESET_CONTROLLER=y
CONFIG_RESOURCE_COUNTERS=y
# CONFIG_RFKILL_REGULATOR is not set
CONFIG_RFS_ACCEL=y
CONFIG_RPS=y
CONFIG_SATA_AHCI_PLATFORM=y
# CONFIG_SATA_RCAR is not set
CONFIG_SCHED_HRTICK=y
CONFIG_SCSI=y
CONFIG_SECURITYFS=y
CONFIG_SERIAL_8250_DW=y
CONFIG_SERIAL_8250_NR_UARTS=8
CONFIG_SERIAL_8250_RUNTIME_UARTS=8
CONFIG_SERIAL_8250_SYSRQ=y
CONFIG_SERIO=y
# CONFIG_SERIO_APBPS2 is not set
# CONFIG_SERIO_OLPC_APSP is not set
CONFIG_SERIO_SERPORT=y
# CONFIG_SLAB is not set
CONFIG_SLUB=y
CONFIG_SLUB_CPU_PARTIAL=y
CONFIG_SLUB_DEBUG=y
# CONFIG_SLUB_DEBUG_ON is not set
CONFIG_SMP=y
CONFIG_SMP_ON_UP=y
CONFIG_SPARSE_IRQ=y
# CONFIG_STAGING is not set
CONFIG_STOP_MACHINE=y
CONFIG_STRICT_DEVMEM=y
# CONFIG_SUN4I_EMAC is not set
CONFIG_SUN4I_TIMER=y
CONFIG_SUN5I_HSTIMER=y
# CONFIG_SUNXI_WATCHDOG is not set
CONFIG_SWP_EMULATE=y
CONFIG_SYS_SUPPORTS_APM_EMULATION=y
CONFIG_TASKSTATS=y
CONFIG_TASK_DELAY_ACCT=y
CONFIG_TASK_IO_ACCOUNTING=y
CONFIG_TASK_XACCT=y
# CONFIG_TCP_CONG_ADVANCED is not set
# CONFIG_THUMB2_KERNEL is not set
CONFIG_TICK_CPU_ACCOUNTING=y
CONFIG_TMPFS_POSIX_ACL=y
CONFIG_TREE_PREEMPT_RCU=y
CONFIG_UEVENT_HELPER_PATH=""
CONFIG_UID16=y
CONFIG_UNCOMPRESS_INCLUDE="debug/uncompress.h"
CONFIG_UNINLINE_SPIN_UNLOCK=y
CONFIG_USB=y
CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
CONFIG_USB_COMMON=y
CONFIG_USB_DEBUG=y
CONFIG_USB_EHCI_HCD=y
# CONFIG_USB_EHCI_HCD_PLATFORM is not set
CONFIG_USB_STORAGE=y
CONFIG_USB_SUNXI_EHCI=y
CONFIG_USB_SUPPORT=y
# CONFIG_USER_NS is not set
CONFIG_USE_GENERIC_SMP_HELPERS=y
CONFIG_USE_OF=y
CONFIG_UTS_NS=y
CONFIG_VECTORS_BASE=0xffff0000
CONFIG_VFP=y
CONFIG_VFPv3=y
CONFIG_VLAN_8021Q_GVRP=y
CONFIG_VM_EVENT_COUNTERS=y
CONFIG_VT=y
CONFIG_VT_CONSOLE=y
CONFIG_VT_HW_CONSOLE_BINDING=y
# CONFIG_WATCHDOG is not set
# CONFIG_XEN is not set
CONFIG_XFRM_ALGO=y
CONFIG_XFRM_USER=y
CONFIG_XPS=y
CONFIG_XZ_DEC_ARM=y
CONFIG_XZ_DEC_ARMTHUMB=y
CONFIG_XZ_DEC_BCJ=y
CONFIG_ZBOOT_ROM_BSS=0
CONFIG_ZBOOT_ROM_TEXT=0
# CONFIG_ZBUD is not set
CONFIG_ZLIB_INFLATE=y
CONFIG_ZONE_DMA_FLAG=0

View file

@ -1,220 +0,0 @@
From 337d479970b0c8493ee3e8b8d89fb80ee39333a6 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Emilio=20L=C3=B3pez?= <emilio@elopez.com.ar>
Date: Sun, 5 May 2013 21:26:23 -0300
Subject: [PATCH] clk: sunxi: register factors clocks behind composite
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
This commit reworks factors clock registration to be done behind a
composite clock. This allows us to additionally add a gate, mux or
divisors, as it will be needed by some future PLLs.
Signed-off-by: Emilio López <emilio@elopez.com.ar>
---
drivers/clk/sunxi/clk-factors.c | 63 +--------------------------------------
drivers/clk/sunxi/clk-factors.h | 16 +++++-----
drivers/clk/sunxi/clk-sunxi.c | 66 ++++++++++++++++++++++++++++++++++++++---
3 files changed, 72 insertions(+), 73 deletions(-)
diff --git a/drivers/clk/sunxi/clk-factors.c b/drivers/clk/sunxi/clk-factors.c
index 88523f9..6e3926c 100644
--- a/drivers/clk/sunxi/clk-factors.c
+++ b/drivers/clk/sunxi/clk-factors.c
@@ -30,14 +30,6 @@
* parent - fixed parent. No clk_set_parent support
*/
-struct clk_factors {
- struct clk_hw hw;
- void __iomem *reg;
- struct clk_factors_config *config;
- void (*get_factors) (u32 *rate, u32 parent, u8 *n, u8 *k, u8 *m, u8 *p);
- spinlock_t *lock;
-};
-
#define to_clk_factors(_hw) container_of(_hw, struct clk_factors, hw)
#define SETMASK(len, pos) (((-1U) >> (31-len)) << (pos))
@@ -120,61 +112,8 @@ static int clk_factors_set_rate(struct clk_hw *hw, unsigned long rate,
return 0;
}
-static const struct clk_ops clk_factors_ops = {
+const struct clk_ops clk_factors_ops = {
.recalc_rate = clk_factors_recalc_rate,
.round_rate = clk_factors_round_rate,
.set_rate = clk_factors_set_rate,
};
-
-/**
- * clk_register_factors - register a factors clock with
- * the clock framework
- * @dev: device registering this clock
- * @name: name of this clock
- * @parent_name: name of clock's parent
- * @flags: framework-specific flags
- * @reg: register address to adjust factors
- * @config: shift and width of factors n, k, m and p
- * @get_factors: function to calculate the factors for a given frequency
- * @lock: shared register lock for this clock
- */
-struct clk *clk_register_factors(struct device *dev, const char *name,
- const char *parent_name,
- unsigned long flags, void __iomem *reg,
- struct clk_factors_config *config,
- void (*get_factors)(u32 *rate, u32 parent,
- u8 *n, u8 *k, u8 *m, u8 *p),
- spinlock_t *lock)
-{
- struct clk_factors *factors;
- struct clk *clk;
- struct clk_init_data init;
-
- /* allocate the factors */
- factors = kzalloc(sizeof(struct clk_factors), GFP_KERNEL);
- if (!factors) {
- pr_err("%s: could not allocate factors clk\n", __func__);
- return ERR_PTR(-ENOMEM);
- }
-
- init.name = name;
- init.ops = &clk_factors_ops;
- init.flags = flags;
- init.parent_names = (parent_name ? &parent_name : NULL);
- init.num_parents = (parent_name ? 1 : 0);
-
- /* struct clk_factors assignments */
- factors->reg = reg;
- factors->config = config;
- factors->lock = lock;
- factors->hw.init = &init;
- factors->get_factors = get_factors;
-
- /* register the clock */
- clk = clk_register(dev, &factors->hw);
-
- if (IS_ERR(clk))
- kfree(factors);
-
- return clk;
-}
diff --git a/drivers/clk/sunxi/clk-factors.h b/drivers/clk/sunxi/clk-factors.h
index f49851c..02e1a43 100644
--- a/drivers/clk/sunxi/clk-factors.h
+++ b/drivers/clk/sunxi/clk-factors.h
@@ -17,11 +17,13 @@ struct clk_factors_config {
u8 pwidth;
};
-struct clk *clk_register_factors(struct device *dev, const char *name,
- const char *parent_name,
- unsigned long flags, void __iomem *reg,
- struct clk_factors_config *config,
- void (*get_factors) (u32 *rate, u32 parent_rate,
- u8 *n, u8 *k, u8 *m, u8 *p),
- spinlock_t *lock);
+struct clk_factors {
+ struct clk_hw hw;
+ void __iomem *reg;
+ struct clk_factors_config *config;
+ void (*get_factors) (u32 *rate, u32 parent, u8 *n, u8 *k, u8 *m, u8 *p);
+ spinlock_t *lock;
+};
+
+extern const struct clk_ops clk_factors_ops;
#endif
diff --git a/drivers/clk/sunxi/clk-sunxi.c b/drivers/clk/sunxi/clk-sunxi.c
index 34ee69f..6aed57f 100644
--- a/drivers/clk/sunxi/clk-sunxi.c
+++ b/drivers/clk/sunxi/clk-sunxi.c
@@ -256,7 +256,11 @@ static void sun4i_get_apb1_factors(u32 *freq, u32 parent_rate,
* sunxi_factors_clk_setup() - Setup function for factor clocks
*/
+#define SUNXI_FACTORS_MUX_MASK 0x3
+
struct factors_data {
+ int enable;
+ int mux;
struct clk_factors_config *table;
void (*getter) (u32 *rate, u32 parent_rate, u8 *n, u8 *k, u8 *m, u8 *p);
};
@@ -307,16 +311,70 @@ static void __init sunxi_factors_clk_setup(struct device_node *node,
struct factors_data *data)
{
struct clk *clk;
+ struct clk_factors *factors;
+ struct clk_gate *gate;
+ struct clk_mux *mux;
+ struct clk_hw *gate_hw = NULL;
+ struct clk_hw *mux_hw = NULL;
const char *clk_name = node->name;
- const char *parent;
+ const char *parents[5];
void *reg;
+ int i = 0;
reg = of_iomap(node, 0);
- parent = of_clk_get_parent_name(node, 0);
+ /* if we have a mux, we will have >1 parents */
+ while (i < 5 && (parents[i] = of_clk_get_parent_name(node, i)) != NULL)
+ i++;
+
+ factors = kzalloc(sizeof(struct clk_factors), GFP_KERNEL);
+ if (!factors)
+ return;
+
+ /* Add a gate if this factor clock can be gated */
+ if (data->enable) {
+ gate = kzalloc(sizeof(struct clk_gate), GFP_KERNEL);
+ if (!gate) {
+ kfree(factors);
+ return;
+ }
+
+ /* set up gate properties */
+ gate->reg = reg;
+ gate->bit_idx = data->enable;
+ gate->lock = &clk_lock;
+ gate_hw = &gate->hw;
+ }
- clk = clk_register_factors(NULL, clk_name, parent, 0, reg,
- data->table, data->getter, &clk_lock);
+ /* Add a mux if this factor clock can be muxed */
+ if (data->mux) {
+ mux = kzalloc(sizeof(struct clk_mux), GFP_KERNEL);
+ if (!mux) {
+ kfree(factors);
+ kfree(gate);
+ return;
+ }
+
+ /* set up gate properties */
+ mux->reg = reg;
+ mux->shift = data->mux;
+ mux->mask = SUNXI_FACTORS_MUX_MASK;
+ mux->lock = &clk_lock;
+ mux_hw = &mux->hw;
+ }
+
+ /* set up factors properties */
+ factors->reg = reg;
+ factors->config = data->table;
+ factors->get_factors = data->getter;
+ factors->lock = &clk_lock;
+
+ clk = clk_register_composite(NULL, clk_name,
+ parents, i,
+ mux_hw, &clk_mux_ops,
+ &factors->hw, &clk_factors_ops,
+ gate_hw, &clk_gate_ops,
+ i ? 0 : CLK_IS_ROOT);
if (!IS_ERR(clk)) {
of_clk_add_provider(node, of_clk_src_simple_get, clk);
--
1.8.4

View file

@ -1,33 +0,0 @@
From 04609953e11377c0705b0aba5c25ebdcbb9e4aa7 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Emilio=20L=C3=B3pez?= <emilio@elopez.com.ar>
Date: Thu, 5 Sep 2013 19:47:20 -0300
Subject: [PATCH] clk: sunxi: factors: fix off-by-one masks
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
The previous code would generate one bit too long masks, and was
needlessly complicated. This patch replaces it by simpler code that can
generate the masks correctly.
Signed-off-by: Emilio López <emilio@elopez.com.ar>
---
drivers/clk/sunxi/clk-factors.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/clk/sunxi/clk-factors.c b/drivers/clk/sunxi/clk-factors.c
index 88523f9..5687ac9 100644
--- a/drivers/clk/sunxi/clk-factors.c
+++ b/drivers/clk/sunxi/clk-factors.c
@@ -40,7 +40,7 @@ struct clk_factors {
#define to_clk_factors(_hw) container_of(_hw, struct clk_factors, hw)
-#define SETMASK(len, pos) (((-1U) >> (31-len)) << (pos))
+#define SETMASK(len, pos) (((1U << (len)) - 1) << (pos))
#define CLRMASK(len, pos) (~(SETMASK(len, pos)))
#define FACTOR_GET(bit, len, reg) (((reg) & SETMASK(len, bit)) >> (bit))
--
1.8.5.1

View file

@ -1,31 +0,0 @@
From 29aef2f23ca8c91bce0a356fd5f120404389125a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Emilio=20L=C3=B3pez?= <emilio@elopez.com.ar>
Date: Thu, 5 Sep 2013 19:50:46 -0300
Subject: [PATCH] clk: sunxi: factors: clear variables before using them
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Random bits may get into our factors if we don't clear n, k, m and p.
Signed-off-by: Emilio López <emilio@elopez.com.ar>
---
drivers/clk/sunxi/clk-factors.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/clk/sunxi/clk-factors.c b/drivers/clk/sunxi/clk-factors.c
index 5687ac9..f05207a 100644
--- a/drivers/clk/sunxi/clk-factors.c
+++ b/drivers/clk/sunxi/clk-factors.c
@@ -88,7 +88,7 @@ static long clk_factors_round_rate(struct clk_hw *hw, unsigned long rate,
static int clk_factors_set_rate(struct clk_hw *hw, unsigned long rate,
unsigned long parent_rate)
{
- u8 n, k, m, p;
+ u8 n = 0, k = 0, m = 0, p = 0;
u32 reg;
struct clk_factors *factors = to_clk_factors(hw);
struct clk_factors_config *config = factors->config;
--
1.8.5.1

View file

@ -1,51 +0,0 @@
From 68557a66b206de79a4556d393d51865407525d52 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Emilio=20L=C3=B3pez?= <emilio@elopez.com.ar>
Date: Mon, 6 May 2013 09:59:00 -0300
Subject: [PATCH] clk: sunxi: add gating support to PLL1
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
This commit adds gating support to PLL1 on the clock driver. This makes
the PLL1 implementation fully compatible with PLL4 as well.
Signed-off-by: Emilio López <emilio@elopez.com.ar>
---
Documentation/devicetree/bindings/clock/sunxi.txt | 2 +-
drivers/clk/sunxi/clk-sunxi.c | 2 ++
2 files changed, 3 insertions(+), 1 deletion(-)
diff --git a/Documentation/devicetree/bindings/clock/sunxi.txt b/Documentation/devicetree/bindings/clock/sunxi.txt
index 00a5c264..7d9245f 100644
--- a/Documentation/devicetree/bindings/clock/sunxi.txt
+++ b/Documentation/devicetree/bindings/clock/sunxi.txt
@@ -7,7 +7,7 @@ This binding uses the common clock binding[1].
Required properties:
- compatible : shall be one of the following:
"allwinner,sun4i-osc-clk" - for a gatable oscillator
- "allwinner,sun4i-pll1-clk" - for the main PLL clock
+ "allwinner,sun4i-pll1-clk" - for the main PLL clock and PLL4
"allwinner,sun6i-a31-pll1-clk" - for the main PLL clock on A31
"allwinner,sun4i-cpu-clk" - for the CPU multiplexer clock
"allwinner,sun4i-axi-clk" - for the AXI clock
diff --git a/drivers/clk/sunxi/clk-sunxi.c b/drivers/clk/sunxi/clk-sunxi.c
index 6aed57f..c0b0675 100644
--- a/drivers/clk/sunxi/clk-sunxi.c
+++ b/drivers/clk/sunxi/clk-sunxi.c
@@ -293,11 +293,13 @@ struct factors_data {
};
static const struct factors_data sun4i_pll1_data __initconst = {
+ .enable = 31,
.table = &sun4i_pll1_config,
.getter = sun4i_get_pll1_factors,
};
static const struct factors_data sun6i_a31_pll1_data __initconst = {
+ .enable = 31,
.table = &sun6i_a31_pll1_config,
.getter = sun6i_a31_get_pll1_factors,
};
--
1.8.4

View file

@ -1,94 +0,0 @@
From 73bff3c4c33a2bfbddc593fad53c6c58af93bfab Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Emilio=20L=C3=B3pez?= <emilio@elopez.com.ar>
Date: Mon, 6 May 2013 11:03:41 -0300
Subject: [PATCH] ARM: sunxi: add PLL4 support
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
This commit adds the PLL4 definition to the sun4i, sun5i and sun7i
device trees. PLL4 is compatible with PLL1.
Signed-off-by: Emilio López <emilio@elopez.com.ar>
---
arch/arm/boot/dts/sun4i-a10.dtsi | 7 +++++++
arch/arm/boot/dts/sun5i-a10s.dtsi | 7 +++++++
arch/arm/boot/dts/sun5i-a13.dtsi | 7 +++++++
arch/arm/boot/dts/sun7i-a20.dtsi | 7 +++++++
4 files changed, 28 insertions(+)
diff --git a/arch/arm/boot/dts/sun4i-a10.dtsi b/arch/arm/boot/dts/sun4i-a10.dtsi
index 319cc6b..a6c1cae 100644
--- a/arch/arm/boot/dts/sun4i-a10.dtsi
+++ b/arch/arm/boot/dts/sun4i-a10.dtsi
@@ -66,6 +66,13 @@
clocks = <&osc24M>;
};
+ pll4: pll4@01c20018 {
+ #clock-cells = <0>;
+ compatible = "allwinner,sun4i-pll1-clk";
+ reg = <0x01c20018 0x4>;
+ clocks = <&osc24M>;
+ };
+
/* dummy is 200M */
cpu: cpu@01c20054 {
#clock-cells = <0>;
diff --git a/arch/arm/boot/dts/sun5i-a10s.dtsi b/arch/arm/boot/dts/sun5i-a10s.dtsi
index 5247674..c3f4eed 100644
--- a/arch/arm/boot/dts/sun5i-a10s.dtsi
+++ b/arch/arm/boot/dts/sun5i-a10s.dtsi
@@ -63,6 +63,13 @@
clocks = <&osc24M>;
};
+ pll4: pll4@01c20018 {
+ #clock-cells = <0>;
+ compatible = "allwinner,sun4i-pll1-clk";
+ reg = <0x01c20018 0x4>;
+ clocks = <&osc24M>;
+ };
+
/* dummy is 200M */
cpu: cpu@01c20054 {
#clock-cells = <0>;
diff --git a/arch/arm/boot/dts/sun5i-a13.dtsi b/arch/arm/boot/dts/sun5i-a13.dtsi
index ce8ef2a..8c4a9c3 100644
--- a/arch/arm/boot/dts/sun5i-a13.dtsi
+++ b/arch/arm/boot/dts/sun5i-a13.dtsi
@@ -67,6 +67,13 @@
clocks = <&osc24M>;
};
+ pll4: pll4@01c20018 {
+ #clock-cells = <0>;
+ compatible = "allwinner,sun4i-pll1-clk";
+ reg = <0x01c20018 0x4>;
+ clocks = <&osc24M>;
+ };
+
/* dummy is 200M */
cpu: cpu@01c20054 {
#clock-cells = <0>;
diff --git a/arch/arm/boot/dts/sun7i-a20.dtsi b/arch/arm/boot/dts/sun7i-a20.dtsi
index 282c775..21bf143 100644
--- a/arch/arm/boot/dts/sun7i-a20.dtsi
+++ b/arch/arm/boot/dts/sun7i-a20.dtsi
@@ -62,6 +62,13 @@
clocks = <&osc24M>;
};
+ pll4: pll4@01c20018 {
+ #clock-cells = <0>;
+ compatible = "allwinner,sun4i-pll1-clk";
+ reg = <0x01c20018 0x4>;
+ clocks = <&osc24M>;
+ };
+
/*
* This is a dummy clock, to be used as placeholder on
* other mux clocks when a specific parent clock is not
--
1.8.4

View file

@ -1,309 +0,0 @@
From cad227619badf2a0ff2593d9935fedc84d5ef1ef Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Emilio=20L=C3=B3pez?= <emilio@elopez.com.ar>
Date: Sun, 26 May 2013 14:23:50 -0300
Subject: [PATCH] clk: sunxi: add PLL5 and PLL6 support
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
This commit implements PLL5 and PLL6 support on the sunxi clock driver.
These PLLs use a similar factor clock, but differ on their outputs.
Signed-off-by: Emilio López <emilio@elopez.com.ar>
---
Documentation/devicetree/bindings/clock/sunxi.txt | 2 +
drivers/clk/sunxi/clk-sunxi.c | 182 +++++++++++++++++++++-
2 files changed, 177 insertions(+), 7 deletions(-)
diff --git a/Documentation/devicetree/bindings/clock/sunxi.txt b/Documentation/devicetree/bindings/clock/sunxi.txt
index 7d9245f..773f3ae 100644
--- a/Documentation/devicetree/bindings/clock/sunxi.txt
+++ b/Documentation/devicetree/bindings/clock/sunxi.txt
@@ -9,6 +9,8 @@ Required properties:
"allwinner,sun4i-osc-clk" - for a gatable oscillator
"allwinner,sun4i-pll1-clk" - for the main PLL clock and PLL4
"allwinner,sun6i-a31-pll1-clk" - for the main PLL clock on A31
+ "allwinner,sun4i-pll5-clk" - for the PLL5 clock
+ "allwinner,sun4i-pll6-clk" - for the PLL6 clock
"allwinner,sun4i-cpu-clk" - for the CPU multiplexer clock
"allwinner,sun4i-axi-clk" - for the AXI clock
"allwinner,sun4i-axi-gates-clk" - for the AXI gates
diff --git a/drivers/clk/sunxi/clk-sunxi.c b/drivers/clk/sunxi/clk-sunxi.c
index c0b0675..6947ba9 100644
--- a/drivers/clk/sunxi/clk-sunxi.c
+++ b/drivers/clk/sunxi/clk-sunxi.c
@@ -210,6 +210,40 @@ static void sun6i_a31_get_pll1_factors(u32 *freq, u32 parent_rate,
}
/**
+ * sun4i_get_pll5_factors() - calculates n, k factors for PLL5
+ * PLL5 rate is calculated as follows
+ * rate = parent_rate * n * (k + 1)
+ * parent_rate is always 24Mhz
+ */
+
+static void sun4i_get_pll5_factors(u32 *freq, u32 parent_rate,
+ u8 *n, u8 *k, u8 *m, u8 *p)
+{
+ u8 div;
+
+ /* Normalize value to a 24M multiple */
+ div = *freq / 24000000;
+ *freq = 24000000 * div;
+
+ /* we were called to round the frequency, we can now return */
+ if (n == NULL)
+ return;
+
+ if (div < 31)
+ *k = 0;
+ else if (div / 2 < 31)
+ *k = 1;
+ else if (div / 3 < 31)
+ *k = 2;
+ else
+ *k = 3;
+
+ *n = DIV_ROUND_UP(div, (*k+1));
+}
+
+
+
+/**
* sun4i_get_apb1_factors() - calculates m, p factors for APB1
* APB1 rate is calculated as follows
* rate = (parent_rate >> p) / (m + 1);
@@ -285,6 +319,13 @@ struct factors_data {
.mwidth = 2,
};
+static struct clk_factors_config sun4i_pll5_config = {
+ .nshift = 8,
+ .nwidth = 5,
+ .kshift = 4,
+ .kwidth = 2,
+};
+
static struct clk_factors_config sun4i_apb1_config = {
.mshift = 0,
.mwidth = 5,
@@ -304,13 +345,19 @@ struct factors_data {
.getter = sun6i_a31_get_pll1_factors,
};
+static const struct factors_data sun4i_pll5_data __initconst = {
+ .enable = 31,
+ .table = &sun4i_pll5_config,
+ .getter = sun4i_get_pll5_factors,
+};
+
static const struct factors_data sun4i_apb1_data __initconst = {
.table = &sun4i_apb1_config,
.getter = sun4i_get_apb1_factors,
};
-static void __init sunxi_factors_clk_setup(struct device_node *node,
- struct factors_data *data)
+static struct clk * __init sunxi_factors_clk_setup(struct device_node *node,
+ const struct factors_data *data)
{
struct clk *clk;
struct clk_factors *factors;
@@ -321,6 +368,7 @@ static void __init sunxi_factors_clk_setup(struct device_node *node,
const char *clk_name = node->name;
const char *parents[5];
void *reg;
+ unsigned long flags;
int i = 0;
reg = of_iomap(node, 0);
@@ -331,14 +379,14 @@ static void __init sunxi_factors_clk_setup(struct device_node *node,
factors = kzalloc(sizeof(struct clk_factors), GFP_KERNEL);
if (!factors)
- return;
+ return NULL;
/* Add a gate if this factor clock can be gated */
if (data->enable) {
gate = kzalloc(sizeof(struct clk_gate), GFP_KERNEL);
if (!gate) {
kfree(factors);
- return;
+ return NULL;
}
/* set up gate properties */
@@ -354,7 +402,7 @@ static void __init sunxi_factors_clk_setup(struct device_node *node,
if (!mux) {
kfree(factors);
kfree(gate);
- return;
+ return NULL;
}
/* set up gate properties */
@@ -371,17 +419,21 @@ static void __init sunxi_factors_clk_setup(struct device_node *node,
factors->get_factors = data->getter;
factors->lock = &clk_lock;
+ /* We should not disable pll5, it powers the RAM */
+ flags = !strcmp("pll5", clk_name) ? CLK_IGNORE_UNUSED : 0;
+
clk = clk_register_composite(NULL, clk_name,
parents, i,
mux_hw, &clk_mux_ops,
&factors->hw, &clk_factors_ops,
- gate_hw, &clk_gate_ops,
- i ? 0 : CLK_IS_ROOT);
+ gate_hw, &clk_gate_ops, flags);
if (!IS_ERR(clk)) {
of_clk_add_provider(node, of_clk_src_simple_get, clk);
clk_register_clkdev(clk, clk_name, NULL);
}
+
+ return clk;
}
@@ -616,6 +668,112 @@ static void __init sunxi_gates_clk_setup(struct device_node *node,
of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
}
+
+
+/**
+ * sunxi_divs_clk_setup() - Setup function for leaf divisors on clocks
+ */
+
+#define SUNXI_DIVS_MAX_QTY 2
+#define SUNXI_DIVISOR_WIDTH 2
+
+struct divs_data {
+ const struct factors_data *factors; /* data for the factor clock */
+ struct {
+ u8 fixed; /* is it a fixed divisor? if not... */
+ struct clk_div_table *table; /* is it a table based divisor? */
+ u8 shift; /* otherwise it's a normal divisor with this shift */
+ u8 pow; /* is it power-of-two based? */
+ } div[SUNXI_DIVS_MAX_QTY];
+};
+
+static struct clk_div_table pll6_sata_table[] = {
+ { .val = 0, .div = 6, },
+ { .val = 1, .div = 12, },
+ { .val = 2, .div = 18, },
+ { .val = 3, .div = 24, },
+ { } /* sentinel */
+};
+
+static const struct divs_data pll5_divs_data __initconst = {
+ .factors = &sun4i_pll5_data,
+ .div = {
+ { .shift = 0, .pow = 0, }, /* M, DDR */
+ { .shift = 16, .pow = 1, }, /* P, other */
+ }
+};
+
+static const struct divs_data pll6_divs_data __initconst = {
+ .factors = &sun4i_pll5_data,
+ .div = {
+ { .shift = 0, .table = pll6_sata_table }, /* M, SATA */
+ { .fixed = 2 }, /* P, other */
+ }
+};
+
+static void __init sunxi_divs_clk_setup(struct device_node *node,
+ struct divs_data *data)
+{
+ struct clk_onecell_data *clk_data;
+ const char *parent = node->name;
+ const char *clk_name;
+ struct clk **clks, *pclk;
+ void *reg;
+ int i = 0;
+ int flags, clkflags;
+
+ /* Set up factor clock that we will be dividing */
+ pclk = sunxi_factors_clk_setup(node, data->factors);
+
+ reg = of_iomap(node, 0);
+
+ clk_data = kmalloc(sizeof(struct clk_onecell_data), GFP_KERNEL);
+ if (!clk_data)
+ return;
+ clks = kzalloc(SUNXI_DIVS_MAX_QTY * sizeof(struct clk *), GFP_KERNEL);
+ if (!clks) {
+ kfree(clk_data);
+ return;
+ }
+ clk_data->clks = clks;
+
+ /* It's not a good idea to have automatic reparenting changing
+ * our RAM clock! */
+ clkflags = !strcmp("pll5", parent) ? 0 : CLK_SET_RATE_PARENT;
+
+ for (i = 0; i < SUNXI_DIVS_MAX_QTY; i++) {
+ if (of_property_read_string_index(node, "clock-output-names",
+ i, &clk_name) != 0)
+ break;
+
+ if (data->div[i].fixed) {
+ clks[i] = clk_register_fixed_factor(NULL, clk_name,
+ parent, clkflags,
+ 1, data->div[i].fixed);
+ } else {
+ flags = data->div[i].pow ? CLK_DIVIDER_POWER_OF_TWO : 0;
+ clks[i] = clk_register_divider_table(NULL, clk_name,
+ parent, clkflags, reg,
+ data->div[i].shift,
+ SUNXI_DIVISOR_WIDTH, flags,
+ data->div[i].table, &clk_lock);
+ }
+
+ WARN_ON(IS_ERR(clk_data->clks[i]));
+ clk_register_clkdev(clks[i], clk_name, NULL);
+ }
+
+ /* The last clock available on the getter is the parent */
+ clks[i++] = pclk;
+
+ /* Adjust to the real max */
+ clk_data->clk_num = i;
+
+ of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
+}
+
+
+
/* Matches for factors clocks */
static const struct of_device_id clk_factors_match[] __initconst = {
{.compatible = "allwinner,sun4i-pll1-clk", .data = &sun4i_pll1_data,},
@@ -633,6 +791,13 @@ static void __init sunxi_gates_clk_setup(struct device_node *node,
{}
};
+/* Matches for divided outputs */
+static const struct of_device_id clk_divs_match[] __initconst = {
+ {.compatible = "allwinner,sun4i-pll5-clk", .data = &pll5_divs_data,},
+ {.compatible = "allwinner,sun4i-pll6-clk", .data = &pll6_divs_data,},
+ {}
+};
+
/* Matches for mux clocks */
static const struct of_device_id clk_mux_match[] __initconst = {
{.compatible = "allwinner,sun4i-cpu-clk", .data = &sun4i_cpu_mux_data,},
@@ -688,6 +853,9 @@ void __init sunxi_init_clocks(void)
/* Register divider clocks */
of_sunxi_table_clock_setup(clk_div_match, sunxi_divider_clk_setup);
+ /* Register divided output clocks */
+ of_sunxi_table_clock_setup(clk_divs_match, sunxi_divs_clk_setup);
+
/* Register mux clocks */
of_sunxi_table_clock_setup(clk_mux_match, sunxi_mux_clk_setup);
--
1.8.4

View file

@ -1,197 +0,0 @@
From 4f40ad1587e9435a2085703fa2a7d7c9245306b2 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Emilio=20L=C3=B3pez?= <emilio@elopez.com.ar>
Date: Sun, 26 May 2013 14:08:59 -0300
Subject: [PATCH] ARM: sunxi: add PLL5 and PLL6 support
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
This commit adds PLL5 and PLL6 nodes to the sun4i, sun5i and sun7i
device trees.
Signed-off-by: Emilio López <emilio@elopez.com.ar>
---
arch/arm/boot/dts/sun4i-a10.dtsi | 19 +++++++++++++++++--
arch/arm/boot/dts/sun5i-a10s.dtsi | 19 +++++++++++++++++--
arch/arm/boot/dts/sun5i-a13.dtsi | 19 +++++++++++++++++--
arch/arm/boot/dts/sun7i-a20.dtsi | 28 ++++++++++++++++------------
4 files changed, 67 insertions(+), 18 deletions(-)
diff --git a/arch/arm/boot/dts/sun4i-a10.dtsi b/arch/arm/boot/dts/sun4i-a10.dtsi
index a6c1cae..5e2fc45 100644
--- a/arch/arm/boot/dts/sun4i-a10.dtsi
+++ b/arch/arm/boot/dts/sun4i-a10.dtsi
@@ -73,6 +73,22 @@
clocks = <&osc24M>;
};
+ pll5: pll5@01c20020 {
+ #clock-cells = <1>;
+ compatible = "allwinner,sun4i-pll5-clk";
+ reg = <0x01c20020 0x4>;
+ clocks = <&osc24M>;
+ clock-output-names = "pll5_ddr", "pll5_other";
+ };
+
+ pll6: pll6@01c20028 {
+ #clock-cells = <1>;
+ compatible = "allwinner,sun4i-pll6-clk";
+ reg = <0x01c20028 0x4>;
+ clocks = <&osc24M>;
+ clock-output-names = "pll6_sata", "pll6_other", "pll6";
+ };
+
/* dummy is 200M */
cpu: cpu@01c20054 {
#clock-cells = <0>;
@@ -138,12 +154,11 @@
"apb0_ir1", "apb0_keypad";
};
- /* dummy is pll62 */
apb1_mux: apb1_mux@01c20058 {
#clock-cells = <0>;
compatible = "allwinner,sun4i-apb1-mux-clk";
reg = <0x01c20058 0x4>;
- clocks = <&osc24M>, <&dummy>, <&osc32k>;
+ clocks = <&osc24M>, <&pll6 1>, <&osc32k>;
};
apb1: apb1@01c20058 {
diff --git a/arch/arm/boot/dts/sun5i-a10s.dtsi b/arch/arm/boot/dts/sun5i-a10s.dtsi
index c3f4eed..b29412a 100644
--- a/arch/arm/boot/dts/sun5i-a10s.dtsi
+++ b/arch/arm/boot/dts/sun5i-a10s.dtsi
@@ -70,6 +70,22 @@
clocks = <&osc24M>;
};
+ pll5: pll5@01c20020 {
+ #clock-cells = <1>;
+ compatible = "allwinner,sun4i-pll5-clk";
+ reg = <0x01c20020 0x4>;
+ clocks = <&osc24M>;
+ clock-output-names = "pll5_ddr", "pll5_other";
+ };
+
+ pll6: pll6@01c20028 {
+ #clock-cells = <1>;
+ compatible = "allwinner,sun4i-pll6-clk";
+ reg = <0x01c20028 0x4>;
+ clocks = <&osc24M>;
+ clock-output-names = "pll6_sata", "pll6_other", "pll6";
+ };
+
/* dummy is 200M */
cpu: cpu@01c20054 {
#clock-cells = <0>;
@@ -130,12 +146,11 @@
"apb0_ir", "apb0_keypad";
};
- /* dummy is pll62 */
apb1_mux: apb1_mux@01c20058 {
#clock-cells = <0>;
compatible = "allwinner,sun4i-apb1-mux-clk";
reg = <0x01c20058 0x4>;
- clocks = <&osc24M>, <&dummy>, <&osc32k>;
+ clocks = <&osc24M>, <&pll6 1>, <&osc32k>;
};
apb1: apb1@01c20058 {
diff --git a/arch/arm/boot/dts/sun5i-a13.dtsi b/arch/arm/boot/dts/sun5i-a13.dtsi
index 8c4a9c3..cded3c7 100644
--- a/arch/arm/boot/dts/sun5i-a13.dtsi
+++ b/arch/arm/boot/dts/sun5i-a13.dtsi
@@ -74,6 +74,22 @@
clocks = <&osc24M>;
};
+ pll5: pll5@01c20020 {
+ #clock-cells = <1>;
+ compatible = "allwinner,sun4i-pll5-clk";
+ reg = <0x01c20020 0x4>;
+ clocks = <&osc24M>;
+ clock-output-names = "pll5_ddr", "pll5_other";
+ };
+
+ pll6: pll6@01c20028 {
+ #clock-cells = <1>;
+ compatible = "allwinner,sun4i-pll6-clk";
+ reg = <0x01c20028 0x4>;
+ clocks = <&osc24M>;
+ clock-output-names = "pll6_sata", "pll6_other", "pll6";
+ };
+
/* dummy is 200M */
cpu: cpu@01c20054 {
#clock-cells = <0>;
@@ -132,12 +148,11 @@
clock-output-names = "apb0_codec", "apb0_pio", "apb0_ir";
};
- /* dummy is pll6 */
apb1_mux: apb1_mux@01c20058 {
#clock-cells = <0>;
compatible = "allwinner,sun4i-apb1-mux-clk";
reg = <0x01c20058 0x4>;
- clocks = <&osc24M>, <&dummy>, <&osc32k>;
+ clocks = <&osc24M>, <&pll6 1>, <&osc32k>;
};
apb1: apb1@01c20058 {
diff --git a/arch/arm/boot/dts/sun7i-a20.dtsi b/arch/arm/boot/dts/sun7i-a20.dtsi
index 21bf143..2e39ed9 100644
--- a/arch/arm/boot/dts/sun7i-a20.dtsi
+++ b/arch/arm/boot/dts/sun7i-a20.dtsi
@@ -69,23 +69,27 @@
clocks = <&osc24M>;
};
- /*
- * This is a dummy clock, to be used as placeholder on
- * other mux clocks when a specific parent clock is not
- * yet implemented. It should be dropped when the driver
- * is complete.
- */
- pll6: pll6 {
- #clock-cells = <0>;
- compatible = "fixed-clock";
- clock-frequency = <0>;
+ pll5: pll5@01c20020 {
+ #clock-cells = <1>;
+ compatible = "allwinner,sun4i-pll5-clk";
+ reg = <0x01c20020 0x4>;
+ clocks = <&osc24M>;
+ clock-output-names = "pll5_ddr", "pll5_other";
+ };
+
+ pll6: pll6@01c20028 {
+ #clock-cells = <1>;
+ compatible = "allwinner,sun4i-pll6-clk";
+ reg = <0x01c20028 0x4>;
+ clocks = <&osc24M>;
+ clock-output-names = "pll6_sata", "pll6_other", "pll6";
};
cpu: cpu@01c20054 {
#clock-cells = <0>;
compatible = "allwinner,sun4i-cpu-clk";
reg = <0x01c20054 0x4>;
- clocks = <&osc32k>, <&osc24M>, <&pll1>, <&pll6>;
+ clocks = <&osc32k>, <&osc24M>, <&pll1>, <&pll6 1>;
};
axi: axi@01c20054 {
@@ -144,7 +148,7 @@
#clock-cells = <0>;
compatible = "allwinner,sun4i-apb1-mux-clk";
reg = <0x01c20058 0x4>;
- clocks = <&osc24M>, <&pll6>, <&osc32k>;
+ clocks = <&osc24M>, <&pll6 1>, <&osc32k>;
};
apb1: apb1@01c20058 {
--
1.8.4

View file

@ -1,121 +0,0 @@
From 3473e6acea4bd01ba2b334628970390207f9f4fd Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Emilio=20L=C3=B3pez?= <emilio@elopez.com.ar>
Date: Tue, 21 May 2013 21:25:05 -0300
Subject: [PATCH] clk: sunxi: mod0 support
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
This commit implements support for the "module 0" type of clocks, as
used by MMC, IR, NAND, SATA and other components.
Signed-off-by: Emilio López <emilio@elopez.com.ar>
---
Documentation/devicetree/bindings/clock/sunxi.txt | 1 +
drivers/clk/sunxi/clk-sunxi.c | 57 +++++++++++++++++++++++
2 files changed, 58 insertions(+)
diff --git a/Documentation/devicetree/bindings/clock/sunxi.txt b/Documentation/devicetree/bindings/clock/sunxi.txt
index 773f3ae..ff3f61c 100644
--- a/Documentation/devicetree/bindings/clock/sunxi.txt
+++ b/Documentation/devicetree/bindings/clock/sunxi.txt
@@ -35,6 +35,7 @@ Required properties:
"allwinner,sun7i-a20-apb1-gates-clk" - for the APB1 gates on A20
"allwinner,sun6i-a31-apb2-div-clk" - for the APB2 gates on A31
"allwinner,sun6i-a31-apb2-gates-clk" - for the APB2 gates on A31
+ "allwinner,sun4i-mod0-clk" - for the module 0 family of clocks
Required properties for all clocks:
- reg : shall be the control register address for the clock.
diff --git a/drivers/clk/sunxi/clk-sunxi.c b/drivers/clk/sunxi/clk-sunxi.c
index 6947ba9..96c01b2 100644
--- a/drivers/clk/sunxi/clk-sunxi.c
+++ b/drivers/clk/sunxi/clk-sunxi.c
@@ -287,6 +287,47 @@ static void sun4i_get_apb1_factors(u32 *freq, u32 parent_rate,
/**
+ * sun4i_get_mod0_factors() - calculates m, n factors for MOD0-style clocks
+ * MMC rate is calculated as follows
+ * rate = (parent_rate >> p) / (m + 1);
+ */
+
+static void sun4i_get_mod0_factors(u32 *freq, u32 parent_rate,
+ u8 *n, u8 *k, u8 *m, u8 *p)
+{
+ u8 div, calcm, calcp;
+
+ /* These clocks can only divide, so we will never be able to achieve
+ * frequencies higher than the parent frequency */
+ if (*freq > parent_rate)
+ *freq = parent_rate;
+
+ div = parent_rate / *freq;
+
+ if (div < 16)
+ calcp = 0;
+ else if (div / 2 < 16)
+ calcp = 1;
+ else if (div / 4 < 16)
+ calcp = 2;
+ else
+ calcp = 3;
+
+ calcm = DIV_ROUND_UP(div, 1 << calcp);
+
+ *freq = (parent_rate >> calcp) / calcm;
+
+ /* we were called to round the frequency, we can now return */
+ if (n == NULL)
+ return;
+
+ *m = calcm - 1;
+ *p = calcp;
+}
+
+
+
+/**
* sunxi_factors_clk_setup() - Setup function for factor clocks
*/
@@ -333,6 +374,14 @@ struct factors_data {
.pwidth = 2,
};
+/* user manual says "n" but it's really "p" */
+static struct clk_factors_config sun4i_mod0_config = {
+ .mshift = 0,
+ .mwidth = 4,
+ .pshift = 16,
+ .pwidth = 2,
+};
+
static const struct factors_data sun4i_pll1_data __initconst = {
.enable = 31,
.table = &sun4i_pll1_config,
@@ -356,6 +405,13 @@ struct factors_data {
.getter = sun4i_get_apb1_factors,
};
+static const struct factors_data sun4i_mod0_data __initconst = {
+ .enable = 31,
+ .mux = 24,
+ .table = &sun4i_mod0_config,
+ .getter = sun4i_get_mod0_factors,
+};
+
static struct clk * __init sunxi_factors_clk_setup(struct device_node *node,
const struct factors_data *data)
{
@@ -779,6 +835,7 @@ static void __init sunxi_divs_clk_setup(struct device_node *node,
{.compatible = "allwinner,sun4i-pll1-clk", .data = &sun4i_pll1_data,},
{.compatible = "allwinner,sun6i-a31-pll1-clk", .data = &sun6i_a31_pll1_data,},
{.compatible = "allwinner,sun4i-apb1-clk", .data = &sun4i_apb1_data,},
+ {.compatible = "allwinner,sun4i-mod0-clk", .data = &sun4i_mod0_data,},
{}
};
--
1.8.4

View file

@ -1,136 +0,0 @@
From 8cf7164b32f2ce228b0c8116fd712484f67c65b5 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Emilio=20L=C3=B3pez?= <emilio@elopez.com.ar>
Date: Wed, 4 Sep 2013 21:28:49 -0300
Subject: [PATCH] ARM: sun7i: dt: mod0 clocks
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
This commit adds all the mod0 clocks available on A20 to its device
tree. This list was created by looking at AW's code release.
Signed-off-by: Emilio López <emilio@elopez.com.ar>
Acked-by: Maxime Ripard <maxime.ripard@free-electrons.com>
---
arch/arm/boot/dts/sun7i-a20.dtsi | 105 +++++++++++++++++++++++++++++++++++++++
1 file changed, 105 insertions(+)
diff --git a/arch/arm/boot/dts/sun7i-a20.dtsi b/arch/arm/boot/dts/sun7i-a20.dtsi
index 0af287e..0596e82 100644
--- a/arch/arm/boot/dts/sun7i-a20.dtsi
+++ b/arch/arm/boot/dts/sun7i-a20.dtsi
@@ -174,6 +174,111 @@
"apb1_uart2", "apb1_uart3", "apb1_uart4",
"apb1_uart5", "apb1_uart6", "apb1_uart7";
};
+
+ nand: nand@01c20080 {
+ #clock-cells = <0>;
+ compatible = "allwinner,sun4i-mod0-clk";
+ reg = <0x01c20080 0x4>;
+ clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+ };
+
+ ms: ms@01c20084 {
+ #clock-cells = <0>;
+ compatible = "allwinner,sun4i-mod0-clk";
+ reg = <0x01c20084 0x4>;
+ clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+ };
+
+ mmc0: mmc0@01c20088 {
+ #clock-cells = <0>;
+ compatible = "allwinner,sun4i-mod0-clk";
+ reg = <0x01c20088 0x4>;
+ clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+ };
+
+ mmc1: mmc1@01c2008c {
+ #clock-cells = <0>;
+ compatible = "allwinner,sun4i-mod0-clk";
+ reg = <0x01c2008c 0x4>;
+ clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+ };
+
+ mmc2: mmc2@01c20090 {
+ #clock-cells = <0>;
+ compatible = "allwinner,sun4i-mod0-clk";
+ reg = <0x01c20090 0x4>;
+ clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+ };
+
+ mmc3: mmc3@01c20094 {
+ #clock-cells = <0>;
+ compatible = "allwinner,sun4i-mod0-clk";
+ reg = <0x01c20094 0x4>;
+ clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+ };
+
+ ts: ts@01c20098 {
+ #clock-cells = <0>;
+ compatible = "allwinner,sun4i-mod0-clk";
+ reg = <0x01c20098 0x4>;
+ clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+ };
+
+ ss: ss@01c2009c {
+ #clock-cells = <0>;
+ compatible = "allwinner,sun4i-mod0-clk";
+ reg = <0x01c2009c 0x4>;
+ clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+ };
+
+ spi0: spi0@01c200a0 {
+ #clock-cells = <0>;
+ compatible = "allwinner,sun4i-mod0-clk";
+ reg = <0x01c200a0 0x4>;
+ clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+ };
+
+ spi1: spi1@01c200a4 {
+ #clock-cells = <0>;
+ compatible = "allwinner,sun4i-mod0-clk";
+ reg = <0x01c200a4 0x4>;
+ clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+ };
+
+ spi2: spi2@01c200a8 {
+ #clock-cells = <0>;
+ compatible = "allwinner,sun4i-mod0-clk";
+ reg = <0x01c200a8 0x4>;
+ clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+ };
+
+ pata: pata@01c200ac {
+ #clock-cells = <0>;
+ compatible = "allwinner,sun4i-mod0-clk";
+ reg = <0x01c200ac 0x4>;
+ clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+ };
+
+ ir0: ir0@01c200b0 {
+ #clock-cells = <0>;
+ compatible = "allwinner,sun4i-mod0-clk";
+ reg = <0x01c200b0 0x4>;
+ clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+ };
+
+ ir1: ir1@01c200b4 {
+ #clock-cells = <0>;
+ compatible = "allwinner,sun4i-mod0-clk";
+ reg = <0x01c200b4 0x4>;
+ clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+ };
+
+ spi3: spi3@01c200d4 {
+ #clock-cells = <0>;
+ compatible = "allwinner,sun4i-mod0-clk";
+ reg = <0x01c200d4 0x4>;
+ clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+ };
};
soc@01c00000 {
--
1.8.5.1

View file

@ -1,198 +0,0 @@
From 0ae543fe8ae8b9ea7166c39b00e977506eccdf4b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Emilio=20L=C3=B3pez?= <emilio@elopez.com.ar>
Date: Wed, 4 Sep 2013 21:21:16 -0300
Subject: [PATCH] ARM: sun5i: dt: mod0 clocks
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
This commit adds all the mod0 clocks available on A10 and A13. The list
has been constructed by looking at the Allwinner code release for A10S
and A13.
Signed-off-by: Emilio López <emilio@elopez.com.ar>
Acked-by: Maxime Ripard <maxime.ripard@free-electrons.com>
---
arch/arm/boot/dts/sun5i-a10s.dtsi | 77 +++++++++++++++++++++++++++++++++++++++
arch/arm/boot/dts/sun5i-a13.dtsi | 77 +++++++++++++++++++++++++++++++++++++++
2 files changed, 154 insertions(+)
diff --git a/arch/arm/boot/dts/sun5i-a10s.dtsi b/arch/arm/boot/dts/sun5i-a10s.dtsi
index 86e06e4..82b5ce6 100644
--- a/arch/arm/boot/dts/sun5i-a10s.dtsi
+++ b/arch/arm/boot/dts/sun5i-a10s.dtsi
@@ -173,6 +173,83 @@
"apb1_i2c2", "apb1_uart0", "apb1_uart1",
"apb1_uart2", "apb1_uart3";
};
+
+ nand: nand@01c20080 {
+ #clock-cells = <0>;
+ compatible = "allwinner,sun4i-mod0-clk";
+ reg = <0x01c20080 0x4>;
+ clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+ };
+
+ ms: ms@01c20084 {
+ #clock-cells = <0>;
+ compatible = "allwinner,sun4i-mod0-clk";
+ reg = <0x01c20084 0x4>;
+ clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+ };
+
+ mmc0: mmc0@01c20088 {
+ #clock-cells = <0>;
+ compatible = "allwinner,sun4i-mod0-clk";
+ reg = <0x01c20088 0x4>;
+ clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+ };
+
+ mmc1: mmc1@01c2008c {
+ #clock-cells = <0>;
+ compatible = "allwinner,sun4i-mod0-clk";
+ reg = <0x01c2008c 0x4>;
+ clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+ };
+
+ mmc2: mmc2@01c20090 {
+ #clock-cells = <0>;
+ compatible = "allwinner,sun4i-mod0-clk";
+ reg = <0x01c20090 0x4>;
+ clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+ };
+
+ ts: ts@01c20098 {
+ #clock-cells = <0>;
+ compatible = "allwinner,sun4i-mod0-clk";
+ reg = <0x01c20098 0x4>;
+ clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+ };
+
+ ss: ss@01c2009c {
+ #clock-cells = <0>;
+ compatible = "allwinner,sun4i-mod0-clk";
+ reg = <0x01c2009c 0x4>;
+ clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+ };
+
+ spi0: spi0@01c200a0 {
+ #clock-cells = <0>;
+ compatible = "allwinner,sun4i-mod0-clk";
+ reg = <0x01c200a0 0x4>;
+ clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+ };
+
+ spi1: spi1@01c200a4 {
+ #clock-cells = <0>;
+ compatible = "allwinner,sun4i-mod0-clk";
+ reg = <0x01c200a4 0x4>;
+ clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+ };
+
+ spi2: spi2@01c200a8 {
+ #clock-cells = <0>;
+ compatible = "allwinner,sun4i-mod0-clk";
+ reg = <0x01c200a8 0x4>;
+ clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+ };
+
+ ir0: ir0@01c200b0 {
+ #clock-cells = <0>;
+ compatible = "allwinner,sun4i-mod0-clk";
+ reg = <0x01c200b0 0x4>;
+ clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+ };
};
soc@01c00000 {
diff --git a/arch/arm/boot/dts/sun5i-a13.dtsi b/arch/arm/boot/dts/sun5i-a13.dtsi
index cded3c7..938e6d3 100644
--- a/arch/arm/boot/dts/sun5i-a13.dtsi
+++ b/arch/arm/boot/dts/sun5i-a13.dtsi
@@ -170,6 +170,83 @@
clock-output-names = "apb1_i2c0", "apb1_i2c1",
"apb1_i2c2", "apb1_uart1", "apb1_uart3";
};
+
+ nand: nand@01c20080 {
+ #clock-cells = <0>;
+ compatible = "allwinner,sun4i-mod0-clk";
+ reg = <0x01c20080 0x4>;
+ clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+ };
+
+ ms: ms@01c20084 {
+ #clock-cells = <0>;
+ compatible = "allwinner,sun4i-mod0-clk";
+ reg = <0x01c20084 0x4>;
+ clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+ };
+
+ mmc0: mmc0@01c20088 {
+ #clock-cells = <0>;
+ compatible = "allwinner,sun4i-mod0-clk";
+ reg = <0x01c20088 0x4>;
+ clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+ };
+
+ mmc1: mmc1@01c2008c {
+ #clock-cells = <0>;
+ compatible = "allwinner,sun4i-mod0-clk";
+ reg = <0x01c2008c 0x4>;
+ clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+ };
+
+ mmc2: mmc2@01c20090 {
+ #clock-cells = <0>;
+ compatible = "allwinner,sun4i-mod0-clk";
+ reg = <0x01c20090 0x4>;
+ clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+ };
+
+ ts: ts@01c20098 {
+ #clock-cells = <0>;
+ compatible = "allwinner,sun4i-mod0-clk";
+ reg = <0x01c20098 0x4>;
+ clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+ };
+
+ ss: ss@01c2009c {
+ #clock-cells = <0>;
+ compatible = "allwinner,sun4i-mod0-clk";
+ reg = <0x01c2009c 0x4>;
+ clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+ };
+
+ spi0: spi0@01c200a0 {
+ #clock-cells = <0>;
+ compatible = "allwinner,sun4i-mod0-clk";
+ reg = <0x01c200a0 0x4>;
+ clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+ };
+
+ spi1: spi1@01c200a4 {
+ #clock-cells = <0>;
+ compatible = "allwinner,sun4i-mod0-clk";
+ reg = <0x01c200a4 0x4>;
+ clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+ };
+
+ spi2: spi2@01c200a8 {
+ #clock-cells = <0>;
+ compatible = "allwinner,sun4i-mod0-clk";
+ reg = <0x01c200a8 0x4>;
+ clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+ };
+
+ ir0: ir0@01c200b0 {
+ #clock-cells = <0>;
+ compatible = "allwinner,sun4i-mod0-clk";
+ reg = <0x01c200b0 0x4>;
+ clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+ };
};
soc@01c00000 {
--
1.8.5.1

View file

@ -1,135 +0,0 @@
From 5f554ea6757748c2fc45228030a20e08f6053ff7 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Emilio=20L=C3=B3pez?= <emilio@elopez.com.ar>
Date: Tue, 21 May 2013 21:28:32 -0300
Subject: [PATCH] ARM: sun4i: dt: mod0 clocks
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
This commit adds all the mod0 clocks present on sun4i to its device tree
Signed-off-by: Emilio López <emilio@elopez.com.ar>
Acked-by: Maxime Ripard <maxime.ripard@free-electrons.com>
---
arch/arm/boot/dts/sun4i-a10.dtsi | 105 +++++++++++++++++++++++++++++++++++++++
1 file changed, 105 insertions(+)
diff --git a/arch/arm/boot/dts/sun4i-a10.dtsi b/arch/arm/boot/dts/sun4i-a10.dtsi
index ebacb5d..2828427e 100644
--- a/arch/arm/boot/dts/sun4i-a10.dtsi
+++ b/arch/arm/boot/dts/sun4i-a10.dtsi
@@ -184,6 +184,111 @@
"apb1_uart4", "apb1_uart5", "apb1_uart6",
"apb1_uart7";
};
+
+ nand: nand@01c20080 {
+ #clock-cells = <0>;
+ compatible = "allwinner,sun4i-mod0-clk";
+ reg = <0x01c20080 0x4>;
+ clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+ };
+
+ ms: ms@01c20084 {
+ #clock-cells = <0>;
+ compatible = "allwinner,sun4i-mod0-clk";
+ reg = <0x01c20084 0x4>;
+ clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+ };
+
+ mmc0: mmc0@01c20088 {
+ #clock-cells = <0>;
+ compatible = "allwinner,sun4i-mod0-clk";
+ reg = <0x01c20088 0x4>;
+ clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+ };
+
+ mmc1: mmc1@01c2008c {
+ #clock-cells = <0>;
+ compatible = "allwinner,sun4i-mod0-clk";
+ reg = <0x01c2008c 0x4>;
+ clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+ };
+
+ mmc2: mmc2@01c20090 {
+ #clock-cells = <0>;
+ compatible = "allwinner,sun4i-mod0-clk";
+ reg = <0x01c20090 0x4>;
+ clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+ };
+
+ mmc3: mmc3@01c20094 {
+ #clock-cells = <0>;
+ compatible = "allwinner,sun4i-mod0-clk";
+ reg = <0x01c20094 0x4>;
+ clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+ };
+
+ ts: ts@01c20098 {
+ #clock-cells = <0>;
+ compatible = "allwinner,sun4i-mod0-clk";
+ reg = <0x01c20098 0x4>;
+ clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+ };
+
+ ss: ss@01c2009c {
+ #clock-cells = <0>;
+ compatible = "allwinner,sun4i-mod0-clk";
+ reg = <0x01c2009c 0x4>;
+ clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+ };
+
+ spi0: spi0@01c200a0 {
+ #clock-cells = <0>;
+ compatible = "allwinner,sun4i-mod0-clk";
+ reg = <0x01c200a0 0x4>;
+ clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+ };
+
+ spi1: spi1@01c200a4 {
+ #clock-cells = <0>;
+ compatible = "allwinner,sun4i-mod0-clk";
+ reg = <0x01c200a4 0x4>;
+ clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+ };
+
+ spi2: spi2@01c200a8 {
+ #clock-cells = <0>;
+ compatible = "allwinner,sun4i-mod0-clk";
+ reg = <0x01c200a8 0x4>;
+ clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+ };
+
+ pata: pata@01c200ac {
+ #clock-cells = <0>;
+ compatible = "allwinner,sun4i-mod0-clk";
+ reg = <0x01c200ac 0x4>;
+ clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+ };
+
+ ir0: ir0@01c200b0 {
+ #clock-cells = <0>;
+ compatible = "allwinner,sun4i-mod0-clk";
+ reg = <0x01c200b0 0x4>;
+ clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+ };
+
+ ir1: ir1@01c200b4 {
+ #clock-cells = <0>;
+ compatible = "allwinner,sun4i-mod0-clk";
+ reg = <0x01c200b4 0x4>;
+ clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+ };
+
+ spi3: spi3@01c200d4 {
+ #clock-cells = <0>;
+ compatible = "allwinner,sun4i-mod0-clk";
+ reg = <0x01c200d4 0x4>;
+ clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+ };
};
soc@01c00000 {
--
1.8.5.1

View file

@ -1,11 +0,0 @@
diff -ruN old/arch/arm/mach-sunxi/sunxi.c new/arch/arm/mach-sunxi/sunxi.c
--- old/arch/arm/mach-sunxi/sunxi.c 2014-01-04 01:57:31.000000000 +0100
+++ new/arch/arm/mach-sunxi/sunxi.c 2014-01-04 01:11:47.000000000 +0100
@@ -10,6 +10,7 @@
* warranty of any kind, whether express or implied.
*/
+#include <linux/clk-provider.h>
#include <linux/clocksource.h>
#include <linux/delay.h>
#include <linux/kernel.h>

View file

@ -1,149 +0,0 @@
From 11e7ff129807394d87c937b880bb58972dc91fc0 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Emilio=20L=C3=B3pez?= <emilio@elopez.com.ar>
Date: Thu, 28 Nov 2013 09:00:47 -0300
Subject: [PATCH] fixup! clk: sunxi: add PLL5 and PLL6 support
---
drivers/clk/sunxi/clk-sunxi.c | 83 +++++++++++++++++++++++++++++++++++--------
1 file changed, 69 insertions(+), 14 deletions(-)
diff --git a/drivers/clk/sunxi/clk-sunxi.c b/drivers/clk/sunxi/clk-sunxi.c
index d2b8d3c..3ce33b8 100644
--- a/drivers/clk/sunxi/clk-sunxi.c
+++ b/drivers/clk/sunxi/clk-sunxi.c
@@ -807,10 +807,11 @@ struct divs_data {
struct clk_div_table *table; /* is it a table based divisor? */
u8 shift; /* otherwise it's a normal divisor with this shift */
u8 pow; /* is it power-of-two based? */
+ u8 gate; /* is it independently gateable? */
} div[SUNXI_DIVS_MAX_QTY];
};
-static struct clk_div_table pll6_sata_table[] = {
+static struct clk_div_table pll6_sata_tbl[] = {
{ .val = 0, .div = 6, },
{ .val = 1, .div = 12, },
{ .val = 2, .div = 18, },
@@ -829,7 +830,7 @@ struct divs_data {
static const struct divs_data pll6_divs_data __initconst = {
.factors = &sun4i_pll5_data,
.div = {
- { .shift = 0, .table = pll6_sata_table }, /* M, SATA */
+ { .shift = 0, .table = pll6_sata_tbl, .gate = 14 }, /* M, SATA */
{ .fixed = 2 }, /* P, other */
}
};
@@ -852,6 +853,11 @@ static void __init sunxi_divs_clk_setup(struct device_node *node,
const char *parent = node->name;
const char *clk_name;
struct clk **clks, *pclk;
+ struct clk_hw *gate_hw, *rate_hw;
+ const struct clk_ops *rate_ops;
+ struct clk_gate *gate = NULL;
+ struct clk_fixed_factor *fix_factor;
+ struct clk_divider *divider;
void *reg;
int i = 0;
int flags, clkflags;
@@ -866,10 +872,9 @@ static void __init sunxi_divs_clk_setup(struct device_node *node,
return;
clks = kzalloc(SUNXI_DIVS_MAX_QTY * sizeof(struct clk *), GFP_KERNEL);
- if (!clks) {
- kfree(clk_data);
- return;
- }
+ if (!clks)
+ goto free_clkdata;
+
clk_data->clks = clks;
/* It's not a good idea to have automatic reparenting changing
@@ -881,19 +886,60 @@ static void __init sunxi_divs_clk_setup(struct device_node *node,
i, &clk_name) != 0)
break;
+ gate_hw = NULL;
+ rate_hw = NULL;
+ rate_ops = NULL;
+
+ /* If this leaf clock can be gated, create a gate */
+ if (data->div[i].gate) {
+ gate = kzalloc(sizeof(*gate), GFP_KERNEL);
+ if (!gate)
+ goto free_clks;
+
+ gate->reg = reg;
+ gate->bit_idx = data->div[i].gate;
+ gate->lock = &clk_lock;
+
+ gate_hw = &gate->hw;
+ }
+
+ /* Leaves can be fixed or configurable divisors */
if (data->div[i].fixed) {
- clks[i] = clk_register_fixed_factor(NULL, clk_name,
- parent, clkflags,
- 1, data->div[i].fixed);
+ fix_factor = kzalloc(sizeof(*fix_factor), GFP_KERNEL);
+ if (!fix_factor)
+ goto free_gate;
+
+ fix_factor->mult = 1;
+ fix_factor->div = data->div[i].fixed;
+
+ rate_hw = &fix_factor->hw;
+ rate_ops = &clk_fixed_factor_ops;
} else {
+ divider = kzalloc(sizeof(*divider), GFP_KERNEL);
+ if (!divider)
+ goto free_gate;
+
flags = data->div[i].pow ? CLK_DIVIDER_POWER_OF_TWO : 0;
- clks[i] = clk_register_divider_table(NULL, clk_name,
- parent, clkflags, reg,
- data->div[i].shift,
- SUNXI_DIVISOR_WIDTH, flags,
- data->div[i].table, &clk_lock);
+
+ divider->reg = reg;
+ divider->shift = data->div[i].shift;
+ divider->width = SUNXI_DIVISOR_WIDTH;
+ divider->flags = flags;
+ divider->lock = &clk_lock;
+ divider->table = data->div[i].table;
+
+ rate_hw = &divider->hw;
+ rate_ops = &clk_divider_ops;
}
+ /* Wrap the (potential) gate and the divisor on a composite
+ * clock to unify them */
+ clks[i] = clk_register_composite(NULL, clk_name, &parent, 1,
+ NULL, NULL,
+ rate_hw, rate_ops,
+ gate_hw, &clk_gate_ops,
+ clkflags);
+
WARN_ON(IS_ERR(clk_data->clks[i]));
clk_register_clkdev(clks[i], clk_name, NULL);
}
@@ -905,6 +951,15 @@ static void __init sunxi_divs_clk_setup(struct device_node *node,
clk_data->clk_num = i;
of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
+
+ return;
+
+free_gate:
+ kfree(gate);
+free_clks:
+ kfree(clks);
+free_clkdata:
+ kfree(clk_data);
}
--
1.8.5.1

View file

@ -1,74 +0,0 @@
From de7bfadd1022613ab2c7eeca124bb1e4a6f4c072 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Emilio=20L=C3=B3pez?= <emilio@elopez.com.ar>
Date: Thu, 5 Sep 2013 19:43:33 -0300
Subject: [PATCH] clk: composite: .determine_rate support
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
This commit adds .determine_rate support to the composite clock. It will
use the .determine_rate callback from the rate component if available,
and fall back on the mux component otherwise. This allows composite
clocks to enjoy the benefits of automatic clock reparenting.
Signed-off-by: Emilio López <emilio@elopez.com.ar>
---
drivers/clk/clk-composite.c | 28 ++++++++++++++++++++++++++++
1 file changed, 28 insertions(+)
diff --git a/drivers/clk/clk-composite.c b/drivers/clk/clk-composite.c
index a33f46f..753d0b7 100644
--- a/drivers/clk/clk-composite.c
+++ b/drivers/clk/clk-composite.c
@@ -55,6 +55,30 @@ static unsigned long clk_composite_recalc_rate(struct clk_hw *hw,
return rate_ops->recalc_rate(rate_hw, parent_rate);
}
+static long clk_composite_determine_rate(struct clk_hw *hw, unsigned long rate,
+ unsigned long *best_parent_rate,
+ struct clk **best_parent_p)
+{
+ struct clk_composite *composite = to_clk_composite(hw);
+ const struct clk_ops *rate_ops = composite->rate_ops;
+ const struct clk_ops *mux_ops = composite->mux_ops;
+ struct clk_hw *rate_hw = composite->rate_hw;
+ struct clk_hw *mux_hw = composite->mux_hw;
+
+ if (rate_hw && rate_ops && rate_ops->determine_rate) {
+ rate_hw->clk = hw->clk;
+ return rate_ops->determine_rate(rate_hw, rate, best_parent_rate,
+ best_parent_p);
+ } else if (mux_hw && mux_ops && mux_ops->determine_rate) {
+ mux_hw->clk = hw->clk;
+ return mux_ops->determine_rate(rate_hw, rate, best_parent_rate,
+ best_parent_p);
+ } else {
+ pr_err("clk: clk_composite_determine_rate function called, but no mux or rate callback set!\n");
+ return 0;
+ }
+}
+
static long clk_composite_round_rate(struct clk_hw *hw, unsigned long rate,
unsigned long *prate)
{
@@ -147,6 +171,8 @@ struct clk *clk_register_composite(struct device *dev, const char *name,
composite->mux_ops = mux_ops;
clk_composite_ops->get_parent = clk_composite_get_parent;
clk_composite_ops->set_parent = clk_composite_set_parent;
+ if (mux_ops->determine_rate)
+ clk_composite_ops->determine_rate = clk_composite_determine_rate;
}
if (rate_hw && rate_ops) {
@@ -170,6 +196,8 @@ struct clk *clk_register_composite(struct device *dev, const char *name,
composite->rate_hw = rate_hw;
composite->rate_ops = rate_ops;
clk_composite_ops->recalc_rate = clk_composite_recalc_rate;
+ if (rate_ops->determine_rate)
+ clk_composite_ops->determine_rate = clk_composite_determine_rate;
}
if (gate_hw && gate_ops) {
--
1.8.5.1

View file

@ -1,73 +0,0 @@
From 679e8db359d0c1994e88f3a4a2aa0697ce001ad4 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Emilio=20L=C3=B3pez?= <emilio@elopez.com.ar>
Date: Thu, 5 Sep 2013 19:52:41 -0300
Subject: [PATCH] clk: sunxi: factors: automatic reparenting support
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
This commit implements .determine_rate, so that our factor clocks can be
reparented when needed.
Signed-off-by: Emilio López <emilio@elopez.com.ar>
---
drivers/clk/sunxi/clk-factors.c | 36 ++++++++++++++++++++++++++++++++++++
1 file changed, 36 insertions(+)
diff --git a/drivers/clk/sunxi/clk-factors.c b/drivers/clk/sunxi/clk-factors.c
index 9e23264..3806d97 100644
--- a/drivers/clk/sunxi/clk-factors.c
+++ b/drivers/clk/sunxi/clk-factors.c
@@ -77,6 +77,41 @@ static long clk_factors_round_rate(struct clk_hw *hw, unsigned long rate,
return rate;
}
+static long clk_factors_determine_rate(struct clk_hw *hw, unsigned long rate,
+ unsigned long *best_parent_rate,
+ struct clk **best_parent_p)
+{
+ struct clk *clk = hw->clk, *parent, *best_parent = NULL;
+ int i, num_parents;
+ unsigned long parent_rate, best = 0, child_rate, best_child_rate = 0;
+
+ /* find the parent that can help provide the fastest rate <= rate */
+ num_parents = __clk_get_num_parents(clk);
+ for (i = 0; i < num_parents; i++) {
+ parent = clk_get_parent_by_index(clk, i);
+ if (!parent)
+ continue;
+ if (__clk_get_flags(clk) & CLK_SET_RATE_PARENT)
+ parent_rate = __clk_round_rate(parent, rate);
+ else
+ parent_rate = __clk_get_rate(parent);
+
+ child_rate = clk_factors_round_rate(hw, rate, &parent_rate);
+
+ if (child_rate <= rate && child_rate > best_child_rate) {
+ best_parent = parent;
+ best = parent_rate;
+ best_child_rate = child_rate;
+ }
+ }
+
+ if (best_parent)
+ *best_parent_p = best_parent;
+ *best_parent_rate = best;
+
+ return best_child_rate;
+}
+
static int clk_factors_set_rate(struct clk_hw *hw, unsigned long rate,
unsigned long parent_rate)
{
@@ -113,6 +148,7 @@ static int clk_factors_set_rate(struct clk_hw *hw, unsigned long rate,
}
const struct clk_ops clk_factors_ops = {
+ .determine_rate = clk_factors_determine_rate,
.recalc_rate = clk_factors_recalc_rate,
.round_rate = clk_factors_round_rate,
.set_rate = clk_factors_set_rate,
--
1.8.5.1

View file

@ -1,63 +0,0 @@
From 75d3fa72634a4943f0f03146916094b6f4908552 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Emilio=20L=C3=B3pez?= <emilio@elopez.com.ar>
Date: Sun, 8 Sep 2013 18:14:52 -0300
Subject: [PATCH] clk: sunxi: unify APB1 clock
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
This commit unifies the APB1 mux with the APB1 clock, using the new
factors infrastructure.
Signed-off-by: Emilio López <emilio@elopez.com.ar>
---
Documentation/devicetree/bindings/clock/sunxi.txt | 1 -
drivers/clk/sunxi/clk-sunxi.c | 6 +-----
2 files changed, 1 insertion(+), 6 deletions(-)
diff --git a/Documentation/devicetree/bindings/clock/sunxi.txt b/Documentation/devicetree/bindings/clock/sunxi.txt
index 46d8433..e840cb2 100644
--- a/Documentation/devicetree/bindings/clock/sunxi.txt
+++ b/Documentation/devicetree/bindings/clock/sunxi.txt
@@ -27,7 +27,6 @@ Required properties:
"allwinner,sun5i-a10s-apb0-gates-clk" - for the APB0 gates on A10s
"allwinner,sun7i-a20-apb0-gates-clk" - for the APB0 gates on A20
"allwinner,sun4i-apb1-clk" - for the APB1 clock
- "allwinner,sun4i-apb1-mux-clk" - for the APB1 clock muxing
"allwinner,sun4i-apb1-gates-clk" - for the APB1 gates on A10
"allwinner,sun5i-a13-apb1-gates-clk" - for the APB1 gates on A13
"allwinner,sun5i-a10s-apb1-gates-clk" - for the APB1 gates on A10s
diff --git a/drivers/clk/sunxi/clk-sunxi.c b/drivers/clk/sunxi/clk-sunxi.c
index 06c4f01..0ecaa18 100644
--- a/drivers/clk/sunxi/clk-sunxi.c
+++ b/drivers/clk/sunxi/clk-sunxi.c
@@ -400,6 +400,7 @@ struct factors_data {
};
static const struct factors_data sun4i_apb1_data __initconst = {
+ .mux = 24,
.table = &sun4i_apb1_config,
.getter = sun4i_get_apb1_factors,
};
@@ -511,10 +512,6 @@ struct mux_data {
.shift = 12,
};
-static const struct mux_data sun4i_apb1_mux_data __initconst = {
- .shift = 24,
-};
-
static void __init sunxi_mux_clk_setup(struct device_node *node,
struct mux_data *data)
{
@@ -869,7 +866,6 @@ static void __init sunxi_divs_clk_setup(struct device_node *node,
/* Matches for mux clocks */
static const struct of_device_id clk_mux_match[] __initconst = {
{.compatible = "allwinner,sun4i-cpu-clk", .data = &sun4i_cpu_mux_data,},
- {.compatible = "allwinner,sun4i-apb1-mux-clk", .data = &sun4i_apb1_mux_data,},
{.compatible = "allwinner,sun6i-a31-ahb1-mux-clk", .data = &sun6i_a31_ahb1_mux_data,},
{}
};
--
1.8.5.1

View file

@ -1,118 +0,0 @@
From f3443f6d43a69a520ae1e636d69a71c4a6bee21e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Emilio=20L=C3=B3pez?= <emilio@elopez.com.ar>
Date: Sun, 8 Sep 2013 18:12:28 -0300
Subject: [PATCH] ARM: sunxi: dt: unify APB1 clock
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
With the new factors infrastructure in place, we can unify apb1 and
apb1_mux as a single clock now.
Signed-off-by: Emilio López <emilio@elopez.com.ar>
---
arch/arm/boot/dts/sun4i-a10.dtsi | 9 +--------
arch/arm/boot/dts/sun5i-a10s.dtsi | 9 +--------
arch/arm/boot/dts/sun5i-a13.dtsi | 9 +--------
arch/arm/boot/dts/sun7i-a20.dtsi | 9 +--------
4 files changed, 4 insertions(+), 32 deletions(-)
diff --git a/arch/arm/boot/dts/sun4i-a10.dtsi b/arch/arm/boot/dts/sun4i-a10.dtsi
index 2828427e..4dccdb0 100644
--- a/arch/arm/boot/dts/sun4i-a10.dtsi
+++ b/arch/arm/boot/dts/sun4i-a10.dtsi
@@ -158,18 +158,11 @@
"apb0_ir1", "apb0_keypad";
};
- apb1_mux: apb1_mux@01c20058 {
- #clock-cells = <0>;
- compatible = "allwinner,sun4i-apb1-mux-clk";
- reg = <0x01c20058 0x4>;
- clocks = <&osc24M>, <&pll6 1>, <&osc32k>;
- };
-
apb1: apb1@01c20058 {
#clock-cells = <0>;
compatible = "allwinner,sun4i-apb1-clk";
reg = <0x01c20058 0x4>;
- clocks = <&apb1_mux>;
+ clocks = <&osc24M>, <&pll6 1>, <&osc32k>;
};
apb1_gates: apb1_gates@01c2006c {
diff --git a/arch/arm/boot/dts/sun5i-a10s.dtsi b/arch/arm/boot/dts/sun5i-a10s.dtsi
index 60bd3f7..9cb1b14 100644
--- a/arch/arm/boot/dts/sun5i-a10s.dtsi
+++ b/arch/arm/boot/dts/sun5i-a10s.dtsi
@@ -150,18 +150,11 @@
"apb0_ir", "apb0_keypad";
};
- apb1_mux: apb1_mux@01c20058 {
- #clock-cells = <0>;
- compatible = "allwinner,sun4i-apb1-mux-clk";
- reg = <0x01c20058 0x4>;
- clocks = <&osc24M>, <&pll6 1>, <&osc32k>;
- };
-
apb1: apb1@01c20058 {
#clock-cells = <0>;
compatible = "allwinner,sun4i-apb1-clk";
reg = <0x01c20058 0x4>;
- clocks = <&apb1_mux>;
+ clocks = <&osc24M>, <&pll6 1>, <&osc32k>;
};
apb1_gates: apb1_gates@01c2006c {
diff --git a/arch/arm/boot/dts/sun5i-a13.dtsi b/arch/arm/boot/dts/sun5i-a13.dtsi
index 3e616a0..6b74dd0 100644
--- a/arch/arm/boot/dts/sun5i-a13.dtsi
+++ b/arch/arm/boot/dts/sun5i-a13.dtsi
@@ -148,18 +148,11 @@
clock-output-names = "apb0_codec", "apb0_pio", "apb0_ir";
};
- apb1_mux: apb1_mux@01c20058 {
- #clock-cells = <0>;
- compatible = "allwinner,sun4i-apb1-mux-clk";
- reg = <0x01c20058 0x4>;
- clocks = <&osc24M>, <&pll6 1>, <&osc32k>;
- };
-
apb1: apb1@01c20058 {
#clock-cells = <0>;
compatible = "allwinner,sun4i-apb1-clk";
reg = <0x01c20058 0x4>;
- clocks = <&apb1_mux>;
+ clocks = <&osc24M>, <&pll6 1>, <&osc32k>;
};
apb1_gates: apb1_gates@01c2006c {
diff --git a/arch/arm/boot/dts/sun7i-a20.dtsi b/arch/arm/boot/dts/sun7i-a20.dtsi
index 0bf5d07..55d3e14 100644
--- a/arch/arm/boot/dts/sun7i-a20.dtsi
+++ b/arch/arm/boot/dts/sun7i-a20.dtsi
@@ -148,18 +148,11 @@
"apb0_iis2", "apb0_keypad";
};
- apb1_mux: apb1_mux@01c20058 {
- #clock-cells = <0>;
- compatible = "allwinner,sun4i-apb1-mux-clk";
- reg = <0x01c20058 0x4>;
- clocks = <&osc24M>, <&pll6 1>, <&osc32k>;
- };
-
apb1: apb1@01c20058 {
#clock-cells = <0>;
compatible = "allwinner,sun4i-apb1-clk";
reg = <0x01c20058 0x4>;
- clocks = <&apb1_mux>;
+ clocks = <&osc24M>, <&pll6 1>, <&osc32k>;
};
apb1_gates: apb1_gates@01c2006c {
--
1.8.5.1

View file

@ -1,102 +0,0 @@
From 147a46beeb49c6baabb85126d570f330a2ba7cad Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Emilio=20L=C3=B3pez?= <emilio@elopez.com.ar>
Date: Sat, 14 Sep 2013 20:48:40 -0300
Subject: [PATCH] clk: sunxi: Implement muxable AHB clock
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
sun5i and sun7i have a mux to change the AHB clock parent, this commit
adds support for it on the driver.
Signed-off-by: Emilio López <emilio@elopez.com.ar>
---
Documentation/devicetree/bindings/clock/sunxi.txt | 1 +
drivers/clk/sunxi/clk-sunxi.c | 37 +++++++++++++++++++++++
2 files changed, 38 insertions(+)
diff --git a/Documentation/devicetree/bindings/clock/sunxi.txt b/Documentation/devicetree/bindings/clock/sunxi.txt
index e840cb2..941bd93 100644
--- a/Documentation/devicetree/bindings/clock/sunxi.txt
+++ b/Documentation/devicetree/bindings/clock/sunxi.txt
@@ -15,6 +15,7 @@ Required properties:
"allwinner,sun4i-axi-clk" - for the AXI clock
"allwinner,sun4i-axi-gates-clk" - for the AXI gates
"allwinner,sun4i-ahb-clk" - for the AHB clock
+ "allwinner,sun5i-a13-ahb-clk" - for the AHB clock on A13
"allwinner,sun4i-ahb-gates-clk" - for the AHB gates on A10
"allwinner,sun5i-a13-ahb-gates-clk" - for the AHB gates on A13
"allwinner,sun5i-a10s-ahb-gates-clk" - for the AHB gates on A10s
diff --git a/drivers/clk/sunxi/clk-sunxi.c b/drivers/clk/sunxi/clk-sunxi.c
index 0ecaa18..360d705 100644
--- a/drivers/clk/sunxi/clk-sunxi.c
+++ b/drivers/clk/sunxi/clk-sunxi.c
@@ -240,7 +240,32 @@ static void sun4i_get_pll5_factors(u32 *freq, u32 parent_rate,
*n = DIV_ROUND_UP(div, (*k+1));
}
+/**
+ * sun5i_get_ahb_factors() - calculates p factor for AHB
+ * AHB rate is calculated as follows
+ * rate = parent_rate >> p
+ */
+static void sun5i_a13_get_ahb_factors(u32 *freq, u32 parent_rate,
+ u8 *n, u8 *k, u8 *m, u8 *p)
+{
+ u8 div;
+
+ /* This clock can only divide, so we will never achieve a higher
+ * rate than the parent's */
+ if (*freq > parent_rate)
+ *freq = parent_rate;
+
+ /* Normalize value to a parent multiple */
+ div = *freq / parent_rate;
+ *freq = parent_rate * div;
+
+ /* we were called to round the frequency, we can now return */
+ if (n == NULL)
+ return;
+
+ *p = div;
+}
/**
* sun4i_get_apb1_factors() - calculates m, p factors for APB1
@@ -366,6 +391,11 @@ struct factors_data {
.kwidth = 2,
};
+static struct clk_factors_config sun5i_a13_ahb_config = {
+ .pshift = 4,
+ .pwidth = 2,
+};
+
static struct clk_factors_config sun4i_apb1_config = {
.mshift = 0,
.mwidth = 5,
@@ -399,6 +429,12 @@ struct factors_data {
.getter = sun4i_get_pll5_factors,
};
+static const struct factors_data sun5i_a13_ahb_data __initconst = {
+ .mux = 6,
+ .table = &sun5i_a13_ahb_config,
+ .getter = sun5i_a13_get_ahb_factors,
+};
+
static const struct factors_data sun4i_apb1_data __initconst = {
.mux = 24,
.table = &sun4i_apb1_config,
@@ -842,6 +878,7 @@ static void __init sunxi_divs_clk_setup(struct device_node *node,
static const struct of_device_id clk_factors_match[] __initconst = {
{.compatible = "allwinner,sun4i-pll1-clk", .data = &sun4i_pll1_data,},
{.compatible = "allwinner,sun6i-a31-pll1-clk", .data = &sun6i_a31_pll1_data,},
+ {.compatible = "allwinner,sun5i-a13-ahb-clk", .data = &sun5i_a13_ahb_data,},
{.compatible = "allwinner,sun4i-apb1-clk", .data = &sun4i_apb1_data,},
{.compatible = "allwinner,sun4i-mod0-clk", .data = &sun4i_mod0_data,},
{}
--
1.8.5.1

View file

@ -1,69 +0,0 @@
From 051f43def45e53d93b9998728e398a68c4948114 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Emilio=20L=C3=B3pez?= <emilio@elopez.com.ar>
Date: Sat, 14 Sep 2013 20:44:03 -0300
Subject: [PATCH] ARM: sunxi: dt: Update AHB clock to be muxable on sun[57]i
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
sun5i and sun7i have a mux to select the parent clock for AHB. This
commit implements the required changes on the device trees.
Signed-off-by: Emilio López <emilio@elopez.com.ar>
---
arch/arm/boot/dts/sun5i-a10s.dtsi | 4 ++--
arch/arm/boot/dts/sun5i-a13.dtsi | 4 ++--
arch/arm/boot/dts/sun7i-a20.dtsi | 4 ++--
3 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/arch/arm/boot/dts/sun5i-a10s.dtsi b/arch/arm/boot/dts/sun5i-a10s.dtsi
index 9cb1b14..83e183c 100644
--- a/arch/arm/boot/dts/sun5i-a10s.dtsi
+++ b/arch/arm/boot/dts/sun5i-a10s.dtsi
@@ -115,9 +115,9 @@
ahb: ahb@01c20054 {
#clock-cells = <0>;
- compatible = "allwinner,sun4i-ahb-clk";
+ compatible = "allwinner,sun5i-a13-ahb-clk";
reg = <0x01c20054 0x4>;
- clocks = <&axi>;
+ clocks = <&axi>, <&cpu>, <&pll6 1>;
};
ahb_gates: ahb_gates@01c20060 {
diff --git a/arch/arm/boot/dts/sun5i-a13.dtsi b/arch/arm/boot/dts/sun5i-a13.dtsi
index 6b74dd0..0bb4300 100644
--- a/arch/arm/boot/dts/sun5i-a13.dtsi
+++ b/arch/arm/boot/dts/sun5i-a13.dtsi
@@ -115,9 +115,9 @@
ahb: ahb@01c20054 {
#clock-cells = <0>;
- compatible = "allwinner,sun4i-ahb-clk";
+ compatible = "allwinner,sun5i-a13-ahb-clk";
reg = <0x01c20054 0x4>;
- clocks = <&axi>;
+ clocks = <&axi>, <&cpu>, <&pll6 1>;
};
ahb_gates: ahb_gates@01c20060 {
diff --git a/arch/arm/boot/dts/sun7i-a20.dtsi b/arch/arm/boot/dts/sun7i-a20.dtsi
index 55d3e14..63757c5 100644
--- a/arch/arm/boot/dts/sun7i-a20.dtsi
+++ b/arch/arm/boot/dts/sun7i-a20.dtsi
@@ -105,9 +105,9 @@
ahb: ahb@01c20054 {
#clock-cells = <0>;
- compatible = "allwinner,sun4i-ahb-clk";
+ compatible = "allwinner,sun5i-a13-ahb-clk";
reg = <0x01c20054 0x4>;
- clocks = <&axi>;
+ clocks = <&axi>, <&pll6 1>, <&pll6 2>;
};
ahb_gates: ahb_gates@01c20060 {
--
1.8.5.1

View file

@ -1,108 +0,0 @@
From be0804513a506de96925f9ed1aa8dc1facd4c180 Mon Sep 17 00:00:00 2001
From: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
Date: Fri, 6 Sep 2013 14:59:57 +0200
Subject: [PATCH] clk: sunxi: declare OF clock provider
Common clock framework allows to register clock providers to get called
on of_clk_init() by using CLK_OF_DECLARE. This converts sunxi clock
providers to make use of it and get rid of the mach specific clk init
call. As sunxi has a bunch of independent clk provider nodes, we hook
current clock init to board compatible to make it called once.
Signed-off-by: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
Acked-by: Maxime Ripard <maxime.ripard@free-electrons.com>
Acked-by: Mike Turquette <mturquette@linaro.org>
---
arch/arm/mach-sunxi/sunxi.c | 4 +---
drivers/clk/sunxi/clk-sunxi.c | 11 ++++++-----
include/linux/clk/sunxi.h | 22 ----------------------
3 files changed, 7 insertions(+), 30 deletions(-)
delete mode 100644 include/linux/clk/sunxi.h
diff --git a/arch/arm/mach-sunxi/sunxi.c b/arch/arm/mach-sunxi/sunxi.c
index e79fb34..e5a6975 100644
--- a/arch/arm/mach-sunxi/sunxi.c
+++ b/arch/arm/mach-sunxi/sunxi.c
@@ -20,8 +20,6 @@
#include <linux/io.h>
#include <linux/reboot.h>
-#include <linux/clk/sunxi.h>
-
#include <asm/mach/arch.h>
#include <asm/mach/map.h>
#include <asm/system_misc.h>
@@ -118,7 +116,7 @@ static void sunxi_setup_restart(void)
static void __init sunxi_timer_init(void)
{
- sunxi_init_clocks();
+ of_clk_init(NULL);
clocksource_of_init();
}
diff --git a/drivers/clk/sunxi/clk-sunxi.c b/drivers/clk/sunxi/clk-sunxi.c
index 34ee69f..9bbd035 100644
--- a/drivers/clk/sunxi/clk-sunxi.c
+++ b/drivers/clk/sunxi/clk-sunxi.c
@@ -16,7 +16,6 @@
#include <linux/clk-provider.h>
#include <linux/clkdev.h>
-#include <linux/clk/sunxi.h>
#include <linux/of.h>
#include <linux/of_address.h>
@@ -617,11 +616,8 @@ static void __init of_sunxi_table_clock_setup(const struct of_device_id *clk_mat
}
}
-void __init sunxi_init_clocks(void)
+static void __init sunxi_init_clocks(struct device_node *np)
{
- /* Register all the simple and basic clocks on DT */
- of_clk_init(NULL);
-
/* Register factor clocks */
of_sunxi_table_clock_setup(clk_factors_match, sunxi_factors_clk_setup);
@@ -634,3 +630,8 @@ void __init sunxi_init_clocks(void)
/* Register gate clocks */
of_sunxi_table_clock_setup(clk_gates_match, sunxi_gates_clk_setup);
}
+CLK_OF_DECLARE(sun4i_a10_clk_init, "allwinner,sun4i-a10", sunxi_init_clocks);
+CLK_OF_DECLARE(sun5i_a10s_clk_init, "allwinner,sun5i-a10s", sunxi_init_clocks);
+CLK_OF_DECLARE(sun5i_a13_clk_init, "allwinner,sun5i-a13", sunxi_init_clocks);
+CLK_OF_DECLARE(sun6i_a31_clk_init, "allwinner,sun6i-a31", sunxi_init_clocks);
+CLK_OF_DECLARE(sun7i_a20_clk_init, "allwinner,sun7i-a20", sunxi_init_clocks);
diff --git a/include/linux/clk/sunxi.h b/include/linux/clk/sunxi.h
deleted file mode 100644
index e074fdd..0000000
--- a/include/linux/clk/sunxi.h
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * Copyright 2012 Maxime Ripard
- *
- * Maxime Ripard <maxime.ripard@free-electrons.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- */
-
-#ifndef __LINUX_CLK_SUNXI_H_
-#define __LINUX_CLK_SUNXI_H_
-
-void __init sunxi_init_clocks(void);
-
-#endif
--
1.8.5.1

View file

@ -1,67 +0,0 @@
From d1bcc34ce6cb7601ce27f3090aee0e8a3e8076e3 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Emilio=20L=C3=B3pez?= <emilio@elopez.com.ar>
Date: Sat, 14 Sep 2013 20:54:42 -0300
Subject: [PATCH] clk: sunxi: protect core clocks from accidental shutdown
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Some important clocks may get disabled as a side effect of another clock
being disabled, because they have no consumers. This patch implements a
mechanism so those clocks can be claimed by the driver and therefore
remain enabled at all times.
Signed-off-by: Emilio López <emilio@elopez.com.ar>
---
drivers/clk/sunxi/clk-sunxi.c | 28 ++++++++++++++++++++++++++++
1 file changed, 28 insertions(+)
diff --git a/drivers/clk/sunxi/clk-sunxi.c b/drivers/clk/sunxi/clk-sunxi.c
index 9bbd035..8fc1375 100644
--- a/drivers/clk/sunxi/clk-sunxi.c
+++ b/drivers/clk/sunxi/clk-sunxi.c
@@ -616,6 +616,31 @@ static void __init of_sunxi_table_clock_setup(const struct of_device_id *clk_mat
}
}
+/**
+ * System clock protection
+ *
+ * By enabling these critical clocks, we prevent their accidental gating
+ * by the framework
+ */
+static void __init sunxi_clock_protect(void)
+{
+ struct clk *clk;
+
+ /* memory bus clock - sun5i+ */
+ clk = clk_get(NULL, "mbus");
+ if (!IS_ERR(clk)) {
+ clk_prepare_enable(clk);
+ clk_put(clk);
+ }
+
+ /* DDR clock - sun4i+ */
+ clk = clk_get(NULL, "pll5_ddr");
+ if (!IS_ERR(clk)) {
+ clk_prepare_enable(clk);
+ clk_put(clk);
+ }
+}
+
static void __init sunxi_init_clocks(struct device_node *np)
{
/* Register factor clocks */
@@ -629,6 +654,9 @@ static void __init sunxi_init_clocks(struct device_node *np)
/* Register gate clocks */
of_sunxi_table_clock_setup(clk_gates_match, sunxi_gates_clk_setup);
+
+ /* Enable core system clocks */
+ sunxi_clock_protect();
}
CLK_OF_DECLARE(sun4i_a10_clk_init, "allwinner,sun4i-a10", sunxi_init_clocks);
CLK_OF_DECLARE(sun5i_a10s_clk_init, "allwinner,sun5i-a10s", sunxi_init_clocks);
--
1.8.5.1

View file

@ -1,117 +0,0 @@
From 52e86b37b1d3f7c02938def3a036e0bb0f723964 Mon Sep 17 00:00:00 2001
From: Hans de Goede <hdegoede@redhat.com>
Date: Sun, 15 Dec 2013 20:23:36 +0100
Subject: [PATCH] ARM: dts: sun5i: Add new sun5i-a13-olinuxino-micro board
The A13-OLinuXino-MICRO is a small dev-board with the Allwinner A13 SoC:
https://www.olimex.com/Products/OLinuXino/A13/A13-OLinuXino-MICRO/
Features:
A13 Cortex A8 processor at 1GHz, 3D Mali400 GPU
256 MB RAM (128Mbit x 16)
5VDC input power supply with own ICs, noise immune design
1 USB host
1 USB OTG which can power the board
SD-card connector for booting the Linux image
VGA video output
LCD signals available on connector so you still can use LCD if you disable VGA/HDMI
Audio output
Microphone input pads (no connector)
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
---
arch/arm/boot/dts/Makefile | 1 +
arch/arm/boot/dts/sun5i-a13-olinuxino-micro.dts | 68 +++++++++++++++++++++++++
2 files changed, 69 insertions(+)
create mode 100644 arch/arm/boot/dts/sun5i-a13-olinuxino-micro.dts
diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
index d57c1a6..b663ed7 100644
--- a/arch/arm/boot/dts/Makefile
+++ b/arch/arm/boot/dts/Makefile
@@ -255,6 +255,7 @@ dtb-$(CONFIG_ARCH_SUNXI) += \
sun4i-a10-hackberry.dtb \
sun5i-a10s-olinuxino-micro.dtb \
sun5i-a13-olinuxino.dtb \
+ sun5i-a13-olinuxino-micro.dtb \
sun6i-a31-colombus.dtb \
sun7i-a20-cubieboard2.dtb \
sun7i-a20-cubietruck.dtb \
diff --git a/arch/arm/boot/dts/sun5i-a13-olinuxino-micro.dts b/arch/arm/boot/dts/sun5i-a13-olinuxino-micro.dts
new file mode 100644
index 0000000..fe2ce0a
--- /dev/null
+++ b/arch/arm/boot/dts/sun5i-a13-olinuxino-micro.dts
@@ -0,0 +1,68 @@
+/*
+ * Copyright 2012 Maxime Ripard
+ * Copyright 2013 Hans de Goede <hdegoede@redhat.com>
+ *
+ * Maxime Ripard <maxime.ripard@free-electrons.com>
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/dts-v1/;
+/include/ "sun5i-a13.dtsi"
+
+/ {
+ model = "Olimex A13-Olinuxino Micro";
+ compatible = "olimex,a13-olinuxino-micro", "allwinner,sun5i-a13";
+
+ soc@01c00000 {
+ pinctrl@01c20800 {
+ led_pins_olinuxinom: led_pins@0 {
+ allwinner,pins = "PG9";
+ allwinner,function = "gpio_out";
+ allwinner,drive = <1>;
+ allwinner,pull = <0>;
+ };
+ };
+
+ uart1: serial@01c28400 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart1_pins_b>;
+ status = "okay";
+ };
+
+ i2c0: i2c@01c2ac00 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c0_pins_a>;
+ status = "okay";
+ };
+
+ i2c1: i2c@01c2b000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c1_pins_a>;
+ status = "okay";
+ };
+
+ i2c2: i2c@01c2b400 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c2_pins_a>;
+ status = "okay";
+ };
+ };
+
+ leds {
+ compatible = "gpio-leds";
+ pinctrl-names = "default";
+ pinctrl-0 = <&led_pins_olinuxinom>;
+
+ power {
+ label = "a13-olinuxino-micro:green:power";
+ gpios = <&pio 6 9 0>;
+ default-state = "on";
+ };
+ };
+};
--
1.8.5.1

View file

@ -1,73 +0,0 @@
From 220d6c860e0c7853aea6509ea2b5a44463c9af8b Mon Sep 17 00:00:00 2001
From: Maxime Ripard <maxime.ripard@free-electrons.com>
Date: Sat, 31 Aug 2013 23:07:24 +0200
Subject: [PATCH] ARM: sun7i: Enable the I2C controllers
The Allwinner A20 shares the same I2C controller than the one that could
be found on earlier SoCs from Allwinner. There is only a few more of
these controllers. Add all of them in the DTSI.
Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
---
arch/arm/boot/dts/sun7i-a20.dtsi | 45 ++++++++++++++++++++++++++++++++++++++++
1 file changed, 45 insertions(+)
diff --git a/arch/arm/boot/dts/sun7i-a20.dtsi b/arch/arm/boot/dts/sun7i-a20.dtsi
index 2e39ed9..0d0ee15 100644
--- a/arch/arm/boot/dts/sun7i-a20.dtsi
+++ b/arch/arm/boot/dts/sun7i-a20.dtsi
@@ -340,6 +340,51 @@
status = "disabled";
};
+ i2c0: i2c@01c2ac00 {
+ compatible = "allwinner,sun4i-i2c";
+ reg = <0x01c2ac00 0x400>;
+ interrupts = <0 7 1>;
+ clocks = <&apb1_gates 0>;
+ clock-frequency = <100000>;
+ status = "disabled";
+ };
+
+ i2c1: i2c@01c2b000 {
+ compatible = "allwinner,sun4i-i2c";
+ reg = <0x01c2b000 0x400>;
+ interrupts = <0 8 1>;
+ clocks = <&apb1_gates 1>;
+ clock-frequency = <100000>;
+ status = "disabled";
+ };
+
+ i2c2: i2c@01c2b400 {
+ compatible = "allwinner,sun4i-i2c";
+ reg = <0x01c2b400 0x400>;
+ interrupts = <0 9 1>;
+ clocks = <&apb1_gates 2>;
+ clock-frequency = <100000>;
+ status = "disabled";
+ };
+
+ i2c3: i2c@01c2b800 {
+ compatible = "allwinner,sun4i-i2c";
+ reg = <0x01c2b800 0x400>;
+ interrupts = <0 88 1>;
+ clocks = <&apb1_gates 3>;
+ clock-frequency = <100000>;
+ status = "disabled";
+ };
+
+ i2c4: i2c@01c2bc00 {
+ compatible = "allwinner,sun4i-i2c";
+ reg = <0x01c2bc00 0x400>;
+ interrupts = <0 89 1>;
+ clocks = <&apb1_gates 15>;
+ clock-frequency = <100000>;
+ status = "disabled";
+ };
+
gic: interrupt-controller@01c81000 {
compatible = "arm,cortex-a7-gic", "arm,cortex-a15-gic";
reg = <0x01c81000 0x1000>,
--
1.8.4

View file

@ -1,49 +0,0 @@
From 1baebecc2892567373f5f9c3650d21496125af18 Mon Sep 17 00:00:00 2001
From: Maxime Ripard <maxime.ripard@free-electrons.com>
Date: Sat, 31 Aug 2013 23:08:49 +0200
Subject: [PATCH] ARM: sun7i: Add the pin muxing options for the I2C
controllers
The A20 boards we currently have share the same pins for the i2c
controllers they share. Add them to the DTSI.
Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
---
arch/arm/boot/dts/sun7i-a20.dtsi | 21 +++++++++++++++++++++
1 file changed, 21 insertions(+)
diff --git a/arch/arm/boot/dts/sun7i-a20.dtsi b/arch/arm/boot/dts/sun7i-a20.dtsi
index 0d0ee15..a6cd039 100644
--- a/arch/arm/boot/dts/sun7i-a20.dtsi
+++ b/arch/arm/boot/dts/sun7i-a20.dtsi
@@ -226,6 +226,27 @@
allwinner,pull = <0>;
};
+ i2c0_pins_a: i2c0@0 {
+ allwinner,pins = "PB0", "PB1";
+ allwinner,function = "i2c0";
+ allwinner,drive = <0>;
+ allwinner,pull = <0>;
+ };
+
+ i2c1_pins_a: i2c1@0 {
+ allwinner,pins = "PB18", "PB19";
+ allwinner,function = "i2c1";
+ allwinner,drive = <0>;
+ allwinner,pull = <0>;
+ };
+
+ i2c2_pins_a: i2c2@0 {
+ allwinner,pins = "PB20", "PB21";
+ allwinner,function = "i2c2";
+ allwinner,drive = <0>;
+ allwinner,pull = <0>;
+ };
+
emac_pins_a: emac0@0 {
allwinner,pins = "PA0", "PA1", "PA2",
"PA3", "PA4", "PA5", "PA6",
--
1.8.4

View file

@ -1,45 +0,0 @@
From 45cfefedb2886fac4a7f18c1720310ea9792ea4c Mon Sep 17 00:00:00 2001
From: Maxime Ripard <maxime.ripard@free-electrons.com>
Date: Sat, 31 Aug 2013 23:14:19 +0200
Subject: [PATCH] ARM: sun7i: olinuxino-micro: Enable the I2C controllers
The A20-olinuxino-micro uses the first three I2C controllers found on
the A20. Enable them in the DT.
Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
---
arch/arm/boot/dts/sun7i-a20-olinuxino-micro.dts | 18 ++++++++++++++++++
1 file changed, 18 insertions(+)
diff --git a/arch/arm/boot/dts/sun7i-a20-olinuxino-micro.dts b/arch/arm/boot/dts/sun7i-a20-olinuxino-micro.dts
index 9e77855..ead3013 100644
--- a/arch/arm/boot/dts/sun7i-a20-olinuxino-micro.dts
+++ b/arch/arm/boot/dts/sun7i-a20-olinuxino-micro.dts
@@ -60,6 +60,24 @@
pinctrl-0 = <&uart7_pins_a>;
status = "okay";
};
+
+ i2c0: i2c@01c2ac00 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c0_pins_a>;
+ status = "okay";
+ };
+
+ i2c1: i2c@01c2b000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c1_pins_a>;
+ status = "okay";
+ };
+
+ i2c2: i2c@01c2b400 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c2_pins_a>;
+ status = "okay";
+ };
};
leds {
--
1.8.4

View file

@ -1,39 +0,0 @@
From ce0106c5bbf689949c752b2a389ee82721c0e5d6 Mon Sep 17 00:00:00 2001
From: Maxime Ripard <maxime.ripard@free-electrons.com>
Date: Sat, 31 Aug 2013 23:12:58 +0200
Subject: [PATCH] ARM: sun7i: cubieboard2: Enable the I2C controllers
The Cubieboard2 uses both the i2c0 and i2c1 controllers. Enable them in
the DT.
Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
---
arch/arm/boot/dts/sun7i-a20-cubieboard2.dts | 12 ++++++++++++
1 file changed, 12 insertions(+)
diff --git a/arch/arm/boot/dts/sun7i-a20-cubieboard2.dts b/arch/arm/boot/dts/sun7i-a20-cubieboard2.dts
index 15e625e..5c51cb8 100644
--- a/arch/arm/boot/dts/sun7i-a20-cubieboard2.dts
+++ b/arch/arm/boot/dts/sun7i-a20-cubieboard2.dts
@@ -48,6 +48,18 @@
pinctrl-0 = <&uart0_pins_a>;
status = "okay";
};
+
+ i2c0: i2c@01c2ac00 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c0_pins_a>;
+ status = "okay";
+ };
+
+ i2c1: i2c@01c2b000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c1_pins_a>;
+ status = "okay";
+ };
};
leds {
--
1.8.5.1

View file

@ -1,35 +0,0 @@
From b788beda4db21ac28ae302f0323cffb75e578cac Mon Sep 17 00:00:00 2001
From: Maxime Ripard <maxime.ripard@free-electrons.com>
Date: Tue, 24 Sep 2013 11:09:19 +0300
Subject: [PATCH] ARM: sunxi: Order Kconfig options alphabetically
Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
---
arch/arm/mach-sunxi/Kconfig | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/arch/arm/mach-sunxi/Kconfig b/arch/arm/mach-sunxi/Kconfig
index 3ab2f65..c9e72c8 100644
--- a/arch/arm/mach-sunxi/Kconfig
+++ b/arch/arm/mach-sunxi/Kconfig
@@ -1,14 +1,14 @@
config ARCH_SUNXI
bool "Allwinner A1X SOCs" if ARCH_MULTI_V7
select ARCH_REQUIRE_GPIOLIB
+ select ARM_GIC
select CLKSRC_MMIO
select CLKSRC_OF
select COMMON_CLK
select GENERIC_CLOCKEVENTS
select GENERIC_IRQ_CHIP
+ select HAVE_SMP
select PINCTRL
+ select PINCTRL_SUNXI
select SPARSE_IRQ
select SUN4I_TIMER
- select PINCTRL_SUNXI
- select ARM_GIC
- select HAVE_SMP
--
1.8.5.1

View file

@ -1,297 +0,0 @@
From 3bf30f6381f9287eb99ce096bf2fa327a69c8a71 Mon Sep 17 00:00:00 2001
From: Maxime Ripard <maxime.ripard@free-electrons.com>
Date: Thu, 7 Nov 2013 12:01:48 +0100
Subject: [PATCH] clocksource: Add Allwinner SoCs HS timers driver
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Most of the Allwinner SoCs (at this time, all but the A10) also have a
High Speed timers that are not using the 24MHz oscillator as a source
but rather the AHB clock running much faster.
The IP is slightly different between the A10s/A13 and the one used in
the A20/A31, since the latter have 4 timers available, while the former
have only 2 of them.
[dlezcano] : Fixed conflict with b788beda "Order Kconfig options
alphabetically"
Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
Tested-by: Emilio López <emilio@elopez.com.ar>
Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
---
.../bindings/timer/allwinner,sun5i-a13-hstimer.txt | 22 +++
arch/arm/mach-sunxi/Kconfig | 1 +
drivers/clocksource/Kconfig | 4 +
drivers/clocksource/Makefile | 1 +
drivers/clocksource/timer-sun5i.c | 192 +++++++++++++++++++++
5 files changed, 220 insertions(+)
create mode 100644 Documentation/devicetree/bindings/timer/allwinner,sun5i-a13-hstimer.txt
create mode 100644 drivers/clocksource/timer-sun5i.c
diff --git a/Documentation/devicetree/bindings/timer/allwinner,sun5i-a13-hstimer.txt b/Documentation/devicetree/bindings/timer/allwinner,sun5i-a13-hstimer.txt
new file mode 100644
index 0000000..7c26154
--- /dev/null
+++ b/Documentation/devicetree/bindings/timer/allwinner,sun5i-a13-hstimer.txt
@@ -0,0 +1,22 @@
+Allwinner SoCs High Speed Timer Controller
+
+Required properties:
+
+- compatible : should be "allwinner,sun5i-a13-hstimer" or
+ "allwinner,sun7i-a20-hstimer"
+- reg : Specifies base physical address and size of the registers.
+- interrupts : The interrupts of these timers (2 for the sun5i IP, 4 for the sun7i
+ one)
+- clocks: phandle to the source clock (usually the AHB clock)
+
+Example:
+
+timer@01c60000 {
+ compatible = "allwinner,sun7i-a20-hstimer";
+ reg = <0x01c60000 0x1000>;
+ interrupts = <0 51 1>,
+ <0 52 1>,
+ <0 53 1>,
+ <0 54 1>;
+ clocks = <&ahb1_gates 19>;
+};
diff --git a/arch/arm/mach-sunxi/Kconfig b/arch/arm/mach-sunxi/Kconfig
index e3457b9..547004c 100644
--- a/arch/arm/mach-sunxi/Kconfig
+++ b/arch/arm/mach-sunxi/Kconfig
@@ -13,3 +13,4 @@ config ARCH_SUNXI
select PINCTRL_SUNXI
select SPARSE_IRQ
select SUN4I_TIMER
+ select SUN5I_HSTIMER
diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig
index 634c4d6..cd6950f 100644
--- a/drivers/clocksource/Kconfig
+++ b/drivers/clocksource/Kconfig
@@ -37,6 +37,10 @@ config SUN4I_TIMER
select CLKSRC_MMIO
bool
+config SUN5I_HSTIMER
+ select CLKSRC_MMIO
+ bool
+
config VT8500_TIMER
bool
diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile
index 33621ef..358358d 100644
--- a/drivers/clocksource/Makefile
+++ b/drivers/clocksource/Makefile
@@ -22,6 +22,7 @@ obj-$(CONFIG_ARCH_MOXART) += moxart_timer.o
obj-$(CONFIG_ARCH_MXS) += mxs_timer.o
obj-$(CONFIG_ARCH_PRIMA2) += timer-prima2.o
obj-$(CONFIG_SUN4I_TIMER) += sun4i_timer.o
+obj-$(CONFIG_SUN5I_HSTIMER) += timer-sun5i.o
obj-$(CONFIG_ARCH_TEGRA) += tegra20_timer.o
obj-$(CONFIG_VT8500_TIMER) += vt8500_timer.o
obj-$(CONFIG_ARCH_NSPIRE) += zevio-timer.o
diff --git a/drivers/clocksource/timer-sun5i.c b/drivers/clocksource/timer-sun5i.c
new file mode 100644
index 0000000..bddc522
--- /dev/null
+++ b/drivers/clocksource/timer-sun5i.c
@@ -0,0 +1,192 @@
+/*
+ * Allwinner SoCs hstimer driver.
+ *
+ * Copyright (C) 2013 Maxime Ripard
+ *
+ * Maxime Ripard <maxime.ripard@free-electrons.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/clk.h>
+#include <linux/clockchips.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/irqreturn.h>
+#include <linux/sched_clock.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+
+#define TIMER_IRQ_EN_REG 0x00
+#define TIMER_IRQ_EN(val) BIT(val)
+#define TIMER_IRQ_ST_REG 0x04
+#define TIMER_CTL_REG(val) (0x20 * (val) + 0x10)
+#define TIMER_CTL_ENABLE BIT(0)
+#define TIMER_CTL_RELOAD BIT(1)
+#define TIMER_CTL_CLK_PRES(val) (((val) & 0x7) << 4)
+#define TIMER_CTL_ONESHOT BIT(7)
+#define TIMER_INTVAL_LO_REG(val) (0x20 * (val) + 0x14)
+#define TIMER_INTVAL_HI_REG(val) (0x20 * (val) + 0x18)
+#define TIMER_CNTVAL_LO_REG(val) (0x20 * (val) + 0x1c)
+#define TIMER_CNTVAL_HI_REG(val) (0x20 * (val) + 0x20)
+
+#define TIMER_SYNC_TICKS 3
+
+static void __iomem *timer_base;
+static u32 ticks_per_jiffy;
+
+/*
+ * When we disable a timer, we need to wait at least for 2 cycles of
+ * the timer source clock. We will use for that the clocksource timer
+ * that is already setup and runs at the same frequency than the other
+ * timers, and we never will be disabled.
+ */
+static void sun5i_clkevt_sync(void)
+{
+ u32 old = readl(timer_base + TIMER_CNTVAL_LO_REG(1));
+
+ while ((old - readl(timer_base + TIMER_CNTVAL_LO_REG(1))) < TIMER_SYNC_TICKS)
+ cpu_relax();
+}
+
+static void sun5i_clkevt_time_stop(u8 timer)
+{
+ u32 val = readl(timer_base + TIMER_CTL_REG(timer));
+ writel(val & ~TIMER_CTL_ENABLE, timer_base + TIMER_CTL_REG(timer));
+
+ sun5i_clkevt_sync();
+}
+
+static void sun5i_clkevt_time_setup(u8 timer, u32 delay)
+{
+ writel(delay, timer_base + TIMER_INTVAL_LO_REG(timer));
+}
+
+static void sun5i_clkevt_time_start(u8 timer, bool periodic)
+{
+ u32 val = readl(timer_base + TIMER_CTL_REG(timer));
+
+ if (periodic)
+ val &= ~TIMER_CTL_ONESHOT;
+ else
+ val |= TIMER_CTL_ONESHOT;
+
+ writel(val | TIMER_CTL_ENABLE | TIMER_CTL_RELOAD,
+ timer_base + TIMER_CTL_REG(timer));
+}
+
+static void sun5i_clkevt_mode(enum clock_event_mode mode,
+ struct clock_event_device *clk)
+{
+ switch (mode) {
+ case CLOCK_EVT_MODE_PERIODIC:
+ sun5i_clkevt_time_stop(0);
+ sun5i_clkevt_time_setup(0, ticks_per_jiffy);
+ sun5i_clkevt_time_start(0, true);
+ break;
+ case CLOCK_EVT_MODE_ONESHOT:
+ sun5i_clkevt_time_stop(0);
+ sun5i_clkevt_time_start(0, false);
+ break;
+ case CLOCK_EVT_MODE_UNUSED:
+ case CLOCK_EVT_MODE_SHUTDOWN:
+ default:
+ sun5i_clkevt_time_stop(0);
+ break;
+ }
+}
+
+static int sun5i_clkevt_next_event(unsigned long evt,
+ struct clock_event_device *unused)
+{
+ sun5i_clkevt_time_stop(0);
+ sun5i_clkevt_time_setup(0, evt - TIMER_SYNC_TICKS);
+ sun5i_clkevt_time_start(0, false);
+
+ return 0;
+}
+
+static struct clock_event_device sun5i_clockevent = {
+ .name = "sun5i_tick",
+ .rating = 340,
+ .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
+ .set_mode = sun5i_clkevt_mode,
+ .set_next_event = sun5i_clkevt_next_event,
+};
+
+
+static irqreturn_t sun5i_timer_interrupt(int irq, void *dev_id)
+{
+ struct clock_event_device *evt = (struct clock_event_device *)dev_id;
+
+ writel(0x1, timer_base + TIMER_IRQ_ST_REG);
+ evt->event_handler(evt);
+
+ return IRQ_HANDLED;
+}
+
+static struct irqaction sun5i_timer_irq = {
+ .name = "sun5i_timer0",
+ .flags = IRQF_TIMER | IRQF_IRQPOLL,
+ .handler = sun5i_timer_interrupt,
+ .dev_id = &sun5i_clockevent,
+};
+
+static u32 sun5i_timer_sched_read(void)
+{
+ return ~readl(timer_base + TIMER_CNTVAL_LO_REG(1));
+}
+
+static void __init sun5i_timer_init(struct device_node *node)
+{
+ unsigned long rate;
+ struct clk *clk;
+ int ret, irq;
+ u32 val;
+
+ timer_base = of_iomap(node, 0);
+ if (!timer_base)
+ panic("Can't map registers");
+
+ irq = irq_of_parse_and_map(node, 0);
+ if (irq <= 0)
+ panic("Can't parse IRQ");
+
+ clk = of_clk_get(node, 0);
+ if (IS_ERR(clk))
+ panic("Can't get timer clock");
+ clk_prepare_enable(clk);
+ rate = clk_get_rate(clk);
+
+ writel(~0, timer_base + TIMER_INTVAL_LO_REG(1));
+ writel(TIMER_CTL_ENABLE | TIMER_CTL_RELOAD,
+ timer_base + TIMER_CTL_REG(1));
+
+ setup_sched_clock(sun5i_timer_sched_read, 32, rate);
+ clocksource_mmio_init(timer_base + TIMER_CNTVAL_LO_REG(1), node->name,
+ rate, 340, 32, clocksource_mmio_readl_down);
+
+ ticks_per_jiffy = DIV_ROUND_UP(rate, HZ);
+
+ ret = setup_irq(irq, &sun5i_timer_irq);
+ if (ret)
+ pr_warn("failed to setup irq %d\n", irq);
+
+ /* Enable timer0 interrupt */
+ val = readl(timer_base + TIMER_IRQ_EN_REG);
+ writel(val | TIMER_IRQ_EN(0), timer_base + TIMER_IRQ_EN_REG);
+
+ sun5i_clockevent.cpumask = cpu_possible_mask;
+ sun5i_clockevent.irq = irq;
+
+ clockevents_config_and_register(&sun5i_clockevent, rate,
+ TIMER_SYNC_TICKS, 0xffffffff);
+}
+CLOCKSOURCE_OF_DECLARE(sun5i_a13, "allwinner,sun5i-a13-hstimer",
+ sun5i_timer_init);
+CLOCKSOURCE_OF_DECLARE(sun7i_a20, "allwinner,sun7i-a20-hstimer",
+ sun5i_timer_init);
--
1.8.5.1

View file

@ -1,48 +0,0 @@
From 6c23e1fa6bd220b8f5665c150c83d4c016d95482 Mon Sep 17 00:00:00 2001
From: Maxime Ripard <maxime.ripard@free-electrons.com>
Date: Thu, 7 Nov 2013 12:01:48 +0100
Subject: [PATCH] ARM: sun7i: a20: Add support for the High Speed Timers
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
The Allwinner A20 has support for four high speed timers. Apart for the
number of timers (4 vs 2), it's basically the same logic than the high
speed timers found in the sun5i chips.
Now that we have a driver to support it, we can enable them in the
device tree.
[dlezcano] : Fixed conflict with 428abbb8 "Enable the I2C controllers"
Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
Tested-by: Emilio López <emilio@elopez.com.ar>
Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
---
arch/arm/boot/dts/sun7i-a20.dtsi | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/arch/arm/boot/dts/sun7i-a20.dtsi b/arch/arm/boot/dts/sun7i-a20.dtsi
index 93f7f96..c74147a 100644
--- a/arch/arm/boot/dts/sun7i-a20.dtsi
+++ b/arch/arm/boot/dts/sun7i-a20.dtsi
@@ -405,6 +405,16 @@
status = "disabled";
};
+ hstimer@01c60000 {
+ compatible = "allwinner,sun7i-a20-hstimer";
+ reg = <0x01c60000 0x1000>;
+ interrupts = <0 81 1>,
+ <0 82 1>,
+ <0 83 1>,
+ <0 84 1>;
+ clocks = <&ahb_gates 28>;
+ };
+
gic: interrupt-controller@01c81000 {
compatible = "arm,cortex-a7-gic", "arm,cortex-a15-gic";
reg = <0x01c81000 0x1000>,
--
1.8.5.1

View file

@ -1,38 +0,0 @@
From 22a3eff19679e0e592e061201690670a2f5fdba7 Mon Sep 17 00:00:00 2001
From: Maxime Ripard <maxime.ripard@free-electrons.com>
Date: Thu, 7 Nov 2013 12:01:48 +0100
Subject: [PATCH] ARM: sun5i: a13: Add support for the High Speed Timers
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
The Allwinner A13 has support for two high speed timers. Now that we
have a driver to support it, we can enable them in the device tree.
Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
Tested-by: Emilio López <emilio@elopez.com.ar>
Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
---
arch/arm/boot/dts/sun5i-a13.dtsi | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/arch/arm/boot/dts/sun5i-a13.dtsi b/arch/arm/boot/dts/sun5i-a13.dtsi
index ce8ef2a..1ccd75d 100644
--- a/arch/arm/boot/dts/sun5i-a13.dtsi
+++ b/arch/arm/boot/dts/sun5i-a13.dtsi
@@ -273,5 +273,12 @@
clock-frequency = <100000>;
status = "disabled";
};
+
+ timer@01c60000 {
+ compatible = "allwinner,sun5i-a13-hstimer";
+ reg = <0x01c60000 0x1000>;
+ interrupts = <82>, <83>;
+ clocks = <&ahb_gates 28>;
+ };
};
};
--
1.8.5.1

View file

@ -1,38 +0,0 @@
From 5ace5467690055b1772dcac69dd1377735b8a34b Mon Sep 17 00:00:00 2001
From: Maxime Ripard <maxime.ripard@free-electrons.com>
Date: Thu, 7 Nov 2013 12:01:48 +0100
Subject: [PATCH] ARM: sun5i: a10s: Add support for the High Speed Timers
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
The Allwinner A10s has support for two high speed timers. Now that we
have a driver to support it, we can enable them in the device tree.
Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
Tested-by: Emilio López <emilio@elopez.com.ar>
Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
---
arch/arm/boot/dts/sun5i-a10s.dtsi | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/arch/arm/boot/dts/sun5i-a10s.dtsi b/arch/arm/boot/dts/sun5i-a10s.dtsi
index b4764be..924a2c1 100644
--- a/arch/arm/boot/dts/sun5i-a10s.dtsi
+++ b/arch/arm/boot/dts/sun5i-a10s.dtsi
@@ -336,5 +336,12 @@
clock-frequency = <100000>;
status = "disabled";
};
+
+ timer@01c60000 {
+ compatible = "allwinner,sun5i-a13-hstimer";
+ reg = <0x01c60000 0x1000>;
+ interrupts = <82>, <83>;
+ clocks = <&ahb_gates 28>;
+ };
};
};
--
1.8.5.1

View file

@ -1,29 +0,0 @@
From cdb1e9d50ad353833902214035a71ce08d86072a Mon Sep 17 00:00:00 2001
From: Zoltan HERPAI <wigyori@uid0.hu>
Date: Sun, 12 Jan 2014 16:48:01 +0100
Subject: [PATCH] ARM: sun5i: dt: update hstimer entry
Rename the hstimer DT entry to make naming consistent with the
A20 dtsi. Also to avoid confusion when switching clocksources.
Signed-off-by: Zoltan HERPAI <wigyori@uid0.hu>
---
arch/arm/boot/dts/sun5i-a13.dtsi | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/arch/arm/boot/dts/sun5i-a13.dtsi b/arch/arm/boot/dts/sun5i-a13.dtsi
index 21900c6..e0a5cdd 100644
--- a/arch/arm/boot/dts/sun5i-a13.dtsi
+++ b/arch/arm/boot/dts/sun5i-a13.dtsi
@@ -427,7 +427,7 @@
status = "disabled";
};
- timer@01c60000 {
+ hstimer@01c60000 {
compatible = "allwinner,sun5i-a13-hstimer";
reg = <0x01c60000 0x1000>;
interrupts = <82>, <83>;
--
1.7.0.4

View file

@ -1,189 +0,0 @@
From d8d7a5805579db687fdfdfda4125b43d6a50e616 Mon Sep 17 00:00:00 2001
From: Maxime Ripard <maxime.ripard@free-electrons.com>
Date: Tue, 24 Sep 2013 11:07:43 +0300
Subject: [PATCH] reset: Add Allwinner A31 Reset Controller Driver
The Allwinner A31 has an IP maintaining a few other IPs in the SoC in
reset by default. Among these IPs are the High Speed Timers, hence why
we can't use the regular driver construct, and need to call the
registering function directly during machine initialisation.
Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
---
drivers/reset/Makefile | 1 +
drivers/reset/reset-sunxi.c | 156 ++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 157 insertions(+)
create mode 100644 drivers/reset/reset-sunxi.c
diff --git a/drivers/reset/Makefile b/drivers/reset/Makefile
index 1e2d83f..f216b74 100644
--- a/drivers/reset/Makefile
+++ b/drivers/reset/Makefile
@@ -1 +1,2 @@
obj-$(CONFIG_RESET_CONTROLLER) += core.o
+obj-$(CONFIG_ARCH_SUNXI) += reset-sun6i.o
diff --git a/drivers/reset/reset-sunxi.c b/drivers/reset/reset-sunxi.c
new file mode 100644
index 0000000..5bbd59a
--- /dev/null
+++ b/drivers/reset/reset-sunxi.c
@@ -0,0 +1,156 @@
+/*
+ * Allwinner SoCs Reset Controller driver
+ *
+ * Copyright 2013 Maxime Ripard
+ *
+ * Maxime Ripard <maxime.ripard@free-electrons.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/platform_device.h>
+#include <linux/reset-controller.h>
+#include <linux/slab.h>
+#include <linux/types.h>
+
+struct sunxi_reset_data {
+ void __iomem *membase;
+ struct reset_controller_dev rcdev;
+};
+
+static int sunxi_reset_assert(struct reset_controller_dev *rcdev,
+ unsigned long id)
+{
+ struct sunxi_reset_data *data = container_of(rcdev,
+ struct sunxi_reset_data,
+ rcdev);
+ int bank = id / BITS_PER_LONG;
+ int offset = id % BITS_PER_LONG;
+ u32 reg = readl(data->membase + (bank * 4));
+
+ writel(reg & ~BIT(offset), data->membase + (bank * 4));
+
+ return 0;
+}
+
+static int sunxi_reset_deassert(struct reset_controller_dev *rcdev,
+ unsigned long id)
+{
+ struct sunxi_reset_data *data = container_of(rcdev,
+ struct sunxi_reset_data,
+ rcdev);
+ int bank = id / BITS_PER_LONG;
+ int offset = id % BITS_PER_LONG;
+ u32 reg = readl(data->membase + (bank * 4));
+
+ writel(reg | BIT(offset), data->membase + (bank * 4));
+
+ return 0;
+}
+
+static struct reset_control_ops sunxi_reset_ops = {
+ .assert = sunxi_reset_assert,
+ .deassert = sunxi_reset_deassert,
+};
+
+static int sunxi_reset_init(struct device_node *np)
+{
+ struct sunxi_reset_data *data;
+ struct resource res;
+ resource_size_t size;
+ int ret;
+
+ data = kzalloc(sizeof(*data), GFP_KERNEL);
+ if (!data)
+ return -ENOMEM;
+
+ ret = of_address_to_resource(np, 0, &res);
+ if (ret)
+ goto err_alloc;
+
+ size = resource_size(&res);
+ data->membase = ioremap(res.start, size);
+ if (!data->membase) {
+ ret = -ENOMEM;
+ goto err_alloc;
+ }
+
+ data->rcdev.owner = THIS_MODULE;
+ data->rcdev.nr_resets = size * 32;
+ data->rcdev.ops = &sunxi_reset_ops;
+ data->rcdev.of_node = np;
+ reset_controller_register(&data->rcdev);
+
+ return 0;
+
+err_alloc:
+ kfree(data);
+ return ret;
+};
+
+/*
+ * These are the reset controller we need to initialize early on in
+ * our system, before we can even think of using a regular device
+ * driver for it.
+ */
+static const struct of_device_id sunxi_early_reset_dt_ids[] __initdata = {
+ { .compatible = "allwinner,sun6i-a31-ahb1-reset", },
+ { /* sentinel */ },
+};
+
+void __init sun6i_reset_init(void)
+{
+ struct device_node *np;
+
+ for_each_matching_node(np, sunxi_early_reset_dt_ids)
+ sunxi_reset_init(np);
+}
+
+/*
+ * And these are the controllers we can register through the regular
+ * device model.
+ */
+static const struct of_device_id sunxi_reset_dt_ids[] = {
+ { .compatible = "allwinner,sun4i-clock-reset", },
+ { /* sentinel */ },
+};
+MODULE_DEVICE_TABLE(of, sunxi_reset_dt_ids);
+
+static int sunxi_reset_probe(struct platform_device *pdev)
+{
+ return sunxi_reset_init(pdev->dev.of_node);
+}
+
+static int sunxi_reset_remove(struct platform_device *pdev)
+{
+ struct sunxi_reset_data *data = platform_get_drvdata(pdev);
+
+ reset_controller_unregister(&data->rcdev);
+ iounmap(data->membase);
+ kfree(data);
+
+ return 0;
+}
+
+static struct platform_driver sunxi_reset_driver = {
+ .probe = sunxi_reset_probe,
+ .remove = sunxi_reset_remove,
+ .driver = {
+ .name = "sunxi-reset",
+ .owner = THIS_MODULE,
+ .of_match_table = sunxi_reset_dt_ids,
+ },
+};
+module_platform_driver(sunxi_reset_driver);
+
+MODULE_AUTHOR("Maxime Ripard <maxime.ripard@free-electrons.com");
+MODULE_DESCRIPTION("Allwinner SoCs Reset Controller Driver");
+MODULE_LICENSE("GPL");
--
1.8.4

View file

@ -1,27 +0,0 @@
From 6bf236bb67dfabd0434df47ff1247b1310d4ccf5 Mon Sep 17 00:00:00 2001
From: Maxime Ripard <maxime.ripard@free-electrons.com>
Date: Tue, 24 Sep 2013 11:09:55 +0300
Subject: [PATCH] ARM: sunxi: Select ARCH_HAS_RESET_CONTROLLER
The A31 has a reset controller, and we have to select this option to
have access to the reset controller framework.
Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
---
arch/arm/mach-sunxi/Kconfig | 1 +
1 file changed, 1 insertion(+)
diff --git a/arch/arm/mach-sunxi/Kconfig b/arch/arm/mach-sunxi/Kconfig
index bce0d42..547004c 100644
--- a/arch/arm/mach-sunxi/Kconfig
+++ b/arch/arm/mach-sunxi/Kconfig
@@ -1,5 +1,6 @@
config ARCH_SUNXI
bool "Allwinner A1X SOCs" if ARCH_MULTI_V7
+ select ARCH_HAS_RESET_CONTROLLER
select ARCH_REQUIRE_GPIOLIB
select ARM_GIC
select CLKSRC_MMIO
--
1.8.4

View file

@ -1,94 +0,0 @@
From 2a906d06b21968803ce504348864908ad1ed66ac Mon Sep 17 00:00:00 2001
From: Maxime Ripard <maxime.ripard@free-electrons.com>
Date: Tue, 24 Sep 2013 11:10:41 +0300
Subject: [PATCH] ARM: sun6i: Add the reset controller to the DTSI
The A31 has a reset controller IP that maintains a few other IPs in
reset, among which we can find the UARTs, high speed timers or the I2C.
Now that we have support for them, add the reset controllers to the DTSI.
Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
---
arch/arm/boot/dts/sun6i-a31.dtsi | 24 ++++++++++++++++++++++++
1 file changed, 24 insertions(+)
diff --git a/arch/arm/boot/dts/sun6i-a31.dtsi b/arch/arm/boot/dts/sun6i-a31.dtsi
index c1751a6..c7e0658 100644
--- a/arch/arm/boot/dts/sun6i-a31.dtsi
+++ b/arch/arm/boot/dts/sun6i-a31.dtsi
@@ -209,6 +209,24 @@
};
};
+ ahb1_rst: reset@01c202c0 {
+ #reset-cells = <1>;
+ compatible = "allwinner,sun6i-a31-ahb1-reset";
+ reg = <0x01c202c0 0xc>;
+ };
+
+ apb1_rst: reset@01c202d0 {
+ #reset-cells = <1>;
+ compatible = "allwinner,sun4i-clock-reset";
+ reg = <0x01c202d0 0x4>;
+ };
+
+ apb2_rst: reset@01c202d8 {
+ #reset-cells = <1>;
+ compatible = "allwinner,sun4i-clock-reset";
+ reg = <0x01c202d8 0x4>;
+ };
+
timer@01c20c00 {
compatible = "allwinner,sun4i-timer";
reg = <0x01c20c00 0xa0>;
@@ -232,6 +250,7 @@
reg-shift = <2>;
reg-io-width = <4>;
clocks = <&apb2_gates 16>;
+ resets = <&apb2_rst 16>;
status = "disabled";
};
@@ -242,6 +261,7 @@
reg-shift = <2>;
reg-io-width = <4>;
clocks = <&apb2_gates 17>;
+ resets = <&apb2_rst 17>;
status = "disabled";
};
@@ -252,6 +272,7 @@
reg-shift = <2>;
reg-io-width = <4>;
clocks = <&apb2_gates 18>;
+ resets = <&apb2_rst 18>;
status = "disabled";
};
@@ -262,6 +283,7 @@
reg-shift = <2>;
reg-io-width = <4>;
clocks = <&apb2_gates 19>;
+ resets = <&apb2_rst 19>;
status = "disabled";
};
@@ -272,6 +294,7 @@
reg-shift = <2>;
reg-io-width = <4>;
clocks = <&apb2_gates 20>;
+ resets = <&apb2_rst 20>;
status = "disabled";
};
@@ -282,6 +305,7 @@
reg-shift = <2>;
reg-io-width = <4>;
clocks = <&apb2_gates 21>;
+ resets = <&apb2_rst 21>;
status = "disabled";
};
--
1.8.4

View file

@ -1,20 +0,0 @@
From ab2f1e0056db0e5a0717981546a69d5b81439661 Mon Sep 17 00:00:00 2001
From: arokux <arokux@gmail.com>
Date: Sun, 20 Oct 2013 22:59:01 +0200
Subject: [PATCH] reset: Fix mpripard's reset patch
---
drivers/reset/Makefile | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/reset/Makefile b/drivers/reset/Makefile
index f216b74..cc29832 100644
--- a/drivers/reset/Makefile
+++ b/drivers/reset/Makefile
@@ -1,2 +1,2 @@
obj-$(CONFIG_RESET_CONTROLLER) += core.o
-obj-$(CONFIG_ARCH_SUNXI) += reset-sun6i.o
+obj-$(CONFIG_ARCH_SUNXI) += reset-sunxi.o
--
1.8.4

View file

@ -1,31 +0,0 @@
From 378dab1f11d0386e26363517922dc086227aa6c5 Mon Sep 17 00:00:00 2001
From: arokux <arokux@gmail.com>
Date: Thu, 19 Sep 2013 21:58:47 +0200
Subject: [PATCH] ARM: sun4i: dt: Add bindings for USB clocks
---
arch/arm/boot/dts/sun4i-a10.dtsi | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/arch/arm/boot/dts/sun4i-a10.dtsi b/arch/arm/boot/dts/sun4i-a10.dtsi
index 5e2fc45..3033684 100644
--- a/arch/arm/boot/dts/sun4i-a10.dtsi
+++ b/arch/arm/boot/dts/sun4i-a10.dtsi
@@ -89,6 +89,14 @@
clock-output-names = "pll6_sata", "pll6_other", "pll6";
};
+ usb:usb@0x01c200cc {
+ #clock-cells = <1>;
+ compatible = "allwinner,sun47i-usb-gates-clk";
+ reg = <0x01c200cc 0x4>;
+ clocks = <&pll6 1>;
+ clock-output-names = "usb_ohci0", "usb_ohci1", "usb_phy";
+ };
+
/* dummy is 200M */
cpu: cpu@01c20054 {
#clock-cells = <0>;
--
1.8.4

View file

@ -1,35 +0,0 @@
From 43c2d3189567342f68ec192f2eeab6ae4c4d1ddf Mon Sep 17 00:00:00 2001
From: arokux <arokux@gmail.com>
Date: Thu, 19 Sep 2013 21:59:32 +0200
Subject: [PATCH] clk: sunxi: Add support for USB clocks
---
drivers/clk/sunxi/clk-sunxi.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/drivers/clk/sunxi/clk-sunxi.c b/drivers/clk/sunxi/clk-sunxi.c
index 96c01b2..cbe1516 100644
--- a/drivers/clk/sunxi/clk-sunxi.c
+++ b/drivers/clk/sunxi/clk-sunxi.c
@@ -619,6 +619,10 @@ struct gates_data {
.mask = {0x7F77FFF, 0x14FB3F},
};
+static const struct gates_data sun47i_usb_gates_data __initconst = {
+ .mask = {0x1C0},
+};
+
static const struct gates_data sun5i_a10s_ahb_gates_data __initconst = {
.mask = {0x147667e7, 0x185915},
};
@@ -867,6 +871,7 @@ static void __init sunxi_divs_clk_setup(struct device_node *node,
static const struct of_device_id clk_gates_match[] __initconst = {
{.compatible = "allwinner,sun4i-axi-gates-clk", .data = &sun4i_axi_gates_data,},
{.compatible = "allwinner,sun4i-ahb-gates-clk", .data = &sun4i_ahb_gates_data,},
+ {.compatible = "allwinner,sun47i-usb-gates-clk", .data = &sun47i_usb_gates_data,},
{.compatible = "allwinner,sun5i-a10s-ahb-gates-clk", .data = &sun5i_a10s_ahb_gates_data,},
{.compatible = "allwinner,sun5i-a13-ahb-gates-clk", .data = &sun5i_a13_ahb_gates_data,},
{.compatible = "allwinner,sun6i-a31-ahb1-gates-clk", .data = &sun6i_a31_ahb1_gates_data,},
--
1.8.4

View file

@ -1,62 +0,0 @@
From 90bc2022b61dcfd4d785416ee3aabc2157bfd57a Mon Sep 17 00:00:00 2001
From: arokux <arokux@gmail.com>
Date: Wed, 18 Sep 2013 00:30:04 +0200
Subject: [PATCH] ARM: sun4i: dt: Add USB EHCI bindings
---
arch/arm/boot/dts/sun4i-a10.dtsi | 33 +++++++++++++++++++++++++++++++++
1 file changed, 33 insertions(+)
diff --git a/arch/arm/boot/dts/sun4i-a10.dtsi b/arch/arm/boot/dts/sun4i-a10.dtsi
index 3033684..6c05264 100644
--- a/arch/arm/boot/dts/sun4i-a10.dtsi
+++ b/arch/arm/boot/dts/sun4i-a10.dtsi
@@ -15,6 +15,11 @@
/ {
interrupt-parent = <&intc>;
+ aliases {
+ ehci1 = &ehci0;
+ ehci2 = &ehci1;
+ };
+
cpus {
#address-cells = <1>;
#size-cells = <0>;
@@ -407,5 +412,33 @@
clock-frequency = <100000>;
status = "disabled";
};
+
+ usb_rst: reset@0x01c200cc {
+ #reset-cells = <1>;
+ compatible = "allwinner,sun4i-clock-reset";
+ reg = <0x01c200cc 0x4>;
+ };
+
+ ehci0: ehci0@0x01c14000 {
+ compatible = "allwinner,sunxi-ehci";
+ reg = <0x01c14000 0x400 0x01c14800 0x4 0x01c13404 0x4>;
+ interrupts = <39>;
+ resets = <&usb_rst 1>;
+ reset-names = "ehci_reset";
+ clocks = <&usb 8>, <&ahb_gates 1>;
+ clock-names = "usb_phy", "ahb_ehci";
+ status = "disabled";
+ };
+
+ ehci1: ehci1@0x01c1c000 {
+ compatible = "allwinner,sunxi-ehci";
+ reg = <0x01c1c000 0x400 0x01c1c800 0x4 0x01c13404 0x4>;
+ interrupts = <40>;
+ resets = <&usb_rst 2>;
+ reset-names = "ehci_reset";
+ clocks = <&usb 8>, <&ahb_gates 3>;
+ clock-names = "usb_phy", "ahb_ehci";
+ status = "disabled";
+ };
};
};
--
1.8.4

View file

@ -1,499 +0,0 @@
From b84d49247eb062672a56ce15f1c08f792099de97 Mon Sep 17 00:00:00 2001
From: arokux <arokux@gmail.com>
Date: Wed, 18 Sep 2013 21:45:03 +0200
Subject: [PATCH] ARM: sunxi: usb: Add Allwinner sunXi EHCI driver
---
drivers/usb/host/Kconfig | 9 +
drivers/usb/host/Makefile | 1 +
drivers/usb/host/ehci-sunxi.c | 446 ++++++++++++++++++++++++++++++++++++++++++
3 files changed, 456 insertions(+)
create mode 100644 drivers/usb/host/ehci-sunxi.c
diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
index b3f20d7..ecc2745 100644
--- a/drivers/usb/host/Kconfig
+++ b/drivers/usb/host/Kconfig
@@ -274,6 +274,15 @@ config USB_OCTEON_EHCI
USB 2.0 device support. All CN6XXX based chips with USB are
supported.
+config USB_SUNXI_EHCI
+ tristate "Allwinner sunXi EHCI support"
+ depends on ARCH_SUNXI
+ default n
+ help
+ Enable support for the Allwinner sunXi on-chip EHCI
+ controller. It is needed for high-speed (480Mbit/sec)
+ USB 2.0 device support.
+
endif # USB_EHCI_HCD
config USB_OXU210HP_HCD
diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile
index 50b0041..d2e2c8c 100644
--- a/drivers/usb/host/Makefile
+++ b/drivers/usb/host/Makefile
@@ -38,6 +38,7 @@ obj-$(CONFIG_USB_EHCI_S5P) += ehci-s5p.o
obj-$(CONFIG_USB_EHCI_HCD_AT91) += ehci-atmel.o
obj-$(CONFIG_USB_EHCI_MSM) += ehci-msm.o
obj-$(CONFIG_USB_EHCI_TEGRA) += ehci-tegra.o
+obj-$(CONFIG_USB_SUNXI_EHCI) += ehci-sunxi.o
obj-$(CONFIG_USB_OXU210HP_HCD) += oxu210hp-hcd.o
obj-$(CONFIG_USB_ISP116X_HCD) += isp116x-hcd.o
diff --git a/drivers/usb/host/ehci-sunxi.c b/drivers/usb/host/ehci-sunxi.c
new file mode 100644
index 0000000..e7e15cc
--- /dev/null
+++ b/drivers/usb/host/ehci-sunxi.c
@@ -0,0 +1,446 @@
+/*
+ * Copyright (C) 2013 Roman Byshko
+ *
+ * Roman Byshko <rbyshko@gmail.com>
+ *
+ * Based on code from
+ * Allwinner Technology Co., Ltd. <www.allwinnertech.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/bitops.h>
+#include <linux/clk.h>
+#include <linux/dma-mapping.h>
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/regulator/consumer.h>
+#include <linux/reset.h>
+#include <linux/usb.h>
+#include <linux/usb/hcd.h>
+
+#include "ehci.h"
+
+#define DRV_DESC "Allwinner sunXi EHCI driver"
+#define DRV_NAME "sunxi-ehci"
+
+#define SUNXI_USB_PASSBY_EN 1
+
+#define SUNXI_EHCI_AHB_ICHR8_EN BIT(10)
+#define SUNXI_EHCI_AHB_INCR4_BURST_EN BIT(9)
+#define SUNXI_EHCI_AHB_INCRX_ALIGN_EN BIT(8)
+#define SUNXI_EHCI_ULPI_BYPASS_EN BIT(0)
+
+struct sunxi_ehci_hcd {
+ struct clk *phy_clk;
+ struct clk *ahb_ehci_clk;
+ struct reset_control *reset;
+ struct regulator *vbus_reg;
+ void __iomem *csr;
+ void __iomem *pmuirq;
+ int irq;
+ int id;
+};
+
+
+static void usb_phy_write(struct sunxi_ehci_hcd *sunxi_ehci,u32 addr, u32 data, u32 len)
+{
+ u32 j = 0;
+ u32 temp = 0;
+ u32 usbc_bit = 0;
+ void __iomem *dest = sunxi_ehci->csr;
+
+ usbc_bit = BIT(sunxi_ehci->id << 1);
+
+ for (j = 0; j < len; j++) {
+ temp = readl(dest);
+
+ /* clear the address portion */
+ temp &= ~(0xff << 8);
+
+ /* set the address */
+ temp |= ((addr + j) << 8);
+ writel(temp, dest);
+
+ /* set the data bit and clear usbc bit*/
+ temp = readb(dest);
+ if (data & 0x1)
+ temp |= BIT(7);
+ else
+ temp &= ~BIT(7);
+ temp &= ~usbc_bit;
+ writeb(temp, dest);
+
+ /* flip usbc_bit */
+ __set_bit(usbc_bit, dest);
+ __clear_bit(usbc_bit, dest);
+
+ data >>= 1;
+ }
+}
+
+/* FIXME: should this function be protected by a lock?
+ * ehci1 and ehci0 could call it concurrently with same csr.
+ */
+static void sunxi_usb_phy_init(struct sunxi_ehci_hcd *sunxi_ehci)
+{
+ /* The following comments are machine
+ * translated from Chinese, you have been warned!
+ */
+
+ /* adjust PHY's magnitude and rate */
+ usb_phy_write(sunxi_ehci, 0x20, 0x14, 5);
+
+ /* threshold adjustment disconnect */
+ usb_phy_write(sunxi_ehci, 0x2a, 3, 2);
+
+ return;
+}
+
+static void sunxi_usb_passby(struct sunxi_ehci_hcd *sunxi_ehci, int enable)
+{
+ unsigned long reg_value = 0;
+ unsigned long bits = 0;
+ static DEFINE_SPINLOCK(lock);
+ unsigned long flags = 0;
+ void __iomem *addr = sunxi_ehci->pmuirq;
+
+ bits = SUNXI_EHCI_AHB_ICHR8_EN |
+ SUNXI_EHCI_AHB_INCR4_BURST_EN |
+ SUNXI_EHCI_AHB_INCRX_ALIGN_EN |
+ SUNXI_EHCI_ULPI_BYPASS_EN;
+
+ spin_lock_irqsave(&lock, flags);
+
+ reg_value = readl(addr);
+
+ if (enable)
+ reg_value |= bits;
+ else
+ reg_value &= ~bits;
+
+ writel(reg_value, addr);
+
+ spin_unlock_irqrestore(&lock, flags);
+
+ return;
+}
+
+static void sunxi_ehci_disable(struct sunxi_ehci_hcd *sunxi_ehci)
+{
+ regulator_disable(sunxi_ehci->vbus_reg);
+
+ sunxi_usb_passby(sunxi_ehci, !SUNXI_USB_PASSBY_EN);
+
+ clk_disable_unprepare(sunxi_ehci->ahb_ehci_clk);
+ clk_disable_unprepare(sunxi_ehci->phy_clk);
+
+ reset_control_assert(sunxi_ehci->reset);
+}
+
+static int sunxi_ehci_enable(struct sunxi_ehci_hcd *sunxi_ehci)
+{
+ int ret;
+
+ ret = clk_prepare_enable(sunxi_ehci->phy_clk);
+ if (ret)
+ return ret;
+
+ ret = reset_control_deassert(sunxi_ehci->reset);
+ if (ret)
+ goto fail1;
+
+ ret = clk_prepare_enable(sunxi_ehci->ahb_ehci_clk);
+ if (ret)
+ goto fail2;
+
+ sunxi_usb_phy_init(sunxi_ehci);
+
+ sunxi_usb_passby(sunxi_ehci, SUNXI_USB_PASSBY_EN);
+
+ ret = regulator_enable(sunxi_ehci->vbus_reg);
+ if (ret)
+ goto fail3;
+
+ return 0;
+
+fail3:
+ clk_disable_unprepare(sunxi_ehci->ahb_ehci_clk);
+fail2:
+ reset_control_assert(sunxi_ehci->reset);
+fail1:
+ clk_disable_unprepare(sunxi_ehci->phy_clk);
+
+ return ret;
+}
+
+#ifdef CONFIG_PM
+static int sunxi_ehci_suspend(struct device *dev)
+{
+ struct sunxi_ehci_hcd *sunxi_ehci = NULL;
+ struct usb_hcd *hcd = dev_get_drvdata(dev);
+ int ret;
+
+ bool do_wakeup = device_may_wakeup(dev);
+
+ ret = ehci_suspend(hcd, do_wakeup);
+
+ sunxi_ehci = (struct sunxi_ehci_hcd *)hcd_to_ehci(hcd)->priv;
+
+ sunxi_ehci_disable(sunxi_ehci);
+
+ return ret;
+}
+
+static int sunxi_ehci_resume(struct device *dev)
+{
+ struct sunxi_ehci_hcd *sunxi_ehci = NULL;
+ struct usb_hcd *hcd = dev_get_drvdata(dev);
+ int ret;
+
+ sunxi_ehci = (struct sunxi_ehci_hcd *)hcd_to_ehci(hcd)->priv;
+
+ ret = sunxi_ehci_enable(sunxi_ehci);
+ if (ret)
+ return ret;
+
+ return ehci_resume(hcd, false);
+}
+
+
+static const struct dev_pm_ops sunxi_ehci_pmops = {
+ .suspend = sunxi_ehci_suspend,
+ .resume = sunxi_ehci_resume,
+};
+
+#define SUNXI_EHCI_PMOPS (&sunxi_ehci_pmops)
+#else /* !CONFIG_PM */
+#define SUNXI_EHCI_PMOPS NULL
+#endif /* CONFIG_PM */
+
+static const struct ehci_driver_overrides sunxi_overrides __initconst = {
+ .reset = NULL,
+ .extra_priv_size = sizeof(struct sunxi_ehci_hcd),
+};
+
+/* FIXME: Should there be two instances of hc_driver,
+ * or one is enough to handle two EHCI controllers? */
+static struct hc_driver __read_mostly sunxi_ehci_hc_driver;
+
+static int sunxi_ehci_init(struct platform_device *pdev, struct usb_hcd *hcd,
+ struct sunxi_ehci_hcd *sunxi_ehci)
+{
+ void __iomem *ehci_regs = NULL;
+ struct resource *res = NULL;
+
+ sunxi_ehci->vbus_reg = devm_regulator_get(&pdev->dev, "vbus");
+ if (IS_ERR(sunxi_ehci->vbus_reg)) {
+ if (PTR_ERR(sunxi_ehci->vbus_reg) == -EPROBE_DEFER)
+ return -EPROBE_DEFER;
+
+ dev_info(&pdev->dev, "no USB VBUS power supply found\n");
+ }
+
+ sunxi_ehci->id = of_alias_get_id(pdev->dev.of_node, "ehci");
+ if (sunxi_ehci->id < 0)
+ return sunxi_ehci->id;
+
+ /* FIXME: should res be freed on some failure? */
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!res) {
+ dev_err(&pdev->dev, "failed to get I/O memory\n");
+ return -ENXIO;
+ }
+ ehci_regs = devm_ioremap_resource(&pdev->dev, res);
+ if (IS_ERR(ehci_regs))
+ return PTR_ERR(ehci_regs);
+
+ hcd->rsrc_start = res->start;
+ hcd->rsrc_len = resource_size(res);
+ hcd->regs = ehci_regs;
+ hcd_to_ehci(hcd)->caps = ehci_regs;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+ if (!res) {
+ dev_err(&pdev->dev, "failed to get I/O memory\n");
+ return -ENXIO;
+ }
+ sunxi_ehci->pmuirq = devm_ioremap_resource(&pdev->dev, res);
+ if (IS_ERR(sunxi_ehci->pmuirq))
+ return PTR_ERR(sunxi_ehci->pmuirq);
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 2);
+ if (!res) {
+ dev_err(&pdev->dev, "failed to get I/O memory\n");
+ return -ENXIO;
+ }
+
+ /* FIXME: this one byte needs to be shared between both EHCIs,
+ * that is why ioremap instead of devm_ioremap_resource,
+ * memory is not unmaped back for now.
+ */
+ sunxi_ehci->csr = ioremap(res->start, resource_size(res));
+ if (IS_ERR(sunxi_ehci->csr)) {
+ dev_err(&pdev->dev, "failed to remap memory\n");
+ return PTR_ERR(sunxi_ehci->csr);
+ }
+
+ sunxi_ehci->irq = platform_get_irq(pdev, 0);
+ if (!sunxi_ehci->irq) {
+ dev_err(&pdev->dev, "failed to get IRQ\n");
+ return -ENODEV;
+ }
+
+ sunxi_ehci->phy_clk = devm_clk_get(&pdev->dev, "usb_phy");
+ if (IS_ERR(sunxi_ehci->phy_clk)) {
+ dev_err(&pdev->dev, "failed to get usb_phy clock\n");
+ return PTR_ERR(sunxi_ehci->phy_clk);
+ }
+ sunxi_ehci->ahb_ehci_clk = devm_clk_get(&pdev->dev, "ahb_ehci");
+ if (IS_ERR(sunxi_ehci->ahb_ehci_clk)) {
+ dev_err(&pdev->dev, "failed to get ahb_ehci clock\n");
+ return PTR_ERR(sunxi_ehci->ahb_ehci_clk);
+ }
+
+ sunxi_ehci->reset = reset_control_get(&pdev->dev, "ehci_reset");
+ if (IS_ERR(sunxi_ehci->reset))
+ {
+ dev_err(&pdev->dev, "failed to get ehci_reset reset line\n");
+ return PTR_ERR(sunxi_ehci->reset);
+ }
+
+ return 0;
+}
+
+static int sunxi_ehci_probe(struct platform_device *pdev)
+{
+ struct sunxi_ehci_hcd *sunxi_ehci = NULL;
+ struct usb_hcd *hcd = NULL;
+ int ret;
+
+ if (pdev->num_resources != 4) {
+ dev_err(&pdev->dev, "invalid number of resources: %i\n",
+ pdev->num_resources);
+ return -ENODEV;
+ }
+
+ if (pdev->resource[0].flags != IORESOURCE_MEM
+ || pdev->resource[1].flags != IORESOURCE_MEM
+ || pdev->resource[2].flags != IORESOURCE_MEM
+ || pdev->resource[3].flags != IORESOURCE_IRQ) {
+ dev_err(&pdev->dev, "invalid resource type\n");
+ return -ENODEV;
+ }
+
+ if (!pdev->dev.dma_mask)
+ pdev->dev.dma_mask = &pdev->dev.coherent_dma_mask;
+ if (!pdev->dev.coherent_dma_mask)
+ pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32);
+
+ hcd = usb_create_hcd(&sunxi_ehci_hc_driver, &pdev->dev,
+ dev_name(&pdev->dev));
+ if (!hcd) {
+ dev_err(&pdev->dev, "unable to create HCD\n");
+ return -ENOMEM;
+ }
+
+ platform_set_drvdata(pdev, hcd);
+
+ sunxi_ehci = (struct sunxi_ehci_hcd *)hcd_to_ehci(hcd)->priv;
+ ret = sunxi_ehci_init(pdev, hcd, sunxi_ehci);
+ if (ret)
+ goto fail1;
+
+ ret = sunxi_ehci_enable(sunxi_ehci);
+ if (ret)
+ goto fail1;
+
+ ret = usb_add_hcd(hcd, sunxi_ehci->irq, IRQF_SHARED | IRQF_DISABLED);
+ if (ret) {
+ dev_err(&pdev->dev, "failed to add USB HCD\n");
+ goto fail2;
+ }
+
+ return 0;
+
+fail2:
+ sunxi_ehci_disable(sunxi_ehci);
+
+fail1:
+ usb_put_hcd(hcd);
+ return ret;
+}
+
+static int sunxi_ehci_remove(struct platform_device *pdev)
+{
+ struct usb_hcd *hcd = platform_get_drvdata(pdev);
+ struct sunxi_ehci_hcd *sunxi_ehci = NULL;
+
+ sunxi_ehci = (struct sunxi_ehci_hcd *)hcd_to_ehci(hcd)->priv;
+
+ usb_remove_hcd(hcd);
+
+ sunxi_ehci_disable(sunxi_ehci);
+
+ usb_put_hcd(hcd);
+
+ return 0;
+}
+
+static void sunxi_ehci_shutdown(struct platform_device *pdev)
+{
+ struct usb_hcd *hcd = platform_get_drvdata(pdev);
+ struct sunxi_ehci_hcd *sunxi_ehci = NULL;
+
+ sunxi_ehci = (struct sunxi_ehci_hcd *)hcd_to_ehci(hcd)->priv;
+
+ usb_hcd_platform_shutdown(pdev);
+
+ sunxi_ehci_disable(sunxi_ehci);
+}
+
+static const struct of_device_id ehci_of_match[] = {
+ {.compatible = "allwinner,sunxi-ehci"},
+ {},
+};
+
+static struct platform_driver ehci_sunxi_driver = {
+ .driver = {
+ .of_match_table = ehci_of_match,
+ .name = DRV_NAME,
+ .pm = SUNXI_EHCI_PMOPS,
+ },
+ .probe = sunxi_ehci_probe,
+ .remove = sunxi_ehci_remove,
+ .shutdown = sunxi_ehci_shutdown,
+};
+
+static int __init sunxi_ehci_init_module(void)
+{
+ if (usb_disabled())
+ return -ENODEV;
+
+ pr_info(DRV_NAME ": " DRV_DESC "\n");
+
+ ehci_init_driver(&sunxi_ehci_hc_driver, &sunxi_overrides);
+
+ return platform_driver_register(&ehci_sunxi_driver);
+}
+module_init(sunxi_ehci_init_module);
+
+static void __exit sunxi_ehci_exit_module(void)
+{
+ platform_driver_unregister(&ehci_sunxi_driver);
+}
+module_exit(sunxi_ehci_exit_module);
+
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:" DRV_NAME);
+MODULE_DEVICE_TABLE(of, ehci_of_match);
+MODULE_AUTHOR("Roman Byshko <rbyshko@gmail.com>");
--
1.8.4

View file

@ -1,82 +0,0 @@
From bc8138b4218307a8f25076ec5c8c1eae1e5e8d78 Mon Sep 17 00:00:00 2001
From: arokux <arokux@gmail.com>
Date: Wed, 18 Sep 2013 00:30:40 +0200
Subject: [PATCH] ARM: sun4i: dt: Add EHCI bindings to the Mele A1000
---
arch/arm/boot/dts/sun4i-a10-a1000.dts | 46 +++++++++++++++++++++++++++++++++++
1 file changed, 46 insertions(+)
diff --git a/arch/arm/boot/dts/sun4i-a10-a1000.dts b/arch/arm/boot/dts/sun4i-a10-a1000.dts
index eb4d73b..68c705d 100644
--- a/arch/arm/boot/dts/sun4i-a10-a1000.dts
+++ b/arch/arm/boot/dts/sun4i-a10-a1000.dts
@@ -53,6 +53,20 @@
allwinner,drive = <0>;
allwinner,pull = <0>;
};
+
+ usb1_vbus_pin: usb1_vbus_pin@0 {
+ allwinner,pins = "PH6";
+ allwinner,function = "gpio_out";
+ allwinner,drive = <0>;
+ allwinner,pull = <2>;
+ };
+
+ usb2_vbus_pin: usb2_vbus_pin@0 {
+ allwinner,pins = "PH3";
+ allwinner,function = "gpio_out";
+ allwinner,drive = <0>;
+ allwinner,pull = <2>;
+ };
};
uart0: serial@01c28000 {
@@ -66,6 +80,16 @@
pinctrl-0 = <&i2c0_pins_a>;
status = "okay";
};
+
+ ehci0: ehci0@0x01c14000 {
+ vbus-supply = <&reg_usb1_vbus>;
+ status = "okay";
+ };
+
+ ehci1: ehci1@0x01c1c000 {
+ vbus-supply = <&reg_usb2_vbus>;
+ status = "okay";
+ };
};
leds {
@@ -97,5 +121,27 @@
enable-active-high;
gpio = <&pio 7 15 0>;
};
+
+ reg_usb1_vbus: usb1-vbus {
+ compatible = "regulator-fixed";
+ pinctrl-names = "default";
+ pinctrl-0 = <&usb1_vbus_pin>;
+ regulator-name = "usb1-vbus";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ enable-active-high;
+ gpio = <&pio 7 6 0>;
+ };
+
+ reg_usb2_vbus: usb2-vbus {
+ compatible = "regulator-fixed";
+ pinctrl-names = "default";
+ pinctrl-0 = <&usb2_vbus_pin>;
+ regulator-name = "usb2-vbus";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ enable-active-high;
+ gpio = <&pio 7 3 0>;
+ };
};
};
--
1.8.4

View file

@ -1,85 +0,0 @@
From bf96cf461ca2d36e962a4acf83f6f779a05c7df3 Mon Sep 17 00:00:00 2001
From: arokux <arokux@gmail.com>
Date: Wed, 18 Sep 2013 22:45:06 +0200
Subject: [PATCH] ARM: sun4i: dt: Add EHCI bindings to Cubieboard-A10
---
arch/arm/boot/dts/sun4i-a10-cubieboard.dts | 50 ++++++++++++++++++++++++++++++
1 file changed, 50 insertions(+)
diff --git a/arch/arm/boot/dts/sun4i-a10-cubieboard.dts b/arch/arm/boot/dts/sun4i-a10-cubieboard.dts
index 425a7db..eb6c3c1 100644
--- a/arch/arm/boot/dts/sun4i-a10-cubieboard.dts
+++ b/arch/arm/boot/dts/sun4i-a10-cubieboard.dts
@@ -49,6 +49,20 @@
allwinner,drive = <1>;
allwinner,pull = <0>;
};
+
+ usb1_vbus_pin: usb1_vbus_pin@0 {
+ allwinner,pins = "PH6";
+ allwinner,function = "gpio_out";
+ allwinner,drive = <0>;
+ allwinner,pull = <2>;
+ };
+
+ usb2_vbus_pin: usb2_vbus_pin@0 {
+ allwinner,pins = "PH3";
+ allwinner,function = "gpio_out";
+ allwinner,drive = <0>;
+ allwinner,pull = <2>;
+ };
};
uart0: serial@01c28000 {
@@ -68,6 +82,16 @@
pinctrl-0 = <&i2c1_pins_a>;
status = "okay";
};
+
+ ehci0: ehci0@0x01c14000 {
+ vbus-supply = <&reg_usb1_vbus>;
+ status = "okay";
+ };
+
+ ehci1: ehci1@0x01c1c000 {
+ vbus-supply = <&reg_usb2_vbus>;
+ status = "okay";
+ };
};
leds {
@@ -86,4 +110,30 @@
linux,default-trigger = "heartbeat";
};
};
+
+ regulators {
+ compatible = "simple-bus";
+
+ reg_usb1_vbus: usb1-vbus {
+ compatible = "regulator-fixed";
+ pinctrl-names = "default";
+ pinctrl-0 = <&usb1_vbus_pin>;
+ regulator-name = "usb1-vbus";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ enable-active-high;
+ gpio = <&pio 7 6 0>;
+ };
+
+ reg_usb2_vbus: usb2-vbus {
+ compatible = "regulator-fixed";
+ pinctrl-names = "default";
+ pinctrl-0 = <&usb2_vbus_pin>;
+ regulator-name = "usb2-vbus";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ enable-active-high;
+ gpio = <&pio 7 3 0>;
+ };
+ };
};
--
1.8.4

View file

@ -1,31 +0,0 @@
From 336d23a348d6595cac9a282616e983dddb7c7600 Mon Sep 17 00:00:00 2001
From: arokux <arokux@gmail.com>
Date: Thu, 19 Sep 2013 21:24:20 +0200
Subject: [PATCH] ARM: sun7i: dt: Add bindings for USB clocks
---
arch/arm/boot/dts/sun7i-a20.dtsi | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/arch/arm/boot/dts/sun7i-a20.dtsi b/arch/arm/boot/dts/sun7i-a20.dtsi
index 81e6e74..4fe484c 100644
--- a/arch/arm/boot/dts/sun7i-a20.dtsi
+++ b/arch/arm/boot/dts/sun7i-a20.dtsi
@@ -85,6 +85,14 @@
clock-output-names = "pll6_sata", "pll6_other", "pll6";
};
+ usb:usb@0x01c200cc {
+ #clock-cells = <1>;
+ compatible = "allwinner,sun47i-usb-gates-clk";
+ reg = <0x01c200cc 0x4>;
+ clocks = <&pll6 1>;
+ clock-output-names = "usb_ohci0", "usb_ohci1", "usb_phy";
+ };
+
cpu: cpu@01c20054 {
#clock-cells = <0>;
compatible = "allwinner,sun4i-cpu-clk";
--
1.8.4

View file

@ -1,62 +0,0 @@
From b434c5aa38e2db0fff9fa39c6e47cc9d13afe8e1 Mon Sep 17 00:00:00 2001
From: arokux <arokux@gmail.com>
Date: Thu, 19 Sep 2013 21:36:10 +0200
Subject: [PATCH] ARM: sun7i: dt: Add USB EHCI bindings
---
arch/arm/boot/dts/sun7i-a20.dtsi | 33 +++++++++++++++++++++++++++++++++
1 file changed, 33 insertions(+)
diff --git a/arch/arm/boot/dts/sun7i-a20.dtsi b/arch/arm/boot/dts/sun7i-a20.dtsi
index 4fe484c..b4e4a5a 100644
--- a/arch/arm/boot/dts/sun7i-a20.dtsi
+++ b/arch/arm/boot/dts/sun7i-a20.dtsi
@@ -16,6 +16,11 @@
/ {
interrupt-parent = <&gic>;
+ aliases {
+ ehci1 = &ehci0;
+ ehci2 = &ehci1;
+ };
+
cpus {
#address-cells = <1>;
#size-cells = <0>;
@@ -434,5 +439,33 @@
#interrupt-cells = <3>;
interrupts = <1 9 0xf04>;
};
+
+ usb_rst: reset@0x01c200cc {
+ #reset-cells = <1>;
+ compatible = "allwinner,sun4i-clock-reset";
+ reg = <0x01c200cc 0x4>;
+ };
+
+ ehci0: ehci0@0x01c14000 {
+ compatible = "allwinner,sunxi-ehci";
+ reg = <0x01c14000 0x400 0x01c14800 0x4 0x01c13404 0x4>;
+ interrupts = <0 39 1>;
+ resets = <&usb_rst 1>;
+ reset-names = "ehci_reset";
+ clocks = <&usb 8>, <&ahb_gates 1>;
+ clock-names = "usb_phy", "ahb_ehci";
+ status = "disabled";
+ };
+
+ ehci1: ehci1@0x01c1c000 {
+ compatible = "allwinner,sunxi-ehci";
+ reg = <0x01c1c000 0x400 0x01c1c800 0x4 0x01c13404 0x4>;
+ interrupts = <0 40 1>;
+ resets = <&usb_rst 2>;
+ reset-names = "ehci_reset";
+ clocks = <&usb 8>, <&ahb_gates 3>;
+ clock-names = "usb_phy", "ahb_ehci";
+ status = "disabled";
+ };
};
};
--
1.8.4

View file

@ -1,31 +0,0 @@
From f4eb27ab7c9893a65fd414451459899cdd6334a7 Mon Sep 17 00:00:00 2001
From: arokux <arokux@gmail.com>
Date: Tue, 24 Sep 2013 20:02:39 +0200
Subject: [PATCH] ARM: sun5i: dt: Add bindings for USB Host clocks
---
arch/arm/boot/dts/sun5i-a13.dtsi | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/arch/arm/boot/dts/sun5i-a13.dtsi b/arch/arm/boot/dts/sun5i-a13.dtsi
index 9ac706a..aad270c 100644
--- a/arch/arm/boot/dts/sun5i-a13.dtsi
+++ b/arch/arm/boot/dts/sun5i-a13.dtsi
@@ -90,6 +90,14 @@
clock-output-names = "pll6_sata", "pll6_other", "pll6";
};
+ usb:usb@0x01c200cc {
+ #clock-cells = <1>;
+ compatible = "allwinner,sun5i-usb-gates-clk";
+ reg = <0x01c200cc 0x4>;
+ clocks = <&pll6 1>;
+ clock-output-names = "usb_ohci0", "usb_phy";
+ };
+
/* dummy is 200M */
cpu: cpu@01c20054 {
#clock-cells = <0>;
--
1.8.4

View file

@ -1,35 +0,0 @@
From aaf8700dfa1b19bbb994e2996bd293190c0cefbd Mon Sep 17 00:00:00 2001
From: arokux <arokux@gmail.com>
Date: Sun, 6 Oct 2013 14:04:50 +0200
Subject: [PATCH] clk: sun5i: Add support for USB clocks
---
drivers/clk/sunxi/clk-sunxi.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/drivers/clk/sunxi/clk-sunxi.c b/drivers/clk/sunxi/clk-sunxi.c
index cbe1516..f9b8b18 100644
--- a/drivers/clk/sunxi/clk-sunxi.c
+++ b/drivers/clk/sunxi/clk-sunxi.c
@@ -623,6 +623,10 @@ struct gates_data {
.mask = {0x1C0},
};
+static const struct gates_data sun5i_usb_gates_data __initconst = {
+ .mask = {0x140},
+};
+
static const struct gates_data sun5i_a10s_ahb_gates_data __initconst = {
.mask = {0x147667e7, 0x185915},
};
@@ -874,6 +878,7 @@ static void __init sunxi_divs_clk_setup(struct device_node *node,
{.compatible = "allwinner,sun47i-usb-gates-clk", .data = &sun47i_usb_gates_data,},
{.compatible = "allwinner,sun5i-a10s-ahb-gates-clk", .data = &sun5i_a10s_ahb_gates_data,},
{.compatible = "allwinner,sun5i-a13-ahb-gates-clk", .data = &sun5i_a13_ahb_gates_data,},
+ {.compatible = "allwinner,sun5i-usb-gates-clk", .data = &sun5i_usb_gates_data,},
{.compatible = "allwinner,sun6i-a31-ahb1-gates-clk", .data = &sun6i_a31_ahb1_gates_data,},
{.compatible = "allwinner,sun7i-a20-ahb-gates-clk", .data = &sun7i_a20_ahb_gates_data,},
{.compatible = "allwinner,sun4i-apb0-gates-clk", .data = &sun4i_apb0_gates_data,},
--
1.8.4

View file

@ -1,50 +0,0 @@
From d3f751a7afe959d53c2b9e71a25921aeb38e0837 Mon Sep 17 00:00:00 2001
From: arokux <arokux@gmail.com>
Date: Tue, 24 Sep 2013 20:03:40 +0200
Subject: [PATCH] ARM: sun5i: dt: Add USB EHCI bindings
---
arch/arm/boot/dts/sun5i-a13.dtsi | 21 +++++++++++++++++++++
1 file changed, 21 insertions(+)
diff --git a/arch/arm/boot/dts/sun5i-a13.dtsi b/arch/arm/boot/dts/sun5i-a13.dtsi
index aad270c..a271a2d 100644
--- a/arch/arm/boot/dts/sun5i-a13.dtsi
+++ b/arch/arm/boot/dts/sun5i-a13.dtsi
@@ -16,6 +16,10 @@
/ {
interrupt-parent = <&intc>;
+ aliases {
+ ehci1 = &ehci0;
+ };
+
cpus {
#address-cells = <1>;
#size-cells = <0>;
@@ -310,5 +314,22 @@
interrupts = <82>, <83>;
clocks = <&ahb_gates 28>;
};
+
+ usb_rst: reset@0x01c200cc {
+ #reset-cells = <1>;
+ compatible = "allwinner,sun4i-clock-reset";
+ reg = <0x01c200cc 0x4>;
+ };
+
+ ehci0: ehci0@0x01c14000 {
+ compatible = "allwinner,sunxi-ehci";
+ reg = <0x01c14000 0x400 0x01c14800 0x4 0x01c13404 0x4>;
+ interrupts = <39>;
+ resets = <&usb_rst 1>;
+ reset-names = "ehci_reset";
+ clocks = <&usb 8>, <&ahb_gates 1>;
+ clock-names = "usb_phy", "ahb_ehci";
+ status = "disabled";
+ };
};
};
--
1.8.4

View file

@ -1,62 +0,0 @@
From 0944583d288e594d10ed0015b3d45839c70f8931 Mon Sep 17 00:00:00 2001
From: arokux <arokux@gmail.com>
Date: Tue, 24 Sep 2013 20:07:53 +0200
Subject: [PATCH] ARM: sun5i: dt: Add EHCI bindings to A13-Olinuxino
---
arch/arm/boot/dts/sun5i-a13-olinuxino.dts | 27 +++++++++++++++++++++++++++
1 file changed, 27 insertions(+)
diff --git a/arch/arm/boot/dts/sun5i-a13-olinuxino.dts b/arch/arm/boot/dts/sun5i-a13-olinuxino.dts
index 9e508dc..e30b89f 100644
--- a/arch/arm/boot/dts/sun5i-a13-olinuxino.dts
+++ b/arch/arm/boot/dts/sun5i-a13-olinuxino.dts
@@ -30,6 +30,13 @@
allwinner,drive = <1>;
allwinner,pull = <0>;
};
+
+ usb1_vbus_pin: usb1_vbus_pin@0 {
+ allwinner,pins = "PG11";
+ allwinner,function = "gpio_out";
+ allwinner,drive = <0>;
+ allwinner,pull = <2>;
+ };
};
uart1: serial@01c28400 {
@@ -55,6 +62,11 @@
pinctrl-0 = <&i2c2_pins_a>;
status = "okay";
};
+
+ ehci0: ehci0@0x01c14000 {
+ vbus-supply = <&reg_usb1_vbus>;
+ status = "okay";
+ };
};
leds {
@@ -67,4 +79,19 @@
default-state = "on";
};
};
+
+ regulators {
+ compatible = "simple-bus";
+
+ reg_usb1_vbus: usb1-vbus {
+ compatible = "regulator-fixed";
+ pinctrl-names = "default";
+ pinctrl-0 = <&usb1_vbus_pin>;
+ regulator-name = "usb1-vbus";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ enable-active-high;
+ gpio = <&pio 6 11 0>;
+ };
+ };
};
--
1.8.4

View file

@ -1,84 +0,0 @@
From 630ccdf33652f8e35b8c84e939d5a86fad9612e2 Mon Sep 17 00:00:00 2001
From: arokux <arokux@gmail.com>
Date: Thu, 19 Sep 2013 21:50:21 +0200
Subject: [PATCH] ARM: sun7i: dt: Add USB EHCI bindings for A20-Olinuxino
---
arch/arm/boot/dts/sun7i-a20-olinuxino-micro.dts | 49 +++++++++++++++++++++++++
1 file changed, 49 insertions(+)
diff --git a/arch/arm/boot/dts/sun7i-a20-olinuxino-micro.dts b/arch/arm/boot/dts/sun7i-a20-olinuxino-micro.dts
index ead3013..e6b1e26 100644
--- a/arch/arm/boot/dts/sun7i-a20-olinuxino-micro.dts
+++ b/arch/arm/boot/dts/sun7i-a20-olinuxino-micro.dts
@@ -41,6 +41,20 @@
allwinner,drive = <1>;
allwinner,pull = <0>;
};
+
+ usb1_vbus_pin: usb1_vbus_pin@0 {
+ allwinner,pins = "PH6";
+ allwinner,function = "gpio_out";
+ allwinner,drive = <0>;
+ allwinner,pull = <2>;
+ };
+
+ usb2_vbus_pin: usb2_vbus_pin@0 {
+ allwinner,pins = "PH3";
+ allwinner,function = "gpio_out";
+ allwinner,drive = <0>;
+ allwinner,pull = <2>;
+ };
};
uart0: serial@01c28000 {
@@ -76,6 +90,15 @@
i2c2: i2c@01c2b400 {
pinctrl-names = "default";
pinctrl-0 = <&i2c2_pins_a>;
+ };
+
+ ehci0: ehci0@0x01c14000 {
+ vbus-supply = <&reg_usb1_vbus>;
+ status = "okay";
+ };
+
+ ehci1: ehci1@0x01c1c000 {
+ vbus-supply = <&reg_usb2_vbus>;
status = "okay";
};
};
@@ -91,4 +114,30 @@
default-state = "on";
};
};
+
+ regulators {
+ compatible = "simple-bus";
+
+ reg_usb1_vbus: usb1-vbus {
+ compatible = "regulator-fixed";
+ pinctrl-names = "default";
+ pinctrl-0 = <&usb1_vbus_pin>;
+ regulator-name = "usb1-vbus";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ enable-active-high;
+ gpio = <&pio 7 6 0>;
+ };
+
+ reg_usb2_vbus: usb2-vbus {
+ compatible = "regulator-fixed";
+ pinctrl-names = "default";
+ pinctrl-0 = <&usb2_vbus_pin>;
+ regulator-name = "usb2-vbus";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ enable-active-high;
+ gpio = <&pio 7 3 0>;
+ };
+ };
};
--
1.8.4

View file

@ -1,85 +0,0 @@
From 8ba068f40cce9612d2ac0879b6978274ab497d31 Mon Sep 17 00:00:00 2001
From: arokux <arokux@gmail.com>
Date: Thu, 19 Sep 2013 21:29:45 +0200
Subject: [PATCH] ARM: sun7i: dt: Add USB EHCI bindings for Cubieboard2
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Conflicts:
arch/arm/boot/dts/sun7i-a20-cubieboard2.dts
---
arch/arm/boot/dts/sun7i-a20-cubieboard2.dts | 45 +++++++++++++++++++++++++++++
1 file changed, 45 insertions(+)
diff --git a/arch/arm/boot/dts/sun7i-a20-cubieboard2.dts b/arch/arm/boot/dts/sun7i-a20-cubieboard2.dts
index a26711c..10ea99d 100644
--- a/arch/arm/boot/dts/sun7i-a20-cubieboard2.dts
+++ b/arch/arm/boot/dts/sun7i-a20-cubieboard2.dts
@@ -54,6 +54,20 @@
allwinner,drive = <0>;
allwinner,pull = <0>;
};
+
+ usb1_vbus_pin: usb1_vbus_pin@0 {
+ allwinner,pins = "PH6";
+ allwinner,function = "gpio_out";
+ allwinner,drive = <0>;
+ allwinner,pull = <2>;
+ };
+
+ usb2_vbus_pin: usb2_vbus_pin@0 {
+ allwinner,pins = "PH3";
+ allwinner,function = "gpio_out";
+ allwinner,drive = <0>;
+ allwinner,pull = <2>;
+ };
};
uart0: serial@01c28000 {
@@ -71,6 +85,15 @@
i2c1: i2c@01c2b000 {
pinctrl-names = "default";
pinctrl-0 = <&i2c1_pins_a>;
+ };
+
+ ehci0: ehci0@0x01c14000 {
+ vbus-supply = <&reg_usb1_vbus>;
+ status = "okay";
+ };
+
+ ehci1: ehci1@0x01c1c000 {
+ vbus-supply = <&reg_usb2_vbus>;
status = "okay";
};
@@ -112,5 +135,27 @@
gpio = <&pio 1 8 0>;
enable-active-high;
};
+
+ reg_usb1_vbus: usb1-vbus {
+ compatible = "regulator-fixed";
+ pinctrl-names = "default";
+ pinctrl-0 = <&usb1_vbus_pin>;
+ regulator-name = "usb1-vbus";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ enable-active-high;
+ gpio = <&pio 7 6 0>;
+ };
+
+ reg_usb2_vbus: usb2-vbus {
+ compatible = "regulator-fixed";
+ pinctrl-names = "default";
+ pinctrl-0 = <&usb2_vbus_pin>;
+ regulator-name = "usb2-vbus";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ enable-active-high;
+ gpio = <&pio 7 3 0>;
+ };
};
};
--
1.8.5.1

View file

@ -1,35 +0,0 @@
From 9468f2e1fb54a67c70f627b3cc75a692b3c2ebce Mon Sep 17 00:00:00 2001
From: Hans de Goede <hdegoede@redhat.com>
Date: Tue, 17 Dec 2013 23:26:45 +0100
Subject: [PATCH] ARM: dts: sun7i: Fix ehci interrupt types
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
arch/arm/boot/dts/sun7i-a20.dtsi | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/arch/arm/boot/dts/sun7i-a20.dtsi b/arch/arm/boot/dts/sun7i-a20.dtsi
index 9f99959..dcee675 100644
--- a/arch/arm/boot/dts/sun7i-a20.dtsi
+++ b/arch/arm/boot/dts/sun7i-a20.dtsi
@@ -648,7 +648,7 @@
ehci0: ehci0@0x01c14000 {
compatible = "allwinner,sunxi-ehci";
reg = <0x01c14000 0x400 0x01c14800 0x4 0x01c13404 0x4>;
- interrupts = <0 39 1>;
+ interrupts = <0 39 4>;
resets = <&usb_rst 1>;
reset-names = "ehci_reset";
clocks = <&usb 8>, <&ahb_gates 1>;
@@ -659,7 +659,7 @@
ehci1: ehci1@0x01c1c000 {
compatible = "allwinner,sunxi-ehci";
reg = <0x01c1c000 0x400 0x01c1c800 0x4 0x01c13404 0x4>;
- interrupts = <0 40 1>;
+ interrupts = <0 40 4>;
resets = <&usb_rst 2>;
reset-names = "ehci_reset";
clocks = <&usb 8>, <&ahb_gates 3>;
--
1.8.5.1

View file

@ -1,27 +0,0 @@
From e8966070a22744582a2b7b63d8dab82f05499eb2 Mon Sep 17 00:00:00 2001
From: Hans de Goede <hdegoede@redhat.com>
Date: Tue, 17 Dec 2013 23:27:03 +0100
Subject: [PATCH] ARM: sunxi-ehci: Fix resource check
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
drivers/usb/host/ehci-sunxi.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/usb/host/ehci-sunxi.c b/drivers/usb/host/ehci-sunxi.c
index e7e15cc..e050d78 100644
--- a/drivers/usb/host/ehci-sunxi.c
+++ b/drivers/usb/host/ehci-sunxi.c
@@ -332,7 +332,8 @@ static int sunxi_ehci_probe(struct platform_device *pdev)
if (pdev->resource[0].flags != IORESOURCE_MEM
|| pdev->resource[1].flags != IORESOURCE_MEM
|| pdev->resource[2].flags != IORESOURCE_MEM
- || pdev->resource[3].flags != IORESOURCE_IRQ) {
+ || (pdev->resource[3].flags & IORESOURCE_TYPE_BITS)
+ != IORESOURCE_IRQ) {
dev_err(&pdev->dev, "invalid resource type\n");
return -ENODEV;
}
--
1.8.5.1

View file

@ -1,109 +0,0 @@
From b0a614458fb67fdb53e1b5518dabb85d688b196e Mon Sep 17 00:00:00 2001
From: Hans de Goede <hdegoede@redhat.com>
Date: Tue, 17 Dec 2013 22:59:17 +0100
Subject: [PATCH] ARM: dts: sunxi: usb Vbus is 5v not 3.3v
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
arch/arm/boot/dts/sun4i-a10-a1000.dts | 8 ++++----
arch/arm/boot/dts/sun4i-a10-cubieboard.dts | 8 ++++----
arch/arm/boot/dts/sun5i-a13-olinuxino.dts | 4 ++--
arch/arm/boot/dts/sun7i-a20-cubieboard2.dts | 8 ++++----
4 files changed, 14 insertions(+), 14 deletions(-)
diff --git a/arch/arm/boot/dts/sun4i-a10-a1000.dts b/arch/arm/boot/dts/sun4i-a10-a1000.dts
index e3bfc59..315e607 100644
--- a/arch/arm/boot/dts/sun4i-a10-a1000.dts
+++ b/arch/arm/boot/dts/sun4i-a10-a1000.dts
@@ -147,8 +147,8 @@
pinctrl-names = "default";
pinctrl-0 = <&usb1_vbus_pin>;
regulator-name = "usb1-vbus";
- regulator-min-microvolt = <3300000>;
- regulator-max-microvolt = <3300000>;
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
enable-active-high;
gpio = <&pio 7 6 0>;
};
@@ -158,8 +158,8 @@
pinctrl-names = "default";
pinctrl-0 = <&usb2_vbus_pin>;
regulator-name = "usb2-vbus";
- regulator-min-microvolt = <3300000>;
- regulator-max-microvolt = <3300000>;
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
enable-active-high;
gpio = <&pio 7 3 0>;
};
diff --git a/arch/arm/boot/dts/sun4i-a10-cubieboard.dts b/arch/arm/boot/dts/sun4i-a10-cubieboard.dts
index 48864a4..0bd2aae 100644
--- a/arch/arm/boot/dts/sun4i-a10-cubieboard.dts
+++ b/arch/arm/boot/dts/sun4i-a10-cubieboard.dts
@@ -158,8 +158,8 @@
pinctrl-names = "default";
pinctrl-0 = <&usb1_vbus_pin>;
regulator-name = "usb1-vbus";
- regulator-min-microvolt = <3300000>;
- regulator-max-microvolt = <3300000>;
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
enable-active-high;
gpio = <&pio 7 6 0>;
};
@@ -169,8 +169,8 @@
pinctrl-names = "default";
pinctrl-0 = <&usb2_vbus_pin>;
regulator-name = "usb2-vbus";
- regulator-min-microvolt = <3300000>;
- regulator-max-microvolt = <3300000>;
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
enable-active-high;
gpio = <&pio 7 3 0>;
};
diff --git a/arch/arm/boot/dts/sun5i-a13-olinuxino.dts b/arch/arm/boot/dts/sun5i-a13-olinuxino.dts
index 4b73e3e..b255d1b 100644
--- a/arch/arm/boot/dts/sun5i-a13-olinuxino.dts
+++ b/arch/arm/boot/dts/sun5i-a13-olinuxino.dts
@@ -104,8 +104,8 @@
pinctrl-names = "default";
pinctrl-0 = <&usb1_vbus_pin>;
regulator-name = "usb1-vbus";
- regulator-min-microvolt = <3300000>;
- regulator-max-microvolt = <3300000>;
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
enable-active-high;
gpio = <&pio 6 11 0>;
};
diff --git a/arch/arm/boot/dts/sun7i-a20-cubieboard2.dts b/arch/arm/boot/dts/sun7i-a20-cubieboard2.dts
index 10ea99d..144b11a 100644
--- a/arch/arm/boot/dts/sun7i-a20-cubieboard2.dts
+++ b/arch/arm/boot/dts/sun7i-a20-cubieboard2.dts
@@ -141,8 +141,8 @@
pinctrl-names = "default";
pinctrl-0 = <&usb1_vbus_pin>;
regulator-name = "usb1-vbus";
- regulator-min-microvolt = <3300000>;
- regulator-max-microvolt = <3300000>;
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
enable-active-high;
gpio = <&pio 7 6 0>;
};
@@ -152,8 +152,8 @@
pinctrl-names = "default";
pinctrl-0 = <&usb2_vbus_pin>;
regulator-name = "usb2-vbus";
- regulator-min-microvolt = <3300000>;
- regulator-max-microvolt = <3300000>;
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
enable-active-high;
gpio = <&pio 7 3 0>;
};
--
1.8.5.1

View file

@ -1,290 +0,0 @@
From 1d4b3ab562fa87e2c7f05cf92af1ff4b6cd42581 Mon Sep 17 00:00:00 2001
From: Oliver Schinagl <oliver@schinagl.nl>
Date: Tue, 3 Sep 2013 12:33:27 +0200
Subject: [PATCH] ARM: sunxi: Initial support for Allwinner's Security ID fuses
Allwinner has electric fuses (efuse) on their line of chips. This driver
reads those fuses, seeds the kernel entropy and exports them as a sysfs
node.
These fuses are most likely to be programmed at the factory, encoding
things like Chip ID, some sort of serial number, etc. and appear to be
reasonably unique.
While in theory, these should be writeable by the user, it will probably
be inconvenient to do so. Allwinner recommends that a certain input pin,
labeled 'efuse_vddq', be connected to GND. To write these fuses however,
a 2.5 V programming voltage needs to be applied to this pin.
Even so, they can still be used to generate a board-unique mac from,
board unique RSA key and seed the kernel RNG.
On sun7i additional storage is available, this is initially used for an
UEFI BOOT key, Secure JTAG key, HDMI-HDCP key and vendor specific keys.
Currently supported are the following known chips:
Allwinner sun4i (A10)
Allwinner sun5i (A10s, A13)
Allwinner sun7i (A20)
Signed-off-by: Oliver Schinagl <oliver@schinagl.nl>
---
Documentation/ABI/testing/sysfs-driver-sunxi-sid | 22 +++
.../bindings/misc/allwinner,sunxi-sid.txt | 17 +++
drivers/misc/eeprom/Kconfig | 13 ++
drivers/misc/eeprom/Makefile | 1 +
drivers/misc/eeprom/sunxi_sid.c | 158 +++++++++++++++++++++
5 files changed, 211 insertions(+)
create mode 100644 Documentation/ABI/testing/sysfs-driver-sunxi-sid
create mode 100644 Documentation/devicetree/bindings/misc/allwinner,sunxi-sid.txt
create mode 100644 drivers/misc/eeprom/sunxi_sid.c
diff --git a/Documentation/ABI/testing/sysfs-driver-sunxi-sid b/Documentation/ABI/testing/sysfs-driver-sunxi-sid
new file mode 100644
index 0000000..ffb9536
--- /dev/null
+++ b/Documentation/ABI/testing/sysfs-driver-sunxi-sid
@@ -0,0 +1,22 @@
+What: /sys/devices/*/<our-device>/eeprom
+Date: August 2013
+Contact: Oliver Schinagl <oliver@schinagl.nl>
+Description: read-only access to the SID (Security-ID) on current
+ A-series SoC's from Allwinner. Currently supports A10, A10s, A13
+ and A20 CPU's. The earlier A1x series of SoCs exports 16 bytes,
+ whereas the newer A20 SoC exposes 512 bytes split into sections.
+ Besides the 16 bytes of SID, there's also an SJTAG area,
+ HDMI-HDCP key and some custom keys. Below a quick overview, for
+ details see the user manual:
+ 0x000 128 bit root-key (sun[457]i)
+ 0x010 128 bit boot-key (sun7i)
+ 0x020 64 bit security-jtag-key (sun7i)
+ 0x028 16 bit key configuration (sun7i)
+ 0x02b 16 bit custom-vendor-key (sun7i)
+ 0x02c 320 bit low general key (sun7i)
+ 0x040 32 bit read-control access (sun7i)
+ 0x064 224 bit low general key (sun7i)
+ 0x080 2304 bit HDCP-key (sun7i)
+ 0x1a0 768 bit high general key (sun7i)
+Users: any user space application which wants to read the SID on
+ Allwinner's A-series of CPU's.
diff --git a/Documentation/devicetree/bindings/misc/allwinner,sunxi-sid.txt b/Documentation/devicetree/bindings/misc/allwinner,sunxi-sid.txt
new file mode 100644
index 0000000..68ba372
--- /dev/null
+++ b/Documentation/devicetree/bindings/misc/allwinner,sunxi-sid.txt
@@ -0,0 +1,17 @@
+Allwinner sunxi-sid
+
+Required properties:
+- compatible: "allwinner,sun4i-sid" or "allwinner,sun7i-a20-sid".
+- reg: Should contain registers location and length
+
+Example for sun4i:
+ sid@01c23800 {
+ compatible = "allwinner,sun4i-sid";
+ reg = <0x01c23800 0x10>
+ };
+
+Example for sun7i:
+ sid@01c23800 {
+ compatible = "allwinner,sun7i-a20-sid";
+ reg = <0x01c23800 0x200>
+ };
diff --git a/drivers/misc/eeprom/Kconfig b/drivers/misc/eeprom/Kconfig
index 04f2e1f..9536852f 100644
--- a/drivers/misc/eeprom/Kconfig
+++ b/drivers/misc/eeprom/Kconfig
@@ -96,4 +96,17 @@ config EEPROM_DIGSY_MTC_CFG
If unsure, say N.
+config EEPROM_SUNXI_SID
+ tristate "Allwinner sunxi security ID support"
+ depends on ARCH_SUNXI && SYSFS
+ help
+ This is a driver for the 'security ID' available on various Allwinner
+ devices.
+
+ Due to the potential risks involved with changing e-fuses,
+ this driver is read-only.
+
+ This driver can also be built as a module. If so, the module
+ will be called sunxi_sid.
+
endmenu
diff --git a/drivers/misc/eeprom/Makefile b/drivers/misc/eeprom/Makefile
index fc1e81d..9507aec 100644
--- a/drivers/misc/eeprom/Makefile
+++ b/drivers/misc/eeprom/Makefile
@@ -4,4 +4,5 @@ obj-$(CONFIG_EEPROM_LEGACY) += eeprom.o
obj-$(CONFIG_EEPROM_MAX6875) += max6875.o
obj-$(CONFIG_EEPROM_93CX6) += eeprom_93cx6.o
obj-$(CONFIG_EEPROM_93XX46) += eeprom_93xx46.o
+obj-$(CONFIG_EEPROM_SUNXI_SID) += sunxi_sid.o
obj-$(CONFIG_EEPROM_DIGSY_MTC_CFG) += digsy_mtc_eeprom.o
diff --git a/drivers/misc/eeprom/sunxi_sid.c b/drivers/misc/eeprom/sunxi_sid.c
new file mode 100644
index 0000000..9c34e57
--- /dev/null
+++ b/drivers/misc/eeprom/sunxi_sid.c
@@ -0,0 +1,158 @@
+/*
+ * Copyright (c) 2013 Oliver Schinagl <oliver@schinagl.nl>
+ * http://www.linux-sunxi.org
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * This driver exposes the Allwinner security ID, efuses exported in byte-
+ * sized chunks.
+ */
+
+#include <linux/compiler.h>
+#include <linux/device.h>
+#include <linux/err.h>
+#include <linux/export.h>
+#include <linux/fs.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/kobject.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/random.h>
+#include <linux/slab.h>
+#include <linux/stat.h>
+#include <linux/sysfs.h>
+#include <linux/types.h>
+
+#define DRV_NAME "sunxi-sid"
+
+struct sunxi_sid_data {
+ void __iomem *reg_base;
+ unsigned int keysize;
+};
+
+/* We read the entire key, due to a 32 bit read alignment requirement. Since we
+ * want to return the requested byte, this results in somewhat slower code and
+ * uses 4 times more reads as needed but keeps code simpler. Since the SID is
+ * only very rarely probed, this is not really an issue.
+ */
+static u8 sunxi_sid_read_byte(const struct sunxi_sid_data *sid_data,
+ const unsigned int offset)
+{
+ u32 sid_key;
+
+ if (offset >= sid_data->keysize)
+ return 0;
+
+ sid_key = ioread32be(sid_data->reg_base + round_down(offset, 4));
+ sid_key >>= (offset % 4) * 8;
+
+ return sid_key; /* Only return the last byte */
+}
+
+static ssize_t sid_read(struct file *fd, struct kobject *kobj,
+ struct bin_attribute *attr, char *buf,
+ loff_t pos, size_t size)
+{
+ struct platform_device *pdev;
+ struct sunxi_sid_data *sid_data;
+ int i;
+
+ pdev = to_platform_device(kobj_to_dev(kobj));
+ sid_data = platform_get_drvdata(pdev);
+
+ if (pos < 0 || pos >= sid_data->keysize)
+ return 0;
+ if (size > sid_data->keysize - pos)
+ size = sid_data->keysize - pos;
+
+ for (i = 0; i < size; i++)
+ buf[i] = sunxi_sid_read_byte(sid_data, pos + i);
+
+ return i;
+}
+
+static struct bin_attribute sid_bin_attr = {
+ .attr = { .name = "eeprom", .mode = S_IRUGO, },
+ .read = sid_read,
+};
+
+static int sunxi_sid_remove(struct platform_device *pdev)
+{
+ device_remove_bin_file(&pdev->dev, &sid_bin_attr);
+ dev_dbg(&pdev->dev, "driver unloaded\n");
+
+ return 0;
+}
+
+static const struct of_device_id sunxi_sid_of_match[] = {
+ { .compatible = "allwinner,sun4i-sid", .data = (void *)16},
+ { .compatible = "allwinner,sun7i-a20-sid", .data = (void *)512},
+ {/* sentinel */},
+};
+MODULE_DEVICE_TABLE(of, sunxi_sid_of_match);
+
+static int sunxi_sid_probe(struct platform_device *pdev)
+{
+ struct sunxi_sid_data *sid_data;
+ struct resource *res;
+ const struct of_device_id *of_dev_id;
+ u8 *entropy;
+ unsigned int i;
+
+ sid_data = devm_kzalloc(&pdev->dev, sizeof(struct sunxi_sid_data),
+ GFP_KERNEL);
+ if (!sid_data)
+ return -ENOMEM;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ sid_data->reg_base = devm_ioremap_resource(&pdev->dev, res);
+ if (IS_ERR(sid_data->reg_base))
+ return PTR_ERR(sid_data->reg_base);
+
+ of_dev_id = of_match_device(sunxi_sid_of_match, &pdev->dev);
+ if (!of_dev_id)
+ return -ENODEV;
+ sid_data->keysize = (int)of_dev_id->data;
+
+ platform_set_drvdata(pdev, sid_data);
+
+ sid_bin_attr.size = sid_data->keysize;
+ if (device_create_bin_file(&pdev->dev, &sid_bin_attr))
+ return -ENODEV;
+
+ entropy = kzalloc(sizeof(u8) * sid_data->keysize, GFP_KERNEL);
+ for (i = 0; i < sid_data->keysize; i++)
+ entropy[i] = sunxi_sid_read_byte(sid_data, i);
+ add_device_randomness(entropy, sid_data->keysize);
+ kfree(entropy);
+
+ dev_dbg(&pdev->dev, "loaded\n");
+
+ return 0;
+}
+
+static struct platform_driver sunxi_sid_driver = {
+ .probe = sunxi_sid_probe,
+ .remove = sunxi_sid_remove,
+ .driver = {
+ .name = DRV_NAME,
+ .owner = THIS_MODULE,
+ .of_match_table = sunxi_sid_of_match,
+ },
+};
+module_platform_driver(sunxi_sid_driver);
+
+MODULE_AUTHOR("Oliver Schinagl <oliver@schinagl.nl>");
+MODULE_DESCRIPTION("Allwinner sunxi security id driver");
+MODULE_LICENSE("GPL");
--
1.8.4

View file

@ -1,84 +0,0 @@
From 3c6625e46113e600fb83468c9a963a10c5cebedc Mon Sep 17 00:00:00 2001
From: Oliver Schinagl <oliver@schinagl.nl>
Date: Tue, 3 Sep 2013 12:33:28 +0200
Subject: [PATCH] ARM: sunxi: dt: Add sunxi-sid to dts for sun4i, sun5i and
sun7i
This patch shall add support for the sunxi-sid driver to the device
tree for A10, A10s, A13 and A20.
Signed-off-by: Oliver Schinagl <oliver@schinagl.nl>
---
arch/arm/boot/dts/sun4i-a10.dtsi | 5 +++++
arch/arm/boot/dts/sun5i-a10s.dtsi | 5 +++++
arch/arm/boot/dts/sun5i-a13.dtsi | 5 +++++
arch/arm/boot/dts/sun7i-a20.dtsi | 5 +++++
4 files changed, 20 insertions(+)
diff --git a/arch/arm/boot/dts/sun4i-a10.dtsi b/arch/arm/boot/dts/sun4i-a10.dtsi
index c32770a..319cc6b 100644
--- a/arch/arm/boot/dts/sun4i-a10.dtsi
+++ b/arch/arm/boot/dts/sun4i-a10.dtsi
@@ -266,6 +266,11 @@
reg = <0x01c20c90 0x10>;
};
+ sid: eeprom@01c23800 {
+ compatible = "allwinner,sun4i-sid";
+ reg = <0x01c23800 0x10>;
+ };
+
uart0: serial@01c28000 {
compatible = "snps,dw-apb-uart";
reg = <0x01c28000 0x400>;
diff --git a/arch/arm/boot/dts/sun5i-a10s.dtsi b/arch/arm/boot/dts/sun5i-a10s.dtsi
index 3b4a057..5247674 100644
--- a/arch/arm/boot/dts/sun5i-a10s.dtsi
+++ b/arch/arm/boot/dts/sun5i-a10s.dtsi
@@ -255,6 +255,11 @@
reg = <0x01c20c90 0x10>;
};
+ sid: eeprom@01c23800 {
+ compatible = "allwinner,sun4i-sid";
+ reg = <0x01c23800 0x10>;
+ };
+
uart0: serial@01c28000 {
compatible = "snps,dw-apb-uart";
reg = <0x01c28000 0x400>;
diff --git a/arch/arm/boot/dts/sun5i-a13.dtsi b/arch/arm/boot/dts/sun5i-a13.dtsi
index f6091dc..ce8ef2a 100644
--- a/arch/arm/boot/dts/sun5i-a13.dtsi
+++ b/arch/arm/boot/dts/sun5i-a13.dtsi
@@ -222,6 +222,11 @@
reg = <0x01c20c90 0x10>;
};
+ sid: eeprom@01c23800 {
+ compatible = "allwinner,sun4i-sid";
+ reg = <0x01c23800 0x10>;
+ };
+
uart1: serial@01c28400 {
compatible = "snps,dw-apb-uart";
reg = <0x01c28400 0x400>;
diff --git a/arch/arm/boot/dts/sun7i-a20.dtsi b/arch/arm/boot/dts/sun7i-a20.dtsi
index b939d30..e46cfed 100644
--- a/arch/arm/boot/dts/sun7i-a20.dtsi
+++ b/arch/arm/boot/dts/sun7i-a20.dtsi
@@ -265,6 +265,11 @@
reg = <0x01c20c90 0x10>;
};
+ sid: eeprom@01c23800 {
+ compatible = "allwinner,sun7i-a20-sid";
+ reg = <0x01c23800 0x200>;
+ };
+
uart0: serial@01c28000 {
compatible = "snps,dw-apb-uart";
reg = <0x01c28000 0x400>;
--
1.8.4

View file

@ -1,542 +0,0 @@
From 9b6e3291426efc69d1e8bf257721997f3eeb3009 Mon Sep 17 00:00:00 2001
From: Carlo Caione <carlo.caione@gmail.com>
Date: Wed, 16 Oct 2013 20:30:27 +0200
Subject: [PATCH] ARM: sun4i/sun7i: RTC driver
This patch introduces the driver for the RTC in the Allwinner A10 and
A20 SoCs.
Signed-off-by: Carlo Caione <carlo.caione@gmail.com>
---
drivers/rtc/Kconfig | 7 +
drivers/rtc/Makefile | 1 +
drivers/rtc/rtc-sunxi.c | 487 ++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 495 insertions(+)
create mode 100644 drivers/rtc/rtc-sunxi.c
diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig
index 9654aa3..ef45e0b 100644
--- a/drivers/rtc/Kconfig
+++ b/drivers/rtc/Kconfig
@@ -1076,6 +1076,13 @@ config RTC_DRV_SUN4V
If you say Y here you will get support for the Hypervisor
based RTC on SUN4V systems.
+config RTC_DRV_SUNXI
+ tristate "Allwinner sun4i/sun7i RTC"
+ depends on ARCH_SUNXI
+ help
+ If you say Y here you will get support for the RTC found on
+ Allwinner A10/A20.
+
config RTC_DRV_STARFIRE
bool "Starfire RTC"
depends on SPARC64
diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile
index 2dff3d2..8b52b5a 100644
--- a/drivers/rtc/Makefile
+++ b/drivers/rtc/Makefile
@@ -115,6 +115,7 @@ obj-$(CONFIG_RTC_DRV_STARFIRE) += rtc-starfire.o
obj-$(CONFIG_RTC_DRV_STK17TA8) += rtc-stk17ta8.o
obj-$(CONFIG_RTC_DRV_STMP) += rtc-stmp3xxx.o
obj-$(CONFIG_RTC_DRV_SUN4V) += rtc-sun4v.o
+obj-$(CONFIG_RTC_DRV_SUNXI) += rtc-sunxi.o
obj-$(CONFIG_RTC_DRV_TEGRA) += rtc-tegra.o
obj-$(CONFIG_RTC_DRV_TEST) += rtc-test.o
obj-$(CONFIG_RTC_DRV_TILE) += rtc-tile.o
diff --git a/drivers/rtc/rtc-sunxi.c b/drivers/rtc/rtc-sunxi.c
new file mode 100644
index 0000000..ccd48ae
--- /dev/null
+++ b/drivers/rtc/rtc-sunxi.c
@@ -0,0 +1,487 @@
+/*
+ * An RTC driver for Allwinner A10/A20
+ *
+ * Copyright (c) 2013, Carlo Caione <carlo.caione@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/fs.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/rtc.h>
+#include <linux/types.h>
+
+#define SUNXI_LOSC_CTRL 0x0000
+#define SUNXI_LOSC_CTRL_RTC_HMS_ACC BIT(8)
+#define SUNXI_LOSC_CTRL_RTC_YMD_ACC BIT(7)
+
+#define SUNXI_RTC_YMD 0x0004
+
+#define SUNXI_RTC_HMS 0x0008
+
+#define SUNXI_ALRM_DHMS 0x000c
+
+#define SUNXI_ALRM_EN 0x0014
+#define SUNXI_ALRM_EN_CNT_EN BIT(8)
+
+#define SUNXI_ALRM_IRQ_EN 0x0018
+#define SUNXI_ALRM_IRQ_EN_CNT_IRQ_EN BIT(0)
+
+#define SUNXI_ALRM_IRQ_STA 0x001c
+#define SUNXI_ALRM_IRQ_STA_CNT_IRQ_PEND BIT(0)
+
+#define SUNXI_LOSC_CTRL_RTC_ACC \
+ (SUNXI_LOSC_CTRL_RTC_HMS_ACC | SUNXI_LOSC_CTRL_RTC_YMD_ACC)
+
+#define SUNXI_MASK_DH 0x0000001f
+#define SUNXI_MASK_SM 0x0000003f
+#define SUNXI_MASK_M 0x0000000f
+#define SUNXI_MASK_LY 0x00000001
+#define SUNXI_MASK_D 0x00000ffe
+#define SUNXI_MASK_M 0x0000000f
+
+#define SUNXI_GET(x, mask, shift) (((x) & ((mask) << (shift))) \
+ >> (shift))
+
+#define SUNXI_SET(x, mask, shift) (((x) & (mask)) << (shift))
+
+/* Get date values */
+#define SUNXI_DATE_GET_DAY_VALUE(x) SUNXI_GET(x, SUNXI_MASK_DH, 0)
+#define SUNXI_DATE_GET_MON_VALUE(x) SUNXI_GET(x, SUNXI_MASK_M, 8)
+#define SUNXI_DATE_GET_YEAR_VALUE(x, mask) SUNXI_GET(x, mask, 16)
+
+/* Get time values */
+#define SUNXI_TIME_GET_SEC_VALUE(x) SUNXI_GET(x, SUNXI_MASK_SM, 0)
+#define SUNXI_TIME_GET_MIN_VALUE(x) SUNXI_GET(x, SUNXI_MASK_SM, 8)
+#define SUNXI_TIME_GET_HOUR_VALUE(x) SUNXI_GET(x, SUNXI_MASK_DH, 16)
+
+/* Get alarm values */
+#define SUNXI_ALRM_GET_SEC_VALUE(x) SUNXI_GET(x, SUNXI_MASK_SM, 0)
+#define SUNXI_ALRM_GET_MIN_VALUE(x) SUNXI_GET(x, SUNXI_MASK_SM, 8)
+#define SUNXI_ALRM_GET_HOUR_VALUE(x) SUNXI_GET(x, SUNXI_MASK_DH, 16)
+
+/* Set date values */
+#define SUNXI_DATE_SET_DAY_VALUE(x) SUNXI_DATE_GET_DAY_VALUE(x)
+#define SUNXI_DATE_SET_MON_VALUE(x) SUNXI_SET(x, SUNXI_MASK_M, 8)
+#define SUNXI_DATE_SET_YEAR_VALUE(x, mask) SUNXI_SET(x, mask, 16)
+#define SUNXI_LEAP_SET_VALUE(x, shift) SUNXI_SET(x, SUNXI_MASK_LY, shift)
+
+/* Set time values */
+#define SUNXI_TIME_SET_SEC_VALUE(x) SUNXI_TIME_GET_SEC_VALUE(x)
+#define SUNXI_TIME_SET_MIN_VALUE(x) SUNXI_SET(x, SUNXI_MASK_SM, 8)
+#define SUNXI_TIME_SET_HOUR_VALUE(x) SUNXI_SET(x, SUNXI_MASK_DH, 16)
+
+/* set alarm values */
+#define SUNXI_ALRM_SET_SEC_VALUE(x) SUNXI_ALRM_GET_SEC_VALUE(x)
+#define SUNXI_ALRM_SET_MIN_VALUE(x) SUNXI_SET(x, SUNXI_MASK_SM, 8)
+#define SUNXI_ALRM_SET_HOUR_VALUE(x) SUNXI_SET(x, SUNXI_MASK_DH, 16)
+#define SUNXI_ALRM_SET_DAY_VALUE(x) SUNXI_SET(x, SUNXI_MASK_D, 21)
+
+/* time unit conversions */
+#define SEC_IN_MIN 60
+#define SEC_IN_HOUR (60 * SEC_IN_MIN)
+#define SEC_IN_DAY (24 * SEC_IN_HOUR)
+
+struct sunxi_rtc_data_year {
+ unsigned int min; /* min year allowed */
+ unsigned int max; /* max year allowed */
+ unsigned int off; /* data year offset */
+ unsigned int mask;
+ unsigned char leap_shift; /* bit shift to get the leap year */
+};
+
+static struct sunxi_rtc_data_year data_year_param[] = {
+ [0] = {
+ .min = 1970,
+ .max = 2100,
+ .off = 0,
+ .mask = 0x000000ff,
+ .leap_shift = 24,
+ },
+ [1] = {
+ .min = 2010,
+ .max = 2073,
+ .off = 110,
+ .mask = 0x0000003f,
+ .leap_shift = 22,
+ },
+};
+
+struct sunxi_rtc_dev {
+ struct rtc_device *rtc;
+ struct device *dev;
+ struct sunxi_rtc_data_year *data_year;
+ void __iomem *base;
+ int irq;
+};
+
+static irqreturn_t sunxi_rtc_alarmirq(int irq, void *id)
+{
+ struct sunxi_rtc_dev *chip = (struct sunxi_rtc_dev *) id;
+ u32 val;
+
+ val = readl(chip->base + SUNXI_ALRM_IRQ_STA);
+
+ if (val & SUNXI_ALRM_IRQ_STA_CNT_IRQ_PEND) {
+ val |= SUNXI_ALRM_IRQ_STA_CNT_IRQ_PEND;
+ writel(val, chip->base + SUNXI_ALRM_IRQ_STA);
+
+ rtc_update_irq(chip->rtc, 1, RTC_AF | RTC_IRQF);
+
+ return IRQ_HANDLED;
+ }
+
+ return IRQ_NONE;
+}
+
+static void sunxi_rtc_setaie(int to, struct sunxi_rtc_dev *chip)
+{
+ u32 alarm_val = 0;
+ u32 alarm_irq_val = 0;
+
+ if (to) {
+ alarm_val = readl(chip->base + SUNXI_ALRM_EN);
+ alarm_val |= SUNXI_ALRM_EN_CNT_EN;
+
+ alarm_irq_val = readl(chip->base + SUNXI_ALRM_IRQ_EN);
+ alarm_irq_val |= SUNXI_ALRM_IRQ_EN_CNT_IRQ_EN;
+ } else {
+ writel(SUNXI_ALRM_IRQ_STA_CNT_IRQ_PEND,
+ chip->base + SUNXI_ALRM_IRQ_STA);
+ }
+
+ writel(alarm_val, chip->base + SUNXI_ALRM_EN);
+ writel(alarm_irq_val, chip->base + SUNXI_ALRM_IRQ_EN);
+}
+
+static int sunxi_rtc_getalarm(struct device *dev, struct rtc_wkalrm *alrm)
+{
+ struct sunxi_rtc_dev *chip = dev_get_drvdata(dev);
+ struct rtc_time *alrm_tm = &alrm->time;
+ u32 alarm;
+ u32 alarm_en;
+ u32 date;
+
+ alarm = readl(chip->base + SUNXI_ALRM_DHMS);
+ date = readl(chip->base + SUNXI_RTC_YMD);
+
+ alrm_tm->tm_sec = SUNXI_ALRM_GET_SEC_VALUE(alarm);
+ alrm_tm->tm_min = SUNXI_ALRM_GET_MIN_VALUE(alarm);
+ alrm_tm->tm_hour = SUNXI_ALRM_GET_HOUR_VALUE(alarm);
+
+ alrm_tm->tm_mday = SUNXI_DATE_GET_DAY_VALUE(date);
+ alrm_tm->tm_mon = SUNXI_DATE_GET_MON_VALUE(date);
+ alrm_tm->tm_year = SUNXI_DATE_GET_YEAR_VALUE(date,
+ chip->data_year->mask);
+
+ alrm_tm->tm_year += chip->data_year->off;
+ alrm_tm->tm_mon -= 1;
+
+ alarm_en = readl(chip->base + SUNXI_ALRM_IRQ_EN);
+ if (alarm_en & SUNXI_ALRM_EN_CNT_EN)
+ alrm->enabled = 1;
+
+ return 0;
+}
+
+static int sunxi_rtc_gettime(struct device *dev, struct rtc_time *rtc_tm)
+{
+ struct sunxi_rtc_dev *chip = dev_get_drvdata(dev);
+ u32 date, time;
+ int t;
+
+ /* read again if the system was mid-updated
+ */
+ for (t = 0; t < 2; t++) {
+ date = readl(chip->base + SUNXI_RTC_YMD);
+ time = readl(chip->base + SUNXI_RTC_HMS);
+
+ rtc_tm->tm_sec = SUNXI_TIME_GET_SEC_VALUE(time);
+ rtc_tm->tm_min = SUNXI_TIME_GET_MIN_VALUE(time);
+ rtc_tm->tm_hour = SUNXI_TIME_GET_HOUR_VALUE(time);
+
+ rtc_tm->tm_mday = SUNXI_DATE_GET_DAY_VALUE(date);
+ rtc_tm->tm_mon = SUNXI_DATE_GET_MON_VALUE(date);
+ rtc_tm->tm_year = SUNXI_DATE_GET_YEAR_VALUE(date,
+ chip->data_year->mask);
+
+ if (rtc_tm->tm_sec == 0)
+ msleep(500);
+ else
+ break;
+ }
+
+ rtc_tm->tm_year += chip->data_year->off;
+ rtc_tm->tm_mon -= 1;
+
+ return rtc_valid_tm(rtc_tm);
+}
+
+static int sunxi_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm)
+{
+ struct sunxi_rtc_dev *chip = dev_get_drvdata(dev);
+ struct rtc_time *alrm_tm = &alrm->time;
+ struct rtc_time tm_now;
+ u32 alarm = 0;
+ unsigned long time_now = 0;
+ unsigned long time_set = 0;
+ unsigned long time_gap = 0;
+ unsigned long time_gap_day = 0;
+ unsigned long time_gap_hour = 0;
+ unsigned long time_gap_min = 0;
+ int ret = 0;
+
+ ret = sunxi_rtc_gettime(dev, &tm_now);
+ if (ret < 0) {
+ dev_err(dev, "Error in getting time\n");
+ return -EINVAL;
+ }
+
+ rtc_tm_to_time(alrm_tm, &time_set);
+ rtc_tm_to_time(&tm_now, &time_now);
+ if (time_set <= time_now) {
+ dev_err(dev, "Date to set in the past\n");
+ return -EINVAL;
+ }
+
+ time_gap = time_set - time_now;
+ time_gap_day = time_gap / SEC_IN_DAY;
+ time_gap -= time_gap_day * SEC_IN_DAY;
+ time_gap_hour = time_gap / SEC_IN_HOUR;
+ time_gap -= time_gap_hour * SEC_IN_HOUR;
+ time_gap_min = time_gap / SEC_IN_MIN;
+ time_gap -= time_gap_min * SEC_IN_MIN;
+
+ if (time_gap_day > 255) {
+ dev_err(dev, "Day must be in the range 0 - 255\n");
+ return -EINVAL;
+ }
+
+ sunxi_rtc_setaie(0, chip);
+ writel(0, chip->base + SUNXI_ALRM_DHMS);
+ usleep_range(100, 300);
+
+ alarm = SUNXI_ALRM_SET_SEC_VALUE(time_gap) |
+ SUNXI_ALRM_SET_MIN_VALUE(time_gap_min) |
+ SUNXI_ALRM_SET_HOUR_VALUE(time_gap_hour) |
+ SUNXI_ALRM_SET_DAY_VALUE(time_gap_day);
+ writel(alarm, chip->base + SUNXI_ALRM_DHMS);
+
+ writel(0, chip->base + SUNXI_ALRM_IRQ_EN);
+ writel(SUNXI_ALRM_IRQ_EN_CNT_IRQ_EN, chip->base + SUNXI_ALRM_IRQ_EN);
+
+ sunxi_rtc_setaie(alrm->enabled, chip);
+
+ return 0;
+}
+
+static int sunxi_rtc_settime(struct device *dev, struct rtc_time *rtc_tm)
+{
+ struct sunxi_rtc_dev *chip = dev_get_drvdata(dev);
+ u32 date = 0;
+ u32 time = 0;
+ int year;
+ int t;
+
+ year = rtc_tm->tm_year + 1900;
+ if (year < chip->data_year->min || year > chip->data_year->max) {
+ dev_err(dev, "rtc only supports year in range %d - %d\n",
+ chip->data_year->min, chip->data_year->max);
+ return -EINVAL;
+ }
+
+ rtc_tm->tm_year -= chip->data_year->off;
+ rtc_tm->tm_mon += 1;
+
+ date = SUNXI_DATE_SET_DAY_VALUE(rtc_tm->tm_mday) |
+ SUNXI_DATE_SET_MON_VALUE(rtc_tm->tm_mon) |
+ SUNXI_DATE_SET_YEAR_VALUE(rtc_tm->tm_year,
+ chip->data_year->mask);
+
+ if (is_leap_year(year))
+ date |= SUNXI_LEAP_SET_VALUE(1, chip->data_year->leap_shift);
+
+ time = SUNXI_TIME_SET_SEC_VALUE(rtc_tm->tm_sec) |
+ SUNXI_TIME_SET_MIN_VALUE(rtc_tm->tm_min) |
+ SUNXI_TIME_SET_HOUR_VALUE(rtc_tm->tm_hour);
+
+ writel(0, chip->base + SUNXI_RTC_HMS);
+ writel(0, chip->base + SUNXI_RTC_YMD);
+
+ writel(time, chip->base + SUNXI_RTC_HMS);
+
+ /* After writing the RCT HH-MM-SS register, the
+ * SUNXI_LOSC_CTRL_RTC_HMS_ACC bit is set and it will be cleared until
+ * the real writing operation is finished
+ */
+ for (t = 0; t < 3; t++) {
+ if ((readl(chip->base + SUNXI_LOSC_CTRL) &
+ SUNXI_LOSC_CTRL_RTC_HMS_ACC) && --t)
+ break;
+ else
+ msleep(50);
+ }
+ if (t == 0) {
+ dev_err(dev, "Failed to set rtc time.\n");
+ return -1;
+ }
+
+ writel(date, chip->base + SUNXI_RTC_YMD);
+
+ /* After writing the RCT YY-MM-DD register, the
+ * SUNXI_LOSC_CTRL_RTC_YMD_ACC bit is set and it will be cleared until
+ * the real writing operation is finished
+ */
+ for (t = 0; t < 3; t++) {
+ if ((readl(chip->base + SUNXI_LOSC_CTRL) &
+ SUNXI_LOSC_CTRL_RTC_YMD_ACC) && --t)
+ break;
+ else
+ msleep(50);
+ }
+ if (t == 0) {
+ dev_err(dev, "Failed to set rtc date.\n");
+ return -1;
+ }
+
+ /* wait about 70us to make sure the the time is really written into
+ * target */
+ usleep_range(70, 100);
+
+ return 0;
+}
+
+static int sunxi_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled)
+{
+ struct sunxi_rtc_dev *chip = dev_get_drvdata(dev);
+
+ if (!enabled)
+ sunxi_rtc_setaie(enabled, chip);
+
+ return 0;
+}
+
+static const struct rtc_class_ops sunxi_rtc_ops = {
+ .read_time = sunxi_rtc_gettime,
+ .set_time = sunxi_rtc_settime,
+ .read_alarm = sunxi_rtc_getalarm,
+ .set_alarm = sunxi_rtc_setalarm,
+ .alarm_irq_enable = sunxi_rtc_alarm_irq_enable
+};
+
+static const struct of_device_id sunxi_rtc_dt_ids[] = {
+ { .compatible = "allwinner,sun4i-rtc", .data = &data_year_param[0] },
+ { .compatible = "allwinner,sun7i-a20-rtc", .data = &data_year_param[1] },
+ { /* sentinel */ },
+};
+MODULE_DEVICE_TABLE(of, sunxi_rtc_dt_ids);
+
+
+static int sunxi_rtc_probe(struct platform_device *pdev)
+{
+ struct sunxi_rtc_dev *chip;
+ struct resource *res;
+ const struct of_device_id *of_id;
+ int ret;
+
+ chip = devm_kzalloc(&pdev->dev, sizeof(*chip), GFP_KERNEL);
+ if (!chip)
+ return -ENOMEM;
+
+ platform_set_drvdata(pdev, chip);
+ chip->dev = &pdev->dev;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ chip->base = devm_ioremap_resource(&pdev->dev, res);
+ if (IS_ERR(chip->base))
+ return PTR_ERR(chip->base);
+
+ chip->irq = platform_get_irq(pdev, 0);
+ if (chip->irq < 0) {
+ dev_err(&pdev->dev, "No IRQ resource\n");
+ return chip->irq;
+ }
+ ret = devm_request_irq(&pdev->dev, chip->irq, sunxi_rtc_alarmirq,
+ 0, dev_name(&pdev->dev), chip);
+ if (ret) {
+ dev_err(&pdev->dev, "Could not request IRQ\n");
+ return ret;
+ }
+
+ of_id = of_match_device(sunxi_rtc_dt_ids, &pdev->dev);
+ if (!of_id) {
+ dev_err(&pdev->dev, "Unable to setup RTC data\n");
+ return -ENODEV;
+ }
+ chip->data_year = (struct sunxi_rtc_data_year *) of_id->data;
+
+ /* clear the alarm count value */
+ writel(0, chip->base + SUNXI_ALRM_DHMS);
+
+ /* disable alarm, not generate irq pending */
+ writel(0, chip->base + SUNXI_ALRM_EN);
+
+ /* disable alarm week/cnt irq, unset to cpu */
+ writel(0, chip->base + SUNXI_ALRM_IRQ_EN);
+
+ /* clear alarm week/cnt irq pending */
+ writel(SUNXI_ALRM_IRQ_STA_CNT_IRQ_PEND, chip->base + SUNXI_ALRM_IRQ_STA);
+
+ chip->rtc = rtc_device_register("rtc-sunxi", &pdev->dev,
+ &sunxi_rtc_ops, THIS_MODULE);
+ if (IS_ERR(chip->rtc)) {
+ dev_err(&pdev->dev, "unable to register device\n");
+ return PTR_ERR(chip->rtc);
+ }
+
+ dev_info(&pdev->dev, "RTC enabled\n");
+
+ return 0;
+}
+
+static int sunxi_rtc_remove(struct platform_device *pdev)
+{
+ struct sunxi_rtc_dev *chip = platform_get_drvdata(pdev);
+
+ rtc_device_unregister(chip->rtc);
+
+ return 0;
+}
+
+static struct platform_driver sunxi_rtc_driver = {
+ .probe = sunxi_rtc_probe,
+ .remove = sunxi_rtc_remove,
+ .driver = {
+ .name = "sunxi-rtc",
+ .owner = THIS_MODULE,
+ .of_match_table = sunxi_rtc_dt_ids,
+ },
+};
+
+module_platform_driver(sunxi_rtc_driver);
+
+MODULE_DESCRIPTION("sunxi RTC driver");
+MODULE_AUTHOR("Carlo Caione <carlo.caione@gmail.com>");
+MODULE_LICENSE("GPL");
--
1.8.4

View file

@ -1,50 +0,0 @@
From 40a111b1ce47fabcff14a3bff131a4d118ada257 Mon Sep 17 00:00:00 2001
From: Carlo Caione <carlo.caione@gmail.com>
Date: Wed, 16 Oct 2013 20:30:26 +0200
Subject: [PATCH] ARM: dts: sun4i/sun7i: add RTC node
Add the RTC node to DTS for Allwinner A10 and Allwinner A20.
Signed-off-by: Carlo Caione <carlo.caione@gmail.com>
---
arch/arm/boot/dts/sun4i-a10.dtsi | 6 ++++++
arch/arm/boot/dts/sun7i-a20.dtsi | 6 ++++++
2 files changed, 12 insertions(+)
diff --git a/arch/arm/boot/dts/sun4i-a10.dtsi b/arch/arm/boot/dts/sun4i-a10.dtsi
index 084fef9..04819a7 100644
--- a/arch/arm/boot/dts/sun4i-a10.dtsi
+++ b/arch/arm/boot/dts/sun4i-a10.dtsi
@@ -393,6 +393,12 @@
reg = <0x01c20c90 0x10>;
};
+ rtc: rtc@01c20d00 {
+ compatible = "allwinner,sun4i-rtc";
+ reg = <0x01c20d00 0x20>;
+ interrupts = <24>;
+ };
+
sid: eeprom@01c23800 {
compatible = "allwinner,sun4i-sid";
reg = <0x01c23800 0x10>;
diff --git a/arch/arm/boot/dts/sun7i-a20.dtsi b/arch/arm/boot/dts/sun7i-a20.dtsi
index fe6cf18..b92e17b 100644
--- a/arch/arm/boot/dts/sun7i-a20.dtsi
+++ b/arch/arm/boot/dts/sun7i-a20.dtsi
@@ -381,6 +381,12 @@
reg = <0x01c20c90 0x10>;
};
+ rtc: rtc@01c20d00 {
+ compatible = "allwinner,sun7i-a20-rtc";
+ reg = <0x01c20d00 0x20>;
+ interrupts = <0 24 1>;
+ };
+
sid: eeprom@01c23800 {
compatible = "allwinner,sun7i-a20-sid";
reg = <0x01c23800 0x200>;
--
1.8.4

View file

@ -1,142 +0,0 @@
From 665414c8e7584be7f1a30f77cf3eae177e93fd3e Mon Sep 17 00:00:00 2001
From: Hans de Goede <hdegoede@redhat.com>
Date: Sat, 14 Dec 2013 22:46:20 +0100
Subject: [PATCH] ARM: dts: sun7i: Add support for mmc
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
arch/arm/boot/dts/sun7i-a20-cubieboard2.dts | 16 ++++++++++++
arch/arm/boot/dts/sun7i-a20-cubietruck.dts | 16 ++++++++++++
arch/arm/boot/dts/sun7i-a20-olinuxino-micro.dts | 32 +++++++++++++++++++++++
arch/arm/boot/dts/sun7i-a20.dtsi | 34 +++++++++++++++++++++++++
4 files changed, 98 insertions(+)
diff --git a/arch/arm/boot/dts/sun7i-a20-cubieboard2.dts b/arch/arm/boot/dts/sun7i-a20-cubieboard2.dts
index 5c51cb8..6aef299 100644
--- a/arch/arm/boot/dts/sun7i-a20-cubieboard2.dts
+++ b/arch/arm/boot/dts/sun7i-a20-cubieboard2.dts
@@ -34,7 +34,23 @@
};
};
+ sdc0: sdc@01c0f000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&sdc0_pins_a>;
+ pinctrl-1 = <&mmc0_cd_pin_cubieboard2>;
+ cd-gpios = <&pio 7 1 0>; /* PH1 */
+ cd-mode = <1>;
+ status = "okay";
+ };
+
pinctrl@01c20800 {
+ mmc0_cd_pin_cubieboard2: mmc0_cd_pin@0 {
+ allwinner,pins = "PH1";
+ allwinner,function = "gpio_in";
+ allwinner,drive = <0>;
+ allwinner,pull = <0>;
+ };
+
led_pins_cubieboard2: led_pins@0 {
allwinner,pins = "PH20", "PH21";
allwinner,function = "gpio_out";
diff --git a/arch/arm/boot/dts/sun7i-a20-cubietruck.dts b/arch/arm/boot/dts/sun7i-a20-cubietruck.dts
index 8a1009d..302c785 100644
diff --git a/arch/arm/boot/dts/sun7i-a20-olinuxino-micro.dts b/arch/arm/boot/dts/sun7i-a20-olinuxino-micro.dts
index ead3013..f271db9 100644
--- a/arch/arm/boot/dts/sun7i-a20-olinuxino-micro.dts
+++ b/arch/arm/boot/dts/sun7i-a20-olinuxino-micro.dts
@@ -34,7 +34,39 @@
};
};
+ sdc0: sdc@01c0f000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&sdc0_pins_a>;
+ pinctrl-1 = <&mmc0_cd_pin_olinuxinom>;
+ cd-gpios = <&pio 7 1 0>; /* PH1 */
+ cd-mode = <1>;
+ status = "okay";
+ };
+
+ sdc3: sdc@01c12000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&sdc3_pins_a>;
+ pinctrl-1 = <&mmc3_cd_pin_olinuxinom>;
+ cd-gpios = <&pio 7 11 0>; /* PH11 */
+ cd-mode = <1>;
+ status = "okay";
+ };
+
pinctrl@01c20800 {
+ mmc0_cd_pin_olinuxinom: mmc0_cd_pin@0 {
+ allwinner,pins = "PH1";
+ allwinner,function = "gpio_in";
+ allwinner,drive = <0>;
+ allwinner,pull = <0>;
+ };
+
+ mmc3_cd_pin_olinuxinom: mmc3_cd_pin@0 {
+ allwinner,pins = "PH11";
+ allwinner,function = "gpio_in";
+ allwinner,drive = <0>;
+ allwinner,pull = <0>;
+ };
+
led_pins_olinuxino: led_pins@0 {
allwinner,pins = "PH2";
allwinner,function = "gpio_out";
diff --git a/arch/arm/boot/dts/sun7i-a20.dtsi b/arch/arm/boot/dts/sun7i-a20.dtsi
index 63757c5..5f9440c 100644
--- a/arch/arm/boot/dts/sun7i-a20.dtsi
+++ b/arch/arm/boot/dts/sun7i-a20.dtsi
@@ -303,6 +303,26 @@
#size-cells = <0>;
};
+ sdc0: sdc@01c0f000 {
+ compatible = "allwinner,sun5i-mmc";
+ reg = <0x01c0f000 0x1000>;
+ clocks = <&ahb_gates 8>, <&mmc0>;
+ clock-names = "ahb", "mod";
+ interrupts = <0 32 4>;
+ bus-width = <4>;
+ status = "disabled";
+ };
+
+ sdc3: sdc@01c12000 {
+ compatible = "allwinner,sun5i-mmc";
+ reg = <0x01c12000 0x1000>;
+ clocks = <&ahb_gates 11>, <&mmc3>;
+ clock-names = "ahb", "mod";
+ interrupts = <0 35 4>;
+ bus-width = <4>;
+ status = "disabled";
+ };
+
pio: pinctrl@01c20800 {
compatible = "allwinner,sun7i-a20-pinctrl";
reg = <0x01c20800 0x400>;
@@ -366,6 +386,20 @@
allwinner,drive = <0>;
allwinner,pull = <0>;
};
+
+ sdc0_pins_a: sdc0@0 {
+ allwinner,pins = "PF0","PF1","PF2","PF3","PF4","PF5";
+ allwinner,function = "mmc0";
+ allwinner,drive = <3>;
+ allwinner,pull = <1>;
+ };
+
+ sdc3_pins_a: sdc3@0 {
+ allwinner,pins = "PI4","PI5","PI6","PI7","PI8","PI9";
+ allwinner,function = "mmc3";
+ allwinner,drive = <3>;
+ allwinner,pull = <1>;
+ };
};
timer@01c20c00 {
--
1.8.5.1

View file

@ -1,76 +0,0 @@
From 82cfcf4cf1329420180ef06b7aaec67928396112 Mon Sep 17 00:00:00 2001
From: Hans de Goede <hdegoede@redhat.com>
Date: Sat, 14 Dec 2013 22:45:39 +0100
Subject: [PATCH] ARM: dts: sun4i: Add support for mmc
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
arch/arm/boot/dts/sun4i-a10-cubieboard.dts | 16 ++++++++++++++++
arch/arm/boot/dts/sun4i-a10.dtsi | 16 ++++++++++++++++
2 files changed, 32 insertions(+)
diff --git a/arch/arm/boot/dts/sun4i-a10-cubieboard.dts b/arch/arm/boot/dts/sun4i-a10-cubieboard.dts
index 425a7db..d193937 100644
--- a/arch/arm/boot/dts/sun4i-a10-cubieboard.dts
+++ b/arch/arm/boot/dts/sun4i-a10-cubieboard.dts
@@ -42,7 +42,23 @@
status = "okay";
};
+ sdc0: sdc@01c0f000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&sdc0_pins_a>;
+ pinctrl-1 = <&mmc0_cd_pin_cubieboard>;
+ cd-gpios = <&pio 7 1 0>; /* PH1 */
+ cd-mode = <1>;
+ status = "okay";
+ };
+
pinctrl@01c20800 {
+ mmc0_cd_pin_cubieboard: mmc0_cd_pin@0 {
+ allwinner,pins = "PH1";
+ allwinner,function = "gpio_in";
+ allwinner,drive = <0>;
+ allwinner,pull = <0>;
+ };
+
led_pins_cubieboard: led_pins@0 {
allwinner,pins = "PH20", "PH21";
allwinner,function = "gpio_out";
diff --git a/arch/arm/boot/dts/sun4i-a10.dtsi b/arch/arm/boot/dts/sun4i-a10.dtsi
index 4dccdb0..13bccd5 100644
--- a/arch/arm/boot/dts/sun4i-a10.dtsi
+++ b/arch/arm/boot/dts/sun4i-a10.dtsi
@@ -306,6 +306,15 @@
#size-cells = <0>;
};
+ sdc0: sdc@01c0f000 {
+ compatible = "allwinner,sun4i-mmc";
+ reg = <0x01c0f000 0x1000>;
+ clocks = <&ahb_gates 8>, <&mmc0>;
+ interrupts = <32>;
+ bus-width = <4>;
+ status = "disabled";
+ };
+
intc: interrupt-controller@01c20400 {
compatible = "allwinner,sun4i-ic";
reg = <0x01c20400 0x400>;
@@ -376,6 +385,13 @@
allwinner,drive = <0>;
allwinner,pull = <0>;
};
+
+ sdc0_pins_a: sdc0@0 {
+ allwinner,pins = "PF0","PF1","PF2","PF3","PF4","PF5";
+ allwinner,function = "mmc0";
+ allwinner,drive = <3>;
+ allwinner,pull = <1>;
+ };
};
timer@01c20c00 {
--
1.8.5.1

View file

@ -1,204 +0,0 @@
From 36e4afca857c8b57bd661135d173bdf65b348f78 Mon Sep 17 00:00:00 2001
From: Hans de Goede <hdegoede@redhat.com>
Date: Sat, 14 Dec 2013 16:20:55 +0100
Subject: [PATCH] ARM: dts: sun5i: Add mmc support
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
arch/arm/boot/dts/sun5i-a10s-olinuxino-micro.dts | 32 ++++++++++++++++++++++
arch/arm/boot/dts/sun5i-a10s.dtsi | 34 ++++++++++++++++++++++++
arch/arm/boot/dts/sun5i-a13-olinuxino-micro.dts | 16 +++++++++++
arch/arm/boot/dts/sun5i-a13-olinuxino.dts | 16 +++++++++++
arch/arm/boot/dts/sun5i-a13.dtsi | 17 ++++++++++++
5 files changed, 115 insertions(+)
diff --git a/arch/arm/boot/dts/sun5i-a10s-olinuxino-micro.dts b/arch/arm/boot/dts/sun5i-a10s-olinuxino-micro.dts
index 3c9f8b3..e53fb12 100644
--- a/arch/arm/boot/dts/sun5i-a10s-olinuxino-micro.dts
+++ b/arch/arm/boot/dts/sun5i-a10s-olinuxino-micro.dts
@@ -34,7 +34,39 @@
};
};
+ sdc0: sdc@01c0f000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&sdc0_pins_a>;
+ pinctrl-1 = <&mmc0_cd_pin_olinuxino_micro>;
+ cd-gpios = <&pio 6 1 0>; /* PG1 */
+ cd-mode = <1>;
+ status = "okay";
+ };
+
+ sdc1: sdc@01c10000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&sdc1_pins_a>;
+ pinctrl-1 = <&mmc1_cd_pin_olinuxino_micro>;
+ cd-gpios = <&pio 6 13 0>; /* PG13 */
+ cd-mode = <1>;
+ status = "okay";
+ };
+
pinctrl@01c20800 {
+ mmc0_cd_pin_olinuxino_micro: mmc0_cd_pin@0 {
+ allwinner,pins = "PG1";
+ allwinner,function = "gpio_in";
+ allwinner,drive = <0>;
+ allwinner,pull = <0>;
+ };
+
+ mmc1_cd_pin_olinuxino_micro: mmc1_cd_pin@0 {
+ allwinner,pins = "PG13";
+ allwinner,function = "gpio_in";
+ allwinner,drive = <0>;
+ allwinner,pull = <0>;
+ };
+
led_pins_olinuxino: led_pins@0 {
allwinner,pins = "PE3";
allwinner,function = "gpio_out";
diff --git a/arch/arm/boot/dts/sun5i-a10s.dtsi b/arch/arm/boot/dts/sun5i-a10s.dtsi
index 83e183c..fdbc290 100644
--- a/arch/arm/boot/dts/sun5i-a10s.dtsi
+++ b/arch/arm/boot/dts/sun5i-a10s.dtsi
@@ -274,6 +274,26 @@
#size-cells = <0>;
};
+ sdc0: sdc@01c0f000 {
+ compatible = "allwinner,sun5i-mmc";
+ reg = <0x01c0f000 0x1000>;
+ clocks = <&ahb_gates 8>, <&mmc0>;
+ clock-names = "ahb", "mod";
+ interrupts = <32>;
+ bus-width = <4>;
+ status = "disabled";
+ };
+
+ sdc1: sdc@01c10000 {
+ compatible = "allwinner,sun5i-mmc";
+ reg = <0x01c10000 0x1000>;
+ clocks = <&ahb_gates 9>, <&mmc1>;
+ clock-names = "ahb", "mod";
+ interrupts = <33>;
+ bus-width = <4>;
+ status = "disabled";
+ };
+
intc: interrupt-controller@01c20400 {
compatible = "allwinner,sun4i-ic";
reg = <0x01c20400 0x400>;
@@ -344,6 +364,20 @@
allwinner,drive = <0>;
allwinner,pull = <0>;
};
+
+ sdc0_pins_a: sdc0@0 {
+ allwinner,pins = "PF0","PF1","PF2","PF3","PF4","PF5";
+ allwinner,function = "mmc0";
+ allwinner,drive = <3>;
+ allwinner,pull = <1>;
+ };
+
+ sdc1_pins_a: sdc1@0 {
+ allwinner,pins = "PG3","PG4","PG5","PG6","PG7","PG8";
+ allwinner,function = "mmc1";
+ allwinner,drive = <3>;
+ allwinner,pull = <1>;
+ };
};
timer@01c20c00 {
diff --git a/arch/arm/boot/dts/sun5i-a13-olinuxino-micro.dts b/arch/arm/boot/dts/sun5i-a13-olinuxino-micro.dts
index fe2ce0a..fbd4e7d 100644
--- a/arch/arm/boot/dts/sun5i-a13-olinuxino-micro.dts
+++ b/arch/arm/boot/dts/sun5i-a13-olinuxino-micro.dts
@@ -20,7 +20,23 @@
compatible = "olimex,a13-olinuxino-micro", "allwinner,sun5i-a13";
soc@01c00000 {
+ sdc0: sdc@01c0f000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&sdc0_pins_a>;
+ pinctrl-1 = <&mmc0_cd_pin_olinuxinom>;
+ cd-gpios = <&pio 6 0 0>; /* PG0 */
+ cd-mode = <1>;
+ status = "okay";
+ };
+
pinctrl@01c20800 {
+ mmc0_cd_pin_olinuxinom: mmc0_cd_pin@0 {
+ allwinner,pins = "PG0";
+ allwinner,function = "gpio_in";
+ allwinner,drive = <0>;
+ allwinner,pull = <0>;
+ };
+
led_pins_olinuxinom: led_pins@0 {
allwinner,pins = "PG9";
allwinner,function = "gpio_out";
diff --git a/arch/arm/boot/dts/sun5i-a13-olinuxino.dts b/arch/arm/boot/dts/sun5i-a13-olinuxino.dts
index 9e508dc..ce22c81 100644
--- a/arch/arm/boot/dts/sun5i-a13-olinuxino.dts
+++ b/arch/arm/boot/dts/sun5i-a13-olinuxino.dts
@@ -23,7 +23,23 @@
};
soc@01c00000 {
+ sdc0: sdc@01c0f000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&sdc0_pins_a>;
+ pinctrl-1 = <&mmc0_cd_pin_olinuxino>;
+ cd-gpios = <&pio 6 0 0>; /* PG0 */
+ cd-mode = <1>;
+ status = "okay";
+ };
+
pinctrl@01c20800 {
+ mmc0_cd_pin_olinuxino: mmc0_cd_pin@0 {
+ allwinner,pins = "PG0";
+ allwinner,function = "gpio_in";
+ allwinner,drive = <0>;
+ allwinner,pull = <0>;
+ };
+
led_pins_olinuxino: led_pins@0 {
allwinner,pins = "PG9";
allwinner,function = "gpio_out";
diff --git a/arch/arm/boot/dts/sun5i-a13.dtsi b/arch/arm/boot/dts/sun5i-a13.dtsi
index 0bb4300..0ca0819 100644
--- a/arch/arm/boot/dts/sun5i-a13.dtsi
+++ b/arch/arm/boot/dts/sun5i-a13.dtsi
@@ -255,6 +255,16 @@
#size-cells = <1>;
ranges;
+ sdc0: sdc@01c0f000 {
+ compatible = "allwinner,sun5i-mmc";
+ reg = <0x01c0f000 0x1000>;
+ clocks = <&ahb_gates 8>, <&mmc0>;
+ clock-names = "ahb", "mod";
+ interrupts = <32>;
+ bus-width = <4>;
+ status = "disabled";
+ };
+
intc: interrupt-controller@01c20400 {
compatible = "allwinner,sun4i-ic";
reg = <0x01c20400 0x400>;
@@ -307,6 +317,13 @@
allwinner,drive = <0>;
allwinner,pull = <0>;
};
+
+ sdc0_pins_a: sdc0@0 {
+ allwinner,pins = "PF0","PF1","PF2","PF3","PF4","PF5";
+ allwinner,function = "mmc0";
+ allwinner,drive = <3>;
+ allwinner,pull = <1>;
+ };
};
timer@01c20c00 {
--
1.8.5.1

View file

@ -1,55 +0,0 @@
From 447675f817b95881e9922f002de3fc7f6d6e9207 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?David=20Lanzend=C3=B6rfer?= <david.lanzendoerfer@o2s.ch>
Date: Fri, 6 Sep 2013 22:34:33 +0200
Subject: [PATCH] ARM: sunxi-mci: Add driver for SD/MMC hosts found within
Allwinner A1X SoCs
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
drivers/mmc/host/Kconfig | 8 +
drivers/mmc/host/Makefile | 2 +
drivers/mmc/host/sunxi-mci.c | 1056 ++++++++++++++++++++++++++++++++++++++++++
drivers/mmc/host/sunxi-mci.h | 334 +++++++++++++
4 files changed, 1400 insertions(+)
create mode 100644 drivers/mmc/host/sunxi-mci.c
create mode 100644 drivers/mmc/host/sunxi-mci.h
diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig
index 7fc5099..0df0322 100644
--- a/drivers/mmc/host/Kconfig
+++ b/drivers/mmc/host/Kconfig
@@ -665,3 +665,11 @@ config MMC_REALTEK_PCI
help
Say Y here to include driver code to support SD/MMC card interface
of Realtek PCI-E card reader
+
+config MMC_SUNXI
+ tristate "Allwinner A1X SD/MMC Host Controller support"
+ depends on ARCH_SUNXI
+ default y
+ help
+ This selects support for the SD/MMC Host Controller on
+ Allwinner A1X based SoCs.
diff --git a/drivers/mmc/host/Makefile b/drivers/mmc/host/Makefile
index c41d0c3..f76f783 100644
--- a/drivers/mmc/host/Makefile
+++ b/drivers/mmc/host/Makefile
@@ -52,6 +52,8 @@ obj-$(CONFIG_MMC_WMT) += wmt-sdmmc.o
obj-$(CONFIG_MMC_REALTEK_PCI) += rtsx_pci_sdmmc.o
+obj-$(CONFIG_MMC_SUNXI) += sunxi-mci.o
+
obj-$(CONFIG_MMC_SDHCI_PLTFM) += sdhci-pltfm.o
obj-$(CONFIG_MMC_SDHCI_CNS3XXX) += sdhci-cns3xxx.o
obj-$(CONFIG_MMC_SDHCI_ESDHC_IMX) += sdhci-esdhc-imx.o
diff --git a/drivers/mmc/host/sunxi-mci.c b/drivers/mmc/host/sunxi-mci.c
new file mode 100644
index 0000000..cbde1d3
diff --git a/drivers/mmc/host/sunxi-mci.h b/drivers/mmc/host/sunxi-mci.h
new file mode 100644
index 0000000..0f5f95c
\ No newline at end of file
--
1.8.5.1

View file

@ -1,42 +0,0 @@
From 518dfd76baef66d0ef4c256fc0f72ea06d6be8cc Mon Sep 17 00:00:00 2001
From: Hans de Goede <hdegoede@redhat.com>
Date: Sun, 15 Dec 2013 19:44:01 +0100
Subject: [PATCH] ARM: sunxi: clk: export clk_sunxi_mmc_phase_control
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
include/linux/clk/sunxi.h | 22 ++++++++++++++++++++++
1 file changed, 22 insertions(+)
create mode 100644 include/linux/clk/sunxi.h
diff --git a/include/linux/clk/sunxi.h b/include/linux/clk/sunxi.h
new file mode 100644
index 0000000..1ef5c89
--- /dev/null
+++ b/include/linux/clk/sunxi.h
@@ -0,0 +1,22 @@
+/*
+ * Copyright 2013 - Hans de Goede <hdegoede@redhat.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef __LINUX_CLK_SUNXI_H_
+#define __LINUX_CLK_SUNXI_H_
+
+#include <linux/clk.h>
+
+void clk_sunxi_mmc_phase_control(struct clk_hw *hw, u8 sample, u8 output);
+
+#endif
--
1.8.5.1

View file

@ -1,62 +0,0 @@
From e074907f73e0bc70740901fb4a05fdf5fc81b3ff Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Emilio=20L=C3=B3pez?= <emilio@elopez.com.ar>
Date: Fri, 20 Sep 2013 20:29:17 -0300
Subject: [PATCH] clk: sunxi: Implement MMC phase control
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Signed-off-by: Emilio López <emilio@elopez.com.ar>
---
drivers/clk/sunxi/clk-sunxi.c | 35 +++++++++++++++++++++++++++++++++++
1 file changed, 35 insertions(+)
diff --git a/drivers/clk/sunxi/clk-sunxi.c b/drivers/clk/sunxi/clk-sunxi.c
index 360d705..d2b8d3c 100644
--- a/drivers/clk/sunxi/clk-sunxi.c
+++ b/drivers/clk/sunxi/clk-sunxi.c
@@ -352,6 +352,41 @@ static void sun4i_get_mod0_factors(u32 *freq, u32 parent_rate,
/**
+ * clk_sunxi_mmc_phase_control() - configures MMC clock phase control
+ */
+
+void clk_sunxi_mmc_phase_control(struct clk_hw *hw, u8 sample, u8 output)
+{
+ #define to_clk_composite(_hw) container_of(_hw, struct clk_composite, hw)
+ #define to_clk_factors(_hw) container_of(_hw, struct clk_factors, hw)
+
+ struct clk_composite *composite = to_clk_composite(hw);
+ struct clk_hw *rate_hw = composite->rate_hw;
+ struct clk_factors *factors = to_clk_factors(rate_hw);
+ unsigned long flags = 0;
+ u32 reg;
+
+ if (factors->lock)
+ spin_lock_irqsave(factors->lock, flags);
+
+ reg = readl(factors->reg);
+
+ /* set sample clock phase control */
+ reg &= ~(0x7 << 20);
+ reg |= ((sample & 0x7) << 20);
+
+ /* set output clock phase control */
+ reg &= ~(0x7 << 8);
+ reg |= ((output & 0x7) << 8);
+
+ writel(reg, factors->reg);
+
+ if (factors->lock)
+ spin_unlock_irqrestore(factors->lock, flags);
+}
+
+
+/**
* sunxi_factors_clk_setup() - Setup function for factor clocks
*/
--
1.8.5.1

View file

@ -1,11 +0,0 @@
diff -ruN old/arch/arm/boot/dts/sun4i-a10.dtsi new/arch/arm/boot/dts/sun4i-a10.dtsi
--- old/arch/arm/boot/dts/sun4i-a10.dtsi 2014-01-04 01:59:34.000000000 +0100
+++ new/arch/arm/boot/dts/sun4i-a10.dtsi 2014-01-04 01:54:00.000000000 +0100
@@ -323,6 +323,7 @@
compatible = "allwinner,sun4i-mmc";
reg = <0x01c0f000 0x1000>;
clocks = <&ahb_gates 8>, <&mmc0>;
+ clock-names = "ahb", "mod";
interrupts = <32>;
bus-width = <4>;
status = "disabled";

View file

@ -1,60 +0,0 @@
From a4c21089299ba411d998b16423a76cbae111194e Mon Sep 17 00:00:00 2001
From: Oliver Schinagl <oliver@schinagl.nl>
Date: Mon, 2 Dec 2013 16:13:32 +0100
Subject: [PATCH] RFC: AHCI: libahci is missing DMA
The Allwinner sunxi platforms have patched in the following to enable
DMA. This patch enables DMA controllers for the SUNXI Architecture.
Signed-off-by: Olliver Schinagl <oliver@schinagl.nl>
---
drivers/ata/ahci.h | 6 ++++++
drivers/ata/libahci.c | 8 ++++++++
2 files changed, 14 insertions(+)
diff --git a/drivers/ata/ahci.h b/drivers/ata/ahci.h
index 2289efd..2bf2423 100644
--- a/drivers/ata/ahci.h
+++ b/drivers/ata/ahci.h
@@ -138,6 +138,7 @@ enum {
PORT_SCR_NTF = 0x3c, /* SATA phy register: SNotification */
PORT_FBS = 0x40, /* FIS-based Switching */
PORT_DEVSLP = 0x44, /* device sleep */
+ PORT_DMA = 0x70, /* direct memory access */
/* PORT_IRQ_{STAT,MASK} bits */
PORT_IRQ_COLD_PRES = (1 << 31), /* cold presence detect */
@@ -209,6 +210,11 @@ enum {
PORT_DEVSLP_DSP = (1 << 1), /* DevSlp present */
PORT_DEVSLP_ADSE = (1 << 0), /* Aggressive DevSlp enable */
+ /* PORT_DMA bits */
+ PORT_DMA_SETUP_OFFSET = 8, /* dma setup offset */
+ PORT_DMA_SETUP_MASK = (0xff << PORT_DMA_SETUP_OFFSET),/* dma mask */
+ PORT_DMA_SETUP_INIT = (0x44 << 0),
+
/* hpriv->flags bits */
#define AHCI_HFLAGS(flags) .private_data = (void *)(flags)
diff --git a/drivers/ata/libahci.c b/drivers/ata/libahci.c
index c482f8c..d697a74 100644
--- a/drivers/ata/libahci.c
+++ b/drivers/ata/libahci.c
@@ -570,6 +570,14 @@ void ahci_start_engine(struct ata_port *ap)
void __iomem *port_mmio = ahci_port_base(ap);
u32 tmp;
+#ifdef CONFIG_ARCH_SUNXI
+ /* Setup DMA before DMA start */
+ tmp = readl(port_mmio + PORT_DMA);
+ tmp &= ~PORT_DMA_SETUP_MASK;
+ tmp |= PORT_DMA_SETUP_INIT << PORT_DMA_SETUP_OFFSET;
+ writel(tmp, port_mmio + PORT_DMA);
+#endif
+
/* start DMA */
tmp = readl(port_mmio + PORT_CMD);
tmp |= PORT_CMD_START;
--
1.8.5.1

View file

@ -1,436 +0,0 @@
From b7f492ca20e480ea3402692e165f919f20145935 Mon Sep 17 00:00:00 2001
From: Oliver Schinagl <oliver@schinagl.nl>
Date: Tue, 3 Dec 2013 12:07:01 +0100
Subject: [PATCH] ARM: sunxi: Add an ahci-platform compatible AHCI driver for
the Allwinner SUNXi series of SoCs
This patch adds support for the sunxi series of SoC's by allwinner. It
plugs into the ahci-platform framework.
Note: Currently it uses a somewhat hackish approach that probably needs
a lot more work, but does the same as the IMX SoC's.
Signed-off-by: Olliver Schinagl <oliver@schinagl.nl>
---
.../devicetree/bindings/ata/ahci-sunxi.txt | 24 ++
drivers/ata/Kconfig | 9 +
drivers/ata/Makefile | 1 +
drivers/ata/ahci_platform.c | 12 +
drivers/ata/ahci_sunxi.c | 305 +++++++++++++++++++++
5 files changed, 351 insertions(+)
create mode 100644 Documentation/devicetree/bindings/ata/ahci-sunxi.txt
create mode 100644 drivers/ata/ahci_sunxi.c
diff --git a/Documentation/devicetree/bindings/ata/ahci-sunxi.txt b/Documentation/devicetree/bindings/ata/ahci-sunxi.txt
new file mode 100644
index 0000000..0792fa5
--- /dev/null
+++ b/Documentation/devicetree/bindings/ata/ahci-sunxi.txt
@@ -0,0 +1,24 @@
+Allwinner SUNXI AHCI SATA Controller
+
+SATA nodes are defined to describe on-chip Serial ATA controllers.
+Each SATA controller should have its own node.
+
+Required properties:
+- compatible : compatible list, contains "allwinner,sun4i-a10-ahci"
+- reg : <registers mapping>
+- interrupts : <interrupt mapping for AHCI IRQ>
+- clocks : clocks for ACHI
+- clock-names : clock names for AHCI
+
+Optional properties:
+- pwr-supply : regulator to control the power supply GPIO
+
+Example:
+ ahci@01c18000 {
+ compatible = "allwinner,sun4i-a10-ahci";
+ reg = <0x01c18000 0x1000>;
+ interrupts = <0 56 1>;
+ clocks = <&ahb_gates 25>, <&pll6 0>;
+ clock-names = "ahb_sata", "pll6_sata";
+ pwr-supply = <&reg_ahci_5v>;
+ };
diff --git a/drivers/ata/Kconfig b/drivers/ata/Kconfig
index 4e73772..b87e2ba 100644
--- a/drivers/ata/Kconfig
+++ b/drivers/ata/Kconfig
@@ -106,6 +106,15 @@ config AHCI_IMX
If unsure, say N.
+config AHCI_SUNXI
+ tristate "Allwinner sunxi AHCI SATA support"
+ depends on SATA_AHCI_PLATFORM && ARCH_SUNXI
+ help
+ This option enables support for the Allwinner sunxi SoC's
+ onboard AHCI SATA.
+
+ If unsure, say N.
+
config SATA_FSL
tristate "Freescale 3.0Gbps SATA support"
depends on FSL_SOC
diff --git a/drivers/ata/Makefile b/drivers/ata/Makefile
index 46518c6..246050b 100644
--- a/drivers/ata/Makefile
+++ b/drivers/ata/Makefile
@@ -11,6 +11,7 @@ obj-$(CONFIG_SATA_SIL24) += sata_sil24.o
obj-$(CONFIG_SATA_DWC) += sata_dwc_460ex.o
obj-$(CONFIG_SATA_HIGHBANK) += sata_highbank.o libahci.o
obj-$(CONFIG_AHCI_IMX) += ahci_imx.o
+obj-$(CONFIG_AHCI_SUNXI) += ahci_sunxi.o
# SFF w/ custom DMA
obj-$(CONFIG_PDC_ADMA) += pdc_adma.o
diff --git a/drivers/ata/ahci_platform.c b/drivers/ata/ahci_platform.c
index 4b231ba..1046b44 100644
--- a/drivers/ata/ahci_platform.c
+++ b/drivers/ata/ahci_platform.c
@@ -31,6 +31,7 @@ enum ahci_type {
AHCI, /* standard platform ahci */
IMX53_AHCI, /* ahci on i.mx53 */
STRICT_AHCI, /* delayed DMA engine start */
+ SUNXI_AHCI, /* ahci on sunxi */
};
static struct platform_device_id ahci_devtype[] = {
@@ -44,6 +45,9 @@ enum ahci_type {
.name = "strict-ahci",
.driver_data = STRICT_AHCI,
}, {
+ .name = "sunxi-ahci",
+ .driver_data = SUNXI_AHCI,
+ }, {
/* sentinel */
}
};
@@ -81,6 +85,14 @@ struct ata_port_operations ahci_platform_ops = {
.udma_mask = ATA_UDMA6,
.port_ops = &ahci_platform_ops,
},
+ [SUNXI_AHCI] = {
+ AHCI_HFLAGS (AHCI_HFLAG_32BIT_ONLY | AHCI_HFLAG_NO_MSI |
+ AHCI_HFLAG_NO_PMP | AHCI_HFLAG_YES_NCQ),
+ .flags = AHCI_FLAG_COMMON,
+ .pio_mask = ATA_PIO4,
+ .udma_mask = ATA_UDMA6,
+ .port_ops = &ahci_platform_ops,
+ },
};
static struct scsi_host_template ahci_platform_sht = {
diff --git a/drivers/ata/ahci_sunxi.c b/drivers/ata/ahci_sunxi.c
new file mode 100644
index 0000000..982641f
--- /dev/null
+++ b/drivers/ata/ahci_sunxi.c
@@ -0,0 +1,305 @@
+/*
+ * Allwinner sunxi AHCI SATA platform driver
+ * Copyright 2013 Olliver Schinagl <oliver@schinagl.nl>
+ *
+ * Based on the AHCI SATA platform driver by Freescale and Allwinner
+ * Based on code from
+ * Allwinner Technology Co., Ltd. <www.allwinnertech.com>
+ * Daniel Wang <danielwang@allwinnertech.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/kernel.h>
+#include <linux/regulator/consumer.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/mod_devicetable.h>
+#include <linux/of_device.h>
+#include <linux/ioport.h>
+#include <linux/device.h>
+#include <linux/gfp.h>
+#include <linux/clk.h>
+#include <linux/clk-provider.h>
+#include <linux/errno.h>
+#include <linux/ahci_platform.h>
+#include "ahci.h"
+
+#define DRV_NAME "sunxi-sata"
+
+#define AHCI_BISTAFR 0x00a0
+#define AHCI_BISTCR 0x00a4
+#define AHCI_BISTFCTR 0x00a8
+#define AHCI_BISTSR 0x00ac
+#define AHCI_BISTDECR 0x00b0
+#define AHCI_DIAGNR0 0x00b4
+#define AHCI_DIAGNR1 0x00b8
+#define AHCI_OOBR 0x00bc
+#define AHCI_PHYCS0R 0x00c0
+#define AHCI_PHYCS1R 0x00c4
+#define AHCI_PHYCS2R 0x00c8
+#define AHCI_TIMER1MS 0x00e0
+#define AHCI_GPARAM1R 0x00e8
+#define AHCI_GPARAM2R 0x00ec
+#define AHCI_PPARAMR 0x00f0
+#define AHCI_TESTR 0x00f4
+#define AHCI_VERSIONR 0x00f8
+#define AHCI_IDR 0x00fc
+#define AHCI_RWCR 0x00fc
+#define AHCI_P0DMACR 0x0170
+#define AHCI_P0PHYCR 0x0178
+#define AHCI_P0PHYSR 0x017c
+
+struct sunxi_ahci_data {
+ struct platform_device *ahci_pdev;
+ struct regulator *regulator;
+ struct clk *sata_clk;
+ struct clk *ahb_clk;
+};
+
+static void sunxi_clrbits(void __iomem *reg, u32 clr_val)
+{
+ u32 reg_val;
+
+ reg_val = readl(reg);
+ reg_val &= ~(clr_val);
+ writel(reg_val, reg);
+}
+
+static void sunxi_setbits(void __iomem *reg, u32 set_val)
+{
+ u32 reg_val;
+
+ reg_val = readl(reg);
+ reg_val |= set_val;
+ writel(reg_val, reg);
+}
+
+static void sunxi_clrsetbits(void __iomem *reg, u32 clr_val, u32 set_val)
+{
+ u32 reg_val;
+
+ reg_val = readl(reg);
+ reg_val &= ~(clr_val);
+ reg_val |= set_val;
+ writel(reg_val, reg);
+}
+
+static u32 sunxi_getbits(void __iomem *reg, u8 mask, u8 shift)
+{
+ return (readl(reg) >> shift) & mask;
+}
+
+static int sunxi_ahci_phy_init(struct device *dev, void __iomem *reg_base)
+{
+ u32 reg_val;
+ int timeout;
+
+ /* This magic is from the original code */
+ writel(0, reg_base + AHCI_RWCR);
+ mdelay(5);
+
+ sunxi_setbits(reg_base + AHCI_PHYCS1R, BIT(19));
+ sunxi_clrsetbits(reg_base + AHCI_PHYCS0R,
+ (0x7 << 24),
+ (0x5 << 24) | BIT(23) | BIT(18));
+ sunxi_clrsetbits(reg_base + AHCI_PHYCS1R,
+ (0x3 << 16) | (0x1f << 8) | (0x3 << 6),
+ (0x2 << 16) | (0x6 << 8) | (0x2 << 6));
+ sunxi_setbits(reg_base + AHCI_PHYCS1R, BIT(28) | BIT(15));
+ sunxi_clrbits(reg_base + AHCI_PHYCS1R, BIT(19));
+ sunxi_clrsetbits(reg_base + AHCI_PHYCS0R,
+ (0x7 << 20), (0x3 << 20));
+ sunxi_clrsetbits(reg_base + AHCI_PHYCS2R,
+ (0x1f << 5), (0x19 << 5));
+ mdelay(5);
+
+ sunxi_setbits(reg_base + AHCI_PHYCS0R, (0x1 << 19));
+
+ timeout = 0x100000;
+ do {
+ reg_val = sunxi_getbits(reg_base + AHCI_PHYCS0R, 0x7, 28);
+ } while (--timeout && (reg_val != 0x2));
+ if (!timeout)
+ dev_err(dev, "PHY power up failed.\n");
+
+ sunxi_setbits(reg_base + AHCI_PHYCS2R, (0x1 << 24));
+
+ timeout = 0x100000;
+ do {
+ reg_val = sunxi_getbits(reg_base + AHCI_PHYCS2R, 0x1, 24);
+ } while (--timeout && reg_val);
+ if (!timeout)
+ dev_err(dev, "PHY calibration failed.\n");
+ mdelay(15);
+
+ writel(0x7, reg_base + AHCI_RWCR);
+
+ return 0;
+}
+
+static int sunxi_ahci_init(struct device *dev, void __iomem *reg_base)
+{
+ struct sunxi_ahci_data *ahci_data;
+ int ret;
+
+ ahci_data = dev_get_drvdata(dev->parent);
+
+ ret = clk_prepare_enable(ahci_data->sata_clk);
+ if (ret < 0)
+ return ret;
+
+ ret = clk_prepare_enable(ahci_data->ahb_clk);
+ if (ret < 0)
+ return ret;
+
+ ret = regulator_enable(ahci_data->regulator);
+ if (ret)
+ return ret;
+
+ return sunxi_ahci_phy_init(dev, reg_base);
+}
+
+static void sunxi_ahci_exit(struct device *dev)
+{
+ struct sunxi_ahci_data *ahci_data;
+
+ ahci_data = dev_get_drvdata(dev->parent);
+
+ regulator_disable(ahci_data->regulator);
+
+ clk_disable_unprepare(ahci_data->ahb_clk);
+ clk_disable_unprepare(ahci_data->sata_clk);
+}
+
+static struct ahci_platform_data sunxi_ahci_pdata = {
+ .init = sunxi_ahci_init,
+ .exit = sunxi_ahci_exit,
+};
+
+static int sunxi_ahci_remove(struct platform_device *pdev)
+{
+ struct sunxi_ahci_data *ahci_data;
+
+ ahci_data = platform_get_drvdata(pdev);
+ platform_device_unregister(ahci_data->ahci_pdev);
+
+ dev_dbg(&pdev->dev, "driver unloaded\n");
+
+ return 0;
+}
+
+static const struct of_device_id sunxi_ahci_of_match[] = {
+ { .compatible = "allwinner,sun4i-a10-ahci", .data = &sunxi_ahci_pdata},
+ {/* sentinel */},
+};
+MODULE_DEVICE_TABLE(of, sunxi_ahci_of_match);
+
+static int sunxi_ahci_probe(struct platform_device *pdev)
+{
+ const struct ahci_platform_data *pdata;
+ const struct of_device_id *of_dev_id;
+ struct resource *mem, *irq, res[2];
+ struct platform_device *ahci_pdev;
+ struct sunxi_ahci_data *ahci_data;
+ struct regulator *regulator;
+ int ret;
+
+ regulator = devm_regulator_get(&pdev->dev, "pwr");
+ if (IS_ERR(regulator)) {
+ ret = PTR_ERR(regulator);
+ if (ret != -EPROBE_DEFER)
+ dev_err(&pdev->dev, "no regulator found (%d)\n", ret);
+ return ret;
+ }
+
+ ahci_data = devm_kzalloc(&pdev->dev, sizeof(*ahci_data), GFP_KERNEL);
+ if (!ahci_data)
+ return -ENOMEM;
+
+ ahci_pdev = platform_device_alloc("sunxi-ahci", -1);
+ if (!ahci_pdev)
+ return -ENODEV;
+
+ ahci_pdev->dev.parent = &pdev->dev;
+
+ ahci_data->regulator = regulator;
+ ahci_data->ahb_clk = devm_clk_get(&pdev->dev, "ahb_sata");
+ if (IS_ERR(ahci_data->ahb_clk)) {
+ ret = PTR_ERR(ahci_data->ahb_clk);
+ goto err_out;
+ }
+
+ ahci_data->sata_clk = devm_clk_get(&pdev->dev, "pll6_sata");
+ if (IS_ERR(ahci_data->sata_clk)) {
+ ret = PTR_ERR(ahci_data->sata_clk);
+ goto err_out;
+ }
+
+ ahci_data->ahci_pdev = ahci_pdev;
+ platform_set_drvdata(pdev, ahci_data);
+
+ ahci_pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32);
+ ahci_pdev->dev.dma_mask = &ahci_pdev->dev.coherent_dma_mask;
+ ahci_pdev->dev.of_node = pdev->dev.of_node;
+
+ of_dev_id = of_match_device(sunxi_ahci_of_match, &pdev->dev);
+ if (of_dev_id) {
+ pdata = of_dev_id->data;
+ } else {
+ ret = -EINVAL;
+ goto err_out;
+ }
+
+ mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+ if (!mem || !irq) {
+ ret = -ENOMEM;
+ goto err_out;
+ }
+ res[0] = *mem;
+ res[1] = *irq;
+ ret = platform_device_add_resources(ahci_pdev, res, 2);
+ if (ret)
+ goto err_out;
+
+ ret = platform_device_add_data(ahci_pdev, pdata, sizeof(*pdata));
+ if (ret)
+ goto err_out;
+
+ ret = platform_device_add(ahci_pdev);
+ if (ret)
+ goto err_out;
+
+ return 0;
+
+err_out:
+ platform_device_put(ahci_pdev);
+ return ret;
+}
+
+static struct platform_driver sunxi_ahci_driver = {
+ .probe = sunxi_ahci_probe,
+ .remove = sunxi_ahci_remove,
+ .driver = {
+ .name = DRV_NAME,
+ .owner = THIS_MODULE,
+ .of_match_table = sunxi_ahci_of_match,
+ },
+};
+module_platform_driver(sunxi_ahci_driver);
+
+MODULE_DESCRIPTION("Allwinner sunxi AHCI SATA platform driver");
+MODULE_AUTHOR("Olliver Schinagl <oliver@schinagl.nl>");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("ahci:sunxi");
--
1.8.5.1

View file

@ -1,193 +0,0 @@
From e5b4d58432bec91414e82069a402d61e6aed631e Mon Sep 17 00:00:00 2001
From: Oliver Schinagl <oliver@schinagl.nl>
Date: Tue, 3 Dec 2013 12:10:11 +0100
Subject: [PATCH] ARM: sunxi: dts: Add ahci support to a few A10 and A20 boards
This patch adds sunxi sata support to A10 and A20 boards that have such
a connector. Some boards also feature a regulator via a GPIO and support
for this is also added.
Signed-off-by: Olliver Schinagl <oliver@schinagl.nl>
---
arch/arm/boot/dts/sun4i-a10-cubieboard.dts | 27 +++++++++++++++++++++++++
arch/arm/boot/dts/sun4i-a10.dtsi | 9 +++++++++
arch/arm/boot/dts/sun7i-a20-cubieboard2.dts | 27 +++++++++++++++++++++++++
arch/arm/boot/dts/sun7i-a20-cubietruck.dts | 27 +++++++++++++++++++++++++
arch/arm/boot/dts/sun7i-a20-olinuxino-micro.dts | 26 ++++++++++++++++++++++++
arch/arm/boot/dts/sun7i-a20.dtsi | 9 +++++++++
6 files changed, 125 insertions(+)
diff --git a/arch/arm/boot/dts/sun4i-a10-cubieboard.dts b/arch/arm/boot/dts/sun4i-a10-cubieboard.dts
index d193937..63bd00d 100644
--- a/arch/arm/boot/dts/sun4i-a10-cubieboard.dts
+++ b/arch/arm/boot/dts/sun4i-a10-cubieboard.dts
@@ -51,7 +51,19 @@
status = "okay";
};
+ sata: ahci@01c18000 {
+ pwr-supply = <&reg_ahci_5v>;
+ status = "okay";
+ };
+
pinctrl@01c20800 {
+ ahci_pwr_pin: ahci_pwr_pin@0 {
+ allwinner,pins = "PB8";
+ allwinner,function = "gpio_out";
+ allwinner,drive = <0>;
+ allwinner,pull = <0>;
+ };
+
mmc0_cd_pin_cubieboard: mmc0_cd_pin@0 {
allwinner,pins = "PH1";
allwinner,function = "gpio_in";
@@ -102,4 +114,19 @@
linux,default-trigger = "heartbeat";
};
};
+
+ regulators {
+ compatible = "simple-bus";
+ pinctrl-names = "default";
+
+ reg_ahci_5v: ahci-5v {
+ compatible = "regulator-fixed";
+ regulator-name = "ahci-5v";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ pinctrl-0 = <&ahci_pwr_pin>;
+ gpio = <&pio 1 8 0>;
+ enable-active-high;
+ };
+ };
};
diff --git a/arch/arm/boot/dts/sun4i-a10.dtsi b/arch/arm/boot/dts/sun4i-a10.dtsi
index 13bccd5..a6dafec 100644
--- a/arch/arm/boot/dts/sun4i-a10.dtsi
+++ b/arch/arm/boot/dts/sun4i-a10.dtsi
@@ -315,6 +315,15 @@
status = "disabled";
};
+ sata: ahci@01c18000 {
+ compatible = "allwinner,sun4i-a10-ahci";
+ reg = <0x01c18000 0x1000>;
+ interrupts = <56>;
+ clocks = <&ahb_gates 25>, <&pll6 0>;
+ clock-names = "ahb_sata", "pll6_sata";
+ status = "disabled";
+ };
+
intc: interrupt-controller@01c20400 {
compatible = "allwinner,sun4i-ic";
reg = <0x01c20400 0x400>;
diff --git a/arch/arm/boot/dts/sun7i-a20-cubieboard2.dts b/arch/arm/boot/dts/sun7i-a20-cubieboard2.dts
index ea55563..1d810bb 100644
--- a/arch/arm/boot/dts/sun7i-a20-cubieboard2.dts
+++ b/arch/arm/boot/dts/sun7i-a20-cubieboard2.dts
@@ -28,7 +28,19 @@
status = "okay";
};
+ sata: ahci@01c18000 {
+ pwr-supply = <&reg_ahci_5v>;
+ status = "okay";
+ };
+
pinctrl@01c20800 {
+ ahci_pwr_pin: ahci_pwr_pin@0 {
+ allwinner,pins = "PB8";
+ allwinner,function = "gpio_out";
+ allwinner,drive = <0>;
+ allwinner,pull = <0>;
+ };
+
mmc0_cd_pin_cubieboard2: mmc0_cd_pin@0 {
allwinner,pins = "PH1";
allwinner,function = "gpio_in";
@@ -86,4 +98,19 @@
gpios = <&pio 7 20 0>;
};
};
+
+ regulators {
+ compatible = "simple-bus";
+ pinctrl-names = "default";
+
+ reg_ahci_5v: ahci-5v {
+ compatible = "regulator-fixed";
+ regulator-name = "ahci-5v";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ pinctrl-0 = <&ahci_pwr_pin>;
+ gpio = <&pio 1 8 0>;
+ enable-active-high;
+ };
+ };
};
diff --git a/arch/arm/boot/dts/sun7i-a20-olinuxino-micro.dts b/arch/arm/boot/dts/sun7i-a20-olinuxino-micro.dts
index bc04cc7..5e9f2ab 100644
--- a/arch/arm/boot/dts/sun7i-a20-olinuxino-micro.dts
+++ b/arch/arm/boot/dts/sun7i-a20-olinuxino-micro.dts
@@ -37,7 +37,19 @@
status = "okay";
};
+ sata: ahci@01c18000 {
+ pwr-supply = <&reg_ahci_5v>;
+ status = "okay";
+ };
+
pinctrl@01c20800 {
+ ahci_pwr_pin: ahci_pwr_pin@0 {
+ allwinner,pins = "PB8";
+ allwinner,function = "gpio_out";
+ allwinner,drive = <0>;
+ allwinner,pull = <0>;
+ };
+
mmc0_cd_pin_olinuxinom: mmc0_cd_pin@0 {
allwinner,pins = "PH1";
allwinner,function = "gpio_in";
@@ -116,4 +128,18 @@
default-state = "on";
};
};
+
+ regulators {
+ compatible = "simple-bus";
+
+ reg_ahci_5v: ahci-5v {
+ compatible = "regulator-fixed";
+ regulator-name = "ahci-5v";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ pinctrl-0 = <&ahci_pwr_pin>;
+ gpio = <&pio 1 8 0>;
+ enable-active-high;
+ };
+ };
};
diff --git a/arch/arm/boot/dts/sun7i-a20.dtsi b/arch/arm/boot/dts/sun7i-a20.dtsi
index 7ebfc89..f161590 100644
--- a/arch/arm/boot/dts/sun7i-a20.dtsi
+++ b/arch/arm/boot/dts/sun7i-a20.dtsi
@@ -432,6 +432,15 @@
};
};
+ sata: ahci@01c18000 {
+ compatible = "allwinner,sun4i-a10-ahci";
+ reg = <0x01c18000 0x1000>;
+ interrupts = <0 56 1>;
+ clocks = <&ahb_gates 25>, <&pll6 0>;
+ clock-names = "ahb_sata", "pll6_sata";
+ status = "disabled";
+ };
+
timer@01c20c00 {
compatible = "allwinner,sun4i-timer";
reg = <0x01c20c00 0x90>;
--
1.8.5.1

View file

@ -1,46 +0,0 @@
From e9c56f8d2f851fb6d6ce6794c0f5463b862a878e Mon Sep 17 00:00:00 2001
From: Maxime Ripard <maxime.ripard@free-electrons.com>
Date: Tue, 10 Dec 2013 19:40:43 +0100
Subject: [PATCH] net: allwinner: emac: Add missing free_irq
The sun4i-emac driver uses devm_request_irq at .ndo_open time, but relies on
the managed device mechanism to actually free it. This causes an issue whenever
someone wants to restart the interface, the interrupt still being held, and not
yet released.
Fall back to using the regular request_irq at .ndo_open time, and introduce a
free_irq during .ndo_stop.
Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
Cc: stable@vger.kernel.org # 3.11+
Signed-off-by: David S. Miller <davem@davemloft.net>
---
drivers/net/ethernet/allwinner/sun4i-emac.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/drivers/net/ethernet/allwinner/sun4i-emac.c b/drivers/net/ethernet/allwinner/sun4i-emac.c
index 50b853a..46dfb13 100644
--- a/drivers/net/ethernet/allwinner/sun4i-emac.c
+++ b/drivers/net/ethernet/allwinner/sun4i-emac.c
@@ -717,8 +717,7 @@ static int emac_open(struct net_device *dev)
if (netif_msg_ifup(db))
dev_dbg(db->dev, "enabling %s\n", dev->name);
- if (devm_request_irq(db->dev, dev->irq, &emac_interrupt,
- 0, dev->name, dev))
+ if (request_irq(dev->irq, &emac_interrupt, 0, dev->name, dev))
return -EAGAIN;
/* Initialize EMAC board */
@@ -774,6 +773,8 @@ static int emac_stop(struct net_device *ndev)
emac_shutdown(ndev);
+ free_irq(ndev->irq, ndev);
+
return 0;
}
--
1.8.5.1

View file

@ -1,70 +0,0 @@
From e751cce9b7b106b62c6d2c4f098c28c7feb10ef6 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Emilio=20L=C3=B3pez?= <emilio@elopez.com.ar>
Date: Sat, 16 Nov 2013 15:17:29 -0300
Subject: [PATCH] ARM: sunxi: dt: add EMAC aliases
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
U-Boot uses the ethernet0 alias to locate the right node to fill in
the MAC address of the first ethernet interface. This patch adds the
alias on all the sunxi SoCs with EMAC. In this way, people using
ethernet in U-Boot (eg, for tftp) can keep a consistent address on both
U-Boot and Linux with no additional effort.
Signed-off-by: Emilio López <emilio@elopez.com.ar>
Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
---
arch/arm/boot/dts/sun4i-a10.dtsi | 4 ++++
arch/arm/boot/dts/sun5i-a10s.dtsi | 4 ++++
arch/arm/boot/dts/sun7i-a20.dtsi | 4 ++++
3 files changed, 12 insertions(+)
diff --git a/arch/arm/boot/dts/sun4i-a10.dtsi b/arch/arm/boot/dts/sun4i-a10.dtsi
index f11f292..0bf70ee 100644
--- a/arch/arm/boot/dts/sun4i-a10.dtsi
+++ b/arch/arm/boot/dts/sun4i-a10.dtsi
@@ -15,6 +15,10 @@
/ {
interrupt-parent = <&intc>;
+ aliases {
+ ethernet0 = &emac;
+ };
+
cpus {
#address-cells = <1>;
#size-cells = <0>;
diff --git a/arch/arm/boot/dts/sun5i-a10s.dtsi b/arch/arm/boot/dts/sun5i-a10s.dtsi
index 5247674..b4764be 100644
--- a/arch/arm/boot/dts/sun5i-a10s.dtsi
+++ b/arch/arm/boot/dts/sun5i-a10s.dtsi
@@ -16,6 +16,10 @@
/ {
interrupt-parent = <&intc>;
+ aliases {
+ ethernet0 = &emac;
+ };
+
cpus {
cpu@0 {
compatible = "arm,cortex-a8";
diff --git a/arch/arm/boot/dts/sun7i-a20.dtsi b/arch/arm/boot/dts/sun7i-a20.dtsi
index 830fcd5..74bf906 100644
--- a/arch/arm/boot/dts/sun7i-a20.dtsi
+++ b/arch/arm/boot/dts/sun7i-a20.dtsi
@@ -16,6 +16,10 @@
/ {
interrupt-parent = <&gic>;
+ aliases {
+ ethernet0 = &emac;
+ };
+
cpus {
#address-cells = <1>;
#size-cells = <0>;
--
1.8.5.1

View file

@ -1,179 +0,0 @@
From 3e52e08e7f8f9cb1137f232e3bfa00f89ed27475 Mon Sep 17 00:00:00 2001
From: Maxime Ripard <maxime.ripard@free-electrons.com>
Date: Sat, 7 Dec 2013 12:38:32 +0100
Subject: [PATCH] ARM: sun7i: dt: Fix interrupt trigger types
The Allwinner A20 uses the ARM GIC as its internal interrupts controller. The
GIC can work on several interrupt triggers, and the A20 was actually setting it
up to use a rising edge as a trigger, while it was actually a level high
trigger, leading to some interrupts that would be completely ignored if the
edge was missed.
Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
Reported-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
arch/arm/boot/dts/sun7i-a20.dtsi | 42 ++++++++++++++++++++--------------------
1 file changed, 21 insertions(+), 21 deletions(-)
diff --git a/arch/arm/boot/dts/sun7i-a20.dtsi b/arch/arm/boot/dts/sun7i-a20.dtsi
index f1a6b24..0b7fcc1 100644
--- a/arch/arm/boot/dts/sun7i-a20.dtsi
+++ b/arch/arm/boot/dts/sun7i-a20.dtsi
@@ -298,7 +298,7 @@
emac: ethernet@01c0b000 {
compatible = "allwinner,sun4i-emac";
reg = <0x01c0b000 0x1000>;
- interrupts = <0 55 1>;
+ interrupts = <0 55 4>;
clocks = <&ahb_gates 17>;
status = "disabled";
};
@@ -324,7 +324,7 @@
pio: pinctrl@01c20800 {
compatible = "allwinner,sun7i-a20-pinctrl";
reg = <0x01c20800 0x400>;
- interrupts = <0 28 1>;
+ interrupts = <0 28 4>;
clocks = <&apb0_gates 5>;
gpio-controller;
interrupt-controller;
@@ -405,12 +405,12 @@
timer@01c20c00 {
compatible = "allwinner,sun4i-timer";
reg = <0x01c20c00 0x90>;
- interrupts = <0 22 1>,
- <0 23 1>,
- <0 24 1>,
- <0 25 1>,
- <0 67 1>,
- <0 68 1>;
+ interrupts = <0 22 4>,
+ <0 23 4>,
+ <0 24 4>,
+ <0 25 4>,
+ <0 67 4>,
+ <0 68 4>;
clocks = <&osc24M>;
};
@@ -432,7 +432,7 @@
uart0: serial@01c28000 {
compatible = "snps,dw-apb-uart";
reg = <0x01c28000 0x400>;
- interrupts = <0 1 1>;
+ interrupts = <0 1 4>;
reg-shift = <2>;
reg-io-width = <4>;
clocks = <&apb1_gates 16>;
@@ -442,7 +442,7 @@
uart1: serial@01c28400 {
compatible = "snps,dw-apb-uart";
reg = <0x01c28400 0x400>;
- interrupts = <0 2 1>;
+ interrupts = <0 2 4>;
reg-shift = <2>;
reg-io-width = <4>;
clocks = <&apb1_gates 17>;
@@ -452,7 +452,7 @@
uart2: serial@01c28800 {
compatible = "snps,dw-apb-uart";
reg = <0x01c28800 0x400>;
- interrupts = <0 3 1>;
+ interrupts = <0 3 4>;
reg-shift = <2>;
reg-io-width = <4>;
clocks = <&apb1_gates 18>;
@@ -462,7 +462,7 @@
uart3: serial@01c28c00 {
compatible = "snps,dw-apb-uart";
reg = <0x01c28c00 0x400>;
- interrupts = <0 4 1>;
+ interrupts = <0 4 4>;
reg-shift = <2>;
reg-io-width = <4>;
clocks = <&apb1_gates 19>;
@@ -472,7 +472,7 @@
uart4: serial@01c29000 {
compatible = "snps,dw-apb-uart";
reg = <0x01c29000 0x400>;
- interrupts = <0 17 1>;
+ interrupts = <0 17 4>;
reg-shift = <2>;
reg-io-width = <4>;
clocks = <&apb1_gates 20>;
@@ -482,7 +482,7 @@
uart5: serial@01c29400 {
compatible = "snps,dw-apb-uart";
reg = <0x01c29400 0x400>;
- interrupts = <0 18 1>;
+ interrupts = <0 18 4>;
reg-shift = <2>;
reg-io-width = <4>;
clocks = <&apb1_gates 21>;
@@ -492,7 +492,7 @@
uart6: serial@01c29800 {
compatible = "snps,dw-apb-uart";
reg = <0x01c29800 0x400>;
- interrupts = <0 19 1>;
+ interrupts = <0 19 4>;
reg-shift = <2>;
reg-io-width = <4>;
clocks = <&apb1_gates 22>;
@@ -502,7 +502,7 @@
uart7: serial@01c29c00 {
compatible = "snps,dw-apb-uart";
reg = <0x01c29c00 0x400>;
- interrupts = <0 20 1>;
+ interrupts = <0 20 4>;
reg-shift = <2>;
reg-io-width = <4>;
clocks = <&apb1_gates 23>;
@@ -512,7 +512,7 @@
i2c0: i2c@01c2ac00 {
compatible = "allwinner,sun4i-i2c";
reg = <0x01c2ac00 0x400>;
- interrupts = <0 7 1>;
+ interrupts = <0 7 4>;
clocks = <&apb1_gates 0>;
clock-frequency = <100000>;
status = "disabled";
@@ -521,7 +521,7 @@
i2c1: i2c@01c2b000 {
compatible = "allwinner,sun4i-i2c";
reg = <0x01c2b000 0x400>;
- interrupts = <0 8 1>;
+ interrupts = <0 8 4>;
clocks = <&apb1_gates 1>;
clock-frequency = <100000>;
status = "disabled";
@@ -530,7 +530,7 @@
i2c2: i2c@01c2b400 {
compatible = "allwinner,sun4i-i2c";
reg = <0x01c2b400 0x400>;
- interrupts = <0 9 1>;
+ interrupts = <0 9 4>;
clocks = <&apb1_gates 2>;
clock-frequency = <100000>;
status = "disabled";
@@ -539,7 +539,7 @@
i2c3: i2c@01c2b800 {
compatible = "allwinner,sun4i-i2c";
reg = <0x01c2b800 0x400>;
- interrupts = <0 88 1>;
+ interrupts = <0 88 4>;
clocks = <&apb1_gates 3>;
clock-frequency = <100000>;
status = "disabled";
@@ -548,7 +548,7 @@
i2c4: i2c@01c2bc00 {
compatible = "allwinner,sun4i-i2c";
reg = <0x01c2bc00 0x400>;
- interrupts = <0 89 1>;
+ interrupts = <0 89 4>;
clocks = <&apb1_gates 15>;
clock-frequency = <100000>;
status = "disabled";
--
1.8.5.1

View file

@ -1,11 +0,0 @@
diff -ruN old/arch/arm/boot/dts/Makefile new/arch/arm/boot/dts/Makefile
--- old/arch/arm/boot/dts/Makefile 2014-01-02 22:08:07.288255421 +0100
+++ new/arch/arm/boot/dts/Makefile 2014-01-02 21:25:02.000000000 +0100
@@ -231,6 +231,7 @@
sun4i-a10-cubieboard.dtb \
sun4i-a10-mini-xplus.dtb \
sun4i-a10-hackberry.dtb \
+ sun4i-a10-pcduino.dtb \
sun5i-a10s-olinuxino-micro.dtb \
sun5i-a13-olinuxino.dtb \
sun6i-a31-colombus.dtb \

View file

@ -1,12 +0,0 @@
Index: linux-3.12.5/arch/arm/boot/dts/Makefile
===================================================================
--- linux-3.12.5.orig/arch/arm/boot/dts/Makefile 2014-01-07 20:20:35.112013217 +0100
+++ linux-3.12.5/arch/arm/boot/dts/Makefile 2014-01-07 20:20:35.124013454 +0100
@@ -232,6 +232,7 @@
sun4i-a10-mini-xplus.dtb \
sun4i-a10-hackberry.dtb \
sun4i-a10-pcduino.dtb \
+ sun4i-a10-olinuxino-lime.dtb \
sun5i-a10s-olinuxino-micro.dtb \
sun5i-a13-olinuxino.dtb \
sun5i-a13-olinuxino-micro.dtb \

View file

@ -1,10 +0,0 @@
--- a/arch/arm/boot/dts/Makefile
+++ b/arch/arm/boot/dts/Makefile
@@ -235,6 +235,7 @@ dtb-$(CONFIG_ARCH_SUNXI) += \
sun5i-a13-olinuxino.dtb \
sun6i-a31-colombus.dtb \
sun7i-a20-cubieboard2.dtb \
+ sun7i-a20-cubietruck.dtb \
sun7i-a20-olinuxino-micro.dtb
dtb-$(CONFIG_ARCH_TEGRA) += tegra20-harmony.dtb \
tegra20-iris-512.dtb \