diff options
author | John Crispin <john@openwrt.org> | 2015-03-16 07:41:24 +0000 |
---|---|---|
committer | John Crispin <john@openwrt.org> | 2015-03-16 07:41:24 +0000 |
commit | c0a15a57bda510fac081d536013d16446baf6813 (patch) | |
tree | 941690d0c41e1342dbcdac9639e64605e230af51 | |
parent | eb396d656911024685f1f514036aec091669211f (diff) | |
download | upstream-c0a15a57bda510fac081d536013d16446baf6813.tar.gz upstream-c0a15a57bda510fac081d536013d16446baf6813.tar.bz2 upstream-c0a15a57bda510fac081d536013d16446baf6813.zip |
sunxi: drop 3.14 support
Signed-off-by: John Crispin <blogic@openwrt.org>
SVN-Revision: 44824
128 files changed, 0 insertions, 19237 deletions
diff --git a/target/linux/sunxi/config-3.14 b/target/linux/sunxi/config-3.14 deleted file mode 100644 index 848a809f33..0000000000 --- a/target/linux/sunxi/config-3.14 +++ /dev/null @@ -1,465 +0,0 @@ -CONFIG_AHCI_SUNXI=y -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_MIGHT_HAVE_PC_PARPORT=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_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_SUPPORTS_ATOMIC_RMW=y -CONFIG_ARCH_SUSPEND_POSSIBLE=y -CONFIG_ARCH_USE_BUILTIN_BSWAP=y -CONFIG_ARCH_USE_CMPXCHG_LOCKREF=y -CONFIG_ARCH_WANT_GENERAL_HUGETLB=y -CONFIG_ARCH_WANT_IPC_PARSE_VERSION=y -CONFIG_ARM=y -CONFIG_ARM_APPENDED_DTB=y -CONFIG_ARM_ARCH_TIMER_EVTSTREAM=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_PSCI=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_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_NET_CLASSID is not set -# CONFIG_CGROUP_PERF is not set -# CONFIG_CGROUP_SCHED 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=y -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_CRC16=y -CONFIG_CRC_T10DIF=y -CONFIG_CRYPTO_ARC4=y -CONFIG_CRYPTO_BLKCIPHER=y -CONFIG_CRYPTO_BLKCIPHER2=y -CONFIG_CRYPTO_CRC32C=y -CONFIG_CRYPTO_CRCT10DIF=y -CONFIG_CRYPTO_DES=y -CONFIG_CRYPTO_DEV_SUNXI_SS=y -CONFIG_CRYPTO_HASH=y -CONFIG_CRYPTO_HASH2=y -CONFIG_CRYPTO_HW=y -CONFIG_CRYPTO_MD5=y -CONFIG_CRYPTO_RNG2=y -CONFIG_CRYPTO_SHA1=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_DWMAC_SUNXI=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_MBCACHE=y -CONFIG_FS_POSIX_ACL=y -CONFIG_GARP=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_PCI_IOMAP=y -CONFIG_GENERIC_PHY=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_GPIO_SYSFS=y -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_ARM_ARCH_TIMER=y -# CONFIG_HAVE_BOOTMEM_INFO_NODE is not set -CONFIG_HAVE_BPF_JIT=y -CONFIG_HAVE_CC_STACKPROTECTOR=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_EFFICIENT_UNALIGNED_ACCESS=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_PERF_REGS=y -CONFIG_HAVE_PERF_USER_STACK_DUMP=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_HAVE_VIRT_CPU_ACCOUNTING_GEN=y -CONFIG_HIGHMEM=y -# CONFIG_HIGHPTE is not set -CONFIG_HWMON=y -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_AXP20X_PEK=y -CONFIG_INPUT_KEYBOARD=y -CONFIG_INPUT_MOUSEDEV=y -CONFIG_INPUT_MOUSEDEV_PSAUX=y -CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 -CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 -CONFIG_INPUT_TOUCHSCREEN=y -CONFIG_IOMMU_HELPER=y -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_JBD2=y -CONFIG_KALLSYMS=y -CONFIG_KERNEL_GZIP=y -# CONFIG_KERNEL_XZ is not set -CONFIG_KEYBOARD_SUN4I_LRADC=y -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_COMPRESS=y -CONFIG_LZO_DECOMPRESS=y -CONFIG_MAGIC_SYSRQ=y -CONFIG_MDIO_BOARDINFO=y -CONFIG_MDIO_SUN4I=y -# CONFIG_MEMCG is not set -CONFIG_MFD_AXP20X=y -CONFIG_MFD_CORE=y -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_MULTI_IRQ_HANDLER=y -CONFIG_MUTEX_SPIN_ON_OWNER=y -CONFIG_NAMESPACES=y -CONFIG_NEED_DMA_MAP_STATE=y -# CONFIG_NEON 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_NLS=y -CONFIG_NO_BOOTMEM=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_MTD=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_PHY_SUN4I_USB=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_PPS=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_DEVICETREE=y -CONFIG_PROC_EVENTS=y -CONFIG_PROC_PAGE_MONITOR=y -CONFIG_PROC_PID_CPUSET=y -CONFIG_PTP_1588_CLOCK=y -CONFIG_PWM=y -CONFIG_PWM_SUNXI=y -CONFIG_PWM_SYSFS=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_REGMAP=y -CONFIG_REGMAP_I2C=y -CONFIG_REGMAP_IRQ=y -CONFIG_REGULATOR=y -CONFIG_REGULATOR_AXP20X=y -# CONFIG_REGULATOR_DEBUG 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_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_SPI=y -CONFIG_SPI_MASTER=y -CONFIG_SPI_SUN4I=y -CONFIG_SPI_SUN6I=y -# CONFIG_STAGING is not set -# CONFIG_STMMAC_DA is not set -# CONFIG_STMMAC_DEBUG_FS is not set -CONFIG_STMMAC_ETH=y -CONFIG_STMMAC_PLATFORM=y -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=y -CONFIG_SWIOTLB=y -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_TOUCHSCREEN_ATMEL_MXT is not set -# CONFIG_TOUCHSCREEN_AUO_PIXCIR is not set -# CONFIG_TOUCHSCREEN_BU21013 is not set -# CONFIG_TOUCHSCREEN_CYTTSP4_CORE is not set -# CONFIG_TOUCHSCREEN_DYNAPRO is not set -# CONFIG_TOUCHSCREEN_EGALAX is not set -# CONFIG_TOUCHSCREEN_HAMPSHIRE is not set -# CONFIG_TOUCHSCREEN_MAX11801 is not set -# CONFIG_TOUCHSCREEN_PIXCIR is not set -# CONFIG_TOUCHSCREEN_ST1232 is not set -CONFIG_TOUCHSCREEN_SUN4I=y -# CONFIG_TOUCHSCREEN_TSC2005 is not set -# CONFIG_TOUCHSCREEN_TSC_SERIO is not set -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_EHCI_HCD=y -CONFIG_USB_EHCI_HCD_PLATFORM=y -CONFIG_USB_OHCI_HCD=y -CONFIG_USB_OHCI_HCD_PLATFORM=y -CONFIG_USB_STORAGE=y -CONFIG_USB_SUPPORT=y -# CONFIG_USER_NS is not set -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_CORE=y -# 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 diff --git a/target/linux/sunxi/patches-3.14/100-dt-sun4i-add-missing-serial-aliases.patch b/target/linux/sunxi/patches-3.14/100-dt-sun4i-add-missing-serial-aliases.patch deleted file mode 100644 index caa5d15874..0000000000 --- a/target/linux/sunxi/patches-3.14/100-dt-sun4i-add-missing-serial-aliases.patch +++ /dev/null @@ -1,28 +0,0 @@ -From b25983b215e889447ae670a158b1af5e7f253091 Mon Sep 17 00:00:00 2001 -From: Maxime Ripard <maxime.ripard@free-electrons.com> -Date: Thu, 2 Jan 2014 22:05:04 +0100 -Subject: [PATCH] ARM: sun4i: a10: Add missing serial aliases - -Some UART aliases have been defined, but not all of them. Add the remaining -ones to be consistent and to ease the parsing of the DT by the bootloaders. - -Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com> ---- - arch/arm/boot/dts/sun4i-a10.dtsi | 6 ++++++ - 1 file changed, 6 insertions(+) - ---- a/arch/arm/boot/dts/sun4i-a10.dtsi -+++ b/arch/arm/boot/dts/sun4i-a10.dtsi -@@ -19,6 +19,12 @@ - ethernet0 = &emac; - serial0 = &uart0; - serial1 = &uart1; -+ serial2 = &uart2; -+ serial3 = &uart3; -+ serial4 = &uart4; -+ serial5 = &uart5; -+ serial6 = &uart6; -+ serial7 = &uart7; - }; - - cpus { diff --git a/target/linux/sunxi/patches-3.14/101-dt-sun6i-add-missing-serial-aliases.patch b/target/linux/sunxi/patches-3.14/101-dt-sun6i-add-missing-serial-aliases.patch deleted file mode 100644 index dd0f741b0d..0000000000 --- a/target/linux/sunxi/patches-3.14/101-dt-sun6i-add-missing-serial-aliases.patch +++ /dev/null @@ -1,32 +0,0 @@ -From b6e3460ee25b8af673d00df0435a304f5dbf7c40 Mon Sep 17 00:00:00 2001 -From: Maxime Ripard <maxime.ripard@free-electrons.com> -Date: Thu, 2 Jan 2014 22:05:04 +0100 -Subject: [PATCH] ARM: sun6i: Add missing serial aliases - -Some UART aliases have been defined, but not all of them. Add the remaining -ones to be consistent and to ease the parsing of the DT by the bootloaders. - -Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com> ---- - arch/arm/boot/dts/sun6i-a31.dtsi | 10 ++++++++++ - 1 file changed, 10 insertions(+) - ---- a/arch/arm/boot/dts/sun6i-a31.dtsi -+++ b/arch/arm/boot/dts/sun6i-a31.dtsi -@@ -16,6 +16,16 @@ - / { - interrupt-parent = <&gic>; - -+ aliases { -+ serial0 = &uart0; -+ serial1 = &uart1; -+ serial2 = &uart2; -+ serial3 = &uart3; -+ serial4 = &uart4; -+ serial5 = &uart5; -+ }; -+ -+ - cpus { - #address-cells = <1>; - #size-cells = <0>; diff --git a/target/linux/sunxi/patches-3.14/102-dt-sun7i-add-missing-serial-aliases.patch b/target/linux/sunxi/patches-3.14/102-dt-sun7i-add-missing-serial-aliases.patch deleted file mode 100644 index 80daddc1fc..0000000000 --- a/target/linux/sunxi/patches-3.14/102-dt-sun7i-add-missing-serial-aliases.patch +++ /dev/null @@ -1,30 +0,0 @@ -From 1070f51b55d11e8831317d718acf2af46a181311 Mon Sep 17 00:00:00 2001 -From: Maxime Ripard <maxime.ripard@free-electrons.com> -Date: Thu, 2 Jan 2014 22:05:04 +0100 -Subject: [PATCH] ARM: sun7i: Add missing serial aliases - -Some UART aliases have been defined, but not all of them. Add the remaining -ones to be consistent and to ease the parsing of the DT by the bootloaders. - -Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com> ---- - arch/arm/boot/dts/sun7i-a20.dtsi | 8 ++++++++ - 1 file changed, 8 insertions(+) - ---- a/arch/arm/boot/dts/sun7i-a20.dtsi -+++ b/arch/arm/boot/dts/sun7i-a20.dtsi -@@ -18,6 +18,14 @@ - - aliases { - ethernet0 = &emac; -+ serial0 = &uart0; -+ serial1 = &uart1; -+ serial2 = &uart2; -+ serial3 = &uart3; -+ serial4 = &uart4; -+ serial5 = &uart5; -+ serial6 = &uart6; -+ serial7 = &uart7; - }; - - cpus { diff --git a/target/linux/sunxi/patches-3.14/103-dt-sun5i-add-missing-serial-aliases.patch b/target/linux/sunxi/patches-3.14/103-dt-sun5i-add-missing-serial-aliases.patch deleted file mode 100644 index cd991dd6bc..0000000000 --- a/target/linux/sunxi/patches-3.14/103-dt-sun5i-add-missing-serial-aliases.patch +++ /dev/null @@ -1,27 +0,0 @@ -From 0ffac463caf4b0022cf0d917552d51b3ec82849a Mon Sep 17 00:00:00 2001 -From: Maxime Ripard <maxime.ripard@free-electrons.com> -Date: Mon, 13 Jan 2014 11:08:47 +0100 -Subject: [PATCH] ARM: sun5i: a13: Add missing serial aliases - -Some UART aliases have been defined, but not all of them. Add the remaining -ones to be consistent and to ease the parsing of the DT by the bootloaders. - -Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com> ---- - arch/arm/boot/dts/sun5i-a13.dtsi | 5 +++++ - 1 file changed, 5 insertions(+) - ---- a/arch/arm/boot/dts/sun5i-a13.dtsi -+++ b/arch/arm/boot/dts/sun5i-a13.dtsi -@@ -16,6 +16,11 @@ - / { - interrupt-parent = <&intc>; - -+ aliases { -+ serial0 = &uart1; -+ serial1 = &uart3; -+ }; -+ - cpus { - #address-cells = <1>; - #size-cells = <0>; diff --git a/target/linux/sunxi/patches-3.14/104-dt-sun7i-add-pinmuxing-for-uart2.patch b/target/linux/sunxi/patches-3.14/104-dt-sun7i-add-pinmuxing-for-uart2.patch deleted file mode 100644 index 84baf3926d..0000000000 --- a/target/linux/sunxi/patches-3.14/104-dt-sun7i-add-pinmuxing-for-uart2.patch +++ /dev/null @@ -1,30 +0,0 @@ -From 875f2d579db0c3ea113f6367af9ccb32b3dbebcc Mon Sep 17 00:00:00 2001 -From: Chen-Yu Tsai <wens@csie.org> -Date: Tue, 14 Jan 2014 22:49:50 +0800 -Subject: [PATCH] ARM: dts: sun7i: add pin muxing options for UART2 - -UART2 is used on CubieTruck to connect to the Bluetooth module. -Add the pin set used in this case. - -Signed-off-by: Chen-Yu Tsai <wens@csie.org> -Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com> ---- - arch/arm/boot/dts/sun7i-a20.dtsi | 7 +++++++ - 1 file changed, 7 insertions(+) - ---- a/arch/arm/boot/dts/sun7i-a20.dtsi -+++ b/arch/arm/boot/dts/sun7i-a20.dtsi -@@ -381,6 +381,13 @@ - allwinner,pull = <0>; - }; - -+ uart2_pins_a: uart2@0 { -+ allwinner,pins = "PI16", "PI17", "PI18", "PI19"; -+ allwinner,function = "uart2"; -+ allwinner,drive = <0>; -+ allwinner,pull = <0>; -+ }; -+ - uart6_pins_a: uart6@0 { - allwinner,pins = "PI12", "PI13"; - allwinner,function = "uart6"; diff --git a/target/linux/sunxi/patches-3.14/105-dt-sun4i-add-linksprite-pcduino.patch b/target/linux/sunxi/patches-3.14/105-dt-sun4i-add-linksprite-pcduino.patch deleted file mode 100644 index 546381981d..0000000000 --- a/target/linux/sunxi/patches-3.14/105-dt-sun4i-add-linksprite-pcduino.patch +++ /dev/null @@ -1,78 +0,0 @@ -From 2fc6dcd5e7c76c203d2e174e70ef21393a231163 Mon Sep 17 00:00:00 2001 -From: Zoltan HERPAI <wigyori@uid0.hu> -Date: Mon, 13 Jan 2014 14:15:01 +0100 -Subject: [PATCH] ARM: sun4i: dt: Add basic board support for LinkSprite - pcDuino - -This patch will add a basic board support DT for the -LinkSprite pcDuino board. - -Signed-off-by: Zoltan HERPAI <wigyori@uid0.hu> -Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com> ---- - arch/arm/boot/dts/Makefile | 1 + - arch/arm/boot/dts/sun4i-a10-pcduino.dts | 48 +++++++++++++++++++++++++++++++++ - 2 files changed, 49 insertions(+) - create mode 100644 arch/arm/boot/dts/sun4i-a10-pcduino.dts - ---- a/arch/arm/boot/dts/Makefile -+++ b/arch/arm/boot/dts/Makefile -@@ -284,6 +284,7 @@ dtb-$(CONFIG_ARCH_SUNXI) += \ - 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 \ - sun5i-a13-olinuxino-micro.dtb \ ---- /dev/null -+++ b/arch/arm/boot/dts/sun4i-a10-pcduino.dts -@@ -0,0 +1,48 @@ -+/* -+ * Copyright 2014 Zoltan HERPAI -+ * Zoltan HERPAI <wigyori@uid0.hu> -+ * -+ * 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/ "sun4i-a10.dtsi" -+ -+/ { -+ model = "LinkSprite pcDuino"; -+ compatible = "linksprite,a10-pcduino", "allwinner,sun4i-a10"; -+ -+ soc@01c00000 { -+ emac: ethernet@01c0b000 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&emac_pins_a>; -+ phy = <&phy1>; -+ status = "okay"; -+ }; -+ -+ mdio@01c0b080 { -+ status = "okay"; -+ -+ phy1: ethernet-phy@1 { -+ reg = <1>; -+ }; -+ }; -+ -+ uart0: serial@01c28000 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&uart0_pins_a>; -+ status = "okay"; -+ }; -+ -+ i2c0: i2c@01c2ac00 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&i2c0_pins_a>; -+ status = "okay"; -+ }; -+ }; -+}; diff --git a/target/linux/sunxi/patches-3.14/106-dt-sun7i-add-arch-timer-node.patch b/target/linux/sunxi/patches-3.14/106-dt-sun7i-add-arch-timer-node.patch deleted file mode 100644 index 386f04295c..0000000000 --- a/target/linux/sunxi/patches-3.14/106-dt-sun7i-add-arch-timer-node.patch +++ /dev/null @@ -1,31 +0,0 @@ -From 0f9bb2cf6171f47d932df46e34cc5cfce384ff3d Mon Sep 17 00:00:00 2001 -From: Marc Zyngier <marc.zyngier@arm.com> -Date: Tue, 18 Feb 2014 14:04:44 +0000 -Subject: [PATCH] ARM: sun7i: add arch timer node - -The Allwinner A20 SoC is built around a pair of Cortex-A7 cores, -which have the usual generic timers. Report this in the DT. - -Signed-off-by: Marc Zyngier <marc.zyngier@arm.com> -Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com> ---- - arch/arm/boot/dts/sun7i-a20.dtsi | 8 ++++++++ - 1 file changed, 8 insertions(+) - ---- a/arch/arm/boot/dts/sun7i-a20.dtsi -+++ b/arch/arm/boot/dts/sun7i-a20.dtsi -@@ -49,6 +49,14 @@ - reg = <0x40000000 0x80000000>; - }; - -+ timer { -+ compatible = "arm,armv7-timer"; -+ interrupts = <1 13 0xf08>, -+ <1 14 0xf08>, -+ <1 11 0xf08>, -+ <1 10 0xf08>; -+ }; -+ - clocks { - #address-cells = <1>; - #size-cells = <1>; diff --git a/target/linux/sunxi/patches-3.14/107-dt-sun4i-add-a10-lime.patch b/target/linux/sunxi/patches-3.14/107-dt-sun4i-add-a10-lime.patch deleted file mode 100644 index d50f362fb0..0000000000 --- a/target/linux/sunxi/patches-3.14/107-dt-sun4i-add-a10-lime.patch +++ /dev/null @@ -1,141 +0,0 @@ -From a1c70ed831e4d5356618834202b0da3aa34e218e Mon Sep 17 00:00:00 2001 -From: Hans de Goede <hdegoede@redhat.com> -Date: Fri, 10 Jan 2014 23:23:06 +0100 -Subject: [PATCH] ARM: sun4i: dt: Add support for the A10-OLinuXino-LIME board - -This add support for the A10-OLinuXino-LIME: -https://www.olimex.com/Products/OLinuXino/A10/A10-OLinuXino-LIME - -A low cost Allwinner A10 based dev-board, with sata, ethernet, hdmi and 2x USB. - -Signed-off-by: Hans de Goede <hdegoede@redhat.com> ---- - arch/arm/boot/dts/Makefile | 1 + - arch/arm/boot/dts/sun4i-a10-olinuxino-lime.dts | 111 +++++++++++++++++++++++++ - 2 files changed, 112 insertions(+) - create mode 100644 arch/arm/boot/dts/sun4i-a10-olinuxino-lime.dts - ---- a/arch/arm/boot/dts/Makefile -+++ b/arch/arm/boot/dts/Makefile -@@ -284,6 +284,7 @@ dtb-$(CONFIG_ARCH_SUNXI) += \ - sun4i-a10-cubieboard.dtb \ - sun4i-a10-mini-xplus.dtb \ - sun4i-a10-hackberry.dtb \ -+ sun4i-a10-olinuxino-lime.dtb \ - sun4i-a10-pcduino.dtb \ - sun5i-a10s-olinuxino-micro.dtb \ - sun5i-a13-olinuxino.dtb \ ---- /dev/null -+++ b/arch/arm/boot/dts/sun4i-a10-olinuxino-lime.dts -@@ -0,0 +1,111 @@ -+/* -+ * Copyright 2014 - Hans de Goede <hdegoede@redhat.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/ "sun4i-a10.dtsi" -+/include/ "sunxi-common-regulators.dtsi" -+ -+/ { -+ model = "Olimex A10-OLinuXino-LIME"; -+ compatible = "olimex,a10-olinuxino-lime", "allwinner,sun4i-a10"; -+ -+ soc@01c00000 { -+ emac: ethernet@01c0b000 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&emac_pins_a>; -+ phy = <&phy1>; -+ status = "okay"; -+ }; -+ -+ mdio@01c0b080 { -+ status = "okay"; -+ -+ phy1: ethernet-phy@1 { -+ reg = <1>; -+ }; -+ }; -+ -+ usbphy: phy@01c13400 { -+ usb1_vbus-supply = <®_usb1_vbus>; -+ usb2_vbus-supply = <®_usb2_vbus>; -+ status = "okay"; -+ }; -+ -+ ehci0: usb@01c14000 { -+ status = "okay"; -+ }; -+ -+ ohci0: usb@01c14400 { -+ status = "okay"; -+ }; -+ -+ ahci: sata@01c18000 { -+ target-supply = <®_ahci_5v>; -+ status = "okay"; -+ }; -+ -+ ehci1: usb@01c1c000 { -+ status = "okay"; -+ }; -+ -+ ohci1: usb@01c1c400 { -+ status = "okay"; -+ }; -+ -+ pinctrl@01c20800 { -+ ahci_pwr_pin_olinuxinolime: ahci_pwr_pin@1 { -+ allwinner,pins = "PC3"; -+ allwinner,function = "gpio_out"; -+ allwinner,drive = <0>; -+ allwinner,pull = <0>; -+ }; -+ -+ led_pins_olinuxinolime: led_pins@0 { -+ allwinner,pins = "PH2"; -+ allwinner,function = "gpio_out"; -+ allwinner,drive = <1>; -+ allwinner,pull = <0>; -+ }; -+ }; -+ -+ uart0: serial@01c28000 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&uart0_pins_a>; -+ status = "okay"; -+ }; -+ }; -+ -+ leds { -+ compatible = "gpio-leds"; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&led_pins_olinuxinolime>; -+ -+ green { -+ label = "a10-olinuxino-lime:green:usr"; -+ gpios = <&pio 7 2 0>; -+ default-state = "on"; -+ }; -+ }; -+ -+ reg_ahci_5v: ahci-5v { -+ pinctrl-0 = <&ahci_pwr_pin_olinuxinolime>; -+ gpio = <&pio 2 3 0>; -+ status = "okay"; -+ }; -+ -+ reg_usb1_vbus: usb1-vbus { -+ status = "okay"; -+ }; -+ -+ reg_usb2_vbus: usb2-vbus { -+ status = "okay"; -+ }; -+}; diff --git a/target/linux/sunxi/patches-3.14/110-dt-sun6i-add-pll-and-spi-modclocks.patch b/target/linux/sunxi/patches-3.14/110-dt-sun6i-add-pll-and-spi-modclocks.patch deleted file mode 100644 index 7d8c2cfbd2..0000000000 --- a/target/linux/sunxi/patches-3.14/110-dt-sun6i-add-pll-and-spi-modclocks.patch +++ /dev/null @@ -1,77 +0,0 @@ -From 7f94ebf35b017f1664e957857a7f36752e2577cd Mon Sep 17 00:00:00 2001 -From: Maxime Ripard <maxime.ripard@free-electrons.com> -Date: Wed, 5 Feb 2014 14:05:04 +0100 -Subject: [PATCH] ARM: sun6i: dt: Add PLL6 and SPI module clocks - -The module clocks in the A31 are still compatible with the A10 one. Add the SPI -module clocks and the PLL6 in the device tree to allow their use by the SPI -controllers. - -Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com> ---- - arch/arm/boot/dts/sun6i-a31.dtsi | 46 ++++++++++++++++++++++++++++++++-------- - 1 file changed, 37 insertions(+), 9 deletions(-) - ---- a/arch/arm/boot/dts/sun6i-a31.dtsi -+++ b/arch/arm/boot/dts/sun6i-a31.dtsi -@@ -83,16 +83,12 @@ - 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 { -+ pll6: clk@01c20028 { - #clock-cells = <0>; -- compatible = "fixed-clock"; -- clock-frequency = <0>; -+ compatible = "allwinner,sun6i-a31-pll6-clk"; -+ reg = <0x01c20028 0x4>; -+ clocks = <&osc24M>; -+ clock-output-names = "pll6"; - }; - - cpu: cpu@01c20050 { -@@ -192,6 +188,38 @@ - "apb2_uart1", "apb2_uart2", "apb2_uart3", - "apb2_uart4", "apb2_uart5"; - }; -+ -+ spi0_clk: clk@01c200a0 { -+ #clock-cells = <0>; -+ compatible = "allwinner,sun4i-mod0-clk"; -+ reg = <0x01c200a0 0x4>; -+ clocks = <&osc24M>, <&pll6>; -+ clock-output-names = "spi0"; -+ }; -+ -+ spi1_clk: clk@01c200a4 { -+ #clock-cells = <0>; -+ compatible = "allwinner,sun4i-mod0-clk"; -+ reg = <0x01c200a4 0x4>; -+ clocks = <&osc24M>, <&pll6>; -+ clock-output-names = "spi1"; -+ }; -+ -+ spi2_clk: clk@01c200a8 { -+ #clock-cells = <0>; -+ compatible = "allwinner,sun4i-mod0-clk"; -+ reg = <0x01c200a8 0x4>; -+ clocks = <&osc24M>, <&pll6>; -+ clock-output-names = "spi2"; -+ }; -+ -+ spi3_clk: clk@01c200ac { -+ #clock-cells = <0>; -+ compatible = "allwinner,sun4i-mod0-clk"; -+ reg = <0x01c200ac 0x4>; -+ clocks = <&osc24M>, <&pll6>; -+ clock-output-names = "spi3"; -+ }; - }; - - soc@01c00000 { diff --git a/target/linux/sunxi/patches-3.14/111-dt-sun4i-rename-clocknodes.patch b/target/linux/sunxi/patches-3.14/111-dt-sun4i-rename-clocknodes.patch deleted file mode 100644 index 9846d5cdee..0000000000 --- a/target/linux/sunxi/patches-3.14/111-dt-sun4i-rename-clocknodes.patch +++ /dev/null @@ -1,134 +0,0 @@ -From 35b7dfc295f4d6079572a22a225c7444134e1f72 Mon Sep 17 00:00:00 2001 -From: Chen-Yu Tsai <wens@csie.org> -Date: Mon, 3 Feb 2014 09:51:41 +0800 -Subject: [PATCH] ARM: dts: sun4i: rename clock node names to clk@N - -Device tree naming conventions state that node names should match -node function. Change fully functioning clock nodes to match and -add clock-output-names to all sunxi clock nodes. - -Signed-off-by: Chen-Yu Tsai <wens@csie.org> -Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com> ---- - arch/arm/boot/dts/sun4i-a10.dtsi | 30 ++++++++++++++++++++---------- - 1 file changed, 20 insertions(+), 10 deletions(-) - ---- a/arch/arm/boot/dts/sun4i-a10.dtsi -+++ b/arch/arm/boot/dts/sun4i-a10.dtsi -@@ -58,34 +58,38 @@ - clock-frequency = <0>; - }; - -- osc24M: osc24M@01c20050 { -+ osc24M: clk@01c20050 { - #clock-cells = <0>; - compatible = "allwinner,sun4i-osc-clk"; - reg = <0x01c20050 0x4>; - clock-frequency = <24000000>; -+ clock-output-names = "osc24M"; - }; - -- osc32k: osc32k { -+ osc32k: clk@0 { - #clock-cells = <0>; - compatible = "fixed-clock"; - clock-frequency = <32768>; -+ clock-output-names = "osc32k"; - }; - -- pll1: pll1@01c20000 { -+ pll1: clk@01c20000 { - #clock-cells = <0>; - compatible = "allwinner,sun4i-pll1-clk"; - reg = <0x01c20000 0x4>; - clocks = <&osc24M>; -+ clock-output-names = "pll1"; - }; - -- pll4: pll4@01c20018 { -+ pll4: clk@01c20018 { - #clock-cells = <0>; - compatible = "allwinner,sun4i-pll1-clk"; - reg = <0x01c20018 0x4>; - clocks = <&osc24M>; -+ clock-output-names = "pll4"; - }; - -- pll5: pll5@01c20020 { -+ pll5: clk@01c20020 { - #clock-cells = <1>; - compatible = "allwinner,sun4i-pll5-clk"; - reg = <0x01c20020 0x4>; -@@ -93,7 +97,7 @@ - clock-output-names = "pll5_ddr", "pll5_other"; - }; - -- pll6: pll6@01c20028 { -+ pll6: clk@01c20028 { - #clock-cells = <1>; - compatible = "allwinner,sun4i-pll6-clk"; - reg = <0x01c20028 0x4>; -@@ -107,6 +111,7 @@ - compatible = "allwinner,sun4i-cpu-clk"; - reg = <0x01c20054 0x4>; - clocks = <&osc32k>, <&osc24M>, <&pll1>, <&dummy>; -+ clock-output-names = "cpu"; - }; - - axi: axi@01c20054 { -@@ -114,9 +119,10 @@ - compatible = "allwinner,sun4i-axi-clk"; - reg = <0x01c20054 0x4>; - clocks = <&cpu>; -+ clock-output-names = "axi"; - }; - -- axi_gates: axi_gates@01c2005c { -+ axi_gates: clk@01c2005c { - #clock-cells = <1>; - compatible = "allwinner,sun4i-axi-gates-clk"; - reg = <0x01c2005c 0x4>; -@@ -129,9 +135,10 @@ - compatible = "allwinner,sun4i-ahb-clk"; - reg = <0x01c20054 0x4>; - clocks = <&axi>; -+ clock-output-names = "ahb"; - }; - -- ahb_gates: ahb_gates@01c20060 { -+ ahb_gates: clk@01c20060 { - #clock-cells = <1>; - compatible = "allwinner,sun4i-ahb-gates-clk"; - reg = <0x01c20060 0x8>; -@@ -154,9 +161,10 @@ - compatible = "allwinner,sun4i-apb0-clk"; - reg = <0x01c20054 0x4>; - clocks = <&ahb>; -+ clock-output-names = "apb0"; - }; - -- apb0_gates: apb0_gates@01c20068 { -+ apb0_gates: clk@01c20068 { - #clock-cells = <1>; - compatible = "allwinner,sun4i-apb0-gates-clk"; - reg = <0x01c20068 0x4>; -@@ -171,6 +179,7 @@ - compatible = "allwinner,sun4i-apb1-mux-clk"; - reg = <0x01c20058 0x4>; - clocks = <&osc24M>, <&pll6 1>, <&osc32k>; -+ clock-output-names = "apb1_mux"; - }; - - apb1: apb1@01c20058 { -@@ -178,9 +187,10 @@ - compatible = "allwinner,sun4i-apb1-clk"; - reg = <0x01c20058 0x4>; - clocks = <&apb1_mux>; -+ clock-output-names = "apb1"; - }; - -- apb1_gates: apb1_gates@01c2006c { -+ apb1_gates: clk@01c2006c { - #clock-cells = <1>; - compatible = "allwinner,sun4i-apb1-gates-clk"; - reg = <0x01c2006c 0x4>; diff --git a/target/linux/sunxi/patches-3.14/112-dt-sun5i-rename-clocknodes.patch b/target/linux/sunxi/patches-3.14/112-dt-sun5i-rename-clocknodes.patch deleted file mode 100644 index d3e65a5e2c..0000000000 --- a/target/linux/sunxi/patches-3.14/112-dt-sun5i-rename-clocknodes.patch +++ /dev/null @@ -1,254 +0,0 @@ -From 266f79cef78cdf3545065a4786506eee0ae012b3 Mon Sep 17 00:00:00 2001 -From: Chen-Yu Tsai <wens@csie.org> -Date: Mon, 3 Feb 2014 09:51:42 +0800 -Subject: [PATCH] ARM: dts: sun5i: rename clock node names to clk@N - -Device tree naming conventions state that node names should match -node function. Change fully functioning clock nodes to match and -add clock-output-names to all sunxi clock nodes. - -Signed-off-by: Chen-Yu Tsai <wens@csie.org> -Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com> ---- - arch/arm/boot/dts/sun5i-a10s.dtsi | 30 ++++++++++++++++++++---------- - arch/arm/boot/dts/sun5i-a13.dtsi | 30 ++++++++++++++++++++---------- - 2 files changed, 40 insertions(+), 20 deletions(-) - ---- a/arch/arm/boot/dts/sun5i-a10s.dtsi -+++ b/arch/arm/boot/dts/sun5i-a10s.dtsi -@@ -47,34 +47,38 @@ - clock-frequency = <0>; - }; - -- osc24M: osc24M@01c20050 { -+ osc24M: clk@01c20050 { - #clock-cells = <0>; - compatible = "allwinner,sun4i-osc-clk"; - reg = <0x01c20050 0x4>; - clock-frequency = <24000000>; -+ clock-output-names = "osc24M"; - }; - -- osc32k: osc32k { -+ osc32k: clk@0 { - #clock-cells = <0>; - compatible = "fixed-clock"; - clock-frequency = <32768>; -+ clock-output-names = "osc32k"; - }; - -- pll1: pll1@01c20000 { -+ pll1: clk@01c20000 { - #clock-cells = <0>; - compatible = "allwinner,sun4i-pll1-clk"; - reg = <0x01c20000 0x4>; - clocks = <&osc24M>; -+ clock-output-names = "pll1"; - }; - -- pll4: pll4@01c20018 { -+ pll4: clk@01c20018 { - #clock-cells = <0>; - compatible = "allwinner,sun4i-pll1-clk"; - reg = <0x01c20018 0x4>; - clocks = <&osc24M>; -+ clock-output-names = "pll4"; - }; - -- pll5: pll5@01c20020 { -+ pll5: clk@01c20020 { - #clock-cells = <1>; - compatible = "allwinner,sun4i-pll5-clk"; - reg = <0x01c20020 0x4>; -@@ -82,7 +86,7 @@ - clock-output-names = "pll5_ddr", "pll5_other"; - }; - -- pll6: pll6@01c20028 { -+ pll6: clk@01c20028 { - #clock-cells = <1>; - compatible = "allwinner,sun4i-pll6-clk"; - reg = <0x01c20028 0x4>; -@@ -96,6 +100,7 @@ - compatible = "allwinner,sun4i-cpu-clk"; - reg = <0x01c20054 0x4>; - clocks = <&osc32k>, <&osc24M>, <&pll1>, <&dummy>; -+ clock-output-names = "cpu"; - }; - - axi: axi@01c20054 { -@@ -103,9 +108,10 @@ - compatible = "allwinner,sun4i-axi-clk"; - reg = <0x01c20054 0x4>; - clocks = <&cpu>; -+ clock-output-names = "axi"; - }; - -- axi_gates: axi_gates@01c2005c { -+ axi_gates: clk@01c2005c { - #clock-cells = <1>; - compatible = "allwinner,sun4i-axi-gates-clk"; - reg = <0x01c2005c 0x4>; -@@ -118,9 +124,10 @@ - compatible = "allwinner,sun4i-ahb-clk"; - reg = <0x01c20054 0x4>; - clocks = <&axi>; -+ clock-output-names = "ahb"; - }; - -- ahb_gates: ahb_gates@01c20060 { -+ ahb_gates: clk@01c20060 { - #clock-cells = <1>; - compatible = "allwinner,sun5i-a10s-ahb-gates-clk"; - reg = <0x01c20060 0x8>; -@@ -139,9 +146,10 @@ - compatible = "allwinner,sun4i-apb0-clk"; - reg = <0x01c20054 0x4>; - clocks = <&ahb>; -+ clock-output-names = "apb0"; - }; - -- apb0_gates: apb0_gates@01c20068 { -+ apb0_gates: clk@01c20068 { - #clock-cells = <1>; - compatible = "allwinner,sun5i-a10s-apb0-gates-clk"; - reg = <0x01c20068 0x4>; -@@ -155,6 +163,7 @@ - compatible = "allwinner,sun4i-apb1-mux-clk"; - reg = <0x01c20058 0x4>; - clocks = <&osc24M>, <&pll6 1>, <&osc32k>; -+ clock-output-names = "apb1_mux"; - }; - - apb1: apb1@01c20058 { -@@ -162,9 +171,10 @@ - compatible = "allwinner,sun4i-apb1-clk"; - reg = <0x01c20058 0x4>; - clocks = <&apb1_mux>; -+ clock-output-names = "apb1"; - }; - -- apb1_gates: apb1_gates@01c2006c { -+ apb1_gates: clk@01c2006c { - #clock-cells = <1>; - compatible = "allwinner,sun5i-a10s-apb1-gates-clk"; - reg = <0x01c2006c 0x4>; ---- a/arch/arm/boot/dts/sun5i-a13.dtsi -+++ b/arch/arm/boot/dts/sun5i-a13.dtsi -@@ -52,34 +52,38 @@ - clock-frequency = <0>; - }; - -- osc24M: osc24M@01c20050 { -+ osc24M: clk@01c20050 { - #clock-cells = <0>; - compatible = "allwinner,sun4i-osc-clk"; - reg = <0x01c20050 0x4>; - clock-frequency = <24000000>; -+ clock-output-names = "osc24M"; - }; - -- osc32k: osc32k { -+ osc32k: clk@0 { - #clock-cells = <0>; - compatible = "fixed-clock"; - clock-frequency = <32768>; -+ clock-output-names = "osc32k"; - }; - -- pll1: pll1@01c20000 { -+ pll1: clk@01c20000 { - #clock-cells = <0>; - compatible = "allwinner,sun4i-pll1-clk"; - reg = <0x01c20000 0x4>; - clocks = <&osc24M>; -+ clock-output-names = "pll1"; - }; - -- pll4: pll4@01c20018 { -+ pll4: clk@01c20018 { - #clock-cells = <0>; - compatible = "allwinner,sun4i-pll1-clk"; - reg = <0x01c20018 0x4>; - clocks = <&osc24M>; -+ clock-output-names = "pll4"; - }; - -- pll5: pll5@01c20020 { -+ pll5: clk@01c20020 { - #clock-cells = <1>; - compatible = "allwinner,sun4i-pll5-clk"; - reg = <0x01c20020 0x4>; -@@ -87,7 +91,7 @@ - clock-output-names = "pll5_ddr", "pll5_other"; - }; - -- pll6: pll6@01c20028 { -+ pll6: clk@01c20028 { - #clock-cells = <1>; - compatible = "allwinner,sun4i-pll6-clk"; - reg = <0x01c20028 0x4>; -@@ -101,6 +105,7 @@ - compatible = "allwinner,sun4i-cpu-clk"; - reg = <0x01c20054 0x4>; - clocks = <&osc32k>, <&osc24M>, <&pll1>, <&dummy>; -+ clock-output-names = "cpu"; - }; - - axi: axi@01c20054 { -@@ -108,9 +113,10 @@ - compatible = "allwinner,sun4i-axi-clk"; - reg = <0x01c20054 0x4>; - clocks = <&cpu>; -+ clock-output-names = "axi"; - }; - -- axi_gates: axi_gates@01c2005c { -+ axi_gates: clk@01c2005c { - #clock-cells = <1>; - compatible = "allwinner,sun4i-axi-gates-clk"; - reg = <0x01c2005c 0x4>; -@@ -123,9 +129,10 @@ - compatible = "allwinner,sun4i-ahb-clk"; - reg = <0x01c20054 0x4>; - clocks = <&axi>; -+ clock-output-names = "ahb"; - }; - -- ahb_gates: ahb_gates@01c20060 { -+ ahb_gates: clk@01c20060 { - #clock-cells = <1>; - compatible = "allwinner,sun5i-a13-ahb-gates-clk"; - reg = <0x01c20060 0x8>; -@@ -143,9 +150,10 @@ - compatible = "allwinner,sun4i-apb0-clk"; - reg = <0x01c20054 0x4>; - clocks = <&ahb>; -+ clock-output-names = "apb0"; - }; - -- apb0_gates: apb0_gates@01c20068 { -+ apb0_gates: clk@01c20068 { - #clock-cells = <1>; - compatible = "allwinner,sun5i-a13-apb0-gates-clk"; - reg = <0x01c20068 0x4>; -@@ -158,6 +166,7 @@ - compatible = "allwinner,sun4i-apb1-mux-clk"; - reg = <0x01c20058 0x4>; - clocks = <&osc24M>, <&pll6 1>, <&osc32k>; -+ clock-output-names = "apb1_mux"; - }; - - apb1: apb1@01c20058 { -@@ -165,9 +174,10 @@ - compatible = "allwinner,sun4i-apb1-clk"; - reg = <0x01c20058 0x4>; - clocks = <&apb1_mux>; -+ clock-output-names = "apb1"; - }; - -- apb1_gates: apb1_gates@01c2006c { -+ apb1_gates: clk@01c2006c { - #clock-cells = <1>; - compatible = "allwinner,sun5i-a13-apb1-gates-clk"; - reg = <0x01c2006c 0x4>; diff --git a/target/linux/sunxi/patches-3.14/113-dt-sun6i-rename-clocknodes.patch b/target/linux/sunxi/patches-3.14/113-dt-sun6i-rename-clocknodes.patch deleted file mode 100644 index b0f7648026..0000000000 --- a/target/linux/sunxi/patches-3.14/113-dt-sun6i-rename-clocknodes.patch +++ /dev/null @@ -1,107 +0,0 @@ -From 8bd1bb3a670aae791c4b2e9ab13c92768233368a Mon Sep 17 00:00:00 2001 -From: Chen-Yu Tsai <wens@csie.org> -Date: Mon, 3 Feb 2014 09:51:43 +0800 -Subject: [PATCH] ARM: dts: sun6i: rename clock node names to clk@N - -Device tree naming conventions state that node names should match -node function. Change fully functioning clock nodes to match and -add clock-output-names to all sunxi clock nodes. - -Signed-off-by: Chen-Yu Tsai <wens@csie.org> -Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com> ---- - arch/arm/boot/dts/sun6i-a31.dtsi | 19 ++++++++++++++----- - 1 file changed, 14 insertions(+), 5 deletions(-) - ---- a/arch/arm/boot/dts/sun6i-a31.dtsi -+++ b/arch/arm/boot/dts/sun6i-a31.dtsi -@@ -70,17 +70,19 @@ - clock-frequency = <24000000>; - }; - -- osc32k: osc32k { -+ osc32k: clk@0 { - #clock-cells = <0>; - compatible = "fixed-clock"; - clock-frequency = <32768>; -+ clock-output-names = "osc32k"; - }; - -- pll1: pll1@01c20000 { -+ pll1: clk@01c20000 { - #clock-cells = <0>; - compatible = "allwinner,sun6i-a31-pll1-clk"; - reg = <0x01c20000 0x4>; - clocks = <&osc24M>; -+ clock-output-names = "pll1"; - }; - - pll6: clk@01c20028 { -@@ -103,6 +105,7 @@ - * Allwinner. - */ - clocks = <&osc32k>, <&osc24M>, <&pll1>, <&pll1>; -+ clock-output-names = "cpu"; - }; - - axi: axi@01c20050 { -@@ -110,6 +113,7 @@ - compatible = "allwinner,sun4i-axi-clk"; - reg = <0x01c20050 0x4>; - clocks = <&cpu>; -+ clock-output-names = "axi"; - }; - - ahb1_mux: ahb1_mux@01c20054 { -@@ -117,6 +121,7 @@ - compatible = "allwinner,sun6i-a31-ahb1-mux-clk"; - reg = <0x01c20054 0x4>; - clocks = <&osc32k>, <&osc24M>, <&axi>, <&pll6>; -+ clock-output-names = "ahb1_mux"; - }; - - ahb1: ahb1@01c20054 { -@@ -124,9 +129,10 @@ - compatible = "allwinner,sun4i-ahb-clk"; - reg = <0x01c20054 0x4>; - clocks = <&ahb1_mux>; -+ clock-output-names = "ahb1"; - }; - -- ahb1_gates: ahb1_gates@01c20060 { -+ ahb1_gates: clk@01c20060 { - #clock-cells = <1>; - compatible = "allwinner,sun6i-a31-ahb1-gates-clk"; - reg = <0x01c20060 0x8>; -@@ -152,9 +158,10 @@ - compatible = "allwinner,sun4i-apb0-clk"; - reg = <0x01c20054 0x4>; - clocks = <&ahb1>; -+ clock-output-names = "apb1"; - }; - -- apb1_gates: apb1_gates@01c20060 { -+ apb1_gates: clk@01c20068 { - #clock-cells = <1>; - compatible = "allwinner,sun6i-a31-apb1-gates-clk"; - reg = <0x01c20068 0x4>; -@@ -169,6 +176,7 @@ - compatible = "allwinner,sun4i-apb1-mux-clk"; - reg = <0x01c20058 0x4>; - clocks = <&osc32k>, <&osc24M>, <&pll6>, <&pll6>; -+ clock-output-names = "apb2_mux"; - }; - - apb2: apb2@01c20058 { -@@ -176,9 +184,10 @@ - compatible = "allwinner,sun6i-a31-apb2-div-clk"; - reg = <0x01c20058 0x4>; - clocks = <&apb2_mux>; -+ clock-output-names = "apb2"; - }; - -- apb2_gates: apb2_gates@01c2006c { -+ apb2_gates: clk@01c2006c { - #clock-cells = <1>; - compatible = "allwinner,sun6i-a31-apb2-gates-clk"; - reg = <0x01c2006c 0x4>; diff --git a/target/linux/sunxi/patches-3.14/114-dt-sun7i-rename-clocknodes.patch b/target/linux/sunxi/patches-3.14/114-dt-sun7i-rename-clocknodes.patch deleted file mode 100644 index a8a6993e99..0000000000 --- a/target/linux/sunxi/patches-3.14/114-dt-sun7i-rename-clocknodes.patch +++ /dev/null @@ -1,127 +0,0 @@ -From c57b781689bba48dad635caf005962cc9c8e5e3d Mon Sep 17 00:00:00 2001 -From: Chen-Yu Tsai <wens@csie.org> -Date: Mon, 3 Feb 2014 09:51:44 +0800 -Subject: [PATCH] ARM: dts: sun7i: rename clock node names to clk@N - -Device tree naming conventions state that node names should match -node function. Change fully functioning clock nodes to match and -add clock-output-names to all sunxi clock nodes. - -Signed-off-by: Chen-Yu Tsai <wens@csie.org> -Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com> ---- - arch/arm/boot/dts/sun7i-a20.dtsi | 25 +++++++++++++++++-------- - 1 file changed, 17 insertions(+), 8 deletions(-) - ---- a/arch/arm/boot/dts/sun7i-a20.dtsi -+++ b/arch/arm/boot/dts/sun7i-a20.dtsi -@@ -62,11 +62,12 @@ - #size-cells = <1>; - ranges; - -- osc24M: osc24M@01c20050 { -+ osc24M: clk@01c20050 { - #clock-cells = <0>; - compatible = "allwinner,sun4i-osc-clk"; - reg = <0x01c20050 0x4>; - clock-frequency = <24000000>; -+ clock-output-names = "osc24M"; - }; - - osc32k: clk@0 { -@@ -76,21 +77,23 @@ - clock-output-names = "osc32k"; - }; - -- pll1: pll1@01c20000 { -+ pll1: clk@01c20000 { - #clock-cells = <0>; - compatible = "allwinner,sun4i-pll1-clk"; - reg = <0x01c20000 0x4>; - clocks = <&osc24M>; -+ clock-output-names = "pll1"; - }; - -- pll4: pll4@01c20018 { -+ pll4: clk@01c20018 { - #clock-cells = <0>; - compatible = "allwinner,sun4i-pll1-clk"; - reg = <0x01c20018 0x4>; - clocks = <&osc24M>; -+ clock-output-names = "pll4"; - }; - -- pll5: pll5@01c20020 { -+ pll5: clk@01c20020 { - #clock-cells = <1>; - compatible = "allwinner,sun4i-pll5-clk"; - reg = <0x01c20020 0x4>; -@@ -98,7 +101,7 @@ - clock-output-names = "pll5_ddr", "pll5_other"; - }; - -- pll6: pll6@01c20028 { -+ pll6: clk@01c20028 { - #clock-cells = <1>; - compatible = "allwinner,sun4i-pll6-clk"; - reg = <0x01c20028 0x4>; -@@ -111,6 +114,7 @@ - compatible = "allwinner,sun4i-cpu-clk"; - reg = <0x01c20054 0x4>; - clocks = <&osc32k>, <&osc24M>, <&pll1>, <&pll6 1>; -+ clock-output-names = "cpu"; - }; - - axi: axi@01c20054 { -@@ -118,6 +122,7 @@ - compatible = "allwinner,sun4i-axi-clk"; - reg = <0x01c20054 0x4>; - clocks = <&cpu>; -+ clock-output-names = "axi"; - }; - - ahb: ahb@01c20054 { -@@ -125,9 +130,10 @@ - compatible = "allwinner,sun4i-ahb-clk"; - reg = <0x01c20054 0x4>; - clocks = <&axi>; -+ clock-output-names = "ahb"; - }; - -- ahb_gates: ahb_gates@01c20060 { -+ ahb_gates: clk@01c20060 { - #clock-cells = <1>; - compatible = "allwinner,sun7i-a20-ahb-gates-clk"; - reg = <0x01c20060 0x8>; -@@ -152,9 +158,10 @@ - compatible = "allwinner,sun4i-apb0-clk"; - reg = <0x01c20054 0x4>; - clocks = <&ahb>; -+ clock-output-names = "apb0"; - }; - -- apb0_gates: apb0_gates@01c20068 { -+ apb0_gates: clk@01c20068 { - #clock-cells = <1>; - compatible = "allwinner,sun7i-a20-apb0-gates-clk"; - reg = <0x01c20068 0x4>; -@@ -170,6 +177,7 @@ - compatible = "allwinner,sun4i-apb1-mux-clk"; - reg = <0x01c20058 0x4>; - clocks = <&osc24M>, <&pll6 1>, <&osc32k>; -+ clock-output-names = "apb1_mux"; - }; - - apb1: apb1@01c20058 { -@@ -177,9 +185,10 @@ - compatible = "allwinner,sun4i-apb1-clk"; - reg = <0x01c20058 0x4>; - clocks = <&apb1_mux>; -+ clock-output-names = "apb1"; - }; - -- apb1_gates: apb1_gates@01c2006c { -+ apb1_gates: clk@01c2006c { - #clock-cells = <1>; - compatible = "allwinner,sun7i-a20-apb1-gates-clk"; - reg = <0x01c2006c 0x4>; diff --git a/target/linux/sunxi/patches-3.14/115-dt-sun6i-fix-mod0-compat.patch b/target/linux/sunxi/patches-3.14/115-dt-sun6i-fix-mod0-compat.patch deleted file mode 100644 index f2644a1df7..0000000000 --- a/target/linux/sunxi/patches-3.14/115-dt-sun6i-fix-mod0-compat.patch +++ /dev/null @@ -1,51 +0,0 @@ -From 95c1fe603fbea0fd01d98262bd5ff7d5442a86db Mon Sep 17 00:00:00 2001 -From: Maxime Ripard <maxime.ripard@free-electrons.com> -Date: Mon, 24 Feb 2014 17:29:06 +0100 -Subject: [PATCH] ARM: sun6i: dt: Fix mod0 compatible - -The module 0 clock compatibles were changed between the time the patch was sent -and it was merged. Update the compatibles. - -Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com> ---- - arch/arm/boot/dts/sun6i-a31.dtsi | 8 ++++---- - 1 file changed, 4 insertions(+), 4 deletions(-) - ---- a/arch/arm/boot/dts/sun6i-a31.dtsi -+++ b/arch/arm/boot/dts/sun6i-a31.dtsi -@@ -200,7 +200,7 @@ - - spi0_clk: clk@01c200a0 { - #clock-cells = <0>; -- compatible = "allwinner,sun4i-mod0-clk"; -+ compatible = "allwinner,sun4i-a10-mod0-clk"; - reg = <0x01c200a0 0x4>; - clocks = <&osc24M>, <&pll6>; - clock-output-names = "spi0"; -@@ -208,7 +208,7 @@ - - spi1_clk: clk@01c200a4 { - #clock-cells = <0>; -- compatible = "allwinner,sun4i-mod0-clk"; -+ compatible = "allwinner,sun4i-a10-mod0-clk"; - reg = <0x01c200a4 0x4>; - clocks = <&osc24M>, <&pll6>; - clock-output-names = "spi1"; -@@ -216,7 +216,7 @@ - - spi2_clk: clk@01c200a8 { - #clock-cells = <0>; -- compatible = "allwinner,sun4i-mod0-clk"; -+ compatible = "allwinner,sun4i-a10-mod0-clk"; - reg = <0x01c200a8 0x4>; - clocks = <&osc24M>, <&pll6>; - clock-output-names = "spi2"; -@@ -224,7 +224,7 @@ - - spi3_clk: clk@01c200ac { - #clock-cells = <0>; -- compatible = "allwinner,sun4i-mod0-clk"; -+ compatible = "allwinner,sun4i-a10-mod0-clk"; - reg = <0x01c200ac 0x4>; - clocks = <&osc24M>, <&pll6>; - clock-output-names = "spi3"; diff --git a/target/linux/sunxi/patches-3.14/116-dt-sun7i-add-usb-to-cubietruck.patch b/target/linux/sunxi/patches-3.14/116-dt-sun7i-add-usb-to-cubietruck.patch deleted file mode 100644 index 529665e240..0000000000 --- a/target/linux/sunxi/patches-3.14/116-dt-sun7i-add-usb-to-cubietruck.patch +++ /dev/null @@ -1,23 +0,0 @@ ---- a/arch/arm/boot/dts/sun7i-a20-cubietruck.dts -+++ b/arch/arm/boot/dts/sun7i-a20-cubietruck.dts -@@ -26,6 +26,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 { diff --git a/target/linux/sunxi/patches-3.14/120-dt-sun7i-add-gmac-clocknode.patch b/target/linux/sunxi/patches-3.14/120-dt-sun7i-add-gmac-clocknode.patch deleted file mode 100644 index 9a1e485fd8..0000000000 --- a/target/linux/sunxi/patches-3.14/120-dt-sun7i-add-gmac-clocknode.patch +++ /dev/null @@ -1,51 +0,0 @@ -From 3e1660161aacc5aeeebb09a0c8d91ad01399e5cd Mon Sep 17 00:00:00 2001 -From: Chen-Yu Tsai <wens@csie.org> -Date: Mon, 10 Feb 2014 18:35:48 +0800 -Subject: [PATCH] ARM: dts: sun7i: Add GMAC clock node to sun7i DTSI - -The GMAC uses 1 of 2 sources for its transmit clock, depending on the -PHY interface mode. Add both sources as dummy clocks, and as parents -to the GMAC clock node. - -Signed-off-by: Chen-Yu Tsai <wens@csie.org> ---- - arch/arm/boot/dts/sun7i-a20.dtsi | 28 ++++++++++++++++++++++++++++ - 1 file changed, 28 insertions(+) - ---- a/arch/arm/boot/dts/sun7i-a20.dtsi -+++ b/arch/arm/boot/dts/sun7i-a20.dtsi -@@ -330,6 +330,34 @@ - }; - - /* -+ * The following two are dummy clocks, placeholders used in the gmac_tx -+ * clock. The gmac driver will choose one parent depending on the PHY -+ * interface mode, using clk_set_rate auto-reparenting. -+ * The actual TX clock rate is not controlled by the gmac_tx clock. -+ */ -+ mii_phy_tx_clk: clk@2 { -+ #clock-cells = <0>; -+ compatible = "fixed-clock"; -+ clock-frequency = <25000000>; -+ clock-output-names = "mii_phy_tx"; -+ }; -+ -+ gmac_int_tx_clk: clk@3 { -+ #clock-cells = <0>; -+ compatible = "fixed-clock"; -+ clock-frequency = <125000000>; -+ clock-output-names = "gmac_int_tx"; -+ }; -+ -+ gmac_tx_clk: clk@01c20164 { -+ #clock-cells = <0>; -+ compatible = "allwinner,sun7i-a20-gmac-clk"; -+ reg = <0x01c20164 0x4>; -+ clocks = <&mii_phy_tx_clk>, <&gmac_int_tx_clk>; -+ clock-output-names = "gmac_tx"; -+ }; -+ -+ /* - * Dummy clock used by output clocks - */ - osc24M_32k: clk@1 { diff --git a/target/linux/sunxi/patches-3.14/121-dt-sun7i-add-gmac-ctrlnode.patch b/target/linux/sunxi/patches-3.14/121-dt-sun7i-add-gmac-ctrlnode.patch deleted file mode 100644 index 3ddb55ec2f..0000000000 --- a/target/linux/sunxi/patches-3.14/121-dt-sun7i-add-gmac-ctrlnode.patch +++ /dev/null @@ -1,34 +0,0 @@ -From 22b9ac16c600694b12479a75461bce031295e4b9 Mon Sep 17 00:00:00 2001 -From: Chen-Yu Tsai <wens@csie.org> -Date: Mon, 10 Feb 2014 18:35:49 +0800 -Subject: [PATCH] ARM: dts: sun7i: Add GMAC controller node to sun7i DTSI - -Signed-off-by: Chen-Yu Tsai <wens@csie.org> ---- - arch/arm/boot/dts/sun7i-a20.dtsi | 15 +++++++++++++++ - 1 file changed, 15 insertions(+) - ---- a/arch/arm/boot/dts/sun7i-a20.dtsi -+++ b/arch/arm/boot/dts/sun7i-a20.dtsi -@@ -653,6 +653,21 @@ - status = "disabled"; - }; - -+ gmac: ethernet@01c50000 { -+ compatible = "allwinner,sun7i-a20-gmac"; -+ reg = <0x01c50000 0x10000>; -+ interrupts = <0 85 4>; -+ interrupt-names = "macirq"; -+ clocks = <&ahb_gates 49>, <&gmac_tx_clk>; -+ clock-names = "stmmaceth", "allwinner_gmac_tx"; -+ snps,pbl = <2>; -+ snps,fixed-burst; -+ snps,force_sf_dma_mode; -+ status = "disabled"; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ }; -+ - hstimer@01c60000 { - compatible = "allwinner,sun7i-a20-hstimer"; - reg = <0x01c60000 0x1000>; diff --git a/target/linux/sunxi/patches-3.14/122-dt-sun7i-add-pinmuxing-for-gmac.patch b/target/linux/sunxi/patches-3.14/122-dt-sun7i-add-pinmuxing-for-gmac.patch deleted file mode 100644 index d539af245d..0000000000 --- a/target/linux/sunxi/patches-3.14/122-dt-sun7i-add-pinmuxing-for-gmac.patch +++ /dev/null @@ -1,48 +0,0 @@ -From 9f6deb688f4cb733cd3f36e0cc88f14d2f81982d Mon Sep 17 00:00:00 2001 -From: Chen-Yu Tsai <wens@csie.org> -Date: Mon, 10 Feb 2014 18:35:50 +0800 -Subject: [PATCH] ARM: dts: sun7i: Add pin muxing options for the GMAC - -The A20 has EMAC and GMAC muxed on the same pins. -Add pin sets with gmac function for MII and RGMII mode to the DTSI. - -Signed-off-by: Chen-Yu Tsai <wens@csie.org> ---- - arch/arm/boot/dts/sun7i-a20.dtsi | 26 ++++++++++++++++++++++++++ - 1 file changed, 26 insertions(+) - ---- a/arch/arm/boot/dts/sun7i-a20.dtsi -+++ b/arch/arm/boot/dts/sun7i-a20.dtsi -@@ -492,6 +492,32 @@ - allwinner,drive = <0>; - allwinner,pull = <0>; - }; -+ -+ gmac_pins_mii_a: gmac_mii@0 { -+ allwinner,pins = "PA0", "PA1", "PA2", -+ "PA3", "PA4", "PA5", "PA6", -+ "PA7", "PA8", "PA9", "PA10", -+ "PA11", "PA12", "PA13", "PA14", -+ "PA15", "PA16"; -+ allwinner,function = "gmac"; -+ allwinner,drive = <0>; -+ allwinner,pull = <0>; -+ }; -+ -+ gmac_pins_rgmii_a: gmac_rgmii@0 { -+ allwinner,pins = "PA0", "PA1", "PA2", -+ "PA3", "PA4", "PA5", "PA6", -+ "PA7", "PA8", "PA10", -+ "PA11", "PA12", "PA13", -+ "PA15", "PA16"; -+ allwinner,function = "gmac"; -+ /* -+ * data lines in RGMII mode use DDR mode -+ * and need a higher signal drive strength -+ */ -+ allwinner,drive = <3>; -+ allwinner,pull = <0>; -+ }; - }; - - timer@01c20c00 { diff --git a/target/linux/sunxi/patches-3.14/123-dt-sun7i-cubietruck-enable-gmac.patch b/target/linux/sunxi/patches-3.14/123-dt-sun7i-cubietruck-enable-gmac.patch deleted file mode 100644 index bac445f31d..0000000000 --- a/target/linux/sunxi/patches-3.14/123-dt-sun7i-cubietruck-enable-gmac.patch +++ /dev/null @@ -1,33 +0,0 @@ -From d09483e1cfcc00be70450c469c3c23496a063d98 Mon Sep 17 00:00:00 2001 -From: Chen-Yu Tsai <wens@csie.org> -Date: Mon, 10 Feb 2014 18:35:51 +0800 -Subject: [PATCH] ARM: dts: sun7i: cubietruck: Enable the GMAC - -The CubieTruck uses the GMAC with an RGMII phy. - -Signed-off-by: Chen-Yu Tsai <wens@csie.org> ---- - arch/arm/boot/dts/sun7i-a20-cubietruck.dts | 12 ++++++++++++ - 1 file changed, 12 insertions(+) - ---- a/arch/arm/boot/dts/sun7i-a20-cubietruck.dts -+++ b/arch/arm/boot/dts/sun7i-a20-cubietruck.dts -@@ -65,6 +65,18 @@ - pinctrl-0 = <&i2c2_pins_a>; - status = "okay"; - }; -+ -+ gmac: ethernet@01c50000 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&gmac_pins_rgmii_a>; -+ phy = <&phy1>; -+ phy-mode = "rgmii"; -+ status = "okay"; -+ -+ phy1: ethernet-phy@1 { -+ reg = <1>; -+ }; -+ }; - }; - - leds { diff --git a/target/linux/sunxi/patches-3.14/124-dt-sun7i-cubieboard2-enable-gmac.patch b/target/linux/sunxi/patches-3.14/124-dt-sun7i-cubieboard2-enable-gmac.patch deleted file mode 100644 index c4744e9b74..0000000000 --- a/target/linux/sunxi/patches-3.14/124-dt-sun7i-cubieboard2-enable-gmac.patch +++ /dev/null @@ -1,56 +0,0 @@ -From 856cae07bff4d7e7a111affd4f15803142d29880 Mon Sep 17 00:00:00 2001 -From: Chen-Yu Tsai <wens@csie.org> -Date: Mon, 10 Feb 2014 18:35:52 +0800 -Subject: [PATCH] ARM: dts: sun7i: cubieboard2: Enable GMAC instead of EMAC - -GMAC has better performance and fewer hardware issues. -Use the GMAC in MII mode for ethernet instead of the EMAC. - -Signed-off-by: Chen-Yu Tsai <wens@csie.org> ---- - arch/arm/boot/dts/sun7i-a20-cubieboard2.dts | 27 ++++++++++++--------------- - 1 file changed, 12 insertions(+), 15 deletions(-) - ---- a/arch/arm/boot/dts/sun7i-a20-cubieboard2.dts -+++ b/arch/arm/boot/dts/sun7i-a20-cubieboard2.dts -@@ -19,21 +19,6 @@ - compatible = "cubietech,cubieboard2", "allwinner,sun7i-a20"; - - soc@01c00000 { -- emac: ethernet@01c0b000 { -- pinctrl-names = "default"; -- pinctrl-0 = <&emac_pins_a>; -- phy = <&phy1>; -- status = "okay"; -- }; -- -- mdio@01c0b080 { -- status = "okay"; -- -- phy1: ethernet-phy@1 { -- reg = <1>; -- }; -- }; -- - pinctrl@01c20800 { - led_pins_cubieboard2: led_pins@0 { - allwinner,pins = "PH20", "PH21"; -@@ -60,6 +45,18 @@ - pinctrl-0 = <&i2c1_pins_a>; - status = "okay"; - }; -+ -+ gmac: ethernet@01c50000 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&gmac_pins_mii_a>; -+ phy = <&phy1>; -+ phy-mode = "mii"; -+ status = "okay"; -+ -+ phy1: ethernet-phy@1 { -+ reg = <1>; -+ }; -+ }; - }; - - leds { diff --git a/target/linux/sunxi/patches-3.14/125-dt-sun7i-olinuxinom-enable-gmac.patch b/target/linux/sunxi/patches-3.14/125-dt-sun7i-olinuxinom-enable-gmac.patch deleted file mode 100644 index b4648c816b..0000000000 --- a/target/linux/sunxi/patches-3.14/125-dt-sun7i-olinuxinom-enable-gmac.patch +++ /dev/null @@ -1,57 +0,0 @@ -From f5b426a2eb246e91eb2de0cd215565d38d1d5ce7 Mon Sep 17 00:00:00 2001 -From: Chen-Yu Tsai <wens@csie.org> -Date: Mon, 10 Feb 2014 18:35:53 +0800 -Subject: [PATCH] ARM: dts: sun7i: a20-olinuxino-micro: Enable GMAC instead of - EMAC - -GMAC has better performance and fewer hardware issues. -Use the GMAC in MII mode for ethernet instead of the EMAC. - -Signed-off-by: Chen-Yu Tsai <wens@csie.org> ---- - arch/arm/boot/dts/sun7i-a20-olinuxino-micro.dts | 27 +++++++++++-------------- - 1 file changed, 12 insertions(+), 15 deletions(-) - ---- a/arch/arm/boot/dts/sun7i-a20-olinuxino-micro.dts -+++ b/arch/arm/boot/dts/sun7i-a20-olinuxino-micro.dts -@@ -19,21 +19,6 @@ - compatible = "olimex,a20-olinuxino-micro", "allwinner,sun7i-a20"; - - soc@01c00000 { -- emac: ethernet@01c0b000 { -- pinctrl-names = "default"; -- pinctrl-0 = <&emac_pins_a>; -- phy = <&phy1>; -- status = "okay"; -- }; -- -- mdio@01c0b080 { -- status = "okay"; -- -- phy1: ethernet-phy@1 { -- reg = <1>; -- }; -- }; -- - pinctrl@01c20800 { - led_pins_olinuxino: led_pins@0 { - allwinner,pins = "PH2"; -@@ -78,6 +63,18 @@ - pinctrl-0 = <&i2c2_pins_a>; - status = "okay"; - }; -+ -+ gmac: ethernet@01c50000 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&gmac_pins_mii_a>; -+ phy = <&phy1>; -+ phy-mode = "mii"; -+ status = "okay"; -+ -+ phy1: ethernet-phy@1 { -+ reg = <1>; -+ }; -+ }; - }; - - leds { diff --git a/target/linux/sunxi/patches-3.14/126-dt-sun7i-add-eth-alias-for-gmac.patch b/target/linux/sunxi/patches-3.14/126-dt-sun7i-add-eth-alias-for-gmac.patch deleted file mode 100644 index 014058802c..0000000000 --- a/target/linux/sunxi/patches-3.14/126-dt-sun7i-add-eth-alias-for-gmac.patch +++ /dev/null @@ -1,26 +0,0 @@ -From 614b4b996be81daca9d8333e1ac163d23e1701c4 Mon Sep 17 00:00:00 2001 -From: Chen-Yu Tsai <wens@csie.org> -Date: Mon, 10 Feb 2014 18:35:54 +0800 -Subject: [PATCH] ARM: dts: sun7i: Add ethernet alias for GMAC - -All Allwinner A20 boards we support can only use either EMAC or GMAC, -as they share the same pins. As we have switched all supported to -GMAC, we should alias GMAC (the active controller) as ethernet0, -so u-boot will insert the MAC address for the correct controller. - -Signed-off-by: Chen-Yu Tsai <wens@csie.org> ---- - arch/arm/boot/dts/sun7i-a20.dtsi | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/arch/arm/boot/dts/sun7i-a20.dtsi -+++ b/arch/arm/boot/dts/sun7i-a20.dtsi -@@ -17,7 +17,7 @@ - interrupt-parent = <&gic>; - - aliases { -- ethernet0 = &emac; -+ ethernet0 = &gmac; - serial0 = &uart0; - serial1 = &uart1; - serial2 = &uart2; diff --git a/target/linux/sunxi/patches-3.14/130-dt-sun4i-add-usbclock-bindings.patch b/target/linux/sunxi/patches-3.14/130-dt-sun4i-add-usbclock-bindings.patch deleted file mode 100644 index b94aeaf81c..0000000000 --- a/target/linux/sunxi/patches-3.14/130-dt-sun4i-add-usbclock-bindings.patch +++ /dev/null @@ -1,30 +0,0 @@ -From b5325f9813a6a7cf80ede22fbee66376abbe2384 Mon Sep 17 00:00:00 2001 -From: Roman Byshko <rbyshko@gmail.com> -Date: Fri, 7 Feb 2014 16:21:51 +0100 -Subject: [PATCH] ARM: sun4i: dt: Add bindings for USB clocks - -Signed-off-by: Roman Byshko <rbyshko@gmail.com> -Signed-off-by: Hans de Goede <hdegoede@redhat.com> -Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com> ---- - arch/arm/boot/dts/sun4i-a10.dtsi | 9 +++++++++ - 1 file changed, 9 insertions(+) - ---- a/arch/arm/boot/dts/sun4i-a10.dtsi -+++ b/arch/arm/boot/dts/sun4i-a10.dtsi -@@ -315,6 +315,15 @@ - clock-output-names = "ir1"; - }; - -+ usb_clk: clk@01c200cc { -+ #clock-cells = <1>; -+ #reset-cells = <1>; -+ compatible = "allwinner,sun4i-a10-usb-clk"; -+ reg = <0x01c200cc 0x4>; -+ clocks = <&pll6 1>; -+ clock-output-names = "usb_ohci0", "usb_ohci1", "usb_phy"; -+ }; -+ - spi3_clk: clk@01c200d4 { - #clock-cells = <0>; - compatible = "allwinner,sun4i-mod0-clk"; diff --git a/target/linux/sunxi/patches-3.14/131-dt-sun5i-add-usbclock-bindings.patch b/target/linux/sunxi/patches-3.14/131-dt-sun5i-add-usbclock-bindings.patch deleted file mode 100644 index 366adb4b57..0000000000 --- a/target/linux/sunxi/patches-3.14/131-dt-sun5i-add-usbclock-bindings.patch +++ /dev/null @@ -1,49 +0,0 @@ -From 5b08dd0d672b59fff16d02239ca6a36aaecdb1ca Mon Sep 17 00:00:00 2001 -From: Roman Byshko <rbyshko@gmail.com> -Date: Fri, 7 Feb 2014 16:21:52 +0100 -Subject: [PATCH] ARM: sun5i: dt: Add bindings for USB clocks - -Signed-off-by: Roman Byshko <rbyshko@gmail.com> -Signed-off-by: Hans de Goede <hdegoede@redhat.com> -Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com> ---- - arch/arm/boot/dts/sun5i-a10s.dtsi | 9 +++++++++ - arch/arm/boot/dts/sun5i-a13.dtsi | 9 +++++++++ - 2 files changed, 18 insertions(+) - ---- a/arch/arm/boot/dts/sun5i-a10s.dtsi -+++ b/arch/arm/boot/dts/sun5i-a10s.dtsi -@@ -272,6 +272,15 @@ - clock-output-names = "ir0"; - }; - -+ usb_clk: clk@01c200cc { -+ #clock-cells = <1>; -+ #reset-cells = <1>; -+ compatible = "allwinner,sun5i-a13-usb-clk"; -+ reg = <0x01c200cc 0x4>; -+ clocks = <&pll6 1>; -+ clock-output-names = "usb_ohci0", "usb_phy"; -+ }; -+ - mbus_clk: clk@01c2015c { - #clock-cells = <0>; - compatible = "allwinner,sun4i-mod0-clk"; ---- a/arch/arm/boot/dts/sun5i-a13.dtsi -+++ b/arch/arm/boot/dts/sun5i-a13.dtsi -@@ -274,6 +274,15 @@ - clock-output-names = "ir0"; - }; - -+ usb_clk: clk@01c200cc { -+ #clock-cells = <1>; -+ #reset-cells = <1>; -+ compatible = "allwinner,sun5i-a13-usb-clk"; -+ reg = <0x01c200cc 0x4>; -+ clocks = <&pll6 1>; -+ clock-output-names = "usb_ohci0", "usb_phy"; -+ }; -+ - mbus_clk: clk@01c2015c { - #clock-cells = <0>; - compatible = "allwinner,sun4i-mod0-clk"; diff --git a/target/linux/sunxi/patches-3.14/132-dt-sun7i-add-usbclock-bindings.patch b/target/linux/sunxi/patches-3.14/132-dt-sun7i-add-usbclock-bindings.patch deleted file mode 100644 index 1a97faef5e..0000000000 --- a/target/linux/sunxi/patches-3.14/132-dt-sun7i-add-usbclock-bindings.patch +++ /dev/null @@ -1,30 +0,0 @@ -From 25a1ac92997df2b1e2c76a374d444605cbc96a9f Mon Sep 17 00:00:00 2001 -From: Roman Byshko <rbyshko@gmail.com> -Date: Fri, 7 Feb 2014 16:21:53 +0100 -Subject: [PATCH] ARM: sun7i: dt: Add bindings for USB clocks - -Signed-off-by: Roman Byshko <rbyshko@gmail.com> -Signed-off-by: Hans de Goede <hdegoede@redhat.com> -Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com> ---- - arch/arm/boot/dts/sun7i-a20.dtsi | 9 +++++++++ - 1 file changed, 9 insertions(+) - ---- a/arch/arm/boot/dts/sun7i-a20.dtsi -+++ b/arch/arm/boot/dts/sun7i-a20.dtsi -@@ -313,6 +313,15 @@ - clock-output-names = "ir1"; - }; - -+ usb_clk: clk@01c200cc { -+ #clock-cells = <1>; -+ #reset-cells = <1>; -+ compatible = "allwinner,sun4i-a10-usb-clk"; -+ reg = <0x01c200cc 0x4>; -+ clocks = <&pll6 1>; -+ clock-output-names = "usb_ohci0", "usb_ohci1", "usb_phy"; -+ }; -+ - spi3_clk: clk@01c200d4 { - #clock-cells = <0>; - compatible = "allwinner,sun4i-mod0-clk"; diff --git a/target/linux/sunxi/patches-3.14/135-pinctrl-fixes.patch b/target/linux/sunxi/patches-3.14/135-pinctrl-fixes.patch deleted file mode 100644 index 5eb1fabc0b..0000000000 --- a/target/linux/sunxi/patches-3.14/135-pinctrl-fixes.patch +++ /dev/null @@ -1,78 +0,0 @@ -From 68a7d9940935cb71440a9ff384e5859592b0dbfd Mon Sep 17 00:00:00 2001 -From: Hans de Goede <hdegoede@redhat.com> -Date: Sat, 14 Dec 2013 17:20:13 +0100 -Subject: [PATCH] pinctrl-sunxi: Fix sun5i-a13 port F multiplexing - -The correct value for selecting the mmc0 function on port F pins is 2 not 4, -as per the data-sheet: -http://dl.linux-sunxi.org/A13/A13%20Datasheet%20-%20v1.12%20%282012-03-29%29.pdf - -Signed-off-by: Hans de Goede <hdegoede@redhat.com> -Acked-by: Maxime Ripard <maxime.ripard@free-electrons.com> ---- - drivers/pinctrl/pinctrl-sunxi-pins.h | 12 ++++++------ - 1 file changed, 6 insertions(+), 6 deletions(-) - ---- a/drivers/pinctrl/pinctrl-sunxi-pins.h -+++ b/drivers/pinctrl/pinctrl-sunxi-pins.h -@@ -1932,27 +1932,27 @@ static const struct sunxi_desc_pin sun5i - SUNXI_PIN(SUNXI_PINCTRL_PIN_PF0, - SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), -- SUNXI_FUNCTION(0x4, "mmc0")), /* D1 */ -+ SUNXI_FUNCTION(0x2, "mmc0")), /* D1 */ - SUNXI_PIN(SUNXI_PINCTRL_PIN_PF1, - SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), -- SUNXI_FUNCTION(0x4, "mmc0")), /* D0 */ -+ SUNXI_FUNCTION(0x2, "mmc0")), /* D0 */ - SUNXI_PIN(SUNXI_PINCTRL_PIN_PF2, - SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), -- SUNXI_FUNCTION(0x4, "mmc0")), /* CLK */ -+ SUNXI_FUNCTION(0x2, "mmc0")), /* CLK */ - SUNXI_PIN(SUNXI_PINCTRL_PIN_PF3, - SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), -- SUNXI_FUNCTION(0x4, "mmc0")), /* CMD */ -+ SUNXI_FUNCTION(0x2, "mmc0")), /* CMD */ - SUNXI_PIN(SUNXI_PINCTRL_PIN_PF4, - SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), -- SUNXI_FUNCTION(0x4, "mmc0")), /* D3 */ -+ SUNXI_FUNCTION(0x2, "mmc0")), /* D3 */ - SUNXI_PIN(SUNXI_PINCTRL_PIN_PF5, - SUNXI_FUNCTION(0x0, "gpio_in"), - SUNXI_FUNCTION(0x1, "gpio_out"), -- SUNXI_FUNCTION(0x4, "mmc0")), /* D2 */ -+ SUNXI_FUNCTION(0x2, "mmc0")), /* D2 */ - /* Hole */ - SUNXI_PIN(SUNXI_PINCTRL_PIN_PG0, - SUNXI_FUNCTION(0x0, "gpio_in"), ---- a/drivers/pinctrl/pinctrl-sunxi.c -+++ b/drivers/pinctrl/pinctrl-sunxi.c -@@ -13,6 +13,7 @@ - #include <linux/io.h> - #include <linux/clk.h> - #include <linux/gpio.h> -+#include <linux/irqchip/chained_irq.h> - #include <linux/irqdomain.h> - #include <linux/irqchip/chained_irq.h> - #include <linux/module.h> -@@ -670,6 +671,8 @@ static void sunxi_pinctrl_irq_handler(un - struct sunxi_pinctrl *pctl = irq_get_handler_data(irq); - const unsigned long reg = readl(pctl->membase + IRQ_STATUS_REG); - -+ chained_irq_enter(chip, desc); -+ - /* Clear all interrupts */ - writel(reg, pctl->membase + IRQ_STATUS_REG); - -@@ -683,6 +686,7 @@ static void sunxi_pinctrl_irq_handler(un - } - chained_irq_exit(chip, desc); - } -+ chained_irq_exit(chip, desc); - } - - static struct of_device_id sunxi_pinctrl_match[] = { diff --git a/target/linux/sunxi/patches-3.14/136-1-irqchip-sun4i-fixes.patch b/target/linux/sunxi/patches-3.14/136-1-irqchip-sun4i-fixes.patch deleted file mode 100644 index 4345d3e0dd..0000000000 --- a/target/linux/sunxi/patches-3.14/136-1-irqchip-sun4i-fixes.patch +++ /dev/null @@ -1,217 +0,0 @@ -From 843da234cfc0e7014f9e2da82786a485e0820665 Mon Sep 17 00:00:00 2001 -From: Thomas Gleixner <tglx@linutronix.de> -Date: Thu, 13 Mar 2014 15:32:05 +0100 -Subject: [PATCH] irq: Add a new IRQCHIP_EOI_THREADED flag - -This flag must be used in combination with handle_fasteoi_irq, when set -handle_fasteoi_irq will delay the calling of chip->irq_eoi until the threaded -handler has run. - -Reviewed-by: Hans de Goede <hdegoede@redhat.com> -Tested-by: Hans de Goede <hdegoede@redhat.com> -Signed-off-by: Hans de Goede <hdegoede@redhat.com> ---- - include/linux/irq.h | 3 +++ - kernel/irq/chip.c | 48 ++++++++++++++++++++++++++++++++++++++++-------- - kernel/irq/internals.h | 1 + - kernel/irq/manage.c | 2 +- - 4 files changed, 45 insertions(+), 9 deletions(-) - ---- a/include/linux/irq.h -+++ b/include/linux/irq.h -@@ -349,6 +349,8 @@ struct irq_chip { - * IRQCHIP_ONOFFLINE_ENABLED: Only call irq_on/off_line callbacks - * when irq enabled - * IRQCHIP_SKIP_SET_WAKE: Skip chip.irq_set_wake(), for this irq chip -+ * IRQCHIP_ONESHOT_SAFE: One shot does not require mask/unmask -+ * IRQCHIP_EOI_THREADED: Chip requires eoi() on unmask in threaded mode - */ - enum { - IRQCHIP_SET_TYPE_MASKED = (1 << 0), -@@ -357,6 +359,7 @@ enum { - IRQCHIP_ONOFFLINE_ENABLED = (1 << 3), - IRQCHIP_SKIP_SET_WAKE = (1 << 4), - IRQCHIP_ONESHOT_SAFE = (1 << 5), -+ IRQCHIP_EOI_THREADED = (1 << 6), - }; - - /* This include will go away once we isolated irq_desc usage to core code */ ---- a/kernel/irq/chip.c -+++ b/kernel/irq/chip.c -@@ -281,6 +281,19 @@ void unmask_irq(struct irq_desc *desc) - } - } - -+void unmask_threaded_irq(struct irq_desc *desc) -+{ -+ struct irq_chip *chip = desc->irq_data.chip; -+ -+ if (chip->flags & IRQCHIP_EOI_THREADED) -+ chip->irq_eoi(&desc->irq_data); -+ -+ if (chip->irq_unmask) { -+ chip->irq_unmask(&desc->irq_data); -+ irq_state_clr_masked(desc); -+ } -+} -+ - /* - * handle_nested_irq - Handle a nested irq from a irq thread - * @irq: the interrupt number -@@ -435,6 +448,27 @@ static inline void preflow_handler(struc - static inline void preflow_handler(struct irq_desc *desc) { } - #endif - -+static void cond_unmask_eoi_irq(struct irq_desc *desc, struct irq_chip *chip) -+{ -+ if (!(desc->istate & IRQS_ONESHOT)) { -+ chip->irq_eoi(&desc->irq_data); -+ return; -+ } -+ /* -+ * We need to unmask in the following cases: -+ * - Oneshot irq which did not wake the thread (caused by a -+ * spurious interrupt or a primary handler handling it -+ * completely). -+ */ -+ if (!irqd_irq_disabled(&desc->irq_data) && -+ irqd_irq_masked(&desc->irq_data) && !desc->threads_oneshot) { -+ chip->irq_eoi(&desc->irq_data); -+ unmask_irq(desc); -+ } else if (!(chip->flags & IRQCHIP_EOI_THREADED)) { -+ chip->irq_eoi(&desc->irq_data); -+ } -+} -+ - /** - * handle_fasteoi_irq - irq handler for transparent controllers - * @irq: the interrupt number -@@ -448,6 +482,8 @@ static inline void preflow_handler(struc - void - handle_fasteoi_irq(unsigned int irq, struct irq_desc *desc) - { -+ struct irq_chip *chip = desc->irq_data.chip; -+ - raw_spin_lock(&desc->lock); - - if (unlikely(irqd_irq_inprogress(&desc->irq_data))) -@@ -473,18 +509,14 @@ handle_fasteoi_irq(unsigned int irq, str - preflow_handler(desc); - handle_irq_event(desc); - -- if (desc->istate & IRQS_ONESHOT) -- cond_unmask_irq(desc); -+ cond_unmask_eoi_irq(desc, chip); - --out_eoi: -- desc->irq_data.chip->irq_eoi(&desc->irq_data); --out_unlock: - raw_spin_unlock(&desc->lock); - return; - out: -- if (!(desc->irq_data.chip->flags & IRQCHIP_EOI_IF_HANDLED)) -- goto out_eoi; -- goto out_unlock; -+ if (!(chip->flags & IRQCHIP_EOI_IF_HANDLED)) -+ chip->irq_eoi(&desc->irq_data); -+ raw_spin_unlock(&desc->lock); - } - - /** ---- a/kernel/irq/internals.h -+++ b/kernel/irq/internals.h -@@ -73,6 +73,7 @@ extern void irq_percpu_enable(struct irq - extern void irq_percpu_disable(struct irq_desc *desc, unsigned int cpu); - extern void mask_irq(struct irq_desc *desc); - extern void unmask_irq(struct irq_desc *desc); -+extern void unmask_threaded_irq(struct irq_desc *desc); - - extern void init_kstat_irqs(struct irq_desc *desc, int node, int nr); - ---- a/kernel/irq/manage.c -+++ b/kernel/irq/manage.c -@@ -713,7 +713,7 @@ again: - - if (!desc->threads_oneshot && !irqd_irq_disabled(&desc->irq_data) && - irqd_irq_masked(&desc->irq_data)) -- unmask_irq(desc); -+ unmask_threaded_irq(desc); - - out_unlock: - raw_spin_unlock_irq(&desc->lock); ---- a/drivers/irqchip/irq-sun4i.c -+++ b/drivers/irqchip/irq-sun4i.c -@@ -41,13 +41,11 @@ static asmlinkage void __exception_irq_e - static void sun4i_irq_ack(struct irq_data *irqd) - { - unsigned int irq = irqd_to_hwirq(irqd); -- unsigned int irq_off = irq % 32; -- int reg = irq / 32; -- u32 val; - -- val = readl(sun4i_irq_base + SUN4I_IRQ_PENDING_REG(reg)); -- writel(val | (1 << irq_off), -- sun4i_irq_base + SUN4I_IRQ_PENDING_REG(reg)); -+ if (irq != 0) -+ return; /* Only IRQ 0 / the ENMI needs to be acked */ -+ -+ writel(BIT(0), sun4i_irq_base + SUN4I_IRQ_PENDING_REG(0)); - } - - static void sun4i_irq_mask(struct irq_data *irqd) -@@ -76,16 +74,16 @@ static void sun4i_irq_unmask(struct irq_ - - static struct irq_chip sun4i_irq_chip = { - .name = "sun4i_irq", -- .irq_ack = sun4i_irq_ack, -+ .irq_eoi = sun4i_irq_ack, - .irq_mask = sun4i_irq_mask, - .irq_unmask = sun4i_irq_unmask, -+ .flags = IRQCHIP_EOI_THREADED | IRQCHIP_EOI_IF_HANDLED, - }; - - static int sun4i_irq_map(struct irq_domain *d, unsigned int virq, - irq_hw_number_t hw) - { -- irq_set_chip_and_handler(virq, &sun4i_irq_chip, -- handle_level_irq); -+ irq_set_chip_and_handler(virq, &sun4i_irq_chip, handle_fasteoi_irq); - set_irq_flags(virq, IRQF_VALID | IRQF_PROBE); - - return 0; -@@ -109,7 +107,7 @@ static int __init sun4i_of_init(struct d - writel(0, sun4i_irq_base + SUN4I_IRQ_ENABLE_REG(1)); - writel(0, sun4i_irq_base + SUN4I_IRQ_ENABLE_REG(2)); - -- /* Mask all the interrupts */ -+ /* Unmask all the interrupts, ENABLE_REG(x) is used for masking */ - writel(0, sun4i_irq_base + SUN4I_IRQ_MASK_REG(0)); - writel(0, sun4i_irq_base + SUN4I_IRQ_MASK_REG(1)); - writel(0, sun4i_irq_base + SUN4I_IRQ_MASK_REG(2)); -@@ -140,10 +138,24 @@ static asmlinkage void __exception_irq_e - { - u32 irq, hwirq; - -+ /* -+ * hwirq == 0 can mean one of 3 things: -+ * 1) no more irqs pending -+ * 2) irq 0 pending -+ * 3) spurious irq -+ * So if we immediately get a reading of 0, check the irq-pending reg -+ * to differentiate between 2 and 3. We only do this once to avoid -+ * the extra check in the common case of 1 hapening after having -+ * read the vector-reg once. -+ */ - hwirq = readl(sun4i_irq_base + SUN4I_IRQ_VECTOR_REG) >> 2; -- while (hwirq != 0) { -+ if (hwirq == 0 && -+ !(readl(sun4i_irq_base + SUN4I_IRQ_PENDING_REG(0)) & BIT(0))) -+ return; -+ -+ do { - irq = irq_find_mapping(sun4i_irq_domain, hwirq); - handle_IRQ(irq, regs); - hwirq = readl(sun4i_irq_base + SUN4I_IRQ_VECTOR_REG) >> 2; -- } -+ } while (hwirq != 0); - } diff --git a/target/linux/sunxi/patches-3.14/137-1-pinctrl-create-irq-pin-mapping.patch b/target/linux/sunxi/patches-3.14/137-1-pinctrl-create-irq-pin-mapping.patch deleted file mode 100644 index 1e4f1c79df..0000000000 --- a/target/linux/sunxi/patches-3.14/137-1-pinctrl-create-irq-pin-mapping.patch +++ /dev/null @@ -1,36 +0,0 @@ -From 4c228d02d1339a286e259893062ea445be82b573 Mon Sep 17 00:00:00 2001 -From: Chen-Yu Tsai <wens@csie.org> -Date: Tue, 7 Jan 2014 18:56:29 +0800 -Subject: [PATCH] pinctrl: sunxi: create irq/pin mapping during init - -The irq/pin mapping is used to lookup the pin to mux to the irq -function when the irq is enabled. It is created when gpio_to_irq -is called. Creating the mapping during init allows us to map the -interrupts directly from the device tree. - -Signed-off-by: Chen-Yu Tsai <wens@csie.org> ---- - drivers/pinctrl/pinctrl-sunxi.c | 5 +++-- - 1 file changed, 3 insertions(+), 2 deletions(-) - ---- a/drivers/pinctrl/pinctrl-sunxi.c -+++ b/drivers/pinctrl/pinctrl-sunxi.c -@@ -531,8 +531,6 @@ static int sunxi_pinctrl_gpio_to_irq(str - if (!desc) - return -EINVAL; - -- pctl->irq_array[desc->irqnum] = offset; -- - dev_dbg(chip->dev, "%s: request IRQ for GPIO %d, return %d\n", - chip->label, offset + chip->base, desc->irqnum); - -@@ -759,6 +757,9 @@ static int sunxi_pinctrl_build_state(str - struct sunxi_desc_function *func = pin->functions; - - while (func->name) { -+ /* Create interrupt mapping while we're at it */ -+ if (!strcmp(func->name, "irq")) -+ pctl->irq_array[func->irqnum] = pin->pin.number; - sunxi_pinctrl_add_function(pctl, func->name); - func++; - } diff --git a/target/linux/sunxi/patches-3.14/137-2-pinctrl-add-IRQCHIP_SKIP_SET_WAKE.patch b/target/linux/sunxi/patches-3.14/137-2-pinctrl-add-IRQCHIP_SKIP_SET_WAKE.patch deleted file mode 100644 index 58e13946d9..0000000000 --- a/target/linux/sunxi/patches-3.14/137-2-pinctrl-add-IRQCHIP_SKIP_SET_WAKE.patch +++ /dev/null @@ -1,26 +0,0 @@ -From 77f1265dd02dfd5dcaa0ebd6d3ea1d131bc095e2 Mon Sep 17 00:00:00 2001 -From: Chen-Yu Tsai <wens@csie.org> -Date: Tue, 7 Jan 2014 19:01:29 +0800 -Subject: [PATCH] pinctrl: sunxi: add IRQCHIP_SKIP_SET_WAKE flag for pinctrl - irq chip - -The sunxi pinctrl irq chip driver does not support wakeup at the -moment. Adding IRQCHIP_SKIP_SET_WAKE lets the irqs work with drivers -using wakeup. - -Also add a name to the irq chip. ---- - drivers/pinctrl/pinctrl-sunxi.c | 2 ++ - 1 file changed, 2 insertions(+) - ---- a/drivers/pinctrl/pinctrl-sunxi.c -+++ b/drivers/pinctrl/pinctrl-sunxi.c -@@ -661,6 +661,8 @@ static struct irq_chip sunxi_pinctrl_irq - .irq_mask_ack = sunxi_pinctrl_irq_mask_ack, - .irq_unmask = sunxi_pinctrl_irq_unmask, - .irq_set_type = sunxi_pinctrl_irq_set_type, -+ .name = "sunxi-pio", -+ .flags = IRQCHIP_SKIP_SET_WAKE, - }; - - static void sunxi_pinctrl_irq_handler(unsigned irq, struct irq_desc *desc) diff --git a/target/linux/sunxi/patches-3.14/137-3-dt-sun7i-add-interrupt-cells.patch b/target/linux/sunxi/patches-3.14/137-3-dt-sun7i-add-interrupt-cells.patch deleted file mode 100644 index fb3b5cde95..0000000000 --- a/target/linux/sunxi/patches-3.14/137-3-dt-sun7i-add-interrupt-cells.patch +++ /dev/null @@ -1,26 +0,0 @@ -From eda34c0692e479dd9cd2b7cb70986ae57f15187f Mon Sep 17 00:00:00 2001 -From: Chen-Yu Tsai <wens@csie.org> -Date: Tue, 7 Jan 2014 18:50:01 +0800 -Subject: [PATCH] ARM: dts: sun7i: Add #interrupt-cells to pinctrl node - -The pinctrl device is also an interrupt controller for external -interrupts. Add the missing #interrupt-cells property. - -Also remove the unused #address-cells property. - -Signed-off-by: Chen-Yu Tsai <wens@csie.org> ---- - arch/arm/boot/dts/sun7i-a20.dtsi | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/arch/arm/boot/dts/sun7i-a20.dtsi -+++ b/arch/arm/boot/dts/sun7i-a20.dtsi -@@ -424,7 +424,7 @@ - clocks = <&apb0_gates 5>; - gpio-controller; - interrupt-controller; -- #address-cells = <1>; -+ #interrupt-cells = <2>; - #size-cells = <0>; - #gpio-cells = <3>; - diff --git a/target/linux/sunxi/patches-3.14/140-dt-sunxi-convert-to-new-clock-compats.patch b/target/linux/sunxi/patches-3.14/140-dt-sunxi-convert-to-new-clock-compats.patch deleted file mode 100644 index 875aea1450..0000000000 --- a/target/linux/sunxi/patches-3.14/140-dt-sunxi-convert-to-new-clock-compats.patch +++ /dev/null @@ -1,1017 +0,0 @@ -From 46b2ee17d7321149b4d48dd86ee2e346624aa141 Mon Sep 17 00:00:00 2001 -From: Maxime Ripard <maxime.ripard@free-electrons.com> -Date: Thu, 6 Feb 2014 09:55:58 +0100 -Subject: [PATCH] ARM: sunxi: dt: Convert to the new clock compatibles - -Switch the device tree to the new compatibles introduced in the clock drivers -to have a common pattern accross all Allwinner SoCs. - -Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com> ---- - arch/arm/boot/dts/sun4i-a10.dtsi | 60 +++++++++++++++++++-------------------- - arch/arm/boot/dts/sun5i-a10s.dtsi | 48 +++++++++++++++---------------- - arch/arm/boot/dts/sun5i-a13.dtsi | 48 +++++++++++++++---------------- - arch/arm/boot/dts/sun6i-a31.dtsi | 10 +++---- - arch/arm/boot/dts/sun7i-a20.dtsi | 54 +++++++++++++++++------------------ - 5 files changed, 110 insertions(+), 110 deletions(-) - ---- a/arch/arm/boot/dts/sun4i-a10.dtsi -+++ b/arch/arm/boot/dts/sun4i-a10.dtsi -@@ -60,7 +60,7 @@ - - osc24M: clk@01c20050 { - #clock-cells = <0>; -- compatible = "allwinner,sun4i-osc-clk"; -+ compatible = "allwinner,sun4i-a10-osc-clk"; - reg = <0x01c20050 0x4>; - clock-frequency = <24000000>; - clock-output-names = "osc24M"; -@@ -75,7 +75,7 @@ - - pll1: clk@01c20000 { - #clock-cells = <0>; -- compatible = "allwinner,sun4i-pll1-clk"; -+ compatible = "allwinner,sun4i-a10-pll1-clk"; - reg = <0x01c20000 0x4>; - clocks = <&osc24M>; - clock-output-names = "pll1"; -@@ -83,7 +83,7 @@ - - pll4: clk@01c20018 { - #clock-cells = <0>; -- compatible = "allwinner,sun4i-pll1-clk"; -+ compatible = "allwinner,sun4i-a10-pll1-clk"; - reg = <0x01c20018 0x4>; - clocks = <&osc24M>; - clock-output-names = "pll4"; -@@ -91,7 +91,7 @@ - - pll5: clk@01c20020 { - #clock-cells = <1>; -- compatible = "allwinner,sun4i-pll5-clk"; -+ compatible = "allwinner,sun4i-a10-pll5-clk"; - reg = <0x01c20020 0x4>; - clocks = <&osc24M>; - clock-output-names = "pll5_ddr", "pll5_other"; -@@ -99,7 +99,7 @@ - - pll6: clk@01c20028 { - #clock-cells = <1>; -- compatible = "allwinner,sun4i-pll6-clk"; -+ compatible = "allwinner,sun4i-a10-pll6-clk"; - reg = <0x01c20028 0x4>; - clocks = <&osc24M>; - clock-output-names = "pll6_sata", "pll6_other", "pll6"; -@@ -108,7 +108,7 @@ - /* dummy is 200M */ - cpu: cpu@01c20054 { - #clock-cells = <0>; -- compatible = "allwinner,sun4i-cpu-clk"; -+ compatible = "allwinner,sun4i-a10-cpu-clk"; - reg = <0x01c20054 0x4>; - clocks = <&osc32k>, <&osc24M>, <&pll1>, <&dummy>; - clock-output-names = "cpu"; -@@ -116,7 +116,7 @@ - - axi: axi@01c20054 { - #clock-cells = <0>; -- compatible = "allwinner,sun4i-axi-clk"; -+ compatible = "allwinner,sun4i-a10-axi-clk"; - reg = <0x01c20054 0x4>; - clocks = <&cpu>; - clock-output-names = "axi"; -@@ -124,7 +124,7 @@ - - axi_gates: clk@01c2005c { - #clock-cells = <1>; -- compatible = "allwinner,sun4i-axi-gates-clk"; -+ compatible = "allwinner,sun4i-a10-axi-gates-clk"; - reg = <0x01c2005c 0x4>; - clocks = <&axi>; - clock-output-names = "axi_dram"; -@@ -132,7 +132,7 @@ - - ahb: ahb@01c20054 { - #clock-cells = <0>; -- compatible = "allwinner,sun4i-ahb-clk"; -+ compatible = "allwinner,sun4i-a10-ahb-clk"; - reg = <0x01c20054 0x4>; - clocks = <&axi>; - clock-output-names = "ahb"; -@@ -140,7 +140,7 @@ - - ahb_gates: clk@01c20060 { - #clock-cells = <1>; -- compatible = "allwinner,sun4i-ahb-gates-clk"; -+ compatible = "allwinner,sun4i-a10-ahb-gates-clk"; - reg = <0x01c20060 0x8>; - clocks = <&ahb>; - clock-output-names = "ahb_usb0", "ahb_ehci0", -@@ -158,7 +158,7 @@ - - apb0: apb0@01c20054 { - #clock-cells = <0>; -- compatible = "allwinner,sun4i-apb0-clk"; -+ compatible = "allwinner,sun4i-a10-apb0-clk"; - reg = <0x01c20054 0x4>; - clocks = <&ahb>; - clock-output-names = "apb0"; -@@ -166,7 +166,7 @@ - - apb0_gates: clk@01c20068 { - #clock-cells = <1>; -- compatible = "allwinner,sun4i-apb0-gates-clk"; -+ compatible = "allwinner,sun4i-a10-apb0-gates-clk"; - reg = <0x01c20068 0x4>; - clocks = <&apb0>; - clock-output-names = "apb0_codec", "apb0_spdif", -@@ -176,7 +176,7 @@ - - apb1_mux: apb1_mux@01c20058 { - #clock-cells = <0>; -- compatible = "allwinner,sun4i-apb1-mux-clk"; -+ compatible = "allwinner,sun4i-a10-apb1-mux-clk"; - reg = <0x01c20058 0x4>; - clocks = <&osc24M>, <&pll6 1>, <&osc32k>; - clock-output-names = "apb1_mux"; -@@ -184,7 +184,7 @@ - - apb1: apb1@01c20058 { - #clock-cells = <0>; -- compatible = "allwinner,sun4i-apb1-clk"; -+ compatible = "allwinner,sun4i-a10-apb1-clk"; - reg = <0x01c20058 0x4>; - clocks = <&apb1_mux>; - clock-output-names = "apb1"; -@@ -192,7 +192,7 @@ - - apb1_gates: clk@01c2006c { - #clock-cells = <1>; -- compatible = "allwinner,sun4i-apb1-gates-clk"; -+ compatible = "allwinner,sun4i-a10-apb1-gates-clk"; - reg = <0x01c2006c 0x4>; - clocks = <&apb1>; - clock-output-names = "apb1_i2c0", "apb1_i2c1", -@@ -205,7 +205,7 @@ - - nand_clk: clk@01c20080 { - #clock-cells = <0>; -- compatible = "allwinner,sun4i-mod0-clk"; -+ compatible = "allwinner,sun4i-a10-mod0-clk"; - reg = <0x01c20080 0x4>; - clocks = <&osc24M>, <&pll6 1>, <&pll5 1>; - clock-output-names = "nand"; -@@ -213,7 +213,7 @@ - - ms_clk: clk@01c20084 { - #clock-cells = <0>; -- compatible = "allwinner,sun4i-mod0-clk"; -+ compatible = "allwinner,sun4i-a10-mod0-clk"; - reg = <0x01c20084 0x4>; - clocks = <&osc24M>, <&pll6 1>, <&pll5 1>; - clock-output-names = "ms"; -@@ -221,7 +221,7 @@ - - mmc0_clk: clk@01c20088 { - #clock-cells = <0>; -- compatible = "allwinner,sun4i-mod0-clk"; -+ compatible = "allwinner,sun4i-a10-mod0-clk"; - reg = <0x01c20088 0x4>; - clocks = <&osc24M>, <&pll6 1>, <&pll5 1>; - clock-output-names = "mmc0"; -@@ -229,7 +229,7 @@ - - mmc1_clk: clk@01c2008c { - #clock-cells = <0>; -- compatible = "allwinner,sun4i-mod0-clk"; -+ compatible = "allwinner,sun4i-a10-mod0-clk"; - reg = <0x01c2008c 0x4>; - clocks = <&osc24M>, <&pll6 1>, <&pll5 1>; - clock-output-names = "mmc1"; -@@ -237,7 +237,7 @@ - - mmc2_clk: clk@01c20090 { - #clock-cells = <0>; -- compatible = "allwinner,sun4i-mod0-clk"; -+ compatible = "allwinner,sun4i-a10-mod0-clk"; - reg = <0x01c20090 0x4>; - clocks = <&osc24M>, <&pll6 1>, <&pll5 1>; - clock-output-names = "mmc2"; -@@ -245,7 +245,7 @@ - - mmc3_clk: clk@01c20094 { - #clock-cells = <0>; -- compatible = "allwinner,sun4i-mod0-clk"; -+ compatible = "allwinner,sun4i-a10-mod0-clk"; - reg = <0x01c20094 0x4>; - clocks = <&osc24M>, <&pll6 1>, <&pll5 1>; - clock-output-names = "mmc3"; -@@ -253,7 +253,7 @@ - - ts_clk: clk@01c20098 { - #clock-cells = <0>; -- compatible = "allwinner,sun4i-mod0-clk"; -+ compatible = "allwinner,sun4i-a10-mod0-clk"; - reg = <0x01c20098 0x4>; - clocks = <&osc24M>, <&pll6 1>, <&pll5 1>; - clock-output-names = "ts"; -@@ -261,7 +261,7 @@ - - ss_clk: clk@01c2009c { - #clock-cells = <0>; -- compatible = "allwinner,sun4i-mod0-clk"; -+ compatible = "allwinner,sun4i-a10-mod0-clk"; - reg = <0x01c2009c 0x4>; - clocks = <&osc24M>, <&pll6 1>, <&pll5 1>; - clock-output-names = "ss"; -@@ -269,7 +269,7 @@ - - spi0_clk: clk@01c200a0 { - #clock-cells = <0>; -- compatible = "allwinner,sun4i-mod0-clk"; -+ compatible = "allwinner,sun4i-a10-mod0-clk"; - reg = <0x01c200a0 0x4>; - clocks = <&osc24M>, <&pll6 1>, <&pll5 1>; - clock-output-names = "spi0"; -@@ -277,7 +277,7 @@ - - spi1_clk: clk@01c200a4 { - #clock-cells = <0>; -- compatible = "allwinner,sun4i-mod0-clk"; -+ compatible = "allwinner,sun4i-a10-mod0-clk"; - reg = <0x01c200a4 0x4>; - clocks = <&osc24M>, <&pll6 1>, <&pll5 1>; - clock-output-names = "spi1"; -@@ -285,7 +285,7 @@ - - spi2_clk: clk@01c200a8 { - #clock-cells = <0>; -- compatible = "allwinner,sun4i-mod0-clk"; -+ compatible = "allwinner,sun4i-a10-mod0-clk"; - reg = <0x01c200a8 0x4>; - clocks = <&osc24M>, <&pll6 1>, <&pll5 1>; - clock-output-names = "spi2"; -@@ -293,7 +293,7 @@ - - pata_clk: clk@01c200ac { - #clock-cells = <0>; -- compatible = "allwinner,sun4i-mod0-clk"; -+ compatible = "allwinner,sun4i-a10-mod0-clk"; - reg = <0x01c200ac 0x4>; - clocks = <&osc24M>, <&pll6 1>, <&pll5 1>; - clock-output-names = "pata"; -@@ -301,7 +301,7 @@ - - ir0_clk: clk@01c200b0 { - #clock-cells = <0>; -- compatible = "allwinner,sun4i-mod0-clk"; -+ compatible = "allwinner,sun4i-a10-mod0-clk"; - reg = <0x01c200b0 0x4>; - clocks = <&osc24M>, <&pll6 1>, <&pll5 1>; - clock-output-names = "ir0"; -@@ -309,7 +309,7 @@ - - ir1_clk: clk@01c200b4 { - #clock-cells = <0>; -- compatible = "allwinner,sun4i-mod0-clk"; -+ compatible = "allwinner,sun4i-a10-mod0-clk"; - reg = <0x01c200b4 0x4>; - clocks = <&osc24M>, <&pll6 1>, <&pll5 1>; - clock-output-names = "ir1"; -@@ -326,7 +326,7 @@ - - spi3_clk: clk@01c200d4 { - #clock-cells = <0>; -- compatible = "allwinner,sun4i-mod0-clk"; -+ compatible = "allwinner,sun4i-a10-mod0-clk"; - reg = <0x01c200d4 0x4>; - clocks = <&osc24M>, <&pll6 1>, <&pll5 1>; - clock-output-names = "spi3"; ---- a/arch/arm/boot/dts/sun5i-a10s.dtsi -+++ b/arch/arm/boot/dts/sun5i-a10s.dtsi -@@ -49,7 +49,7 @@ - - osc24M: clk@01c20050 { - #clock-cells = <0>; -- compatible = "allwinner,sun4i-osc-clk"; -+ compatible = "allwinner,sun4i-a10-osc-clk"; - reg = <0x01c20050 0x4>; - clock-frequency = <24000000>; - clock-output-names = "osc24M"; -@@ -64,7 +64,7 @@ - - pll1: clk@01c20000 { - #clock-cells = <0>; -- compatible = "allwinner,sun4i-pll1-clk"; -+ compatible = "allwinner,sun4i-a10-pll1-clk"; - reg = <0x01c20000 0x4>; - clocks = <&osc24M>; - clock-output-names = "pll1"; -@@ -72,7 +72,7 @@ - - pll4: clk@01c20018 { - #clock-cells = <0>; -- compatible = "allwinner,sun4i-pll1-clk"; -+ compatible = "allwinner,sun4i-a10-pll1-clk"; - reg = <0x01c20018 0x4>; - clocks = <&osc24M>; - clock-output-names = "pll4"; -@@ -80,7 +80,7 @@ - - pll5: clk@01c20020 { - #clock-cells = <1>; -- compatible = "allwinner,sun4i-pll5-clk"; -+ compatible = "allwinner,sun4i-a10-pll5-clk"; - reg = <0x01c20020 0x4>; - clocks = <&osc24M>; - clock-output-names = "pll5_ddr", "pll5_other"; -@@ -88,7 +88,7 @@ - - pll6: clk@01c20028 { - #clock-cells = <1>; -- compatible = "allwinner,sun4i-pll6-clk"; -+ compatible = "allwinner,sun4i-a10-pll6-clk"; - reg = <0x01c20028 0x4>; - clocks = <&osc24M>; - clock-output-names = "pll6_sata", "pll6_other", "pll6"; -@@ -97,7 +97,7 @@ - /* dummy is 200M */ - cpu: cpu@01c20054 { - #clock-cells = <0>; -- compatible = "allwinner,sun4i-cpu-clk"; -+ compatible = "allwinner,sun4i-a10-cpu-clk"; - reg = <0x01c20054 0x4>; - clocks = <&osc32k>, <&osc24M>, <&pll1>, <&dummy>; - clock-output-names = "cpu"; -@@ -105,7 +105,7 @@ - - axi: axi@01c20054 { - #clock-cells = <0>; -- compatible = "allwinner,sun4i-axi-clk"; -+ compatible = "allwinner,sun4i-a10-axi-clk"; - reg = <0x01c20054 0x4>; - clocks = <&cpu>; - clock-output-names = "axi"; -@@ -113,7 +113,7 @@ - - axi_gates: clk@01c2005c { - #clock-cells = <1>; -- compatible = "allwinner,sun4i-axi-gates-clk"; -+ compatible = "allwinner,sun4i-a10-axi-gates-clk"; - reg = <0x01c2005c 0x4>; - clocks = <&axi>; - clock-output-names = "axi_dram"; -@@ -121,7 +121,7 @@ - - ahb: ahb@01c20054 { - #clock-cells = <0>; -- compatible = "allwinner,sun4i-ahb-clk"; -+ compatible = "allwinner,sun4i-a10-ahb-clk"; - reg = <0x01c20054 0x4>; - clocks = <&axi>; - clock-output-names = "ahb"; -@@ -143,7 +143,7 @@ - - apb0: apb0@01c20054 { - #clock-cells = <0>; -- compatible = "allwinner,sun4i-apb0-clk"; -+ compatible = "allwinner,sun4i-a10-apb0-clk"; - reg = <0x01c20054 0x4>; - clocks = <&ahb>; - clock-output-names = "apb0"; -@@ -160,7 +160,7 @@ - - apb1_mux: apb1_mux@01c20058 { - #clock-cells = <0>; -- compatible = "allwinner,sun4i-apb1-mux-clk"; -+ compatible = "allwinner,sun4i-a10-apb1-mux-clk"; - reg = <0x01c20058 0x4>; - clocks = <&osc24M>, <&pll6 1>, <&osc32k>; - clock-output-names = "apb1_mux"; -@@ -168,7 +168,7 @@ - - apb1: apb1@01c20058 { - #clock-cells = <0>; -- compatible = "allwinner,sun4i-apb1-clk"; -+ compatible = "allwinner,sun4i-a10-apb1-clk"; - reg = <0x01c20058 0x4>; - clocks = <&apb1_mux>; - clock-output-names = "apb1"; -@@ -186,7 +186,7 @@ - - nand_clk: clk@01c20080 { - #clock-cells = <0>; -- compatible = "allwinner,sun4i-mod0-clk"; -+ compatible = "allwinner,sun4i-a10-mod0-clk"; - reg = <0x01c20080 0x4>; - clocks = <&osc24M>, <&pll6 1>, <&pll5 1>; - clock-output-names = "nand"; -@@ -194,7 +194,7 @@ - - ms_clk: clk@01c20084 { - #clock-cells = <0>; -- compatible = "allwinner,sun4i-mod0-clk"; -+ compatible = "allwinner,sun4i-a10-mod0-clk"; - reg = <0x01c20084 0x4>; - clocks = <&osc24M>, <&pll6 1>, <&pll5 1>; - clock-output-names = "ms"; -@@ -202,7 +202,7 @@ - - mmc0_clk: clk@01c20088 { - #clock-cells = <0>; -- compatible = "allwinner,sun4i-mod0-clk"; -+ compatible = "allwinner,sun4i-a10-mod0-clk"; - reg = <0x01c20088 0x4>; - clocks = <&osc24M>, <&pll6 1>, <&pll5 1>; - clock-output-names = "mmc0"; -@@ -210,7 +210,7 @@ - - mmc1_clk: clk@01c2008c { - #clock-cells = <0>; -- compatible = "allwinner,sun4i-mod0-clk"; -+ compatible = "allwinner,sun4i-a10-mod0-clk"; - reg = <0x01c2008c 0x4>; - clocks = <&osc24M>, <&pll6 1>, <&pll5 1>; - clock-output-names = "mmc1"; -@@ -218,7 +218,7 @@ - - mmc2_clk: clk@01c20090 { - #clock-cells = <0>; -- compatible = "allwinner,sun4i-mod0-clk"; -+ compatible = "allwinner,sun4i-a10-mod0-clk"; - reg = <0x01c20090 0x4>; - clocks = <&osc24M>, <&pll6 1>, <&pll5 1>; - clock-output-names = "mmc2"; -@@ -226,7 +226,7 @@ - - ts_clk: clk@01c20098 { - #clock-cells = <0>; -- compatible = "allwinner,sun4i-mod0-clk"; -+ compatible = "allwinner,sun4i-a10-mod0-clk"; - reg = <0x01c20098 0x4>; - clocks = <&osc24M>, <&pll6 1>, <&pll5 1>; - clock-output-names = "ts"; -@@ -234,7 +234,7 @@ - - ss_clk: clk@01c2009c { - #clock-cells = <0>; -- compatible = "allwinner,sun4i-mod0-clk"; -+ compatible = "allwinner,sun4i-a10-mod0-clk"; - reg = <0x01c2009c 0x4>; - clocks = <&osc24M>, <&pll6 1>, <&pll5 1>; - clock-output-names = "ss"; -@@ -242,7 +242,7 @@ - - spi0_clk: clk@01c200a0 { - #clock-cells = <0>; -- compatible = "allwinner,sun4i-mod0-clk"; -+ compatible = "allwinner,sun4i-a10-mod0-clk"; - reg = <0x01c200a0 0x4>; - clocks = <&osc24M>, <&pll6 1>, <&pll5 1>; - clock-output-names = "spi0"; -@@ -250,7 +250,7 @@ - - spi1_clk: clk@01c200a4 { - #clock-cells = <0>; -- compatible = "allwinner,sun4i-mod0-clk"; -+ compatible = "allwinner,sun4i-a10-mod0-clk"; - reg = <0x01c200a4 0x4>; - clocks = <&osc24M>, <&pll6 1>, <&pll5 1>; - clock-output-names = "spi1"; -@@ -258,7 +258,7 @@ - - spi2_clk: clk@01c200a8 { - #clock-cells = <0>; -- compatible = "allwinner,sun4i-mod0-clk"; -+ compatible = "allwinner,sun4i-a10-mod0-clk"; - reg = <0x01c200a8 0x4>; - clocks = <&osc24M>, <&pll6 1>, <&pll5 1>; - clock-output-names = "spi2"; -@@ -266,7 +266,7 @@ - - ir0_clk: clk@01c200b0 { - #clock-cells = <0>; -- compatible = "allwinner,sun4i-mod0-clk"; -+ compatible = "allwinner,sun4i-a10-mod0-clk"; - reg = <0x01c200b0 0x4>; - clocks = <&osc24M>, <&pll6 1>, <&pll5 1>; - clock-output-names = "ir0"; -@@ -283,7 +283,7 @@ - - mbus_clk: clk@01c2015c { - #clock-cells = <0>; -- compatible = "allwinner,sun4i-mod0-clk"; -+ compatible = "allwinner,sun4i-a10-mod0-clk"; - reg = <0x01c2015c 0x4>; - clocks = <&osc24M>, <&pll6 1>, <&pll5 1>; - clock-output-names = "mbus"; ---- a/arch/arm/boot/dts/sun5i-a13.dtsi -+++ b/arch/arm/boot/dts/sun5i-a13.dtsi -@@ -54,7 +54,7 @@ - - osc24M: clk@01c20050 { - #clock-cells = <0>; -- compatible = "allwinner,sun4i-osc-clk"; -+ compatible = "allwinner,sun4i-a10-osc-clk"; - reg = <0x01c20050 0x4>; - clock-frequency = <24000000>; - clock-output-names = "osc24M"; -@@ -69,7 +69,7 @@ - - pll1: clk@01c20000 { - #clock-cells = <0>; -- compatible = "allwinner,sun4i-pll1-clk"; -+ compatible = "allwinner,sun4i-a10-pll1-clk"; - reg = <0x01c20000 0x4>; - clocks = <&osc24M>; - clock-output-names = "pll1"; -@@ -77,7 +77,7 @@ - - pll4: clk@01c20018 { - #clock-cells = <0>; -- compatible = "allwinner,sun4i-pll1-clk"; -+ compatible = "allwinner,sun4i-a10-pll1-clk"; - reg = <0x01c20018 0x4>; - clocks = <&osc24M>; - clock-output-names = "pll4"; -@@ -85,7 +85,7 @@ - - pll5: clk@01c20020 { - #clock-cells = <1>; -- compatible = "allwinner,sun4i-pll5-clk"; -+ compatible = "allwinner,sun4i-a10-pll5-clk"; - reg = <0x01c20020 0x4>; - clocks = <&osc24M>; - clock-output-names = "pll5_ddr", "pll5_other"; -@@ -93,7 +93,7 @@ - - pll6: clk@01c20028 { - #clock-cells = <1>; -- compatible = "allwinner,sun4i-pll6-clk"; -+ compatible = "allwinner,sun4i-a10-pll6-clk"; - reg = <0x01c20028 0x4>; - clocks = <&osc24M>; - clock-output-names = "pll6_sata", "pll6_other", "pll6"; -@@ -102,7 +102,7 @@ - /* dummy is 200M */ - cpu: cpu@01c20054 { - #clock-cells = <0>; -- compatible = "allwinner,sun4i-cpu-clk"; -+ compatible = "allwinner,sun4i-a10-cpu-clk"; - reg = <0x01c20054 0x4>; - clocks = <&osc32k>, <&osc24M>, <&pll1>, <&dummy>; - clock-output-names = "cpu"; -@@ -110,7 +110,7 @@ - - axi: axi@01c20054 { - #clock-cells = <0>; -- compatible = "allwinner,sun4i-axi-clk"; -+ compatible = "allwinner,sun4i-a10-axi-clk"; - reg = <0x01c20054 0x4>; - clocks = <&cpu>; - clock-output-names = "axi"; -@@ -118,7 +118,7 @@ - - axi_gates: clk@01c2005c { - #clock-cells = <1>; -- compatible = "allwinner,sun4i-axi-gates-clk"; -+ compatible = "allwinner,sun4i-a10-axi-gates-clk"; - reg = <0x01c2005c 0x4>; - clocks = <&axi>; - clock-output-names = "axi_dram"; -@@ -126,7 +126,7 @@ - - ahb: ahb@01c20054 { - #clock-cells = <0>; -- compatible = "allwinner,sun4i-ahb-clk"; -+ compatible = "allwinner,sun4i-a10-ahb-clk"; - reg = <0x01c20054 0x4>; - clocks = <&axi>; - clock-output-names = "ahb"; -@@ -147,7 +147,7 @@ - - apb0: apb0@01c20054 { - #clock-cells = <0>; -- compatible = "allwinner,sun4i-apb0-clk"; -+ compatible = "allwinner,sun4i-a10-apb0-clk"; - reg = <0x01c20054 0x4>; - clocks = <&ahb>; - clock-output-names = "apb0"; -@@ -163,7 +163,7 @@ - - apb1_mux: apb1_mux@01c20058 { - #clock-cells = <0>; -- compatible = "allwinner,sun4i-apb1-mux-clk"; -+ compatible = "allwinner,sun4i-a10-apb1-mux-clk"; - reg = <0x01c20058 0x4>; - clocks = <&osc24M>, <&pll6 1>, <&osc32k>; - clock-output-names = "apb1_mux"; -@@ -171,7 +171,7 @@ - - apb1: apb1@01c20058 { - #clock-cells = <0>; -- compatible = "allwinner,sun4i-apb1-clk"; -+ compatible = "allwinner,sun4i-a10-apb1-clk"; - reg = <0x01c20058 0x4>; - clocks = <&apb1_mux>; - clock-output-names = "apb1"; -@@ -188,7 +188,7 @@ - - nand_clk: clk@01c20080 { - #clock-cells = <0>; -- compatible = "allwinner,sun4i-mod0-clk"; -+ compatible = "allwinner,sun4i-a10-mod0-clk"; - reg = <0x01c20080 0x4>; - clocks = <&osc24M>, <&pll6 1>, <&pll5 1>; - clock-output-names = "nand"; -@@ -196,7 +196,7 @@ - - ms_clk: clk@01c20084 { - #clock-cells = <0>; -- compatible = "allwinner,sun4i-mod0-clk"; -+ compatible = "allwinner,sun4i-a10-mod0-clk"; - reg = <0x01c20084 0x4>; - clocks = <&osc24M>, <&pll6 1>, <&pll5 1>; - clock-output-names = "ms"; -@@ -204,7 +204,7 @@ - - mmc0_clk: clk@01c20088 { - #clock-cells = <0>; -- compatible = "allwinner,sun4i-mod0-clk"; -+ compatible = "allwinner,sun4i-a10-mod0-clk"; - reg = <0x01c20088 0x4>; - clocks = <&osc24M>, <&pll6 1>, <&pll5 1>; - clock-output-names = "mmc0"; -@@ -212,7 +212,7 @@ - - mmc1_clk: clk@01c2008c { - #clock-cells = <0>; -- compatible = "allwinner,sun4i-mod0-clk"; -+ compatible = "allwinner,sun4i-a10-mod0-clk"; - reg = <0x01c2008c 0x4>; - clocks = <&osc24M>, <&pll6 1>, <&pll5 1>; - clock-output-names = "mmc1"; -@@ -220,7 +220,7 @@ - - mmc2_clk: clk@01c20090 { - #clock-cells = <0>; -- compatible = "allwinner,sun4i-mod0-clk"; -+ compatible = "allwinner,sun4i-a10-mod0-clk"; - reg = <0x01c20090 0x4>; - clocks = <&osc24M>, <&pll6 1>, <&pll5 1>; - clock-output-names = "mmc2"; -@@ -228,7 +228,7 @@ - - ts_clk: clk@01c20098 { - #clock-cells = <0>; -- compatible = "allwinner,sun4i-mod0-clk"; -+ compatible = "allwinner,sun4i-a10-mod0-clk"; - reg = <0x01c20098 0x4>; - clocks = <&osc24M>, <&pll6 1>, <&pll5 1>; - clock-output-names = "ts"; -@@ -236,7 +236,7 @@ - - ss_clk: clk@01c2009c { - #clock-cells = <0>; -- compatible = "allwinner,sun4i-mod0-clk"; -+ compatible = "allwinner,sun4i-a10-mod0-clk"; - reg = <0x01c2009c 0x4>; - clocks = <&osc24M>, <&pll6 1>, <&pll5 1>; - clock-output-names = "ss"; -@@ -244,7 +244,7 @@ - - spi0_clk: clk@01c200a0 { - #clock-cells = <0>; -- compatible = "allwinner,sun4i-mod0-clk"; -+ compatible = "allwinner,sun4i-a10-mod0-clk"; - reg = <0x01c200a0 0x4>; - clocks = <&osc24M>, <&pll6 1>, <&pll5 1>; - clock-output-names = "spi0"; -@@ -252,7 +252,7 @@ - - spi1_clk: clk@01c200a4 { - #clock-cells = <0>; -- compatible = "allwinner,sun4i-mod0-clk"; -+ compatible = "allwinner,sun4i-a10-mod0-clk"; - reg = <0x01c200a4 0x4>; - clocks = <&osc24M>, <&pll6 1>, <&pll5 1>; - clock-output-names = "spi1"; -@@ -260,7 +260,7 @@ - - spi2_clk: clk@01c200a8 { - #clock-cells = <0>; -- compatible = "allwinner,sun4i-mod0-clk"; -+ compatible = "allwinner,sun4i-a10-mod0-clk"; - reg = <0x01c200a8 0x4>; - clocks = <&osc24M>, <&pll6 1>, <&pll5 1>; - clock-output-names = "spi2"; -@@ -268,7 +268,7 @@ - - ir0_clk: clk@01c200b0 { - #clock-cells = <0>; -- compatible = "allwinner,sun4i-mod0-clk"; -+ compatible = "allwinner,sun4i-a10-mod0-clk"; - reg = <0x01c200b0 0x4>; - clocks = <&osc24M>, <&pll6 1>, <&pll5 1>; - clock-output-names = "ir0"; -@@ -285,7 +285,7 @@ - - mbus_clk: clk@01c2015c { - #clock-cells = <0>; -- compatible = "allwinner,sun4i-mod0-clk"; -+ compatible = "allwinner,sun4i-a10-mod0-clk"; - reg = <0x01c2015c 0x4>; - clocks = <&osc24M>, <&pll6 1>, <&pll5 1>; - clock-output-names = "mbus"; ---- a/arch/arm/boot/dts/sun6i-a31.dtsi -+++ b/arch/arm/boot/dts/sun6i-a31.dtsi -@@ -95,7 +95,7 @@ - - cpu: cpu@01c20050 { - #clock-cells = <0>; -- compatible = "allwinner,sun4i-cpu-clk"; -+ compatible = "allwinner,sun4i-a10-cpu-clk"; - reg = <0x01c20050 0x4>; - - /* -@@ -110,7 +110,7 @@ - - axi: axi@01c20050 { - #clock-cells = <0>; -- compatible = "allwinner,sun4i-axi-clk"; -+ compatible = "allwinner,sun4i-a10-axi-clk"; - reg = <0x01c20050 0x4>; - clocks = <&cpu>; - clock-output-names = "axi"; -@@ -126,7 +126,7 @@ - - ahb1: ahb1@01c20054 { - #clock-cells = <0>; -- compatible = "allwinner,sun4i-ahb-clk"; -+ compatible = "allwinner,sun4i-a10-ahb-clk"; - reg = <0x01c20054 0x4>; - clocks = <&ahb1_mux>; - clock-output-names = "ahb1"; -@@ -155,7 +155,7 @@ - - apb1: apb1@01c20054 { - #clock-cells = <0>; -- compatible = "allwinner,sun4i-apb0-clk"; -+ compatible = "allwinner,sun4i-a10-apb0-clk"; - reg = <0x01c20054 0x4>; - clocks = <&ahb1>; - clock-output-names = "apb1"; -@@ -173,7 +173,7 @@ - - apb2_mux: apb2_mux@01c20058 { - #clock-cells = <0>; -- compatible = "allwinner,sun4i-apb1-mux-clk"; -+ compatible = "allwinner,sun4i-a10-apb1-mux-clk"; - reg = <0x01c20058 0x4>; - clocks = <&osc32k>, <&osc24M>, <&pll6>, <&pll6>; - clock-output-names = "apb2_mux"; ---- a/arch/arm/boot/dts/sun7i-a20.dtsi -+++ b/arch/arm/boot/dts/sun7i-a20.dtsi -@@ -64,7 +64,7 @@ - - osc24M: clk@01c20050 { - #clock-cells = <0>; -- compatible = "allwinner,sun4i-osc-clk"; -+ compatible = "allwinner,sun4i-a10-osc-clk"; - reg = <0x01c20050 0x4>; - clock-frequency = <24000000>; - clock-output-names = "osc24M"; -@@ -79,7 +79,7 @@ - - pll1: clk@01c20000 { - #clock-cells = <0>; -- compatible = "allwinner,sun4i-pll1-clk"; -+ compatible = "allwinner,sun4i-a10-pll1-clk"; - reg = <0x01c20000 0x4>; - clocks = <&osc24M>; - clock-output-names = "pll1"; -@@ -87,7 +87,7 @@ - - pll4: clk@01c20018 { - #clock-cells = <0>; -- compatible = "allwinner,sun4i-pll1-clk"; -+ compatible = "allwinner,sun4i-a10-pll1-clk"; - reg = <0x01c20018 0x4>; - clocks = <&osc24M>; - clock-output-names = "pll4"; -@@ -95,7 +95,7 @@ - - pll5: clk@01c20020 { - #clock-cells = <1>; -- compatible = "allwinner,sun4i-pll5-clk"; -+ compatible = "allwinner,sun4i-a10-pll5-clk"; - reg = <0x01c20020 0x4>; - clocks = <&osc24M>; - clock-output-names = "pll5_ddr", "pll5_other"; -@@ -103,7 +103,7 @@ - - pll6: clk@01c20028 { - #clock-cells = <1>; -- compatible = "allwinner,sun4i-pll6-clk"; -+ compatible = "allwinner,sun4i-a10-pll6-clk"; - reg = <0x01c20028 0x4>; - clocks = <&osc24M>; - clock-output-names = "pll6_sata", "pll6_other", "pll6"; -@@ -111,7 +111,7 @@ - - cpu: cpu@01c20054 { - #clock-cells = <0>; -- compatible = "allwinner,sun4i-cpu-clk"; -+ compatible = "allwinner,sun4i-a10-cpu-clk"; - reg = <0x01c20054 0x4>; - clocks = <&osc32k>, <&osc24M>, <&pll1>, <&pll6 1>; - clock-output-names = "cpu"; -@@ -119,7 +119,7 @@ - - axi: axi@01c20054 { - #clock-cells = <0>; -- compatible = "allwinner,sun4i-axi-clk"; -+ compatible = "allwinner,sun4i-a10-axi-clk"; - reg = <0x01c20054 0x4>; - clocks = <&cpu>; - clock-output-names = "axi"; -@@ -127,7 +127,7 @@ - - ahb: ahb@01c20054 { - #clock-cells = <0>; -- compatible = "allwinner,sun4i-ahb-clk"; -+ compatible = "allwinner,sun4i-a10-ahb-clk"; - reg = <0x01c20054 0x4>; - clocks = <&axi>; - clock-output-names = "ahb"; -@@ -155,7 +155,7 @@ - - apb0: apb0@01c20054 { - #clock-cells = <0>; -- compatible = "allwinner,sun4i-apb0-clk"; -+ compatible = "allwinner,sun4i-a10-apb0-clk"; - reg = <0x01c20054 0x4>; - clocks = <&ahb>; - clock-output-names = "apb0"; -@@ -174,7 +174,7 @@ - - apb1_mux: apb1_mux@01c20058 { - #clock-cells = <0>; -- compatible = "allwinner,sun4i-apb1-mux-clk"; -+ compatible = "allwinner,sun4i-a10-apb1-mux-clk"; - reg = <0x01c20058 0x4>; - clocks = <&osc24M>, <&pll6 1>, <&osc32k>; - clock-output-names = "apb1_mux"; -@@ -182,7 +182,7 @@ - - apb1: apb1@01c20058 { - #clock-cells = <0>; -- compatible = "allwinner,sun4i-apb1-clk"; -+ compatible = "allwinner,sun4i-a10-apb1-clk"; - reg = <0x01c20058 0x4>; - clocks = <&apb1_mux>; - clock-output-names = "apb1"; -@@ -203,7 +203,7 @@ - - nand_clk: clk@01c20080 { - #clock-cells = <0>; -- compatible = "allwinner,sun4i-mod0-clk"; -+ compatible = "allwinner,sun4i-a10-mod0-clk"; - reg = <0x01c20080 0x4>; - clocks = <&osc24M>, <&pll6 1>, <&pll5 1>; - clock-output-names = "nand"; -@@ -211,7 +211,7 @@ - - ms_clk: clk@01c20084 { - #clock-cells = <0>; -- compatible = "allwinner,sun4i-mod0-clk"; -+ compatible = "allwinner,sun4i-a10-mod0-clk"; - reg = <0x01c20084 0x4>; - clocks = <&osc24M>, <&pll6 1>, <&pll5 1>; - clock-output-names = "ms"; -@@ -219,7 +219,7 @@ - - mmc0_clk: clk@01c20088 { - #clock-cells = <0>; -- compatible = "allwinner,sun4i-mod0-clk"; -+ compatible = "allwinner,sun4i-a10-mod0-clk"; - reg = <0x01c20088 0x4>; - clocks = <&osc24M>, <&pll6 1>, <&pll5 1>; - clock-output-names = "mmc0"; -@@ -227,7 +227,7 @@ - - mmc1_clk: clk@01c2008c { - #clock-cells = <0>; -- compatible = "allwinner,sun4i-mod0-clk"; -+ compatible = "allwinner,sun4i-a10-mod0-clk"; - reg = <0x01c2008c 0x4>; - clocks = <&osc24M>, <&pll6 1>, <&pll5 1>; - clock-output-names = "mmc1"; -@@ -235,7 +235,7 @@ - - mmc2_clk: clk@01c20090 { - #clock-cells = <0>; -- compatible = "allwinner,sun4i-mod0-clk"; -+ compatible = "allwinner,sun4i-a10-mod0-clk"; - reg = <0x01c20090 0x4>; - clocks = <&osc24M>, <&pll6 1>, <&pll5 1>; - clock-output-names = "mmc2"; -@@ -243,7 +243,7 @@ - - mmc3_clk: clk@01c20094 { - #clock-cells = <0>; -- compatible = "allwinner,sun4i-mod0-clk"; -+ compatible = "allwinner,sun4i-a10-mod0-clk"; - reg = <0x01c20094 0x4>; - clocks = <&osc24M>, <&pll6 1>, <&pll5 1>; - clock-output-names = "mmc3"; -@@ -251,7 +251,7 @@ - - ts_clk: clk@01c20098 { - #clock-cells = <0>; -- compatible = "allwinner,sun4i-mod0-clk"; -+ compatible = "allwinner,sun4i-a10-mod0-clk"; - reg = <0x01c20098 0x4>; - clocks = <&osc24M>, <&pll6 1>, <&pll5 1>; - clock-output-names = "ts"; -@@ -259,7 +259,7 @@ - - ss_clk: clk@01c2009c { - #clock-cells = <0>; -- compatible = "allwinner,sun4i-mod0-clk"; -+ compatible = "allwinner,sun4i-a10-mod0-clk"; - reg = <0x01c2009c 0x4>; - clocks = <&osc24M>, <&pll6 1>, <&pll5 1>; - clock-output-names = "ss"; -@@ -267,7 +267,7 @@ - - spi0_clk: clk@01c200a0 { - #clock-cells = <0>; -- compatible = "allwinner,sun4i-mod0-clk"; -+ compatible = "allwinner,sun4i-a10-mod0-clk"; - reg = <0x01c200a0 0x4>; - clocks = <&osc24M>, <&pll6 1>, <&pll5 1>; - clock-output-names = "spi0"; -@@ -275,7 +275,7 @@ - - spi1_clk: clk@01c200a4 { - #clock-cells = <0>; -- compatible = "allwinner,sun4i-mod0-clk"; -+ compatible = "allwinner,sun4i-a10-mod0-clk"; - reg = <0x01c200a4 0x4>; - clocks = <&osc24M>, <&pll6 1>, <&pll5 1>; - clock-output-names = "spi1"; -@@ -283,7 +283,7 @@ - - spi2_clk: clk@01c200a8 { - #clock-cells = <0>; -- compatible = "allwinner,sun4i-mod0-clk"; -+ compatible = "allwinner,sun4i-a10-mod0-clk"; - reg = <0x01c200a8 0x4>; - clocks = <&osc24M>, <&pll6 1>, <&pll5 1>; - clock-output-names = "spi2"; -@@ -291,7 +291,7 @@ - - pata_clk: clk@01c200ac { - #clock-cells = <0>; -- compatible = "allwinner,sun4i-mod0-clk"; -+ compatible = "allwinner,sun4i-a10-mod0-clk"; - reg = <0x01c200ac 0x4>; - clocks = <&osc24M>, <&pll6 1>, <&pll5 1>; - clock-output-names = "pata"; -@@ -299,7 +299,7 @@ - - ir0_clk: clk@01c200b0 { - #clock-cells = <0>; -- compatible = "allwinner,sun4i-mod0-clk"; -+ compatible = "allwinner,sun4i-a10-mod0-clk"; - reg = <0x01c200b0 0x4>; - clocks = <&osc24M>, <&pll6 1>, <&pll5 1>; - clock-output-names = "ir0"; -@@ -307,7 +307,7 @@ - - ir1_clk: clk@01c200b4 { - #clock-cells = <0>; -- compatible = "allwinner,sun4i-mod0-clk"; -+ compatible = "allwinner,sun4i-a10-mod0-clk"; - reg = <0x01c200b4 0x4>; - clocks = <&osc24M>, <&pll6 1>, <&pll5 1>; - clock-output-names = "ir1"; -@@ -324,7 +324,7 @@ - - spi3_clk: clk@01c200d4 { - #clock-cells = <0>; -- compatible = "allwinner,sun4i-mod0-clk"; -+ compatible = "allwinner,sun4i-a10-mod0-clk"; - reg = <0x01c200d4 0x4>; - clocks = <&osc24M>, <&pll6 1>, <&pll5 1>; - clock-output-names = "spi3"; -@@ -332,7 +332,7 @@ - - mbus_clk: clk@01c2015c { - #clock-cells = <0>; -- compatible = "allwinner,sun4i-mod0-clk"; -+ compatible = "allwinner,sun4i-a10-mod0-clk"; - reg = <0x01c2015c 0x4>; - clocks = <&osc24M>, <&pll6 2>, <&pll5 1>; - clock-output-names = "mbus"; diff --git a/target/linux/sunxi/patches-3.14/141-dt-sunxi-add-common-regulator-include.patch b/target/linux/sunxi/patches-3.14/141-dt-sunxi-add-common-regulator-include.patch deleted file mode 100644 index 32f4f72a9b..0000000000 --- a/target/linux/sunxi/patches-3.14/141-dt-sunxi-add-common-regulator-include.patch +++ /dev/null @@ -1,97 +0,0 @@ -From 6e763a8ebe7a16ae5635ade146fd2930749ed775 Mon Sep 17 00:00:00 2001 -From: Hans de Goede <hdegoede@redhat.com> -Date: Sat, 1 Mar 2014 14:57:56 +0100 -Subject: [PATCH] ARM: sunxi: dt: Add sunxi-common-regulators include file - -Most sunxi boards with a sata connector also have a gpio controlled connector -for sata target power and almost all sunxi boards have a gpio controlled vbus -for usb1 and usb2. - -This commit adds an include file for the regulators representing these -supplies, avoiding the need to copy and paste the regulator code to allmost -all sunxi board dts files. - -Signed-off-by: Hans de Goede <hdegoede@redhat.com> ---- - arch/arm/boot/dts/sunxi-common-regulators.dtsi | 75 ++++++++++++++++++++++++++ - 1 file changed, 75 insertions(+) - create mode 100644 arch/arm/boot/dts/sunxi-common-regulators.dtsi - ---- /dev/null -+++ b/arch/arm/boot/dts/sunxi-common-regulators.dtsi -@@ -0,0 +1,75 @@ -+/* -+ * sunxi boards common regulator (ahci target power supply, usb-vbus) code -+ * -+ * Copyright 2014 - Hans de Goede <hdegoede@redhat.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 -+ */ -+ -+/ { -+ soc@01c00000 { -+ pio: pinctrl@01c20800 { -+ ahci_pwr_pin_a: ahci_pwr_pin@0 { -+ allwinner,pins = "PB8"; -+ allwinner,function = "gpio_out"; -+ allwinner,drive = <0>; -+ allwinner,pull = <0>; -+ }; -+ -+ usb1_vbus_pin_a: usb1_vbus_pin@0 { -+ allwinner,pins = "PH6"; -+ allwinner,function = "gpio_out"; -+ allwinner,drive = <0>; -+ allwinner,pull = <0>; -+ }; -+ -+ usb2_vbus_pin_a: usb2_vbus_pin@0 { -+ allwinner,pins = "PH3"; -+ allwinner,function = "gpio_out"; -+ allwinner,drive = <0>; -+ allwinner,pull = <0>; -+ }; -+ }; -+ }; -+ -+ reg_ahci_5v: ahci-5v { -+ compatible = "regulator-fixed"; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&ahci_pwr_pin_a>; -+ regulator-name = "ahci-5v"; -+ regulator-min-microvolt = <5000000>; -+ regulator-max-microvolt = <5000000>; -+ enable-active-high; -+ gpio = <&pio 1 8 0>; -+ status = "disabled"; -+ }; -+ -+ reg_usb1_vbus: usb1-vbus { -+ compatible = "regulator-fixed"; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&usb1_vbus_pin_a>; -+ regulator-name = "usb1-vbus"; -+ regulator-min-microvolt = <5000000>; -+ regulator-max-microvolt = <5000000>; -+ enable-active-high; -+ gpio = <&pio 7 6 0>; -+ status = "disabled"; -+ }; -+ -+ reg_usb2_vbus: usb2-vbus { -+ compatible = "regulator-fixed"; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&usb2_vbus_pin_a>; -+ regulator-name = "usb2-vbus"; -+ regulator-min-microvolt = <5000000>; -+ regulator-max-microvolt = <5000000>; -+ enable-active-high; -+ gpio = <&pio 7 3 0>; -+ status = "disabled"; -+ }; -+}; diff --git a/target/linux/sunxi/patches-3.14/145-1-dt-sun7i-add-a20-spi.patch b/target/linux/sunxi/patches-3.14/145-1-dt-sun7i-add-a20-spi.patch deleted file mode 100644 index 9f8f00c6f8..0000000000 --- a/target/linux/sunxi/patches-3.14/145-1-dt-sun7i-add-a20-spi.patch +++ /dev/null @@ -1,73 +0,0 @@ -From c9bfaadf8973cb4d9074e80c4bf8708deca62712 Mon Sep 17 00:00:00 2001 -From: Maxime Ripard <maxime.ripard@free-electrons.com> -Date: Sat, 22 Feb 2014 22:35:54 +0100 -Subject: [PATCH] ARM: dt: sun7i: Add A20 SPI controller nodes - -The A20 has 4 SPI controllers compatible with the one found in the A10. Add -them in the DT. - -Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com> ---- - arch/arm/boot/dts/sun7i-a20.dtsi | 44 ++++++++++++++++++++++++++++++++++++++++ - 1 file changed, 44 insertions(+) - ---- a/arch/arm/boot/dts/sun7i-a20.dtsi -+++ b/arch/arm/boot/dts/sun7i-a20.dtsi -@@ -401,6 +401,28 @@ - #size-cells = <1>; - ranges; - -+ spi0: spi@01c05000 { -+ compatible = "allwinner,sun4i-a10-spi"; -+ reg = <0x01c05000 0x1000>; -+ interrupts = <0 10 4>; -+ clocks = <&ahb_gates 20>, <&spi0_clk>; -+ clock-names = "ahb", "mod"; -+ status = "disabled"; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ }; -+ -+ spi1: spi@01c06000 { -+ compatible = "allwinner,sun4i-a10-spi"; -+ reg = <0x01c06000 0x1000>; -+ interrupts = <0 11 4>; -+ clocks = <&ahb_gates 21>, <&spi1_clk>; -+ clock-names = "ahb", "mod"; -+ status = "disabled"; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ }; -+ - emac: ethernet@01c0b000 { - compatible = "allwinner,sun4i-a10-emac"; - reg = <0x01c0b000 0x1000>; -@@ -417,6 +439,28 @@ - #size-cells = <0>; - }; - -+ spi2: spi@01c17000 { -+ compatible = "allwinner,sun4i-a10-spi"; -+ reg = <0x01c17000 0x1000>; -+ interrupts = <0 12 4>; -+ clocks = <&ahb_gates 22>, <&spi2_clk>; -+ clock-names = "ahb", "mod"; -+ status = "disabled"; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ }; -+ -+ spi3: spi@01c1f000 { -+ compatible = "allwinner,sun4i-a10-spi"; -+ reg = <0x01c1f000 0x1000>; -+ interrupts = <0 50 4>; -+ clocks = <&ahb_gates 23>, <&spi3_clk>; -+ clock-names = "ahb", "mod"; -+ status = "disabled"; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ }; -+ - pio: pinctrl@01c20800 { - compatible = "allwinner,sun7i-a20-pinctrl"; - reg = <0x01c20800 0x400>; diff --git a/target/linux/sunxi/patches-3.14/145-2-dt-sun4i-add-a10-spi.patch b/target/linux/sunxi/patches-3.14/145-2-dt-sun4i-add-a10-spi.patch deleted file mode 100644 index 4bc9ea0039..0000000000 --- a/target/linux/sunxi/patches-3.14/145-2-dt-sun4i-add-a10-spi.patch +++ /dev/null @@ -1,72 +0,0 @@ -From cac3c4d67c80c4895d0d44e609beb535d66af6a3 Mon Sep 17 00:00:00 2001 -From: Maxime Ripard <maxime.ripard@free-electrons.com> -Date: Sat, 22 Feb 2014 22:35:55 +0100 -Subject: [PATCH] ARM: dt: sun4i: Add A10 SPI controller nodes - -The A10 has 4 SPI controllers that are now supported. Add them in the DT. - -Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com> ---- - arch/arm/boot/dts/sun4i-a10.dtsi | 44 ++++++++++++++++++++++++++++++++++++++++ - 1 file changed, 44 insertions(+) - ---- a/arch/arm/boot/dts/sun4i-a10.dtsi -+++ b/arch/arm/boot/dts/sun4i-a10.dtsi -@@ -339,6 +339,28 @@ - #size-cells = <1>; - ranges; - -+ spi0: spi@01c05000 { -+ compatible = "allwinner,sun4i-a10-spi"; -+ reg = <0x01c05000 0x1000>; -+ interrupts = <10>; -+ clocks = <&ahb_gates 20>, <&spi0_clk>; -+ clock-names = "ahb", "mod"; -+ status = "disabled"; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ }; -+ -+ spi1: spi@01c06000 { -+ compatible = "allwinner,sun4i-a10-spi"; -+ reg = <0x01c06000 0x1000>; -+ interrupts = <11>; -+ clocks = <&ahb_gates 21>, <&spi1_clk>; -+ clock-names = "ahb", "mod"; -+ status = "disabled"; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ }; -+ - emac: ethernet@01c0b000 { - compatible = "allwinner,sun4i-a10-emac"; - reg = <0x01c0b000 0x1000>; -@@ -355,6 +377,28 @@ - #size-cells = <0>; - }; - -+ spi2: spi@01c17000 { -+ compatible = "allwinner,sun4i-a10-spi"; -+ reg = <0x01c17000 0x1000>; -+ interrupts = <12>; -+ clocks = <&ahb_gates 22>, <&spi2_clk>; -+ clock-names = "ahb", "mod"; -+ status = "disabled"; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ }; -+ -+ spi3: spi@01c1f000 { -+ compatible = "allwinner,sun4i-a10-spi"; -+ reg = <0x01c1f000 0x1000>; -+ interrupts = <50>; -+ clocks = <&ahb_gates 23>, <&spi3_clk>; -+ clock-names = "ahb", "mod"; -+ status = "disabled"; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ }; -+ - intc: interrupt-controller@01c20400 { - compatible = "allwinner,sun4i-ic"; - reg = <0x01c20400 0x400>; diff --git a/target/linux/sunxi/patches-3.14/145-3-dt-sun5i-add-a13-spi.patch b/target/linux/sunxi/patches-3.14/145-3-dt-sun5i-add-a13-spi.patch deleted file mode 100644 index 7558d5623e..0000000000 --- a/target/linux/sunxi/patches-3.14/145-3-dt-sun5i-add-a13-spi.patch +++ /dev/null @@ -1,55 +0,0 @@ -From aeb3b73fc416e14afd25f25e69f8713488edcc1b Mon Sep 17 00:00:00 2001 -From: Maxime Ripard <maxime.ripard@free-electrons.com> -Date: Sat, 22 Feb 2014 22:35:57 +0100 -Subject: [PATCH] ARM: dt: sun5i: Add A13 SPI controller nodes - -The A13 has 3 SPI controllers compatible with the one found in the A10. Add -them in the DT. - -Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com> ---- - arch/arm/boot/dts/sun5i-a13.dtsi | 33 +++++++++++++++++++++++++++++++++ - 1 file changed, 33 insertions(+) - ---- a/arch/arm/boot/dts/sun5i-a13.dtsi -+++ b/arch/arm/boot/dts/sun5i-a13.dtsi -@@ -298,6 +298,39 @@ - #size-cells = <1>; - ranges; - -+ spi0: spi@01c05000 { -+ compatible = "allwinner,sun4i-a10-spi"; -+ reg = <0x01c05000 0x1000>; -+ interrupts = <10>; -+ clocks = <&ahb_gates 20>, <&spi0_clk>; -+ clock-names = "ahb", "mod"; -+ status = "disabled"; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ }; -+ -+ spi1: spi@01c06000 { -+ compatible = "allwinner,sun4i-a10-spi"; -+ reg = <0x01c06000 0x1000>; -+ interrupts = <11>; -+ clocks = <&ahb_gates 21>, <&spi1_clk>; -+ clock-names = "ahb", "mod"; -+ status = "disabled"; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ }; -+ -+ spi2: spi@01c17000 { -+ compatible = "allwinner,sun4i-a10-spi"; -+ reg = <0x01c17000 0x1000>; -+ interrupts = <12>; -+ clocks = <&ahb_gates 22>, <&spi2_clk>; -+ clock-names = "ahb", "mod"; -+ status = "disabled"; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ }; -+ - intc: interrupt-controller@01c20400 { - compatible = "allwinner,sun4i-ic"; - reg = <0x01c20400 0x400>; diff --git a/target/linux/sunxi/patches-3.14/146-1-spi-add-a31-spi.patch b/target/linux/sunxi/patches-3.14/146-1-spi-add-a31-spi.patch deleted file mode 100644 index 761ecc18f2..0000000000 --- a/target/linux/sunxi/patches-3.14/146-1-spi-add-a31-spi.patch +++ /dev/null @@ -1,559 +0,0 @@ -From 86cb7c7ab176112f8b0031dc7c8d19103ba52277 Mon Sep 17 00:00:00 2001 -From: Maxime Ripard <maxime.ripard@free-electrons.com> -Date: Wed, 5 Feb 2014 14:05:05 +0100 -Subject: [PATCH] spi: sunxi: Add Allwinner A31 SPI controller driver - -The Allwinner A31 has a new SPI controller IP compared to the older Allwinner -SoCs. - -It supports DMA, but the driver only does PIO for now, and DMA will be -supported eventually. - -Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com> ---- - .../devicetree/bindings/spi/spi-sun6i.txt | 24 + - drivers/spi/Kconfig | 6 + - drivers/spi/Makefile | 1 + - drivers/spi/spi-sun6i.c | 483 +++++++++++++++++++++ - 4 files changed, 514 insertions(+) - create mode 100644 Documentation/devicetree/bindings/spi/spi-sun6i.txt - create mode 100644 drivers/spi/spi-sun6i.c - ---- /dev/null -+++ b/Documentation/devicetree/bindings/spi/spi-sun6i.txt -@@ -0,0 +1,24 @@ -+Allwinner A31 SPI controller -+ -+Required properties: -+- compatible: Should be "allwinner,sun6i-a31-spi". -+- reg: Should contain register location and length. -+- interrupts: Should contain interrupt. -+- clocks: phandle to the clocks feeding the SPI controller. Two are -+ needed: -+ - "ahb": the gated AHB parent clock -+ - "mod": the parent module clock -+- clock-names: Must contain the clock names described just above -+- resets: phandle to the reset controller asserting this device in -+ reset -+ -+Example: -+ -+spi1: spi@01c69000 { -+ compatible = "allwinner,sun6i-a31-spi"; -+ reg = <0x01c69000 0x1000>; -+ interrupts = <0 66 4>; -+ clocks = <&ahb1_gates 21>, <&spi1_clk>; -+ clock-names = "ahb", "mod"; -+ resets = <&ahb1_rst 21>; -+}; ---- a/drivers/spi/Kconfig -+++ b/drivers/spi/Kconfig -@@ -455,6 +455,12 @@ config SPI_SIRF - help - SPI driver for CSR SiRFprimaII SoCs - -+config SPI_SUN6I -+ tristate "Allwinner A31 SPI controller" -+ depends on ARCH_SUNXI || COMPILE_TEST -+ help -+ This enables using the SPI controller on the Allwinner A31 SoCs. -+ - config SPI_MXS - tristate "Freescale MXS SPI controller" - depends on ARCH_MXS ---- a/drivers/spi/Makefile -+++ b/drivers/spi/Makefile -@@ -71,6 +71,7 @@ obj-$(CONFIG_SPI_SH_HSPI) += spi-sh-hsp - obj-$(CONFIG_SPI_SH_MSIOF) += spi-sh-msiof.o - obj-$(CONFIG_SPI_SH_SCI) += spi-sh-sci.o - obj-$(CONFIG_SPI_SIRF) += spi-sirf.o -+obj-$(CONFIG_SPI_SUN6I) += spi-sun6i.o - obj-$(CONFIG_SPI_TEGRA114) += spi-tegra114.o - obj-$(CONFIG_SPI_TEGRA20_SFLASH) += spi-tegra20-sflash.o - obj-$(CONFIG_SPI_TEGRA20_SLINK) += spi-tegra20-slink.o ---- /dev/null -+++ b/drivers/spi/spi-sun6i.c -@@ -0,0 +1,483 @@ -+/* -+ * Copyright (C) 2012 - 2014 Allwinner Tech -+ * Pan Nan <pannan@allwinnertech.com> -+ * -+ * Copyright (C) 2014 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/clk.h> -+#include <linux/delay.h> -+#include <linux/device.h> -+#include <linux/interrupt.h> -+#include <linux/io.h> -+#include <linux/module.h> -+#include <linux/platform_device.h> -+#include <linux/pm_runtime.h> -+#include <linux/reset.h> -+#include <linux/workqueue.h> -+ -+#include <linux/spi/spi.h> -+ -+#define SUN6I_FIFO_DEPTH 128 -+ -+#define SUN6I_GBL_CTL_REG 0x04 -+#define SUN6I_GBL_CTL_BUS_ENABLE BIT(0) -+#define SUN6I_GBL_CTL_MASTER BIT(1) -+#define SUN6I_GBL_CTL_TP BIT(7) -+#define SUN6I_GBL_CTL_RST BIT(31) -+ -+#define SUN6I_TFR_CTL_REG 0x08 -+#define SUN6I_TFR_CTL_CPHA BIT(0) -+#define SUN6I_TFR_CTL_CPOL BIT(1) -+#define SUN6I_TFR_CTL_SPOL BIT(2) -+#define SUN6I_TFR_CTL_CS_MASK 0x3 -+#define SUN6I_TFR_CTL_CS(cs) (((cs) & SUN6I_TFR_CTL_CS_MASK) << 4) -+#define SUN6I_TFR_CTL_CS_MANUAL BIT(6) -+#define SUN6I_TFR_CTL_CS_LEVEL BIT(7) -+#define SUN6I_TFR_CTL_DHB BIT(8) -+#define SUN6I_TFR_CTL_FBS BIT(12) -+#define SUN6I_TFR_CTL_XCH BIT(31) -+ -+#define SUN6I_INT_CTL_REG 0x10 -+#define SUN6I_INT_CTL_RF_OVF BIT(8) -+#define SUN6I_INT_CTL_TC BIT(12) -+ -+#define SUN6I_INT_STA_REG 0x14 -+ -+#define SUN6I_FIFO_CTL_REG 0x18 -+#define SUN6I_FIFO_CTL_RF_RST BIT(15) -+#define SUN6I_FIFO_CTL_TF_RST BIT(31) -+ -+#define SUN6I_FIFO_STA_REG 0x1c -+#define SUN6I_FIFO_STA_RF_CNT_MASK 0x7f -+#define SUN6I_FIFO_STA_RF_CNT_BITS 0 -+#define SUN6I_FIFO_STA_TF_CNT_MASK 0x7f -+#define SUN6I_FIFO_STA_TF_CNT_BITS 16 -+ -+#define SUN6I_CLK_CTL_REG 0x24 -+#define SUN6I_CLK_CTL_CDR2_MASK 0xff -+#define SUN6I_CLK_CTL_CDR2(div) (((div) & SUN6I_CLK_CTL_CDR2_MASK) << 0) -+#define SUN6I_CLK_CTL_CDR1_MASK 0xf -+#define SUN6I_CLK_CTL_CDR1(div) (((div) & SUN6I_CLK_CTL_CDR1_MASK) << 8) -+#define SUN6I_CLK_CTL_DRS BIT(12) -+ -+#define SUN6I_BURST_CNT_REG 0x30 -+#define SUN6I_BURST_CNT(cnt) ((cnt) & 0xffffff) -+ -+#define SUN6I_XMIT_CNT_REG 0x34 -+#define SUN6I_XMIT_CNT(cnt) ((cnt) & 0xffffff) -+ -+#define SUN6I_BURST_CTL_CNT_REG 0x38 -+#define SUN6I_BURST_CTL_CNT_STC(cnt) ((cnt) & 0xffffff) -+ -+#define SUN6I_TXDATA_REG 0x200 -+#define SUN6I_RXDATA_REG 0x300 -+ -+struct sun6i_spi { -+ struct spi_master *master; -+ void __iomem *base_addr; -+ struct clk *hclk; -+ struct clk *mclk; -+ struct reset_control *rstc; -+ -+ struct completion done; -+ -+ const u8 *tx_buf; -+ u8 *rx_buf; -+ int len; -+}; -+ -+static inline u32 sun6i_spi_read(struct sun6i_spi *sspi, u32 reg) -+{ -+ return readl(sspi->base_addr + reg); -+} -+ -+static inline void sun6i_spi_write(struct sun6i_spi *sspi, u32 reg, u32 value) -+{ -+ writel(value, sspi->base_addr + reg); -+} -+ -+static inline void sun6i_spi_drain_fifo(struct sun6i_spi *sspi, int len) -+{ -+ u32 reg, cnt; -+ u8 byte; -+ -+ /* See how much data is available */ -+ reg = sun6i_spi_read(sspi, SUN6I_FIFO_STA_REG); -+ reg &= SUN6I_FIFO_STA_RF_CNT_MASK; -+ cnt = reg >> SUN6I_FIFO_STA_RF_CNT_BITS; -+ -+ if (len > cnt) -+ len = cnt; -+ -+ while (len--) { -+ byte = readb(sspi->base_addr + SUN6I_RXDATA_REG); -+ if (sspi->rx_buf) -+ *sspi->rx_buf++ = byte; -+ } -+} -+ -+static inline void sun6i_spi_fill_fifo(struct sun6i_spi *sspi, int len) -+{ -+ u8 byte; -+ -+ if (len > sspi->len) -+ len = sspi->len; -+ -+ while (len--) { -+ byte = sspi->tx_buf ? *sspi->tx_buf++ : 0; -+ writeb(byte, sspi->base_addr + SUN6I_TXDATA_REG); -+ sspi->len--; -+ } -+} -+ -+static void sun6i_spi_set_cs(struct spi_device *spi, bool enable) -+{ -+ struct sun6i_spi *sspi = spi_master_get_devdata(spi->master); -+ u32 reg; -+ -+ reg = sun6i_spi_read(sspi, SUN6I_TFR_CTL_REG); -+ reg &= ~SUN6I_TFR_CTL_CS_MASK; -+ reg |= SUN6I_TFR_CTL_CS(spi->chip_select); -+ -+ if (enable) -+ reg |= SUN6I_TFR_CTL_CS_LEVEL; -+ else -+ reg &= ~SUN6I_TFR_CTL_CS_LEVEL; -+ -+ sun6i_spi_write(sspi, SUN6I_TFR_CTL_REG, reg); -+} -+ -+ -+static int sun6i_spi_transfer_one(struct spi_master *master, -+ struct spi_device *spi, -+ struct spi_transfer *tfr) -+{ -+ struct sun6i_spi *sspi = spi_master_get_devdata(master); -+ unsigned int mclk_rate, div, timeout; -+ unsigned int tx_len = 0; -+ int ret = 0; -+ u32 reg; -+ -+ /* We don't support transfer larger than the FIFO */ -+ if (tfr->len > SUN6I_FIFO_DEPTH) -+ return -EINVAL; -+ -+ reinit_completion(&sspi->done); -+ sspi->tx_buf = tfr->tx_buf; -+ sspi->rx_buf = tfr->rx_buf; -+ sspi->len = tfr->len; -+ -+ /* Clear pending interrupts */ -+ sun6i_spi_write(sspi, SUN6I_INT_STA_REG, ~0); -+ -+ /* Reset FIFO */ -+ sun6i_spi_write(sspi, SUN6I_FIFO_CTL_REG, -+ SUN6I_FIFO_CTL_RF_RST | SUN6I_FIFO_CTL_TF_RST); -+ -+ /* -+ * Setup the transfer control register: Chip Select, -+ * polarities, etc. -+ */ -+ reg = sun6i_spi_read(sspi, SUN6I_TFR_CTL_REG); -+ -+ if (spi->mode & SPI_CPOL) -+ reg |= SUN6I_TFR_CTL_CPOL; -+ else -+ reg &= ~SUN6I_TFR_CTL_CPOL; -+ -+ if (spi->mode & SPI_CPHA) -+ reg |= SUN6I_TFR_CTL_CPHA; -+ else -+ reg &= ~SUN6I_TFR_CTL_CPHA; -+ -+ if (spi->mode & SPI_LSB_FIRST) -+ reg |= SUN6I_TFR_CTL_FBS; -+ else -+ reg &= ~SUN6I_TFR_CTL_FBS; -+ -+ /* -+ * If it's a TX only transfer, we don't want to fill the RX -+ * FIFO with bogus data -+ */ -+ if (sspi->rx_buf) -+ reg &= ~SUN6I_TFR_CTL_DHB; -+ else -+ reg |= SUN6I_TFR_CTL_DHB; -+ -+ /* We want to control the chip select manually */ -+ reg |= SUN6I_TFR_CTL_CS_MANUAL; -+ -+ sun6i_spi_write(sspi, SUN6I_TFR_CTL_REG, reg); -+ -+ /* Ensure that we have a parent clock fast enough */ -+ mclk_rate = clk_get_rate(sspi->mclk); -+ if (mclk_rate < (2 * spi->max_speed_hz)) { -+ clk_set_rate(sspi->mclk, 2 * spi->max_speed_hz); -+ mclk_rate = clk_get_rate(sspi->mclk); -+ } -+ -+ /* -+ * Setup clock divider. -+ * -+ * We have two choices there. Either we can use the clock -+ * divide rate 1, which is calculated thanks to this formula: -+ * SPI_CLK = MOD_CLK / (2 ^ cdr) -+ * Or we can use CDR2, which is calculated with the formula: -+ * SPI_CLK = MOD_CLK / (2 * (cdr + 1)) -+ * Wether we use the former or the latter is set through the -+ * DRS bit. -+ * -+ * First try CDR2, and if we can't reach the expected -+ * frequency, fall back to CDR1. -+ */ -+ div = mclk_rate / (2 * spi->max_speed_hz); -+ if (div <= (SUN6I_CLK_CTL_CDR2_MASK + 1)) { -+ if (div > 0) -+ div--; -+ -+ reg = SUN6I_CLK_CTL_CDR2(div) | SUN6I_CLK_CTL_DRS; -+ } else { -+ div = ilog2(mclk_rate) - ilog2(spi->max_speed_hz); -+ reg = SUN6I_CLK_CTL_CDR1(div); -+ } -+ -+ sun6i_spi_write(sspi, SUN6I_CLK_CTL_REG, reg); -+ -+ /* Setup the transfer now... */ -+ if (sspi->tx_buf) -+ tx_len = tfr->len; -+ -+ /* Setup the counters */ -+ sun6i_spi_write(sspi, SUN6I_BURST_CNT_REG, SUN6I_BURST_CNT(tfr->len)); -+ sun6i_spi_write(sspi, SUN6I_XMIT_CNT_REG, SUN6I_XMIT_CNT(tx_len)); -+ sun6i_spi_write(sspi, SUN6I_BURST_CTL_CNT_REG, -+ SUN6I_BURST_CTL_CNT_STC(tx_len)); -+ -+ /* Fill the TX FIFO */ -+ sun6i_spi_fill_fifo(sspi, SUN6I_FIFO_DEPTH); -+ -+ /* Enable the interrupts */ -+ sun6i_spi_write(sspi, SUN6I_INT_CTL_REG, SUN6I_INT_CTL_TC); -+ -+ /* Start the transfer */ -+ reg = sun6i_spi_read(sspi, SUN6I_TFR_CTL_REG); -+ sun6i_spi_write(sspi, SUN6I_TFR_CTL_REG, reg | SUN6I_TFR_CTL_XCH); -+ -+ timeout = wait_for_completion_timeout(&sspi->done, -+ msecs_to_jiffies(1000)); -+ if (!timeout) { -+ ret = -ETIMEDOUT; -+ goto out; -+ } -+ -+ sun6i_spi_drain_fifo(sspi, SUN6I_FIFO_DEPTH); -+ -+out: -+ sun6i_spi_write(sspi, SUN6I_INT_CTL_REG, 0); -+ -+ return ret; -+} -+ -+static irqreturn_t sun6i_spi_handler(int irq, void *dev_id) -+{ -+ struct sun6i_spi *sspi = dev_id; -+ u32 status = sun6i_spi_read(sspi, SUN6I_INT_STA_REG); -+ -+ /* Transfer complete */ -+ if (status & SUN6I_INT_CTL_TC) { -+ sun6i_spi_write(sspi, SUN6I_INT_STA_REG, SUN6I_INT_CTL_TC); -+ complete(&sspi->done); -+ return IRQ_HANDLED; -+ } -+ -+ return IRQ_NONE; -+} -+ -+static int sun6i_spi_runtime_resume(struct device *dev) -+{ -+ struct spi_master *master = dev_get_drvdata(dev); -+ struct sun6i_spi *sspi = spi_master_get_devdata(master); -+ int ret; -+ -+ ret = clk_prepare_enable(sspi->hclk); -+ if (ret) { -+ dev_err(dev, "Couldn't enable AHB clock\n"); -+ goto out; -+ } -+ -+ ret = clk_prepare_enable(sspi->mclk); -+ if (ret) { -+ dev_err(dev, "Couldn't enable module clock\n"); -+ goto err; -+ } -+ -+ ret = reset_control_deassert(sspi->rstc); -+ if (ret) { -+ dev_err(dev, "Couldn't deassert the device from reset\n"); -+ goto err2; -+ } -+ -+ sun6i_spi_write(sspi, SUN6I_GBL_CTL_REG, -+ SUN6I_GBL_CTL_BUS_ENABLE | SUN6I_GBL_CTL_MASTER | SUN6I_GBL_CTL_TP); -+ -+ return 0; -+ -+err2: -+ clk_disable_unprepare(sspi->mclk); -+err: -+ clk_disable_unprepare(sspi->hclk); -+out: -+ return ret; -+} -+ -+static int sun6i_spi_runtime_suspend(struct device *dev) -+{ -+ struct spi_master *master = dev_get_drvdata(dev); -+ struct sun6i_spi *sspi = spi_master_get_devdata(master); -+ -+ reset_control_assert(sspi->rstc); -+ clk_disable_unprepare(sspi->mclk); -+ clk_disable_unprepare(sspi->hclk); -+ -+ return 0; -+} -+ -+static int sun6i_spi_probe(struct platform_device *pdev) -+{ -+ struct spi_master *master; -+ struct sun6i_spi *sspi; -+ struct resource *res; -+ int ret = 0, irq; -+ -+ master = spi_alloc_master(&pdev->dev, sizeof(struct sun6i_spi)); -+ if (!master) { -+ dev_err(&pdev->dev, "Unable to allocate SPI Master\n"); -+ return -ENOMEM; -+ } -+ -+ platform_set_drvdata(pdev, master); -+ sspi = spi_master_get_devdata(master); -+ -+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -+ sspi->base_addr = devm_ioremap_resource(&pdev->dev, res); -+ if (IS_ERR(sspi->base_addr)) { -+ ret = PTR_ERR(sspi->base_addr); -+ goto err_free_master; -+ } -+ -+ irq = platform_get_irq(pdev, 0); -+ if (irq < 0) { -+ dev_err(&pdev->dev, "No spi IRQ specified\n"); -+ ret = -ENXIO; -+ goto err_free_master; -+ } -+ -+ ret = devm_request_irq(&pdev->dev, irq, sun6i_spi_handler, -+ 0, "sun6i-spi", sspi); -+ if (ret) { -+ dev_err(&pdev->dev, "Cannot request IRQ\n"); -+ goto err_free_master; -+ } -+ -+ sspi->master = master; -+ master->set_cs = sun6i_spi_set_cs; -+ master->transfer_one = sun6i_spi_transfer_one; -+ master->num_chipselect = 4; -+ master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH | SPI_LSB_FIRST; -+ master->dev.of_node = pdev->dev.of_node; -+ master->auto_runtime_pm = true; -+ -+ sspi->hclk = devm_clk_get(&pdev->dev, "ahb"); -+ if (IS_ERR(sspi->hclk)) { -+ dev_err(&pdev->dev, "Unable to acquire AHB clock\n"); -+ ret = PTR_ERR(sspi->hclk); -+ goto err_free_master; -+ } -+ -+ sspi->mclk = devm_clk_get(&pdev->dev, "mod"); -+ if (IS_ERR(sspi->mclk)) { -+ dev_err(&pdev->dev, "Unable to acquire module clock\n"); -+ ret = PTR_ERR(sspi->mclk); -+ goto err_free_master; -+ } -+ -+ init_completion(&sspi->done); -+ -+ sspi->rstc = devm_reset_control_get(&pdev->dev, NULL); -+ if (IS_ERR(sspi->rstc)) { -+ dev_err(&pdev->dev, "Couldn't get reset controller\n"); -+ ret = PTR_ERR(sspi->rstc); -+ goto err_free_master; -+ } -+ -+ /* -+ * This wake-up/shutdown pattern is to be able to have the -+ * device woken up, even if runtime_pm is disabled -+ */ -+ ret = sun6i_spi_runtime_resume(&pdev->dev); -+ if (ret) { -+ dev_err(&pdev->dev, "Couldn't resume the device\n"); -+ goto err_free_master; -+ } -+ -+ pm_runtime_set_active(&pdev->dev); -+ pm_runtime_enable(&pdev->dev); -+ pm_runtime_idle(&pdev->dev); -+ -+ ret = devm_spi_register_master(&pdev->dev, master); -+ if (ret) { -+ dev_err(&pdev->dev, "cannot register SPI master\n"); -+ goto err_pm_disable; -+ } -+ -+ return 0; -+ -+err_pm_disable: -+ pm_runtime_disable(&pdev->dev); -+ sun6i_spi_runtime_suspend(&pdev->dev); -+err_free_master: -+ spi_master_put(master); -+ return ret; -+} -+ -+static int sun6i_spi_remove(struct platform_device *pdev) -+{ -+ pm_runtime_disable(&pdev->dev); -+ -+ return 0; -+} -+ -+static const struct of_device_id sun6i_spi_match[] = { -+ { .compatible = "allwinner,sun6i-a31-spi", }, -+ {} -+}; -+MODULE_DEVICE_TABLE(of, sun6i_spi_match); -+ -+static const struct dev_pm_ops sun6i_spi_pm_ops = { -+ .runtime_resume = sun6i_spi_runtime_resume, -+ .runtime_suspend = sun6i_spi_runtime_suspend, -+}; -+ -+static struct platform_driver sun6i_spi_driver = { -+ .probe = sun6i_spi_probe, -+ .remove = sun6i_spi_remove, -+ .driver = { -+ .name = "sun6i-spi", -+ .owner = THIS_MODULE, -+ .of_match_table = sun6i_spi_match, -+ .pm = &sun6i_spi_pm_ops, -+ }, -+}; -+module_platform_driver(sun6i_spi_driver); -+ -+MODULE_AUTHOR("Pan Nan <pannan@allwinnertech.com>"); -+MODULE_AUTHOR("Maxime Ripard <maxime.ripard@free-electrons.com>"); -+MODULE_DESCRIPTION("Allwinner A31 SPI controller driver"); -+MODULE_LICENSE("GPL"); diff --git a/target/linux/sunxi/patches-3.14/146-2-spi-add-a10-spi.patch b/target/linux/sunxi/patches-3.14/146-2-spi-add-a10-spi.patch deleted file mode 100644 index 483d216a57..0000000000 --- a/target/linux/sunxi/patches-3.14/146-2-spi-add-a10-spi.patch +++ /dev/null @@ -1,558 +0,0 @@ -From 1ae7667375308c27023d793372d6be1f3b89f5b5 Mon Sep 17 00:00:00 2001 -From: Maxime Ripard <maxime.ripard@free-electrons.com> -Date: Sat, 22 Feb 2014 22:35:53 +0100 -Subject: [PATCH] spi: sunxi: Add Allwinner A10 SPI controller driver - -The older Allwinner SoCs (A10, A13, A10s and A20) all have the same SPI -controller. - -Unfortunately, this SPI controller, even though quite similar, is significantly -different from the recently supported A31 SPI controller (different registers -offset, split/merged registers, etc.). Supporting both controllers in a single -driver would be unreasonable, hence the addition of a new driver. - -Like its more recent counterpart, it supports DMA, but the driver only does PIO -until we have a dmaengine driver for this platform. - -Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com> ---- - .../devicetree/bindings/spi/spi-sun4i.txt | 24 ++ - drivers/spi/Kconfig | 6 + - drivers/spi/Makefile | 1 + - drivers/spi/spi-sun4i.c | 477 +++++++++++++++++++++ - 4 files changed, 508 insertions(+) - create mode 100644 Documentation/devicetree/bindings/spi/spi-sun4i.txt - create mode 100644 drivers/spi/spi-sun4i.c - ---- /dev/null -+++ b/Documentation/devicetree/bindings/spi/spi-sun4i.txt -@@ -0,0 +1,24 @@ -+Allwinner A10 SPI controller -+ -+Required properties: -+- compatible: Should be "allwinner,sun4-a10-spi". -+- reg: Should contain register location and length. -+- interrupts: Should contain interrupt. -+- clocks: phandle to the clocks feeding the SPI controller. Two are -+ needed: -+ - "ahb": the gated AHB parent clock -+ - "mod": the parent module clock -+- clock-names: Must contain the clock names described just above -+ -+Example: -+ -+spi1: spi@01c06000 { -+ compatible = "allwinner,sun4i-a10-spi"; -+ reg = <0x01c06000 0x1000>; -+ interrupts = <11>; -+ clocks = <&ahb_gates 21>, <&spi1_clk>; -+ clock-names = "ahb", "mod"; -+ status = "disabled"; -+ #address-cells = <1>; -+ #size-cells = <0>; -+}; ---- a/drivers/spi/Kconfig -+++ b/drivers/spi/Kconfig -@@ -455,6 +455,12 @@ config SPI_SIRF - help - SPI driver for CSR SiRFprimaII SoCs - -+config SPI_SUN4I -+ tristate "Allwinner A10 SoCs SPI controller" -+ depends on ARCH_SUNXI || COMPILE_TEST -+ help -+ SPI driver for Allwinner sun4i, sun5i and sun7i SoCs -+ - config SPI_SUN6I - tristate "Allwinner A31 SPI controller" - depends on ARCH_SUNXI || COMPILE_TEST ---- a/drivers/spi/Makefile -+++ b/drivers/spi/Makefile -@@ -71,6 +71,7 @@ obj-$(CONFIG_SPI_SH_HSPI) += spi-sh-hsp - obj-$(CONFIG_SPI_SH_MSIOF) += spi-sh-msiof.o - obj-$(CONFIG_SPI_SH_SCI) += spi-sh-sci.o - obj-$(CONFIG_SPI_SIRF) += spi-sirf.o -+obj-$(CONFIG_SPI_SUN4I) += spi-sun4i.o - obj-$(CONFIG_SPI_SUN6I) += spi-sun6i.o - obj-$(CONFIG_SPI_TEGRA114) += spi-tegra114.o - obj-$(CONFIG_SPI_TEGRA20_SFLASH) += spi-tegra20-sflash.o ---- /dev/null -+++ b/drivers/spi/spi-sun4i.c -@@ -0,0 +1,477 @@ -+/* -+ * Copyright (C) 2012 - 2014 Allwinner Tech -+ * Pan Nan <pannan@allwinnertech.com> -+ * -+ * Copyright (C) 2014 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/clk.h> -+#include <linux/delay.h> -+#include <linux/device.h> -+#include <linux/interrupt.h> -+#include <linux/io.h> -+#include <linux/module.h> -+#include <linux/platform_device.h> -+#include <linux/pm_runtime.h> -+#include <linux/workqueue.h> -+ -+#include <linux/spi/spi.h> -+ -+#define SUN4I_FIFO_DEPTH 64 -+ -+#define SUN4I_RXDATA_REG 0x00 -+ -+#define SUN4I_TXDATA_REG 0x04 -+ -+#define SUN4I_CTL_REG 0x08 -+#define SUN4I_CTL_ENABLE BIT(0) -+#define SUN4I_CTL_MASTER BIT(1) -+#define SUN4I_CTL_CPHA BIT(2) -+#define SUN4I_CTL_CPOL BIT(3) -+#define SUN4I_CTL_CS_ACTIVE_LOW BIT(4) -+#define SUN4I_CTL_LMTF BIT(6) -+#define SUN4I_CTL_TF_RST BIT(8) -+#define SUN4I_CTL_RF_RST BIT(9) -+#define SUN4I_CTL_XCH BIT(10) -+#define SUN4I_CTL_CS_MASK 0x3000 -+#define SUN4I_CTL_CS(cs) (((cs) << 12) & SUN4I_CTL_CS_MASK) -+#define SUN4I_CTL_DHB BIT(15) -+#define SUN4I_CTL_CS_MANUAL BIT(16) -+#define SUN4I_CTL_CS_LEVEL BIT(17) -+#define SUN4I_CTL_TP BIT(18) -+ -+#define SUN4I_INT_CTL_REG 0x0c -+#define SUN4I_INT_CTL_TC BIT(16) -+ -+#define SUN4I_INT_STA_REG 0x10 -+ -+#define SUN4I_DMA_CTL_REG 0x14 -+ -+#define SUN4I_WAIT_REG 0x18 -+ -+#define SUN4I_CLK_CTL_REG 0x1c -+#define SUN4I_CLK_CTL_CDR2_MASK 0xff -+#define SUN4I_CLK_CTL_CDR2(div) ((div) & SUN4I_CLK_CTL_CDR2_MASK) -+#define SUN4I_CLK_CTL_CDR1_MASK 0xf -+#define SUN4I_CLK_CTL_CDR1(div) (((div) & SUN4I_CLK_CTL_CDR1_MASK) << 8) -+#define SUN4I_CLK_CTL_DRS BIT(12) -+ -+#define SUN4I_BURST_CNT_REG 0x20 -+#define SUN4I_BURST_CNT(cnt) ((cnt) & 0xffffff) -+ -+#define SUN4I_XMIT_CNT_REG 0x24 -+#define SUN4I_XMIT_CNT(cnt) ((cnt) & 0xffffff) -+ -+#define SUN4I_FIFO_STA_REG 0x28 -+#define SUN4I_FIFO_STA_RF_CNT_MASK 0x7f -+#define SUN4I_FIFO_STA_RF_CNT_BITS 0 -+#define SUN4I_FIFO_STA_TF_CNT_MASK 0x7f -+#define SUN4I_FIFO_STA_TF_CNT_BITS 16 -+ -+struct sun4i_spi { -+ struct spi_master *master; -+ void __iomem *base_addr; -+ struct clk *hclk; -+ struct clk *mclk; -+ -+ struct completion done; -+ -+ const u8 *tx_buf; -+ u8 *rx_buf; -+ int len; -+}; -+ -+static inline u32 sun4i_spi_read(struct sun4i_spi *sspi, u32 reg) -+{ -+ return readl(sspi->base_addr + reg); -+} -+ -+static inline void sun4i_spi_write(struct sun4i_spi *sspi, u32 reg, u32 value) -+{ -+ writel(value, sspi->base_addr + reg); -+} -+ -+static inline void sun4i_spi_drain_fifo(struct sun4i_spi *sspi, int len) -+{ -+ u32 reg, cnt; -+ u8 byte; -+ -+ /* See how much data is available */ -+ reg = sun4i_spi_read(sspi, SUN4I_FIFO_STA_REG); -+ reg &= SUN4I_FIFO_STA_RF_CNT_MASK; -+ cnt = reg >> SUN4I_FIFO_STA_RF_CNT_BITS; -+ -+ if (len > cnt) -+ len = cnt; -+ -+ while (len--) { -+ byte = readb(sspi->base_addr + SUN4I_RXDATA_REG); -+ if (sspi->rx_buf) -+ *sspi->rx_buf++ = byte; -+ } -+} -+ -+static inline void sun4i_spi_fill_fifo(struct sun4i_spi *sspi, int len) -+{ -+ u8 byte; -+ -+ if (len > sspi->len) -+ len = sspi->len; -+ -+ while (len--) { -+ byte = sspi->tx_buf ? *sspi->tx_buf++ : 0; -+ writeb(byte, sspi->base_addr + SUN4I_TXDATA_REG); -+ sspi->len--; -+ } -+} -+ -+static void sun4i_spi_set_cs(struct spi_device *spi, bool enable) -+{ -+ struct sun4i_spi *sspi = spi_master_get_devdata(spi->master); -+ u32 reg; -+ -+ reg = sun4i_spi_read(sspi, SUN4I_CTL_REG); -+ -+ reg &= ~SUN4I_CTL_CS_MASK; -+ reg |= SUN4I_CTL_CS(spi->chip_select); -+ -+ if (enable) -+ reg |= SUN4I_CTL_CS_LEVEL; -+ else -+ reg &= ~SUN4I_CTL_CS_LEVEL; -+ -+ /* -+ * Even though this looks irrelevant since we are supposed to -+ * be controlling the chip select manually, this bit also -+ * controls the levels of the chip select for inactive -+ * devices. -+ * -+ * If we don't set it, the chip select level will go low by -+ * default when the device is idle, which is not really -+ * expected in the common case where the chip select is active -+ * low. -+ */ -+ if (spi->mode & SPI_CS_HIGH) -+ reg &= ~SUN4I_CTL_CS_ACTIVE_LOW; -+ else -+ reg |= SUN4I_CTL_CS_ACTIVE_LOW; -+ -+ sun4i_spi_write(sspi, SUN4I_CTL_REG, reg); -+} -+ -+static int sun4i_spi_transfer_one(struct spi_master *master, -+ struct spi_device *spi, -+ struct spi_transfer *tfr) -+{ -+ struct sun4i_spi *sspi = spi_master_get_devdata(master); -+ unsigned int mclk_rate, div, timeout; -+ unsigned int tx_len = 0; -+ int ret = 0; -+ u32 reg; -+ -+ /* We don't support transfer larger than the FIFO */ -+ if (tfr->len > SUN4I_FIFO_DEPTH) -+ return -EINVAL; -+ -+ reinit_completion(&sspi->done); -+ sspi->tx_buf = tfr->tx_buf; -+ sspi->rx_buf = tfr->rx_buf; -+ sspi->len = tfr->len; -+ -+ /* Clear pending interrupts */ -+ sun4i_spi_write(sspi, SUN4I_INT_STA_REG, ~0); -+ -+ -+ reg = sun4i_spi_read(sspi, SUN4I_CTL_REG); -+ -+ /* Reset FIFOs */ -+ sun4i_spi_write(sspi, SUN4I_CTL_REG, -+ reg | SUN4I_CTL_RF_RST | SUN4I_CTL_TF_RST); -+ -+ /* -+ * Setup the transfer control register: Chip Select, -+ * polarities, etc. -+ */ -+ if (spi->mode & SPI_CPOL) -+ reg |= SUN4I_CTL_CPOL; -+ else -+ reg &= ~SUN4I_CTL_CPOL; -+ -+ if (spi->mode & SPI_CPHA) -+ reg |= SUN4I_CTL_CPHA; -+ else -+ reg &= ~SUN4I_CTL_CPHA; -+ -+ if (spi->mode & SPI_LSB_FIRST) -+ reg |= SUN4I_CTL_LMTF; -+ else -+ reg &= ~SUN4I_CTL_LMTF; -+ -+ -+ /* -+ * If it's a TX only transfer, we don't want to fill the RX -+ * FIFO with bogus data -+ */ -+ if (sspi->rx_buf) -+ reg &= ~SUN4I_CTL_DHB; -+ else -+ reg |= SUN4I_CTL_DHB; -+ -+ /* We want to control the chip select manually */ -+ reg |= SUN4I_CTL_CS_MANUAL; -+ -+ sun4i_spi_write(sspi, SUN4I_CTL_REG, reg); -+ -+ /* Ensure that we have a parent clock fast enough */ -+ mclk_rate = clk_get_rate(sspi->mclk); -+ if (mclk_rate < (2 * spi->max_speed_hz)) { -+ clk_set_rate(sspi->mclk, 2 * spi->max_speed_hz); -+ mclk_rate = clk_get_rate(sspi->mclk); -+ } -+ -+ /* -+ * Setup clock divider. -+ * -+ * We have two choices there. Either we can use the clock -+ * divide rate 1, which is calculated thanks to this formula: -+ * SPI_CLK = MOD_CLK / (2 ^ (cdr + 1)) -+ * Or we can use CDR2, which is calculated with the formula: -+ * SPI_CLK = MOD_CLK / (2 * (cdr + 1)) -+ * Wether we use the former or the latter is set through the -+ * DRS bit. -+ * -+ * First try CDR2, and if we can't reach the expected -+ * frequency, fall back to CDR1. -+ */ -+ div = mclk_rate / (2 * spi->max_speed_hz); -+ if (div <= (SUN4I_CLK_CTL_CDR2_MASK + 1)) { -+ if (div > 0) -+ div--; -+ -+ reg = SUN4I_CLK_CTL_CDR2(div) | SUN4I_CLK_CTL_DRS; -+ } else { -+ div = ilog2(mclk_rate) - ilog2(spi->max_speed_hz); -+ reg = SUN4I_CLK_CTL_CDR1(div); -+ } -+ -+ sun4i_spi_write(sspi, SUN4I_CLK_CTL_REG, reg); -+ -+ /* Setup the transfer now... */ -+ if (sspi->tx_buf) -+ tx_len = tfr->len; -+ -+ /* Setup the counters */ -+ sun4i_spi_write(sspi, SUN4I_BURST_CNT_REG, SUN4I_BURST_CNT(tfr->len)); -+ sun4i_spi_write(sspi, SUN4I_XMIT_CNT_REG, SUN4I_XMIT_CNT(tx_len)); -+ -+ /* Fill the TX FIFO */ -+ sun4i_spi_fill_fifo(sspi, SUN4I_FIFO_DEPTH); -+ -+ /* Enable the interrupts */ -+ sun4i_spi_write(sspi, SUN4I_INT_CTL_REG, SUN4I_INT_CTL_TC); -+ -+ /* Start the transfer */ -+ reg = sun4i_spi_read(sspi, SUN4I_CTL_REG); -+ sun4i_spi_write(sspi, SUN4I_CTL_REG, reg | SUN4I_CTL_XCH); -+ -+ timeout = wait_for_completion_timeout(&sspi->done, -+ msecs_to_jiffies(1000)); -+ if (!timeout) { -+ ret = -ETIMEDOUT; -+ goto out; -+ } -+ -+ sun4i_spi_drain_fifo(sspi, SUN4I_FIFO_DEPTH); -+ -+out: -+ sun4i_spi_write(sspi, SUN4I_INT_CTL_REG, 0); -+ -+ return ret; -+} -+ -+static irqreturn_t sun4i_spi_handler(int irq, void *dev_id) -+{ -+ struct sun4i_spi *sspi = dev_id; -+ u32 status = sun4i_spi_read(sspi, SUN4I_INT_STA_REG); -+ -+ /* Transfer complete */ -+ if (status & SUN4I_INT_CTL_TC) { -+ sun4i_spi_write(sspi, SUN4I_INT_STA_REG, SUN4I_INT_CTL_TC); -+ complete(&sspi->done); -+ return IRQ_HANDLED; -+ } -+ -+ return IRQ_NONE; -+} -+ -+static int sun4i_spi_runtime_resume(struct device *dev) -+{ -+ struct spi_master *master = dev_get_drvdata(dev); -+ struct sun4i_spi *sspi = spi_master_get_devdata(master); -+ int ret; -+ -+ ret = clk_prepare_enable(sspi->hclk); -+ if (ret) { -+ dev_err(dev, "Couldn't enable AHB clock\n"); -+ goto out; -+ } -+ -+ ret = clk_prepare_enable(sspi->mclk); -+ if (ret) { -+ dev_err(dev, "Couldn't enable module clock\n"); -+ goto err; -+ } -+ -+ sun4i_spi_write(sspi, SUN4I_CTL_REG, -+ SUN4I_CTL_ENABLE | SUN4I_CTL_MASTER | SUN4I_CTL_TP); -+ -+ return 0; -+ -+err: -+ clk_disable_unprepare(sspi->hclk); -+out: -+ return ret; -+} -+ -+static int sun4i_spi_runtime_suspend(struct device *dev) -+{ -+ struct spi_master *master = dev_get_drvdata(dev); -+ struct sun4i_spi *sspi = spi_master_get_devdata(master); -+ -+ clk_disable_unprepare(sspi->mclk); -+ clk_disable_unprepare(sspi->hclk); -+ -+ return 0; -+} -+ -+static int sun4i_spi_probe(struct platform_device *pdev) -+{ -+ struct spi_master *master; -+ struct sun4i_spi *sspi; -+ struct resource *res; -+ int ret = 0, irq; -+ -+ master = spi_alloc_master(&pdev->dev, sizeof(struct sun4i_spi)); -+ if (!master) { -+ dev_err(&pdev->dev, "Unable to allocate SPI Master\n"); -+ return -ENOMEM; -+ } -+ -+ platform_set_drvdata(pdev, master); -+ sspi = spi_master_get_devdata(master); -+ -+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -+ sspi->base_addr = devm_ioremap_resource(&pdev->dev, res); -+ if (IS_ERR(sspi->base_addr)) { -+ ret = PTR_ERR(sspi->base_addr); -+ goto err_free_master; -+ } -+ -+ irq = platform_get_irq(pdev, 0); -+ if (irq < 0) { -+ dev_err(&pdev->dev, "No spi IRQ specified\n"); -+ ret = -ENXIO; -+ goto err_free_master; -+ } -+ -+ ret = devm_request_irq(&pdev->dev, irq, sun4i_spi_handler, -+ 0, "sun4i-spi", sspi); -+ if (ret) { -+ dev_err(&pdev->dev, "Cannot request IRQ\n"); -+ goto err_free_master; -+ } -+ -+ sspi->master = master; -+ master->set_cs = sun4i_spi_set_cs; -+ master->transfer_one = sun4i_spi_transfer_one; -+ master->num_chipselect = 4; -+ master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH | SPI_LSB_FIRST; -+ master->dev.of_node = pdev->dev.of_node; -+ master->auto_runtime_pm = true; -+ -+ sspi->hclk = devm_clk_get(&pdev->dev, "ahb"); -+ if (IS_ERR(sspi->hclk)) { -+ dev_err(&pdev->dev, "Unable to acquire AHB clock\n"); -+ ret = PTR_ERR(sspi->hclk); -+ goto err_free_master; -+ } -+ -+ sspi->mclk = devm_clk_get(&pdev->dev, "mod"); -+ if (IS_ERR(sspi->mclk)) { -+ dev_err(&pdev->dev, "Unable to acquire module clock\n"); -+ ret = PTR_ERR(sspi->mclk); -+ goto err_free_master; -+ } -+ -+ init_completion(&sspi->done); -+ -+ /* -+ * This wake-up/shutdown pattern is to be able to have the -+ * device woken up, even if runtime_pm is disabled -+ */ -+ ret = sun4i_spi_runtime_resume(&pdev->dev); -+ if (ret) { -+ dev_err(&pdev->dev, "Couldn't resume the device\n"); -+ goto err_free_master; -+ } -+ -+ pm_runtime_set_active(&pdev->dev); -+ pm_runtime_enable(&pdev->dev); -+ pm_runtime_idle(&pdev->dev); -+ -+ ret = devm_spi_register_master(&pdev->dev, master); -+ if (ret) { -+ dev_err(&pdev->dev, "cannot register SPI master\n"); -+ goto err_pm_disable; -+ } -+ -+ return 0; -+ -+err_pm_disable: -+ pm_runtime_disable(&pdev->dev); -+ sun4i_spi_runtime_suspend(&pdev->dev); -+err_free_master: -+ spi_master_put(master); -+ return ret; -+} -+ -+static int sun4i_spi_remove(struct platform_device *pdev) -+{ -+ pm_runtime_disable(&pdev->dev); -+ -+ return 0; -+} -+ -+static const struct of_device_id sun4i_spi_match[] = { -+ { .compatible = "allwinner,sun4i-a10-spi", }, -+ {} -+}; -+MODULE_DEVICE_TABLE(of, sun4i_spi_match); -+ -+static const struct dev_pm_ops sun4i_spi_pm_ops = { -+ .runtime_resume = sun4i_spi_runtime_resume, -+ .runtime_suspend = sun4i_spi_runtime_suspend, -+}; -+ -+static struct platform_driver sun4i_spi_driver = { -+ .probe = sun4i_spi_probe, -+ .remove = sun4i_spi_remove, -+ .driver = { -+ .name = "sun4i-spi", -+ .owner = THIS_MODULE, -+ .of_match_table = sun4i_spi_match, -+ .pm = &sun4i_spi_pm_ops, -+ }, -+}; -+module_platform_driver(sun4i_spi_driver); -+ -+MODULE_AUTHOR("Pan Nan <pannan@allwinnertech.com>"); -+MODULE_AUTHOR("Maxime Ripard <maxime.ripard@free-electrons.com>"); -+MODULE_DESCRIPTION("Allwinner A1X/A20 SPI controller driver"); -+MODULE_LICENSE("GPL"); diff --git a/target/linux/sunxi/patches-3.14/147-sun6i-enable-spi-in-defconfig.patch b/target/linux/sunxi/patches-3.14/147-sun6i-enable-spi-in-defconfig.patch deleted file mode 100644 index 6f2dbe5375..0000000000 --- a/target/linux/sunxi/patches-3.14/147-sun6i-enable-spi-in-defconfig.patch +++ /dev/null @@ -1,29 +0,0 @@ -From 3aa7ff0de5bddc825406ffff49dc4a38b13ebac3 Mon Sep 17 00:00:00 2001 -From: Maxime Ripard <maxime.ripard@free-electrons.com> -Date: Wed, 5 Feb 2014 14:05:07 +0100 -Subject: [PATCH] ARM: sunxi: Enable A31 SPI and SID in the defconfig - -Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com> ---- - arch/arm/configs/sunxi_defconfig | 3 +++ - 1 file changed, 3 insertions(+) - ---- a/arch/arm/configs/sunxi_defconfig -+++ b/arch/arm/configs/sunxi_defconfig -@@ -24,6 +24,7 @@ CONFIG_IP_PNP_BOOTP=y - # CONFIG_WIRELESS is not set - CONFIG_DEVTMPFS=y - CONFIG_DEVTMPFS_MOUNT=y -+CONFIG_EEPROM_SUNXI_SID=y - CONFIG_NETDEVICES=y - CONFIG_SUN4I_EMAC=y - # CONFIG_NET_CADENCE is not set -@@ -48,6 +49,8 @@ CONFIG_I2C=y - # CONFIG_I2C_COMPAT is not set - CONFIG_I2C_CHARDEV=y - CONFIG_I2C_MV64XXX=y -+CONFIG_SPI=y -+CONFIG_SPI_SUN6I=y - CONFIG_GPIO_SYSFS=y - # CONFIG_HWMON is not set - CONFIG_WATCHDOG=y diff --git a/target/linux/sunxi/patches-3.14/148-dt-sun7i-add-spi-muxing.patch b/target/linux/sunxi/patches-3.14/148-dt-sun7i-add-spi-muxing.patch deleted file mode 100644 index 0c78fa4bc8..0000000000 --- a/target/linux/sunxi/patches-3.14/148-dt-sun7i-add-spi-muxing.patch +++ /dev/null @@ -1,33 +0,0 @@ -From c38fe0f410a59e194ef5e58429658506d853f1b4 Mon Sep 17 00:00:00 2001 -From: Maxime Ripard <maxime.ripard@free-electrons.com> -Date: Sat, 22 Feb 2014 22:35:58 +0100 -Subject: [PATCH] ARM: dt: sun7i: Add SPI muxing options - -Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com> ---- - arch/arm/boot/dts/sun7i-a20.dtsi | 14 ++++++++++++++ - 1 file changed, 14 insertions(+) - ---- a/arch/arm/boot/dts/sun7i-a20.dtsi -+++ b/arch/arm/boot/dts/sun7i-a20.dtsi -@@ -571,6 +571,20 @@ - allwinner,drive = <3>; - allwinner,pull = <0>; - }; -+ -+ spi1_pins_a: spi1@0 { -+ allwinner,pins = "PI16", "PI17", "PI18", "PI19"; -+ allwinner,function = "spi1"; -+ allwinner,drive = <0>; -+ allwinner,pull = <0>; -+ }; -+ -+ spi2_pins_a: spi2@0 { -+ allwinner,pins = "PC19", "PC20", "PC21", "PC22"; -+ allwinner,function = "spi2"; -+ allwinner,drive = <0>; -+ allwinner,pull = <0>; -+ }; - }; - - timer@01c20c00 { diff --git a/target/linux/sunxi/patches-3.14/149-dt-sun7i-add-spi-on-olinuxinom.patch b/target/linux/sunxi/patches-3.14/149-dt-sun7i-add-spi-on-olinuxinom.patch deleted file mode 100644 index cbcfea7c9c..0000000000 --- a/target/linux/sunxi/patches-3.14/149-dt-sun7i-add-spi-on-olinuxinom.patch +++ /dev/null @@ -1,41 +0,0 @@ -From 3f134732aaf4d785532c716f4ef7703d631a510b Mon Sep 17 00:00:00 2001 -From: Maxime Ripard <maxime.ripard@free-electrons.com> -Date: Sat, 22 Feb 2014 22:35:59 +0100 -Subject: [PATCH] ARM: dts: sun7i: Enable the SPI controllers of the - A20-olinuxino-micro - -The A20-Olinuxino-micro has two SPI bus exposed on its UEXT connectors, enable -them. - -Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com> ---- - arch/arm/boot/dts/sun7i-a20-olinuxino-micro.dts | 17 +++++++++++++++++ - 1 file changed, 17 insertions(+) - ---- a/arch/arm/boot/dts/sun7i-a20-olinuxino-micro.dts -+++ b/arch/arm/boot/dts/sun7i-a20-olinuxino-micro.dts -@@ -18,7 +18,24 @@ - model = "Olimex A20-Olinuxino Micro"; - compatible = "olimex,a20-olinuxino-micro", "allwinner,sun7i-a20"; - -+ aliases { -+ spi0 = &spi1; -+ spi1 = &spi2; -+ }; -+ - soc@01c00000 { -+ spi1: spi@01c06000 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&spi1_pins_a>; -+ status = "okay"; -+ }; -+ -+ spi2: spi@01c17000 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&spi2_pins_a>; -+ status = "okay"; -+ }; -+ - pinctrl@01c20800 { - led_pins_olinuxino: led_pins@0 { - allwinner,pins = "PH2"; diff --git a/target/linux/sunxi/patches-3.14/150-dt-sun4i-add-ahci.patch b/target/linux/sunxi/patches-3.14/150-dt-sun4i-add-ahci.patch deleted file mode 100644 index 6c10a98d77..0000000000 --- a/target/linux/sunxi/patches-3.14/150-dt-sun4i-add-ahci.patch +++ /dev/null @@ -1,78 +0,0 @@ -From a9868f7ef1d3828e55de36cfeac2f84a77653a1e 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: sun4i: dt: Add ahci / sata support - -This patch adds sunxi sata support to A10 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> -Signed-off-by: Hans de Goede <hdegoede@redhat.com> ---- - arch/arm/boot/dts/sun4i-a10-a1000.dts | 4 ++++ - arch/arm/boot/dts/sun4i-a10-cubieboard.dts | 10 ++++++++++ - arch/arm/boot/dts/sun4i-a10.dtsi | 8 ++++++++ - 3 files changed, 22 insertions(+) - ---- a/arch/arm/boot/dts/sun4i-a10-a1000.dts -+++ b/arch/arm/boot/dts/sun4i-a10-a1000.dts -@@ -35,6 +35,10 @@ - }; - }; - -+ ahci: sata@01c18000 { -+ status = "okay"; -+ }; -+ - pinctrl@01c20800 { - emac_power_pin_a1000: emac_power_pin@0 { - allwinner,pins = "PH15"; ---- a/arch/arm/boot/dts/sun4i-a10-cubieboard.dts -+++ b/arch/arm/boot/dts/sun4i-a10-cubieboard.dts -@@ -12,6 +12,7 @@ - - /dts-v1/; - /include/ "sun4i-a10.dtsi" -+/include/ "sunxi-common-regulators.dtsi" - - / { - model = "Cubietech Cubieboard"; -@@ -33,6 +34,11 @@ - }; - }; - -+ ahci: sata@01c18000 { -+ target-supply = <®_ahci_5v>; -+ status = "okay"; -+ }; -+ - pinctrl@01c20800 { - led_pins_cubieboard: led_pins@0 { - allwinner,pins = "PH20", "PH21"; -@@ -77,4 +83,8 @@ - linux,default-trigger = "heartbeat"; - }; - }; -+ -+ reg_ahci_5v: ahci-5v { -+ status = "okay"; -+ }; - }; ---- a/arch/arm/boot/dts/sun4i-a10.dtsi -+++ b/arch/arm/boot/dts/sun4i-a10.dtsi -@@ -388,6 +388,14 @@ - #size-cells = <0>; - }; - -+ ahci: sata@01c18000 { -+ compatible = "allwinner,sun4i-a10-ahci"; -+ reg = <0x01c18000 0x1000>; -+ interrupts = <56>; -+ clocks = <&pll6 0>, <&ahb_gates 25>; -+ status = "disabled"; -+ }; -+ - spi3: spi@01c1f000 { - compatible = "allwinner,sun4i-a10-spi"; - reg = <0x01c1f000 0x1000>; diff --git a/target/linux/sunxi/patches-3.14/151-dt-sun7i-add-ahci.patch b/target/linux/sunxi/patches-3.14/151-dt-sun7i-add-ahci.patch deleted file mode 100644 index bd3cc5f55a..0000000000 --- a/target/linux/sunxi/patches-3.14/151-dt-sun7i-add-ahci.patch +++ /dev/null @@ -1,136 +0,0 @@ -From cf454a47b64ef78ff85b097c8cb404120c14e6a5 Mon Sep 17 00:00:00 2001 -From: Hans de Goede <hdegoede@redhat.com> -Date: Fri, 3 Jan 2014 10:27:51 +0100 -Subject: [PATCH] ARM: sun7i: dt: Add ahci / sata support - -This patch adds sunxi sata support to 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> -Signed-off-by: Hans de Goede <hdegoede@redhat.com> ---- - arch/arm/boot/dts/sun7i-a20-cubieboard2.dts | 10 ++++++++++ - arch/arm/boot/dts/sun7i-a20-cubietruck.dts | 19 +++++++++++++++++++ - arch/arm/boot/dts/sun7i-a20-olinuxino-micro.dts | 10 ++++++++++ - arch/arm/boot/dts/sun7i-a20.dtsi | 8 ++++++++ - 4 files changed, 47 insertions(+) - ---- a/arch/arm/boot/dts/sun7i-a20-cubieboard2.dts -+++ b/arch/arm/boot/dts/sun7i-a20-cubieboard2.dts -@@ -13,12 +13,18 @@ - - /dts-v1/; - /include/ "sun7i-a20.dtsi" -+/include/ "sunxi-common-regulators.dtsi" - - / { - model = "Cubietech Cubieboard2"; - compatible = "cubietech,cubieboard2", "allwinner,sun7i-a20"; - - soc@01c00000 { -+ ahci: sata@01c18000 { -+ target-supply = <®_ahci_5v>; -+ status = "okay"; -+ }; -+ - pinctrl@01c20800 { - led_pins_cubieboard2: led_pins@0 { - allwinner,pins = "PH20", "PH21"; -@@ -74,4 +80,8 @@ - gpios = <&pio 7 20 0>; - }; - }; -+ -+ reg_ahci_5v: ahci-5v { -+ status = "okay"; -+ }; - }; ---- a/arch/arm/boot/dts/sun7i-a20-cubietruck.dts -+++ b/arch/arm/boot/dts/sun7i-a20-cubietruck.dts -@@ -13,13 +13,26 @@ - - /dts-v1/; - /include/ "sun7i-a20.dtsi" -+/include/ "sunxi-common-regulators.dtsi" - - / { - model = "Cubietech Cubietruck"; - compatible = "cubietech,cubietruck", "allwinner,sun7i-a20"; - - soc@01c00000 { -+ ahci: sata@01c18000 { -+ target-supply = <®_ahci_5v>; -+ status = "okay"; -+ }; -+ - pinctrl@01c20800 { -+ ahci_pwr_pin_cubietruck: ahci_pwr_pin@1 { -+ allwinner,pins = "PH12"; -+ allwinner,function = "gpio_out"; -+ allwinner,drive = <0>; -+ allwinner,pull = <0>; -+ }; -+ - led_pins_cubietruck: led_pins@0 { - allwinner,pins = "PH7", "PH11", "PH20", "PH21"; - allwinner,function = "gpio_out"; -@@ -104,4 +117,10 @@ - gpios = <&pio 7 7 0>; - }; - }; -+ -+ reg_ahci_5v: ahci-5v { -+ pinctrl-0 = <&ahci_pwr_pin_cubietruck>; -+ gpio = <&pio 7 12 0>; -+ status = "okay"; -+ }; - }; ---- a/arch/arm/boot/dts/sun7i-a20-olinuxino-micro.dts -+++ b/arch/arm/boot/dts/sun7i-a20-olinuxino-micro.dts -@@ -13,6 +13,7 @@ - - /dts-v1/; - /include/ "sun7i-a20.dtsi" -+/include/ "sunxi-common-regulators.dtsi" - - / { - model = "Olimex A20-Olinuxino Micro"; -@@ -36,6 +37,11 @@ - status = "okay"; - }; - -+ ahci: sata@01c18000 { -+ target-supply = <®_ahci_5v>; -+ status = "okay"; -+ }; -+ - pinctrl@01c20800 { - led_pins_olinuxino: led_pins@0 { - allwinner,pins = "PH2"; -@@ -105,4 +111,8 @@ - default-state = "on"; - }; - }; -+ -+ reg_ahci_5v: ahci-5v { -+ status = "okay"; -+ }; - }; ---- a/arch/arm/boot/dts/sun7i-a20.dtsi -+++ b/arch/arm/boot/dts/sun7i-a20.dtsi -@@ -450,6 +450,14 @@ - #size-cells = <0>; - }; - -+ ahci: sata@01c18000 { -+ compatible = "allwinner,sun4i-a10-ahci"; -+ reg = <0x01c18000 0x1000>; -+ interrupts = <0 56 4>; -+ clocks = <&pll6 0>, <&ahb_gates 25>; -+ status = "disabled"; -+ }; -+ - spi3: spi@01c1f000 { - compatible = "allwinner,sun4i-a10-spi"; - reg = <0x01c1f000 0x1000>; diff --git a/target/linux/sunxi/patches-3.14/155-wdt-add-new-compats.patch b/target/linux/sunxi/patches-3.14/155-wdt-add-new-compats.patch deleted file mode 100644 index 75c444d6d0..0000000000 --- a/target/linux/sunxi/patches-3.14/155-wdt-add-new-compats.patch +++ /dev/null @@ -1,46 +0,0 @@ -From ac45fe6b0056d1f92b7c7e5f13514b591a6a9caf Mon Sep 17 00:00:00 2001 -From: Maxime Ripard <maxime.ripard@free-electrons.com> -Date: Sun, 2 Feb 2014 14:55:23 +0100 -Subject: [PATCH] wdt: sunxi: Introduce a new compatible for the A10 and A31 - -For historical reasons, the Allwinner A10 compatibles are not following the -patterns used for this other Allwinner SoCs. - -Introduce a new compatible following the usual pattern, and deprecate the olders. - -Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com> ---- - Documentation/devicetree/bindings/watchdog/sunxi-wdt.txt | 7 ++++--- - drivers/watchdog/sunxi_wdt.c | 1 + - 2 files changed, 5 insertions(+), 3 deletions(-) - ---- a/Documentation/devicetree/bindings/watchdog/sunxi-wdt.txt -+++ b/Documentation/devicetree/bindings/watchdog/sunxi-wdt.txt -@@ -2,13 +2,14 @@ Allwinner SoCs Watchdog timer - - Required properties: - --- compatible : should be "allwinner,<soc-family>-wdt", the currently supported -- SoC families being sun4i and sun6i -+- compatible : should be either "allwinner,sun4i-a10-wdt" or -+ "allwinner,sun6i-a31-wdt" (deprecated: -+ "allwinner,sun4i-wdt", "allwinner,sun6i-wdt") - - reg : Specifies base physical address and size of the registers. - - Example: - - wdt: watchdog@01c20c90 { -- compatible = "allwinner,sun4i-wdt"; -+ compatible = "allwinner,sun4i-a10-wdt"; - reg = <0x01c20c90 0x10>; - }; ---- a/drivers/watchdog/sunxi_wdt.c -+++ b/drivers/watchdog/sunxi_wdt.c -@@ -206,6 +206,7 @@ static void sunxi_wdt_shutdown(struct pl - - static const struct of_device_id sunxi_wdt_dt_ids[] = { - { .compatible = "allwinner,sun4i-wdt" }, -+ { .compatible = "allwinner,sun4i-a10-wdt" }, - { /* sentinel */ } - }; - MODULE_DEVICE_TABLE(of, sunxi_wdt_dt_ids); diff --git a/target/linux/sunxi/patches-3.14/156-dt-sunxi-update-wdt-compats.patch b/target/linux/sunxi/patches-3.14/156-dt-sunxi-update-wdt-compats.patch deleted file mode 100644 index 235550b47d..0000000000 --- a/target/linux/sunxi/patches-3.14/156-dt-sunxi-update-wdt-compats.patch +++ /dev/null @@ -1,73 +0,0 @@ -From f722ea226581a75107ef16b46db1b7b5b999c93a Mon Sep 17 00:00:00 2001 -From: Maxime Ripard <maxime.ripard@free-electrons.com> -Date: Sun, 2 Feb 2014 14:55:25 +0100 -Subject: [PATCH] ARM: sunxi: dt: Update the watchdog compatibles - -The watchdog compatibles were following a different pattern than the one found -in the other devices. Now that the driver supports the right pattern, switch to -it in the DT. - -Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com> ---- - arch/arm/boot/dts/sun4i-a10.dtsi | 2 +- - arch/arm/boot/dts/sun5i-a10s.dtsi | 2 +- - arch/arm/boot/dts/sun5i-a13.dtsi | 2 +- - arch/arm/boot/dts/sun6i-a31.dtsi | 2 +- - arch/arm/boot/dts/sun7i-a20.dtsi | 2 +- - 5 files changed, 5 insertions(+), 5 deletions(-) - ---- a/arch/arm/boot/dts/sun4i-a10.dtsi -+++ b/arch/arm/boot/dts/sun4i-a10.dtsi -@@ -487,7 +487,7 @@ - }; - - wdt: watchdog@01c20c90 { -- compatible = "allwinner,sun4i-wdt"; -+ compatible = "allwinner,sun4i-a10-wdt"; - reg = <0x01c20c90 0x10>; - }; - ---- a/arch/arm/boot/dts/sun5i-a10s.dtsi -+++ b/arch/arm/boot/dts/sun5i-a10s.dtsi -@@ -392,7 +392,7 @@ - }; - - wdt: watchdog@01c20c90 { -- compatible = "allwinner,sun4i-wdt"; -+ compatible = "allwinner,sun4i-a10-wdt"; - reg = <0x01c20c90 0x10>; - }; - ---- a/arch/arm/boot/dts/sun5i-a13.dtsi -+++ b/arch/arm/boot/dts/sun5i-a13.dtsi -@@ -393,7 +393,7 @@ - }; - - wdt: watchdog@01c20c90 { -- compatible = "allwinner,sun4i-wdt"; -+ compatible = "allwinner,sun4i-a10-wdt"; - reg = <0x01c20c90 0x10>; - }; - ---- a/arch/arm/boot/dts/sun6i-a31.dtsi -+++ b/arch/arm/boot/dts/sun6i-a31.dtsi -@@ -289,7 +289,7 @@ - }; - - wdt1: watchdog@01c20ca0 { -- compatible = "allwinner,sun6i-wdt"; -+ compatible = "allwinner,sun6i-a31-wdt"; - reg = <0x01c20ca0 0x20>; - }; - ---- a/arch/arm/boot/dts/sun7i-a20.dtsi -+++ b/arch/arm/boot/dts/sun7i-a20.dtsi -@@ -608,7 +608,7 @@ - }; - - wdt: watchdog@01c20c90 { -- compatible = "allwinner,sun4i-wdt"; -+ compatible = "allwinner,sun4i-a10-wdt"; - reg = <0x01c20c90 0x10>; - }; - diff --git a/target/linux/sunxi/patches-3.14/157-mach-add-new-wdtcompats-to-reboot-code.patch b/target/linux/sunxi/patches-3.14/157-mach-add-new-wdtcompats-to-reboot-code.patch deleted file mode 100644 index 6dcda3aea4..0000000000 --- a/target/linux/sunxi/patches-3.14/157-mach-add-new-wdtcompats-to-reboot-code.patch +++ /dev/null @@ -1,26 +0,0 @@ -From 30e5365b3ad3858bbdf40e8364c1e3260861b4e4 Mon Sep 17 00:00:00 2001 -From: Maxime Ripard <maxime.ripard@free-electrons.com> -Date: Sun, 2 Feb 2014 14:55:24 +0100 -Subject: [PATCH] ARM: sunxi: Add the new watchog compatibles to the reboot - code - -Now that the watchdog driver has new compatibles, we need to support them in -the machine reboot code too. - -Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com> ---- - arch/arm/mach-sunxi/sunxi.c | 2 ++ - 1 file changed, 2 insertions(+) - ---- a/arch/arm/mach-sunxi/sunxi.c -+++ b/arch/arm/mach-sunxi/sunxi.c -@@ -95,7 +95,9 @@ static void sun6i_restart(enum reboot_mo - - static struct of_device_id sunxi_restart_ids[] = { - { .compatible = "allwinner,sun4i-wdt" }, -+ { .compatible = "allwinner,sun4i-a10-wdt" }, - { .compatible = "allwinner,sun6i-wdt" }, -+ { .compatible = "allwinner,sun6i-a31-wdt" }, - { /*sentinel*/ } - }; - diff --git a/target/linux/sunxi/patches-3.14/160-dt-sun4i-add-usb-host-bindings.patch b/target/linux/sunxi/patches-3.14/160-dt-sun4i-add-usb-host-bindings.patch deleted file mode 100644 index f1853dfb42..0000000000 --- a/target/linux/sunxi/patches-3.14/160-dt-sun4i-add-usb-host-bindings.patch +++ /dev/null @@ -1,81 +0,0 @@ -From 991b5f6d2af837b56adfcb3b3a1fe167647b9fdb Mon Sep 17 00:00:00 2001 -From: Roman Byshko <rbyshko@gmail.com> -Date: Wed, 18 Sep 2013 00:30:04 +0200 -Subject: [PATCH] ARM: sun4i: dt: Add USB host bindings - -Add nodes for the usb-phy and ehci- and ohci-usb-host controllers. - -Signed-off-by: Roman Byshko <rbyshko@gmail.com> -Signed-off-by: Hans de Goede <hdegoede@redhat.com> ---- - arch/arm/boot/dts/sun4i-a10.dtsi | 52 ++++++++++++++++++++++++++++++++++++++++ - 1 file changed, 52 insertions(+) - ---- a/arch/arm/boot/dts/sun4i-a10.dtsi -+++ b/arch/arm/boot/dts/sun4i-a10.dtsi -@@ -377,6 +377,38 @@ - #size-cells = <0>; - }; - -+ usbphy: phy@01c13400 { -+ #phy-cells = <1>; -+ compatible = "allwinner,sun4i-a10-usb-phy"; -+ reg = <0x01c13400 0x10 0x01c14800 0x4 0x01c1c800 0x4>; -+ reg-names = "phy_ctrl", "pmu1", "pmu2"; -+ clocks = <&usb_clk 8>; -+ clock-names = "usb_phy"; -+ resets = <&usb_clk 1>, <&usb_clk 2>; -+ reset-names = "usb1_reset", "usb2_reset"; -+ status = "disabled"; -+ }; -+ -+ ehci0: usb@01c14000 { -+ compatible = "allwinner,sun4i-a10-ehci", "generic-ehci"; -+ reg = <0x01c14000 0x100>; -+ interrupts = <39>; -+ clocks = <&ahb_gates 1>; -+ phys = <&usbphy 1>; -+ phy-names = "usb"; -+ status = "disabled"; -+ }; -+ -+ ohci0: usb@01c14400 { -+ compatible = "allwinner,sun4i-a10-ohci", "generic-ohci"; -+ reg = <0x01c14400 0x100>; -+ interrupts = <64>; -+ clocks = <&usb_clk 6>, <&ahb_gates 2>; -+ phys = <&usbphy 1>; -+ phy-names = "usb"; -+ status = "disabled"; -+ }; -+ - spi2: spi@01c17000 { - compatible = "allwinner,sun4i-a10-spi"; - reg = <0x01c17000 0x1000>; -@@ -396,6 +428,26 @@ - status = "disabled"; - }; - -+ ehci1: usb@01c1c000 { -+ compatible = "allwinner,sun4i-a10-ehci", "generic-ehci"; -+ reg = <0x01c1c000 0x100>; -+ interrupts = <40>; -+ clocks = <&ahb_gates 3>; -+ phys = <&usbphy 2>; -+ phy-names = "usb"; -+ status = "disabled"; -+ }; -+ -+ ohci1: usb@01c1c400 { -+ compatible = "allwinner,sun4i-a10-ohci", "generic-ohci"; -+ reg = <0x01c1c400 0x100>; -+ interrupts = <65>; -+ clocks = <&usb_clk 7>, <&ahb_gates 4>; -+ phys = <&usbphy 2>; -+ phy-names = "usb"; -+ status = "disabled"; -+ }; -+ - spi3: spi@01c1f000 { - compatible = "allwinner,sun4i-a10-spi"; - reg = <0x01c1f000 0x1000>; diff --git a/target/linux/sunxi/patches-3.14/161-dt-sun5i-add-usb-host-bindings.patch b/target/linux/sunxi/patches-3.14/161-dt-sun5i-add-usb-host-bindings.patch deleted file mode 100644 index 7b014954f7..0000000000 --- a/target/linux/sunxi/patches-3.14/161-dt-sun5i-add-usb-host-bindings.patch +++ /dev/null @@ -1,55 +0,0 @@ -From 1b5a1b92147936c5aa2acec1683663b4d22e9ae6 Mon Sep 17 00:00:00 2001 -From: Roman Byshko <rbyshko@gmail.com> -Date: Tue, 24 Sep 2013 20:03:40 +0200 -Subject: [PATCH] ARM: sun5i: dt: Add USB host bindings - -Add nodes for the usb-phy and ehci- and ohci-usb-host controllers. - -Signed-off-by: Roman Byshko <rbyshko@gmail.com> -Signed-off-by: Hans de Goede <hdegoede@redhat.com> ---- - arch/arm/boot/dts/sun5i-a10s.dtsi | 32 ++++++++++++++++++++++++++++++++ - arch/arm/boot/dts/sun5i-a13.dtsi | 32 ++++++++++++++++++++++++++++++++ - 2 files changed, 64 insertions(+) - ---- a/arch/arm/boot/dts/sun5i-a13.dtsi -+++ b/arch/arm/boot/dts/sun5i-a13.dtsi -@@ -320,6 +320,38 @@ - #size-cells = <0>; - }; - -+ usbphy: phy@01c13400 { -+ #phy-cells = <1>; -+ compatible = "allwinner,sun5i-a13-usb-phy"; -+ reg = <0x01c13400 0x10 0x01c14800 0x4>; -+ reg-names = "phy_ctrl", "pmu1"; -+ clocks = <&usb_clk 8>; -+ clock-names = "usb_phy"; -+ resets = <&usb_clk 1>; -+ reset-names = "usb1_reset"; -+ status = "disabled"; -+ }; -+ -+ ehci0: usb@01c14000 { -+ compatible = "allwinner,sun5i-a13-ehci", "generic-ehci"; -+ reg = <0x01c14000 0x100>; -+ interrupts = <39>; -+ clocks = <&ahb_gates 1>; -+ phys = <&usbphy 1>; -+ phy-names = "usb"; -+ status = "disabled"; -+ }; -+ -+ ohci0: usb@01c14400 { -+ compatible = "allwinner,sun5i-a13-ohci", "generic-ohci"; -+ reg = <0x01c14400 0x100>; -+ interrupts = <40>; -+ clocks = <&usb_clk 6>, <&ahb_gates 2>; -+ phys = <&usbphy 1>; -+ phy-names = "usb"; -+ status = "disabled"; -+ }; -+ - spi2: spi@01c17000 { - compatible = "allwinner,sun4i-a10-spi"; - reg = <0x01c17000 0x1000>; diff --git a/target/linux/sunxi/patches-3.14/162-dt-sun7i-add-usb-host-bindings.patch b/target/linux/sunxi/patches-3.14/162-dt-sun7i-add-usb-host-bindings.patch deleted file mode 100644 index a8d0f171d9..0000000000 --- a/target/linux/sunxi/patches-3.14/162-dt-sun7i-add-usb-host-bindings.patch +++ /dev/null @@ -1,81 +0,0 @@ -From 008dffff2fa751c988671c4fc0c9a404ea808280 Mon Sep 17 00:00:00 2001 -From: Roman Byshko <rbyshko@gmail.com> -Date: Thu, 19 Sep 2013 21:36:10 +0200 -Subject: [PATCH] ARM: sun7i: dt: Add USB host bindings - -Add nodes for the usb-phy and ehci- and ohci-usb-host controllers. - -Signed-off-by: Roman Byshko <rbyshko@gmail.com> -Signed-off-by: Hans de Goede <hdegoede@redhat.com> ---- - arch/arm/boot/dts/sun7i-a20.dtsi | 52 ++++++++++++++++++++++++++++++++++++++++ - 1 file changed, 52 insertions(+) - ---- a/arch/arm/boot/dts/sun7i-a20.dtsi -+++ b/arch/arm/boot/dts/sun7i-a20.dtsi -@@ -439,6 +439,38 @@ - #size-cells = <0>; - }; - -+ usbphy: phy@01c13400 { -+ #phy-cells = <1>; -+ compatible = "allwinner,sun7i-a20-usb-phy"; -+ reg = <0x01c13400 0x10 0x01c14800 0x4 0x01c1c800 0x4>; -+ reg-names = "phy_ctrl", "pmu1", "pmu2"; -+ clocks = <&usb_clk 8>; -+ clock-names = "usb_phy"; -+ resets = <&usb_clk 1>, <&usb_clk 2>; -+ reset-names = "usb1_reset", "usb2_reset"; -+ status = "disabled"; -+ }; -+ -+ ehci0: usb@01c14000 { -+ compatible = "allwinner,sun7i-a20-ehci", "generic-ehci"; -+ reg = <0x01c14000 0x100>; -+ interrupts = <0 39 4>; -+ clocks = <&ahb_gates 1>; -+ phys = <&usbphy 1>; -+ phy-names = "usb"; -+ status = "disabled"; -+ }; -+ -+ ohci0: usb@01c14400 { -+ compatible = "allwinner,sun7i-a20-ohci", "generic-ohci"; -+ reg = <0x01c14400 0x100>; -+ interrupts = <0 64 4>; -+ clocks = <&usb_clk 6>, <&ahb_gates 2>; -+ phys = <&usbphy 1>; -+ phy-names = "usb"; -+ status = "disabled"; -+ }; -+ - spi2: spi@01c17000 { - compatible = "allwinner,sun4i-a10-spi"; - reg = <0x01c17000 0x1000>; -@@ -458,6 +490,26 @@ - status = "disabled"; - }; - -+ ehci1: usb@01c1c000 { -+ compatible = "allwinner,sun7i-a20-ehci", "generic-ehci"; -+ reg = <0x01c1c000 0x100>; -+ interrupts = <0 40 4>; -+ clocks = <&ahb_gates 3>; -+ phys = <&usbphy 2>; -+ phy-names = "usb"; -+ status = "disabled"; -+ }; -+ -+ ohci1: usb@01c1c400 { -+ compatible = "allwinner,sun7i-a20-ohci", "generic-ohci"; -+ reg = <0x01c1c400 0x100>; -+ interrupts = <0 65 4>; -+ clocks = <&usb_clk 7>, <&ahb_gates 4>; -+ phys = <&usbphy 2>; -+ phy-names = "usb"; -+ status = "disabled"; -+ }; -+ - spi3: spi@01c1f000 { - compatible = "allwinner,sun4i-a10-spi"; - reg = <0x01c1f000 0x1000>; diff --git a/target/linux/sunxi/patches-3.14/163-dt-sun4i-add-usb-host-to-boards.patch b/target/linux/sunxi/patches-3.14/163-dt-sun4i-add-usb-host-to-boards.patch deleted file mode 100644 index ce78cb7512..0000000000 --- a/target/linux/sunxi/patches-3.14/163-dt-sun4i-add-usb-host-to-boards.patch +++ /dev/null @@ -1,240 +0,0 @@ -From f2509ec45a09013e300460a967f694561d169b98 Mon Sep 17 00:00:00 2001 -From: Hans de Goede <hdegoede@redhat.com> -Date: Sat, 11 Jan 2014 04:47:38 +0100 -Subject: [PATCH] ARM: sun4i: dt: Add USB host nodes to hackberry dts - -Add nodes for the usb-phy and ehci- and ohci-usb-host controllers. - -Based on fex file settings, the fex file also contains a mysterious line: -usb_hub_vcc_en_gpio = port:PB09<1><0><default><0> - -Which also clashes with usbc0, which has: -usb_drv_vbus_gpio = port:PB09<1><0><default><0> - -So if usb does not work properly we need someone with a hackberry to look -closer into this. - -Signed-off-by: Hans de Goede <hdegoede@redhat.com> ---- - arch/arm/boot/dts/sun4i-a10-hackberry.dts | 40 +++++++++++++++++++++++++++++++ - 1 file changed, 40 insertions(+) - ---- a/arch/arm/boot/dts/sun4i-a10-hackberry.dts -+++ b/arch/arm/boot/dts/sun4i-a10-hackberry.dts -@@ -13,6 +13,7 @@ - - /dts-v1/; - /include/ "sun4i-a10.dtsi" -+/include/ "sunxi-common-regulators.dtsi" - - / { - model = "Miniand Hackberry"; -@@ -35,6 +36,28 @@ - }; - }; - -+ usbphy: phy@01c13400 { -+ usb1_vbus-supply = <®_usb1_vbus>; -+ usb2_vbus-supply = <®_usb2_vbus>; -+ status = "okay"; -+ }; -+ -+ ehci0: usb@01c14000 { -+ status = "okay"; -+ }; -+ -+ ohci0: usb@01c14400 { -+ status = "okay"; -+ }; -+ -+ ehci1: usb@01c1c000 { -+ status = "okay"; -+ }; -+ -+ ohci1: usb@01c1c400 { -+ status = "okay"; -+ }; -+ - pio: pinctrl@01c20800 { - pinctrl-names = "default"; - pinctrl-0 = <&hackberry_hogs>; -@@ -45,6 +68,13 @@ - allwinner,drive = <0>; - allwinner,pull = <0>; - }; -+ -+ usb2_vbus_pin_hackberry: usb2_vbus_pin@0 { -+ allwinner,pins = "PH12"; -+ allwinner,function = "gpio_out"; -+ allwinner,drive = <0>; -+ allwinner,pull = <0>; -+ }; - }; - - uart0: serial@01c28000 { -@@ -66,4 +96,14 @@ - gpio = <&pio 7 19 0>; - }; - }; -+ -+ reg_usb1_vbus: usb1-vbus { -+ status = "okay"; -+ }; -+ -+ reg_usb2_vbus: usb2-vbus { -+ pinctrl-0 = <&usb2_vbus_pin_hackberry>; -+ gpio = <&pio 7 12 0>; -+ status = "okay"; -+ }; - }; ---- a/arch/arm/boot/dts/sun4i-a10-mini-xplus.dts -+++ b/arch/arm/boot/dts/sun4i-a10-mini-xplus.dts -@@ -13,16 +13,47 @@ - - /dts-v1/; - /include/ "sun4i-a10.dtsi" -+/include/ "sunxi-common-regulators.dtsi" - - / { - model = "PineRiver Mini X-Plus"; - compatible = "pineriver,mini-xplus", "allwinner,sun4i-a10"; - - soc@01c00000 { -+ usbphy: phy@01c13400 { -+ usb1_vbus-supply = <®_usb1_vbus>; -+ usb2_vbus-supply = <®_usb2_vbus>; -+ status = "okay"; -+ }; -+ -+ ehci0: usb@01c14000 { -+ status = "okay"; -+ }; -+ -+ ohci0: usb@01c14400 { -+ status = "okay"; -+ }; -+ -+ ehci1: usb@01c1c000 { -+ status = "okay"; -+ }; -+ -+ ohci1: usb@01c1c400 { -+ status = "okay"; -+ }; -+ - uart0: serial@01c28000 { - pinctrl-names = "default"; - pinctrl-0 = <&uart0_pins_a>; - status = "okay"; - }; - }; -+ -+ reg_usb1_vbus: usb1-vbus { -+ status = "okay"; -+ }; -+ -+ reg_usb2_vbus: usb2-vbus { -+ status = "okay"; -+ }; - }; ---- a/arch/arm/boot/dts/sun4i-a10-pcduino.dts -+++ b/arch/arm/boot/dts/sun4i-a10-pcduino.dts -@@ -12,6 +12,7 @@ - - /dts-v1/; - /include/ "sun4i-a10.dtsi" -+/include/ "sunxi-common-regulators.dtsi" - - / { - model = "LinkSprite pcDuino"; -@@ -33,6 +34,28 @@ - }; - }; - -+ usbphy: phy@01c13400 { -+ usb1_vbus-supply = <®_usb1_vbus>; -+ usb2_vbus-supply = <®_usb2_vbus>; -+ status = "okay"; -+ }; -+ -+ ehci0: usb@01c14000 { -+ status = "okay"; -+ }; -+ -+ ohci0: usb@01c14400 { -+ status = "okay"; -+ }; -+ -+ ehci1: usb@01c1c000 { -+ status = "okay"; -+ }; -+ -+ ohci1: usb@01c1c400 { -+ status = "okay"; -+ }; -+ - uart0: serial@01c28000 { - pinctrl-names = "default"; - pinctrl-0 = <&uart0_pins_a>; -@@ -45,4 +68,12 @@ - status = "okay"; - }; - }; -+ -+ reg_usb1_vbus: usb1-vbus { -+ status = "okay"; -+ }; -+ -+ reg_usb2_vbus: usb2-vbus { -+ status = "okay"; -+ }; - }; ---- a/arch/arm/boot/dts/sun4i-a10-cubieboard.dts -+++ b/arch/arm/boot/dts/sun4i-a10-cubieboard.dts -@@ -34,11 +34,33 @@ - }; - }; - -+ usbphy: phy@01c13400 { -+ usb1_vbus-supply = <®_usb1_vbus>; -+ usb2_vbus-supply = <®_usb2_vbus>; -+ status = "okay"; -+ }; -+ -+ ehci0: usb@01c14000 { -+ status = "okay"; -+ }; -+ -+ ohci0: usb@01c14400 { -+ status = "okay"; -+ }; -+ - ahci: sata@01c18000 { - target-supply = <®_ahci_5v>; - status = "okay"; - }; - -+ ehci1: usb@01c1c000 { -+ status = "okay"; -+ }; -+ -+ ohci1: usb@01c1c400 { -+ status = "okay"; -+ }; -+ - pinctrl@01c20800 { - led_pins_cubieboard: led_pins@0 { - allwinner,pins = "PH20", "PH21"; -@@ -87,4 +109,12 @@ - reg_ahci_5v: ahci-5v { - status = "okay"; - }; -+ -+ reg_usb1_vbus: usb1-vbus { -+ status = "okay"; -+ }; -+ -+ reg_usb2_vbus: usb2-vbus { -+ status = "okay"; -+ }; - }; diff --git a/target/linux/sunxi/patches-3.14/164-dt-sun5i-add-usb-host-to-boards.patch b/target/linux/sunxi/patches-3.14/164-dt-sun5i-add-usb-host-to-boards.patch deleted file mode 100644 index 9776f5ba5c..0000000000 --- a/target/linux/sunxi/patches-3.14/164-dt-sun5i-add-usb-host-to-boards.patch +++ /dev/null @@ -1,121 +0,0 @@ -From 9f193366e6094f6e2087c4767e7e413a395bf0d2 Mon Sep 17 00:00:00 2001 -From: Roman Byshko <rbyshko@gmail.com> -Date: Tue, 24 Sep 2013 20:07:53 +0200 -Subject: [PATCH] ARM: sun5i: dt: Add USB host nodes to A13-Olinuxino - -Add nodes for the usb-phy and ehci- and ohci-usb-host controllers. - -Signed-off-by: Roman Byshko <rbyshko@gmail.com> -Signed-off-by: Hans de Goede <hdegoede@redhat.com> ---- - arch/arm/boot/dts/sun5i-a13-olinuxino.dts | 27 +++++++++++++++++++++++++++ - 1 file changed, 27 insertions(+) - ---- a/arch/arm/boot/dts/sun5i-a13-olinuxino.dts -+++ b/arch/arm/boot/dts/sun5i-a13-olinuxino.dts -@@ -13,12 +13,26 @@ - - /dts-v1/; - /include/ "sun5i-a13.dtsi" -+/include/ "sunxi-common-regulators.dtsi" - - / { - model = "Olimex A13-Olinuxino"; - compatible = "olimex,a13-olinuxino", "allwinner,sun5i-a13"; - - soc@01c00000 { -+ usbphy: phy@01c13400 { -+ usb1_vbus-supply = <®_usb1_vbus>; -+ status = "okay"; -+ }; -+ -+ ehci0: usb@01c14000 { -+ status = "okay"; -+ }; -+ -+ ohci0: usb@01c14400 { -+ status = "okay"; -+ }; -+ - pinctrl@01c20800 { - led_pins_olinuxino: led_pins@0 { - allwinner,pins = "PG9"; -@@ -26,6 +40,13 @@ - allwinner,drive = <1>; - allwinner,pull = <0>; - }; -+ -+ usb1_vbus_pin_olinuxino: usb1_vbus_pin@0 { -+ allwinner,pins = "PG11"; -+ allwinner,function = "gpio_out"; -+ allwinner,drive = <0>; -+ allwinner,pull = <0>; -+ }; - }; - - uart1: serial@01c28400 { -@@ -63,4 +84,10 @@ - default-state = "on"; - }; - }; -+ -+ reg_usb1_vbus: usb1-vbus { -+ pinctrl-0 = <&usb1_vbus_pin_olinuxino>; -+ gpio = <&pio 6 11 0>; -+ status = "okay"; -+ }; - }; ---- a/arch/arm/boot/dts/sun5i-a13-olinuxino-micro.dts -+++ b/arch/arm/boot/dts/sun5i-a13-olinuxino-micro.dts -@@ -14,12 +14,26 @@ - - /dts-v1/; - /include/ "sun5i-a13.dtsi" -+/include/ "sunxi-common-regulators.dtsi" - - / { - model = "Olimex A13-Olinuxino Micro"; - compatible = "olimex,a13-olinuxino-micro", "allwinner,sun5i-a13"; - - soc@01c00000 { -+ usbphy: phy@01c13400 { -+ usb1_vbus-supply = <®_usb1_vbus>; -+ status = "okay"; -+ }; -+ -+ ehci0: usb@01c14000 { -+ status = "okay"; -+ }; -+ -+ ohci0: usb@01c14400 { -+ status = "okay"; -+ }; -+ - pinctrl@01c20800 { - led_pins_olinuxinom: led_pins@0 { - allwinner,pins = "PG9"; -@@ -27,6 +41,13 @@ - allwinner,drive = <1>; - allwinner,pull = <0>; - }; -+ -+ usb1_vbus_pin_olinuxinom: usb1_vbus_pin@0 { -+ allwinner,pins = "PG11"; -+ allwinner,function = "gpio_out"; -+ allwinner,drive = <0>; -+ allwinner,pull = <0>; -+ }; - }; - - uart1: serial@01c28400 { -@@ -65,4 +86,10 @@ - default-state = "on"; - }; - }; -+ -+ reg_usb1_vbus: usb1-vbus { -+ pinctrl-0 = <&usb1_vbus_pin_olinuxinom>; -+ gpio = <&pio 6 11 0>; -+ status = "okay"; -+ }; - }; diff --git a/target/linux/sunxi/patches-3.14/165-dt-sun7i-add-usb-host-to-boards.patch b/target/linux/sunxi/patches-3.14/165-dt-sun7i-add-usb-host-to-boards.patch deleted file mode 100644 index 6bfb1b5c13..0000000000 --- a/target/linux/sunxi/patches-3.14/165-dt-sun7i-add-usb-host-to-boards.patch +++ /dev/null @@ -1,161 +0,0 @@ -From 56de1b69bf6782338193e373cee06fff252b31da Mon Sep 17 00:00:00 2001 -From: Hans de Goede <hdegoede@redhat.com> -Date: Tue, 17 Dec 2013 23:04:57 +0100 -Subject: [PATCH] ARM: sun7i: dt: Add USB host nodes to cubietruck dts - -Add nodes for the usb-phy and ehci- and ohci-usb-host controllers. - -Signed-off-by: Hans de Goede <hdegoede@redhat.com> ---- - arch/arm/boot/dts/sun7i-a20-cubietruck.dts | 30 ++++++++++++++++++++++++++++++ - 1 file changed, 30 insertions(+) - ---- a/arch/arm/boot/dts/sun7i-a20-cubietruck.dts -+++ b/arch/arm/boot/dts/sun7i-a20-cubietruck.dts -@@ -20,11 +20,33 @@ - compatible = "cubietech,cubietruck", "allwinner,sun7i-a20"; - - soc@01c00000 { -+ usbphy: phy@01c13400 { -+ usb1_vbus-supply = <®_usb1_vbus>; -+ usb2_vbus-supply = <®_usb2_vbus>; -+ status = "okay"; -+ }; -+ -+ ehci0: usb@01c14000 { -+ status = "okay"; -+ }; -+ -+ ohci0: usb@01c14400 { -+ status = "okay"; -+ }; -+ - ahci: sata@01c18000 { - target-supply = <®_ahci_5v>; - status = "okay"; - }; - -+ ehci1: usb@01c1c000 { -+ status = "okay"; -+ }; -+ -+ ohci1: usb@01c1c400 { -+ status = "okay"; -+ }; -+ - pinctrl@01c20800 { - ahci_pwr_pin_cubietruck: ahci_pwr_pin@1 { - allwinner,pins = "PH12"; -@@ -123,4 +145,12 @@ - gpio = <&pio 7 12 0>; - status = "okay"; - }; -+ -+ reg_usb1_vbus: usb1-vbus { -+ status = "okay"; -+ }; -+ -+ reg_usb2_vbus: usb2-vbus { -+ status = "okay"; -+ }; - }; ---- a/arch/arm/boot/dts/sun7i-a20-cubieboard2.dts -+++ b/arch/arm/boot/dts/sun7i-a20-cubieboard2.dts -@@ -20,11 +20,33 @@ - compatible = "cubietech,cubieboard2", "allwinner,sun7i-a20"; - - soc@01c00000 { -+ usbphy: phy@01c13400 { -+ usb1_vbus-supply = <®_usb1_vbus>; -+ usb2_vbus-supply = <®_usb2_vbus>; -+ status = "okay"; -+ }; -+ -+ ehci0: usb@01c14000 { -+ status = "okay"; -+ }; -+ -+ ohci0: usb@01c14400 { -+ status = "okay"; -+ }; -+ - ahci: sata@01c18000 { - target-supply = <®_ahci_5v>; - status = "okay"; - }; - -+ ehci1: usb@01c1c000 { -+ status = "okay"; -+ }; -+ -+ ohci1: usb@01c1c400 { -+ status = "okay"; -+ }; -+ - pinctrl@01c20800 { - led_pins_cubieboard2: led_pins@0 { - allwinner,pins = "PH20", "PH21"; -@@ -84,4 +106,12 @@ - reg_ahci_5v: ahci-5v { - status = "okay"; - }; -+ -+ reg_usb1_vbus: usb1-vbus { -+ status = "okay"; -+ }; -+ -+ reg_usb2_vbus: usb2-vbus { -+ status = "okay"; -+ }; - }; ---- a/arch/arm/boot/dts/sun7i-a20-olinuxino-micro.dts -+++ b/arch/arm/boot/dts/sun7i-a20-olinuxino-micro.dts -@@ -31,6 +31,20 @@ - status = "okay"; - }; - -+ usbphy: phy@01c13400 { -+ usb1_vbus-supply = <®_usb1_vbus>; -+ usb2_vbus-supply = <®_usb2_vbus>; -+ status = "okay"; -+ }; -+ -+ ehci0: usb@01c14000 { -+ status = "okay"; -+ }; -+ -+ ohci0: usb@01c14400 { -+ status = "okay"; -+ }; -+ - spi2: spi@01c17000 { - pinctrl-names = "default"; - pinctrl-0 = <&spi2_pins_a>; -@@ -42,6 +56,14 @@ - status = "okay"; - }; - -+ ehci1: usb@01c1c000 { -+ status = "okay"; -+ }; -+ -+ ohci1: usb@01c1c400 { -+ status = "okay"; -+ }; -+ - pinctrl@01c20800 { - led_pins_olinuxino: led_pins@0 { - allwinner,pins = "PH2"; -@@ -115,4 +137,12 @@ - reg_ahci_5v: ahci-5v { - status = "okay"; - }; -+ -+ reg_usb1_vbus: usb1-vbus { -+ status = "okay"; -+ }; -+ -+ reg_usb2_vbus: usb2-vbus { -+ status = "okay"; -+ }; - }; diff --git a/target/linux/sunxi/patches-3.14/170-input-add-sun4i-ts-driver.patch b/target/linux/sunxi/patches-3.14/170-input-add-sun4i-ts-driver.patch deleted file mode 100644 index bde35b1f12..0000000000 --- a/target/linux/sunxi/patches-3.14/170-input-add-sun4i-ts-driver.patch +++ /dev/null @@ -1,341 +0,0 @@ -From afbd58e1b1219cbcbe2cc07273fc51f658891e9b Mon Sep 17 00:00:00 2001 -From: Hans de Goede <hdegoede@redhat.com> -Date: Mon, 23 Dec 2013 16:21:02 +0100 -Subject: [PATCH] input: Add new sun4i-ts driver for Allwinner sunxi SoC's rtp - controller - -Note the sun4i-ts controller is capable of detecting a second touch, but when -a second touch is present then the accuracy becomes so bad the reported touch -location is not useable. - -The original android driver contains some complicated heuristics using the -aprox. distance between the 2 touches to see if the user is making a pinch -open / close movement, and then reports emulated multi-touch events around -the last touch coordinate (as the dual-touch coordinates are worthless). - -These kinds of heuristics are just asking for trouble (and don't belong -in the kernel). So this driver offers straight forward, reliable single -touch functionality only. - -Signed-off-by: Hans de Goede <hdegoede@redhat.com> ---- - .../bindings/input/touchscreen/sun4i.txt | 15 ++ - drivers/input/touchscreen/Kconfig | 10 + - drivers/input/touchscreen/Makefile | 1 + - drivers/input/touchscreen/sun4i-ts.c | 262 +++++++++++++++++++++ - 4 files changed, 288 insertions(+) - create mode 100644 Documentation/devicetree/bindings/input/touchscreen/sun4i.txt - create mode 100644 drivers/input/touchscreen/sun4i-ts.c - ---- /dev/null -+++ b/Documentation/devicetree/bindings/input/touchscreen/sun4i.txt -@@ -0,0 +1,15 @@ -+sun4i resistive touchscreen controller -+-------------------------------------- -+ -+Required properties: -+ - compatible: "allwinner,sun4i-ts" -+ - reg: mmio address range of the chip -+ - interrupts: interrupt to which the chip is connected -+ -+Example: -+ -+ rtp: rtp@01c25000 { -+ compatible = "allwinner,sun4i-ts"; -+ reg = <0x01c25000 0x100>; -+ interrupts = <29>; -+ }; ---- a/drivers/input/touchscreen/Kconfig -+++ b/drivers/input/touchscreen/Kconfig -@@ -906,6 +906,16 @@ config TOUCHSCREEN_STMPE - To compile this driver as a module, choose M here: the - module will be called stmpe-ts. - -+config TOUCHSCREEN_SUN4I -+ tristate "Allwinner sun4i resistive touchscreen controller support" -+ depends on ARCH_SUNXI -+ help -+ This selects support for the resistive touchscreen controller -+ found on Allwinner sunxi SoCs. -+ -+ To compile this driver as a module, choose M here: the -+ module will be called sun4i-ts. -+ - config TOUCHSCREEN_SUR40 - tristate "Samsung SUR40 (Surface 2.0/PixelSense) touchscreen" - depends on USB ---- a/drivers/input/touchscreen/Makefile -+++ b/drivers/input/touchscreen/Makefile -@@ -54,6 +54,7 @@ obj-$(CONFIG_TOUCHSCREEN_PIXCIR) += pixc - obj-$(CONFIG_TOUCHSCREEN_S3C2410) += s3c2410_ts.o - obj-$(CONFIG_TOUCHSCREEN_ST1232) += st1232.o - obj-$(CONFIG_TOUCHSCREEN_STMPE) += stmpe-ts.o -+obj-$(CONFIG_TOUCHSCREEN_SUN4I) += sun4i-ts.o - obj-$(CONFIG_TOUCHSCREEN_SUR40) += sur40.o - obj-$(CONFIG_TOUCHSCREEN_TI_AM335X_TSC) += ti_am335x_tsc.o - obj-$(CONFIG_TOUCHSCREEN_TNETV107X) += tnetv107x-ts.o ---- /dev/null -+++ b/drivers/input/touchscreen/sun4i-ts.c -@@ -0,0 +1,262 @@ -+/* -+ * Allwinner sunxi resistive touchscreen controller driver -+ * -+ * Copyright (C) 2013 - 2014 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. -+ */ -+ -+/* -+ * The sun4i-ts controller is capable of detecting a second touch, but when a -+ * second touch is present then the accuracy becomes so bad the reported touch -+ * location is not useable. -+ * -+ * The original android driver contains some complicated heuristics using the -+ * aprox. distance between the 2 touches to see if the user is making a pinch -+ * open / close movement, and then reports emulated multi-touch events around -+ * the last touch coordinate (as the dual-touch coordinates are worthless). -+ * -+ * These kinds of heuristics are just asking for trouble (and don't belong -+ * in the kernel). So this driver offers straight forward, reliable single -+ * touch functionality only. -+ */ -+ -+#include <linux/err.h> -+#include <linux/init.h> -+#include <linux/input.h> -+#include <linux/interrupt.h> -+#include <linux/io.h> -+#include <linux/module.h> -+#include <linux/of_platform.h> -+#include <linux/platform_device.h> -+#include <linux/slab.h> -+ -+#define TP_CTRL0 0x00 -+#define TP_CTRL1 0x04 -+#define TP_CTRL2 0x08 -+#define TP_CTRL3 0x0c -+#define TP_INT_FIFOC 0x10 -+#define TP_INT_FIFOS 0x14 -+#define TP_TPR 0x18 -+#define TP_CDAT 0x1c -+#define TEMP_DATA 0x20 -+#define TP_DATA 0x24 -+ -+/* TP_CTRL0 bits */ -+#define ADC_FIRST_DLY(x) ((x) << 24) /* 8 bits */ -+#define ADC_FIRST_DLY_MODE(x) ((x) << 23) -+#define ADC_CLK_SEL(x) ((x) << 22) -+#define ADC_CLK_DIV(x) ((x) << 20) /* 3 bits */ -+#define FS_DIV(x) ((x) << 16) /* 4 bits */ -+#define T_ACQ(x) ((x) << 0) /* 16 bits */ -+ -+/* TP_CTRL1 bits */ -+#define STYLUS_UP_DEBOUN(x) ((x) << 12) /* 8 bits */ -+#define STYLUS_UP_DEBOUN_EN(x) ((x) << 9) -+#define TOUCH_PAN_CALI_EN(x) ((x) << 6) -+#define TP_DUAL_EN(x) ((x) << 5) -+#define TP_MODE_EN(x) ((x) << 4) -+#define TP_ADC_SELECT(x) ((x) << 3) -+#define ADC_CHAN_SELECT(x) ((x) << 0) /* 3 bits */ -+ -+/* TP_CTRL2 bits */ -+#define TP_SENSITIVE_ADJUST(x) ((x) << 28) /* 4 bits */ -+#define TP_MODE_SELECT(x) ((x) << 26) /* 2 bits */ -+#define PRE_MEA_EN(x) ((x) << 24) -+#define PRE_MEA_THRE_CNT(x) ((x) << 0) /* 24 bits */ -+ -+/* TP_CTRL3 bits */ -+#define FILTER_EN(x) ((x) << 2) -+#define FILTER_TYPE(x) ((x) << 0) /* 2 bits */ -+ -+/* TP_INT_FIFOC irq and fifo mask / control bits */ -+#define TEMP_IRQ_EN(x) ((x) << 18) -+#define OVERRUN_IRQ_EN(x) ((x) << 17) -+#define DATA_IRQ_EN(x) ((x) << 16) -+#define TP_DATA_XY_CHANGE(x) ((x) << 13) -+#define FIFO_TRIG(x) ((x) << 8) /* 5 bits */ -+#define DATA_DRQ_EN(x) ((x) << 7) -+#define FIFO_FLUSH(x) ((x) << 4) -+#define TP_UP_IRQ_EN(x) ((x) << 1) -+#define TP_DOWN_IRQ_EN(x) ((x) << 0) -+ -+/* TP_INT_FIFOS irq and fifo status bits */ -+#define TEMP_DATA_PENDING BIT(18) -+#define FIFO_OVERRUN_PENDING BIT(17) -+#define FIFO_DATA_PENDING BIT(16) -+#define TP_IDLE_FLG BIT(2) -+#define TP_UP_PENDING BIT(1) -+#define TP_DOWN_PENDING BIT(0) -+ -+/* TP_TPR bits */ -+#define TEMP_ENABLE(x) ((x) << 16) -+#define TEMP_PERIOD(x) ((x) << 0) /* t = x * 256 * 16 / clkin */ -+ -+struct sun4i_ts_data { -+ struct device *dev; -+ struct input_dev *input; -+ void __iomem *base; -+ unsigned int irq; -+ bool ignore_fifo_data; -+}; -+ -+static irqreturn_t sun4i_ts_irq(int irq, void *dev_id) -+{ -+ struct sun4i_ts_data *ts = dev_id; -+ u32 reg_val, x, y; -+ -+ reg_val = readl(ts->base + TP_INT_FIFOS); -+ -+ if (reg_val & FIFO_DATA_PENDING) { -+ x = readl(ts->base + TP_DATA); -+ y = readl(ts->base + TP_DATA); -+ /* The 1st location reported after an up event is unreliable */ -+ if (!ts->ignore_fifo_data) { -+ input_report_abs(ts->input, ABS_X, x); -+ input_report_abs(ts->input, ABS_Y, y); -+ /* -+ * The hardware has a separate down status bit, but -+ * that gets set before we get the first location, -+ * resulting in reporting a click on the old location. -+ */ -+ input_report_key(ts->input, BTN_TOUCH, 1); -+ input_sync(ts->input); -+ } else { -+ ts->ignore_fifo_data = false; -+ } -+ } -+ -+ if (reg_val & TP_UP_PENDING) { -+ ts->ignore_fifo_data = true; -+ input_report_key(ts->input, BTN_TOUCH, 0); -+ input_sync(ts->input); -+ } -+ -+ writel(reg_val, ts->base + TP_INT_FIFOS); -+ -+ return IRQ_HANDLED; -+} -+ -+static int sun4i_ts_open(struct input_dev *dev) -+{ -+ struct sun4i_ts_data *ts = input_get_drvdata(dev); -+ -+ /* Flush, set trig level to 1, enable data and up irqs */ -+ writel(DATA_IRQ_EN(1) | FIFO_TRIG(1) | FIFO_FLUSH(1) | TP_UP_IRQ_EN(1), -+ ts->base + TP_INT_FIFOC); -+ -+ return 0; -+} -+ -+static void sun4i_ts_close(struct input_dev *dev) -+{ -+ struct sun4i_ts_data *ts = input_get_drvdata(dev); -+ -+ /* Deactivate all IRQs */ -+ writel(0, ts->base + TP_INT_FIFOC); -+} -+ -+static int sun4i_ts_probe(struct platform_device *pdev) -+{ -+ struct sun4i_ts_data *ts; -+ struct device *dev = &pdev->dev; -+ int ret; -+ -+ ts = devm_kzalloc(dev, sizeof(struct sun4i_ts_data), GFP_KERNEL); -+ if (!ts) -+ return -ENOMEM; -+ -+ ts->dev = dev; -+ ts->ignore_fifo_data = true; -+ -+ ts->input = devm_input_allocate_device(dev); -+ if (!ts->input) -+ return -ENOMEM; -+ -+ ts->input->name = pdev->name; -+ ts->input->phys = "sun4i_ts/input0"; -+ ts->input->open = sun4i_ts_open; -+ ts->input->close = sun4i_ts_close; -+ ts->input->id.bustype = BUS_HOST; -+ ts->input->id.vendor = 0x0001; -+ ts->input->id.product = 0x0001; -+ ts->input->id.version = 0x0100; -+ ts->input->evbit[0] = BIT(EV_SYN) | BIT(EV_KEY) | BIT(EV_ABS); -+ set_bit(BTN_TOUCH, ts->input->keybit); -+ input_set_abs_params(ts->input, ABS_X, 0, 4095, 0, 0); -+ input_set_abs_params(ts->input, ABS_Y, 0, 4095, 0, 0); -+ input_set_drvdata(ts->input, ts); -+ -+ ts->base = devm_ioremap_resource(dev, -+ platform_get_resource(pdev, IORESOURCE_MEM, 0)); -+ if (IS_ERR(ts->base)) -+ return PTR_ERR(ts->base); -+ -+ ts->irq = platform_get_irq(pdev, 0); -+ ret = devm_request_irq(dev, ts->irq, sun4i_ts_irq, 0, "sun4i-ts", ts); -+ if (ret) -+ return ret; -+ -+ /* -+ * Select HOSC clk, clkin = clk / 6, adc samplefreq = clkin / 8192, -+ * t_acq = clkin / (16 * 64) -+ */ -+ writel(ADC_CLK_SEL(0) | ADC_CLK_DIV(2) | FS_DIV(7) | T_ACQ(63), -+ ts->base + TP_CTRL0); -+ -+ /* -+ * sensitive_adjust = 15 : max, which is not all that sensitive, -+ * tp_mode = 0 : only x and y coordinates, as we don't use dual touch -+ */ -+ writel(TP_SENSITIVE_ADJUST(15) | TP_MODE_SELECT(0), -+ ts->base + TP_CTRL2); -+ -+ /* Enable median filter, type 1 : 5/3 */ -+ writel(FILTER_EN(1) | FILTER_TYPE(1), ts->base + TP_CTRL3); -+ -+ /* Enable temperature measurement, period 1953 (2 seconds) */ -+ writel(TEMP_ENABLE(1) | TEMP_PERIOD(1953), ts->base + TP_TPR); -+ -+ /* -+ * Set stylus up debounce to aprox 10 ms, enable debounce, and -+ * finally enable tp mode. -+ */ -+ writel(STYLUS_UP_DEBOUN(5) | STYLUS_UP_DEBOUN_EN(1) | TP_MODE_EN(1), -+ ts->base + TP_CTRL1); -+ -+ ret = input_register_device(ts->input); -+ if (ret) -+ return ret; -+ -+ platform_set_drvdata(pdev, ts); -+ return 0; -+} -+ -+static const struct of_device_id sun4i_ts_of_match[] = { -+ { .compatible = "allwinner,sun4i-ts", }, -+ { /* sentinel */ } -+}; -+MODULE_DEVICE_TABLE(of, sun4i_ts_of_match); -+ -+static struct platform_driver sun4i_ts_driver = { -+ .driver = { -+ .owner = THIS_MODULE, -+ .name = "sun4i-ts", -+ .of_match_table = of_match_ptr(sun4i_ts_of_match), -+ }, -+ .probe = sun4i_ts_probe, -+}; -+ -+module_platform_driver(sun4i_ts_driver); -+ -+MODULE_DESCRIPTION("Allwinner sun4i resistive touchscreen controller driver"); -+MODULE_AUTHOR("Hans de Goede <hdegoede@redhat.com>"); -+MODULE_LICENSE("GPL"); diff --git a/target/linux/sunxi/patches-3.14/171-input-add-temp-sensor-support.patch b/target/linux/sunxi/patches-3.14/171-input-add-temp-sensor-support.patch deleted file mode 100644 index bad8df7687..0000000000 --- a/target/linux/sunxi/patches-3.14/171-input-add-temp-sensor-support.patch +++ /dev/null @@ -1,256 +0,0 @@ -From d8b5553dbf60e519d565dbd83327b08865e960e2 Mon Sep 17 00:00:00 2001 -From: Hans de Goede <hdegoede@redhat.com> -Date: Fri, 27 Dec 2013 15:25:28 +0100 -Subject: [PATCH] input: sun4i-ts: Add support for temperature sensor - -The sun4i resisitive touchscreen controller also comes with a built-in -temperature sensor. This commit adds support for it. - -This commit also introduces a new "ts-attached" device-tree property, -when this is not set, the input part of the driver won't register. This way -the internal temperature sensor can be used to measure the SoC temperature -independent of there actually being a touchscreen attached to the controller. - -Signed-off-by: Hans de Goede <hdegoede@redhat.com> ---- - .../bindings/input/touchscreen/sun4i.txt | 5 + - drivers/input/touchscreen/sun4i-ts.c | 140 ++++++++++++++++----- - 2 files changed, 114 insertions(+), 31 deletions(-) - ---- a/Documentation/devicetree/bindings/input/touchscreen/sun4i.txt -+++ b/Documentation/devicetree/bindings/input/touchscreen/sun4i.txt -@@ -6,10 +6,15 @@ Required properties: - - reg: mmio address range of the chip - - interrupts: interrupt to which the chip is connected - -+Optional properties: -+ - allwinner,ts-attached: boolean indicating that an actual touchscreen is -+ attached to the controller -+ - Example: - - rtp: rtp@01c25000 { - compatible = "allwinner,sun4i-ts"; - reg = <0x01c25000 0x100>; - interrupts = <29>; -+ allwinner,ts-attached; - }; ---- a/drivers/input/touchscreen/sun4i-ts.c -+++ b/drivers/input/touchscreen/sun4i-ts.c -@@ -3,6 +3,9 @@ - * - * Copyright (C) 2013 - 2014 Hans de Goede <hdegoede@redhat.com> - * -+ * The hwmon parts are based on work by Corentin LABBE which is: -+ * Copyright (C) 2013 Corentin LABBE <clabbe.montjoie@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 -@@ -30,6 +33,7 @@ - */ - - #include <linux/err.h> -+#include <linux/hwmon.h> - #include <linux/init.h> - #include <linux/input.h> - #include <linux/interrupt.h> -@@ -106,14 +110,12 @@ struct sun4i_ts_data { - void __iomem *base; - unsigned int irq; - bool ignore_fifo_data; -+ int temp_data; - }; - --static irqreturn_t sun4i_ts_irq(int irq, void *dev_id) -+static void sun4i_ts_irq_handle_input(struct sun4i_ts_data *ts, u32 reg_val) - { -- struct sun4i_ts_data *ts = dev_id; -- u32 reg_val, x, y; -- -- reg_val = readl(ts->base + TP_INT_FIFOS); -+ u32 x, y; - - if (reg_val & FIFO_DATA_PENDING) { - x = readl(ts->base + TP_DATA); -@@ -139,6 +141,20 @@ static irqreturn_t sun4i_ts_irq(int irq, - input_report_key(ts->input, BTN_TOUCH, 0); - input_sync(ts->input); - } -+} -+ -+static irqreturn_t sun4i_ts_irq(int irq, void *dev_id) -+{ -+ struct sun4i_ts_data *ts = dev_id; -+ u32 reg_val; -+ -+ reg_val = readl(ts->base + TP_INT_FIFOS); -+ -+ if (reg_val & TEMP_DATA_PENDING) -+ ts->temp_data = readl(ts->base + TEMP_DATA); -+ -+ if (ts->input) -+ sun4i_ts_irq_handle_input(ts, reg_val); - - writel(reg_val, ts->base + TP_INT_FIFOS); - -@@ -149,9 +165,9 @@ static int sun4i_ts_open(struct input_de - { - struct sun4i_ts_data *ts = input_get_drvdata(dev); - -- /* Flush, set trig level to 1, enable data and up irqs */ -- writel(DATA_IRQ_EN(1) | FIFO_TRIG(1) | FIFO_FLUSH(1) | TP_UP_IRQ_EN(1), -- ts->base + TP_INT_FIFOC); -+ /* Flush, set trig level to 1, enable temp, data and up irqs */ -+ writel(TEMP_IRQ_EN(1) | DATA_IRQ_EN(1) | FIFO_TRIG(1) | FIFO_FLUSH(1) | -+ TP_UP_IRQ_EN(1), ts->base + TP_INT_FIFOC); - - return 0; - } -@@ -160,15 +176,48 @@ static void sun4i_ts_close(struct input_ - { - struct sun4i_ts_data *ts = input_get_drvdata(dev); - -- /* Deactivate all IRQs */ -- writel(0, ts->base + TP_INT_FIFOC); -+ /* Deactivate all input IRQs */ -+ writel(TEMP_IRQ_EN(1), ts->base + TP_INT_FIFOC); -+} -+ -+static ssize_t show_temp(struct device *dev, struct device_attribute *devattr, -+ char *buf) -+{ -+ struct sun4i_ts_data *ts = dev_get_drvdata(dev); -+ -+ /* No temp_data until the first irq */ -+ if (ts->temp_data == -1) -+ return -EAGAIN; -+ -+ return sprintf(buf, "%d\n", (ts->temp_data - 1447) * 100); -+} -+ -+static ssize_t show_temp_label(struct device *dev, -+ struct device_attribute *devattr, char *buf) -+{ -+ return sprintf(buf, "SoC temperature\n"); - } - -+static DEVICE_ATTR(temp1_input, S_IRUGO, show_temp, NULL); -+static DEVICE_ATTR(temp1_label, S_IRUGO, show_temp_label, NULL); -+ -+static struct attribute *sun4i_ts_attrs[] = { -+ &dev_attr_temp1_input.attr, -+ &dev_attr_temp1_label.attr, -+ NULL -+}; -+ATTRIBUTE_GROUPS(sun4i_ts); -+ - static int sun4i_ts_probe(struct platform_device *pdev) - { - struct sun4i_ts_data *ts; - struct device *dev = &pdev->dev; -+ struct device_node *np = dev->of_node; -+ struct device *hwmon; - int ret; -+ bool ts_attached; -+ -+ ts_attached = of_property_read_bool(np, "allwinner,ts-attached"); - - ts = devm_kzalloc(dev, sizeof(struct sun4i_ts_data), GFP_KERNEL); - if (!ts) -@@ -176,24 +225,27 @@ static int sun4i_ts_probe(struct platfor - - ts->dev = dev; - ts->ignore_fifo_data = true; -+ ts->temp_data = -1; - -- ts->input = devm_input_allocate_device(dev); -- if (!ts->input) -- return -ENOMEM; -- -- ts->input->name = pdev->name; -- ts->input->phys = "sun4i_ts/input0"; -- ts->input->open = sun4i_ts_open; -- ts->input->close = sun4i_ts_close; -- ts->input->id.bustype = BUS_HOST; -- ts->input->id.vendor = 0x0001; -- ts->input->id.product = 0x0001; -- ts->input->id.version = 0x0100; -- ts->input->evbit[0] = BIT(EV_SYN) | BIT(EV_KEY) | BIT(EV_ABS); -- set_bit(BTN_TOUCH, ts->input->keybit); -- input_set_abs_params(ts->input, ABS_X, 0, 4095, 0, 0); -- input_set_abs_params(ts->input, ABS_Y, 0, 4095, 0, 0); -- input_set_drvdata(ts->input, ts); -+ if (ts_attached) { -+ ts->input = devm_input_allocate_device(dev); -+ if (!ts->input) -+ return -ENOMEM; -+ -+ ts->input->name = pdev->name; -+ ts->input->phys = "sun4i_ts/input0"; -+ ts->input->open = sun4i_ts_open; -+ ts->input->close = sun4i_ts_close; -+ ts->input->id.bustype = BUS_HOST; -+ ts->input->id.vendor = 0x0001; -+ ts->input->id.product = 0x0001; -+ ts->input->id.version = 0x0100; -+ ts->input->evbit[0] = BIT(EV_SYN) | BIT(EV_KEY) | BIT(EV_ABS); -+ set_bit(BTN_TOUCH, ts->input->keybit); -+ input_set_abs_params(ts->input, ABS_X, 0, 4095, 0, 0); -+ input_set_abs_params(ts->input, ABS_Y, 0, 4095, 0, 0); -+ input_set_drvdata(ts->input, ts); -+ } - - ts->base = devm_ioremap_resource(dev, - platform_get_resource(pdev, IORESOURCE_MEM, 0)); -@@ -232,14 +284,39 @@ static int sun4i_ts_probe(struct platfor - writel(STYLUS_UP_DEBOUN(5) | STYLUS_UP_DEBOUN_EN(1) | TP_MODE_EN(1), - ts->base + TP_CTRL1); - -- ret = input_register_device(ts->input); -- if (ret) -- return ret; -+ hwmon = devm_hwmon_device_register_with_groups(ts->dev, "sun4i_ts", -+ ts, sun4i_ts_groups); -+ if (IS_ERR(hwmon)) -+ return PTR_ERR(hwmon); -+ -+ writel(TEMP_IRQ_EN(1), ts->base + TP_INT_FIFOC); -+ -+ if (ts_attached) { -+ ret = input_register_device(ts->input); -+ if (ret) { -+ writel(0, ts->base + TP_INT_FIFOC); -+ return ret; -+ } -+ } - - platform_set_drvdata(pdev, ts); - return 0; - } - -+static int sun4i_ts_remove(struct platform_device *pdev) -+{ -+ struct sun4i_ts_data *ts = platform_get_drvdata(pdev); -+ -+ /* Explicit unregister to avoid open/close changing the imask later */ -+ if (ts->input) -+ input_unregister_device(ts->input); -+ -+ /* Deactivate all IRQs */ -+ writel(0, ts->base + TP_INT_FIFOC); -+ -+ return 0; -+} -+ - static const struct of_device_id sun4i_ts_of_match[] = { - { .compatible = "allwinner,sun4i-ts", }, - { /* sentinel */ } -@@ -253,6 +330,7 @@ static struct platform_driver sun4i_ts_d - .of_match_table = of_match_ptr(sun4i_ts_of_match), - }, - .probe = sun4i_ts_probe, -+ .remove = sun4i_ts_remove, - }; - - module_platform_driver(sun4i_ts_driver); diff --git a/target/linux/sunxi/patches-3.14/172-input-add-lradc-keys-driver.patch b/target/linux/sunxi/patches-3.14/172-input-add-lradc-keys-driver.patch deleted file mode 100644 index 859a7f1a67..0000000000 --- a/target/linux/sunxi/patches-3.14/172-input-add-lradc-keys-driver.patch +++ /dev/null @@ -1,326 +0,0 @@ -From 3f8fd9b9e2daefb7be4c46369f86af1c7bb2f1ca Mon Sep 17 00:00:00 2001 -From: Hans de Goede <hdegoede@redhat.com> -Date: Wed, 1 Jan 2014 19:44:49 +0100 -Subject: [PATCH] input: Add new sun4i-lradc-keys driver - -Allwinnner sunxi SoCs have a low resolution adc (called lradc) which is -specifically designed to have various (tablet) keys (ie home, back, search, -etc). attached to it using a resistor network. This adds a driver for this. - -There are 2 channels, currently this driver only supports chan0 since there -are no boards known to use chan1. The devicetree properties are already -prefixed with chan0 as preparation for chan1 support in the future. - -This has been tested on an olimex a10s-olinuxino-micro, a13-olinuxino, and -a20-olinuxino-micro. - -Signed-off-by: Hans de Goede <hdegoede@redhat.com> ---- - .../devicetree/bindings/input/sun4i-lradc-keys.txt | 22 ++ - drivers/input/keyboard/Kconfig | 10 + - drivers/input/keyboard/Makefile | 1 + - drivers/input/keyboard/sun4i-lradc-keys.c | 243 +++++++++++++++++++++ - 4 files changed, 276 insertions(+) - create mode 100644 Documentation/devicetree/bindings/input/sun4i-lradc-keys.txt - create mode 100644 drivers/input/keyboard/sun4i-lradc-keys.c - ---- /dev/null -+++ b/Documentation/devicetree/bindings/input/sun4i-lradc-keys.txt -@@ -0,0 +1,22 @@ -+Allwinner sun4i low res adc attached tablet keys -+------------------------------------------------ -+ -+Required properties: -+ - compatible: "allwinner,sun4i-lradc-keys" -+ - reg: mmio address range of the chip -+ - interrupts: interrupt to which the chip is connected -+ - allwinner,chan0-step: step in mV between keys must be 150 or 200 -+ - linux,chan0-keycodes: array of dt-bindings/input/input.h KEY_ codes -+ -+Example: -+ -+#include <dt-bindings/input/input.h> -+ -+ lradc: lradc@01c22800 { -+ compatible = "allwinner,sun4i-lradc-keys"; -+ reg = <0x01c22800 0x100>; -+ interrupts = <31>; -+ allwinner,chan0-step = <200>; -+ linux,chan0-keycodes = <KEY_VOLUMEUP KEY_VOLUMEDOWN -+ KEY_MENU KEY_ENTER KEY_HOME>; -+ }; ---- a/drivers/input/keyboard/Kconfig -+++ b/drivers/input/keyboard/Kconfig -@@ -544,6 +544,16 @@ config KEYBOARD_STMPE - To compile this driver as a module, choose M here: the module will be - called stmpe-keypad. - -+config KEYBOARD_SUN4I_LRADC -+ tristate "Allwinner sun4i low res adc attached tablet keys support" -+ depends on ARCH_SUNXI -+ help -+ This selects support for the Allwinner low res adc attached tablet -+ keys found on Allwinner sunxi SoCs. -+ -+ To compile this driver as a module, choose M here: the -+ module will be called sun4i-lradc-keys. -+ - config KEYBOARD_DAVINCI - tristate "TI DaVinci Key Scan" - depends on ARCH_DAVINCI_DM365 ---- a/drivers/input/keyboard/Makefile -+++ b/drivers/input/keyboard/Makefile -@@ -50,6 +50,7 @@ obj-$(CONFIG_KEYBOARD_SH_KEYSC) += sh_k - obj-$(CONFIG_KEYBOARD_SPEAR) += spear-keyboard.o - obj-$(CONFIG_KEYBOARD_STMPE) += stmpe-keypad.o - obj-$(CONFIG_KEYBOARD_STOWAWAY) += stowaway.o -+obj-$(CONFIG_KEYBOARD_SUN4I_LRADC) += sun4i-lradc-keys.o - obj-$(CONFIG_KEYBOARD_SUNKBD) += sunkbd.o - obj-$(CONFIG_KEYBOARD_TC3589X) += tc3589x-keypad.o - obj-$(CONFIG_KEYBOARD_TEGRA) += tegra-kbc.o ---- /dev/null -+++ b/drivers/input/keyboard/sun4i-lradc-keys.c -@@ -0,0 +1,243 @@ -+/* -+ * Allwinner sun4i low res adc attached tablet keys driver -+ * -+ * Copyright (C) 2014 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. -+ */ -+ -+/* -+ * Allwinnner sunxi SoCs have a lradc which is specifically designed to have -+ * various (tablet) keys (ie home, back, search, etc). attached to it using -+ * a resistor network. This driver is for the keys on such boards. -+ * -+ * There are 2 channels, currently this driver only supports chan0 since there -+ * are no boards known to use chan1. The devicetree properties are already -+ * prefixed with chan0 as preparation for chan1 support in the future. -+ */ -+ -+#include <linux/err.h> -+#include <linux/init.h> -+#include <linux/input.h> -+#include <linux/interrupt.h> -+#include <linux/io.h> -+#include <linux/module.h> -+#include <linux/of_platform.h> -+#include <linux/platform_device.h> -+#include <linux/slab.h> -+ -+#define LRADC_CTRL 0x00 -+#define LRADC_INTC 0x04 -+#define LRADC_INTS 0x08 -+#define LRADC_DATA0 0x0c -+#define LRADC_DATA1 0x10 -+ -+/* LRADC_CTRL bits */ -+#define FIRST_CONVERT_DLY(x) ((x) << 24) /* 8 bits */ -+#define CHAN_SELECT(x) ((x) << 22) /* 2 bits */ -+#define CONTINUE_TIME_SEL(x) ((x) << 16) /* 4 bits */ -+#define KEY_MODE_SEL(x) ((x) << 12) /* 2 bits */ -+#define LEVELA_B_CNT(x) ((x) << 8) /* 4 bits */ -+#define HOLD_EN(x) ((x) << 6) -+#define LEVELB_VOL(x) ((x) << 4) /* 2 bits */ -+#define SAMPLE_RATE(x) ((x) << 2) /* 2 bits */ -+#define ENABLE(x) ((x) << 0) -+ -+/* LRADC_INTC and LRADC_INTS bits */ -+#define CHAN1_KEYUP_IRQ BIT(12) -+#define CHAN1_ALRDY_HOLD_IRQ BIT(11) -+#define CHAN1_HOLD_IRQ BIT(10) -+#define CHAN1_KEYDOWN_IRQ BIT(9) -+#define CHAN1_DATA_IRQ BIT(8) -+#define CHAN0_KEYUP_IRQ BIT(4) -+#define CHAN0_ALRDY_HOLD_IRQ BIT(3) -+#define CHAN0_HOLD_IRQ BIT(2) -+#define CHAN0_KEYDOWN_IRQ BIT(1) -+#define CHAN0_DATA_IRQ BIT(0) -+ -+#define MAX_KEYS 13 -+ -+/* Lookup table to map the adc val to a keycode index for 150 mv step size */ -+static const u8 adc_val_to_key_index_step150[64] = { -+ 0, 0, 0, -+ 1, 1, 1, 1, 1, -+ 2, 2, 2, 2, 2, -+ 3, 3, 3, 3, -+ 4, 4, 4, 4, 4, -+ 5, 5, 5, 5, 5, -+ 6, 6, 6, 6, 6, -+ 7, 7, 7, 7, -+ 8, 8, 8, 8, 8, -+ 9, 9, 9, 9, 9, -+ 10, 10, 10, 10, -+ 11, 11, 11, 11, -+ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12 -+}; -+ -+/* Lookup table to map the adc val to a keycode index for 200 mv step size */ -+static const u8 adc_val_to_key_index_step200[64] = { -+ 0, 0, 0, 0, 0, 0, 0, 0, -+ 1, 1, 1, 1, 1, 1, 1, -+ 2, 2, 2, 2, 2, 2, 2, -+ 3, 3, 3, 3, 3, 3, -+ 4, 4, 4, 4, 4, 4, -+ 5, 5, 5, 5, 5, 5, -+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, -+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7 -+}; -+ -+struct sun4i_lradc_data { -+ struct device *dev; -+ struct input_dev *input; -+ void __iomem *base; -+ u32 chan0_step; -+ u32 chan0_keycode; -+ u32 chan0_keycodes[MAX_KEYS]; -+}; -+ -+static irqreturn_t sun4i_lradc_irq(int irq, void *dev_id) -+{ -+ struct sun4i_lradc_data *lradc = dev_id; -+ u32 ints, val; -+ -+ ints = readl(lradc->base + LRADC_INTS); -+ -+ /* -+ * lradc supports only one keypress at a time, release does not give -+ * any info as to which key was released, so we cache the keycode. -+ */ -+ if ((ints & CHAN0_KEYDOWN_IRQ) && lradc->chan0_keycode == 0) { -+ val = readl(lradc->base + LRADC_DATA0); -+ if (lradc->chan0_step == 150) -+ val = adc_val_to_key_index_step150[val]; -+ else -+ val = adc_val_to_key_index_step200[val]; -+ -+ lradc->chan0_keycode = lradc->chan0_keycodes[val]; -+ input_report_key(lradc->input, lradc->chan0_keycode, 1); -+ } -+ -+ if (ints & CHAN0_KEYUP_IRQ) { -+ input_report_key(lradc->input, lradc->chan0_keycode, 0); -+ lradc->chan0_keycode = 0; -+ } -+ -+ input_sync(lradc->input); -+ -+ writel(ints, lradc->base + LRADC_INTS); -+ -+ return IRQ_HANDLED; -+} -+ -+static int sun4i_lradc_open(struct input_dev *dev) -+{ -+ struct sun4i_lradc_data *lradc = input_get_drvdata(dev); -+ -+ /* -+ * Set sample time to 16 ms / 62.5 Hz. Wait 2 * 16 ms for key to -+ * stabilize on press, wait (1 + 1) * 16 ms for key release -+ */ -+ writel(FIRST_CONVERT_DLY(2) | LEVELA_B_CNT(1) | HOLD_EN(1) | -+ SAMPLE_RATE(2) | ENABLE(1), lradc->base + LRADC_CTRL); -+ -+ writel(CHAN0_KEYUP_IRQ | CHAN0_KEYDOWN_IRQ, lradc->base + LRADC_INTC); -+ -+ return 0; -+} -+ -+static void sun4i_lradc_close(struct input_dev *dev) -+{ -+ struct sun4i_lradc_data *lradc = input_get_drvdata(dev); -+ -+ /* Disable lradc, leave other settings unchanged */ -+ writel(FIRST_CONVERT_DLY(2) | LEVELA_B_CNT(1) | HOLD_EN(1) | -+ SAMPLE_RATE(2), lradc->base + LRADC_CTRL); -+ writel(0, lradc->base + LRADC_INTC); -+} -+ -+static int sun4i_lradc_probe(struct platform_device *pdev) -+{ -+ struct sun4i_lradc_data *lradc; -+ struct device *dev = &pdev->dev; -+ struct device_node *np = dev->of_node; -+ int i, ret; -+ -+ lradc = devm_kzalloc(dev, sizeof(struct sun4i_lradc_data), GFP_KERNEL); -+ if (!lradc) -+ return -ENOMEM; -+ -+ ret = of_property_read_u32(np, "allwinner,chan0-step", -+ &lradc->chan0_step); -+ if (ret || (lradc->chan0_step != 150 && lradc->chan0_step != 200)) { -+ dev_err(dev, "Invalid allwinner,chan0-step dt-property\n"); -+ return -EINVAL; -+ } -+ -+ for (i = 0; i < MAX_KEYS; i++) -+ of_property_read_u32_index(np, "linux,chan0-keycodes", -+ i, &lradc->chan0_keycodes[i]); -+ -+ lradc->dev = dev; -+ lradc->input = devm_input_allocate_device(dev); -+ if (!lradc->input) -+ return -ENOMEM; -+ -+ lradc->input->name = pdev->name; -+ lradc->input->phys = "sun4i_lradc/input0"; -+ lradc->input->open = sun4i_lradc_open; -+ lradc->input->close = sun4i_lradc_close; -+ lradc->input->id.bustype = BUS_HOST; -+ lradc->input->id.vendor = 0x0001; -+ lradc->input->id.product = 0x0001; -+ lradc->input->id.version = 0x0100; -+ lradc->input->evbit[0] = BIT(EV_SYN) | BIT(EV_KEY); -+ for (i = 0; i < MAX_KEYS; i++) -+ set_bit(lradc->chan0_keycodes[i], lradc->input->keybit); -+ input_set_drvdata(lradc->input, lradc); -+ -+ lradc->base = devm_ioremap_resource(dev, -+ platform_get_resource(pdev, IORESOURCE_MEM, 0)); -+ if (IS_ERR(lradc->base)) -+ return PTR_ERR(lradc->base); -+ -+ ret = devm_request_irq(dev, platform_get_irq(pdev, 0), sun4i_lradc_irq, -+ 0, "sun4i-lradc-keys", lradc); -+ if (ret) -+ return ret; -+ -+ ret = input_register_device(lradc->input); -+ if (ret) -+ return ret; -+ -+ platform_set_drvdata(pdev, lradc); -+ return 0; -+} -+ -+static const struct of_device_id sun4i_lradc_of_match[] = { -+ { .compatible = "allwinner,sun4i-lradc-keys", }, -+ { /* sentinel */ } -+}; -+MODULE_DEVICE_TABLE(of, sun4i_lradc_of_match); -+ -+static struct platform_driver sun4i_lradc_driver = { -+ .driver = { -+ .owner = THIS_MODULE, -+ .name = "sun4i-lradc-keys", -+ .of_match_table = of_match_ptr(sun4i_lradc_of_match), -+ }, -+ .probe = sun4i_lradc_probe, -+}; -+ -+module_platform_driver(sun4i_lradc_driver); -+ -+MODULE_DESCRIPTION("Allwinner sun4i low res adc attached tablet keys driver"); -+MODULE_AUTHOR("Hans de Goede <hdegoede@redhat.com>"); -+MODULE_LICENSE("GPL"); diff --git a/target/linux/sunxi/patches-3.14/173-1-dt-sun4i-add-lradc-node.patch b/target/linux/sunxi/patches-3.14/173-1-dt-sun4i-add-lradc-node.patch deleted file mode 100644 index 544528d8e7..0000000000 --- a/target/linux/sunxi/patches-3.14/173-1-dt-sun4i-add-lradc-node.patch +++ /dev/null @@ -1,26 +0,0 @@ -From 87d0c26803eec56971c8a7e6299aefc4d72dfb3c Mon Sep 17 00:00:00 2001 -From: Hans de Goede <hdegoede@redhat.com> -Date: Wed, 1 Jan 2014 19:51:36 +0100 -Subject: [PATCH] ARM: dts: sun4i: Add lradc node - -Signed-off-by: Hans de Goede <hdegoede@redhat.com> ---- - arch/arm/boot/dts/sun4i-a10.dtsi | 7 +++++++ - 1 file changed, 7 insertions(+) - ---- a/arch/arm/boot/dts/sun4i-a10.dtsi -+++ b/arch/arm/boot/dts/sun4i-a10.dtsi -@@ -549,6 +549,13 @@ - interrupts = <24>; - }; - -+ lradc: lradc@01c22800 { -+ compatible = "allwinner,sun4i-lradc-keys"; -+ reg = <0x01c22800 0x100>; -+ interrupts = <31>; -+ status = "disabled"; -+ }; -+ - sid: eeprom@01c23800 { - compatible = "allwinner,sun4i-sid"; - reg = <0x01c23800 0x10>; diff --git a/target/linux/sunxi/patches-3.14/173-2-dt-sun5i-add-lradc-node.patch b/target/linux/sunxi/patches-3.14/173-2-dt-sun5i-add-lradc-node.patch deleted file mode 100644 index 6fa1c2b9f6..0000000000 --- a/target/linux/sunxi/patches-3.14/173-2-dt-sun5i-add-lradc-node.patch +++ /dev/null @@ -1,53 +0,0 @@ -From 9041b1f6118b32929e6357affb53db28439a11e7 Mon Sep 17 00:00:00 2001 -From: Hans de Goede <hdegoede@redhat.com> -Date: Wed, 1 Jan 2014 19:50:33 +0100 -Subject: [PATCH] ARM: dts: sun5i: Add lradc node - -Signed-off-by: Hans de Goede <hdegoede@redhat.com> ---- - arch/arm/boot/dts/sun5i-a10s-olinuxino-micro.dts | 8 ++++++++ - arch/arm/boot/dts/sun5i-a10s.dtsi | 7 +++++++ - arch/arm/boot/dts/sun5i-a13-olinuxino.dts | 8 ++++++++ - arch/arm/boot/dts/sun5i-a13.dtsi | 7 +++++++ - 4 files changed, 30 insertions(+) - ---- a/arch/arm/boot/dts/sun5i-a13-olinuxino.dts -+++ b/arch/arm/boot/dts/sun5i-a13-olinuxino.dts -@@ -14,6 +14,7 @@ - /dts-v1/; - /include/ "sun5i-a13.dtsi" - /include/ "sunxi-common-regulators.dtsi" -+#include <dt-bindings/input/input.h> - - / { - model = "Olimex A13-Olinuxino"; -@@ -49,6 +50,13 @@ - }; - }; - -+ lradc: lradc@01c22800 { -+ allwinner,chan0-step = <200>; -+ linux,chan0-keycodes = <KEY_VOLUMEUP KEY_VOLUMEDOWN -+ KEY_MENU KEY_ENTER KEY_HOME>; -+ status = "okay"; -+ }; -+ - uart1: serial@01c28400 { - pinctrl-names = "default"; - pinctrl-0 = <&uart1_pins_b>; ---- a/arch/arm/boot/dts/sun5i-a13.dtsi -+++ b/arch/arm/boot/dts/sun5i-a13.dtsi -@@ -429,6 +429,13 @@ - reg = <0x01c20c90 0x10>; - }; - -+ lradc: lradc@01c22800 { -+ compatible = "allwinner,sun4i-lradc-keys"; -+ reg = <0x01c22800 0x100>; -+ interrupts = <31>; -+ status = "disabled"; -+ }; -+ - sid: eeprom@01c23800 { - compatible = "allwinner,sun4i-sid"; - reg = <0x01c23800 0x10>; diff --git a/target/linux/sunxi/patches-3.14/173-3-dt-sun7i-add-lradc-node.patch b/target/linux/sunxi/patches-3.14/173-3-dt-sun7i-add-lradc-node.patch deleted file mode 100644 index 44e9f53cbc..0000000000 --- a/target/linux/sunxi/patches-3.14/173-3-dt-sun7i-add-lradc-node.patch +++ /dev/null @@ -1,52 +0,0 @@ -From 98e21d18a26032912bf6c979f084c200a94e976b Mon Sep 17 00:00:00 2001 -From: Hans de Goede <hdegoede@redhat.com> -Date: Wed, 1 Jan 2014 20:26:21 +0100 -Subject: [PATCH] ARM: dts: sun7i: Add lradc node - -Signed-off-by: Hans de Goede <hdegoede@redhat.com> ---- - arch/arm/boot/dts/sun7i-a20-olinuxino-micro.dts | 9 +++++++++ - arch/arm/boot/dts/sun7i-a20.dtsi | 7 +++++++ - 2 files changed, 16 insertions(+) - ---- a/arch/arm/boot/dts/sun7i-a20-olinuxino-micro.dts -+++ b/arch/arm/boot/dts/sun7i-a20-olinuxino-micro.dts -@@ -14,6 +14,7 @@ - /dts-v1/; - /include/ "sun7i-a20.dtsi" - /include/ "sunxi-common-regulators.dtsi" -+#include <dt-bindings/input/input.h> - - / { - model = "Olimex A20-Olinuxino Micro"; -@@ -73,6 +74,14 @@ - }; - }; - -+ lradc: lradc@01c22800 { -+ allwinner,chan0-step = <200>; -+ linux,chan0-keycodes = <KEY_VOLUMEUP KEY_VOLUMEDOWN -+ KEY_MENU KEY_SEARCH KEY_HOME -+ KEY_ESC KEY_ENTER>; -+ status = "okay"; -+ }; -+ - uart0: serial@01c28000 { - pinctrl-names = "default"; - pinctrl-0 = <&uart0_pins_a>; ---- a/arch/arm/boot/dts/sun7i-a20.dtsi -+++ b/arch/arm/boot/dts/sun7i-a20.dtsi -@@ -670,6 +670,13 @@ - interrupts = <0 24 4>; - }; - -+ lradc: lradc@01c22800 { -+ compatible = "allwinner,sun4i-lradc-keys"; -+ reg = <0x01c22800 0x100>; -+ interrupts = <0 31 4>; -+ status = "disabled"; -+ }; -+ - sid: eeprom@01c23800 { - compatible = "allwinner,sun7i-a20-sid"; - reg = <0x01c23800 0x200>; diff --git a/target/linux/sunxi/patches-3.14/175-reset-add-of_reset_control_get.patch b/target/linux/sunxi/patches-3.14/175-reset-add-of_reset_control_get.patch deleted file mode 100644 index 3b6db99dbf..0000000000 --- a/target/linux/sunxi/patches-3.14/175-reset-add-of_reset_control_get.patch +++ /dev/null @@ -1,112 +0,0 @@ -From bfea2b9be28b20e076d5df8863c25e966f413fa3 Mon Sep 17 00:00:00 2001 -From: Maxime Ripard <maxime.ripard@free-electrons.com> -Date: Fri, 20 Dec 2013 22:41:07 +0100 -Subject: [PATCH] reset: Add of_reset_control_get - -In some cases, you might need to deassert from reset an hardware block that -doesn't associated to a struct device (CPUs, timers, etc.). - -Add a small helper to retrieve the reset controller from the device tree -without the need to pass a struct device. - -Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com> ---- - drivers/reset/core.c | 39 ++++++++++++++++++++++++++++++--------- - include/linux/reset.h | 4 ++++ - 2 files changed, 34 insertions(+), 9 deletions(-) - ---- a/drivers/reset/core.c -+++ b/drivers/reset/core.c -@@ -127,15 +127,16 @@ int reset_control_deassert(struct reset_ - EXPORT_SYMBOL_GPL(reset_control_deassert); - - /** -- * reset_control_get - Lookup and obtain a reference to a reset controller. -- * @dev: device to be reset by the controller -+ * of_reset_control_get - Lookup and obtain a reference to a reset controller. -+ * @node: device to be reset by the controller - * @id: reset line name - * - * Returns a struct reset_control or IS_ERR() condition containing errno. - * - * Use of id names is optional. - */ --struct reset_control *reset_control_get(struct device *dev, const char *id) -+struct reset_control *of_reset_control_get(struct device_node *node, -+ const char *id) - { - struct reset_control *rstc = ERR_PTR(-EPROBE_DEFER); - struct reset_controller_dev *r, *rcdev; -@@ -144,13 +145,10 @@ struct reset_control *reset_control_get( - int rstc_id; - int ret; - -- if (!dev) -- return ERR_PTR(-EINVAL); -- - if (id) -- index = of_property_match_string(dev->of_node, -+ index = of_property_match_string(node, - "reset-names", id); -- ret = of_parse_phandle_with_args(dev->of_node, "resets", "#reset-cells", -+ ret = of_parse_phandle_with_args(node, "resets", "#reset-cells", - index, &args); - if (ret) - return ERR_PTR(ret); -@@ -185,12 +183,35 @@ struct reset_control *reset_control_get( - return ERR_PTR(-ENOMEM); - } - -- rstc->dev = dev; - rstc->rcdev = rcdev; - rstc->id = rstc_id; - - return rstc; - } -+EXPORT_SYMBOL_GPL(of_reset_control_get); -+ -+/** -+ * reset_control_get - Lookup and obtain a reference to a reset controller. -+ * @dev: device to be reset by the controller -+ * @id: reset line name -+ * -+ * Returns a struct reset_control or IS_ERR() condition containing errno. -+ * -+ * Use of id names is optional. -+ */ -+struct reset_control *reset_control_get(struct device *dev, const char *id) -+{ -+ struct reset_control *rstc; -+ -+ if (!dev) -+ return ERR_PTR(-EINVAL); -+ -+ rstc = of_reset_control_get(dev->of_node, id); -+ if (!IS_ERR(rstc)) -+ rstc->dev = dev; -+ -+ return rstc; -+} - EXPORT_SYMBOL_GPL(reset_control_get); - - /** ---- a/include/linux/reset.h -+++ b/include/linux/reset.h -@@ -1,6 +1,8 @@ - #ifndef _LINUX_RESET_H_ - #define _LINUX_RESET_H_ - -+#include <linux/of.h> -+ - struct device; - struct reset_control; - -@@ -8,6 +10,8 @@ int reset_control_reset(struct reset_con - int reset_control_assert(struct reset_control *rstc); - int reset_control_deassert(struct reset_control *rstc); - -+struct reset_control *of_reset_control_get(struct device_node *node, -+ const char *id); - struct reset_control *reset_control_get(struct device *dev, const char *id); - void reset_control_put(struct reset_control *rstc); - struct reset_control *devm_reset_control_get(struct device *dev, const char *id); diff --git a/target/linux/sunxi/patches-3.14/176-clk-sun5i-add-support-for-reset-ctrler.patch b/target/linux/sunxi/patches-3.14/176-clk-sun5i-add-support-for-reset-ctrler.patch deleted file mode 100644 index 3986d193b1..0000000000 --- a/target/linux/sunxi/patches-3.14/176-clk-sun5i-add-support-for-reset-ctrler.patch +++ /dev/null @@ -1,62 +0,0 @@ -From 3ec31fa2ce161d35f787354037f94d9d22d825d1 Mon Sep 17 00:00:00 2001 -From: Maxime Ripard <maxime.ripard@free-electrons.com> -Date: Fri, 20 Dec 2013 22:41:08 +0100 -Subject: [PATCH] clocksource: sun5i: Add support for reset controller - -The Allwinner A31 that uses this timer has the timer IP asserted in reset. -Add an optional reset property to the DT, and deassert the timer from reset if -it's there. - -Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com> ---- - .../devicetree/bindings/timer/allwinner,sun5i-a13-hstimer.txt | 4 ++++ - drivers/clocksource/timer-sun5i.c | 6 ++++++ - 2 files changed, 10 insertions(+) - ---- a/Documentation/devicetree/bindings/timer/allwinner,sun5i-a13-hstimer.txt -+++ b/Documentation/devicetree/bindings/timer/allwinner,sun5i-a13-hstimer.txt -@@ -9,6 +9,9 @@ Required properties: - one) - - clocks: phandle to the source clock (usually the AHB clock) - -+Optionnal properties: -+- resets: phandle to a reset controller asserting the timer -+ - Example: - - timer@01c60000 { -@@ -19,4 +22,5 @@ timer@01c60000 { - <0 53 1>, - <0 54 1>; - clocks = <&ahb1_gates 19>; -+ resets = <&ahb1rst 19>; - }; ---- a/drivers/clocksource/timer-sun5i.c -+++ b/drivers/clocksource/timer-sun5i.c -@@ -16,6 +16,7 @@ - #include <linux/interrupt.h> - #include <linux/irq.h> - #include <linux/irqreturn.h> -+#include <linux/reset.h> - #include <linux/sched_clock.h> - #include <linux/of.h> - #include <linux/of_address.h> -@@ -143,6 +144,7 @@ static u64 sun5i_timer_sched_read(void) - - static void __init sun5i_timer_init(struct device_node *node) - { -+ struct reset_control *rstc; - unsigned long rate; - struct clk *clk; - int ret, irq; -@@ -162,6 +164,10 @@ static void __init sun5i_timer_init(stru - clk_prepare_enable(clk); - rate = clk_get_rate(clk); - -+ rstc = of_reset_control_get(node, NULL); -+ if (!IS_ERR(rstc)) -+ reset_control_deassert(rstc); -+ - writel(~0, timer_base + TIMER_INTVAL_LO_REG(1)); - writel(TIMER_CTL_ENABLE | TIMER_CTL_RELOAD, - timer_base + TIMER_CTL_REG(1)); diff --git a/target/linux/sunxi/patches-3.14/180-clk-sunxi-add-clock-output-names-dt-prop-support.patch b/target/linux/sunxi/patches-3.14/180-clk-sunxi-add-clock-output-names-dt-prop-support.patch deleted file mode 100644 index 73caeb9ba3..0000000000 --- a/target/linux/sunxi/patches-3.14/180-clk-sunxi-add-clock-output-names-dt-prop-support.patch +++ /dev/null @@ -1,50 +0,0 @@ -From 0bf618fda3ad24649add0bf943d16a9b4f5c3463 Mon Sep 17 00:00:00 2001 -From: Chen-Yu Tsai <wens@csie.org> -Date: Mon, 3 Feb 2014 09:51:37 +0800 -Subject: [PATCH] clk: sunxi: add clock-output-names dt property support -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -sunxi clock drivers use dt node name as clock name, but clock -nodes should be named clk@X, so the names would be the same. -Let the drivers read clock names from dt clock-output-names -property. - -Signed-off-by: Chen-Yu Tsai <wens@csie.org> -Acked-by: Maxime Ripard <maxime.ripard@free-electrons.com> -Acked-by: Mike Turquette <mturquette@linaro.org> -Signed-off-by: Emilio López <emilio@elopez.com.ar> ---- - drivers/clk/sunxi/clk-sunxi.c | 6 ++++++ - 1 file changed, 6 insertions(+) - ---- a/drivers/clk/sunxi/clk-sunxi.c -+++ b/drivers/clk/sunxi/clk-sunxi.c -@@ -51,6 +51,8 @@ static void __init sun4i_osc_clk_setup(s - if (!gate) - goto err_free_fixed; - -+ of_property_read_string(node, "clock-output-names", &clk_name); -+ - /* set up gate and fixed rate properties */ - gate->reg = of_iomap(node, 0); - gate->bit_idx = SUNXI_OSC24M_GATE; -@@ -601,6 +603,8 @@ static void __init sunxi_mux_clk_setup(s - (parents[i] = of_clk_get_parent_name(node, i)) != NULL) - i++; - -+ of_property_read_string(node, "clock-output-names", &clk_name); -+ - clk = clk_register_mux(NULL, clk_name, parents, i, - CLK_SET_RATE_NO_REPARENT, reg, - data->shift, SUNXI_MUX_GATE_WIDTH, -@@ -660,6 +664,8 @@ static void __init sunxi_divider_clk_set - - clk_parent = of_clk_get_parent_name(node, 0); - -+ of_property_read_string(node, "clock-output-names", &clk_name); -+ - clk = clk_register_divider(NULL, clk_name, clk_parent, 0, - reg, data->shift, data->width, - data->pow ? CLK_DIVIDER_POWER_OF_TWO : 0, diff --git a/target/linux/sunxi/patches-3.14/181-clk-sunxi-add-names-for-pll56.patch b/target/linux/sunxi/patches-3.14/181-clk-sunxi-add-names-for-pll56.patch deleted file mode 100644 index 4229fa4f1c..0000000000 --- a/target/linux/sunxi/patches-3.14/181-clk-sunxi-add-names-for-pll56.patch +++ /dev/null @@ -1,78 +0,0 @@ -From 8f3156f3f2b70128b2761526c208c8e3bfda694e Mon Sep 17 00:00:00 2001 -From: Chen-Yu Tsai <wens@csie.org> -Date: Mon, 3 Feb 2014 09:51:39 +0800 -Subject: [PATCH] clk: sunxi: add names for pll5, pll6 parent clocks to - factors_data -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Some factor clocks, such as the parent clock of pll5 and pll6, have -multiple output names. Add the corresponding names to factors_data -tied to compatible string. - -Signed-off-by: Chen-Yu Tsai <wens@csie.org> -Acked-by: Maxime Ripard <maxime.ripard@free-electrons.com> -Acked-by: Mike Turquette <mturquette@linaro.org> -Signed-off-by: Emilio López <emilio@elopez.com.ar> ---- - drivers/clk/sunxi/clk-sunxi.c | 27 ++++++++++++++++++--------- - 1 file changed, 18 insertions(+), 9 deletions(-) - ---- a/drivers/clk/sunxi/clk-sunxi.c -+++ b/drivers/clk/sunxi/clk-sunxi.c -@@ -389,6 +389,7 @@ struct factors_data { - int mux; - struct clk_factors_config *table; - void (*getter) (u32 *rate, u32 parent_rate, u8 *n, u8 *k, u8 *m, u8 *p); -+ const char *name; - }; - - static struct clk_factors_config sun4i_pll1_config = { -@@ -457,6 +458,14 @@ static const struct factors_data sun4i_p - .enable = 31, - .table = &sun4i_pll5_config, - .getter = sun4i_get_pll5_factors, -+ .name = "pll5", -+}; -+ -+static const struct factors_data sun4i_pll6_data __initconst = { -+ .enable = 31, -+ .table = &sun4i_pll5_config, -+ .getter = sun4i_get_pll5_factors, -+ .name = "pll6", - }; - - static const struct factors_data sun4i_apb1_data __initconst = { -@@ -499,14 +508,14 @@ static struct clk * __init sunxi_factors - (parents[i] = of_clk_get_parent_name(node, i)) != NULL) - i++; - -- /* Nodes should be providing the name via clock-output-names -- * but originally our dts didn't, and so we used node->name. -- * The new, better nodes look like clk@deadbeef, so we pull the -- * name just in this case */ -- if (!strcmp("clk", clk_name)) { -- of_property_read_string_index(node, "clock-output-names", -- 0, &clk_name); -- } -+ /* -+ * some factor clocks, such as pll5 and pll6, may have multiple -+ * outputs, and have their name designated in factors_data -+ */ -+ if (data->name) -+ clk_name = data->name; -+ else -+ of_property_read_string(node, "clock-output-names", &clk_name); - - factors = kzalloc(sizeof(struct clk_factors), GFP_KERNEL); - if (!factors) -@@ -838,7 +847,7 @@ static const struct divs_data pll5_divs_ - }; - - static const struct divs_data pll6_divs_data __initconst = { -- .factors = &sun4i_pll5_data, -+ .factors = &sun4i_pll6_data, - .div = { - { .shift = 0, .table = pll6_sata_tbl, .gate = 14 }, /* M, SATA */ - { .fixed = 2 }, /* P, other */ diff --git a/target/linux/sunxi/patches-3.14/182-clk-sunxi-add-support-for-usb-clockreg-reset.patch b/target/linux/sunxi/patches-3.14/182-clk-sunxi-add-support-for-usb-clockreg-reset.patch deleted file mode 100644 index e8977362c7..0000000000 --- a/target/linux/sunxi/patches-3.14/182-clk-sunxi-add-support-for-usb-clockreg-reset.patch +++ /dev/null @@ -1,128 +0,0 @@ -From 0643a93746775da2189ab0afd8f748afcaa791c5 Mon Sep 17 00:00:00 2001 -From: Hans de Goede <hdegoede@redhat.com> -Date: Fri, 7 Feb 2014 16:21:49 +0100 -Subject: [PATCH] clk: sunxi: Add support for USB clock-register reset bits -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -The usb-clk register is special in that it not only contains clk gate bits, -but also has a few reset bits. This commit adds support for this by allowing -gates type sunxi clks to also register a reset controller. - -Signed-off-by: Hans de Goede <hdegoede@redhat.com> -Acked-by: Philipp Zabel <p.zabel@pengutronix.de> -Acked-by: Maxime Ripard <maxime.ripard@free-electrons.com> -Signed-off-by: Emilio López <emilio@elopez.com.ar> ---- - drivers/clk/sunxi/clk-sunxi.c | 71 +++++++++++++++++++++++++++++++++++++++++++ - 1 file changed, 71 insertions(+) - ---- a/drivers/clk/sunxi/clk-sunxi.c -+++ b/drivers/clk/sunxi/clk-sunxi.c -@@ -18,6 +18,7 @@ - #include <linux/clkdev.h> - #include <linux/of.h> - #include <linux/of_address.h> -+#include <linux/reset-controller.h> - - #include "clk-factors.h" - -@@ -688,6 +689,59 @@ static void __init sunxi_divider_clk_set - - - /** -+ * sunxi_gates_reset... - reset bits in leaf gate clk registers handling -+ */ -+ -+struct gates_reset_data { -+ void __iomem *reg; -+ spinlock_t *lock; -+ struct reset_controller_dev rcdev; -+}; -+ -+static int sunxi_gates_reset_assert(struct reset_controller_dev *rcdev, -+ unsigned long id) -+{ -+ struct gates_reset_data *data = container_of(rcdev, -+ struct gates_reset_data, -+ rcdev); -+ unsigned long flags; -+ u32 reg; -+ -+ spin_lock_irqsave(data->lock, flags); -+ -+ reg = readl(data->reg); -+ writel(reg & ~BIT(id), data->reg); -+ -+ spin_unlock_irqrestore(data->lock, flags); -+ -+ return 0; -+} -+ -+static int sunxi_gates_reset_deassert(struct reset_controller_dev *rcdev, -+ unsigned long id) -+{ -+ struct gates_reset_data *data = container_of(rcdev, -+ struct gates_reset_data, -+ rcdev); -+ unsigned long flags; -+ u32 reg; -+ -+ spin_lock_irqsave(data->lock, flags); -+ -+ reg = readl(data->reg); -+ writel(reg | BIT(id), data->reg); -+ -+ spin_unlock_irqrestore(data->lock, flags); -+ -+ return 0; -+} -+ -+static struct reset_control_ops sunxi_gates_reset_ops = { -+ .assert = sunxi_gates_reset_assert, -+ .deassert = sunxi_gates_reset_deassert, -+}; -+ -+/** - * sunxi_gates_clk_setup() - Setup function for leaf gates on clocks - */ - -@@ -695,6 +749,7 @@ static void __init sunxi_divider_clk_set - - struct gates_data { - DECLARE_BITMAP(mask, SUNXI_GATES_MAX_SIZE); -+ u32 reset_mask; - }; - - static const struct gates_data sun4i_axi_gates_data __initconst = { -@@ -765,6 +820,7 @@ static void __init sunxi_gates_clk_setup - struct gates_data *data) - { - struct clk_onecell_data *clk_data; -+ struct gates_reset_data *reset_data; - const char *clk_parent; - const char *clk_name; - void *reg; -@@ -808,6 +864,21 @@ static void __init sunxi_gates_clk_setup - clk_data->clk_num = i; - - of_clk_add_provider(node, of_clk_src_onecell_get, clk_data); -+ -+ /* Register a reset controler for gates with reset bits */ -+ if (data->reset_mask == 0) -+ return; -+ -+ reset_data = kzalloc(sizeof(*reset_data), GFP_KERNEL); -+ if (!reset_data) -+ return; -+ -+ reset_data->reg = reg; -+ reset_data->lock = &clk_lock; -+ reset_data->rcdev.nr_resets = __fls(data->reset_mask) + 1; -+ reset_data->rcdev.ops = &sunxi_gates_reset_ops; -+ reset_data->rcdev.of_node = node; -+ reset_controller_register(&reset_data->rcdev); - } - - diff --git a/target/linux/sunxi/patches-3.14/182-clk-sunxi-get-divs-parent-clockname.patch b/target/linux/sunxi/patches-3.14/182-clk-sunxi-get-divs-parent-clockname.patch deleted file mode 100644 index 777dfde856..0000000000 --- a/target/linux/sunxi/patches-3.14/182-clk-sunxi-get-divs-parent-clockname.patch +++ /dev/null @@ -1,40 +0,0 @@ -From 0566b74f93eaf6b2281d2605a63e06e6ba809334 Mon Sep 17 00:00:00 2001 -From: Chen-Yu Tsai <wens@csie.org> -Date: Mon, 3 Feb 2014 09:51:40 +0800 -Subject: [PATCH] clk: sunxi: get divs parent clock name from parent factor - clock -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Divs clocks consist of a parent factor clock with multiple outputs, -and seperate clocks for each output. Get the name of the parent -clock from the parent factor clock, instead of the DT node name. - -Signed-off-by: Chen-Yu Tsai <wens@csie.org> -Acked-by: Maxime Ripard <maxime.ripard@free-electrons.com> -Acked-by: Mike Turquette <mturquette@linaro.org> -Signed-off-by: Emilio López <emilio@elopez.com.ar> ---- - drivers/clk/sunxi/clk-sunxi.c | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - ---- a/drivers/clk/sunxi/clk-sunxi.c -+++ b/drivers/clk/sunxi/clk-sunxi.c -@@ -940,7 +940,7 @@ static void __init sunxi_divs_clk_setup( - struct divs_data *data) - { - struct clk_onecell_data *clk_data; -- const char *parent = node->name; -+ const char *parent; - const char *clk_name; - struct clk **clks, *pclk; - struct clk_hw *gate_hw, *rate_hw; -@@ -954,6 +954,7 @@ static void __init sunxi_divs_clk_setup( - - /* Set up factor clock that we will be dividing */ - pclk = sunxi_factors_clk_setup(node, data->factors); -+ parent = __clk_get_name(pclk); - - reg = of_iomap(node, 0); - diff --git a/target/linux/sunxi/patches-3.14/183-clk-sunxi-add-usb-clockreg-defs.patch b/target/linux/sunxi/patches-3.14/183-clk-sunxi-add-usb-clockreg-defs.patch deleted file mode 100644 index c79f803198..0000000000 --- a/target/linux/sunxi/patches-3.14/183-clk-sunxi-add-usb-clockreg-defs.patch +++ /dev/null @@ -1,69 +0,0 @@ -From c61dfeb17581d32360a817ba40636aaed85caade Mon Sep 17 00:00:00 2001 -From: Roman Byshko <rbyshko@gmail.com> -Date: Fri, 7 Feb 2014 16:21:50 +0100 -Subject: [PATCH] clk: sunxi: Add USB clock register defintions -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Add register definitions for the usb-clk register found on sun4i, sun5i and -sun7i SoCs. - -Signed-off-by: Roman Byshko <rbyshko@gmail.com> -Signed-off-by: Hans de Goede <hdegoede@redhat.com> -Acked-by: Maxime Ripard <maxime.ripard@free-electrons.com> -Signed-off-by: Emilio López <emilio@elopez.com.ar> ---- - Documentation/devicetree/bindings/clock/sunxi.txt | 5 +++++ - drivers/clk/sunxi/clk-sunxi.c | 12 ++++++++++++ - 2 files changed, 17 insertions(+) - ---- a/Documentation/devicetree/bindings/clock/sunxi.txt -+++ b/Documentation/devicetree/bindings/clock/sunxi.txt -@@ -37,6 +37,8 @@ Required properties: - "allwinner,sun6i-a31-apb2-gates-clk" - for the APB2 gates on A31 - "allwinner,sun4i-mod0-clk" - for the module 0 family of clocks - "allwinner,sun7i-a20-out-clk" - for the external output clocks -+ "allwinner,sun4i-a10-usb-clk" - for usb gates + resets on A10 / A20 -+ "allwinner,sun5i-a13-usb-clk" - for usb gates + resets on A13 - - Required properties for all clocks: - - reg : shall be the control register address for the clock. -@@ -49,6 +51,9 @@ Required properties for all clocks: - Additionally, "allwinner,*-gates-clk" clocks require: - - clock-output-names : the corresponding gate names that the clock controls - -+And "allwinner,*-usb-clk" clocks also require: -+- reset-cells : shall be set to 1 -+ - Clock consumers should specify the desired clocks they use with a - "clocks" phandle cell. Consumers that are using a gated clock should - provide an additional ID in their clock property. This ID is the ---- a/drivers/clk/sunxi/clk-sunxi.c -+++ b/drivers/clk/sunxi/clk-sunxi.c -@@ -816,6 +816,16 @@ static const struct gates_data sun7i_a20 - .mask = { 0xff80ff }, - }; - -+static const struct gates_data sun4i_a10_usb_gates_data __initconst = { -+ .mask = {0x1C0}, -+ .reset_mask = 0x07, -+}; -+ -+static const struct gates_data sun5i_a13_usb_gates_data __initconst = { -+ .mask = {0x140}, -+ .reset_mask = 0x03, -+}; -+ - static void __init sunxi_gates_clk_setup(struct device_node *node, - struct gates_data *data) - { -@@ -1107,6 +1117,8 @@ static const struct of_device_id clk_gat - {.compatible = "allwinner,sun6i-a31-apb1-gates-clk", .data = &sun6i_a31_apb1_gates_data,}, - {.compatible = "allwinner,sun7i-a20-apb1-gates-clk", .data = &sun7i_a20_apb1_gates_data,}, - {.compatible = "allwinner,sun6i-a31-apb2-gates-clk", .data = &sun6i_a31_apb2_gates_data,}, -+ {.compatible = "allwinner,sun4i-a10-usb-clk", .data = &sun4i_a10_usb_gates_data,}, -+ {.compatible = "allwinner,sun5i-a13-usb-clk", .data = &sun5i_a13_usb_gates_data,}, - {} - }; - diff --git a/target/linux/sunxi/patches-3.14/184-clk-sunxi-add-pll6-on-a31.patch b/target/linux/sunxi/patches-3.14/184-clk-sunxi-add-pll6-on-a31.patch deleted file mode 100644 index 7193c5029b..0000000000 --- a/target/linux/sunxi/patches-3.14/184-clk-sunxi-add-pll6-on-a31.patch +++ /dev/null @@ -1,104 +0,0 @@ -From c225f78660cd61914f25dd00499c7ae71d1d6919 Mon Sep 17 00:00:00 2001 -From: Maxime Ripard <maxime.ripard@free-electrons.com> -Date: Wed, 5 Feb 2014 14:05:03 +0100 -Subject: [PATCH] clk: sunxi: Add support for PLL6 on the A31 -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -The A31 has a slightly different PLL6 clock. Add support for this new clock in -our driver. - -Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com> -Signed-off-by: Emilio López <emilio@elopez.com.ar> ---- - Documentation/devicetree/bindings/clock/sunxi.txt | 1 + - drivers/clk/sunxi/clk-sunxi.c | 45 +++++++++++++++++++++++ - 2 files changed, 46 insertions(+) - ---- a/Documentation/devicetree/bindings/clock/sunxi.txt -+++ b/Documentation/devicetree/bindings/clock/sunxi.txt -@@ -11,6 +11,7 @@ Required properties: - "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,sun6i-a31-pll6-clk" - for the PLL6 clock on A31 - "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 ---- a/drivers/clk/sunxi/clk-sunxi.c -+++ b/drivers/clk/sunxi/clk-sunxi.c -@@ -252,7 +252,38 @@ static void sun4i_get_pll5_factors(u32 * - *n = DIV_ROUND_UP(div, (*k+1)); - } - -+/** -+ * sun6i_a31_get_pll6_factors() - calculates n, k factors for A31 PLL6 -+ * PLL6 rate is calculated as follows -+ * rate = parent_rate * n * (k + 1) / 2 -+ * parent_rate is always 24Mhz -+ */ -+ -+static void sun6i_a31_get_pll6_factors(u32 *freq, u32 parent_rate, -+ u8 *n, u8 *k, u8 *m, u8 *p) -+{ -+ u8 div; -+ -+ /* -+ * We always have 24MHz / 2, so we can just say that our -+ * parent clock is 12MHz. -+ */ -+ parent_rate = parent_rate / 2; -+ -+ /* Normalize value to a parent_rate multiple (24M / 2) */ -+ div = *freq / parent_rate; -+ *freq = parent_rate * div; -+ -+ /* we were called to round the frequency, we can now return */ -+ if (n == NULL) -+ return; - -+ *k = div / 32; -+ if (*k > 3) -+ *k = 3; -+ -+ *n = DIV_ROUND_UP(div, (*k+1)); -+} - - /** - * sun4i_get_apb1_factors() - calculates m, p factors for APB1 -@@ -420,6 +451,13 @@ static struct clk_factors_config sun4i_p - .kwidth = 2, - }; - -+static struct clk_factors_config sun6i_a31_pll6_config = { -+ .nshift = 8, -+ .nwidth = 5, -+ .kshift = 4, -+ .kwidth = 2, -+}; -+ - static struct clk_factors_config sun4i_apb1_config = { - .mshift = 0, - .mwidth = 5, -@@ -469,6 +507,12 @@ static const struct factors_data sun4i_p - .name = "pll6", - }; - -+static const struct factors_data sun6i_a31_pll6_data __initconst = { -+ .enable = 31, -+ .table = &sun6i_a31_pll6_config, -+ .getter = sun6i_a31_get_pll6_factors, -+}; -+ - static const struct factors_data sun4i_apb1_data __initconst = { - .table = &sun4i_apb1_config, - .getter = sun4i_get_apb1_factors, -@@ -1069,6 +1113,7 @@ free_clkdata: - 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,sun6i-a31-pll6-clk", .data = &sun6i_a31_pll6_data,}, - {.compatible = "allwinner,sun4i-apb1-clk", .data = &sun4i_apb1_data,}, - {.compatible = "allwinner,sun4i-mod0-clk", .data = &sun4i_mod0_data,}, - {.compatible = "allwinner,sun7i-a20-out-clk", .data = &sun7i_a20_out_data,}, diff --git a/target/linux/sunxi/patches-3.14/185-clk-sunxi-add-a20-a31-gmac-clock.patch b/target/linux/sunxi/patches-3.14/185-clk-sunxi-add-a20-a31-gmac-clock.patch deleted file mode 100644 index 86d6301937..0000000000 --- a/target/linux/sunxi/patches-3.14/185-clk-sunxi-add-a20-a31-gmac-clock.patch +++ /dev/null @@ -1,175 +0,0 @@ -From dd91dc4b9c55c8fa24738249214274442e2fcbd3 Mon Sep 17 00:00:00 2001 -From: Chen-Yu Tsai <wens@csie.org> -Date: Mon, 10 Feb 2014 18:35:47 +0800 -Subject: [PATCH] clk: sunxi: Add Allwinner A20/A31 GMAC clock unit -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -The Allwinner A20/A31 clock module controls the transmit clock source -and interface type of the GMAC ethernet controller. Model this as -a single clock for GMAC drivers to use. - -Signed-off-by: Chen-Yu Tsai <wens@csie.org> -Acked-by: Maxime Ripard <maxime.ripard@free-electrons.com> -Signed-off-by: Emilio López <emilio@elopez.com.ar> ---- - Documentation/devicetree/bindings/clock/sunxi.txt | 30 +++++++ - drivers/clk/sunxi/clk-sunxi.c | 96 +++++++++++++++++++++++ - 2 files changed, 126 insertions(+) - ---- a/Documentation/devicetree/bindings/clock/sunxi.txt -+++ b/Documentation/devicetree/bindings/clock/sunxi.txt -@@ -38,6 +38,7 @@ Required properties: - "allwinner,sun6i-a31-apb2-gates-clk" - for the APB2 gates on A31 - "allwinner,sun4i-mod0-clk" - for the module 0 family of clocks - "allwinner,sun7i-a20-out-clk" - for the external output clocks -+ "allwinner,sun7i-a20-gmac-clk" - for the GMAC clock module on A20/A31 - "allwinner,sun4i-a10-usb-clk" - for usb gates + resets on A10 / A20 - "allwinner,sun5i-a13-usb-clk" - for usb gates + resets on A13 - -@@ -55,6 +56,9 @@ Additionally, "allwinner,*-gates-clk" cl - And "allwinner,*-usb-clk" clocks also require: - - reset-cells : shall be set to 1 - -+For "allwinner,sun7i-a20-gmac-clk", the parent clocks shall be fixed rate -+dummy clocks at 25 MHz and 125 MHz, respectively. See example. -+ - Clock consumers should specify the desired clocks they use with a - "clocks" phandle cell. Consumers that are using a gated clock should - provide an additional ID in their clock property. This ID is the -@@ -82,3 +86,29 @@ cpu: cpu@01c20054 { - reg = <0x01c20054 0x4>; - clocks = <&osc32k>, <&osc24M>, <&pll1>; - }; -+ -+mii_phy_tx_clk: clk@2 { -+ #clock-cells = <0>; -+ compatible = "fixed-clock"; -+ clock-frequency = <25000000>; -+ clock-output-names = "mii_phy_tx"; -+}; -+ -+gmac_int_tx_clk: clk@3 { -+ #clock-cells = <0>; -+ compatible = "fixed-clock"; -+ clock-frequency = <125000000>; -+ clock-output-names = "gmac_int_tx"; -+}; -+ -+gmac_clk: clk@01c20164 { -+ #clock-cells = <0>; -+ compatible = "allwinner,sun7i-a20-gmac-clk"; -+ reg = <0x01c20164 0x4>; -+ /* -+ * The first clock must be fixed at 25MHz; -+ * the second clock must be fixed at 125MHz -+ */ -+ clocks = <&mii_phy_tx_clk>, <&gmac_int_tx_clk>; -+ clock-output-names = "gmac"; -+}; ---- a/drivers/clk/sunxi/clk-sunxi.c -+++ b/drivers/clk/sunxi/clk-sunxi.c -@@ -411,6 +411,102 @@ static void sun7i_a20_get_out_factors(u3 - - - /** -+ * sun7i_a20_gmac_clk_setup - Setup function for A20/A31 GMAC clock module -+ * -+ * This clock looks something like this -+ * ________________________ -+ * MII TX clock from PHY >-----|___________ _________|----> to GMAC core -+ * GMAC Int. RGMII TX clk >----|___________\__/__gate---|----> to PHY -+ * Ext. 125MHz RGMII TX clk >--|__divider__/ | -+ * |________________________| -+ * -+ * The external 125 MHz reference is optional, i.e. GMAC can use its -+ * internal TX clock just fine. The A31 GMAC clock module does not have -+ * the divider controls for the external reference. -+ * -+ * To keep it simple, let the GMAC use either the MII TX clock for MII mode, -+ * and its internal TX clock for GMII and RGMII modes. The GMAC driver should -+ * select the appropriate source and gate/ungate the output to the PHY. -+ * -+ * Only the GMAC should use this clock. Altering the clock so that it doesn't -+ * match the GMAC's operation parameters will result in the GMAC not being -+ * able to send traffic out. The GMAC driver should set the clock rate and -+ * enable/disable this clock to configure the required state. The clock -+ * driver then responds by auto-reparenting the clock. -+ */ -+ -+#define SUN7I_A20_GMAC_GPIT 2 -+#define SUN7I_A20_GMAC_MASK 0x3 -+#define SUN7I_A20_GMAC_PARENTS 2 -+ -+static void __init sun7i_a20_gmac_clk_setup(struct device_node *node) -+{ -+ struct clk *clk; -+ struct clk_mux *mux; -+ struct clk_gate *gate; -+ const char *clk_name = node->name; -+ const char *parents[SUN7I_A20_GMAC_PARENTS]; -+ void *reg; -+ -+ if (of_property_read_string(node, "clock-output-names", &clk_name)) -+ return; -+ -+ /* allocate mux and gate clock structs */ -+ mux = kzalloc(sizeof(struct clk_mux), GFP_KERNEL); -+ if (!mux) -+ return; -+ -+ gate = kzalloc(sizeof(struct clk_gate), GFP_KERNEL); -+ if (!gate) -+ goto free_mux; -+ -+ /* gmac clock requires exactly 2 parents */ -+ parents[0] = of_clk_get_parent_name(node, 0); -+ parents[1] = of_clk_get_parent_name(node, 1); -+ if (!parents[0] || !parents[1]) -+ goto free_gate; -+ -+ reg = of_iomap(node, 0); -+ if (!reg) -+ goto free_gate; -+ -+ /* set up gate and fixed rate properties */ -+ gate->reg = reg; -+ gate->bit_idx = SUN7I_A20_GMAC_GPIT; -+ gate->lock = &clk_lock; -+ mux->reg = reg; -+ mux->mask = SUN7I_A20_GMAC_MASK; -+ mux->flags = CLK_MUX_INDEX_BIT; -+ mux->lock = &clk_lock; -+ -+ clk = clk_register_composite(NULL, clk_name, -+ parents, SUN7I_A20_GMAC_PARENTS, -+ &mux->hw, &clk_mux_ops, -+ NULL, NULL, -+ &gate->hw, &clk_gate_ops, -+ 0); -+ -+ if (IS_ERR(clk)) -+ goto iounmap_reg; -+ -+ of_clk_add_provider(node, of_clk_src_simple_get, clk); -+ clk_register_clkdev(clk, clk_name, NULL); -+ -+ return; -+ -+iounmap_reg: -+ iounmap(reg); -+free_gate: -+ kfree(gate); -+free_mux: -+ kfree(mux); -+} -+CLK_OF_DECLARE(sun7i_a20_gmac, "allwinner,sun7i-a20-gmac-clk", -+ sun7i_a20_gmac_clk_setup); -+ -+ -+ -+/** - * sunxi_factors_clk_setup() - Setup function for factor clocks - */ - diff --git a/target/linux/sunxi/patches-3.14/186-clk-sunxi-add-new-clock-compats.patch b/target/linux/sunxi/patches-3.14/186-clk-sunxi-add-new-clock-compats.patch deleted file mode 100644 index f842a23912..0000000000 --- a/target/linux/sunxi/patches-3.14/186-clk-sunxi-add-new-clock-compats.patch +++ /dev/null @@ -1,178 +0,0 @@ -From 45ff9697ed1668e82ca3902b32309e157464e745 Mon Sep 17 00:00:00 2001 -From: Maxime Ripard <maxime.ripard@free-electrons.com> -Date: Thu, 6 Feb 2014 09:55:57 +0100 -Subject: [PATCH] clk: sunxi: Add new clock compatibles -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -The Allwinner A10 compatibles were following a slightly different compatible -patterns than the rest of the SoCs for historical reasons. Add compatibles -matching the other pattern to the clock driver for consistency, and keep the -older one for backward compatibility. - -Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com> -Signed-off-by: Emilio López <emilio@elopez.com.ar> ---- - Documentation/devicetree/bindings/clock/sunxi.txt | 36 +++++++++++------------ - drivers/clk/sunxi/clk-sunxi.c | 30 +++++++++---------- - 2 files changed, 33 insertions(+), 33 deletions(-) - ---- a/Documentation/devicetree/bindings/clock/sunxi.txt -+++ b/Documentation/devicetree/bindings/clock/sunxi.txt -@@ -6,37 +6,37 @@ This binding uses the common clock bindi - - 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 and PLL4 -+ "allwinner,sun4i-a10-osc-clk" - for a gatable oscillator -+ "allwinner,sun4i-a10-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-a10-pll5-clk" - for the PLL5 clock -+ "allwinner,sun4i-a10-pll6-clk" - for the PLL6 clock - "allwinner,sun6i-a31-pll6-clk" - for the PLL6 clock on A31 -- "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 -- "allwinner,sun4i-ahb-clk" - for the AHB clock -- "allwinner,sun4i-ahb-gates-clk" - for the AHB gates on A10 -+ "allwinner,sun4i-a10-cpu-clk" - for the CPU multiplexer clock -+ "allwinner,sun4i-a10-axi-clk" - for the AXI clock -+ "allwinner,sun4i-a10-axi-gates-clk" - for the AXI gates -+ "allwinner,sun4i-a10-ahb-clk" - for the AHB clock -+ "allwinner,sun4i-a10-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 - "allwinner,sun7i-a20-ahb-gates-clk" - for the AHB gates on A20 - "allwinner,sun6i-a31-ahb1-mux-clk" - for the AHB1 multiplexer on A31 - "allwinner,sun6i-a31-ahb1-gates-clk" - for the AHB1 gates on A31 -- "allwinner,sun4i-apb0-clk" - for the APB0 clock -- "allwinner,sun4i-apb0-gates-clk" - for the APB0 gates on A10 -+ "allwinner,sun4i-a10-apb0-clk" - for the APB0 clock -+ "allwinner,sun4i-a10-apb0-gates-clk" - for the APB0 gates on A10 - "allwinner,sun5i-a13-apb0-gates-clk" - for the APB0 gates on A13 - "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,sun4i-a10-apb1-clk" - for the APB1 clock -+ "allwinner,sun4i-a10-apb1-mux-clk" - for the APB1 clock muxing -+ "allwinner,sun4i-a10-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 - "allwinner,sun6i-a31-apb1-gates-clk" - for the APB1 gates on A31 - "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 -+ "allwinner,sun4i-a10-mod0-clk" - for the module 0 family of clocks - "allwinner,sun7i-a20-out-clk" - for the external output clocks - "allwinner,sun7i-a20-gmac-clk" - for the GMAC clock module on A20/A31 - "allwinner,sun4i-a10-usb-clk" - for usb gates + resets on A10 / A20 -@@ -68,21 +68,21 @@ For example: - - osc24M: osc24M@01c20050 { - #clock-cells = <0>; -- compatible = "allwinner,sun4i-osc-clk"; -+ compatible = "allwinner,sun4i-a10-osc-clk"; - reg = <0x01c20050 0x4>; - clocks = <&osc24M_fixed>; - }; - - pll1: pll1@01c20000 { - #clock-cells = <0>; -- compatible = "allwinner,sun4i-pll1-clk"; -+ compatible = "allwinner,sun4i-a10-pll1-clk"; - reg = <0x01c20000 0x4>; - clocks = <&osc24M>; - }; - - cpu: cpu@01c20054 { - #clock-cells = <0>; -- compatible = "allwinner,sun4i-cpu-clk"; -+ compatible = "allwinner,sun4i-a10-cpu-clk"; - reg = <0x01c20054 0x4>; - clocks = <&osc32k>, <&osc24M>, <&pll1>; - }; ---- a/drivers/clk/sunxi/clk-sunxi.c -+++ b/drivers/clk/sunxi/clk-sunxi.c -@@ -80,7 +80,7 @@ err_free_gate: - err_free_fixed: - kfree(fixed); - } --CLK_OF_DECLARE(sun4i_osc, "allwinner,sun4i-osc-clk", sun4i_osc_clk_setup); -+CLK_OF_DECLARE(sun4i_osc, "allwinner,sun4i-a10-osc-clk", sun4i_osc_clk_setup); - - - -@@ -1207,52 +1207,52 @@ free_clkdata: - - /* Matches for factors clocks */ - static const struct of_device_id clk_factors_match[] __initconst = { -- {.compatible = "allwinner,sun4i-pll1-clk", .data = &sun4i_pll1_data,}, -+ {.compatible = "allwinner,sun4i-a10-pll1-clk", .data = &sun4i_pll1_data,}, - {.compatible = "allwinner,sun6i-a31-pll1-clk", .data = &sun6i_a31_pll1_data,}, - {.compatible = "allwinner,sun6i-a31-pll6-clk", .data = &sun6i_a31_pll6_data,}, -- {.compatible = "allwinner,sun4i-apb1-clk", .data = &sun4i_apb1_data,}, -- {.compatible = "allwinner,sun4i-mod0-clk", .data = &sun4i_mod0_data,}, -+ {.compatible = "allwinner,sun4i-a10-apb1-clk", .data = &sun4i_apb1_data,}, -+ {.compatible = "allwinner,sun4i-a10-mod0-clk", .data = &sun4i_mod0_data,}, - {.compatible = "allwinner,sun7i-a20-out-clk", .data = &sun7i_a20_out_data,}, - {} - }; - - /* Matches for divider clocks */ - static const struct of_device_id clk_div_match[] __initconst = { -- {.compatible = "allwinner,sun4i-axi-clk", .data = &sun4i_axi_data,}, -- {.compatible = "allwinner,sun4i-ahb-clk", .data = &sun4i_ahb_data,}, -- {.compatible = "allwinner,sun4i-apb0-clk", .data = &sun4i_apb0_data,}, -+ {.compatible = "allwinner,sun4i-a10-axi-clk", .data = &sun4i_axi_data,}, -+ {.compatible = "allwinner,sun4i-a10-ahb-clk", .data = &sun4i_ahb_data,}, -+ {.compatible = "allwinner,sun4i-a10-apb0-clk", .data = &sun4i_apb0_data,}, - {.compatible = "allwinner,sun6i-a31-apb2-div-clk", .data = &sun6i_a31_apb2_div_data,}, - {} - }; - - /* 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,}, -+ {.compatible = "allwinner,sun4i-a10-pll5-clk", .data = &pll5_divs_data,}, -+ {.compatible = "allwinner,sun4i-a10-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,}, -- {.compatible = "allwinner,sun4i-apb1-mux-clk", .data = &sun4i_apb1_mux_data,}, -+ {.compatible = "allwinner,sun4i-a10-cpu-clk", .data = &sun4i_cpu_mux_data,}, -+ {.compatible = "allwinner,sun4i-a10-apb1-mux-clk", .data = &sun4i_apb1_mux_data,}, - {.compatible = "allwinner,sun6i-a31-ahb1-mux-clk", .data = &sun6i_a31_ahb1_mux_data,}, - {} - }; - - /* Matches for gate clocks */ - 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,sun4i-a10-axi-gates-clk", .data = &sun4i_axi_gates_data,}, -+ {.compatible = "allwinner,sun4i-a10-ahb-gates-clk", .data = &sun4i_ahb_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,}, - {.compatible = "allwinner,sun7i-a20-ahb-gates-clk", .data = &sun7i_a20_ahb_gates_data,}, -- {.compatible = "allwinner,sun4i-apb0-gates-clk", .data = &sun4i_apb0_gates_data,}, -+ {.compatible = "allwinner,sun4i-a10-apb0-gates-clk", .data = &sun4i_apb0_gates_data,}, - {.compatible = "allwinner,sun5i-a10s-apb0-gates-clk", .data = &sun5i_a10s_apb0_gates_data,}, - {.compatible = "allwinner,sun5i-a13-apb0-gates-clk", .data = &sun5i_a13_apb0_gates_data,}, - {.compatible = "allwinner,sun7i-a20-apb0-gates-clk", .data = &sun7i_a20_apb0_gates_data,}, -- {.compatible = "allwinner,sun4i-apb1-gates-clk", .data = &sun4i_apb1_gates_data,}, -+ {.compatible = "allwinner,sun4i-a10-apb1-gates-clk", .data = &sun4i_apb1_gates_data,}, - {.compatible = "allwinner,sun5i-a10s-apb1-gates-clk", .data = &sun5i_a10s_apb1_gates_data,}, - {.compatible = "allwinner,sun5i-a13-apb1-gates-clk", .data = &sun5i_a13_apb1_gates_data,}, - {.compatible = "allwinner,sun6i-a31-apb1-gates-clk", .data = &sun6i_a31_apb1_gates_data,}, diff --git a/target/linux/sunxi/patches-3.14/187-clk-sunxi-automatic-reparenting.patch b/target/linux/sunxi/patches-3.14/187-clk-sunxi-automatic-reparenting.patch deleted file mode 100644 index 2cd8a263be..0000000000 --- a/target/linux/sunxi/patches-3.14/187-clk-sunxi-automatic-reparenting.patch +++ /dev/null @@ -1,68 +0,0 @@ -From b416520f239aeaa4207ebe84c22247cff2da444f 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(+) - ---- a/drivers/clk/sunxi/clk-factors.c -+++ b/drivers/clk/sunxi/clk-factors.c -@@ -77,6 +77,41 @@ static long clk_factors_round_rate(struc - 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 c - } - - 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, diff --git a/target/linux/sunxi/patches-3.14/188-clk-sunxi-implement-mmc-phasectrl.patch b/target/linux/sunxi/patches-3.14/188-clk-sunxi-implement-mmc-phasectrl.patch deleted file mode 100644 index c191b350f8..0000000000 --- a/target/linux/sunxi/patches-3.14/188-clk-sunxi-implement-mmc-phasectrl.patch +++ /dev/null @@ -1,87 +0,0 @@ -From 36268d704307282109ec246f65cac2a42c825629 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 - -HdG: add header exporting clk_sunxi_mmc_phase_control - -Signed-off-by: Emilio López <emilio@elopez.com.ar> -Signed-off-by: Hans de Goede <hdegoede@redhat.com> ---- - drivers/clk/sunxi/clk-sunxi.c | 35 +++++++++++++++++++++++++++++++++++ - include/linux/clk/sunxi.h | 22 ++++++++++++++++++++++ - 2 files changed, 57 insertions(+) - create mode 100644 include/linux/clk/sunxi.h - ---- a/drivers/clk/sunxi/clk-sunxi.c -+++ b/drivers/clk/sunxi/clk-sunxi.c -@@ -507,6 +507,41 @@ CLK_OF_DECLARE(sun7i_a20_gmac, "allwinne - - - /** -+ * 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 - */ - ---- /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 diff --git a/target/linux/sunxi/patches-3.14/190-ahci-libahci-changes.patch b/target/linux/sunxi/patches-3.14/190-ahci-libahci-changes.patch deleted file mode 100644 index c4d918d5da..0000000000 --- a/target/linux/sunxi/patches-3.14/190-ahci-libahci-changes.patch +++ /dev/null @@ -1,872 +0,0 @@ -From 3b5db9d024f173c30ef4060c31bb8e9fbd194cc1 Mon Sep 17 00:00:00 2001 -From: Hans de Goede <hdegoede@redhat.com> -Date: Mon, 2 Dec 2013 16:13:32 +0100 -Subject: [PATCH] libahci: Allow drivers to override start_engine - -Allwinner A10 and A20 ARM SoCs have an AHCI sata controller which needs a -special register to be poked before starting the DMA engine. - -This register gets reset on an ahci_stop_engine call, so there is no other -place then ahci_start_engine where this poking can be done. - -This commit allows drivers to override ahci_start_engine behavior for use by -the Allwinner AHCI driver (and potentially other drivers in the future). - -Signed-off-by: Hans de Goede <hdegoede@redhat.com> ---- - drivers/ata/ahci.c | 6 ++++-- - drivers/ata/ahci.h | 6 ++++++ - drivers/ata/libahci.c | 26 +++++++++++++++++++------- - drivers/ata/sata_highbank.c | 3 ++- - 4 files changed, 31 insertions(+), 10 deletions(-) - ---- a/drivers/ata/ahci.c -+++ b/drivers/ata/ahci.c -@@ -606,6 +606,7 @@ static int ahci_vt8251_hardreset(struct - unsigned long deadline) - { - struct ata_port *ap = link->ap; -+ struct ahci_host_priv *hpriv = ap->host->private_data; - bool online; - int rc; - -@@ -616,7 +617,7 @@ static int ahci_vt8251_hardreset(struct - rc = sata_link_hardreset(link, sata_ehc_deb_timing(&link->eh_context), - deadline, &online, NULL); - -- ahci_start_engine(ap); -+ hpriv->start_engine(ap); - - DPRINTK("EXIT, rc=%d, class=%u\n", rc, *class); - -@@ -631,6 +632,7 @@ static int ahci_p5wdh_hardreset(struct a - { - struct ata_port *ap = link->ap; - struct ahci_port_priv *pp = ap->private_data; -+ struct ahci_host_priv *hpriv = ap->host->private_data; - u8 *d2h_fis = pp->rx_fis + RX_FIS_D2H_REG; - struct ata_taskfile tf; - bool online; -@@ -646,7 +648,7 @@ static int ahci_p5wdh_hardreset(struct a - rc = sata_link_hardreset(link, sata_ehc_deb_timing(&link->eh_context), - deadline, &online, NULL); - -- ahci_start_engine(ap); -+ hpriv->start_engine(ap); - - /* The pseudo configuration device on SIMG4726 attached to - * ASUS P5W-DH Deluxe doesn't send signature FIS after ---- a/drivers/ata/ahci.h -+++ b/drivers/ata/ahci.h -@@ -37,6 +37,7 @@ - - #include <linux/clk.h> - #include <linux/libata.h> -+#include <linux/regulator/consumer.h> - - /* Enclosure Management Control */ - #define EM_CTRL_MSG_TYPE 0x000f0000 -@@ -51,6 +52,7 @@ - - enum { - AHCI_MAX_PORTS = 32, -+ AHCI_MAX_CLKS = 3, - AHCI_MAX_SG = 168, /* hardware max is 64K */ - AHCI_DMA_BOUNDARY = 0xffffffff, - AHCI_MAX_CMDS = 32, -@@ -322,8 +324,15 @@ struct ahci_host_priv { - u32 em_loc; /* enclosure management location */ - u32 em_buf_sz; /* EM buffer size in byte */ - u32 em_msg_type; /* EM message type */ -- struct clk *clk; /* Only for platforms supporting clk */ -+ struct clk *clks[AHCI_MAX_CLKS]; /* Optional */ -+ struct regulator *target_pwr; /* Optional */ - void *plat_data; /* Other platform data */ -+ /* -+ * Optional ahci_start_engine override, if not set this gets set to the -+ * default ahci_start_engine during ahci_save_initial_config, this can -+ * be overridden anytime before the host is activated. -+ */ -+ void (*start_engine)(struct ata_port *ap); - }; - - extern int ahci_ignore_sss; ---- a/drivers/ata/libahci.c -+++ b/drivers/ata/libahci.c -@@ -394,6 +394,9 @@ static ssize_t ahci_show_em_supported(st - * - * If inconsistent, config values are fixed up by this function. - * -+ * If it is not set already this function sets hpriv->start_engine to -+ * ahci_start_engine. -+ * - * LOCKING: - * None. - */ -@@ -500,6 +503,9 @@ void ahci_save_initial_config(struct dev - hpriv->cap = cap; - hpriv->cap2 = cap2; - hpriv->port_map = port_map; -+ -+ if (!hpriv->start_engine) -+ hpriv->start_engine = ahci_start_engine; - } - EXPORT_SYMBOL_GPL(ahci_save_initial_config); - -@@ -766,7 +772,7 @@ static void ahci_start_port(struct ata_p - - /* enable DMA */ - if (!(hpriv->flags & AHCI_HFLAG_DELAY_ENGINE)) -- ahci_start_engine(ap); -+ hpriv->start_engine(ap); - - /* turn on LEDs */ - if (ap->flags & ATA_FLAG_EM) { -@@ -1234,7 +1240,7 @@ int ahci_kick_engine(struct ata_port *ap - - /* restart engine */ - out_restart: -- ahci_start_engine(ap); -+ hpriv->start_engine(ap); - return rc; - } - EXPORT_SYMBOL_GPL(ahci_kick_engine); -@@ -1426,6 +1432,7 @@ static int ahci_hardreset(struct ata_lin - const unsigned long *timing = sata_ehc_deb_timing(&link->eh_context); - struct ata_port *ap = link->ap; - struct ahci_port_priv *pp = ap->private_data; -+ struct ahci_host_priv *hpriv = ap->host->private_data; - u8 *d2h_fis = pp->rx_fis + RX_FIS_D2H_REG; - struct ata_taskfile tf; - bool online; -@@ -1443,7 +1450,7 @@ static int ahci_hardreset(struct ata_lin - rc = sata_link_hardreset(link, timing, deadline, &online, - ahci_check_ready); - -- ahci_start_engine(ap); -+ hpriv->start_engine(ap); - - if (online) - *class = ahci_dev_classify(ap); -@@ -2007,10 +2014,12 @@ static void ahci_thaw(struct ata_port *a - - void ahci_error_handler(struct ata_port *ap) - { -+ struct ahci_host_priv *hpriv = ap->host->private_data; -+ - if (!(ap->pflags & ATA_PFLAG_FROZEN)) { - /* restart engine */ - ahci_stop_engine(ap); -- ahci_start_engine(ap); -+ hpriv->start_engine(ap); - } - - sata_pmp_error_handler(ap); -@@ -2031,6 +2040,7 @@ static void ahci_post_internal_cmd(struc - - static void ahci_set_aggressive_devslp(struct ata_port *ap, bool sleep) - { -+ struct ahci_host_priv *hpriv = ap->host->private_data; - void __iomem *port_mmio = ahci_port_base(ap); - struct ata_device *dev = ap->link.device; - u32 devslp, dm, dito, mdat, deto; -@@ -2094,7 +2104,7 @@ static void ahci_set_aggressive_devslp(s - PORT_DEVSLP_ADSE); - writel(devslp, port_mmio + PORT_DEVSLP); - -- ahci_start_engine(ap); -+ hpriv->start_engine(ap); - - /* enable device sleep feature for the drive */ - err_mask = ata_dev_set_feature(dev, -@@ -2106,6 +2116,7 @@ static void ahci_set_aggressive_devslp(s - - static void ahci_enable_fbs(struct ata_port *ap) - { -+ struct ahci_host_priv *hpriv = ap->host->private_data; - struct ahci_port_priv *pp = ap->private_data; - void __iomem *port_mmio = ahci_port_base(ap); - u32 fbs; -@@ -2134,11 +2145,12 @@ static void ahci_enable_fbs(struct ata_p - } else - dev_err(ap->host->dev, "Failed to enable FBS\n"); - -- ahci_start_engine(ap); -+ hpriv->start_engine(ap); - } - - static void ahci_disable_fbs(struct ata_port *ap) - { -+ struct ahci_host_priv *hpriv = ap->host->private_data; - struct ahci_port_priv *pp = ap->private_data; - void __iomem *port_mmio = ahci_port_base(ap); - u32 fbs; -@@ -2166,7 +2178,7 @@ static void ahci_disable_fbs(struct ata_ - pp->fbs_enabled = false; - } - -- ahci_start_engine(ap); -+ hpriv->start_engine(ap); - } - - static void ahci_pmp_attach(struct ata_port *ap) ---- a/drivers/ata/sata_highbank.c -+++ b/drivers/ata/sata_highbank.c -@@ -403,6 +403,7 @@ static int ahci_highbank_hardreset(struc - static const unsigned long timing[] = { 5, 100, 500}; - struct ata_port *ap = link->ap; - struct ahci_port_priv *pp = ap->private_data; -+ struct ahci_host_priv *hpriv = ap->host->private_data; - u8 *d2h_fis = pp->rx_fis + RX_FIS_D2H_REG; - struct ata_taskfile tf; - bool online; -@@ -431,7 +432,7 @@ static int ahci_highbank_hardreset(struc - break; - } while (!online && retry--); - -- ahci_start_engine(ap); -+ hpriv->start_engine(ap); - - if (online) - *class = ahci_dev_classify(ap); ---- a/Documentation/devicetree/bindings/ata/ahci-platform.txt -+++ b/Documentation/devicetree/bindings/ata/ahci-platform.txt -@@ -10,6 +10,8 @@ Required properties: - - Optional properties: - - dma-coherent : Present if dma operations are coherent -+- clocks : a list of phandle + clock specifier pairs -+- target-supply : regulator for SATA target power - - Example: - sata@ffe08000 { ---- a/drivers/ata/ahci_platform.c -+++ b/drivers/ata/ahci_platform.c -@@ -87,78 +87,252 @@ static struct scsi_host_template ahci_pl - AHCI_SHT("ahci_platform"), - }; - --static int ahci_probe(struct platform_device *pdev) -+/** -+ * ahci_platform_enable_clks - Enable platform clocks -+ * @hpriv: host private area to store config values -+ * -+ * This function enables all the clks found in hpriv->clks, starting -+ * at index 0. If any clk fails to enable it disables all the clks -+ * already enabled in reverse order, and then returns an error. -+ * -+ * LOCKING: -+ * None. -+ * -+ * RETURNS: -+ * 0 on success otherwise a negative error code -+ */ -+int ahci_platform_enable_clks(struct ahci_host_priv *hpriv) - { -- struct device *dev = &pdev->dev; -- struct ahci_platform_data *pdata = dev_get_platdata(dev); -- const struct platform_device_id *id = platform_get_device_id(pdev); -- struct ata_port_info pi = ahci_port_info[id ? id->driver_data : 0]; -- const struct ata_port_info *ppi[] = { &pi, NULL }; -- struct ahci_host_priv *hpriv; -- struct ata_host *host; -- struct resource *mem; -- int irq; -- int n_ports; -- int i; -- int rc; -+ int c, rc; - -- mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); -- if (!mem) { -- dev_err(dev, "no mmio space\n"); -- return -EINVAL; -+ for (c = 0; c < AHCI_MAX_CLKS && hpriv->clks[c]; c++) { -+ rc = clk_prepare_enable(hpriv->clks[c]); -+ if (rc) -+ goto disable_unprepare_clk; - } -+ return 0; - -- irq = platform_get_irq(pdev, 0); -- if (irq <= 0) { -- dev_err(dev, "no irq\n"); -- return -EINVAL; -- } -+disable_unprepare_clk: -+ while (--c >= 0) -+ clk_disable_unprepare(hpriv->clks[c]); -+ return rc; -+} -+EXPORT_SYMBOL_GPL(ahci_platform_enable_clks); - -- if (pdata && pdata->ata_port_info) -- pi = *pdata->ata_port_info; -+/** -+ * ahci_platform_disable_clks - Disable platform clocks -+ * @hpriv: host private area to store config values -+ * -+ * This function disables all the clks found in hpriv->clks, in reverse -+ * order of ahci_platform_enable_clks (starting at the end of the array). -+ * -+ * LOCKING: -+ * None. -+ */ -+void ahci_platform_disable_clks(struct ahci_host_priv *hpriv) -+{ -+ int c; - -- hpriv = devm_kzalloc(dev, sizeof(*hpriv), GFP_KERNEL); -- if (!hpriv) { -- dev_err(dev, "can't alloc ahci_host_priv\n"); -- return -ENOMEM; -+ for (c = AHCI_MAX_CLKS - 1; c >= 0; c--) -+ if (hpriv->clks[c]) -+ clk_disable_unprepare(hpriv->clks[c]); -+} -+EXPORT_SYMBOL_GPL(ahci_platform_disable_clks); -+ -+/** -+ * ahci_platform_enable_resources - Enable platform resources -+ * @hpriv: host private area to store config values -+ * -+ * This function enables all ahci_platform managed resources in -+ * the following order: -+ * 1) Regulator -+ * 2) Clocks (through ahci_platform_enable_clks) -+ * -+ * If resource enabling fails at any point the previous enabled -+ * resources are disabled in reverse order. -+ * -+ * LOCKING: -+ * None. -+ * -+ * RETURNS: -+ * 0 on success otherwise a negative error code -+ */ -+int ahci_platform_enable_resources(struct ahci_host_priv *hpriv) -+{ -+ int rc; -+ -+ if (hpriv->target_pwr) { -+ rc = regulator_enable(hpriv->target_pwr); -+ if (rc) -+ return rc; - } - -- hpriv->flags |= (unsigned long)pi.private_data; -+ rc = ahci_platform_enable_clks(hpriv); -+ if (rc) -+ goto disable_regulator; -+ -+ return 0; -+ -+disable_regulator: -+ if (hpriv->target_pwr) -+ regulator_disable(hpriv->target_pwr); -+ return rc; -+} -+EXPORT_SYMBOL_GPL(ahci_platform_enable_resources); -+ -+/** -+ * ahci_platform_disable_resources - Disable platform resources -+ * @hpriv: host private area to store config values -+ * -+ * This function disables all ahci_platform managed resources in -+ * the following order: -+ * 1) Clocks (through ahci_platform_disable_clks) -+ * 2) Regulator -+ * -+ * LOCKING: -+ * None. -+ */ -+void ahci_platform_disable_resources(struct ahci_host_priv *hpriv) -+{ -+ ahci_platform_disable_clks(hpriv); - -- hpriv->mmio = devm_ioremap(dev, mem->start, resource_size(mem)); -+ if (hpriv->target_pwr) -+ regulator_disable(hpriv->target_pwr); -+} -+EXPORT_SYMBOL_GPL(ahci_platform_disable_resources); -+ -+static void ahci_platform_put_resources(struct device *dev, void *res) -+{ -+ struct ahci_host_priv *hpriv = res; -+ int c; -+ -+ for (c = 0; c < AHCI_MAX_CLKS && hpriv->clks[c]; c++) -+ clk_put(hpriv->clks[c]); -+} -+ -+/** -+ * ahci_platform_get_resources - Get platform resources -+ * @pdev: platform device to get resources for -+ * -+ * This function allocates an ahci_host_priv struct, and gets the -+ * following resources, storing a reference to them inside the returned -+ * struct: -+ * -+ * 1) mmio registers (IORESOURCE_MEM 0, mandatory) -+ * 2) regulator for controlling the targets power (optional) -+ * 3) 0 - AHCI_MAX_CLKS clocks, as specified in the devs devicetree node, -+ * or for non devicetree enabled platforms a single clock -+ * -+ * LOCKING: -+ * None. -+ * -+ * RETURNS: -+ * The allocated ahci_host_priv on success, otherwise an ERR_PTR value -+ */ -+struct ahci_host_priv *ahci_platform_get_resources( -+ struct platform_device *pdev) -+{ -+ struct device *dev = &pdev->dev; -+ struct ahci_host_priv *hpriv; -+ struct clk *clk; -+ int i, rc = -ENOMEM; -+ -+ if (!devres_open_group(dev, NULL, GFP_KERNEL)) -+ return ERR_PTR(-ENOMEM); -+ -+ hpriv = devres_alloc(ahci_platform_put_resources, sizeof(*hpriv), -+ GFP_KERNEL); -+ if (!hpriv) -+ goto err_out; -+ -+ devres_add(dev, hpriv); -+ -+ hpriv->mmio = devm_ioremap_resource(dev, -+ platform_get_resource(pdev, IORESOURCE_MEM, 0)); - if (!hpriv->mmio) { -- dev_err(dev, "can't map %pR\n", mem); -- return -ENOMEM; -+ dev_err(dev, "no mmio space\n"); -+ goto err_out; - } - -- hpriv->clk = clk_get(dev, NULL); -- if (IS_ERR(hpriv->clk)) { -- dev_err(dev, "can't get clock\n"); -- } else { -- rc = clk_prepare_enable(hpriv->clk); -- if (rc) { -- dev_err(dev, "clock prepare enable failed"); -- goto free_clk; -+ hpriv->target_pwr = devm_regulator_get_optional(dev, "target"); -+ if (IS_ERR(hpriv->target_pwr)) { -+ rc = PTR_ERR(hpriv->target_pwr); -+ if (rc == -EPROBE_DEFER) -+ goto err_out; -+ hpriv->target_pwr = NULL; -+ } -+ -+ for (i = 0; i < AHCI_MAX_CLKS; i++) { -+ /* -+ * For now we must use clk_get(dev, NULL) for the first clock, -+ * because some platforms (da850, spear13xx) are not yet -+ * converted to use devicetree for clocks. For new platforms -+ * this is equivalent to of_clk_get(dev->of_node, 0). -+ */ -+ if (i == 0) -+ clk = clk_get(dev, NULL); -+ else -+ clk = of_clk_get(dev->of_node, i); -+ -+ if (IS_ERR(clk)) { -+ rc = PTR_ERR(clk); -+ if (rc == -EPROBE_DEFER) -+ goto err_out; -+ break; - } -+ hpriv->clks[i] = clk; - } - -- /* -- * Some platforms might need to prepare for mmio region access, -- * which could be done in the following init call. So, the mmio -- * region shouldn't be accessed before init (if provided) has -- * returned successfully. -- */ -- if (pdata && pdata->init) { -- rc = pdata->init(dev, hpriv->mmio); -- if (rc) -- goto disable_unprepare_clk; -- } -+ devres_remove_group(dev, NULL); -+ return hpriv; -+ -+err_out: -+ devres_release_group(dev, NULL); -+ return ERR_PTR(rc); -+} -+EXPORT_SYMBOL_GPL(ahci_platform_get_resources); -+ -+/** -+ * ahci_platform_init_host - Bring up an ahci-platform host -+ * @pdev: platform device pointer for the host -+ * @hpriv: ahci-host private data for the host -+ * @pi_template: template for the ata_port_info to use -+ * @force_port_map: param passed to ahci_save_initial_config -+ * @mask_port_map: param passed to ahci_save_initial_config -+ * -+ * This function does all the usual steps needed to bring up an -+ * ahci-platform host, note any necessary resources (ie clks, phy, etc.) -+ * must be initialized / enabled before calling this. -+ * -+ * LOCKING: -+ * None. -+ * -+ * RETURNS: -+ * 0 on success otherwise a negative error code -+ */ -+int ahci_platform_init_host(struct platform_device *pdev, -+ struct ahci_host_priv *hpriv, -+ const struct ata_port_info *pi_template, -+ unsigned int force_port_map, -+ unsigned int mask_port_map) -+{ -+ struct device *dev = &pdev->dev; -+ struct ata_port_info pi = *pi_template; -+ const struct ata_port_info *ppi[] = { &pi, NULL }; -+ struct ata_host *host; -+ int i, irq, n_ports, rc; - -- ahci_save_initial_config(dev, hpriv, -- pdata ? pdata->force_port_map : 0, -- pdata ? pdata->mask_port_map : 0); -+ irq = platform_get_irq(pdev, 0); -+ if (irq <= 0) { -+ dev_err(dev, "no irq\n"); -+ return -EINVAL; -+ } - - /* prepare host */ -+ hpriv->flags |= (unsigned long)pi.private_data; -+ -+ ahci_save_initial_config(dev, hpriv, force_port_map, mask_port_map); -+ - if (hpriv->cap & HOST_CAP_NCQ) - pi.flags |= ATA_FLAG_NCQ; - -@@ -175,10 +349,8 @@ static int ahci_probe(struct platform_de - n_ports = max(ahci_nr_ports(hpriv->cap), fls(hpriv->port_map)); - - host = ata_host_alloc_pinfo(dev, ppi, n_ports); -- if (!host) { -- rc = -ENOMEM; -- goto pdata_exit; -- } -+ if (!host) -+ return -ENOMEM; - - host->private_data = hpriv; - -@@ -193,7 +365,8 @@ static int ahci_probe(struct platform_de - for (i = 0; i < host->n_ports; i++) { - struct ata_port *ap = host->ports[i]; - -- ata_port_desc(ap, "mmio %pR", mem); -+ ata_port_desc(ap, "mmio %pR", -+ platform_get_resource(pdev, IORESOURCE_MEM, 0)); - ata_port_desc(ap, "port 0x%x", 0x100 + ap->port_no * 0x80); - - /* set enclosure management message type */ -@@ -207,13 +380,53 @@ static int ahci_probe(struct platform_de - - rc = ahci_reset_controller(host); - if (rc) -- goto pdata_exit; -+ return rc; - - ahci_init_controller(host); - ahci_print_info(host, "platform"); - -- rc = ata_host_activate(host, irq, ahci_interrupt, IRQF_SHARED, -- &ahci_platform_sht); -+ return ata_host_activate(host, irq, ahci_interrupt, IRQF_SHARED, -+ &ahci_platform_sht); -+} -+EXPORT_SYMBOL_GPL(ahci_platform_init_host); -+ -+static int ahci_probe(struct platform_device *pdev) -+{ -+ struct device *dev = &pdev->dev; -+ struct ahci_platform_data *pdata = dev_get_platdata(dev); -+ const struct platform_device_id *id = platform_get_device_id(pdev); -+ const struct ata_port_info *pi_template; -+ struct ahci_host_priv *hpriv; -+ int rc; -+ -+ hpriv = ahci_platform_get_resources(pdev); -+ if (IS_ERR(hpriv)) -+ return PTR_ERR(hpriv); -+ -+ rc = ahci_platform_enable_resources(hpriv); -+ if (rc) -+ return rc; -+ -+ /* -+ * Some platforms might need to prepare for mmio region access, -+ * which could be done in the following init call. So, the mmio -+ * region shouldn't be accessed before init (if provided) has -+ * returned successfully. -+ */ -+ if (pdata && pdata->init) { -+ rc = pdata->init(dev, hpriv->mmio); -+ if (rc) -+ goto disable_resources; -+ } -+ -+ if (pdata && pdata->ata_port_info) -+ pi_template = pdata->ata_port_info; -+ else -+ pi_template = &ahci_port_info[id ? id->driver_data : 0]; -+ -+ rc = ahci_platform_init_host(pdev, hpriv, pi_template, -+ pdata ? pdata->force_port_map : 0, -+ pdata ? pdata->mask_port_map : 0); - if (rc) - goto pdata_exit; - -@@ -221,12 +434,8 @@ static int ahci_probe(struct platform_de - pdata_exit: - if (pdata && pdata->exit) - pdata->exit(dev); --disable_unprepare_clk: -- if (!IS_ERR(hpriv->clk)) -- clk_disable_unprepare(hpriv->clk); --free_clk: -- if (!IS_ERR(hpriv->clk)) -- clk_put(hpriv->clk); -+disable_resources: -+ ahci_platform_disable_resources(hpriv); - return rc; - } - -@@ -239,21 +448,30 @@ static void ahci_host_stop(struct ata_ho - if (pdata && pdata->exit) - pdata->exit(dev); - -- if (!IS_ERR(hpriv->clk)) { -- clk_disable_unprepare(hpriv->clk); -- clk_put(hpriv->clk); -- } -+ ahci_platform_disable_resources(hpriv); - } - - #ifdef CONFIG_PM_SLEEP --static int ahci_suspend(struct device *dev) -+/** -+ * ahci_platform_suspend_host - Suspend an ahci-platform host -+ * @dev: device pointer for the host -+ * -+ * This function does all the usual steps needed to suspend an -+ * ahci-platform host, note any necessary resources (ie clks, phy, etc.) -+ * must be disabled after calling this. -+ * -+ * LOCKING: -+ * None. -+ * -+ * RETURNS: -+ * 0 on success otherwise a negative error code -+ */ -+int ahci_platform_suspend_host(struct device *dev) - { -- struct ahci_platform_data *pdata = dev_get_platdata(dev); - struct ata_host *host = dev_get_drvdata(dev); - struct ahci_host_priv *hpriv = host->private_data; - void __iomem *mmio = hpriv->mmio; - u32 ctl; -- int rc; - - if (hpriv->flags & AHCI_HFLAG_NO_SUSPEND) { - dev_err(dev, "firmware update required for suspend/resume\n"); -@@ -270,61 +488,122 @@ static int ahci_suspend(struct device *d - writel(ctl, mmio + HOST_CTL); - readl(mmio + HOST_CTL); /* flush */ - -- rc = ata_host_suspend(host, PMSG_SUSPEND); -+ return ata_host_suspend(host, PMSG_SUSPEND); -+} -+EXPORT_SYMBOL_GPL(ahci_platform_suspend_host); -+ -+/** -+ * ahci_platform_resume_host - Resume an ahci-platform host -+ * @dev: device pointer for the host -+ * -+ * This function does all the usual steps needed to resume an -+ * ahci-platform host, note any necessary resources (ie clks, phy, etc.) -+ * must be initialized / enabled before calling this. -+ * -+ * LOCKING: -+ * None. -+ * -+ * RETURNS: -+ * 0 on success otherwise a negative error code -+ */ -+int ahci_platform_resume_host(struct device *dev) -+{ -+ struct ata_host *host = dev_get_drvdata(dev); -+ int rc; -+ -+ if (dev->power.power_state.event == PM_EVENT_SUSPEND) { -+ rc = ahci_reset_controller(host); -+ if (rc) -+ return rc; -+ -+ ahci_init_controller(host); -+ } -+ -+ ata_host_resume(host); -+ -+ return 0; -+} -+EXPORT_SYMBOL_GPL(ahci_platform_resume_host); -+ -+/** -+ * ahci_platform_suspend - Suspend an ahci-platform device -+ * @dev: the platform device to suspend -+ * -+ * This function suspends the host associated with the device, followed -+ * by disabling all the resources of the device. -+ * -+ * LOCKING: -+ * None. -+ * -+ * RETURNS: -+ * 0 on success otherwise a negative error code -+ */ -+int ahci_platform_suspend(struct device *dev) -+{ -+ struct ahci_platform_data *pdata = dev_get_platdata(dev); -+ struct ata_host *host = dev_get_drvdata(dev); -+ struct ahci_host_priv *hpriv = host->private_data; -+ int rc; -+ -+ rc = ahci_platform_suspend_host(dev); - if (rc) - return rc; - - if (pdata && pdata->suspend) - return pdata->suspend(dev); - -- if (!IS_ERR(hpriv->clk)) -- clk_disable_unprepare(hpriv->clk); -+ ahci_platform_disable_resources(hpriv); - - return 0; - } -+EXPORT_SYMBOL_GPL(ahci_platform_suspend); - --static int ahci_resume(struct device *dev) -+/** -+ * ahci_platform_resume - Resume an ahci-platform device -+ * @dev: the platform device to resume -+ * -+ * This function enables all the resources of the device followed by -+ * resuming the host associated with the device. -+ * -+ * LOCKING: -+ * None. -+ * -+ * RETURNS: -+ * 0 on success otherwise a negative error code -+ */ -+int ahci_platform_resume(struct device *dev) - { - struct ahci_platform_data *pdata = dev_get_platdata(dev); - struct ata_host *host = dev_get_drvdata(dev); - struct ahci_host_priv *hpriv = host->private_data; - int rc; - -- if (!IS_ERR(hpriv->clk)) { -- rc = clk_prepare_enable(hpriv->clk); -- if (rc) { -- dev_err(dev, "clock prepare enable failed"); -- return rc; -- } -- } -+ rc = ahci_platform_enable_resources(hpriv); -+ if (rc) -+ return rc; - - if (pdata && pdata->resume) { - rc = pdata->resume(dev); - if (rc) -- goto disable_unprepare_clk; -- } -- -- if (dev->power.power_state.event == PM_EVENT_SUSPEND) { -- rc = ahci_reset_controller(host); -- if (rc) -- goto disable_unprepare_clk; -- -- ahci_init_controller(host); -+ goto disable_resources; - } - -- ata_host_resume(host); -+ rc = ahci_platform_resume_host(dev); -+ if (rc) -+ goto disable_resources; - - return 0; - --disable_unprepare_clk: -- if (!IS_ERR(hpriv->clk)) -- clk_disable_unprepare(hpriv->clk); -+disable_resources: -+ ahci_platform_disable_resources(hpriv); - - return rc; - } -+EXPORT_SYMBOL_GPL(ahci_platform_resume); - #endif - --static SIMPLE_DEV_PM_OPS(ahci_pm_ops, ahci_suspend, ahci_resume); -+static SIMPLE_DEV_PM_OPS(ahci_pm_ops, ahci_platform_suspend, -+ ahci_platform_resume); - - static const struct of_device_id ahci_of_match[] = { - { .compatible = "snps,spear-ahci", }, ---- a/include/linux/ahci_platform.h -+++ b/include/linux/ahci_platform.h -@@ -19,7 +19,15 @@ - - struct device; - struct ata_port_info; -+struct ahci_host_priv; -+struct platform_device; - -+/* -+ * Note ahci_platform_data is deprecated, it is only kept around for use -+ * by the old da850 and spear13xx ahci code. -+ * New drivers should instead declare their own platform_driver struct, and -+ * use ahci_platform* functions in their own probe, suspend and resume methods. -+ */ - struct ahci_platform_data { - int (*init)(struct device *dev, void __iomem *addr); - void (*exit)(struct device *dev); -@@ -30,4 +38,21 @@ struct ahci_platform_data { - unsigned int mask_port_map; - }; - -+int ahci_platform_enable_clks(struct ahci_host_priv *hpriv); -+void ahci_platform_disable_clks(struct ahci_host_priv *hpriv); -+int ahci_platform_enable_resources(struct ahci_host_priv *hpriv); -+void ahci_platform_disable_resources(struct ahci_host_priv *hpriv); -+struct ahci_host_priv *ahci_platform_get_resources( -+ struct platform_device *pdev); -+int ahci_platform_init_host(struct platform_device *pdev, -+ struct ahci_host_priv *hpriv, -+ const struct ata_port_info *pi_template, -+ unsigned int force_port_map, -+ unsigned int mask_port_map); -+ -+int ahci_platform_suspend_host(struct device *dev); -+int ahci_platform_resume_host(struct device *dev); -+int ahci_platform_suspend(struct device *dev); -+int ahci_platform_resume(struct device *dev); -+ - #endif /* _AHCI_PLATFORM_H */ diff --git a/target/linux/sunxi/patches-3.14/191-ahci-add-sunxi-driver.patch b/target/linux/sunxi/patches-3.14/191-ahci-add-sunxi-driver.patch deleted file mode 100644 index 563b19d366..0000000000 --- a/target/linux/sunxi/patches-3.14/191-ahci-add-sunxi-driver.patch +++ /dev/null @@ -1,340 +0,0 @@ -From 49270be12ed66b6aff84292f63c16ed77a62e8a6 Mon Sep 17 00:00:00 2001 -From: Olliver Schinagl <oliver@schinagl.nl> -Date: Sat, 18 Jan 2014 15:00:45 +0100 -Subject: [PATCH] ARM: sunxi: Add support for Allwinner SUNXi SoCs sata to - ahci_platform - -This patch adds support for the ahci sata controler found on Allwinner A10 -and A20 SoCs to the ahci_platform driver. - -Orignally written by Olliver Schinagl using the approach of having a platform -device which probe method creates a new child platform device which gets -driven by ahci_platform.c, as done by ahci_imx.c . - -Refactored by Hans de Goede to add most of the non sunxi specific functionality -to ahci_platform.c and use a platform_data pointer from of_device_id for the -sunxi specific bits. - -Signed-off-by: Olliver Schinagl <oliver@schinagl.nl> -Signed-off-by: Hans de Goede <hdegoede@redhat.com> ---- - .../devicetree/bindings/ata/ahci-platform.txt | 15 +- - drivers/ata/Kconfig | 9 + - drivers/ata/Makefile | 1 + - drivers/ata/ahci_sunxi.c | 249 +++++++++++++++++++++ - 4 files changed, 271 insertions(+), 3 deletions(-) - create mode 100644 drivers/ata/ahci_sunxi.c - ---- a/Documentation/devicetree/bindings/ata/ahci-platform.txt -+++ b/Documentation/devicetree/bindings/ata/ahci-platform.txt -@@ -4,7 +4,9 @@ SATA nodes are defined to describe on-ch - Each SATA controller should have its own node. - - Required properties: --- compatible : compatible list, contains "snps,spear-ahci" -+- compatible : compatible list, one of "snps,spear-ahci", -+ "snps,exynos5440-ahci", "ibm,476gtr-ahci", or -+ "allwinner,sun4i-a10-ahci" - - interrupts : <interrupt mapping for SATA IRQ> - - reg : <registers mapping> - -@@ -13,10 +15,17 @@ Optional properties: - - clocks : a list of phandle + clock specifier pairs - - target-supply : regulator for SATA target power - --Example: -+Examples: - sata@ffe08000 { - compatible = "snps,spear-ahci"; - reg = <0xffe08000 0x1000>; - interrupts = <115>; -- - }; -+ -+ ahci: sata@01c18000 { -+ compatible = "allwinner,sun4i-a10-ahci"; -+ reg = <0x01c18000 0x1000>; -+ interrupts = <56>; -+ clocks = <&pll6 0>, <&ahb_gates 25>; -+ target-supply = <®_ahci_5v>; -+ }; ---- 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 ARCH_SUNXI && SATA_AHCI_PLATFORM -+ 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 ---- 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 ---- /dev/null -+++ b/drivers/ata/ahci_sunxi.c -@@ -0,0 +1,249 @@ -+/* -+ * Allwinner sunxi AHCI SATA platform driver -+ * Copyright 2013 Olliver Schinagl <oliver@schinagl.nl> -+ * Copyright 2014 Hans de Goede <hdegoede@redhat.com> -+ * -+ * based on the AHCI SATA platform driver by Jeff Garzik and Anton Vorontsov -+ * 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. -+ */ -+ -+#include <linux/ahci_platform.h> -+#include <linux/clk.h> -+#include <linux/errno.h> -+#include <linux/kernel.h> -+#include <linux/module.h> -+#include <linux/of_device.h> -+#include <linux/platform_device.h> -+#include <linux/regulator/consumer.h> -+#include "ahci.h" -+ -+#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 -+ -+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 ahci_sunxi_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 = 250; /* Power up takes aprox 50 us */ -+ do { -+ reg_val = sunxi_getbits(reg_base + AHCI_PHYCS0R, 0x7, 28); -+ if (reg_val == 0x02) -+ break; -+ -+ if (--timeout == 0) { -+ dev_err(dev, "PHY power up failed.\n"); -+ return -EIO; -+ } -+ udelay(1); -+ } while (1); -+ -+ sunxi_setbits(reg_base + AHCI_PHYCS2R, (0x1 << 24)); -+ -+ timeout = 100; /* Calibration takes aprox 10 us */ -+ do { -+ reg_val = sunxi_getbits(reg_base + AHCI_PHYCS2R, 0x1, 24); -+ if (reg_val == 0x00) -+ break; -+ -+ if (--timeout == 0) { -+ dev_err(dev, "PHY calibration failed.\n"); -+ return -EIO; -+ } -+ udelay(1); -+ } while (1); -+ -+ mdelay(15); -+ -+ writel(0x7, reg_base + AHCI_RWCR); -+ -+ return 0; -+} -+ -+static void ahci_sunxi_start_engine(struct ata_port *ap) -+{ -+ void __iomem *port_mmio = ahci_port_base(ap); -+ struct ahci_host_priv *hpriv = ap->host->private_data; -+ -+ /* Setup DMA before DMA start */ -+ sunxi_clrsetbits(hpriv->mmio + AHCI_P0DMACR, 0x0000ff00, 0x00004400); -+ -+ /* Start DMA */ -+ sunxi_setbits(port_mmio + PORT_CMD, PORT_CMD_START); -+} -+ -+static const struct ata_port_info ahci_sunxi_port_info = { -+ AHCI_HFLAGS(AHCI_HFLAG_32BIT_ONLY | AHCI_HFLAG_NO_MSI | -+ AHCI_HFLAG_NO_PMP | AHCI_HFLAG_YES_NCQ), -+ .flags = AHCI_FLAG_COMMON | ATA_FLAG_NCQ, -+ .pio_mask = ATA_PIO4, -+ .udma_mask = ATA_UDMA6, -+ .port_ops = &ahci_platform_ops, -+}; -+ -+static int ahci_sunxi_probe(struct platform_device *pdev) -+{ -+ struct device *dev = &pdev->dev; -+ struct ahci_host_priv *hpriv; -+ int rc; -+ -+ hpriv = ahci_platform_get_resources(pdev); -+ if (IS_ERR(hpriv)) -+ return PTR_ERR(hpriv); -+ -+ hpriv->start_engine = ahci_sunxi_start_engine; -+ -+ rc = ahci_platform_enable_resources(hpriv); -+ if (rc) -+ return rc; -+ -+ rc = ahci_sunxi_phy_init(dev, hpriv->mmio); -+ if (rc) -+ goto disable_resources; -+ -+ rc = ahci_platform_init_host(pdev, hpriv, &ahci_sunxi_port_info, 0, 0); -+ if (rc) -+ goto disable_resources; -+ -+ return 0; -+ -+disable_resources: -+ ahci_platform_disable_resources(hpriv); -+ return rc; -+} -+ -+#ifdef CONFIG_PM_SLEEP -+int ahci_sunxi_resume(struct device *dev) -+{ -+ struct ata_host *host = dev_get_drvdata(dev); -+ struct ahci_host_priv *hpriv = host->private_data; -+ int rc; -+ -+ rc = ahci_platform_enable_resources(hpriv); -+ if (rc) -+ return rc; -+ -+ rc = ahci_sunxi_phy_init(dev, hpriv->mmio); -+ if (rc) -+ goto disable_resources; -+ -+ rc = ahci_platform_resume_host(dev); -+ if (rc) -+ goto disable_resources; -+ -+ return 0; -+ -+disable_resources: -+ ahci_platform_disable_resources(hpriv); -+ return rc; -+} -+#endif -+ -+static SIMPLE_DEV_PM_OPS(ahci_sunxi_pm_ops, ahci_platform_suspend, -+ ahci_sunxi_resume); -+ -+static const struct of_device_id ahci_sunxi_of_match[] = { -+ { .compatible = "allwinner,sun4i-a10-ahci", }, -+ { }, -+}; -+MODULE_DEVICE_TABLE(of, ahci_sunxi_of_match); -+ -+static struct platform_driver ahci_sunxi_driver = { -+ .probe = ahci_sunxi_probe, -+ .remove = ata_platform_remove_one, -+ .driver = { -+ .name = "ahci-sunxi", -+ .owner = THIS_MODULE, -+ .of_match_table = ahci_sunxi_of_match, -+ .pm = &ahci_sunxi_pm_ops, -+ }, -+}; -+module_platform_driver(ahci_sunxi_driver); -+ -+MODULE_DESCRIPTION("Allwinner sunxi AHCI SATA driver"); -+MODULE_AUTHOR("Olliver Schinagl <oliver@schinagl.nl>"); -+MODULE_LICENSE("GPL"); diff --git a/target/linux/sunxi/patches-3.14/192-ahci-platform-changes.patch b/target/linux/sunxi/patches-3.14/192-ahci-platform-changes.patch deleted file mode 100644 index a5f4fc50a0..0000000000 --- a/target/linux/sunxi/patches-3.14/192-ahci-platform-changes.patch +++ /dev/null @@ -1,202 +0,0 @@ -From a52ae09871d171d6771b4bef2d4c56dd435e740f Mon Sep 17 00:00:00 2001 -From: Roger Quadros <rogerq@ti.com> -Date: Mon, 20 Jan 2014 16:32:33 +0200 -Subject: [PATCH] ata: ahci_platform: Add DT compatible for Synopsis DWC AHCI - controller - -Add compatible string "snps,dwc-ahci", which should be used -for Synopsis Designware SATA cores. e.g. on TI OMAP5 and DRA7 platforms. - -Signed-off-by: Roger Quadros <rogerq@ti.com> -Reviewed-by: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com> -Signed-off-by: Hans de Goede <hdegoede@redhat.com> ---- - drivers/ata/ahci_platform.c | 1 + - 1 file changed, 1 insertion(+) - ---- a/drivers/ata/ahci_platform.c -+++ b/drivers/ata/ahci_platform.c -@@ -23,6 +23,8 @@ - #include <linux/platform_device.h> - #include <linux/libata.h> - #include <linux/ahci_platform.h> -+#include <linux/phy/phy.h> -+#include <linux/pm_runtime.h> - #include "ahci.h" - - static void ahci_host_stop(struct ata_host *host); -@@ -147,6 +149,7 @@ EXPORT_SYMBOL_GPL(ahci_platform_disable_ - * the following order: - * 1) Regulator - * 2) Clocks (through ahci_platform_enable_clks) -+ * 3) Phy - * - * If resource enabling fails at any point the previous enabled - * resources are disabled in reverse order. -@@ -171,8 +174,23 @@ int ahci_platform_enable_resources(struc - if (rc) - goto disable_regulator; - -+ if (hpriv->phy) { -+ rc = phy_init(hpriv->phy); -+ if (rc) -+ goto disable_clks; -+ -+ rc = phy_power_on(hpriv->phy); -+ if (rc) { -+ phy_exit(hpriv->phy); -+ goto disable_clks; -+ } -+ } -+ - return 0; - -+disable_clks: -+ ahci_platform_disable_clks(hpriv); -+ - disable_regulator: - if (hpriv->target_pwr) - regulator_disable(hpriv->target_pwr); -@@ -186,14 +204,20 @@ EXPORT_SYMBOL_GPL(ahci_platform_enable_r - * - * This function disables all ahci_platform managed resources in - * the following order: -- * 1) Clocks (through ahci_platform_disable_clks) -- * 2) Regulator -+ * 1) Phy -+ * 2) Clocks (through ahci_platform_disable_clks) -+ * 3) Regulator - * - * LOCKING: - * None. - */ - void ahci_platform_disable_resources(struct ahci_host_priv *hpriv) - { -+ if (hpriv->phy) { -+ phy_power_off(hpriv->phy); -+ phy_exit(hpriv->phy); -+ } -+ - ahci_platform_disable_clks(hpriv); - - if (hpriv->target_pwr) -@@ -206,6 +230,11 @@ static void ahci_platform_put_resources( - struct ahci_host_priv *hpriv = res; - int c; - -+ if (hpriv->got_runtime_pm) { -+ pm_runtime_put_sync(dev); -+ pm_runtime_disable(dev); -+ } -+ - for (c = 0; c < AHCI_MAX_CLKS && hpriv->clks[c]; c++) - clk_put(hpriv->clks[c]); - } -@@ -222,6 +251,7 @@ static void ahci_platform_put_resources( - * 2) regulator for controlling the targets power (optional) - * 3) 0 - AHCI_MAX_CLKS clocks, as specified in the devs devicetree node, - * or for non devicetree enabled platforms a single clock -+ * 4) phy (optional) - * - * LOCKING: - * None. -@@ -283,6 +313,29 @@ struct ahci_host_priv *ahci_platform_get - hpriv->clks[i] = clk; - } - -+ hpriv->phy = devm_phy_get(dev, "sata-phy"); -+ if (IS_ERR(hpriv->phy)) { -+ rc = PTR_ERR(hpriv->phy); -+ switch (rc) { -+ case -ENODEV: -+ case -ENOSYS: -+ /* continue normally */ -+ hpriv->phy = NULL; -+ break; -+ -+ case -EPROBE_DEFER: -+ goto err_out; -+ -+ default: -+ dev_err(dev, "couldn't get sata-phy\n"); -+ goto err_out; -+ } -+ } -+ -+ pm_runtime_enable(dev); -+ pm_runtime_get_sync(dev); -+ hpriv->got_runtime_pm = true; -+ - devres_remove_group(dev, NULL); - return hpriv; - -@@ -592,6 +645,11 @@ int ahci_platform_resume(struct device * - if (rc) - goto disable_resources; - -+ /* We resumed so update PM runtime state */ -+ pm_runtime_disable(dev); -+ pm_runtime_set_active(dev); -+ pm_runtime_enable(dev); -+ - return 0; - - disable_resources: -@@ -609,6 +667,7 @@ static const struct of_device_id ahci_of - { .compatible = "snps,spear-ahci", }, - { .compatible = "snps,exynos5440-ahci", }, - { .compatible = "ibm,476gtr-ahci", }, -+ { .compatible = "snps,dwc-ahci", }, - {}, - }; - MODULE_DEVICE_TABLE(of, ahci_of_match); ---- a/drivers/ata/ahci.h -+++ b/drivers/ata/ahci.h -@@ -37,6 +37,7 @@ - - #include <linux/clk.h> - #include <linux/libata.h> -+#include <linux/phy/phy.h> - #include <linux/regulator/consumer.h> - - /* Enclosure Management Control */ -@@ -324,8 +325,10 @@ struct ahci_host_priv { - u32 em_loc; /* enclosure management location */ - u32 em_buf_sz; /* EM buffer size in byte */ - u32 em_msg_type; /* EM message type */ -+ bool got_runtime_pm; /* Did we do pm_runtime_get? */ - struct clk *clks[AHCI_MAX_CLKS]; /* Optional */ - struct regulator *target_pwr; /* Optional */ -+ struct phy *phy; /* If platform uses phy */ - void *plat_data; /* Other platform data */ - /* - * Optional ahci_start_engine override, if not set this gets set to the ---- a/drivers/ata/ahci_sunxi.c -+++ b/drivers/ata/ahci_sunxi.c -@@ -90,7 +90,7 @@ static int ahci_sunxi_phy_init(struct de - - /* This magic is from the original code */ - writel(0, reg_base + AHCI_RWCR); -- mdelay(5); -+ msleep(5); - - sunxi_setbits(reg_base + AHCI_PHYCS1R, BIT(19)); - sunxi_clrsetbits(reg_base + AHCI_PHYCS0R, -@@ -105,7 +105,7 @@ static int ahci_sunxi_phy_init(struct de - (0x7 << 20), (0x3 << 20)); - sunxi_clrsetbits(reg_base + AHCI_PHYCS2R, - (0x1f << 5), (0x19 << 5)); -- mdelay(5); -+ msleep(5); - - sunxi_setbits(reg_base + AHCI_PHYCS0R, (0x1 << 19)); - -@@ -137,7 +137,7 @@ static int ahci_sunxi_phy_init(struct de - udelay(1); - } while (1); - -- mdelay(15); -+ msleep(15); - - writel(0x7, reg_base + AHCI_RWCR); - diff --git a/target/linux/sunxi/patches-3.14/195-1-ohci-plat-changes.patch b/target/linux/sunxi/patches-3.14/195-1-ohci-plat-changes.patch deleted file mode 100644 index fb4c87ea9e..0000000000 --- a/target/linux/sunxi/patches-3.14/195-1-ohci-plat-changes.patch +++ /dev/null @@ -1,344 +0,0 @@ -From 49ff47db168655cac5213cf5dd1844b08fb9823c Mon Sep 17 00:00:00 2001 -From: Hans de Goede <hdegoede@redhat.com> -Date: Sun, 5 Jan 2014 14:42:39 +0100 -Subject: [PATCH] ohci-platform: Add support for devicetree instantiation - -Add support for ohci-platform instantiation from devicetree, including -optionally getting clks and a phy from devicetree, and enabling / disabling -those on power_on / off. - -This should allow using ohci-platform from devicetree in various cases. -Specifically after this commit it can be used for the ohci controller found -on Allwinner sunxi SoCs. - -Signed-off-by: Hans de Goede <hdegoede@redhat.com> -Acked-by: Alan Stern <stern@rowland.harvard.edu> ---- - Documentation/devicetree/bindings/usb/usb-ohci.txt | 22 +++ - drivers/usb/host/ohci-platform.c | 162 ++++++++++++++++++--- - 2 files changed, 162 insertions(+), 22 deletions(-) - create mode 100644 Documentation/devicetree/bindings/usb/usb-ohci.txt - ---- /dev/null -+++ b/Documentation/devicetree/bindings/usb/usb-ohci.txt -@@ -0,0 +1,25 @@ -+USB OHCI controllers -+ -+Required properties: -+- compatible : "generic-ohci" -+- reg : ohci controller register range (address and length) -+- interrupts : ohci controller interrupt -+ -+Optional properties: -+- big-endian-regs : boolean, set this for hcds with big-endian registers -+- big-endian-desc : boolean, set this for hcds with big-endian descriptors -+- big-endian : boolean, for hcds with big-endian-regs + big-endian-desc -+- clocks : a list of phandle + clock specifier pairs -+- phys : phandle + phy specifier pair -+- phy-names : "usb" -+ -+Example: -+ -+ ohci0: usb@01c14400 { -+ compatible = "allwinner,sun4i-a10-ohci", "generic-ohci"; -+ reg = <0x01c14400 0x100>; -+ interrupts = <64>; -+ clocks = <&usb_clk 6>, <&ahb_gates 2>; -+ phys = <&usbphy 1>; -+ phy-names = "usb"; -+ }; ---- a/drivers/usb/host/ohci-platform.c -+++ b/drivers/usb/host/ohci-platform.c -@@ -3,6 +3,7 @@ - * - * Copyright 2007 Michael Buesch <m@bues.ch> - * Copyright 2011-2012 Hauke Mehrtens <hauke@hauke-m.de> -+ * Copyright 2014 Hans de Goede <hdegoede@redhat.com> - * - * Derived from the OCHI-SSB driver - * Derived from the OHCI-PCI driver -@@ -14,11 +15,14 @@ - * Licensed under the GNU/GPL. See COPYING for details. - */ - -+#include <linux/clk.h> -+#include <linux/dma-mapping.h> - #include <linux/hrtimer.h> - #include <linux/io.h> - #include <linux/kernel.h> - #include <linux/module.h> - #include <linux/err.h> -+#include <linux/phy/phy.h> - #include <linux/platform_device.h> - #include <linux/usb/ohci_pdriver.h> - #include <linux/usb.h> -@@ -27,6 +31,13 @@ - #include "ohci.h" - - #define DRIVER_DESC "OHCI generic platform driver" -+#define OHCI_MAX_CLKS 3 -+#define hcd_to_ohci_priv(h) ((struct ohci_platform_priv *)hcd_to_ohci(h)->priv) -+ -+struct ohci_platform_priv { -+ struct clk *clks[OHCI_MAX_CLKS]; -+ struct phy *phy; -+}; - - static const char hcd_name[] = "ohci-platform"; - -@@ -48,11 +59,67 @@ static int ohci_platform_reset(struct us - return ohci_setup(hcd); - } - -+static int ohci_platform_power_on(struct platform_device *dev) -+{ -+ struct usb_hcd *hcd = platform_get_drvdata(dev); -+ struct ohci_platform_priv *priv = hcd_to_ohci_priv(hcd); -+ int clk, ret; -+ -+ for (clk = 0; clk < OHCI_MAX_CLKS && priv->clks[clk]; clk++) { -+ ret = clk_prepare_enable(priv->clks[clk]); -+ if (ret) -+ goto err_disable_clks; -+ } -+ -+ if (priv->phy) { -+ ret = phy_init(priv->phy); -+ if (ret) -+ goto err_disable_clks; -+ -+ ret = phy_power_on(priv->phy); -+ if (ret) -+ goto err_exit_phy; -+ } -+ -+ return 0; -+ -+err_exit_phy: -+ phy_exit(priv->phy); -+err_disable_clks: -+ while (--clk >= 0) -+ clk_disable_unprepare(priv->clks[clk]); -+ -+ return ret; -+} -+ -+static void ohci_platform_power_off(struct platform_device *dev) -+{ -+ struct usb_hcd *hcd = platform_get_drvdata(dev); -+ struct ohci_platform_priv *priv = hcd_to_ohci_priv(hcd); -+ int clk; -+ -+ if (priv->phy) { -+ phy_power_off(priv->phy); -+ phy_exit(priv->phy); -+ } -+ -+ for (clk = OHCI_MAX_CLKS - 1; clk >= 0; clk--) -+ if (priv->clks[clk]) -+ clk_disable_unprepare(priv->clks[clk]); -+} -+ - static struct hc_driver __read_mostly ohci_platform_hc_driver; - - static const struct ohci_driver_overrides platform_overrides __initconst = { -- .product_desc = "Generic Platform OHCI controller", -- .reset = ohci_platform_reset, -+ .product_desc = "Generic Platform OHCI controller", -+ .reset = ohci_platform_reset, -+ .extra_priv_size = sizeof(struct ohci_platform_priv), -+}; -+ -+static struct usb_ohci_pdata ohci_platform_defaults = { -+ .power_on = ohci_platform_power_on, -+ .power_suspend = ohci_platform_power_off, -+ .power_off = ohci_platform_power_off, - }; - - static int ohci_platform_probe(struct platform_device *dev) -@@ -60,17 +127,24 @@ static int ohci_platform_probe(struct pl - struct usb_hcd *hcd; - struct resource *res_mem; - struct usb_ohci_pdata *pdata = dev_get_platdata(&dev->dev); -- int irq; -- int err = -ENOMEM; -- -- if (!pdata) { -- WARN_ON(1); -- return -ENODEV; -- } -+ struct ohci_platform_priv *priv; -+ struct ohci_hcd *ohci; -+ int err, irq, clk = 0; - - if (usb_disabled()) - return -ENODEV; - -+ /* -+ * Use reasonable defaults so platforms don't have to provide these -+ * with DT probing on ARM. -+ */ -+ if (!pdata) -+ pdata = &ohci_platform_defaults; -+ -+ err = dma_coerce_mask_and_coherent(&dev->dev, DMA_BIT_MASK(32)); -+ if (err) -+ return err; -+ - irq = platform_get_irq(dev, 0); - if (irq < 0) { - dev_err(&dev->dev, "no irq provided"); -@@ -83,17 +157,66 @@ static int ohci_platform_probe(struct pl - return -ENXIO; - } - -+ hcd = usb_create_hcd(&ohci_platform_hc_driver, &dev->dev, -+ dev_name(&dev->dev)); -+ if (!hcd) -+ return -ENOMEM; -+ -+ platform_set_drvdata(dev, hcd); -+ dev->dev.platform_data = pdata; -+ priv = hcd_to_ohci_priv(hcd); -+ ohci = hcd_to_ohci(hcd); -+ -+ if (pdata == &ohci_platform_defaults && dev->dev.of_node) { -+ if (of_property_read_bool(dev->dev.of_node, "big-endian-regs")) -+ ohci->flags |= OHCI_QUIRK_BE_MMIO; -+ -+ if (of_property_read_bool(dev->dev.of_node, "big-endian-desc")) -+ ohci->flags |= OHCI_QUIRK_BE_DESC; -+ -+ if (of_property_read_bool(dev->dev.of_node, "big-endian")) -+ ohci->flags |= OHCI_QUIRK_BE_MMIO | OHCI_QUIRK_BE_DESC; -+ -+#ifndef CONFIG_USB_OHCI_BIG_ENDIAN_MMIO -+ if (ohci->flags & OHCI_QUIRK_BE_MMIO) { -+ dev_err(&dev->dev, -+ "Error big-endian-regs not compiled in\n"); -+ err = -EINVAL; -+ goto err_put_hcd; -+ } -+#endif -+#ifndef CONFIG_USB_OHCI_BIG_ENDIAN_DESC -+ if (ohci->flags & OHCI_QUIRK_BE_DESC) { -+ dev_err(&dev->dev, -+ "Error big-endian-desc not compiled in\n"); -+ err = -EINVAL; -+ goto err_put_hcd; -+ } -+#endif -+ priv->phy = devm_phy_get(&dev->dev, "usb"); -+ if (IS_ERR(priv->phy)) { -+ err = PTR_ERR(priv->phy); -+ if (err == -EPROBE_DEFER) -+ goto err_put_hcd; -+ priv->phy = NULL; -+ } -+ -+ for (clk = 0; clk < OHCI_MAX_CLKS; clk++) { -+ priv->clks[clk] = of_clk_get(dev->dev.of_node, clk); -+ if (IS_ERR(priv->clks[clk])) { -+ err = PTR_ERR(priv->clks[clk]); -+ if (err == -EPROBE_DEFER) -+ goto err_put_clks; -+ priv->clks[clk] = NULL; -+ break; -+ } -+ } -+ } -+ - if (pdata->power_on) { - err = pdata->power_on(dev); - if (err < 0) -- return err; -- } -- -- hcd = usb_create_hcd(&ohci_platform_hc_driver, &dev->dev, -- dev_name(&dev->dev)); -- if (!hcd) { -- err = -ENOMEM; -- goto err_power; -+ goto err_put_clks; - } - - hcd->rsrc_start = res_mem->start; -@@ -102,11 +225,11 @@ static int ohci_platform_probe(struct pl - hcd->regs = devm_ioremap_resource(&dev->dev, res_mem); - if (IS_ERR(hcd->regs)) { - err = PTR_ERR(hcd->regs); -- goto err_put_hcd; -+ goto err_power; - } - err = usb_add_hcd(hcd, irq, IRQF_SHARED); - if (err) -- goto err_put_hcd; -+ goto err_power; - - device_wakeup_enable(hcd->self.controller); - -@@ -114,11 +237,17 @@ static int ohci_platform_probe(struct pl - - return err; - --err_put_hcd: -- usb_put_hcd(hcd); - err_power: - if (pdata->power_off) - pdata->power_off(dev); -+err_put_clks: -+ while (--clk >= 0) -+ clk_put(priv->clks[clk]); -+err_put_hcd: -+ if (pdata == &ohci_platform_defaults) -+ dev->dev.platform_data = NULL; -+ -+ usb_put_hcd(hcd); - - return err; - } -@@ -127,13 +256,22 @@ static int ohci_platform_remove(struct p - { - struct usb_hcd *hcd = platform_get_drvdata(dev); - struct usb_ohci_pdata *pdata = dev_get_platdata(&dev->dev); -+ struct ohci_platform_priv *priv = hcd_to_ohci_priv(hcd); -+ int clk; - - usb_remove_hcd(hcd); -- usb_put_hcd(hcd); - - if (pdata->power_off) - pdata->power_off(dev); - -+ for (clk = 0; clk < OHCI_MAX_CLKS && priv->clks[clk]; clk++) -+ clk_put(priv->clks[clk]); -+ -+ usb_put_hcd(hcd); -+ -+ if (pdata == &ohci_platform_defaults) -+ dev->dev.platform_data = NULL; -+ - return 0; - } - -@@ -180,6 +318,12 @@ static int ohci_platform_resume(struct d - #define ohci_platform_resume NULL - #endif /* CONFIG_PM */ - -+static const struct of_device_id ohci_platform_ids[] = { -+ { .compatible = "generic-ohci", }, -+ { } -+}; -+MODULE_DEVICE_TABLE(of, ohci_platform_ids); -+ - static const struct platform_device_id ohci_platform_table[] = { - { "ohci-platform", 0 }, - { } -@@ -200,6 +344,7 @@ static struct platform_driver ohci_platf - .owner = THIS_MODULE, - .name = "ohci-platform", - .pm = &ohci_platform_pm_ops, -+ .of_match_table = ohci_platform_ids, - } - }; - diff --git a/target/linux/sunxi/patches-3.14/195-2-ehci-plat-changes.patch b/target/linux/sunxi/patches-3.14/195-2-ehci-plat-changes.patch deleted file mode 100644 index 425993c7bb..0000000000 --- a/target/linux/sunxi/patches-3.14/195-2-ehci-plat-changes.patch +++ /dev/null @@ -1,414 +0,0 @@ -From 738b350437abfca820dae226549ecf4fb100fa30 Mon Sep 17 00:00:00 2001 -From: Hans de Goede <hdegoede@redhat.com> -Date: Sun, 5 Jan 2014 00:04:02 +0100 -Subject: [PATCH] ehci-platform: Add support for clks and phy passed through - devicetree - -Currently ehci-platform is only used in combination with devicetree when used -with some Via socs. By extending it to (optionally) get clks and a phy from -devicetree, and enabling / disabling those on power_on / off, it can be used -more generically. Specifically after this commit it can be used for the -ehci controller on Allwinner sunxi SoCs. - -Since ehci-platform is intended to handle any generic enough non pci ehci -device, add a "usb-ehci" compatibility string. - -There already is a usb-ehci device-tree bindings document, update this -with clks and phy bindings info. - -Although actually quite generic so far the via,vt8500 compatibilty string -had its own bindings document. Somehow we even ended up with 2 of them. Since -these provide no extra information over the generic usb-ehci documentation, -this patch removes them. - -The ehci-ppc-of.c driver also claims the usb-ehci compatibility string, -even though it mostly is ibm,usb-ehci-440epx specific. ehci-platform.c is -not needed on ppc platforms, so add a !PPC_OF dependency to it to avoid -2 drivers claiming the same compatibility string getting build on ppc. - -Signed-off-by: Hans de Goede <hdegoede@redhat.com> -Acked-by: Alan Stern <stern@rowland.harvard.edu> ---- - Documentation/devicetree/bindings/usb/usb-ehci.txt | 25 +++- - .../devicetree/bindings/usb/via,vt8500-ehci.txt | 15 --- - .../devicetree/bindings/usb/vt8500-ehci.txt | 12 -- - drivers/usb/host/Kconfig | 1 + - drivers/usb/host/ehci-platform.c | 147 +++++++++++++++++---- - 5 files changed, 142 insertions(+), 58 deletions(-) - delete mode 100644 Documentation/devicetree/bindings/usb/via,vt8500-ehci.txt - delete mode 100644 Documentation/devicetree/bindings/usb/vt8500-ehci.txt - ---- a/Documentation/devicetree/bindings/usb/usb-ehci.txt -+++ b/Documentation/devicetree/bindings/usb/usb-ehci.txt -@@ -1,19 +1,20 @@ - USB EHCI controllers - - Required properties: -- - compatible : should be "usb-ehci". -+ - compatible : should be "generic-ehci". - - reg : should contain at least address and length of the standard EHCI - register set for the device. Optional platform-dependent registers - (debug-port or other) can be also specified here, but only after - definition of standard EHCI registers. - - interrupts : one EHCI interrupt should be described here. --If device registers are implemented in big endian mode, the device --node should have "big-endian-regs" property. --If controller implementation operates with big endian descriptors, --"big-endian-desc" property should be specified. --If both big endian registers and descriptors are used by the controller --implementation, "big-endian" property can be specified instead of having --both "big-endian-regs" and "big-endian-desc". -+ -+Optional properties: -+ - big-endian-regs : boolean, set this for hcds with big-endian registers -+ - big-endian-desc : boolean, set this for hcds with big-endian descriptors -+ - big-endian : boolean, for hcds with big-endian-regs + big-endian-desc -+ - clocks : a list of phandle + clock specifier pairs -+ - phys : phandle + phy specifier pair -+ - phy-names : "usb" - - Example (Sequoia 440EPx): - ehci@e0000300 { -@@ -23,3 +24,13 @@ Example (Sequoia 440EPx): - reg = <0 e0000300 90 0 e0000390 70>; - big-endian; - }; -+ -+Example (Allwinner sun4i A10 SoC): -+ ehci0: usb@01c14000 { -+ compatible = "allwinner,sun4i-a10-ehci", "generic-ehci"; -+ reg = <0x01c14000 0x100>; -+ interrupts = <39>; -+ clocks = <&ahb_gates 1>; -+ phys = <&usbphy 1>; -+ phy-names = "usb"; -+ }; ---- a/Documentation/devicetree/bindings/usb/via,vt8500-ehci.txt -+++ /dev/null -@@ -1,15 +0,0 @@ --VIA/Wondermedia VT8500 EHCI Controller ------------------------------------------------------- -- --Required properties: --- compatible : "via,vt8500-ehci" --- reg : Should contain 1 register ranges(address and length) --- interrupts : ehci controller interrupt -- --Example: -- -- ehci@d8007900 { -- compatible = "via,vt8500-ehci"; -- reg = <0xd8007900 0x200>; -- interrupts = <43>; -- }; ---- a/Documentation/devicetree/bindings/usb/vt8500-ehci.txt -+++ /dev/null -@@ -1,12 +0,0 @@ --VIA VT8500 and Wondermedia WM8xxx SoC USB controllers. -- --Required properties: -- - compatible: Should be "via,vt8500-ehci" or "wm,prizm-ehci". -- - reg: Address range of the ehci registers. size should be 0x200 -- - interrupts: Should contain the ehci interrupt. -- --usb: ehci@D8007100 { -- compatible = "wm,prizm-ehci", "usb-ehci"; -- reg = <0xD8007100 0x200>; -- interrupts = <1>; --}; ---- a/drivers/usb/host/ehci-platform.c -+++ b/drivers/usb/host/ehci-platform.c -@@ -3,6 +3,7 @@ - * - * Copyright 2007 Steven Brown <sbrown@cortland.com> - * Copyright 2010-2012 Hauke Mehrtens <hauke@hauke-m.de> -+ * Copyright 2014 Hans de Goede <hdegoede@redhat.com> - * - * Derived from the ohci-ssb driver - * Copyright 2007 Michael Buesch <m@bues.ch> -@@ -18,6 +19,7 @@ - * - * Licensed under the GNU/GPL. See COPYING for details. - */ -+#include <linux/clk.h> - #include <linux/dma-mapping.h> - #include <linux/err.h> - #include <linux/kernel.h> -@@ -25,6 +27,7 @@ - #include <linux/io.h> - #include <linux/module.h> - #include <linux/of.h> -+#include <linux/phy/phy.h> - #include <linux/platform_device.h> - #include <linux/usb.h> - #include <linux/usb/hcd.h> -@@ -33,6 +36,13 @@ - #include "ehci.h" - - #define DRIVER_DESC "EHCI generic platform driver" -+#define EHCI_MAX_CLKS 3 -+#define hcd_to_ehci_priv(h) ((struct ehci_platform_priv *)hcd_to_ehci(h)->priv) -+ -+struct ehci_platform_priv { -+ struct clk *clks[EHCI_MAX_CLKS]; -+ struct phy *phy; -+}; - - static const char hcd_name[] = "ehci-platform"; - -@@ -45,8 +55,10 @@ static int ehci_platform_reset(struct us - - hcd->has_tt = pdata->has_tt; - ehci->has_synopsys_hc_bug = pdata->has_synopsys_hc_bug; -- ehci->big_endian_desc = pdata->big_endian_desc; -- ehci->big_endian_mmio = pdata->big_endian_mmio; -+ if (pdata->big_endian_desc) -+ ehci->big_endian_desc = 1; -+ if (pdata->big_endian_mmio) -+ ehci->big_endian_mmio = 1; - ehci->ignore_oc = pdata->ignore_oc; - - if (pdata->pre_setup) { -@@ -65,38 +77,91 @@ static int ehci_platform_reset(struct us - return 0; - } - -+static int ehci_platform_power_on(struct platform_device *dev) -+{ -+ struct usb_hcd *hcd = platform_get_drvdata(dev); -+ struct ehci_platform_priv *priv = hcd_to_ehci_priv(hcd); -+ int clk, ret; -+ -+ for (clk = 0; clk < EHCI_MAX_CLKS && priv->clks[clk]; clk++) { -+ ret = clk_prepare_enable(priv->clks[clk]); -+ if (ret) -+ goto err_disable_clks; -+ } -+ -+ if (priv->phy) { -+ ret = phy_init(priv->phy); -+ if (ret) -+ goto err_disable_clks; -+ -+ ret = phy_power_on(priv->phy); -+ if (ret) -+ goto err_exit_phy; -+ } -+ -+ return 0; -+ -+err_exit_phy: -+ phy_exit(priv->phy); -+err_disable_clks: -+ while (--clk >= 0) -+ clk_disable_unprepare(priv->clks[clk]); -+ -+ return ret; -+} -+ -+static void ehci_platform_power_off(struct platform_device *dev) -+{ -+ struct usb_hcd *hcd = platform_get_drvdata(dev); -+ struct ehci_platform_priv *priv = hcd_to_ehci_priv(hcd); -+ int clk; -+ -+ if (priv->phy) { -+ phy_power_off(priv->phy); -+ phy_exit(priv->phy); -+ } -+ -+ for (clk = EHCI_MAX_CLKS - 1; clk >= 0; clk--) -+ if (priv->clks[clk]) -+ clk_disable_unprepare(priv->clks[clk]); -+} -+ - static struct hc_driver __read_mostly ehci_platform_hc_driver; - - static const struct ehci_driver_overrides platform_overrides __initconst = { -- .reset = ehci_platform_reset, -+ .reset = ehci_platform_reset, -+ .extra_priv_size = sizeof(struct ehci_platform_priv), - }; - --static struct usb_ehci_pdata ehci_platform_defaults; -+static struct usb_ehci_pdata ehci_platform_defaults = { -+ .power_on = ehci_platform_power_on, -+ .power_suspend = ehci_platform_power_off, -+ .power_off = ehci_platform_power_off, -+}; - - static int ehci_platform_probe(struct platform_device *dev) - { - struct usb_hcd *hcd; - struct resource *res_mem; -- struct usb_ehci_pdata *pdata; -- int irq; -- int err; -+ struct usb_ehci_pdata *pdata = dev_get_platdata(&dev->dev); -+ struct ehci_platform_priv *priv; -+ struct ehci_hcd *ehci; -+ int err, irq, clk = 0; - - if (usb_disabled()) - return -ENODEV; - - /* -- * use reasonable defaults so platforms don't have to provide these. -- * with DT probing on ARM, none of these are set. -+ * Use reasonable defaults so platforms don't have to provide these -+ * with DT probing on ARM. - */ -- if (!dev_get_platdata(&dev->dev)) -- dev->dev.platform_data = &ehci_platform_defaults; -+ if (!pdata) -+ pdata = &ehci_platform_defaults; - - err = dma_coerce_mask_and_coherent(&dev->dev, DMA_BIT_MASK(32)); - if (err) - return err; - -- pdata = dev_get_platdata(&dev->dev); -- - irq = platform_get_irq(dev, 0); - if (irq < 0) { - dev_err(&dev->dev, "no irq provided"); -@@ -108,17 +173,66 @@ static int ehci_platform_probe(struct pl - return -ENXIO; - } - -+ hcd = usb_create_hcd(&ehci_platform_hc_driver, &dev->dev, -+ dev_name(&dev->dev)); -+ if (!hcd) -+ return -ENOMEM; -+ -+ platform_set_drvdata(dev, hcd); -+ dev->dev.platform_data = pdata; -+ priv = hcd_to_ehci_priv(hcd); -+ ehci = hcd_to_ehci(hcd); -+ -+ if (pdata == &ehci_platform_defaults && dev->dev.of_node) { -+ if (of_property_read_bool(dev->dev.of_node, "big-endian-regs")) -+ ehci->big_endian_mmio = 1; -+ -+ if (of_property_read_bool(dev->dev.of_node, "big-endian-desc")) -+ ehci->big_endian_desc = 1; -+ -+ if (of_property_read_bool(dev->dev.of_node, "big-endian")) -+ ehci->big_endian_mmio = ehci->big_endian_desc = 1; -+ -+#ifndef CONFIG_USB_EHCI_BIG_ENDIAN_MMIO -+ if (ehci->big_endian_mmio) { -+ dev_err(&dev->dev, -+ "Error big-endian-regs not compiled in\n"); -+ err = -EINVAL; -+ goto err_put_hcd; -+ } -+#endif -+#ifndef CONFIG_USB_EHCI_BIG_ENDIAN_DESC -+ if (ehci->big_endian_desc) { -+ dev_err(&dev->dev, -+ "Error big-endian-desc not compiled in\n"); -+ err = -EINVAL; -+ goto err_put_hcd; -+ } -+#endif -+ priv->phy = devm_phy_get(&dev->dev, "usb"); -+ if (IS_ERR(priv->phy)) { -+ err = PTR_ERR(priv->phy); -+ if (err == -EPROBE_DEFER) -+ goto err_put_hcd; -+ priv->phy = NULL; -+ } -+ -+ for (clk = 0; clk < EHCI_MAX_CLKS; clk++) { -+ priv->clks[clk] = of_clk_get(dev->dev.of_node, clk); -+ if (IS_ERR(priv->clks[clk])) { -+ err = PTR_ERR(priv->clks[clk]); -+ if (err == -EPROBE_DEFER) -+ goto err_put_clks; -+ priv->clks[clk] = NULL; -+ break; -+ } -+ } -+ } -+ - if (pdata->power_on) { - err = pdata->power_on(dev); - if (err < 0) -- return err; -- } -- -- hcd = usb_create_hcd(&ehci_platform_hc_driver, &dev->dev, -- dev_name(&dev->dev)); -- if (!hcd) { -- err = -ENOMEM; -- goto err_power; -+ goto err_put_clks; - } - - hcd->rsrc_start = res_mem->start; -@@ -127,22 +241,28 @@ static int ehci_platform_probe(struct pl - hcd->regs = devm_ioremap_resource(&dev->dev, res_mem); - if (IS_ERR(hcd->regs)) { - err = PTR_ERR(hcd->regs); -- goto err_put_hcd; -+ goto err_power; - } - err = usb_add_hcd(hcd, irq, IRQF_SHARED); - if (err) -- goto err_put_hcd; -+ goto err_power; - - device_wakeup_enable(hcd->self.controller); - platform_set_drvdata(dev, hcd); - - return err; - --err_put_hcd: -- usb_put_hcd(hcd); - err_power: - if (pdata->power_off) - pdata->power_off(dev); -+err_put_clks: -+ while (--clk >= 0) -+ clk_put(priv->clks[clk]); -+err_put_hcd: -+ if (pdata == &ehci_platform_defaults) -+ dev->dev.platform_data = NULL; -+ -+ usb_put_hcd(hcd); - - return err; - } -@@ -151,13 +271,19 @@ static int ehci_platform_remove(struct p - { - struct usb_hcd *hcd = platform_get_drvdata(dev); - struct usb_ehci_pdata *pdata = dev_get_platdata(&dev->dev); -+ struct ehci_platform_priv *priv = hcd_to_ehci_priv(hcd); -+ int clk; - - usb_remove_hcd(hcd); -- usb_put_hcd(hcd); - - if (pdata->power_off) - pdata->power_off(dev); - -+ for (clk = 0; clk < EHCI_MAX_CLKS && priv->clks[clk]; clk++) -+ clk_put(priv->clks[clk]); -+ -+ usb_put_hcd(hcd); -+ - if (pdata == &ehci_platform_defaults) - dev->dev.platform_data = NULL; - -@@ -208,8 +334,10 @@ static int ehci_platform_resume(struct d - static const struct of_device_id vt8500_ehci_ids[] = { - { .compatible = "via,vt8500-ehci", }, - { .compatible = "wm,prizm-ehci", }, -+ { .compatible = "generic-ehci", }, - {} - }; -+MODULE_DEVICE_TABLE(of, vt8500_ehci_ids); - - static const struct platform_device_id ehci_platform_table[] = { - { "ehci-platform", 0 }, diff --git a/target/linux/sunxi/patches-3.14/195-3-uhci-plat-changes.patch b/target/linux/sunxi/patches-3.14/195-3-uhci-plat-changes.patch deleted file mode 100644 index 53c808fbb3..0000000000 --- a/target/linux/sunxi/patches-3.14/195-3-uhci-plat-changes.patch +++ /dev/null @@ -1,72 +0,0 @@ -From 2adf0917bc9d6db8d957d56c8289a623be4027b6 Mon Sep 17 00:00:00 2001 -From: Hans de Goede <hdegoede@redhat.com> -Date: Tue, 11 Feb 2014 17:41:48 +0100 -Subject: [PATCH] uhci-platform: Change compatible string from platform-uhci to - generic-uhci - -This brings the uhci-platform bindings in sync with what we've done for -the ohci- and ehci-platform drivers. As discussed there using platform as a -prefix is a bit weird as the platform bus is a Linux specific thing and -the bindings are supposed to be OS agnostic. - -Note that the old platform-uhci compatible string is kept around for, well, -compatibility reasons. - -While at it rename the bindings txt file to match the name of all the -other ?hci-platform bindings docs. - -Signed-off-by: Hans de Goede <hdegoede@redhat.com> ---- - Documentation/devicetree/bindings/usb/platform-uhci.txt | 15 --------------- - Documentation/devicetree/bindings/usb/usb-uhci.txt | 15 +++++++++++++++ - drivers/usb/host/uhci-platform.c | 1 + - 3 files changed, 16 insertions(+), 15 deletions(-) - delete mode 100644 Documentation/devicetree/bindings/usb/platform-uhci.txt - create mode 100644 Documentation/devicetree/bindings/usb/usb-uhci.txt - ---- a/Documentation/devicetree/bindings/usb/platform-uhci.txt -+++ /dev/null -@@ -1,15 +0,0 @@ --Generic Platform UHCI Controller ------------------------------------------------------- -- --Required properties: --- compatible : "platform-uhci" --- reg : Should contain 1 register ranges(address and length) --- interrupts : UHCI controller interrupt -- --Example: -- -- uhci@d8007b00 { -- compatible = "platform-uhci"; -- reg = <0xd8007b00 0x200>; -- interrupts = <43>; -- }; ---- /dev/null -+++ b/Documentation/devicetree/bindings/usb/usb-uhci.txt -@@ -0,0 +1,15 @@ -+Generic Platform UHCI Controller -+----------------------------------------------------- -+ -+Required properties: -+- compatible : "generic-uhci" (deprecated: "platform-uhci") -+- reg : Should contain 1 register ranges(address and length) -+- interrupts : UHCI controller interrupt -+ -+Example: -+ -+ uhci@d8007b00 { -+ compatible = "generic-uhci"; -+ reg = <0xd8007b00 0x200>; -+ interrupts = <43>; -+ }; ---- a/drivers/usb/host/uhci-platform.c -+++ b/drivers/usb/host/uhci-platform.c -@@ -148,6 +148,7 @@ static void uhci_hcd_platform_shutdown(s - } - - static const struct of_device_id platform_uhci_ids[] = { -+ { .compatible = "generic-uhci", }, - { .compatible = "platform-uhci", }, - {} - }; diff --git a/target/linux/sunxi/patches-3.14/195-4-xhci-plat-changes.patch b/target/linux/sunxi/patches-3.14/195-4-xhci-plat-changes.patch deleted file mode 100644 index 09c3076cd8..0000000000 --- a/target/linux/sunxi/patches-3.14/195-4-xhci-plat-changes.patch +++ /dev/null @@ -1,49 +0,0 @@ -From 8fd033e1b6cdd30c32762ef1c5e2216226dd61e1 Mon Sep 17 00:00:00 2001 -From: Hans de Goede <hdegoede@redhat.com> -Date: Tue, 11 Feb 2014 17:50:51 +0100 -Subject: [PATCH] xhci-platform: Change compatible string from xhci-platform to - generic-xhci - -This brings the xhci-platform bindings in sync with what we've done for -the ohci- and ehci-platform drivers. As discussed there using platform as a -postfix is a bit weird as the platform bus is a Linux specific thing and -the bindings are supposed to be OS agnostic. - -Note that the old xhci-platform compatible string is kept around for, well, -compatibility reasons. - -Signed-off-by: Hans de Goede <hdegoede@redhat.com> ---- - Documentation/devicetree/bindings/usb/usb-xhci.txt | 4 ++-- - drivers/usb/host/xhci-plat.c | 1 + - 2 files changed, 3 insertions(+), 2 deletions(-) - ---- a/Documentation/devicetree/bindings/usb/usb-xhci.txt -+++ b/Documentation/devicetree/bindings/usb/usb-xhci.txt -@@ -1,14 +1,14 @@ - USB xHCI controllers - - Required properties: -- - compatible: should be "xhci-platform". -+ - compatible: should be "generic-xhci" (deprecated: "xhci-platform"). - - reg: should contain address and length of the standard XHCI - register set for the device. - - interrupts: one XHCI interrupt should be described here. - - Example: - usb@f0931000 { -- compatible = "xhci-platform"; -+ compatible = "generic-xhci"; - reg = <0xf0931000 0x8c8>; - interrupts = <0x0 0x4e 0x0>; - }; ---- a/drivers/usb/host/xhci-plat.c -+++ b/drivers/usb/host/xhci-plat.c -@@ -234,6 +234,7 @@ static const struct dev_pm_ops xhci_plat - - #ifdef CONFIG_OF - static const struct of_device_id usb_xhci_of_match[] = { -+ { .compatible = "generic-xhci" }, - { .compatible = "xhci-platform" }, - { }, - }; diff --git a/target/linux/sunxi/patches-3.14/196-usb-add-sunxi-phy-driver.patch b/target/linux/sunxi/patches-3.14/196-usb-add-sunxi-phy-driver.patch deleted file mode 100644 index 5f1ea836bd..0000000000 --- a/target/linux/sunxi/patches-3.14/196-usb-add-sunxi-phy-driver.patch +++ /dev/null @@ -1,410 +0,0 @@ -From 56feaa546c5ce4152fe14f725e9fc6b85f8a565b Mon Sep 17 00:00:00 2001 -From: Hans de Goede <hdegoede@redhat.com> -Date: Sat, 4 Jan 2014 23:56:17 +0100 -Subject: [PATCH] PHY: sunxi: Add driver for sunxi usb phy - -The Allwinner A1x / A2x SoCs have 2 or 3 usb phys which are all accessed -through a single set of registers. Besides this there are also some other -phy related bits which need poking, which are per phy, but shared between the -ohci and ehci controllers, so these are also controlled from this new phy -driver. - -Signed-off-by: Hans de Goede <hdegoede@redhat.com> -Acked-by: Maxime Ripard <maxime.ripard@free-electrons.com> ---- - .../devicetree/bindings/phy/sun4i-usb-phy.txt | 26 ++ - drivers/phy/Kconfig | 11 + - drivers/phy/Makefile | 1 + - drivers/phy/phy-sun4i-usb.c | 331 +++++++++++++++++++++ - 4 files changed, 369 insertions(+) - create mode 100644 Documentation/devicetree/bindings/phy/sun4i-usb-phy.txt - create mode 100644 drivers/phy/phy-sun4i-usb.c - ---- /dev/null -+++ b/Documentation/devicetree/bindings/phy/sun4i-usb-phy.txt -@@ -0,0 +1,26 @@ -+Allwinner sun4i USB PHY -+----------------------- -+ -+Required properties: -+- compatible : should be one of "allwinner,sun4i-a10-usb-phy", -+ "allwinner,sun5i-a13-usb-phy" or "allwinner,sun7i-a20-usb-phy" -+- reg : a list of offset + length pairs -+- reg-names : "phy_ctrl", "pmu1" and for sun4i or sun7i "pmu2" -+- #phy-cells : from the generic phy bindings, must be 1 -+- clocks : phandle + clock specifier for the phy clock -+- clock-names : "usb_phy" -+- resets : a list of phandle + reset specifier pairs -+- reset-names : "usb0_reset", "usb1_reset" and for sun4i or sun7i "usb2_reset" -+ -+Example: -+ usbphy: phy@0x01c13400 { -+ #phy-cells = <1>; -+ compatible = "allwinner,sun4i-a10-usb-phy"; -+ /* phy base regs, phy1 pmu reg, phy2 pmu reg */ -+ reg = <0x01c13400 0x10 0x01c14800 0x4 0x01c1c800 0x4>; -+ reg-names = "phy_ctrl", "pmu1", "pmu2"; -+ clocks = <&usb_clk 8>; -+ clock-names = "usb_phy"; -+ resets = <&usb_clk 1>, <&usb_clk 2>; -+ reset-names = "usb1_reset", "usb2_reset"; -+ }; ---- a/drivers/phy/Kconfig -+++ b/drivers/phy/Kconfig -@@ -65,4 +65,15 @@ config BCM_KONA_USB2_PHY - help - Enable this to support the Broadcom Kona USB 2.0 PHY. - -+config PHY_SUN4I_USB -+ tristate "Allwinner sunxi SoC USB PHY driver" -+ depends on ARCH_SUNXI && HAS_IOMEM && OF -+ select GENERIC_PHY -+ help -+ Enable this to support the transceiver that is part of Allwinner -+ sunxi SoCs. -+ -+ This driver controls the entire USB PHY block, both the USB OTG -+ parts, as well as the 2 regular USB 2 host PHYs. -+ - endmenu ---- a/drivers/phy/Makefile -+++ b/drivers/phy/Makefile -@@ -9,3 +9,4 @@ obj-$(CONFIG_PHY_EXYNOS_MIPI_VIDEO) += p - obj-$(CONFIG_PHY_MVEBU_SATA) += phy-mvebu-sata.o - obj-$(CONFIG_OMAP_USB2) += phy-omap-usb2.o - obj-$(CONFIG_TWL4030_USB) += phy-twl4030-usb.o -+obj-$(CONFIG_PHY_SUN4I_USB) += phy-sun4i-usb.o ---- /dev/null -+++ b/drivers/phy/phy-sun4i-usb.c -@@ -0,0 +1,331 @@ -+/* -+ * Allwinner sun4i USB phy driver -+ * -+ * Copyright (C) 2014 Hans de Goede <hdegoede@redhat.com> -+ * -+ * Based on code from -+ * Allwinner Technology Co., Ltd. <www.allwinnertech.com> -+ * -+ * Modelled after: Samsung S5P/EXYNOS SoC series MIPI CSIS/DSIM DPHY driver -+ * Copyright (C) 2013 Samsung Electronics Co., Ltd. -+ * Author: Sylwester Nawrocki <s.nawrocki@samsung.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. -+ */ -+ -+#include <linux/clk.h> -+#include <linux/io.h> -+#include <linux/kernel.h> -+#include <linux/module.h> -+#include <linux/mutex.h> -+#include <linux/of.h> -+#include <linux/of_address.h> -+#include <linux/phy/phy.h> -+#include <linux/platform_device.h> -+#include <linux/regulator/consumer.h> -+#include <linux/reset.h> -+ -+#define REG_ISCR 0x00 -+#define REG_PHYCTL 0x04 -+#define REG_PHYBIST 0x08 -+#define REG_PHYTUNE 0x0c -+ -+#define PHYCTL_DATA BIT(7) -+ -+#define SUNXI_AHB_ICHR8_EN BIT(10) -+#define SUNXI_AHB_INCR4_BURST_EN BIT(9) -+#define SUNXI_AHB_INCRX_ALIGN_EN BIT(8) -+#define SUNXI_ULPI_BYPASS_EN BIT(0) -+ -+/* Common Control Bits for Both PHYs */ -+#define PHY_PLL_BW 0x03 -+#define PHY_RES45_CAL_EN 0x0c -+ -+/* Private Control Bits for Each PHY */ -+#define PHY_TX_AMPLITUDE_TUNE 0x20 -+#define PHY_TX_SLEWRATE_TUNE 0x22 -+#define PHY_VBUSVALID_TH_SEL 0x25 -+#define PHY_PULLUP_RES_SEL 0x27 -+#define PHY_OTG_FUNC_EN 0x28 -+#define PHY_VBUS_DET_EN 0x29 -+#define PHY_DISCON_TH_SEL 0x2a -+ -+#define MAX_PHYS 3 -+ -+struct sun4i_usb_phy_data { -+ struct clk *clk; -+ void __iomem *base; -+ struct mutex mutex; -+ int num_phys; -+ u32 disc_thresh; -+ struct sun4i_usb_phy { -+ struct phy *phy; -+ void __iomem *pmu; -+ struct regulator *vbus; -+ struct reset_control *reset; -+ int index; -+ } phys[MAX_PHYS]; -+}; -+ -+#define to_sun4i_usb_phy_data(phy) \ -+ container_of((phy), struct sun4i_usb_phy_data, phys[(phy)->index]) -+ -+static void sun4i_usb_phy_write(struct sun4i_usb_phy *phy, u32 addr, u32 data, -+ int len) -+{ -+ struct sun4i_usb_phy_data *phy_data = to_sun4i_usb_phy_data(phy); -+ u32 temp, usbc_bit = BIT(phy->index * 2); -+ int i; -+ -+ mutex_lock(&phy_data->mutex); -+ -+ for (i = 0; i < len; i++) { -+ temp = readl(phy_data->base + REG_PHYCTL); -+ -+ /* clear the address portion */ -+ temp &= ~(0xff << 8); -+ -+ /* set the address */ -+ temp |= ((addr + i) << 8); -+ writel(temp, phy_data->base + REG_PHYCTL); -+ -+ /* set the data bit and clear usbc bit*/ -+ temp = readb(phy_data->base + REG_PHYCTL); -+ if (data & 0x1) -+ temp |= PHYCTL_DATA; -+ else -+ temp &= ~PHYCTL_DATA; -+ temp &= ~usbc_bit; -+ writeb(temp, phy_data->base + REG_PHYCTL); -+ -+ /* pulse usbc_bit */ -+ temp = readb(phy_data->base + REG_PHYCTL); -+ temp |= usbc_bit; -+ writeb(temp, phy_data->base + REG_PHYCTL); -+ -+ temp = readb(phy_data->base + REG_PHYCTL); -+ temp &= ~usbc_bit; -+ writeb(temp, phy_data->base + REG_PHYCTL); -+ -+ data >>= 1; -+ } -+ mutex_unlock(&phy_data->mutex); -+} -+ -+static void sun4i_usb_phy_passby(struct sun4i_usb_phy *phy, int enable) -+{ -+ u32 bits, reg_value; -+ -+ if (!phy->pmu) -+ return; -+ -+ bits = SUNXI_AHB_ICHR8_EN | SUNXI_AHB_INCR4_BURST_EN | -+ SUNXI_AHB_INCRX_ALIGN_EN | SUNXI_ULPI_BYPASS_EN; -+ -+ reg_value = readl(phy->pmu); -+ -+ if (enable) -+ reg_value |= bits; -+ else -+ reg_value &= ~bits; -+ -+ writel(reg_value, phy->pmu); -+} -+ -+static int sun4i_usb_phy_init(struct phy *_phy) -+{ -+ struct sun4i_usb_phy *phy = phy_get_drvdata(_phy); -+ struct sun4i_usb_phy_data *data = to_sun4i_usb_phy_data(phy); -+ int ret; -+ -+ ret = clk_prepare_enable(data->clk); -+ if (ret) -+ return ret; -+ -+ ret = reset_control_deassert(phy->reset); -+ if (ret) { -+ clk_disable_unprepare(data->clk); -+ return ret; -+ } -+ -+ /* Adjust PHY's magnitude and rate */ -+ sun4i_usb_phy_write(phy, PHY_TX_AMPLITUDE_TUNE, 0x14, 5); -+ -+ /* Disconnect threshold adjustment */ -+ sun4i_usb_phy_write(phy, PHY_DISCON_TH_SEL, data->disc_thresh, 2); -+ -+ sun4i_usb_phy_passby(phy, 1); -+ -+ return 0; -+} -+ -+static int sun4i_usb_phy_exit(struct phy *_phy) -+{ -+ struct sun4i_usb_phy *phy = phy_get_drvdata(_phy); -+ struct sun4i_usb_phy_data *data = to_sun4i_usb_phy_data(phy); -+ -+ sun4i_usb_phy_passby(phy, 0); -+ reset_control_assert(phy->reset); -+ clk_disable_unprepare(data->clk); -+ -+ return 0; -+} -+ -+static int sun4i_usb_phy_power_on(struct phy *_phy) -+{ -+ struct sun4i_usb_phy *phy = phy_get_drvdata(_phy); -+ int ret = 0; -+ -+ if (phy->vbus) -+ ret = regulator_enable(phy->vbus); -+ -+ return ret; -+} -+ -+static int sun4i_usb_phy_power_off(struct phy *_phy) -+{ -+ struct sun4i_usb_phy *phy = phy_get_drvdata(_phy); -+ -+ if (phy->vbus) -+ regulator_disable(phy->vbus); -+ -+ return 0; -+} -+ -+static struct phy_ops sun4i_usb_phy_ops = { -+ .init = sun4i_usb_phy_init, -+ .exit = sun4i_usb_phy_exit, -+ .power_on = sun4i_usb_phy_power_on, -+ .power_off = sun4i_usb_phy_power_off, -+ .owner = THIS_MODULE, -+}; -+ -+static struct phy *sun4i_usb_phy_xlate(struct device *dev, -+ struct of_phandle_args *args) -+{ -+ struct sun4i_usb_phy_data *data = dev_get_drvdata(dev); -+ -+ if (WARN_ON(args->args[0] == 0 || args->args[0] >= data->num_phys)) -+ return ERR_PTR(-ENODEV); -+ -+ return data->phys[args->args[0]].phy; -+} -+ -+static int sun4i_usb_phy_probe(struct platform_device *pdev) -+{ -+ struct sun4i_usb_phy_data *data; -+ struct device *dev = &pdev->dev; -+ struct device_node *np = dev->of_node; -+ void __iomem *pmu = NULL; -+ struct phy_provider *phy_provider; -+ struct reset_control *reset; -+ struct regulator *vbus; -+ struct resource *res; -+ struct phy *phy; -+ char name[16]; -+ int i; -+ -+ data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL); -+ if (!data) -+ return -ENOMEM; -+ -+ mutex_init(&data->mutex); -+ -+ if (of_device_is_compatible(np, "allwinner,sun5i-a13-usb-phy")) -+ data->num_phys = 2; -+ else -+ data->num_phys = 3; -+ -+ if (of_device_is_compatible(np, "allwinner,sun4i-a10-usb-phy")) -+ data->disc_thresh = 3; -+ else -+ data->disc_thresh = 2; -+ -+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "phy_ctrl"); -+ data->base = devm_ioremap_resource(dev, res); -+ if (IS_ERR(data->base)) -+ return PTR_ERR(data->base); -+ -+ data->clk = devm_clk_get(dev, "usb_phy"); -+ if (IS_ERR(data->clk)) { -+ dev_err(dev, "could not get usb_phy clock\n"); -+ return PTR_ERR(data->clk); -+ } -+ -+ /* Skip 0, 0 is the phy for otg which is not yet supported. */ -+ for (i = 1; i < data->num_phys; i++) { -+ snprintf(name, sizeof(name), "usb%d_vbus", i); -+ vbus = devm_regulator_get_optional(dev, name); -+ if (IS_ERR(vbus)) { -+ if (PTR_ERR(vbus) == -EPROBE_DEFER) -+ return -EPROBE_DEFER; -+ vbus = NULL; -+ } -+ -+ snprintf(name, sizeof(name), "usb%d_reset", i); -+ reset = devm_reset_control_get(dev, name); -+ if (IS_ERR(reset)) { -+ dev_err(dev, "failed to get reset %s\n", name); -+ return PTR_ERR(reset); -+ } -+ -+ if (i) { /* No pmu for usbc0 */ -+ snprintf(name, sizeof(name), "pmu%d", i); -+ res = platform_get_resource_byname(pdev, -+ IORESOURCE_MEM, name); -+ pmu = devm_ioremap_resource(dev, res); -+ if (IS_ERR(pmu)) -+ return PTR_ERR(pmu); -+ } -+ -+ phy = devm_phy_create(dev, &sun4i_usb_phy_ops, NULL); -+ if (IS_ERR(phy)) { -+ dev_err(dev, "failed to create PHY %d\n", i); -+ return PTR_ERR(phy); -+ } -+ -+ data->phys[i].phy = phy; -+ data->phys[i].pmu = pmu; -+ data->phys[i].vbus = vbus; -+ data->phys[i].reset = reset; -+ data->phys[i].index = i; -+ phy_set_drvdata(phy, &data->phys[i]); -+ } -+ -+ dev_set_drvdata(dev, data); -+ phy_provider = devm_of_phy_provider_register(dev, sun4i_usb_phy_xlate); -+ if (IS_ERR(phy_provider)) -+ return PTR_ERR(phy_provider); -+ -+ return 0; -+} -+ -+static const struct of_device_id sun4i_usb_phy_of_match[] = { -+ { .compatible = "allwinner,sun4i-a10-usb-phy" }, -+ { .compatible = "allwinner,sun5i-a13-usb-phy" }, -+ { .compatible = "allwinner,sun7i-a20-usb-phy" }, -+ { }, -+}; -+MODULE_DEVICE_TABLE(of, sun4i_usb_phy_of_match); -+ -+static struct platform_driver sun4i_usb_phy_driver = { -+ .probe = sun4i_usb_phy_probe, -+ .driver = { -+ .of_match_table = sun4i_usb_phy_of_match, -+ .name = "sun4i-usb-phy", -+ .owner = THIS_MODULE, -+ } -+}; -+module_platform_driver(sun4i_usb_phy_driver); -+ -+MODULE_DESCRIPTION("Allwinner sun4i USB phy driver"); -+MODULE_AUTHOR("Hans de Goede <hdegoede@redhat.com>"); -+MODULE_LICENSE("GPL v2"); diff --git a/target/linux/sunxi/patches-3.14/200-mmc-add-driver.patch b/target/linux/sunxi/patches-3.14/200-mmc-add-driver.patch deleted file mode 100644 index ece71540c3..0000000000 --- a/target/linux/sunxi/patches-3.14/200-mmc-add-driver.patch +++ /dev/null @@ -1,1150 +0,0 @@ -From a2fb45195f1b90058e96e09892c071ef4207b593 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?David=20Lanzend=C3=B6rfer?= <david.lanzendoerfer@o2s.ch> -Date: Sat, 22 Feb 2014 09:13:55 +0100 -Subject: [PATCH] ARM: sunxi: Add driver for SD/MMC hosts found on Allwinner - sunxi SoCs -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -This is based on the driver Allwinner ships in their Android kernel sources. - -Initial porting to upstream kernels done by David Lanzendörfer, additional -fixes and cleanups by Hans de Goede. - -It uses dma in bus-master mode using a built-in designware idmac controller, -which is identical to the one found in the mmc-dw hosts. -The rest of the host is not identical to mmc-dw. - -Signed-off-by: David Lanzendörfer <david.lanzendoerfer@o2s.ch> -Signed-off-by: Hans de Goede <hdegoede@redhat.com> ---- - drivers/mmc/host/Kconfig | 7 + - drivers/mmc/host/Makefile | 2 + - drivers/mmc/host/sunxi-mmc.c | 853 +++++++++++++++++++++++++++++++++++++++++++ - drivers/mmc/host/sunxi-mmc.h | 238 ++++++++++++ - 4 files changed, 1100 insertions(+) - create mode 100644 drivers/mmc/host/sunxi-mmc.c - create mode 100644 drivers/mmc/host/sunxi-mmc.h - ---- a/drivers/mmc/host/Kconfig -+++ b/drivers/mmc/host/Kconfig -@@ -714,3 +714,10 @@ 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 sunxi SD/MMC Host Controller support" -+ depends on ARCH_SUNXI -+ help -+ This selects support for the SD/MMC Host Controller on -+ Allwinner sunxi SoCs. ---- a/drivers/mmc/host/Makefile -+++ b/drivers/mmc/host/Makefile -@@ -55,6 +55,8 @@ obj-$(CONFIG_MMC_WMT) += wmt-sdmmc.o - - obj-$(CONFIG_MMC_REALTEK_PCI) += rtsx_pci_sdmmc.o - -+obj-$(CONFIG_MMC_SUNXI) += sunxi-mmc.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 ---- /dev/null -+++ b/drivers/mmc/host/sunxi-mmc.c -@@ -0,0 +1,853 @@ -+/* -+ * Driver for sunxi SD/MMC host controllers -+ * (C) Copyright 2007-2011 Reuuimlla Technology Co., Ltd. -+ * (C) Copyright 2007-2011 Aaron Maoye <leafy.myeh@reuuimllatech.com> -+ * (C) Copyright 2013-2014 O2S GmbH <www.o2s.ch> -+ * (C) Copyright 2013-2014 David Lanzendörfer <david.lanzendoerfer@o2s.ch> -+ * (C) Copyright 2013-2014 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. -+ */ -+ -+#include <linux/kernel.h> -+#include <linux/module.h> -+#include <linux/io.h> -+#include <linux/device.h> -+#include <linux/interrupt.h> -+#include <linux/delay.h> -+#include <linux/err.h> -+ -+#include <linux/clk.h> -+#include <linux/clk-private.h> -+#include <linux/clk/sunxi.h> -+ -+#include <linux/gpio.h> -+#include <linux/platform_device.h> -+#include <linux/spinlock.h> -+#include <linux/scatterlist.h> -+#include <linux/dma-mapping.h> -+#include <linux/slab.h> -+#include <linux/regulator/consumer.h> -+ -+#include <linux/of_address.h> -+#include <linux/of_gpio.h> -+#include <linux/of_platform.h> -+ -+#include <linux/mmc/host.h> -+#include <linux/mmc/sd.h> -+#include <linux/mmc/sdio.h> -+#include <linux/mmc/mmc.h> -+#include <linux/mmc/core.h> -+#include <linux/mmc/card.h> -+#include <linux/mmc/slot-gpio.h> -+ -+#include "sunxi-mmc.h" -+ -+static int sunxi_mmc_init_host(struct mmc_host *mmc) -+{ -+ u32 rval; -+ struct sunxi_mmc_host *smc_host = mmc_priv(mmc); -+ int ret; -+ -+ ret = clk_prepare_enable(smc_host->clk_ahb); -+ if (ret) { -+ dev_err(mmc_dev(smc_host->mmc), "AHB clk err %d\n", ret); -+ return ret; -+ } -+ ret = clk_prepare_enable(smc_host->clk_mod); -+ if (ret) { -+ dev_err(mmc_dev(smc_host->mmc), "MOD clk err %d\n", ret); -+ clk_disable_unprepare(smc_host->clk_ahb); -+ return ret; -+ } -+ -+ /* reset controller */ -+ rval = mci_readl(smc_host, REG_GCTRL) | SDXC_HARDWARE_RESET; -+ mci_writel(smc_host, REG_GCTRL, rval); -+ -+ mci_writel(smc_host, REG_FTRGL, 0x20070008); -+ mci_writel(smc_host, REG_TMOUT, 0xffffffff); -+ mci_writel(smc_host, REG_IMASK, smc_host->sdio_imask); -+ mci_writel(smc_host, REG_RINTR, 0xffffffff); -+ mci_writel(smc_host, REG_DBGC, 0xdeb); -+ mci_writel(smc_host, REG_FUNS, 0xceaa0000); -+ mci_writel(smc_host, REG_DLBA, smc_host->sg_dma); -+ rval = mci_readl(smc_host, REG_GCTRL)|SDXC_INTERRUPT_ENABLE_BIT; -+ rval &= ~SDXC_ACCESS_DONE_DIRECT; -+ mci_writel(smc_host, REG_GCTRL, rval); -+ -+ return 0; -+} -+ -+static void sunxi_mmc_exit_host(struct sunxi_mmc_host *smc_host) -+{ -+ mci_writel(smc_host, REG_GCTRL, SDXC_HARDWARE_RESET); -+ clk_disable_unprepare(smc_host->clk_ahb); -+ clk_disable_unprepare(smc_host->clk_mod); -+} -+ -+/* /\* UHS-I Operation Modes */ -+/* * DS 25MHz 12.5MB/s 3.3V */ -+/* * HS 50MHz 25MB/s 3.3V */ -+/* * SDR12 25MHz 12.5MB/s 1.8V */ -+/* * SDR25 50MHz 25MB/s 1.8V */ -+/* * SDR50 100MHz 50MB/s 1.8V */ -+/* * SDR104 208MHz 104MB/s 1.8V */ -+/* * DDR50 50MHz 50MB/s 1.8V */ -+/* * MMC Operation Modes */ -+/* * DS 26MHz 26MB/s 3/1.8/1.2V */ -+/* * HS 52MHz 52MB/s 3/1.8/1.2V */ -+/* * HSDDR 52MHz 104MB/s 3/1.8/1.2V */ -+/* * HS200 200MHz 200MB/s 1.8/1.2V */ -+/* * */ -+/* * Spec. Timing */ -+/* * SD3.0 */ -+/* * Fcclk Tcclk Fsclk Tsclk Tis Tih odly RTis RTih */ -+/* * 400K 2.5us 24M 41ns 5ns 5ns 1 2209ns 41ns */ -+/* * 25M 40ns 600M 1.67ns 5ns 5ns 3 14.99ns 5.01ns */ -+/* * 50M 20ns 600M 1.67ns 6ns 2ns 3 14.99ns 5.01ns */ -+/* * 50MDDR 20ns 600M 1.67ns 6ns 0.8ns 2 6.67ns 3.33ns */ -+/* * 104M 9.6ns 600M 1.67ns 3ns 0.8ns 1 7.93ns 1.67ns */ -+/* * 208M 4.8ns 600M 1.67ns 1.4ns 0.8ns 1 3.33ns 1.67ns */ -+ -+/* * 25M 40ns 300M 3.33ns 5ns 5ns 2 13.34ns 6.66ns */ -+/* * 50M 20ns 300M 3.33ns 6ns 2ns 2 13.34ns 6.66ns */ -+/* * 50MDDR 20ns 300M 3.33ns 6ns 0.8ns 1 6.67ns 3.33ns */ -+/* * 104M 9.6ns 300M 3.33ns 3ns 0.8ns 0 7.93ns 1.67ns */ -+/* * 208M 4.8ns 300M 3.33ns 1.4ns 0.8ns 0 3.13ns 1.67ns */ -+ -+/* * eMMC4.5 */ -+/* * 400K 2.5us 24M 41ns 3ns 3ns 1 2209ns 41ns */ -+/* * 25M 40ns 600M 1.67ns 3ns 3ns 3 14.99ns 5.01ns */ -+/* * 50M 20ns 600M 1.67ns 3ns 3ns 3 14.99ns 5.01ns */ -+/* * 50MDDR 20ns 600M 1.67ns 2.5ns 2.5ns 2 6.67ns 3.33ns */ -+/* * 200M 5ns 600M 1.67ns 1.4ns 0.8ns 1 3.33ns 1.67ns */ -+/* *\/ */ -+ -+static void sunxi_mmc_init_idma_des(struct sunxi_mmc_host *host, -+ struct mmc_data *data) -+{ -+ struct sunxi_idma_des *pdes = (struct sunxi_idma_des *)host->sg_cpu; -+ struct sunxi_idma_des *pdes_pa = (struct sunxi_idma_des *)host->sg_dma; -+ int i, max_len = (1 << host->idma_des_size_bits); -+ -+ for (i = 0; i < data->sg_len; i++) { -+ pdes[i].config = SDXC_IDMAC_DES0_CH | SDXC_IDMAC_DES0_OWN | -+ SDXC_IDMAC_DES0_DIC; -+ -+ if (data->sg[i].length == max_len) -+ pdes[i].buf_size = 0; /* 0 == max_len */ -+ else -+ pdes[i].buf_size = data->sg[i].length; -+ -+ pdes[i].buf_addr_ptr1 = sg_dma_address(&data->sg[i]); -+ pdes[i].buf_addr_ptr2 = (u32)&pdes_pa[i + 1]; -+ } -+ -+ pdes[0].config |= SDXC_IDMAC_DES0_FD; -+ pdes[i - 1].config = SDXC_IDMAC_DES0_OWN | SDXC_IDMAC_DES0_LD; -+ -+ wmb(); /* Ensure idma_des hit main mem before we start the idmac */ -+} -+ -+static enum dma_data_direction sunxi_mmc_get_dma_dir(struct mmc_data *data) -+{ -+ if (data->flags & MMC_DATA_WRITE) -+ return DMA_TO_DEVICE; -+ else -+ return DMA_FROM_DEVICE; -+} -+ -+static int sunxi_mmc_prepare_dma(struct sunxi_mmc_host *smc_host, -+ struct mmc_data *data) -+{ -+ u32 dma_len; -+ u32 i; -+ u32 temp; -+ struct scatterlist *sg; -+ -+ dma_len = dma_map_sg(mmc_dev(smc_host->mmc), data->sg, data->sg_len, -+ sunxi_mmc_get_dma_dir(data)); -+ if (dma_len == 0) { -+ dev_err(mmc_dev(smc_host->mmc), "dma_map_sg failed\n"); -+ return -ENOMEM; -+ } -+ -+ for_each_sg(data->sg, sg, data->sg_len, i) { -+ if (sg->offset & 3 || sg->length & 3) { -+ dev_err(mmc_dev(smc_host->mmc), -+ "unaligned scatterlist: os %x length %d\n", -+ sg->offset, sg->length); -+ return -EINVAL; -+ } -+ } -+ -+ sunxi_mmc_init_idma_des(smc_host, data); -+ -+ temp = mci_readl(smc_host, REG_GCTRL); -+ temp |= SDXC_DMA_ENABLE_BIT; -+ mci_writel(smc_host, REG_GCTRL, temp); -+ temp |= SDXC_DMA_RESET; -+ mci_writel(smc_host, REG_GCTRL, temp); -+ mci_writel(smc_host, REG_DMAC, SDXC_IDMAC_SOFT_RESET); -+ -+ if (!(data->flags & MMC_DATA_WRITE)) -+ mci_writel(smc_host, REG_IDIE, SDXC_IDMAC_RECEIVE_INTERRUPT); -+ -+ mci_writel(smc_host, REG_DMAC, SDXC_IDMAC_FIX_BURST | SDXC_IDMAC_IDMA_ON); -+ -+ return 0; -+} -+ -+static void sunxi_mmc_send_manual_stop(struct sunxi_mmc_host *host, -+ struct mmc_request *req) -+{ -+ u32 cmd_val = SDXC_START | SDXC_RESP_EXPIRE | SDXC_STOP_ABORT_CMD -+ | SDXC_CHECK_RESPONSE_CRC | MMC_STOP_TRANSMISSION; -+ u32 ri = 0; -+ unsigned long expire = jiffies + msecs_to_jiffies(1000); -+ -+ mci_writel(host, REG_CARG, 0); -+ mci_writel(host, REG_CMDR, cmd_val); -+ -+ do { -+ ri = mci_readl(host, REG_RINTR); -+ } while (!(ri & (SDXC_COMMAND_DONE | SDXC_INTERRUPT_ERROR_BIT)) && -+ time_before(jiffies, expire)); -+ -+ if (ri & SDXC_INTERRUPT_ERROR_BIT) { -+ dev_err(mmc_dev(host->mmc), "send stop command failed\n"); -+ if (req->stop) -+ req->stop->resp[0] = -ETIMEDOUT; -+ } else { -+ if (req->stop) -+ req->stop->resp[0] = mci_readl(host, REG_RESP0); -+ } -+ -+ mci_writel(host, REG_RINTR, 0xffff); -+} -+ -+static void sunxi_mmc_dump_errinfo(struct sunxi_mmc_host *smc_host) -+{ -+ struct mmc_command *cmd = smc_host->mrq->cmd; -+ struct mmc_data *data = smc_host->mrq->data; -+ -+ /* For some cmds timeout is normal with sd/mmc cards */ -+ if ((smc_host->int_sum & SDXC_INTERRUPT_ERROR_BIT) == SDXC_RESP_TIMEOUT && -+ (cmd->opcode == SD_IO_SEND_OP_COND || cmd->opcode == SD_IO_RW_DIRECT)) -+ return; -+ -+ dev_err(mmc_dev(smc_host->mmc), -+ "smc %d err, cmd %d,%s%s%s%s%s%s%s%s%s%s !!\n", -+ smc_host->mmc->index, cmd->opcode, -+ data ? (data->flags & MMC_DATA_WRITE ? " WR" : " RD") : "", -+ smc_host->int_sum & SDXC_RESP_ERROR ? " RE" : "", -+ smc_host->int_sum & SDXC_RESP_CRC_ERROR ? " RCE" : "", -+ smc_host->int_sum & SDXC_DATA_CRC_ERROR ? " DCE" : "", -+ smc_host->int_sum & SDXC_RESP_TIMEOUT ? " RTO" : "", -+ smc_host->int_sum & SDXC_DATA_TIMEOUT ? " DTO" : "", -+ smc_host->int_sum & SDXC_FIFO_RUN_ERROR ? " FE" : "", -+ smc_host->int_sum & SDXC_HARD_WARE_LOCKED ? " HL" : "", -+ smc_host->int_sum & SDXC_START_BIT_ERROR ? " SBE" : "", -+ smc_host->int_sum & SDXC_END_BIT_ERROR ? " EBE" : "" -+ ); -+} -+ -+static void sunxi_mmc_finalize_request(struct sunxi_mmc_host *host) -+{ -+ struct mmc_request *mrq; -+ unsigned long iflags; -+ -+ spin_lock_irqsave(&host->lock, iflags); -+ -+ mrq = host->mrq; -+ if (!mrq) { -+ spin_unlock_irqrestore(&host->lock, iflags); -+ dev_err(mmc_dev(host->mmc), "no request to finalize\n"); -+ return; -+ } -+ -+ if (host->int_sum & SDXC_INTERRUPT_ERROR_BIT) { -+ sunxi_mmc_dump_errinfo(host); -+ mrq->cmd->error = -ETIMEDOUT; -+ if (mrq->data) -+ mrq->data->error = -ETIMEDOUT; -+ if (mrq->stop) -+ mrq->stop->error = -ETIMEDOUT; -+ } else { -+ if (mrq->cmd->flags & MMC_RSP_136) { -+ mrq->cmd->resp[0] = mci_readl(host, REG_RESP3); -+ mrq->cmd->resp[1] = mci_readl(host, REG_RESP2); -+ mrq->cmd->resp[2] = mci_readl(host, REG_RESP1); -+ mrq->cmd->resp[3] = mci_readl(host, REG_RESP0); -+ } else { -+ mrq->cmd->resp[0] = mci_readl(host, REG_RESP0); -+ } -+ if (mrq->data) -+ mrq->data->bytes_xfered = -+ mrq->data->blocks * mrq->data->blksz; -+ } -+ -+ if (mrq->data) { -+ struct mmc_data *data = mrq->data; -+ u32 temp; -+ -+ mci_writel(host, REG_IDST, 0x337); -+ mci_writel(host, REG_DMAC, 0); -+ temp = mci_readl(host, REG_GCTRL); -+ mci_writel(host, REG_GCTRL, temp|SDXC_DMA_RESET); -+ temp &= ~SDXC_DMA_ENABLE_BIT; -+ mci_writel(host, REG_GCTRL, temp); -+ temp |= SDXC_FIFO_RESET; -+ mci_writel(host, REG_GCTRL, temp); -+ dma_unmap_sg(mmc_dev(host->mmc), data->sg, data->sg_len, -+ sunxi_mmc_get_dma_dir(data)); -+ } -+ -+ mci_writel(host, REG_RINTR, 0xffff); -+ -+ dev_dbg(mmc_dev(host->mmc), "req done, resp %08x %08x %08x %08x\n", -+ mrq->cmd->resp[0], mrq->cmd->resp[1], -+ mrq->cmd->resp[2], mrq->cmd->resp[3]); -+ -+ host->mrq = NULL; -+ host->int_sum = 0; -+ host->wait_dma = 0; -+ -+ spin_unlock_irqrestore(&host->lock, iflags); -+ -+ if (mrq->data && mrq->data->error) { -+ dev_err(mmc_dev(host->mmc), -+ "data error, sending stop command\n"); -+ sunxi_mmc_send_manual_stop(host, mrq); -+ } -+ -+ mmc_request_done(host->mmc, mrq); -+} -+ -+static irqreturn_t sunxi_mmc_irq(int irq, void *dev_id) -+{ -+ struct sunxi_mmc_host *host = dev_id; -+ u32 finalize = 0; -+ u32 sdio_int = 0; -+ u32 msk_int; -+ u32 idma_int; -+ -+ spin_lock(&host->lock); -+ -+ idma_int = mci_readl(host, REG_IDST); -+ msk_int = mci_readl(host, REG_MISTA); -+ -+ dev_dbg(mmc_dev(host->mmc), "irq: rq %p mi %08x idi %08x\n", -+ host->mrq, msk_int, idma_int); -+ -+ if (host->mrq) { -+ if (idma_int & SDXC_IDMAC_RECEIVE_INTERRUPT) -+ host->wait_dma = 0; -+ -+ host->int_sum |= msk_int; -+ -+ /* Wait for COMMAND_DONE on RESPONSE_TIMEOUT before finishing the req */ -+ if ((host->int_sum & SDXC_RESP_TIMEOUT) && -+ !(host->int_sum & SDXC_COMMAND_DONE)) -+ mci_writel(host, REG_IMASK, -+ host->sdio_imask | SDXC_COMMAND_DONE); -+ else if (host->int_sum & SDXC_INTERRUPT_ERROR_BIT) -+ finalize = 1; /* Don't wait for dma on error */ -+ else if (host->int_sum & SDXC_INTERRUPT_DONE_BIT && !host->wait_dma) -+ finalize = 1; /* Done */ -+ -+ if (finalize) { -+ mci_writel(host, REG_IMASK, host->sdio_imask); -+ mci_writel(host, REG_IDIE, 0); -+ } -+ } -+ -+ if (msk_int & SDXC_SDIO_INTERRUPT) -+ sdio_int = 1; -+ -+ mci_writel(host, REG_RINTR, msk_int); -+ mci_writel(host, REG_IDST, idma_int); -+ -+ spin_unlock(&host->lock); -+ -+ if (finalize) -+ tasklet_schedule(&host->tasklet); -+ -+ if (sdio_int) -+ mmc_signal_sdio_irq(host->mmc); -+ -+ return IRQ_HANDLED; -+} -+ -+static void sunxi_mmc_tasklet(unsigned long data) -+{ -+ struct sunxi_mmc_host *smc_host = (struct sunxi_mmc_host *) data; -+ sunxi_mmc_finalize_request(smc_host); -+} -+ -+static void sunxi_mmc_oclk_onoff(struct sunxi_mmc_host *host, u32 oclk_en) -+{ -+ unsigned long expire = jiffies + msecs_to_jiffies(2000); -+ u32 rval; -+ -+ rval = mci_readl(host, REG_CLKCR); -+ rval &= ~(SDXC_CARD_CLOCK_ON | SDXC_LOW_POWER_ON); -+ -+ if (oclk_en) -+ rval |= SDXC_CARD_CLOCK_ON; -+ -+ mci_writel(host, REG_CLKCR, rval); -+ -+ rval = SDXC_START | SDXC_UPCLK_ONLY | SDXC_WAIT_PRE_OVER; -+ if (host->voltage_switching) -+ rval |= SDXC_VOLTAGE_SWITCH; -+ mci_writel(host, REG_CMDR, rval); -+ -+ do { -+ rval = mci_readl(host, REG_CMDR); -+ } while (time_before(jiffies, expire) && (rval & SDXC_START)); -+ -+ if (rval & SDXC_START) { -+ dev_err(mmc_dev(host->mmc), "fatal err update clk timeout\n"); -+ host->ferror = 1; -+ } -+} -+ -+struct sunxi_mmc_clk_dly mmc_clk_dly[MMC_CLK_MOD_NUM] = { -+ { MMC_CLK_400K, 0, 7 }, -+ { MMC_CLK_25M, 0, 5 }, -+ { MMC_CLK_50M, 3, 5 }, -+ { MMC_CLK_50MDDR, 2, 4 }, -+ { MMC_CLK_50MDDR_8BIT, 2, 4 }, -+ { MMC_CLK_100M, 1, 4 }, -+ { MMC_CLK_200M, 1, 4 }, -+}; -+ -+static void sunxi_mmc_clk_set_rate(struct sunxi_mmc_host *smc_host, -+ unsigned int rate) -+{ -+ u32 newrate; -+ u32 src_clk; -+ u32 oclk_dly; -+ u32 sclk_dly; -+ u32 temp; -+ struct sunxi_mmc_clk_dly *dly = NULL; -+ struct clk_hw *hw = __clk_get_hw(smc_host->clk_mod); -+ -+ newrate = clk_round_rate(smc_host->clk_mod, rate); -+ if (smc_host->clk_mod_rate == newrate) { -+ dev_dbg(mmc_dev(smc_host->mmc), "clk already %d, rounded %d\n", -+ rate, newrate); -+ return; -+ } -+ -+ dev_dbg(mmc_dev(smc_host->mmc), "setting clk to %d, rounded %d\n", -+ rate, newrate); -+ -+ /* setting clock rate */ -+ clk_disable(smc_host->clk_mod); -+ clk_set_rate(smc_host->clk_mod, newrate); -+ clk_enable(smc_host->clk_mod); -+ smc_host->clk_mod_rate = newrate = clk_get_rate(smc_host->clk_mod); -+ dev_dbg(mmc_dev(smc_host->mmc), "clk is now %d\n", newrate); -+ -+ sunxi_mmc_oclk_onoff(smc_host, 0); -+ /* clear internal divider */ -+ temp = mci_readl(smc_host, REG_CLKCR); -+ temp &= ~0xff; -+ mci_writel(smc_host, REG_CLKCR, temp); -+ -+ /* determine delays */ -+ if (rate <= 400000) { -+ dly = &mmc_clk_dly[MMC_CLK_400K]; -+ } else if (rate <= 25000000) { -+ dly = &mmc_clk_dly[MMC_CLK_25M]; -+ } else if (rate <= 50000000) { -+ if (smc_host->ddr) { -+ if (smc_host->bus_width == 8) -+ dly = &mmc_clk_dly[MMC_CLK_50MDDR_8BIT]; -+ else -+ dly = &mmc_clk_dly[MMC_CLK_50MDDR]; -+ } else { -+ dly = &mmc_clk_dly[MMC_CLK_50M]; -+ } -+ } else if (rate <= 104000000) { -+ dly = &mmc_clk_dly[MMC_CLK_100M]; -+ } else if (rate <= 208000000) { -+ dly = &mmc_clk_dly[MMC_CLK_200M]; -+ } else { -+ dly = &mmc_clk_dly[MMC_CLK_50M]; -+ } -+ -+ oclk_dly = dly->oclk_dly; -+ sclk_dly = dly->sclk_dly; -+ -+ src_clk = clk_get_rate(clk_get_parent(smc_host->clk_mod)); -+ -+ if (src_clk >= 300000000 && src_clk <= 400000000) { -+ if (oclk_dly) -+ oclk_dly--; -+ if (sclk_dly) -+ sclk_dly--; -+ } -+ -+ clk_sunxi_mmc_phase_control(hw, sclk_dly, oclk_dly); -+ sunxi_mmc_oclk_onoff(smc_host, 1); -+ -+ /* oclk_onoff sets various irq status bits, clear these */ -+ mci_writel(smc_host, REG_RINTR, -+ mci_readl(smc_host, REG_RINTR) & ~SDXC_SDIO_INTERRUPT); -+} -+ -+static void sunxi_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) -+{ -+ struct sunxi_mmc_host *host = mmc_priv(mmc); -+ u32 temp; -+ s32 err; -+ -+ /* Set the power state */ -+ switch (ios->power_mode) { -+ case MMC_POWER_ON: -+ break; -+ -+ case MMC_POWER_UP: -+ if (!IS_ERR(host->vmmc)) { -+ mmc_regulator_set_ocr(host->mmc, host->vmmc, ios->vdd); -+ udelay(200); -+ } -+ -+ err = sunxi_mmc_init_host(mmc); -+ if (err) { -+ host->ferror = 1; -+ return; -+ } -+ enable_irq(host->irq); -+ -+ dev_dbg(mmc_dev(host->mmc), "power on!\n"); -+ host->ferror = 0; -+ break; -+ -+ case MMC_POWER_OFF: -+ dev_dbg(mmc_dev(host->mmc), "power off!\n"); -+ disable_irq(host->irq); -+ sunxi_mmc_exit_host(host); -+ if (!IS_ERR(host->vmmc)) -+ mmc_regulator_set_ocr(host->mmc, host->vmmc, 0); -+ host->ferror = 0; -+ break; -+ } -+ -+ /* set bus width */ -+ switch (ios->bus_width) { -+ case MMC_BUS_WIDTH_1: -+ mci_writel(host, REG_WIDTH, SDXC_WIDTH1); -+ host->bus_width = 1; -+ break; -+ case MMC_BUS_WIDTH_4: -+ mci_writel(host, REG_WIDTH, SDXC_WIDTH4); -+ host->bus_width = 4; -+ break; -+ case MMC_BUS_WIDTH_8: -+ mci_writel(host, REG_WIDTH, SDXC_WIDTH8); -+ host->bus_width = 8; -+ break; -+ } -+ -+ /* set ddr mode */ -+ temp = mci_readl(host, REG_GCTRL); -+ if (ios->timing == MMC_TIMING_UHS_DDR50) { -+ temp |= SDXC_DDR_MODE; -+ host->ddr = 1; -+ } else { -+ temp &= ~SDXC_DDR_MODE; -+ host->ddr = 0; -+ } -+ mci_writel(host, REG_GCTRL, temp); -+ -+ /* set up clock */ -+ if (ios->clock && ios->power_mode) { -+ dev_dbg(mmc_dev(host->mmc), "ios->clock: %d\n", ios->clock); -+ sunxi_mmc_clk_set_rate(host, ios->clock); -+ usleep_range(50000, 55000); -+ } -+} -+ -+static void sunxi_mmc_enable_sdio_irq(struct mmc_host *mmc, int enable) -+{ -+ struct sunxi_mmc_host *smc_host = mmc_priv(mmc); -+ unsigned long flags; -+ u32 imask; -+ -+ spin_lock_irqsave(&smc_host->lock, flags); -+ -+ imask = mci_readl(smc_host, REG_IMASK); -+ if (enable) { -+ smc_host->sdio_imask = SDXC_SDIO_INTERRUPT; -+ imask |= SDXC_SDIO_INTERRUPT; -+ } else { -+ smc_host->sdio_imask = 0; -+ imask &= ~SDXC_SDIO_INTERRUPT; -+ } -+ mci_writel(smc_host, REG_IMASK, imask); -+ spin_unlock_irqrestore(&smc_host->lock, flags); -+} -+ -+static void sunxi_mmc_hw_reset(struct mmc_host *mmc) -+{ -+ struct sunxi_mmc_host *smc_host = mmc_priv(mmc); -+ mci_writel(smc_host, REG_HWRST, 0); -+ udelay(10); -+ mci_writel(smc_host, REG_HWRST, 1); -+ udelay(300); -+} -+ -+static void sunxi_mmc_request(struct mmc_host *mmc, struct mmc_request *mrq) -+{ -+ struct sunxi_mmc_host *host = mmc_priv(mmc); -+ struct mmc_command *cmd = mrq->cmd; -+ struct mmc_data *data = mrq->data; -+ unsigned long iflags; -+ u32 imask = SDXC_INTERRUPT_ERROR_BIT; -+ u32 cmd_val = SDXC_START | (cmd->opcode & 0x3f); -+ u32 byte_cnt = 0; -+ int ret; -+ -+ if (!mmc_gpio_get_cd(mmc) || host->ferror) { -+ dev_dbg(mmc_dev(host->mmc), "no medium present\n"); -+ mrq->cmd->error = -ENOMEDIUM; -+ mmc_request_done(mmc, mrq); -+ return; -+ } -+ -+ if (data) { -+ byte_cnt = data->blksz * data->blocks; -+ mci_writel(host, REG_BLKSZ, data->blksz); -+ mci_writel(host, REG_BCNTR, byte_cnt); -+ ret = sunxi_mmc_prepare_dma(host, data); -+ if (ret < 0) { -+ dev_err(mmc_dev(host->mmc), "prepare DMA failed\n"); -+ cmd->error = ret; -+ cmd->data->error = ret; -+ mmc_request_done(host->mmc, mrq); -+ return; -+ } -+ } -+ -+ if (cmd->opcode == MMC_GO_IDLE_STATE) { -+ cmd_val |= SDXC_SEND_INIT_SEQUENCE; -+ imask |= SDXC_COMMAND_DONE; -+ } -+ -+ if (cmd->opcode == SD_SWITCH_VOLTAGE) { -+ cmd_val |= SDXC_VOLTAGE_SWITCH; -+ imask |= SDXC_VOLTAGE_CHANGE_DONE; -+ host->voltage_switching = 1; -+ sunxi_mmc_oclk_onoff(host, 1); -+ } -+ -+ if (cmd->flags & MMC_RSP_PRESENT) { -+ cmd_val |= SDXC_RESP_EXPIRE; -+ if (cmd->flags & MMC_RSP_136) -+ cmd_val |= SDXC_LONG_RESPONSE; -+ if (cmd->flags & MMC_RSP_CRC) -+ cmd_val |= SDXC_CHECK_RESPONSE_CRC; -+ -+ if ((cmd->flags & MMC_CMD_MASK) == MMC_CMD_ADTC) { -+ cmd_val |= SDXC_DATA_EXPIRE | SDXC_WAIT_PRE_OVER; -+ if (cmd->data->flags & MMC_DATA_STREAM) { -+ imask |= SDXC_AUTO_COMMAND_DONE; -+ cmd_val |= SDXC_SEQUENCE_MODE | SDXC_SEND_AUTO_STOP; -+ } -+ if (cmd->data->stop) { -+ imask |= SDXC_AUTO_COMMAND_DONE; -+ cmd_val |= SDXC_SEND_AUTO_STOP; -+ } else -+ imask |= SDXC_DATA_OVER; -+ -+ if (cmd->data->flags & MMC_DATA_WRITE) -+ cmd_val |= SDXC_WRITE; -+ else -+ host->wait_dma = 1; -+ } else -+ imask |= SDXC_COMMAND_DONE; -+ } else -+ imask |= SDXC_COMMAND_DONE; -+ -+ dev_dbg(mmc_dev(host->mmc), "cmd %d(%08x) arg %x ie 0x%08x len %d\n", -+ cmd_val & 0x3f, cmd_val, cmd->arg, imask, -+ mrq->data ? mrq->data->blksz * mrq->data->blocks : 0); -+ -+ spin_lock_irqsave(&host->lock, iflags); -+ host->mrq = mrq; -+ mci_writel(host, REG_IMASK, host->sdio_imask | imask); -+ spin_unlock_irqrestore(&host->lock, iflags); -+ -+ mci_writel(host, REG_CARG, cmd->arg); -+ mci_writel(host, REG_CMDR, cmd_val); -+} -+ -+static const struct of_device_id sunxi_mmc_of_match[] = { -+ { .compatible = "allwinner,sun4i-a10-mmc", }, -+ { .compatible = "allwinner,sun5i-a13-mmc", }, -+ { /* sentinel */ } -+}; -+MODULE_DEVICE_TABLE(of, sunxi_mmc_of_match); -+ -+static struct mmc_host_ops sunxi_mmc_ops = { -+ .request = sunxi_mmc_request, -+ .set_ios = sunxi_mmc_set_ios, -+ .get_ro = mmc_gpio_get_ro, -+ .get_cd = mmc_gpio_get_cd, -+ .enable_sdio_irq = sunxi_mmc_enable_sdio_irq, -+ .hw_reset = sunxi_mmc_hw_reset, -+}; -+ -+static int sunxi_mmc_resource_request(struct sunxi_mmc_host *host, -+ struct platform_device *pdev) -+{ -+ struct device_node *np = pdev->dev.of_node; -+ int ret; -+ -+ if (of_device_is_compatible(np, "allwinner,sun4i-a10-mmc")) -+ host->idma_des_size_bits = 13; -+ else -+ host->idma_des_size_bits = 16; -+ -+ host->vmmc = devm_regulator_get_optional(&pdev->dev, "vmmc"); -+ if (IS_ERR(host->vmmc) && PTR_ERR(host->vmmc) == -EPROBE_DEFER) -+ return -EPROBE_DEFER; -+ -+ host->reg_base = devm_ioremap_resource(&pdev->dev, -+ platform_get_resource(pdev, IORESOURCE_MEM, 0)); -+ if (IS_ERR(host->reg_base)) -+ return PTR_ERR(host->reg_base); -+ -+ host->clk_ahb = devm_clk_get(&pdev->dev, "ahb"); -+ if (IS_ERR(host->clk_ahb)) { -+ dev_err(&pdev->dev, "Could not get ahb clock\n"); -+ return PTR_ERR(host->clk_ahb); -+ } -+ -+ host->clk_mod = devm_clk_get(&pdev->dev, "mod"); -+ if (IS_ERR(host->clk_mod)) { -+ dev_err(&pdev->dev, "Could not get mod clock\n"); -+ return PTR_ERR(host->clk_mod); -+ } -+ -+ /* Make sure the controller is in a sane state before enabling irqs */ -+ ret = sunxi_mmc_init_host(host->mmc); -+ if (ret) -+ return ret; -+ -+ host->irq = platform_get_irq(pdev, 0); -+ ret = devm_request_irq(&pdev->dev, host->irq, sunxi_mmc_irq, 0, -+ "sunxi-mmc", host); -+ if (ret == 0) -+ disable_irq(host->irq); -+ -+ /* And put it back in reset */ -+ sunxi_mmc_exit_host(host); -+ -+ return ret; -+} -+ -+static int sunxi_mmc_probe(struct platform_device *pdev) -+{ -+ struct sunxi_mmc_host *host; -+ struct mmc_host *mmc; -+ int ret; -+ -+ mmc = mmc_alloc_host(sizeof(struct sunxi_mmc_host), &pdev->dev); -+ if (!mmc) { -+ dev_err(&pdev->dev, "mmc alloc host failed\n"); -+ return -ENOMEM; -+ } -+ -+ host = mmc_priv(mmc); -+ host->mmc = mmc; -+ spin_lock_init(&host->lock); -+ tasklet_init(&host->tasklet, sunxi_mmc_tasklet, (unsigned long)host); -+ -+ ret = sunxi_mmc_resource_request(host, pdev); -+ if (ret) -+ goto error_free_host; -+ -+ host->sg_cpu = dma_alloc_coherent(&pdev->dev, PAGE_SIZE, -+ &host->sg_dma, GFP_KERNEL); -+ if (!host->sg_cpu) { -+ dev_err(&pdev->dev, "Failed to allocate DMA descriptor mem\n"); -+ ret = -ENOMEM; -+ goto error_free_host; -+ } -+ -+ mmc->ops = &sunxi_mmc_ops; -+ mmc->max_blk_count = 8192; -+ mmc->max_blk_size = 4096; -+ mmc->max_segs = PAGE_SIZE / sizeof(struct sunxi_idma_des); -+ mmc->max_seg_size = (1 << host->idma_des_size_bits); -+ mmc->max_req_size = mmc->max_seg_size * mmc->max_segs; -+ /* 400kHz ~ 50MHz */ -+ mmc->f_min = 400000; -+ mmc->f_max = 50000000; -+ /* available voltages */ -+ if (!IS_ERR(host->vmmc)) -+ mmc->ocr_avail = mmc_regulator_get_ocrmask(host->vmmc); -+ else -+ mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34; -+ -+ mmc->caps |= MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED | -+ MMC_CAP_SDIO_IRQ; -+ mmc->caps2 |= MMC_CAP2_NO_PRESCAN_POWERUP; -+ -+ ret = mmc_of_parse(mmc); -+ if (ret) -+ goto error_free_dma; -+ -+ ret = mmc_add_host(mmc); -+ if (ret) -+ goto error_free_dma; -+ -+ dev_info(&pdev->dev, "base:0x%p irq:%u\n", host->reg_base, host->irq); -+ platform_set_drvdata(pdev, mmc); -+ return 0; -+ -+error_free_dma: -+ dma_free_coherent(&pdev->dev, PAGE_SIZE, host->sg_cpu, host->sg_dma); -+error_free_host: -+ mmc_free_host(mmc); -+ return ret; -+} -+ -+static int sunxi_mmc_remove(struct platform_device *pdev) -+{ -+ struct mmc_host *mmc = platform_get_drvdata(pdev); -+ struct sunxi_mmc_host *host = mmc_priv(mmc); -+ -+ mmc_remove_host(mmc); -+ sunxi_mmc_exit_host(host); -+ tasklet_disable(&host->tasklet); -+ dma_free_coherent(&pdev->dev, PAGE_SIZE, host->sg_cpu, host->sg_dma); -+ mmc_free_host(mmc); -+ -+ return 0; -+} -+ -+static struct platform_driver sunxi_mmc_driver = { -+ .driver = { -+ .name = "sunxi-mmc", -+ .owner = THIS_MODULE, -+ .of_match_table = of_match_ptr(sunxi_mmc_of_match), -+ }, -+ .probe = sunxi_mmc_probe, -+ .remove = sunxi_mmc_remove, -+}; -+module_platform_driver(sunxi_mmc_driver); -+ -+MODULE_DESCRIPTION("Allwinner's SD/MMC Card Controller Driver"); -+MODULE_LICENSE("GPL v2"); -+MODULE_AUTHOR("David Lanzendörfer <david.lanzendoerfer@o2s.ch>"); -+MODULE_ALIAS("platform:sunxi-mmc"); ---- /dev/null -+++ b/drivers/mmc/host/sunxi-mmc.h -@@ -0,0 +1,238 @@ -+/* -+ * Driver for sunxi SD/MMC host controllers -+ * (C) Copyright 2007-2011 Reuuimlla Technology Co., Ltd. -+ * (C) Copyright 2007-2011 Aaron Maoye <leafy.myeh@reuuimllatech.com> -+ * (C) Copyright 2013-2014 O2S GmbH <www.o2s.ch> -+ * (C) Copyright 2013-2014 David Lanzendörfer <david.lanzendoerfer@o2s.ch> -+ * (C) Copyright 2013-2014 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. -+ */ -+ -+#ifndef __SUNXI_MMC_H__ -+#define __SUNXI_MMC_H__ -+ -+/* register offset definitions */ -+#define SDXC_REG_GCTRL (0x00) /* SMC Global Control Register */ -+#define SDXC_REG_CLKCR (0x04) /* SMC Clock Control Register */ -+#define SDXC_REG_TMOUT (0x08) /* SMC Time Out Register */ -+#define SDXC_REG_WIDTH (0x0C) /* SMC Bus Width Register */ -+#define SDXC_REG_BLKSZ (0x10) /* SMC Block Size Register */ -+#define SDXC_REG_BCNTR (0x14) /* SMC Byte Count Register */ -+#define SDXC_REG_CMDR (0x18) /* SMC Command Register */ -+#define SDXC_REG_CARG (0x1C) /* SMC Argument Register */ -+#define SDXC_REG_RESP0 (0x20) /* SMC Response Register 0 */ -+#define SDXC_REG_RESP1 (0x24) /* SMC Response Register 1 */ -+#define SDXC_REG_RESP2 (0x28) /* SMC Response Register 2 */ -+#define SDXC_REG_RESP3 (0x2C) /* SMC Response Register 3 */ -+#define SDXC_REG_IMASK (0x30) /* SMC Interrupt Mask Register */ -+#define SDXC_REG_MISTA (0x34) /* SMC Masked Interrupt Status Register */ -+#define SDXC_REG_RINTR (0x38) /* SMC Raw Interrupt Status Register */ -+#define SDXC_REG_STAS (0x3C) /* SMC Status Register */ -+#define SDXC_REG_FTRGL (0x40) /* SMC FIFO Threshold Watermark Registe */ -+#define SDXC_REG_FUNS (0x44) /* SMC Function Select Register */ -+#define SDXC_REG_CBCR (0x48) /* SMC CIU Byte Count Register */ -+#define SDXC_REG_BBCR (0x4C) /* SMC BIU Byte Count Register */ -+#define SDXC_REG_DBGC (0x50) /* SMC Debug Enable Register */ -+#define SDXC_REG_HWRST (0x78) /* SMC Card Hardware Reset for Register */ -+#define SDXC_REG_DMAC (0x80) /* SMC IDMAC Control Register */ -+#define SDXC_REG_DLBA (0x84) /* SMC IDMAC Descriptor List Base Addre */ -+#define SDXC_REG_IDST (0x88) /* SMC IDMAC Status Register */ -+#define SDXC_REG_IDIE (0x8C) /* SMC IDMAC Interrupt Enable Register */ -+#define SDXC_REG_CHDA (0x90) -+#define SDXC_REG_CBDA (0x94) -+ -+#define mci_readl(host, reg) \ -+ readl((host)->reg_base + SDXC_##reg) -+#define mci_writel(host, reg, value) \ -+ writel((value), (host)->reg_base + SDXC_##reg) -+ -+/* global control register bits */ -+#define SDXC_SOFT_RESET BIT(0) -+#define SDXC_FIFO_RESET BIT(1) -+#define SDXC_DMA_RESET BIT(2) -+#define SDXC_HARDWARE_RESET (SDXC_SOFT_RESET|SDXC_FIFO_RESET|SDXC_DMA_RESET) -+#define SDXC_INTERRUPT_ENABLE_BIT BIT(4) -+#define SDXC_DMA_ENABLE_BIT BIT(5) -+#define SDXC_DEBOUNCE_ENABLE_BIT BIT(8) -+#define SDXC_POSEDGE_LATCH_DATA BIT(9) -+#define SDXC_DDR_MODE BIT(10) -+#define SDXC_MEMORY_ACCESS_DONE BIT(29) -+#define SDXC_ACCESS_DONE_DIRECT BIT(30) -+#define SDXC_ACCESS_BY_AHB BIT(31) -+#define SDXC_ACCESS_BY_DMA (0U << 31) -+/* clock control bits */ -+#define SDXC_CARD_CLOCK_ON BIT(16) -+#define SDXC_LOW_POWER_ON BIT(17) -+/* bus width */ -+#define SDXC_WIDTH1 (0) -+#define SDXC_WIDTH4 (1) -+#define SDXC_WIDTH8 (2) -+/* smc command bits */ -+#define SDXC_RESP_EXPIRE BIT(6) -+#define SDXC_LONG_RESPONSE BIT(7) -+#define SDXC_CHECK_RESPONSE_CRC BIT(8) -+#define SDXC_DATA_EXPIRE BIT(9) -+#define SDXC_WRITE BIT(10) -+#define SDXC_SEQUENCE_MODE BIT(11) -+#define SDXC_SEND_AUTO_STOP BIT(12) -+#define SDXC_WAIT_PRE_OVER BIT(13) -+#define SDXC_STOP_ABORT_CMD BIT(14) -+#define SDXC_SEND_INIT_SEQUENCE BIT(15) -+#define SDXC_UPCLK_ONLY BIT(21) -+#define SDXC_READ_CEATA_DEV BIT(22) -+#define SDXC_CCS_EXPIRE BIT(23) -+#define SDXC_ENABLE_BIT_BOOT BIT(24) -+#define SDXC_ALT_BOOT_OPTIONS BIT(25) -+#define SDXC_BOOT_ACK_EXPIRE BIT(26) -+#define SDXC_BOOT_ABORT BIT(27) -+#define SDXC_VOLTAGE_SWITCH BIT(28) -+#define SDXC_USE_HOLD_REGISTER BIT(29) -+#define SDXC_START BIT(31) -+/* interrupt bits */ -+#define SDXC_RESP_ERROR BIT(1) -+#define SDXC_COMMAND_DONE BIT(2) -+#define SDXC_DATA_OVER BIT(3) -+#define SDXC_TX_DATA_REQUEST BIT(4) -+#define SDXC_RX_DATA_REQUEST BIT(5) -+#define SDXC_RESP_CRC_ERROR BIT(6) -+#define SDXC_DATA_CRC_ERROR BIT(7) -+#define SDXC_RESP_TIMEOUT BIT(8) -+#define SDXC_DATA_TIMEOUT BIT(9) -+#define SDXC_VOLTAGE_CHANGE_DONE BIT(10) -+#define SDXC_FIFO_RUN_ERROR BIT(11) -+#define SDXC_HARD_WARE_LOCKED BIT(12) -+#define SDXC_START_BIT_ERROR BIT(13) -+#define SDXC_AUTO_COMMAND_DONE BIT(14) -+#define SDXC_END_BIT_ERROR BIT(15) -+#define SDXC_SDIO_INTERRUPT BIT(16) -+#define SDXC_CARD_INSERT BIT(30) -+#define SDXC_CARD_REMOVE BIT(31) -+#define SDXC_INTERRUPT_ERROR_BIT (SDXC_RESP_ERROR | SDXC_RESP_CRC_ERROR | \ -+ SDXC_DATA_CRC_ERROR | SDXC_RESP_TIMEOUT | \ -+ SDXC_DATA_TIMEOUT | SDXC_FIFO_RUN_ERROR | \ -+ SDXC_HARD_WARE_LOCKED | SDXC_START_BIT_ERROR | \ -+ SDXC_END_BIT_ERROR) /* 0xbbc2 */ -+#define SDXC_INTERRUPT_DONE_BIT (SDXC_AUTO_COMMAND_DONE | SDXC_DATA_OVER | \ -+ SDXC_COMMAND_DONE | SDXC_VOLTAGE_CHANGE_DONE) -+/* status */ -+#define SDXC_RXWL_FLAG BIT(0) -+#define SDXC_TXWL_FLAG BIT(1) -+#define SDXC_FIFO_EMPTY BIT(2) -+#define SDXC_FIFO_FULL BIT(3) -+#define SDXC_CARD_PRESENT BIT(8) -+#define SDXC_CARD_DATA_BUSY BIT(9) -+#define SDXC_DATA_FSM_BUSY BIT(10) -+#define SDXC_DMA_REQUEST BIT(31) -+#define SDXC_FIFO_SIZE (16) -+/* Function select */ -+#define SDXC_CEATA_ON (0xceaaU << 16) -+#define SDXC_SEND_IRQ_RESPONSE BIT(0) -+#define SDXC_SDIO_READ_WAIT BIT(1) -+#define SDXC_ABORT_READ_DATA BIT(2) -+#define SDXC_SEND_CCSD BIT(8) -+#define SDXC_SEND_AUTO_STOPCCSD BIT(9) -+#define SDXC_CEATA_DEV_INTERRUPT_ENABLE_BIT BIT(10) -+/* IDMA controller bus mod bit field */ -+#define SDXC_IDMAC_SOFT_RESET BIT(0) -+#define SDXC_IDMAC_FIX_BURST BIT(1) -+#define SDXC_IDMAC_IDMA_ON BIT(7) -+#define SDXC_IDMAC_REFETCH_DES BIT(31) -+/* IDMA status bit field */ -+#define SDXC_IDMAC_TRANSMIT_INTERRUPT BIT(0) -+#define SDXC_IDMAC_RECEIVE_INTERRUPT BIT(1) -+#define SDXC_IDMAC_FATAL_BUS_ERROR BIT(2) -+#define SDXC_IDMAC_DESTINATION_INVALID BIT(4) -+#define SDXC_IDMAC_CARD_ERROR_SUM BIT(5) -+#define SDXC_IDMAC_NORMAL_INTERRUPT_SUM BIT(8) -+#define SDXC_IDMAC_ABNORMAL_INTERRUPT_SUM BIT(9) -+#define SDXC_IDMAC_HOST_ABORT_INTERRUPT_TX BIT(10) -+#define SDXC_IDMAC_HOST_ABORT_INTERRUPT_RX BIT(10) -+#define SDXC_IDMAC_IDLE (0U << 13) -+#define SDXC_IDMAC_SUSPEND (1U << 13) -+#define SDXC_IDMAC_DESC_READ (2U << 13) -+#define SDXC_IDMAC_DESC_CHECK (3U << 13) -+#define SDXC_IDMAC_READ_REQUEST_WAIT (4U << 13) -+#define SDXC_IDMAC_WRITE_REQUEST_WAIT (5U << 13) -+#define SDXC_IDMAC_READ (6U << 13) -+#define SDXC_IDMAC_WRITE (7U << 13) -+#define SDXC_IDMAC_DESC_CLOSE (8U << 13) -+ -+/* -+* If the idma-des-size-bits of property is ie 13, bufsize bits are: -+* Bits 0-12: buf1 size -+* Bits 13-25: buf2 size -+* Bits 26-31: not used -+* Since we only ever set buf1 size, we can simply store it directly. -+*/ -+#define SDXC_IDMAC_DES0_DIC BIT(1) /* disable interrupt on completion */ -+#define SDXC_IDMAC_DES0_LD BIT(2) /* last descriptor */ -+#define SDXC_IDMAC_DES0_FD BIT(3) /* first descriptor */ -+#define SDXC_IDMAC_DES0_CH BIT(4) /* chain mode */ -+#define SDXC_IDMAC_DES0_ER BIT(5) /* end of ring */ -+#define SDXC_IDMAC_DES0_CES BIT(30) /* card error summary */ -+#define SDXC_IDMAC_DES0_OWN BIT(31) /* 1-idma owns it, 0-host owns it */ -+ -+struct sunxi_idma_des { -+ u32 config; -+ u32 buf_size; -+ u32 buf_addr_ptr1; -+ u32 buf_addr_ptr2; -+}; -+ -+struct sunxi_mmc_host { -+ struct mmc_host *mmc; -+ struct regulator *vmmc; -+ -+ /* IO mapping base */ -+ void __iomem *reg_base; -+ -+ spinlock_t lock; -+ struct tasklet_struct tasklet; -+ -+ /* clock management */ -+ struct clk *clk_ahb; -+ struct clk *clk_mod; -+ -+ /* ios information */ -+ u32 clk_mod_rate; -+ u32 bus_width; -+ u32 idma_des_size_bits; -+ u32 ddr; -+ u32 voltage_switching; -+ -+ /* irq */ -+ int irq; -+ u32 int_sum; -+ u32 sdio_imask; -+ -+ /* flags */ -+ u32 power_on:1; -+ u32 wait_dma:1; -+ -+ dma_addr_t sg_dma; -+ void *sg_cpu; -+ -+ struct mmc_request *mrq; -+ u32 ferror; -+}; -+ -+#define MMC_CLK_400K 0 -+#define MMC_CLK_25M 1 -+#define MMC_CLK_50M 2 -+#define MMC_CLK_50MDDR 3 -+#define MMC_CLK_50MDDR_8BIT 4 -+#define MMC_CLK_100M 5 -+#define MMC_CLK_200M 6 -+#define MMC_CLK_MOD_NUM 7 -+ -+struct sunxi_mmc_clk_dly { -+ u32 mode; -+ u32 oclk_dly; -+ u32 sclk_dly; -+}; -+ -+#endif diff --git a/target/linux/sunxi/patches-3.14/201-dt-sun4i-add-mmc-nodes_NEED_REFRESH.patch b/target/linux/sunxi/patches-3.14/201-dt-sun4i-add-mmc-nodes_NEED_REFRESH.patch deleted file mode 100644 index 10d4d5823b..0000000000 --- a/target/linux/sunxi/patches-3.14/201-dt-sun4i-add-mmc-nodes_NEED_REFRESH.patch +++ /dev/null @@ -1,159 +0,0 @@ -From b66989fe7a41e1093b1f825967ab29963e06cccd Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?David=20Lanzend=C3=B6rfer?= <david.lanzendoerfer@o2s.ch> -Date: Sat, 15 Feb 2014 14:02:51 +0100 -Subject: [PATCH] ARM: dts: sun4i: Add support for mmc -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Signed-off-by: David Lanzendörfer <david.lanzendoerfer@o2s.ch> -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/sun4i-a10.dtsi | 58 ++++++++++++++++++++++++++++++ - 3 files changed, 74 insertions(+) - ---- a/arch/arm/boot/dts/sun4i-a10-cubieboard.dts -+++ b/arch/arm/boot/dts/sun4i-a10-cubieboard.dts -@@ -34,6 +34,14 @@ - }; - }; - -+ mmc0: mmc@01c0f000 { -+ pinctrl-names = "default", "default"; -+ pinctrl-0 = <&mmc0_pins_a>; -+ pinctrl-1 = <&mmc0_cd_pin_reference_design>; -+ cd-gpios = <&pio 7 1 0>; /* PH1 */ -+ status = "okay"; -+ }; -+ - usbphy: phy@01c13400 { - usb1_vbus-supply = <®_usb1_vbus>; - usb2_vbus-supply = <®_usb2_vbus>; ---- a/arch/arm/boot/dts/sun4i-a10.dtsi -+++ b/arch/arm/boot/dts/sun4i-a10.dtsi -@@ -377,6 +377,50 @@ - #size-cells = <0>; - }; - -+ mmc0: mmc@01c0f000 { -+ compatible = "allwinner,sun4i-a10-mmc"; -+ reg = <0x01c0f000 0x1000>; -+ clocks = <&ahb_gates 8>, <&mmc0_clk>; -+ clock-names = "ahb", "mod"; -+ interrupts = <32>; -+ bus-width = <4>; -+ cd-inverted; -+ status = "disabled"; -+ }; -+ -+ mmc1: mmc@01c10000 { -+ compatible = "allwinner,sun4i-a10-mmc"; -+ reg = <0x01c10000 0x1000>; -+ clocks = <&ahb_gates 9>, <&mmc1_clk>; -+ clock-names = "ahb", "mod"; -+ interrupts = <33>; -+ bus-width = <4>; -+ cd-inverted; -+ status = "disabled"; -+ }; -+ -+ mmc2: mmc@01c11000 { -+ compatible = "allwinner,sun4i-a10-mmc"; -+ reg = <0x01c11000 0x1000>; -+ clocks = <&ahb_gates 10>, <&mmc2_clk>; -+ clock-names = "ahb", "mod"; -+ interrupts = <34>; -+ bus-width = <4>; -+ cd-inverted; -+ status = "disabled"; -+ }; -+ -+ mmc3: mmc@01c12000 { -+ compatible = "allwinner,sun4i-a10-mmc"; -+ reg = <0x01c12000 0x1000>; -+ clocks = <&ahb_gates 11>, <&mmc3_clk>; -+ clock-names = "ahb", "mod"; -+ interrupts = <35>; -+ bus-width = <4>; -+ cd-inverted; -+ status = "disabled"; -+ }; -+ - usbphy: phy@01c13400 { - #phy-cells = <1>; - compatible = "allwinner,sun4i-a10-usb-phy"; -@@ -529,6 +573,20 @@ - allwinner,drive = <0>; - allwinner,pull = <0>; - }; -+ -+ mmc0_pins_a: mmc0@0 { -+ allwinner,pins = "PF0","PF1","PF2","PF3","PF4","PF5"; -+ allwinner,function = "mmc0"; -+ allwinner,drive = <2>; -+ allwinner,pull = <0>; -+ }; -+ -+ mmc0_cd_pin_reference_design: mmc0_cd_pin@0 { -+ allwinner,pins = "PH1"; -+ allwinner,function = "gpio_in"; -+ allwinner,drive = <0>; -+ allwinner,pull = <1>; -+ }; - }; - - timer@01c20c00 { ---- a/arch/arm/boot/dts/sun4i-a10-mini-xplus.dts -+++ b/arch/arm/boot/dts/sun4i-a10-mini-xplus.dts -@@ -20,6 +20,14 @@ - compatible = "pineriver,mini-xplus", "allwinner,sun4i-a10"; - - soc@01c00000 { -+ mmc0: mmc@01c0f000 { -+ pinctrl-names = "default", "default"; -+ pinctrl-0 = <&mmc0_pins_a>; -+ pinctrl-1 = <&mmc0_cd_pin_reference_design>; -+ cd-gpios = <&pio 7 1 0>; /* PH1 */ -+ status = "okay"; -+ }; -+ - usbphy: phy@01c13400 { - usb1_vbus-supply = <®_usb1_vbus>; - usb2_vbus-supply = <®_usb2_vbus>; ---- a/arch/arm/boot/dts/sun4i-a10-olinuxino-lime.dts -+++ b/arch/arm/boot/dts/sun4i-a10-olinuxino-lime.dts -@@ -33,6 +33,15 @@ - }; - }; - -+ mmc0: mmc@01c0f000 { -+ pinctrl-names = "default", "default"; -+ pinctrl-0 = <&mmc0_pins_a>; -+ pinctrl-1 = <&mmc0_cd_pin_reference_design>; -+ cd-gpios = <&pio 7 1 0>; /* PH1 */ -+ cd-mode = <1>; -+ status = "okay"; -+ }; -+ - usbphy: phy@01c13400 { - usb1_vbus-supply = <®_usb1_vbus>; - usb2_vbus-supply = <®_usb2_vbus>; ---- a/arch/arm/boot/dts/sun4i-a10-pcduino.dts -+++ b/arch/arm/boot/dts/sun4i-a10-pcduino.dts -@@ -34,6 +34,14 @@ - }; - }; - -+ mmc0: mmc@01c0f000 { -+ pinctrl-names = "default", "default"; -+ pinctrl-0 = <&mmc0_pins_a>; -+ pinctrl-1 = <&mmc0_cd_pin_reference_design>; -+ cd-gpios = <&pio 7 1 0>; /* PH1 */ -+ status = "okay"; -+ }; -+ - usbphy: phy@01c13400 { - usb1_vbus-supply = <®_usb1_vbus>; - usb2_vbus-supply = <®_usb2_vbus>; diff --git a/target/linux/sunxi/patches-3.14/202-dt-sun5i-add-mmc-nodes.patch b/target/linux/sunxi/patches-3.14/202-dt-sun5i-add-mmc-nodes.patch deleted file mode 100644 index 541cef6852..0000000000 --- a/target/linux/sunxi/patches-3.14/202-dt-sun5i-add-mmc-nodes.patch +++ /dev/null @@ -1,125 +0,0 @@ -From 7afa5fb704679e84c59e5ad25bbdf7605844c5ca Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?David=20Lanzend=C3=B6rfer?= <david.lanzendoerfer@o2s.ch> -Date: Sat, 15 Feb 2014 14:02:29 +0100 -Subject: [PATCH] ARM: dts: sun5i: Add support for mmc -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Signed-off-by: David Lanzendörfer <david.lanzendoerfer@o2s.ch> -Signed-off-by: Hans de Goede <hdegoede@redhat.com> ---- - arch/arm/boot/dts/sun5i-a10s-olinuxino-micro.dts | 30 +++++++++++++++ - arch/arm/boot/dts/sun5i-a10s.dtsi | 47 ++++++++++++++++++++++++ - arch/arm/boot/dts/sun5i-a13-olinuxino-micro.dts | 15 ++++++++ - arch/arm/boot/dts/sun5i-a13-olinuxino.dts | 15 ++++++++ - arch/arm/boot/dts/sun5i-a13.dtsi | 29 +++++++++++++++ - 5 files changed, 136 insertions(+) - ---- a/arch/arm/boot/dts/sun5i-a13-olinuxino-micro.dts -+++ b/arch/arm/boot/dts/sun5i-a13-olinuxino-micro.dts -@@ -21,6 +21,14 @@ - compatible = "olimex,a13-olinuxino-micro", "allwinner,sun5i-a13"; - - soc@01c00000 { -+ mmc0: mmc@01c0f000 { -+ pinctrl-names = "default", "default"; -+ pinctrl-0 = <&mmc0_pins_a>; -+ pinctrl-1 = <&mmc0_cd_pin_olinuxinom>; -+ cd-gpios = <&pio 6 0 0>; /* PG0 */ -+ status = "okay"; -+ }; -+ - usbphy: phy@01c13400 { - usb1_vbus-supply = <®_usb1_vbus>; - status = "okay"; -@@ -35,6 +43,13 @@ - }; - - pinctrl@01c20800 { -+ mmc0_cd_pin_olinuxinom: mmc0_cd_pin@0 { -+ allwinner,pins = "PG0"; -+ allwinner,function = "gpio_in"; -+ allwinner,drive = <0>; -+ allwinner,pull = <1>; -+ }; -+ - led_pins_olinuxinom: led_pins@0 { - allwinner,pins = "PG9"; - allwinner,function = "gpio_out"; ---- a/arch/arm/boot/dts/sun5i-a13-olinuxino.dts -+++ b/arch/arm/boot/dts/sun5i-a13-olinuxino.dts -@@ -21,6 +21,14 @@ - compatible = "olimex,a13-olinuxino", "allwinner,sun5i-a13"; - - soc@01c00000 { -+ mmc0: mmc@01c0f000 { -+ pinctrl-names = "default", "default"; -+ pinctrl-0 = <&mmc0_pins_a>; -+ pinctrl-1 = <&mmc0_cd_pin_olinuxino>; -+ cd-gpios = <&pio 6 0 0>; /* PG0 */ -+ status = "okay"; -+ }; -+ - usbphy: phy@01c13400 { - usb1_vbus-supply = <®_usb1_vbus>; - status = "okay"; -@@ -35,6 +43,13 @@ - }; - - pinctrl@01c20800 { -+ mmc0_cd_pin_olinuxino: mmc0_cd_pin@0 { -+ allwinner,pins = "PG0"; -+ allwinner,function = "gpio_in"; -+ allwinner,drive = <0>; -+ allwinner,pull = <1>; -+ }; -+ - led_pins_olinuxino: led_pins@0 { - allwinner,pins = "PG9"; - allwinner,function = "gpio_out"; ---- a/arch/arm/boot/dts/sun5i-a13.dtsi -+++ b/arch/arm/boot/dts/sun5i-a13.dtsi -@@ -320,6 +320,28 @@ - #size-cells = <0>; - }; - -+ mmc0: mmc@01c0f000 { -+ compatible = "allwinner,sun5i-a13-mmc"; -+ reg = <0x01c0f000 0x1000>; -+ clocks = <&ahb_gates 8>, <&mmc0_clk>; -+ clock-names = "ahb", "mod"; -+ interrupts = <32>; -+ bus-width = <4>; -+ cd-inverted; -+ status = "disabled"; -+ }; -+ -+ mmc2: mmc@01c11000 { -+ compatible = "allwinner,sun5i-a13-mmc"; -+ reg = <0x01c11000 0x1000>; -+ clocks = <&ahb_gates 10>, <&mmc2_clk>; -+ clock-names = "ahb", "mod"; -+ interrupts = <34>; -+ bus-width = <4>; -+ cd-inverted; -+ status = "disabled"; -+ }; -+ - usbphy: phy@01c13400 { - #phy-cells = <1>; - compatible = "allwinner,sun5i-a13-usb-phy"; -@@ -415,6 +437,13 @@ - allwinner,drive = <0>; - allwinner,pull = <0>; - }; -+ -+ mmc0_pins_a: mmc0@0 { -+ allwinner,pins = "PF0","PF1","PF2","PF3","PF4","PF5"; -+ allwinner,function = "mmc0"; -+ allwinner,drive = <2>; -+ allwinner,pull = <0>; -+ }; - }; - - timer@01c20c00 { diff --git a/target/linux/sunxi/patches-3.14/203-dt-sun7i-add-mmc-nodes.patch b/target/linux/sunxi/patches-3.14/203-dt-sun7i-add-mmc-nodes.patch deleted file mode 100644 index 1a0459cb25..0000000000 --- a/target/linux/sunxi/patches-3.14/203-dt-sun7i-add-mmc-nodes.patch +++ /dev/null @@ -1,171 +0,0 @@ -From 33654facee61ebbd88684c9cf482ec2ea41f575e Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?David=20Lanzend=C3=B6rfer?= <david.lanzendoerfer@o2s.ch> -Date: Sat, 15 Feb 2014 14:02:01 +0100 -Subject: [PATCH] ARM: dts: sun7i: Add support for mmc -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Signed-off-by: David Lanzendörfer <david.lanzendoerfer@o2s.ch> -Signed-off-by: Hans de Goede <hdegoede@redhat.com> ---- - arch/arm/boot/dts/sun7i-a20-cubieboard2.dts | 8 +++ - arch/arm/boot/dts/sun7i-a20-cubietruck.dts | 8 +++ - arch/arm/boot/dts/sun7i-a20-olinuxino-micro.dts | 23 +++++++++ - arch/arm/boot/dts/sun7i-a20.dtsi | 65 +++++++++++++++++++++++++ - 4 files changed, 104 insertions(+) - ---- a/arch/arm/boot/dts/sun7i-a20-cubieboard2.dts -+++ b/arch/arm/boot/dts/sun7i-a20-cubieboard2.dts -@@ -20,6 +20,14 @@ - compatible = "cubietech,cubieboard2", "allwinner,sun7i-a20"; - - soc@01c00000 { -+ mmc0: mmc@01c0f000 { -+ pinctrl-names = "default", "default"; -+ pinctrl-0 = <&mmc0_pins_a>; -+ pinctrl-1 = <&mmc0_cd_pin_reference_design>; -+ cd-gpios = <&pio 7 1 0>; /* PH1 */ -+ status = "okay"; -+ }; -+ - usbphy: phy@01c13400 { - usb1_vbus-supply = <®_usb1_vbus>; - usb2_vbus-supply = <®_usb2_vbus>; ---- a/arch/arm/boot/dts/sun7i-a20-cubietruck.dts -+++ b/arch/arm/boot/dts/sun7i-a20-cubietruck.dts -@@ -20,6 +20,14 @@ - compatible = "cubietech,cubietruck", "allwinner,sun7i-a20"; - - soc@01c00000 { -+ mmc0: mmc@01c0f000 { -+ pinctrl-names = "default", "default"; -+ pinctrl-0 = <&mmc0_pins_a>; -+ pinctrl-1 = <&mmc0_cd_pin_reference_design>; -+ cd-gpios = <&pio 7 1 0>; /* PH1 */ -+ status = "okay"; -+ }; -+ - usbphy: phy@01c13400 { - usb1_vbus-supply = <®_usb1_vbus>; - usb2_vbus-supply = <®_usb2_vbus>; ---- a/arch/arm/boot/dts/sun7i-a20-olinuxino-micro.dts -+++ b/arch/arm/boot/dts/sun7i-a20-olinuxino-micro.dts -@@ -32,6 +32,22 @@ - status = "okay"; - }; - -+ mmc0: mmc@01c0f000 { -+ pinctrl-names = "default", "default"; -+ pinctrl-0 = <&mmc0_pins_a>; -+ pinctrl-1 = <&mmc0_cd_pin_reference_design>; -+ cd-gpios = <&pio 7 1 0>; /* PH1 */ -+ status = "okay"; -+ }; -+ -+ mmc3: mmc@01c12000 { -+ pinctrl-names = "default", "default"; -+ pinctrl-0 = <&mmc3_pins_a>; -+ pinctrl-1 = <&mmc3_cd_pin_olinuxinom>; -+ cd-gpios = <&pio 7 11 0>; /* PH11 */ -+ status = "okay"; -+ }; -+ - usbphy: phy@01c13400 { - usb1_vbus-supply = <®_usb1_vbus>; - usb2_vbus-supply = <®_usb2_vbus>; -@@ -66,6 +82,13 @@ - }; - - pinctrl@01c20800 { -+ mmc3_cd_pin_olinuxinom: mmc3_cd_pin@0 { -+ allwinner,pins = "PH11"; -+ allwinner,function = "gpio_in"; -+ allwinner,drive = <0>; -+ allwinner,pull = <1>; -+ }; -+ - led_pins_olinuxino: led_pins@0 { - allwinner,pins = "PH2"; - allwinner,function = "gpio_out"; ---- a/arch/arm/boot/dts/sun7i-a20.dtsi -+++ b/arch/arm/boot/dts/sun7i-a20.dtsi -@@ -439,6 +439,50 @@ - #size-cells = <0>; - }; - -+ mmc0: mmc@01c0f000 { -+ compatible = "allwinner,sun5i-a13-mmc"; -+ reg = <0x01c0f000 0x1000>; -+ clocks = <&ahb_gates 8>, <&mmc0_clk>; -+ clock-names = "ahb", "mod"; -+ interrupts = <0 32 4>; -+ bus-width = <4>; -+ cd-inverted; -+ status = "disabled"; -+ }; -+ -+ mmc1: mmc@01c10000 { -+ compatible = "allwinner,sun5i-a13-mmc"; -+ reg = <0x01c10000 0x1000>; -+ clocks = <&ahb_gates 9>, <&mmc1_clk>; -+ clock-names = "ahb", "mod"; -+ interrupts = <0 33 4>; -+ bus-width = <4>; -+ cd-inverted; -+ status = "disabled"; -+ }; -+ -+ mmc2: mmc@01c11000 { -+ compatible = "allwinner,sun5i-a13-mmc"; -+ reg = <0x01c11000 0x1000>; -+ clocks = <&ahb_gates 10>, <&mmc2_clk>; -+ clock-names = "ahb", "mod"; -+ interrupts = <0 34 4>; -+ bus-width = <4>; -+ cd-inverted; -+ status = "disabled"; -+ }; -+ -+ mmc3: mmc@01c12000 { -+ compatible = "allwinner,sun5i-a13-mmc"; -+ reg = <0x01c12000 0x1000>; -+ clocks = <&ahb_gates 11>, <&mmc3_clk>; -+ clock-names = "ahb", "mod"; -+ interrupts = <0 35 4>; -+ bus-width = <4>; -+ cd-inverted; -+ status = "disabled"; -+ }; -+ - usbphy: phy@01c13400 { - #phy-cells = <1>; - compatible = "allwinner,sun7i-a20-usb-phy"; -@@ -645,6 +689,27 @@ - allwinner,drive = <0>; - allwinner,pull = <0>; - }; -+ -+ mmc0_pins_a: mmc0@0 { -+ allwinner,pins = "PF0","PF1","PF2","PF3","PF4","PF5"; -+ allwinner,function = "mmc0"; -+ allwinner,drive = <2>; -+ allwinner,pull = <0>; -+ }; -+ -+ mmc0_cd_pin_reference_design: mmc0_cd_pin@0 { -+ allwinner,pins = "PH1"; -+ allwinner,function = "gpio_in"; -+ allwinner,drive = <0>; -+ allwinner,pull = <1>; -+ }; -+ -+ mmc3_pins_a: mmc3@0 { -+ allwinner,pins = "PI4","PI5","PI6","PI7","PI8","PI9"; -+ allwinner,function = "mmc3"; -+ allwinner,drive = <2>; -+ allwinner,pull = <0>; -+ }; - }; - - timer@01c20c00 { diff --git a/target/linux/sunxi/patches-3.14/205-nmi-add-driver.patch b/target/linux/sunxi/patches-3.14/205-nmi-add-driver.patch deleted file mode 100644 index 98b5fe746a..0000000000 --- a/target/linux/sunxi/patches-3.14/205-nmi-add-driver.patch +++ /dev/null @@ -1,239 +0,0 @@ -From b9ad0253e6c68ac3d37fd2ed8ed9bf8a334e4b65 Mon Sep 17 00:00:00 2001 -From: Carlo Caione <carlo@caione.org> -Date: Sat, 15 Mar 2014 14:40:59 +0100 -Subject: [PATCH] ARM: sun7i/sun6i: irqchip: Add irqchip driver for NMI - controller - -Allwinner A20/A31 SoCs have special registers to control / (un)mask / -acknowledge NMI. This NMI controller is separated and independent from GIC. -This patch adds a new irqchip to manage NMI. - -Signed-off-by: Carlo Caione <carlo@caione.org> -Acked-by: Maxime Ripard <maxime.ripard@free-electrons.com> ---- - drivers/irqchip/Makefile | 1 + - drivers/irqchip/irq-sunxi-nmi.c | 208 ++++++++++++++++++++++++++++++++++++++++ - 2 files changed, 209 insertions(+) - create mode 100644 drivers/irqchip/irq-sunxi-nmi.c - ---- a/drivers/irqchip/Makefile -+++ b/drivers/irqchip/Makefile -@@ -12,6 +12,7 @@ obj-$(CONFIG_METAG_PERFCOUNTER_IRQS) += - obj-$(CONFIG_ARCH_MOXART) += irq-moxart.o - obj-$(CONFIG_ORION_IRQCHIP) += irq-orion.o - obj-$(CONFIG_ARCH_SUNXI) += irq-sun4i.o -+obj-$(CONFIG_ARCH_SUNXI) += irq-sunxi-nmi.o - obj-$(CONFIG_ARCH_SPEAR3XX) += spear-shirq.o - obj-$(CONFIG_ARM_GIC) += irq-gic.o - obj-$(CONFIG_ARM_NVIC) += irq-nvic.o ---- /dev/null -+++ b/drivers/irqchip/irq-sunxi-nmi.c -@@ -0,0 +1,208 @@ -+/* -+ * Allwinner A20/A31 SoCs NMI IRQ chip driver. -+ * -+ * Carlo Caione <carlo.caione@gmail.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/device.h> -+#include <linux/io.h> -+#include <linux/irq.h> -+#include <linux/interrupt.h> -+#include <linux/irqdomain.h> -+#include <linux/of_irq.h> -+#include <linux/of_address.h> -+#include <linux/of_platform.h> -+#include <linux/irqchip/chained_irq.h> -+#include "irqchip.h" -+ -+#define SUNXI_NMI_SRC_TYPE_MASK 0x00000003 -+ -+enum { -+ SUNXI_SRC_TYPE_LEVEL_LOW = 0, -+ SUNXI_SRC_TYPE_EDGE_FALLING, -+ SUNXI_SRC_TYPE_LEVEL_HIGH, -+ SUNXI_SRC_TYPE_EDGE_RISING, -+}; -+ -+struct sunxi_sc_nmi_reg_offs { -+ u32 ctrl; -+ u32 pend; -+ u32 enable; -+}; -+ -+static struct sunxi_sc_nmi_reg_offs sun7i_reg_offs = { -+ .ctrl = 0x00, -+ .pend = 0x04, -+ .enable = 0x08, -+}; -+ -+static struct sunxi_sc_nmi_reg_offs sun6i_reg_offs = { -+ .ctrl = 0x00, -+ .pend = 0x04, -+ .enable = 0x34, -+}; -+ -+static inline void sunxi_sc_nmi_write(struct irq_chip_generic *gc, u32 off, -+ u32 val) -+{ -+ irq_reg_writel(val, gc->reg_base + off); -+} -+ -+static inline u32 sunxi_sc_nmi_read(struct irq_chip_generic *gc, u32 off) -+{ -+ return irq_reg_readl(gc->reg_base + off); -+} -+ -+static void sunxi_sc_nmi_handle_irq(unsigned int irq, struct irq_desc *desc) -+{ -+ struct irq_domain *domain = irq_desc_get_handler_data(desc); -+ struct irq_chip *chip = irq_get_chip(irq); -+ unsigned int virq = irq_find_mapping(domain, 0); -+ -+ chained_irq_enter(chip, desc); -+ generic_handle_irq(virq); -+ chained_irq_exit(chip, desc); -+} -+ -+static int sunxi_sc_nmi_set_type(struct irq_data *data, unsigned int flow_type) -+{ -+ struct irq_chip_generic *gc = irq_data_get_irq_chip_data(data); -+ struct irq_chip_type *ct = gc->chip_types; -+ u32 src_type_reg; -+ u32 ctrl_off = ct->regs.type; -+ unsigned int src_type; -+ unsigned int i; -+ -+ irq_gc_lock(gc); -+ -+ switch (flow_type & IRQF_TRIGGER_MASK) { -+ case IRQ_TYPE_EDGE_FALLING: -+ src_type = SUNXI_SRC_TYPE_EDGE_FALLING; -+ break; -+ case IRQ_TYPE_EDGE_RISING: -+ src_type = SUNXI_SRC_TYPE_EDGE_RISING; -+ break; -+ case IRQ_TYPE_LEVEL_HIGH: -+ src_type = SUNXI_SRC_TYPE_LEVEL_HIGH; -+ break; -+ case IRQ_TYPE_NONE: -+ case IRQ_TYPE_LEVEL_LOW: -+ src_type = SUNXI_SRC_TYPE_LEVEL_LOW; -+ break; -+ default: -+ irq_gc_unlock(gc); -+ pr_err("%s: Cannot assign multiple trigger modes to IRQ %d.\n", -+ __func__, data->irq); -+ return -EBADR; -+ } -+ -+ irqd_set_trigger_type(data, flow_type); -+ irq_setup_alt_chip(data, flow_type); -+ -+ for (i = 0; i <= gc->num_ct; i++, ct++) -+ if (ct->type & flow_type) -+ ctrl_off = ct->regs.type; -+ -+ src_type_reg = sunxi_sc_nmi_read(gc, ctrl_off); -+ src_type_reg &= ~SUNXI_NMI_SRC_TYPE_MASK; -+ src_type_reg |= src_type; -+ sunxi_sc_nmi_write(gc, ctrl_off, src_type_reg); -+ -+ irq_gc_unlock(gc); -+ -+ return IRQ_SET_MASK_OK; -+} -+ -+static int __init sunxi_sc_nmi_irq_init(struct device_node *node, -+ struct sunxi_sc_nmi_reg_offs *reg_offs) -+{ -+ struct irq_domain *domain; -+ struct irq_chip_generic *gc; -+ unsigned int irq; -+ unsigned int clr = IRQ_NOREQUEST | IRQ_NOPROBE | IRQ_NOAUTOEN; -+ int ret; -+ -+ -+ domain = irq_domain_add_linear(node, 1, &irq_generic_chip_ops, NULL); -+ if (!domain) { -+ pr_err("%s: Could not register interrupt domain.\n", node->name); -+ return -ENOMEM; -+ } -+ -+ ret = irq_alloc_domain_generic_chips(domain, 1, 2, node->name, -+ handle_fasteoi_irq, clr, 0, -+ IRQ_GC_INIT_MASK_CACHE); -+ if (ret) { -+ pr_err("%s: Could not allocate generic interrupt chip.\n", -+ node->name); -+ goto fail_irqd_remove; -+ } -+ -+ irq = irq_of_parse_and_map(node, 0); -+ if (irq <= 0) { -+ pr_err("%s: unable to parse irq\n", node->name); -+ ret = -EINVAL; -+ goto fail_irqd_remove; -+ } -+ -+ gc = irq_get_domain_generic_chip(domain, 0); -+ gc->reg_base = of_iomap(node, 0); -+ if (!gc->reg_base) { -+ pr_err("%s: unable to map resource\n", node->name); -+ ret = -ENOMEM; -+ goto fail_irqd_remove; -+ } -+ -+ gc->chip_types[0].type = IRQ_TYPE_LEVEL_MASK; -+ gc->chip_types[0].chip.irq_mask = irq_gc_mask_clr_bit; -+ gc->chip_types[0].chip.irq_unmask = irq_gc_mask_set_bit; -+ gc->chip_types[0].chip.irq_eoi = irq_gc_ack_set_bit; -+ gc->chip_types[0].chip.irq_set_type = sunxi_sc_nmi_set_type; -+ gc->chip_types[0].chip.flags = IRQCHIP_EOI_THREADED | IRQCHIP_EOI_IF_HANDLED; -+ gc->chip_types[0].regs.ack = reg_offs->pend; -+ gc->chip_types[0].regs.mask = reg_offs->enable; -+ gc->chip_types[0].regs.type = reg_offs->ctrl; -+ -+ gc->chip_types[1].type = IRQ_TYPE_EDGE_BOTH; -+ gc->chip_types[1].chip.name = gc->chip_types[0].chip.name; -+ gc->chip_types[1].chip.irq_ack = irq_gc_ack_set_bit; -+ gc->chip_types[1].chip.irq_mask = irq_gc_mask_clr_bit; -+ gc->chip_types[1].chip.irq_unmask = irq_gc_mask_set_bit; -+ gc->chip_types[1].chip.irq_set_type = sunxi_sc_nmi_set_type; -+ gc->chip_types[1].regs.ack = reg_offs->pend; -+ gc->chip_types[1].regs.mask = reg_offs->enable; -+ gc->chip_types[1].regs.type = reg_offs->ctrl; -+ gc->chip_types[1].handler = handle_edge_irq; -+ -+ sunxi_sc_nmi_write(gc, reg_offs->enable, 0); -+ sunxi_sc_nmi_write(gc, reg_offs->pend, 0x1); -+ -+ irq_set_handler_data(irq, domain); -+ irq_set_chained_handler(irq, sunxi_sc_nmi_handle_irq); -+ -+ return 0; -+ -+fail_irqd_remove: -+ irq_domain_remove(domain); -+ -+ return ret; -+} -+ -+static int __init sun6i_sc_nmi_irq_init(struct device_node *node, -+ struct device_node *parent) -+{ -+ return sunxi_sc_nmi_irq_init(node, &sun6i_reg_offs); -+} -+IRQCHIP_DECLARE(sun6i_sc_nmi, "allwinner,sun6i-a31-sc-nmi", sun6i_sc_nmi_irq_init); -+ -+static int __init sun7i_sc_nmi_irq_init(struct device_node *node, -+ struct device_node *parent) -+{ -+ return sunxi_sc_nmi_irq_init(node, &sun7i_reg_offs); -+} -+IRQCHIP_DECLARE(sun7i_sc_nmi, "allwinner,sun7i-a20-sc-nmi", sun7i_sc_nmi_irq_init); diff --git a/target/linux/sunxi/patches-3.14/206-dt-sun67i-add-nmi-irqchip.patch b/target/linux/sunxi/patches-3.14/206-dt-sun67i-add-nmi-irqchip.patch deleted file mode 100644 index 3f18c50d88..0000000000 --- a/target/linux/sunxi/patches-3.14/206-dt-sun67i-add-nmi-irqchip.patch +++ /dev/null @@ -1,47 +0,0 @@ -From eebb592523672ee7288b9327bd222165db638d1a Mon Sep 17 00:00:00 2001 -From: Carlo Caione <carlo@caione.org> -Date: Thu, 27 Feb 2014 20:34:21 +0100 -Subject: [PATCH] ARM: sun7i/sun6i: dts: Add NMI irqchip support - -This patch adds DTS entries for NMI controller as child of GIC. - -Signed-off-by: Carlo Caione <carlo@caione.org> ---- - arch/arm/boot/dts/sun6i-a31.dtsi | 8 ++++++++ - arch/arm/boot/dts/sun7i-a20.dtsi | 8 ++++++++ - 2 files changed, 16 insertions(+) - ---- a/arch/arm/boot/dts/sun6i-a31.dtsi -+++ b/arch/arm/boot/dts/sun6i-a31.dtsi -@@ -370,6 +370,14 @@ - interrupts = <1 9 0xf04>; - }; - -+ nmi_intc: interrupt-controller@01f00c0c { -+ compatible = "allwinner,sun6i-a31-sc-nmi"; -+ interrupt-controller; -+ #interrupt-cells = <2>; -+ reg = <0x01f00c0c 0x38>; -+ interrupts = <0 32 4>; -+ }; -+ - cpucfg@01f01c00 { - compatible = "allwinner,sun6i-a31-cpuconfig"; - reg = <0x01f01c00 0x300>; ---- a/arch/arm/boot/dts/sun7i-a20.dtsi -+++ b/arch/arm/boot/dts/sun7i-a20.dtsi -@@ -401,6 +401,14 @@ - #size-cells = <1>; - ranges; - -+ nmi_intc: interrupt-controller@01c00030 { -+ compatible = "allwinner,sun7i-a20-sc-nmi"; -+ interrupt-controller; -+ #interrupt-cells = <2>; -+ reg = <0x01c00030 0x0c>; -+ interrupts = <0 0 4>; -+ }; -+ - spi0: spi@01c05000 { - compatible = "allwinner,sun4i-a10-spi"; - reg = <0x01c05000 0x1000>; diff --git a/target/linux/sunxi/patches-3.14/210-mfd-add-axp20x-pmic-driver.patch b/target/linux/sunxi/patches-3.14/210-mfd-add-axp20x-pmic-driver.patch deleted file mode 100644 index 6197300e9e..0000000000 --- a/target/linux/sunxi/patches-3.14/210-mfd-add-axp20x-pmic-driver.patch +++ /dev/null @@ -1,502 +0,0 @@ -From 509326e0138b762067904c0c60f818e9bdba4cd4 Mon Sep 17 00:00:00 2001 -From: Carlo Caione <carlo@caione.org> -Date: Sat, 1 Mar 2014 17:45:46 +0100 -Subject: [PATCH] mfd: AXP20x: Add mfd driver for AXP20x PMIC - -This patch introduces the preliminary support for PMICs X-Powers AXP202 -and AXP209. The AXP209 and AXP202 are the PMUs (Power Management Unit) -used by A10, A13 and A20 SoCs and developed by X-Powers, a sister company -of Allwinner. - -The core enables support for two subsystems: -- PEK (Power Enable Key) -- Regulators - -Signed-off-by: Carlo Caione <carlo@caione.org> ---- - arch/arm/configs/sunxi_defconfig | 1 + - drivers/mfd/Kconfig | 12 ++ - drivers/mfd/Makefile | 1 + - drivers/mfd/axp20x.c | 250 +++++++++++++++++++++++++++++++++++++++ - include/linux/mfd/axp20x.h | 180 ++++++++++++++++++++++++++++ - 5 files changed, 444 insertions(+) - create mode 100644 drivers/mfd/axp20x.c - create mode 100644 include/linux/mfd/axp20x.h - ---- a/arch/arm/configs/sunxi_defconfig -+++ b/arch/arm/configs/sunxi_defconfig -@@ -55,6 +55,7 @@ CONFIG_GPIO_SYSFS=y - # CONFIG_HWMON is not set - CONFIG_WATCHDOG=y - CONFIG_SUNXI_WATCHDOG=y -+CONFIG_MFD_AXP20X=y - # CONFIG_USB_SUPPORT is not set - CONFIG_NEW_LEDS=y - CONFIG_LEDS_CLASS=y ---- a/drivers/mfd/Kconfig -+++ b/drivers/mfd/Kconfig -@@ -59,6 +59,18 @@ config MFD_AAT2870_CORE - additional drivers must be enabled in order to use the - functionality of the device. - -+config MFD_AXP20X -+ bool "X-Powers AXP20X" -+ select MFD_CORE -+ select REGMAP_I2C -+ select REGMAP_IRQ -+ depends on I2C=y -+ help -+ If you say Y here you get support for the AXP20X. -+ This driver provides common support for accessing the device, -+ additional drivers must be enabled in order to use the -+ functionality of the device. -+ - config MFD_CROS_EC - tristate "ChromeOS Embedded Controller" - select MFD_CORE ---- a/drivers/mfd/Makefile -+++ b/drivers/mfd/Makefile -@@ -101,6 +101,7 @@ obj-$(CONFIG_PMIC_DA9052) += da9052-irq. - obj-$(CONFIG_PMIC_DA9052) += da9052-core.o - obj-$(CONFIG_MFD_DA9052_SPI) += da9052-spi.o - obj-$(CONFIG_MFD_DA9052_I2C) += da9052-i2c.o -+obj-$(CONFIG_MFD_AXP20X) += axp20x.o - - obj-$(CONFIG_MFD_LP3943) += lp3943.o - obj-$(CONFIG_MFD_LP8788) += lp8788.o lp8788-irq.o ---- /dev/null -+++ b/drivers/mfd/axp20x.c -@@ -0,0 +1,250 @@ -+/* -+ * axp20x.c - mfd core driver for the X-Powers AXP202 and AXP209 -+ * -+ * Author: Carlo Caione <carlo@caione.org> -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ */ -+ -+#include <linux/err.h> -+#include <linux/i2c.h> -+#include <linux/interrupt.h> -+#include <linux/kernel.h> -+#include <linux/module.h> -+#include <linux/pm_runtime.h> -+#include <linux/regmap.h> -+#include <linux/slab.h> -+#include <linux/regulator/consumer.h> -+#include <linux/mfd/axp20x.h> -+#include <linux/mfd/core.h> -+#include <linux/of_device.h> -+#include <linux/of_irq.h> -+ -+#define AXP20X_OFF 0x80 -+ -+static const struct regmap_range axp20x_writeable_ranges[] = { -+ regmap_reg_range(AXP20X_DATACACHE(0), AXP20X_IRQ5_STATE), -+ regmap_reg_range(AXP20X_DCDC_MODE, AXP20X_FG_RES), -+}; -+ -+static const struct regmap_range axp20x_volatile_ranges[] = { -+ regmap_reg_range(AXP20X_IRQ1_EN, AXP20X_IRQ5_STATE), -+}; -+ -+static const struct regmap_access_table axp20x_writeable_table = { -+ .yes_ranges = axp20x_writeable_ranges, -+ .n_yes_ranges = ARRAY_SIZE(axp20x_writeable_ranges), -+}; -+ -+static const struct regmap_access_table axp20x_volatile_table = { -+ .yes_ranges = axp20x_volatile_ranges, -+ .n_yes_ranges = ARRAY_SIZE(axp20x_volatile_ranges), -+}; -+ -+static struct resource axp20x_pek_resources[] = { -+ { -+ .name = "PEK_DBR", -+ .start = AXP20X_IRQ_PEK_RIS_EDGE, -+ .end = AXP20X_IRQ_PEK_RIS_EDGE, -+ .flags = IORESOURCE_IRQ, -+ }, -+ { -+ .name = "PEK_DBF", -+ .start = AXP20X_IRQ_PEK_FAL_EDGE, -+ .end = AXP20X_IRQ_PEK_FAL_EDGE, -+ .flags = IORESOURCE_IRQ, -+ }, -+}; -+ -+static const struct regmap_config axp20x_regmap_config = { -+ .reg_bits = 8, -+ .val_bits = 8, -+ .wr_table = &axp20x_writeable_table, -+ .volatile_table = &axp20x_volatile_table, -+ .max_register = AXP20X_FG_RES, -+ .cache_type = REGCACHE_RBTREE, -+}; -+ -+#define AXP20X_IRQ(_irq, _off, _mask) \ -+ [AXP20X_IRQ_##_irq] = { .reg_offset = (_off), .mask = BIT(_mask) } -+ -+static const struct regmap_irq axp20x_regmap_irqs[] = { -+ AXP20X_IRQ(ACIN_OVER_V, 0, 7), -+ AXP20X_IRQ(ACIN_PLUGIN, 0, 6), -+ AXP20X_IRQ(ACIN_REMOVAL, 0, 5), -+ AXP20X_IRQ(VBUS_OVER_V, 0, 4), -+ AXP20X_IRQ(VBUS_PLUGIN, 0, 3), -+ AXP20X_IRQ(VBUS_REMOVAL, 0, 2), -+ AXP20X_IRQ(VBUS_V_LOW, 0, 1), -+ AXP20X_IRQ(BATT_PLUGIN, 1, 7), -+ AXP20X_IRQ(BATT_REMOVAL, 1, 6), -+ AXP20X_IRQ(BATT_ENT_ACT_MODE, 1, 5), -+ AXP20X_IRQ(BATT_EXIT_ACT_MODE, 1, 4), -+ AXP20X_IRQ(CHARG, 1, 3), -+ AXP20X_IRQ(CHARG_DONE, 1, 2), -+ AXP20X_IRQ(BATT_TEMP_HIGH, 1, 1), -+ AXP20X_IRQ(BATT_TEMP_LOW, 1, 0), -+ AXP20X_IRQ(DIE_TEMP_HIGH, 2, 7), -+ AXP20X_IRQ(CHARG_I_LOW, 2, 6), -+ AXP20X_IRQ(DCDC1_V_LONG, 2, 5), -+ AXP20X_IRQ(DCDC2_V_LONG, 2, 4), -+ AXP20X_IRQ(DCDC3_V_LONG, 2, 3), -+ AXP20X_IRQ(PEK_SHORT, 2, 1), -+ AXP20X_IRQ(PEK_LONG, 2, 0), -+ AXP20X_IRQ(N_OE_PWR_ON, 3, 7), -+ AXP20X_IRQ(N_OE_PWR_OFF, 3, 6), -+ AXP20X_IRQ(VBUS_VALID, 3, 5), -+ AXP20X_IRQ(VBUS_NOT_VALID, 3, 4), -+ AXP20X_IRQ(VBUS_SESS_VALID, 3, 3), -+ AXP20X_IRQ(VBUS_SESS_END, 3, 2), -+ AXP20X_IRQ(LOW_PWR_LVL1, 3, 1), -+ AXP20X_IRQ(LOW_PWR_LVL2, 3, 0), -+ AXP20X_IRQ(TIMER, 4, 7), -+ AXP20X_IRQ(PEK_RIS_EDGE, 4, 6), -+ AXP20X_IRQ(PEK_FAL_EDGE, 4, 5), -+ AXP20X_IRQ(GPIO3_INPUT, 4, 3), -+ AXP20X_IRQ(GPIO2_INPUT, 4, 2), -+ AXP20X_IRQ(GPIO1_INPUT, 4, 1), -+ AXP20X_IRQ(GPIO0_INPUT, 4, 0), -+}; -+ -+static const struct regmap_irq_chip axp20x_regmap_irq_chip = { -+ .name = "axp20x_irq_chip", -+ .status_base = AXP20X_IRQ1_STATE, -+ .ack_base = AXP20X_IRQ1_STATE, -+ .mask_base = AXP20X_IRQ1_EN, -+ .num_regs = 5, -+ .irqs = axp20x_regmap_irqs, -+ .num_irqs = ARRAY_SIZE(axp20x_regmap_irqs), -+ .mask_invert = true, -+ .init_ack_masked = true, -+}; -+ -+static struct mfd_cell axp20x_cells[] = { -+ { -+ .name = "axp20x-pek", -+ .of_compatible = "x-powers,axp20x-pek", -+ .num_resources = ARRAY_SIZE(axp20x_pek_resources), -+ .resources = axp20x_pek_resources, -+ }, { -+ .name = "axp20x-regulator", -+ }, -+}; -+ -+const struct of_device_id axp20x_of_match[] = { -+ { .compatible = "x-powers,axp202", .data = (void *) AXP202_ID }, -+ { .compatible = "x-powers,axp209", .data = (void *) AXP209_ID }, -+ { }, -+}; -+ -+static struct axp20x_dev *axp20x_pm_power_off; -+static void axp20x_power_off(void) -+{ -+ regmap_write(axp20x_pm_power_off->regmap, AXP20X_OFF_CTRL, -+ AXP20X_OFF); -+} -+ -+static int axp20x_i2c_probe(struct i2c_client *i2c, -+ const struct i2c_device_id *id) -+{ -+ struct axp20x_dev *axp20x; -+ const struct of_device_id *of_id; -+ struct device_node *node = i2c->dev.of_node; -+ int ret; -+ -+ axp20x = devm_kzalloc(&i2c->dev, sizeof(*axp20x), GFP_KERNEL); -+ if (!axp20x) -+ return -ENOMEM; -+ -+ of_id = of_match_device(axp20x_of_match, &i2c->dev); -+ if (!of_id) { -+ dev_err(&i2c->dev, "Unable to setup AXP20X data\n"); -+ return -ENODEV; -+ } -+ axp20x->variant = (int) of_id->data; -+ -+ axp20x->i2c_client = i2c; -+ axp20x->dev = &i2c->dev; -+ dev_set_drvdata(axp20x->dev, axp20x); -+ -+ axp20x->regmap = devm_regmap_init_i2c(i2c, &axp20x_regmap_config); -+ if (IS_ERR(axp20x->regmap)) { -+ ret = PTR_ERR(axp20x->regmap); -+ dev_err(&i2c->dev, "regmap init failed: %d\n", ret); -+ return ret; -+ } -+ -+ axp20x->irq = i2c->irq; -+ ret = regmap_add_irq_chip(axp20x->regmap, axp20x->irq, -+ IRQF_ONESHOT | IRQF_SHARED, -1, -+ &axp20x_regmap_irq_chip, -+ &axp20x->regmap_irqc); -+ if (ret) { -+ dev_err(&i2c->dev, "failed to add irq chip: %d\n", ret); -+ return ret; -+ } -+ -+ ret = mfd_add_devices(axp20x->dev, -1, axp20x_cells, -+ ARRAY_SIZE(axp20x_cells), NULL, 0, NULL); -+ if (ret) { -+ dev_err(&i2c->dev, "failed to add MFD devices: %d\n", ret); -+ goto mfd_err; -+ } -+ -+ axp20x->pm_off = of_property_read_bool(node, "axp,system-power-controller"); -+ -+ if (axp20x->pm_off && !pm_power_off) { -+ axp20x_pm_power_off = axp20x; -+ pm_power_off = axp20x_power_off; -+ } -+ -+ dev_info(&i2c->dev, "AXP20X driver loaded\n"); -+ -+ return 0; -+ -+mfd_err: -+ regmap_del_irq_chip(axp20x->irq, axp20x->regmap_irqc); -+ -+ return ret; -+} -+ -+static int axp20x_i2c_remove(struct i2c_client *i2c) -+{ -+ struct axp20x_dev *axp20x = i2c_get_clientdata(i2c); -+ -+ if (axp20x == axp20x_pm_power_off) { -+ axp20x_pm_power_off = NULL; -+ pm_power_off = NULL; -+ } -+ -+ mfd_remove_devices(axp20x->dev); -+ regmap_del_irq_chip(axp20x->i2c_client->irq, axp20x->regmap_irqc); -+ -+ return 0; -+} -+ -+static const struct i2c_device_id axp20x_i2c_id[] = { -+ { "axp202", AXP202_ID }, -+ { "axp209", AXP209_ID }, -+ { } -+}; -+MODULE_DEVICE_TABLE(i2c, axp20x_i2c_id); -+ -+static struct i2c_driver axp20x_i2c_driver = { -+ .driver = { -+ .name = "axp20x", -+ .owner = THIS_MODULE, -+ .of_match_table = of_match_ptr(axp20x_of_match), -+ }, -+ .probe = axp20x_i2c_probe, -+ .remove = axp20x_i2c_remove, -+ .id_table = axp20x_i2c_id, -+}; -+ -+module_i2c_driver(axp20x_i2c_driver); -+ -+MODULE_DESCRIPTION("PMIC MFD core driver for AXP20X"); -+MODULE_AUTHOR("Carlo Caione <carlo@caione.org>"); -+MODULE_LICENSE("GPL"); ---- /dev/null -+++ b/include/linux/mfd/axp20x.h -@@ -0,0 +1,180 @@ -+/* -+ * Functions to access AXP20X power management chip. -+ * -+ * Copyright (C) 2013, Carlo Caione <carlo@caione.org> -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ */ -+ -+#ifndef __LINUX_MFD_AXP20X_H -+#define __LINUX_MFD_AXP20X_H -+ -+#define AXP202_ID 0 -+#define AXP209_ID 1 -+ -+#define AXP20X_DATACACHE(m) (0x04 + (m)) -+ -+/* Power supply */ -+#define AXP20X_PWR_INPUT_STATUS 0x00 -+#define AXP20X_PWR_OP_MODE 0x01 -+#define AXP20X_USB_OTG_STATUS 0x02 -+#define AXP20X_PWR_OUT_CTRL 0x12 -+#define AXP20X_DCDC2_V_OUT 0x23 -+#define AXP20X_DCDC2_LDO3_V_SCAL 0x25 -+#define AXP20X_DCDC3_V_OUT 0x27 -+#define AXP20X_LDO24_V_OUT 0x28 -+#define AXP20X_LDO3_V_OUT 0x29 -+#define AXP20X_VBUS_IPSOUT_MGMT 0x30 -+#define AXP20X_V_OFF 0x31 -+#define AXP20X_OFF_CTRL 0x32 -+#define AXP20X_CHRG_CTRL1 0x33 -+#define AXP20X_CHRG_CTRL2 0x34 -+#define AXP20X_CHRG_BAK_CTRL 0x35 -+#define AXP20X_PEK_KEY 0x36 -+#define AXP20X_DCDC_FREQ 0x37 -+#define AXP20X_V_LTF_CHRG 0x38 -+#define AXP20X_V_HTF_CHRG 0x39 -+#define AXP20X_APS_WARN_L1 0x3a -+#define AXP20X_APS_WARN_L2 0x3b -+#define AXP20X_V_LTF_DISCHRG 0x3c -+#define AXP20X_V_HTF_DISCHRG 0x3d -+ -+/* Interrupt */ -+#define AXP20X_IRQ1_EN 0x40 -+#define AXP20X_IRQ2_EN 0x41 -+#define AXP20X_IRQ3_EN 0x42 -+#define AXP20X_IRQ4_EN 0x43 -+#define AXP20X_IRQ5_EN 0x44 -+#define AXP20X_IRQ1_STATE 0x48 -+#define AXP20X_IRQ2_STATE 0x49 -+#define AXP20X_IRQ3_STATE 0x4a -+#define AXP20X_IRQ4_STATE 0x4b -+#define AXP20X_IRQ5_STATE 0x4c -+ -+/* ADC */ -+#define AXP20X_ACIN_V_ADC_H 0x56 -+#define AXP20X_ACIN_V_ADC_L 0x57 -+#define AXP20X_ACIN_I_ADC_H 0x58 -+#define AXP20X_ACIN_I_ADC_L 0x59 -+#define AXP20X_VBUS_V_ADC_H 0x5a -+#define AXP20X_VBUS_V_ADC_L 0x5b -+#define AXP20X_VBUS_I_ADC_H 0x5c -+#define AXP20X_VBUS_I_ADC_L 0x5d -+#define AXP20X_TEMP_ADC_H 0x5e -+#define AXP20X_TEMP_ADC_L 0x5f -+#define AXP20X_TS_IN_H 0x62 -+#define AXP20X_TS_IN_L 0x63 -+#define AXP20X_GPIO0_V_ADC_H 0x64 -+#define AXP20X_GPIO0_V_ADC_L 0x65 -+#define AXP20X_GPIO1_V_ADC_H 0x66 -+#define AXP20X_GPIO1_V_ADC_L 0x67 -+#define AXP20X_PWR_BATT_H 0x70 -+#define AXP20X_PWR_BATT_M 0x71 -+#define AXP20X_PWR_BATT_L 0x72 -+#define AXP20X_BATT_V_H 0x78 -+#define AXP20X_BATT_V_L 0x79 -+#define AXP20X_BATT_CHRG_I_H 0x7a -+#define AXP20X_BATT_CHRG_I_L 0x7b -+#define AXP20X_BATT_DISCHRG_I_H 0x7c -+#define AXP20X_BATT_DISCHRG_I_L 0x7d -+#define AXP20X_IPSOUT_V_HIGH_H 0x7e -+#define AXP20X_IPSOUT_V_HIGH_L 0x7f -+ -+/* Power supply */ -+#define AXP20X_DCDC_MODE 0x80 -+#define AXP20X_ADC_EN1 0x82 -+#define AXP20X_ADC_EN2 0x83 -+#define AXP20X_ADC_RATE 0x84 -+#define AXP20X_GPIO10_IN_RANGE 0x85 -+#define AXP20X_GPIO1_ADC_IRQ_RIS 0x86 -+#define AXP20X_GPIO1_ADC_IRQ_FAL 0x87 -+#define AXP20X_TIMER_CTRL 0x8a -+#define AXP20X_VBUS_MON 0x8b -+#define AXP20X_OVER_TMP 0x8f -+ -+/* GPIO */ -+#define AXP20X_GPIO0_CTRL 0x90 -+#define AXP20X_LDO5_V_OUT 0x91 -+#define AXP20X_GPIO1_CTRL 0x92 -+#define AXP20X_GPIO2_CTRL 0x93 -+#define AXP20X_GPIO20_SS 0x94 -+#define AXP20X_GPIO3_CTRL 0x95 -+ -+/* Battery */ -+#define AXP20X_CHRG_CC_31_24 0xb0 -+#define AXP20X_CHRG_CC_23_16 0xb1 -+#define AXP20X_CHRG_CC_15_8 0xb2 -+#define AXP20X_CHRG_CC_7_0 0xb3 -+#define AXP20X_DISCHRG_CC_31_24 0xb4 -+#define AXP20X_DISCHRG_CC_23_16 0xb5 -+#define AXP20X_DISCHRG_CC_15_8 0xb6 -+#define AXP20X_DISCHRG_CC_7_0 0xb7 -+#define AXP20X_CC_CTRL 0xb8 -+#define AXP20X_FG_RES 0xb9 -+ -+/* Regulators IDs */ -+enum { -+ AXP20X_LDO1 = 0, -+ AXP20X_LDO2, -+ AXP20X_LDO3, -+ AXP20X_LDO4, -+ AXP20X_LDO5, -+ AXP20X_DCDC2, -+ AXP20X_DCDC3, -+ AXP20X_REG_ID_MAX, -+}; -+ -+/* IRQs */ -+enum { -+ AXP20X_IRQ_ACIN_OVER_V = 1, -+ AXP20X_IRQ_ACIN_PLUGIN, -+ AXP20X_IRQ_ACIN_REMOVAL, -+ AXP20X_IRQ_VBUS_OVER_V, -+ AXP20X_IRQ_VBUS_PLUGIN, -+ AXP20X_IRQ_VBUS_REMOVAL, -+ AXP20X_IRQ_VBUS_V_LOW, -+ AXP20X_IRQ_BATT_PLUGIN, -+ AXP20X_IRQ_BATT_REMOVAL, -+ AXP20X_IRQ_BATT_ENT_ACT_MODE, -+ AXP20X_IRQ_BATT_EXIT_ACT_MODE, -+ AXP20X_IRQ_CHARG, -+ AXP20X_IRQ_CHARG_DONE, -+ AXP20X_IRQ_BATT_TEMP_HIGH, -+ AXP20X_IRQ_BATT_TEMP_LOW, -+ AXP20X_IRQ_DIE_TEMP_HIGH, -+ AXP20X_IRQ_CHARG_I_LOW, -+ AXP20X_IRQ_DCDC1_V_LONG, -+ AXP20X_IRQ_DCDC2_V_LONG, -+ AXP20X_IRQ_DCDC3_V_LONG, -+ AXP20X_IRQ_PEK_SHORT = 22, -+ AXP20X_IRQ_PEK_LONG, -+ AXP20X_IRQ_N_OE_PWR_ON, -+ AXP20X_IRQ_N_OE_PWR_OFF, -+ AXP20X_IRQ_VBUS_VALID, -+ AXP20X_IRQ_VBUS_NOT_VALID, -+ AXP20X_IRQ_VBUS_SESS_VALID, -+ AXP20X_IRQ_VBUS_SESS_END, -+ AXP20X_IRQ_LOW_PWR_LVL1, -+ AXP20X_IRQ_LOW_PWR_LVL2, -+ AXP20X_IRQ_TIMER, -+ AXP20X_IRQ_PEK_RIS_EDGE, -+ AXP20X_IRQ_PEK_FAL_EDGE, -+ AXP20X_IRQ_GPIO3_INPUT, -+ AXP20X_IRQ_GPIO2_INPUT, -+ AXP20X_IRQ_GPIO1_INPUT, -+ AXP20X_IRQ_GPIO0_INPUT, -+}; -+ -+struct axp20x_dev { -+ struct device *dev; -+ struct i2c_client *i2c_client; -+ struct regmap *regmap; -+ struct regmap_irq_chip_data *regmap_irqc; -+ int variant; -+ int irq; -+ bool pm_off; -+}; -+ -+#endif /* __LINUX_MFD_AXP20X_H */ diff --git a/target/linux/sunxi/patches-3.14/211-input-add-axp20x-power-enable-key-support.patch b/target/linux/sunxi/patches-3.14/211-input-add-axp20x-power-enable-key-support.patch deleted file mode 100644 index c7ce5e22b9..0000000000 --- a/target/linux/sunxi/patches-3.14/211-input-add-axp20x-power-enable-key-support.patch +++ /dev/null @@ -1,327 +0,0 @@ -From 656b9ff9781aa3ffeb4231f32dfc545c92d04a12 Mon Sep 17 00:00:00 2001 -From: Carlo Caione <carlo@caione.org> -Date: Sat, 1 Mar 2014 17:45:49 +0100 -Subject: [PATCH] input: misc: Add driver for AXP20x Power Enable Key - -This patch add support for the Power Enable Key found on MFD AXP202 and -AXP209. Besides the basic support for the button, the driver adds two -entries in sysfs to configure the time delay for power on/off. - -Signed-off-by: Carlo Caione <carlo@caione.org> ---- - arch/arm/configs/sunxi_defconfig | 2 + - drivers/input/misc/Kconfig | 11 ++ - drivers/input/misc/Makefile | 1 + - drivers/input/misc/axp20x-pek.c | 265 +++++++++++++++++++++++++++++++++++++++ - 4 files changed, 279 insertions(+) - create mode 100644 drivers/input/misc/axp20x-pek.c - ---- a/arch/arm/configs/sunxi_defconfig -+++ b/arch/arm/configs/sunxi_defconfig -@@ -40,6 +40,8 @@ CONFIG_SUN4I_EMAC=y - # CONFIG_NET_VENDOR_STMICRO is not set - # CONFIG_NET_VENDOR_WIZNET is not set - # CONFIG_WLAN is not set -+CONFIG_INPUT_MISC=y -+CONFIG_INPUT_AXP20X_PEK=y - CONFIG_SERIAL_8250=y - CONFIG_SERIAL_8250_CONSOLE=y - CONFIG_SERIAL_8250_NR_UARTS=8 ---- a/drivers/input/misc/Kconfig -+++ b/drivers/input/misc/Kconfig -@@ -393,6 +393,17 @@ config INPUT_RETU_PWRBUTTON - To compile this driver as a module, choose M here. The module will - be called retu-pwrbutton. - -+config INPUT_AXP20X_PEK -+ tristate "X-Powers AXP20X power button driver" -+ depends on MFD_AXP20X -+ help -+ Say Y here if you want to enable power key reporting via the -+ AXP20X PMIC. -+ -+ To compile this driver as a module, choose M here. The module will -+ be called axp20x-pek. -+ -+ - config INPUT_TWL4030_PWRBUTTON - tristate "TWL4030 Power button Driver" - depends on TWL4030_CORE ---- a/drivers/input/misc/Makefile -+++ b/drivers/input/misc/Makefile -@@ -50,6 +50,7 @@ obj-$(CONFIG_INPUT_POWERMATE) += powerm - obj-$(CONFIG_INPUT_PWM_BEEPER) += pwm-beeper.o - obj-$(CONFIG_INPUT_RB532_BUTTON) += rb532_button.o - obj-$(CONFIG_INPUT_RETU_PWRBUTTON) += retu-pwrbutton.o -+obj-$(CONFIG_INPUT_AXP20X_PEK) += axp20x-pek.o - obj-$(CONFIG_INPUT_GPIO_ROTARY_ENCODER) += rotary_encoder.o - obj-$(CONFIG_INPUT_SGI_BTNS) += sgi_btns.o - obj-$(CONFIG_INPUT_SIRFSOC_ONKEY) += sirfsoc-onkey.o ---- /dev/null -+++ b/drivers/input/misc/axp20x-pek.c -@@ -0,0 +1,265 @@ -+/* -+ * axp20x power button driver. -+ * -+ * Copyright (C) 2013 Carlo Caione <carlo@caione.org> -+ * -+ * This file is subject to the terms and conditions of the GNU General -+ * Public License. See the file "COPYING" in the main directory of this -+ * archive for more details. -+ * -+ * 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. -+ */ -+ -+#include <linux/errno.h> -+#include <linux/irq.h> -+#include <linux/init.h> -+#include <linux/input.h> -+#include <linux/interrupt.h> -+#include <linux/kernel.h> -+#include <linux/mfd/axp20x.h> -+#include <linux/module.h> -+#include <linux/platform_device.h> -+#include <linux/regmap.h> -+#include <linux/slab.h> -+ -+#define AXP20X_PEK_STARTUP_MASK (0xc0) -+#define AXP20X_PEK_SHUTDOWN_MASK (0x03) -+ -+static const char const *startup_time[] = { "128mS", "3S" , "1S", "2S" }; -+static const char const *shutdown_time[] = { "4S", "6S" , "8S", "10S" }; -+ -+struct axp20x_pek { -+ struct axp20x_dev *axp20x; -+ struct input_dev *input; -+ int irq_dbr; -+ int irq_dbf; -+}; -+ -+struct axp20x_pek_ext_attr { -+ const char const **str; -+ unsigned int mask; -+}; -+ -+static struct axp20x_pek_ext_attr axp20x_pek_startup_ext_attr = { -+ .str = startup_time, -+ .mask = AXP20X_PEK_STARTUP_MASK, -+}; -+ -+static struct axp20x_pek_ext_attr axp20x_pek_shutdown_ext_attr = { -+ .str = shutdown_time, -+ .mask = AXP20X_PEK_SHUTDOWN_MASK, -+}; -+ -+static struct axp20x_pek_ext_attr *get_axp_ext_attr(struct device_attribute *attr) -+{ -+ return container_of(attr, struct dev_ext_attribute, attr)->var; -+} -+ -+ssize_t axp20x_show_ext_attr(struct device *dev, struct device_attribute *attr, -+ char *buf) -+{ -+ struct axp20x_pek *axp20x_pek = dev_get_drvdata(dev); -+ struct axp20x_pek_ext_attr *axp20x_ea = get_axp_ext_attr(attr); -+ unsigned int val; -+ int ret, i; -+ int cnt = 0; -+ -+ ret = regmap_read(axp20x_pek->axp20x->regmap, AXP20X_PEK_KEY, &val); -+ if (ret != 0) -+ return ret; -+ -+ val &= axp20x_ea->mask; -+ val >>= ffs(axp20x_ea->mask) - 1; -+ -+ for (i = 0; i < 4; i++) { -+ if (val == i) -+ cnt += sprintf(buf + cnt, "[%s] ", axp20x_ea->str[i]); -+ else -+ cnt += sprintf(buf + cnt, "%s ", axp20x_ea->str[i]); -+ } -+ -+ cnt += sprintf(buf + cnt, "\n"); -+ -+ return cnt; -+} -+ -+ssize_t axp20x_store_ext_attr(struct device *dev, struct device_attribute *attr, -+ const char *buf, size_t count) -+{ -+ struct axp20x_pek *axp20x_pek = dev_get_drvdata(dev); -+ struct axp20x_pek_ext_attr *axp20x_ea = get_axp_ext_attr(attr); -+ char val_str[20]; -+ int ret, i; -+ size_t len; -+ -+ val_str[sizeof(val_str) - 1] = '\0'; -+ strncpy(val_str, buf, sizeof(val_str) - 1); -+ len = strlen(val_str); -+ -+ if (len && val_str[len - 1] == '\n') -+ val_str[len - 1] = '\0'; -+ -+ for (i = 0; i < 4; i++) { -+ if (!strcmp(val_str, axp20x_ea->str[i])) { -+ ret = regmap_update_bits(axp20x_pek->axp20x->regmap, -+ AXP20X_PEK_KEY, -+ axp20x_ea->mask, i); -+ if (ret != 0) -+ return -EINVAL; -+ return count; -+ } -+ } -+ -+ return -EINVAL; -+} -+ -+static struct dev_ext_attribute axp20x_dev_attr_startup = { -+ .attr = __ATTR(startup, 0644, axp20x_show_ext_attr, axp20x_store_ext_attr), -+ .var = &axp20x_pek_startup_ext_attr -+}; -+ -+static struct dev_ext_attribute axp20x_dev_attr_shutdown = { -+ __ATTR(shutdown, 0644, axp20x_show_ext_attr, axp20x_store_ext_attr), -+ &axp20x_pek_shutdown_ext_attr -+}; -+ -+static struct attribute *dev_attrs[] = { -+ &axp20x_dev_attr_startup.attr.attr, -+ &axp20x_dev_attr_shutdown.attr.attr, -+ NULL, -+}; -+ -+static struct attribute_group dev_attr_group = { -+ .attrs = dev_attrs, -+}; -+ -+static const struct attribute_group *dev_attr_groups[] = { -+ &dev_attr_group, -+ NULL, -+}; -+ -+static irqreturn_t axp20x_pek_irq(int irq, void *pwr) -+{ -+ struct input_dev *idev = pwr; -+ struct axp20x_pek *axp20x_pek = input_get_drvdata(idev); -+ -+ if (irq == axp20x_pek->irq_dbr) -+ input_report_key(idev, KEY_POWER, true); -+ else if (irq == axp20x_pek->irq_dbf) -+ input_report_key(idev, KEY_POWER, false); -+ -+ input_sync(idev); -+ -+ return IRQ_HANDLED; -+} -+ -+static int axp20x_pek_probe(struct platform_device *pdev) -+{ -+ struct axp20x_pek *axp20x_pek; -+ struct axp20x_dev *axp20x; -+ struct input_dev *idev; -+ int error; -+ -+ axp20x_pek = devm_kzalloc(&pdev->dev, sizeof(struct axp20x_pek), -+ GFP_KERNEL); -+ if (!axp20x_pek) -+ return -ENOMEM; -+ -+ axp20x_pek->axp20x = dev_get_drvdata(pdev->dev.parent); -+ axp20x = axp20x_pek->axp20x; -+ -+ axp20x_pek->irq_dbr = platform_get_irq_byname(pdev, "PEK_DBR"); -+ if (axp20x_pek->irq_dbr < 0) { -+ dev_err(&pdev->dev, "No IRQ for PEK_DBR, error=%d\n", -+ axp20x_pek->irq_dbr); -+ return axp20x_pek->irq_dbr; -+ } -+ axp20x_pek->irq_dbr = regmap_irq_get_virq(axp20x->regmap_irqc, -+ axp20x_pek->irq_dbr); -+ -+ axp20x_pek->irq_dbf = platform_get_irq_byname(pdev, "PEK_DBF"); -+ if (axp20x_pek->irq_dbf < 0) { -+ dev_err(&pdev->dev, "No IRQ for PEK_DBF, error=%d\n", -+ axp20x_pek->irq_dbf); -+ return axp20x_pek->irq_dbf; -+ } -+ axp20x_pek->irq_dbf = regmap_irq_get_virq(axp20x->regmap_irqc, -+ axp20x_pek->irq_dbf); -+ -+ axp20x_pek->input = devm_input_allocate_device(&pdev->dev); -+ if (!axp20x_pek->input) -+ return -ENOMEM; -+ -+ idev = axp20x_pek->input; -+ -+ idev->name = "axp20x-pek"; -+ idev->phys = "m1kbd/input2"; -+ idev->dev.parent = &pdev->dev; -+ -+ input_set_capability(idev, EV_KEY, KEY_POWER); -+ -+ input_set_drvdata(idev, axp20x_pek); -+ -+ error = devm_request_threaded_irq(&pdev->dev, axp20x_pek->irq_dbr, -+ NULL, axp20x_pek_irq, 0, -+ "axp20x-pek-dbr", idev); -+ if (error) { -+ dev_err(axp20x->dev, "Failed to request dbr IRQ#%d: %d\n", -+ axp20x_pek->irq_dbr, error); -+ -+ return error; -+ } -+ -+ error = devm_request_threaded_irq(&pdev->dev, axp20x_pek->irq_dbf, -+ NULL, axp20x_pek_irq, 0, -+ "axp20x-pek-dbf", idev); -+ if (error) { -+ dev_err(axp20x->dev, "Failed to request dbf IRQ#%d: %d\n", -+ axp20x_pek->irq_dbf, error); -+ return error; -+ } -+ -+ idev->dev.groups = dev_attr_groups; -+ error = input_register_device(idev); -+ if (error) { -+ dev_err(axp20x->dev, "Can't register input device: %d\n", error); -+ return error; -+ } -+ -+ platform_set_drvdata(pdev, axp20x_pek); -+ -+ return 0; -+} -+ -+static int axp20x_pek_remove(struct platform_device *pdev) -+{ -+ struct axp20x_pek *axp20x_pek = platform_get_drvdata(pdev); -+ -+ input_unregister_device(axp20x_pek->input); -+ -+ return 0; -+} -+ -+static const struct of_device_id axp20x_pek_match[] = { -+ { .compatible = "x-powers,axp20x-pek", }, -+ { /* sentinel */ }, -+}; -+MODULE_DEVICE_TABLE(of, axp20x_pek_match); -+ -+static struct platform_driver axp20x_pek_driver = { -+ .probe = axp20x_pek_probe, -+ .remove = axp20x_pek_remove, -+ .driver = { -+ .name = "axp20x-pek", -+ .owner = THIS_MODULE, -+ .of_match_table = axp20x_pek_match, -+ }, -+}; -+module_platform_driver(axp20x_pek_driver); -+ -+MODULE_DESCRIPTION("axp20x Power Button"); -+MODULE_AUTHOR("Carlo Caione <carlo@caione.org>"); -+MODULE_LICENSE("GPL"); diff --git a/target/linux/sunxi/patches-3.14/212-regulator-add-axp20x-regulator-support.patch b/target/linux/sunxi/patches-3.14/212-regulator-add-axp20x-regulator-support.patch deleted file mode 100644 index 1ec041ceb7..0000000000 --- a/target/linux/sunxi/patches-3.14/212-regulator-add-axp20x-regulator-support.patch +++ /dev/null @@ -1,402 +0,0 @@ -From c3af279a9031b3375d3e5a684619c1adbbe30da9 Mon Sep 17 00:00:00 2001 -From: Carlo Caione <carlo@caione.org> -Date: Sat, 1 Mar 2014 17:45:51 +0100 -Subject: [PATCH] regulator: AXP20x: Add support for regulators subsystem - -AXP202 and AXP209 come with two synchronous step-down DC-DCs and five -LDOs. This patch introduces basic support for those regulators. - -Signed-off-by: Carlo Caione <carlo@caione.org> ---- - arch/arm/configs/sunxi_defconfig | 1 + - drivers/regulator/Kconfig | 7 + - drivers/regulator/Makefile | 1 + - drivers/regulator/axp20x-regulator.c | 349 +++++++++++++++++++++++++++++++++++ - 4 files changed, 358 insertions(+) - create mode 100644 drivers/regulator/axp20x-regulator.c - ---- a/arch/arm/configs/sunxi_defconfig -+++ b/arch/arm/configs/sunxi_defconfig -@@ -72,3 +72,4 @@ CONFIG_NFS_FS=y - CONFIG_ROOT_NFS=y - CONFIG_NLS=y - CONFIG_PRINTK_TIME=y -+CONFIG_REGULATOR_AXP20X=y ---- a/drivers/regulator/Kconfig -+++ b/drivers/regulator/Kconfig -@@ -139,6 +139,13 @@ config REGULATOR_AS3722 - AS3722 PMIC. This will enable support for all the software - controllable DCDC/LDO regulators. - -+config REGULATOR_AXP20X -+ tristate "X-POWERS AXP20X PMIC Regulators" -+ depends on MFD_AXP20X -+ help -+ This driver provides support for the voltage regulators on the -+ AXP20X PMIC. -+ - config REGULATOR_DA903X - tristate "Dialog Semiconductor DA9030/DA9034 regulators" - depends on PMIC_DA903X ---- a/drivers/regulator/Makefile -+++ b/drivers/regulator/Makefile -@@ -20,6 +20,7 @@ obj-$(CONFIG_REGULATOR_ANATOP) += anatop - obj-$(CONFIG_REGULATOR_ARIZONA) += arizona-micsupp.o arizona-ldo1.o - obj-$(CONFIG_REGULATOR_AS3711) += as3711-regulator.o - obj-$(CONFIG_REGULATOR_AS3722) += as3722-regulator.o -+obj-$(CONFIG_REGULATOR_AXP20X) += axp20x-regulator.o - obj-$(CONFIG_REGULATOR_DA903X) += da903x.o - obj-$(CONFIG_REGULATOR_DA9052) += da9052-regulator.o - obj-$(CONFIG_REGULATOR_DA9055) += da9055-regulator.o ---- /dev/null -+++ b/drivers/regulator/axp20x-regulator.c -@@ -0,0 +1,349 @@ -+/* -+ * axp20x regulators driver. -+ * -+ * Copyright (C) 2013 Carlo Caione <carlo@caione.org> -+ * -+ * This file is subject to the terms and conditions of the GNU General -+ * Public License. See the file "COPYING" in the main directory of this -+ * archive for more details. -+ * -+ * 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. -+ */ -+ -+#include <linux/module.h> -+#include <linux/init.h> -+#include <linux/err.h> -+#include <linux/platform_device.h> -+#include <linux/of.h> -+#include <linux/of_device.h> -+#include <linux/regulator/driver.h> -+#include <linux/regulator/of_regulator.h> -+#include <linux/mfd/axp20x.h> -+#include <linux/regmap.h> -+ -+#define AXP20X_IO_ENABLED (0x03) -+ -+#define AXP20X_WORKMODE_DCDC2_MASK BIT(2) -+#define AXP20X_WORKMODE_DCDC3_MASK BIT(1) -+ -+#define AXP20X_FREQ_DCDC_MASK (0x0f) -+ -+struct axp20x_regulators { -+ struct regulator_desc rdesc[AXP20X_REG_ID_MAX]; -+ struct regulator_dev *rdev[AXP20X_REG_ID_MAX]; -+ struct axp20x_dev *axp20x; -+}; -+ -+#define AXP20X_DESC(_id, _min, _max, _step, _vreg, _vmask, _ereg, _emask) \ -+ [AXP20X_##_id] = { \ -+ .name = #_id, \ -+ .type = REGULATOR_VOLTAGE, \ -+ .id = AXP20X_##_id, \ -+ .n_voltages = (((_max) - (_min)) / (_step) + 1), \ -+ .owner = THIS_MODULE, \ -+ .min_uV = (_min) * 1000, \ -+ .uV_step = (_step) * 1000, \ -+ .vsel_reg = (_vreg), \ -+ .vsel_mask = (_vmask), \ -+ .enable_reg = (_ereg), \ -+ .enable_mask = (_emask), \ -+ .ops = &axp20x_ops, \ -+ } -+ -+#define AXP20X_DESC_IO(_id, _min, _max, _step, _vreg, _vmask, _ereg, _emask) \ -+ [AXP20X_##_id] = { \ -+ .name = #_id, \ -+ .type = REGULATOR_VOLTAGE, \ -+ .id = AXP20X_##_id, \ -+ .n_voltages = (((_max) - (_min)) / (_step) + 1), \ -+ .owner = THIS_MODULE, \ -+ .min_uV = (_min) * 1000, \ -+ .uV_step = (_step) * 1000, \ -+ .vsel_reg = (_vreg), \ -+ .vsel_mask = (_vmask), \ -+ .enable_reg = (_ereg), \ -+ .enable_mask = (_emask), \ -+ .ops = &axp20x_ops_io, \ -+ } -+ -+#define AXP20X_DESC_FIXED(_id, _volt) \ -+ [AXP20X_##_id] = { \ -+ .name = #_id, \ -+ .type = REGULATOR_VOLTAGE, \ -+ .id = AXP20X_##_id, \ -+ .n_voltages = 1, \ -+ .owner = THIS_MODULE, \ -+ .min_uV = (_volt) * 1000, \ -+ .ops = &axp20x_ops, \ -+ } -+ -+#define AXP20X_DESC_TABLE(_id, _table, _vreg, _vmask, _ereg, _emask) \ -+ [AXP20X_##_id] = { \ -+ .name = #_id, \ -+ .type = REGULATOR_VOLTAGE, \ -+ .id = AXP20X_##_id, \ -+ .n_voltages = ARRAY_SIZE(_table), \ -+ .owner = THIS_MODULE, \ -+ .vsel_reg = (_vreg), \ -+ .vsel_mask = (_vmask), \ -+ .enable_reg = (_ereg), \ -+ .enable_mask = (_emask), \ -+ .volt_table = (_table), \ -+ .ops = &axp20x_ops_table, \ -+ } -+ -+static int axp20x_ldo4_data[] = { 1250000, 1300000, 1400000, 1500000, 1600000, 1700000, -+ 1800000, 1900000, 2000000, 2500000, 2700000, 2800000, -+ 3000000, 3100000, 3200000, 3300000 }; -+ -+static int axp20x_set_suspend_voltage(struct regulator_dev *rdev, int uV) -+{ -+ return regulator_set_voltage_sel_regmap(rdev, 0); -+} -+ -+static int axp20x_io_enable_regmap(struct regulator_dev *rdev) -+{ -+ return regmap_update_bits(rdev->regmap, rdev->desc->enable_reg, -+ rdev->desc->enable_mask, AXP20X_IO_ENABLED); -+} -+ -+static int axp109_io_is_enabled_regmap(struct regulator_dev *rdev) -+{ -+ unsigned int val; -+ int ret; -+ -+ ret = regmap_read(rdev->regmap, rdev->desc->enable_reg, &val); -+ if (ret != 0) -+ return ret; -+ -+ val &= rdev->desc->enable_mask; -+ return (val == AXP20X_IO_ENABLED); -+} -+ -+static struct regulator_ops axp20x_ops_table = { -+ .set_voltage_sel = regulator_set_voltage_sel_regmap, -+ .get_voltage_sel = regulator_get_voltage_sel_regmap, -+ .list_voltage = regulator_list_voltage_table, -+ .enable = regulator_enable_regmap, -+ .disable = regulator_disable_regmap, -+ .is_enabled = regulator_is_enabled_regmap, -+ .set_suspend_enable = regulator_enable_regmap, -+ .set_suspend_disable = regulator_disable_regmap, -+ .set_suspend_voltage = axp20x_set_suspend_voltage, -+}; -+ -+ -+static struct regulator_ops axp20x_ops = { -+ .set_voltage_sel = regulator_set_voltage_sel_regmap, -+ .get_voltage_sel = regulator_get_voltage_sel_regmap, -+ .list_voltage = regulator_list_voltage_linear, -+ .enable = regulator_enable_regmap, -+ .disable = regulator_disable_regmap, -+ .is_enabled = regulator_is_enabled_regmap, -+ .set_suspend_enable = regulator_enable_regmap, -+ .set_suspend_disable = regulator_disable_regmap, -+ .set_suspend_voltage = axp20x_set_suspend_voltage, -+}; -+ -+static struct regulator_ops axp20x_ops_io = { -+ .set_voltage_sel = regulator_set_voltage_sel_regmap, -+ .get_voltage_sel = regulator_get_voltage_sel_regmap, -+ .list_voltage = regulator_list_voltage_linear, -+ .enable = axp20x_io_enable_regmap, -+ .disable = regulator_disable_regmap, -+ .is_enabled = axp109_io_is_enabled_regmap, -+ .set_suspend_enable = regulator_enable_regmap, -+ .set_suspend_disable = regulator_disable_regmap, -+ .set_suspend_voltage = axp20x_set_suspend_voltage, -+}; -+ -+static struct regulator_desc axp20x_regulators[] = { -+ AXP20X_DESC(DCDC2, 700, 2275, 25, AXP20X_DCDC2_V_OUT, 0x3f, -+ AXP20X_PWR_OUT_CTRL, 0x10), -+ AXP20X_DESC(DCDC3, 700, 3500, 25, AXP20X_DCDC3_V_OUT, 0x7f, -+ AXP20X_PWR_OUT_CTRL, 0x02), -+ AXP20X_DESC_FIXED(LDO1, 1300), -+ AXP20X_DESC(LDO2, 1800, 3300, 100, AXP20X_LDO24_V_OUT, 0xf0, -+ AXP20X_PWR_OUT_CTRL, 0x04), -+ AXP20X_DESC(LDO3, 700, 3500, 25, AXP20X_LDO3_V_OUT, 0x7f, -+ AXP20X_PWR_OUT_CTRL, 0x40), -+ AXP20X_DESC_TABLE(LDO4, axp20x_ldo4_data, AXP20X_LDO24_V_OUT, 0x0f, -+ AXP20X_PWR_OUT_CTRL, 0x08), -+ AXP20X_DESC_IO(LDO5, 1800, 3300, 100, AXP20X_LDO5_V_OUT, 0xf0, -+ AXP20X_GPIO0_CTRL, 0x07), -+}; -+ -+#define AXP_MATCH(_name, _id) \ -+ [AXP20X_##_id] = { \ -+ .name = #_name, \ -+ .driver_data = (void *) &axp20x_regulators[AXP20X_##_id], \ -+ } -+ -+static struct of_regulator_match axp20x_matches[] = { -+ AXP_MATCH(dcdc2, DCDC2), -+ AXP_MATCH(dcdc3, DCDC3), -+ AXP_MATCH(ldo1, LDO1), -+ AXP_MATCH(ldo2, LDO2), -+ AXP_MATCH(ldo3, LDO3), -+ AXP_MATCH(ldo4, LDO4), -+ AXP_MATCH(ldo5, LDO5), -+}; -+ -+static int axp20x_set_dcdc_freq(struct platform_device *pdev, u32 dcdcfreq) -+{ -+ struct axp20x_dev *axp20x = dev_get_drvdata(pdev->dev.parent); -+ -+ if (dcdcfreq < 750) -+ dcdcfreq = 750; -+ -+ if (dcdcfreq > 1875) -+ dcdcfreq = 1875; -+ -+ dcdcfreq = (dcdcfreq - 750) / 75; -+ -+ return regmap_update_bits(axp20x->regmap, AXP20X_DCDC_FREQ, -+ AXP20X_FREQ_DCDC_MASK, dcdcfreq); -+} -+ -+static int axp20x_regulator_parse_dt(struct platform_device *pdev) -+{ -+ struct device_node *np, *regulators; -+ int ret; -+ u32 dcdcfreq; -+ -+ np = of_node_get(pdev->dev.parent->of_node); -+ if (!np) -+ return 0; -+ -+ regulators = of_find_node_by_name(np, "regulators"); -+ if (!regulators) { -+ dev_err(&pdev->dev, "regulators node not found\n"); -+ return -EINVAL; -+ } -+ -+ ret = of_regulator_match(&pdev->dev, regulators, axp20x_matches, -+ ARRAY_SIZE(axp20x_matches)); -+ if (ret < 0) { -+ dev_err(&pdev->dev, "Error parsing regulator init data: %d\n", -+ ret); -+ return ret; -+ } -+ -+ dcdcfreq = 0x08; -+ of_property_read_u32(regulators, "dcdc-freq", &dcdcfreq); -+ ret = axp20x_set_dcdc_freq(pdev, dcdcfreq); -+ if (ret < 0) { -+ dev_err(&pdev->dev, "Error setting dcdc frequency: %d\n", ret); -+ return ret; -+ } -+ -+ of_node_put(regulators); -+ -+ return 0; -+} -+ -+static int axp20x_set_dcdc_workmode(struct regulator_dev *rdev, int id, u32 workmode) -+{ -+ unsigned int mask = AXP20X_WORKMODE_DCDC2_MASK; -+ -+ if ((id != AXP20X_DCDC2) && (id != AXP20X_DCDC3)) -+ return -EINVAL; -+ -+ if (id == AXP20X_DCDC3) -+ mask = AXP20X_WORKMODE_DCDC3_MASK; -+ -+ return regmap_update_bits(rdev->regmap, AXP20X_DCDC_MODE, mask, workmode); -+} -+ -+static int axp20x_regulator_probe(struct platform_device *pdev) -+{ -+ struct axp20x_regulators *pmic; -+ struct axp20x_dev *axp20x = dev_get_drvdata(pdev->dev.parent); -+ struct regulator_config config = { }; -+ struct regulator_init_data *init_data; -+ int ret, i; -+ u32 workmode; -+ -+ ret = axp20x_regulator_parse_dt(pdev); -+ if (ret) -+ return ret; -+ -+ pmic = devm_kzalloc(&pdev->dev, sizeof(*pmic), GFP_KERNEL); -+ if (!pmic) { -+ dev_err(&pdev->dev, "Failed to alloc pmic\n"); -+ return -ENOMEM; -+ } -+ -+ pmic->axp20x = axp20x; -+ memcpy(pmic->rdesc, axp20x_regulators, sizeof(pmic->rdesc)); -+ platform_set_drvdata(pdev, pmic); -+ -+ for (i = 0; i < AXP20X_REG_ID_MAX; i++) { -+ init_data = axp20x_matches[i].init_data; -+ if (!init_data) -+ continue; -+ -+ config.dev = &pdev->dev; -+ config.init_data = init_data; -+ config.driver_data = pmic; -+ config.regmap = axp20x->regmap; -+ config.of_node = axp20x_matches[i].of_node; -+ -+ pmic->rdev[i] = regulator_register(&pmic->rdesc[i], &config); -+ if (IS_ERR(pmic->rdev[i])) { -+ ret = PTR_ERR(pmic->rdev[i]); -+ dev_err(&pdev->dev, "Failed to register %s\n", -+ pmic->rdesc[i].name); -+ -+ while (--i >= 0) -+ regulator_unregister(pmic->rdev[i]); -+ -+ return ret; -+ } -+ -+ ret = of_property_read_u32(axp20x_matches[i].of_node, "dcdc-workmode", -+ &workmode); -+ if (!ret) { -+ ret = axp20x_set_dcdc_workmode(pmic->rdev[i], i, workmode); -+ if (ret) -+ dev_err(&pdev->dev, "Failed to set workmode on %s\n", -+ pmic->rdesc[i].name); -+ } -+ } -+ -+ return 0; -+} -+ -+static int axp20x_regulator_remove(struct platform_device *pdev) -+{ -+ struct axp20x_regulators *pmic = platform_get_drvdata(pdev); -+ int i; -+ -+ for (i = 0; i < AXP20X_REG_ID_MAX; i++) -+ regulator_unregister(pmic->rdev[i]); -+ -+ return 0; -+} -+ -+static struct platform_driver axp20x_regulator_driver = { -+ .probe = axp20x_regulator_probe, -+ .remove = axp20x_regulator_remove, -+ .driver = { -+ .name = "axp20x-regulator", -+ .owner = THIS_MODULE, -+ }, -+}; -+ -+static int __init axp20x_regulator_init(void) -+{ -+ return platform_driver_register(&axp20x_regulator_driver); -+} -+ -+subsys_initcall(axp20x_regulator_init); -+ -+MODULE_LICENSE("GPL v2"); -+MODULE_AUTHOR("Carlo Caione <carlo@caione.org>"); -+MODULE_DESCRIPTION("Regulator Driver for AXP20X PMIC"); diff --git a/target/linux/sunxi/patches-3.14/213-dt-sunxi-add-x-powers.patch b/target/linux/sunxi/patches-3.14/213-dt-sunxi-add-x-powers.patch deleted file mode 100644 index aa29a01089..0000000000 --- a/target/linux/sunxi/patches-3.14/213-dt-sunxi-add-x-powers.patch +++ /dev/null @@ -1,77 +0,0 @@ -From 7b42dc4ff2cca887e0c6e1ad291d65b30e64dd92 Mon Sep 17 00:00:00 2001 -From: Hans de Goede <hdegoede@redhat.com> -Date: Wed, 5 Mar 2014 20:30:41 +0100 -Subject: [PATCH] ARM: sunxi: dt: Add x-powers-axp209.dtsi file - -This dtsi describes the axp209 PMIC, and is to be included from inside -the i2c controller node to which the axp209 is connected. - -Signed-off-by: Hans de Goede <hdegoede@redhat.com> ---- - arch/arm/boot/dts/x-powers-axp209.dtsi | 60 ++++++++++++++++++++++++++++++++++ - 1 file changed, 60 insertions(+) - create mode 100644 arch/arm/boot/dts/x-powers-axp209.dtsi - ---- /dev/null -+++ b/arch/arm/boot/dts/x-powers-axp209.dtsi -@@ -0,0 +1,60 @@ -+/* -+ * x-powers,axp209 common code to be include from inside the axp209 node -+ * -+ * Copyright 2014 - Carlo Caione <carlo@caione.org> -+ * -+ * 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 -+ */ -+ -+ compatible = "x-powers,axp209"; -+ interrupt-controller; -+ #interrupt-cells = <1>; -+ -+ regulators { -+ dcdc-freq = "8"; -+ -+ axp_dcdc2: dcdc2 { -+ regulator-min-microvolt = <700000>; -+ regulator-max-microvolt = <2275000>; -+ dcdc-workmode = <0>; -+ regulator-always-on; -+ }; -+ -+ axp_dcdc3: dcdc3 { -+ regulator-min-microvolt = <700000>; -+ regulator-max-microvolt = <3500000>; -+ dcdc-workmode = <0>; -+ regulator-always-on; -+ }; -+ -+ axp_ldo1: ldo1 { -+ regulator-min-microvolt = <1300000>; -+ regulator-max-microvolt = <1300000>; -+ }; -+ -+ axp_ldo2: ldo2 { -+ regulator-min-microvolt = <1800000>; -+ regulator-max-microvolt = <3300000>; -+ regulator-always-on; -+ }; -+ -+ axp_ldo3: ldo3 { -+ regulator-min-microvolt = <700000>; -+ regulator-max-microvolt = <3500000>; -+ }; -+ -+ axp_ldo4: ldo4 { -+ regulator-min-microvolt = <1250000>; -+ regulator-max-microvolt = <3300000>; -+ }; -+ -+ axp_ldo5: ldo5 { -+ regulator-min-microvolt = <1800000>; -+ regulator-max-microvolt = <3300000>; -+ }; -+ }; diff --git a/target/linux/sunxi/patches-3.14/214-1-dt-sun7i-add-axp209-to-cubieboard2.patch b/target/linux/sunxi/patches-3.14/214-1-dt-sun7i-add-axp209-to-cubieboard2.patch deleted file mode 100644 index f7f4d9af98..0000000000 --- a/target/linux/sunxi/patches-3.14/214-1-dt-sun7i-add-axp209-to-cubieboard2.patch +++ /dev/null @@ -1,35 +0,0 @@ -From c792a05efcfebcf94ba925135a778961700965f5 Mon Sep 17 00:00:00 2001 -From: Carlo Caione <carlo@caione.org> -Date: Sat, 1 Mar 2014 17:45:48 +0100 -Subject: [PATCH] ARM: sun7i: dt: Add AXP209 support to the cubieboard2 - -AXP209 is the PMU used by Cubieboard2. This patch enables the AXP209 -support in the dts file. - -This patch requires: "ARM: sun7i/sun6i: irqchip: Add irqchip driver for -NMI controller" - -Signed-off-by: Carlo Caione <carlo@caione.org> ---- - arch/arm/boot/dts/sun7i-a20-cubieboard2.dts | 10 ++++++++++ - 1 file changed, 10 insertions(+) - ---- a/arch/arm/boot/dts/sun7i-a20-cubieboard2.dts -+++ b/arch/arm/boot/dts/sun7i-a20-cubieboard2.dts -@@ -74,6 +74,16 @@ - pinctrl-names = "default"; - pinctrl-0 = <&i2c0_pins_a>; - status = "okay"; -+ -+ axp: axp20x@34 { -+ reg = <0x34>; -+ interrupt-parent = <&nmi_intc>; -+ interrupts = <0 8>; -+ -+ axp,system-power-controller; -+ -+ /include/ "x-powers-axp209.dtsi" -+ }; - }; - - i2c1: i2c@01c2b000 { diff --git a/target/linux/sunxi/patches-3.14/214-2-dt-sun4i-add-axp209-to-boards.patch b/target/linux/sunxi/patches-3.14/214-2-dt-sun4i-add-axp209-to-boards.patch deleted file mode 100644 index 35dea87902..0000000000 --- a/target/linux/sunxi/patches-3.14/214-2-dt-sun4i-add-axp209-to-boards.patch +++ /dev/null @@ -1,142 +0,0 @@ -From d14c5523653ca6ce9f1487922c8ab4e571d17b62 Mon Sep 17 00:00:00 2001 -From: Hans de Goede <hdegoede@redhat.com> -Date: Tue, 11 Mar 2014 16:51:44 +0100 -Subject: [PATCH] ARM: sun4i: dt: Add AXP209 support to various boards - -Signed-off-by: Hans de Goede <hdegoede@redhat.com> ---- - arch/arm/boot/dts/sun4i-a10-a1000.dts | 9 +++++++++ - arch/arm/boot/dts/sun4i-a10-cubieboard.dts | 9 +++++++++ - arch/arm/boot/dts/sun4i-a10-hackberry.dts | 15 +++++++++++++++ - arch/arm/boot/dts/sun4i-a10-inet97fv2.dts | 9 +++++++++ - arch/arm/boot/dts/sun4i-a10-mini-xplus.dts | 15 +++++++++++++++ - arch/arm/boot/dts/sun4i-a10-olinuxino-lime.dts | 15 +++++++++++++++ - arch/arm/boot/dts/sun4i-a10-pcduino.dts | 9 +++++++++ - 7 files changed, 81 insertions(+) - ---- a/arch/arm/boot/dts/sun4i-a10-a1000.dts -+++ b/arch/arm/boot/dts/sun4i-a10-a1000.dts -@@ -65,6 +65,15 @@ - pinctrl-names = "default"; - pinctrl-0 = <&i2c0_pins_a>; - status = "okay"; -+ -+ axp: axp20x@34 { -+ reg = <0x34>; -+ interrupts = <0>; -+ -+ axp,system-power-controller; -+ -+ /include/ "x-powers-axp209.dtsi" -+ }; - }; - }; - ---- a/arch/arm/boot/dts/sun4i-a10-cubieboard.dts -+++ b/arch/arm/boot/dts/sun4i-a10-cubieboard.dts -@@ -88,6 +88,15 @@ - pinctrl-names = "default"; - pinctrl-0 = <&i2c0_pins_a>; - status = "okay"; -+ -+ axp: axp20x@34 { -+ reg = <0x34>; -+ interrupts = <0>; -+ -+ axp,system-power-controller; -+ -+ /include/ "x-powers-axp209.dtsi" -+ }; - }; - - i2c1: i2c@01c2b000 { ---- a/arch/arm/boot/dts/sun4i-a10-hackberry.dts -+++ b/arch/arm/boot/dts/sun4i-a10-hackberry.dts -@@ -82,6 +82,21 @@ - pinctrl-0 = <&uart0_pins_a>; - status = "okay"; - }; -+ -+ i2c0: i2c@01c2ac00 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&i2c0_pins_a>; -+ status = "okay"; -+ -+ axp: axp20x@34 { -+ reg = <0x34>; -+ interrupts = <0>; -+ -+ axp,system-power-controller; -+ -+ /include/ "x-powers-axp209.dtsi" -+ }; -+ }; - }; - - regulators { ---- a/arch/arm/boot/dts/sun4i-a10-mini-xplus.dts -+++ b/arch/arm/boot/dts/sun4i-a10-mini-xplus.dts -@@ -55,6 +55,21 @@ - pinctrl-0 = <&uart0_pins_a>; - status = "okay"; - }; -+ -+ i2c0: i2c@01c2ac00 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&i2c0_pins_a>; -+ status = "okay"; -+ -+ axp: axp20x@34 { -+ reg = <0x34>; -+ interrupts = <0>; -+ -+ axp,system-power-controller; -+ -+ /include/ "x-powers-axp209.dtsi" -+ }; -+ }; - }; - - reg_usb1_vbus: usb1-vbus { ---- a/arch/arm/boot/dts/sun4i-a10-olinuxino-lime.dts -+++ b/arch/arm/boot/dts/sun4i-a10-olinuxino-lime.dts -@@ -90,6 +90,21 @@ - pinctrl-0 = <&uart0_pins_a>; - status = "okay"; - }; -+ -+ i2c0: i2c@01c2ac00 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&i2c0_pins_a>; -+ status = "okay"; -+ -+ axp: axp20x@34 { -+ reg = <0x34>; -+ interrupts = <0>; -+ -+ axp,system-power-controller; -+ -+ /include/ "x-powers-axp209.dtsi" -+ }; -+ }; - }; - - leds { ---- a/arch/arm/boot/dts/sun4i-a10-pcduino.dts -+++ b/arch/arm/boot/dts/sun4i-a10-pcduino.dts -@@ -74,6 +74,15 @@ - pinctrl-names = "default"; - pinctrl-0 = <&i2c0_pins_a>; - status = "okay"; -+ -+ axp: axp20x@34 { -+ reg = <0x34>; -+ interrupts = <0>; -+ -+ axp,system-power-controller; -+ -+ /include/ "x-powers-axp209.dtsi" -+ }; - }; - }; - diff --git a/target/linux/sunxi/patches-3.14/214-3-dt-sun7i-add-axp209-to-cubietruck.patch b/target/linux/sunxi/patches-3.14/214-3-dt-sun7i-add-axp209-to-cubietruck.patch deleted file mode 100644 index 8764e9ed5c..0000000000 --- a/target/linux/sunxi/patches-3.14/214-3-dt-sun7i-add-axp209-to-cubietruck.patch +++ /dev/null @@ -1,49 +0,0 @@ -From 886f41537ad5e873caee522704e96e844a485961 Mon Sep 17 00:00:00 2001 -From: Hans de Goede <hdegoede@redhat.com> -Date: Wed, 5 Mar 2014 20:41:17 +0100 -Subject: [PATCH] ARM: sun7i: dt: Add AXP209 support to cubietruck - -Signed-off-by: Hans de Goede <hdegoede@redhat.com> ---- - arch/arm/boot/dts/sun7i-a20-cubietruck.dts | 10 ++++++++++ - arch/arm/boot/dts/sun7i-a20-olinuxino-micro.dts | 10 ++++++++++ - 2 files changed, 20 insertions(+) - ---- a/arch/arm/boot/dts/sun7i-a20-cubietruck.dts -+++ b/arch/arm/boot/dts/sun7i-a20-cubietruck.dts -@@ -89,6 +89,16 @@ - pinctrl-names = "default"; - pinctrl-0 = <&uart0_pins_a>; - status = "okay"; -+ -+ axp: axp20x@34 { -+ reg = <0x34>; -+ interrupt-parent = <&nmi_intc>; -+ interrupts = <0 8>; -+ -+ axp,system-power-controller; -+ -+ /include/ "x-powers-axp209.dtsi" -+ }; - }; - - i2c0: i2c@01c2ac00 { ---- a/arch/arm/boot/dts/sun7i-a20-olinuxino-micro.dts -+++ b/arch/arm/boot/dts/sun7i-a20-olinuxino-micro.dts -@@ -127,6 +127,16 @@ - pinctrl-names = "default"; - pinctrl-0 = <&i2c0_pins_a>; - status = "okay"; -+ -+ axp: axp20x@34 { -+ reg = <0x34>; -+ interrupt-parent = <&nmi_intc>; -+ interrupts = <0 8>; -+ -+ axp,system-power-controller; -+ -+ /include/ "x-powers-axp209.dtsi" -+ }; - }; - - i2c1: i2c@01c2b000 { diff --git a/target/linux/sunxi/patches-3.14/215-2-dt-sun5i-add-address-and-sizecells-to-i2c.patch b/target/linux/sunxi/patches-3.14/215-2-dt-sun5i-add-address-and-sizecells-to-i2c.patch deleted file mode 100644 index 9b5fd57863..0000000000 --- a/target/linux/sunxi/patches-3.14/215-2-dt-sun5i-add-address-and-sizecells-to-i2c.patch +++ /dev/null @@ -1,40 +0,0 @@ -From 505ad20db47442ae2650a41eca0a7a869aace789 Mon Sep 17 00:00:00 2001 -From: Hans de Goede <hdegoede@redhat.com> -Date: Wed, 5 Mar 2014 20:40:44 +0100 -Subject: [PATCH] ARM: sun5i: dt: Add address- and size-cells info to i2c - controller nodes - -Signed-off-by: Hans de Goede <hdegoede@redhat.com> ---- - arch/arm/boot/dts/sun5i-a13.dtsi | 6 ++++++ - 1 file changed, 6 insertions(+) - ---- a/arch/arm/boot/dts/sun5i-a13.dtsi -+++ b/arch/arm/boot/dts/sun5i-a13.dtsi -@@ -503,6 +503,8 @@ - clocks = <&apb1_gates 0>; - clock-frequency = <100000>; - status = "disabled"; -+ #address-cells = <1>; -+ #size-cells = <0>; - }; - - i2c1: i2c@01c2b000 { -@@ -512,6 +514,8 @@ - clocks = <&apb1_gates 1>; - clock-frequency = <100000>; - status = "disabled"; -+ #address-cells = <1>; -+ #size-cells = <0>; - }; - - i2c2: i2c@01c2b400 { -@@ -521,6 +525,8 @@ - clocks = <&apb1_gates 2>; - clock-frequency = <100000>; - status = "disabled"; -+ #address-cells = <1>; -+ #size-cells = <0>; - }; - - timer@01c60000 { diff --git a/target/linux/sunxi/patches-3.14/215-3-dt-sun7i-add-address-and-sizecells-to-i2c.patch b/target/linux/sunxi/patches-3.14/215-3-dt-sun7i-add-address-and-sizecells-to-i2c.patch deleted file mode 100644 index 35ae842f87..0000000000 --- a/target/linux/sunxi/patches-3.14/215-3-dt-sun7i-add-address-and-sizecells-to-i2c.patch +++ /dev/null @@ -1,58 +0,0 @@ -From 338560ad44f2e8b6f4eb095567830b6c78b35ba2 Mon Sep 17 00:00:00 2001 -From: Hans de Goede <hdegoede@redhat.com> -Date: Wed, 5 Mar 2014 20:40:57 +0100 -Subject: [PATCH] ARM: sun7i: dt: Add address- and size-cells info to i2c - controller nodes - -Signed-off-by: Hans de Goede <hdegoede@redhat.com> ---- - arch/arm/boot/dts/sun7i-a20.dtsi | 10 ++++++++++ - 1 file changed, 10 insertions(+) - ---- a/arch/arm/boot/dts/sun7i-a20.dtsi -+++ b/arch/arm/boot/dts/sun7i-a20.dtsi -@@ -848,6 +848,8 @@ - clocks = <&apb1_gates 0>; - clock-frequency = <100000>; - status = "disabled"; -+ #address-cells = <1>; -+ #size-cells = <0>; - }; - - i2c1: i2c@01c2b000 { -@@ -857,6 +859,8 @@ - clocks = <&apb1_gates 1>; - clock-frequency = <100000>; - status = "disabled"; -+ #address-cells = <1>; -+ #size-cells = <0>; - }; - - i2c2: i2c@01c2b400 { -@@ -866,6 +870,8 @@ - clocks = <&apb1_gates 2>; - clock-frequency = <100000>; - status = "disabled"; -+ #address-cells = <1>; -+ #size-cells = <0>; - }; - - i2c3: i2c@01c2b800 { -@@ -875,6 +881,8 @@ - clocks = <&apb1_gates 3>; - clock-frequency = <100000>; - status = "disabled"; -+ #address-cells = <1>; -+ #size-cells = <0>; - }; - - i2c4: i2c@01c2bc00 { -@@ -884,6 +892,8 @@ - clocks = <&apb1_gates 15>; - clock-frequency = <100000>; - status = "disabled"; -+ #address-cells = <1>; -+ #size-cells = <0>; - }; - - gmac: ethernet@01c50000 { diff --git a/target/linux/sunxi/patches-3.14/215-dt-sun4i-add-address-and-sizecells-to-i2c.patch b/target/linux/sunxi/patches-3.14/215-dt-sun4i-add-address-and-sizecells-to-i2c.patch deleted file mode 100644 index 60fe06f5aa..0000000000 --- a/target/linux/sunxi/patches-3.14/215-dt-sun4i-add-address-and-sizecells-to-i2c.patch +++ /dev/null @@ -1,40 +0,0 @@ -From 46d3d005e5f91d8221676cbb6307e790d4b63345 Mon Sep 17 00:00:00 2001 -From: Hans de Goede <hdegoede@redhat.com> -Date: Wed, 5 Mar 2014 20:40:26 +0100 -Subject: [PATCH] ARM: sun4i: dt: Add address- and size-cells info to i2c - controller nodes - -Signed-off-by: Hans de Goede <hdegoede@redhat.com> ---- - arch/arm/boot/dts/sun4i-a10.dtsi | 6 ++++++ - 1 file changed, 6 insertions(+) - ---- a/arch/arm/boot/dts/sun4i-a10.dtsi -+++ b/arch/arm/boot/dts/sun4i-a10.dtsi -@@ -712,6 +712,8 @@ - clocks = <&apb1_gates 0>; - clock-frequency = <100000>; - status = "disabled"; -+ #address-cells = <1>; -+ #size-cells = <0>; - }; - - i2c1: i2c@01c2b000 { -@@ -721,6 +723,8 @@ - clocks = <&apb1_gates 1>; - clock-frequency = <100000>; - status = "disabled"; -+ #address-cells = <1>; -+ #size-cells = <0>; - }; - - i2c2: i2c@01c2b400 { -@@ -730,6 +734,8 @@ - clocks = <&apb1_gates 2>; - clock-frequency = <100000>; - status = "disabled"; -+ #address-cells = <1>; -+ #size-cells = <0>; - }; - }; - }; diff --git a/target/linux/sunxi/patches-3.14/216-dt-sun7i-add-i2c-to-cubietruck.patch b/target/linux/sunxi/patches-3.14/216-dt-sun7i-add-i2c-to-cubietruck.patch deleted file mode 100644 index a8b0b61558..0000000000 --- a/target/linux/sunxi/patches-3.14/216-dt-sun7i-add-i2c-to-cubietruck.patch +++ /dev/null @@ -1,43 +0,0 @@ -From 6267355f0e513bed9a5009924abc7a1e7de22ab3 Mon Sep 17 00:00:00 2001 -From: Chen-Yu Tsai <wens@csie.org> -Date: Mon, 6 Jan 2014 13:58:12 +0800 -Subject: [PATCH] arm: sun7i: cubietruck: Enable the i2c controllers - -The Cubietruck makes use of the first three i2c controllers found on the -Allwinner A20; i2c-0 is used internally for the PMIC, i2c-1 is exposed on -the board headers, and i2c-2 is used for DDC on the VGA connector. This -patch enables them in the device tree. - -Signed-off-by: Chen-Yu Tsai <wens@csie.org> -Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com> ---- - arch/arm/boot/dts/sun7i-a20-cubietruck.dts | 18 ++++++++++++++++++ - 1 file changed, 18 insertions(+) - ---- a/arch/arm/boot/dts/sun7i-a20-cubietruck.dts -+++ b/arch/arm/boot/dts/sun7i-a20-cubietruck.dts -@@ -130,6 +130,24 @@ - reg = <1>; - }; - }; -+ -+ 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 { diff --git a/target/linux/sunxi/patches-3.14/220-clk-sunxi-remove-calls-to-clk_put.patch b/target/linux/sunxi/patches-3.14/220-clk-sunxi-remove-calls-to-clk_put.patch deleted file mode 100644 index bac72f99a6..0000000000 --- a/target/linux/sunxi/patches-3.14/220-clk-sunxi-remove-calls-to-clk_put.patch +++ /dev/null @@ -1,36 +0,0 @@ -From 81b745ee30dc7cd230f924f6263879f1b7ffbc0c Mon Sep 17 00:00:00 2001 -From: Maxime Ripard <maxime.ripard@free-electrons.com> -Date: Thu, 13 Mar 2014 16:14:13 +0100 -Subject: [PATCH] clk: sunxi: Remove calls to clk_put - -Callers of clk_put must disable the clock first. This also means that as long -as the clock is enabled the driver should hold a reference to that clock. -Hence, the call to clk_put here are bogus and should be removed. - -Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com> ---- - drivers/clk/sunxi/clk-sunxi.c | 8 ++------ - 1 file changed, 2 insertions(+), 6 deletions(-) - ---- a/drivers/clk/sunxi/clk-sunxi.c -+++ b/drivers/clk/sunxi/clk-sunxi.c -@@ -1325,17 +1325,13 @@ static void __init sunxi_clock_protect(v - - /* memory bus clock - sun5i+ */ - clk = clk_get(NULL, "mbus"); -- if (!IS_ERR(clk)) { -+ if (!IS_ERR(clk)) - clk_prepare_enable(clk); -- clk_put(clk); -- } - - /* DDR clock - sun4i+ */ - clk = clk_get(NULL, "pll5_ddr"); -- if (!IS_ERR(clk)) { -+ if (!IS_ERR(clk)) - clk_prepare_enable(clk); -- clk_put(clk); -- } - } - - static void __init sunxi_init_clocks(void) diff --git a/target/linux/sunxi/patches-3.14/230-net-rfkill-changes.patch b/target/linux/sunxi/patches-3.14/230-net-rfkill-changes.patch deleted file mode 100644 index d5e107875e..0000000000 --- a/target/linux/sunxi/patches-3.14/230-net-rfkill-changes.patch +++ /dev/null @@ -1,148 +0,0 @@ -From 5f6f6af41e39677c9b722376a4088d10732cdd44 Mon Sep 17 00:00:00 2001 -From: Chen-Yu Tsai <wens@csie.org> -Date: Fri, 17 Jan 2014 14:47:26 +0800 -Subject: [PATCH] net: rfkill: gpio: fix gpio name buffer size off by 1 - -snprintf should be passed the complete size of the buffer, including -the space for '\0'. The previous code resulted in the *_reset and -*_shutdown strings being truncated. - -Signed-off-by: Chen-Yu Tsai <wens@csie.org> ---- - net/rfkill/rfkill-gpio.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - ---- a/net/rfkill/rfkill-gpio.c -+++ b/net/rfkill/rfkill-gpio.c -@@ -26,6 +26,7 @@ - #include <linux/slab.h> - #include <linux/acpi.h> - #include <linux/gpio/consumer.h> -+#include <linux/of_gpio.h> - - #include <linux/rfkill-gpio.h> - -@@ -39,6 +40,7 @@ struct rfkill_gpio_data { - char *reset_name; - char *shutdown_name; - struct clk *clk; -+ int clk_frequency; - - bool clk_enabled; - }; -@@ -51,15 +53,15 @@ static int rfkill_gpio_set_power(void *d - gpiod_set_value(rfkill->shutdown_gpio, 0); - gpiod_set_value(rfkill->reset_gpio, 0); - if (!IS_ERR(rfkill->clk) && rfkill->clk_enabled) -- clk_disable(rfkill->clk); -+ clk_disable_unprepare(rfkill->clk); - } else { - if (!IS_ERR(rfkill->clk) && !rfkill->clk_enabled) -- clk_enable(rfkill->clk); -+ clk_prepare_enable(rfkill->clk); - gpiod_set_value(rfkill->reset_gpio, 1); - gpiod_set_value(rfkill->shutdown_gpio, 1); - } - -- rfkill->clk_enabled = blocked; -+ rfkill->clk_enabled = !blocked; - - return 0; - } -@@ -83,6 +85,19 @@ static int rfkill_gpio_acpi_probe(struct - return 0; - } - -+static int rfkill_gpio_dt_probe(struct device *dev, -+ struct rfkill_gpio_data *rfkill) -+{ -+ struct device_node * np = dev->of_node; -+ -+ rfkill->name = np->name; -+ of_property_read_string(np, "rfkill-name", &rfkill->name); -+ of_property_read_u32(np, "rfkill-type", &rfkill->type); -+ of_property_read_u32(np, "clock-frequency", &rfkill->clk_frequency); -+ -+ return 0; -+} -+ - static int rfkill_gpio_probe(struct platform_device *pdev) - { - struct rfkill_gpio_platform_data *pdata = pdev->dev.platform_data; -@@ -100,6 +115,10 @@ static int rfkill_gpio_probe(struct plat - ret = rfkill_gpio_acpi_probe(&pdev->dev, rfkill); - if (ret) - return ret; -+ } else if (&pdev->dev.of_node) { -+ ret = rfkill_gpio_dt_probe(&pdev->dev, rfkill); -+ if (ret) -+ return ret; - } else if (pdata) { - clk_name = pdata->power_clk_name; - rfkill->name = pdata->name; -@@ -117,10 +136,12 @@ static int rfkill_gpio_probe(struct plat - if (!rfkill->shutdown_name) - return -ENOMEM; - -- snprintf(rfkill->reset_name, len + 6 , "%s_reset", rfkill->name); -- snprintf(rfkill->shutdown_name, len + 9, "%s_shutdown", rfkill->name); -+ snprintf(rfkill->reset_name, len + 7 , "%s_reset", rfkill->name); -+ snprintf(rfkill->shutdown_name, len + 10, "%s_shutdown", rfkill->name); - - rfkill->clk = devm_clk_get(&pdev->dev, clk_name); -+ if (!IS_ERR(rfkill->clk) && rfkill->clk_frequency > 0) -+ clk_set_rate(rfkill->clk, rfkill->clk_frequency); - - gpio = devm_gpiod_get_index(&pdev->dev, rfkill->reset_name, 0); - if (!IS_ERR(gpio)) { -@@ -189,6 +210,11 @@ static const struct acpi_device_id rfkil - { }, - }; - -+static const struct of_device_id rfkill_of_match[] = { -+ { .compatible = "rfkill-gpio", }, -+ {}, -+}; -+ - static struct platform_driver rfkill_gpio_driver = { - .probe = rfkill_gpio_probe, - .remove = rfkill_gpio_remove, -@@ -196,6 +222,7 @@ static struct platform_driver rfkill_gpi - .name = "rfkill_gpio", - .owner = THIS_MODULE, - .acpi_match_table = ACPI_PTR(rfkill_acpi_match), -+ .of_match_table = of_match_ptr(rfkill_of_match), - }, - }; - ---- /dev/null -+++ b/Documentation/devicetree/bindings/rfkill/rfkill-gpio.txt -@@ -0,0 +1,28 @@ -+GPIO controlled RFKILL devices -+ -+Required properties: -+- compatible : Must be "rfkill-gpio". -+- rfkill-name : Name of RFKILL device -+- rfkill-type : Type of RFKILL device: 1 for WiFi, 2 for BlueTooth -+- NAME_shutdown-gpios : GPIO phandle to shutdown control -+ (phandle must be the second) -+- NAME_reset-gpios : GPIO phandle to reset control -+ -+NAME must match the rfkill-name property. NAME_shutdown-gpios or -+NAME_reset-gpios, or both, must be defined. -+ -+Optional properties: -+- clocks : phandle to clock to enable/disable -+- clock-frequency : clock rate to set for the given clock -+ -+Example: -+ -+ rfkill_bt: rfkill@0 { -+ compatible = "rfkill-gpio"; -+ rfkill-name = "bluetooth"; -+ rfkill-type = <2>; -+ bluetooth_shutdown-gpios = <0>, <&pio 7 18 0>; -+ bluetooth_reset-gpios = <&pio 7 24 0>; -+ clocks = <&clk_out_a>; -+ clock-frequency = <32678>; -+ }; diff --git a/target/linux/sunxi/patches-3.14/231-1-brcmfmac-fix-sdio-sending.patch b/target/linux/sunxi/patches-3.14/231-1-brcmfmac-fix-sdio-sending.patch deleted file mode 100644 index 7a8715ade4..0000000000 --- a/target/linux/sunxi/patches-3.14/231-1-brcmfmac-fix-sdio-sending.patch +++ /dev/null @@ -1,32 +0,0 @@ -From df25859babd9c164a61e86d953d5c88400009a14 Mon Sep 17 00:00:00 2001 -From: Hante Meuleman <meuleman@broadcom.com> -Date: Wed, 29 Jan 2014 15:32:16 +0100 -Subject: [PATCH] brcmfmac: fix sdio sending of large buffers. - -the function brcmf_sdiod_ramrw is supposed to be able to send -large blobs of data. However inside the loop the skb->len field -did not correctly get reset each round. As a result only small -blobs could be sent. This patch fixes this problem. - -Reviewed-by: Arend Van Spriel <arend@broadcom.com> -Reviewed-by: Franky (Zhenhui) Lin <frankyl@broadcom.com> -Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com> -Reviewed-by: Daniel (Deognyoun) Kim <dekim@broadcom.com> -Signed-off-by: Hante Meuleman <meuleman@broadcom.com> -Signed-off-by: Arend van Spriel <arend@broadcom.com> -Signed-off-by: John W. Linville <linville@tuxdriver.com> ---- - drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c -+++ b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c -@@ -827,7 +827,7 @@ brcmf_sdiod_ramrw(struct brcmf_sdio_dev - } - if (!write) - memcpy(data, pkt->data, dsize); -- skb_trim(pkt, dsize); -+ skb_trim(pkt, 0); - - /* Adjust for next transfer (if any) */ - size -= dsize; diff --git a/target/linux/sunxi/patches-3.14/231-2-brcmfmac-fix-use-of-skb-ctrlbuf-in-SDIO.patch b/target/linux/sunxi/patches-3.14/231-2-brcmfmac-fix-use-of-skb-ctrlbuf-in-SDIO.patch deleted file mode 100644 index 27d037c44e..0000000000 --- a/target/linux/sunxi/patches-3.14/231-2-brcmfmac-fix-use-of-skb-ctrlbuf-in-SDIO.patch +++ /dev/null @@ -1,64 +0,0 @@ -From 3eee5fd6d045dc744f98fd684258e3fdfa667fd6 Mon Sep 17 00:00:00 2001 -From: Arend van Spriel <arend@broadcom.com> -Date: Tue, 25 Feb 2014 20:30:27 +0100 -Subject: [PATCH] brcmfmac: fix use of skb control buffer in SDIO driver part - -The SDIO driver has a 16-bit field defined in the skbuff control buffer. -However, it is accessed as a u32 overwriting other control info. Another -issue is that the field is not initialized for networking packets, but -the control buffer content is unspecified as other networking layers can -use it. - -Reviewed-by: Hante Meuleman <meuleman@broadcom.com> -Reviewed-by: Franky (Zhenhui) Lin <frankyl@broadcom.com> -Reviewed-by: Daniel (Deognyoun) Kim <dekim@broadcom.com> -Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com> -Signed-off-by: Arend van Spriel <arend@broadcom.com> -Signed-off-by: John W. Linville <linville@tuxdriver.com> ---- - drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c | 10 ++++++---- - 1 file changed, 6 insertions(+), 4 deletions(-) - ---- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c -+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c -@@ -1955,7 +1955,7 @@ static int brcmf_sdio_txpkt_prep_sg(stru - memcpy(pkt_pad->data, - pkt->data + pkt->len - tail_chop, - tail_chop); -- *(u32 *)(pkt_pad->cb) = ALIGN_SKB_FLAG + tail_chop; -+ *(u16 *)(pkt_pad->cb) = ALIGN_SKB_FLAG + tail_chop; - skb_trim(pkt, pkt->len - tail_chop); - skb_trim(pkt_pad, tail_pad + tail_chop); - __skb_queue_after(pktq, pkt, pkt_pad); -@@ -2003,7 +2003,7 @@ brcmf_sdio_txpkt_prep(struct brcmf_sdio - * already properly aligned and does not - * need an sdpcm header. - */ -- if (*(u32 *)(pkt_next->cb) & ALIGN_SKB_FLAG) -+ if (*(u16 *)(pkt_next->cb) & ALIGN_SKB_FLAG) - continue; - - /* align packet data pointer */ -@@ -2067,11 +2067,11 @@ brcmf_sdio_txpkt_postp(struct brcmf_sdio - u8 *hdr; - u32 dat_offset; - u16 tail_pad; -- u32 dummy_flags, chop_len; -+ u16 dummy_flags, chop_len; - struct sk_buff *pkt_next, *tmp, *pkt_prev; - - skb_queue_walk_safe(pktq, pkt_next, tmp) { -- dummy_flags = *(u32 *)(pkt_next->cb); -+ dummy_flags = *(u16 *)(pkt_next->cb); - if (dummy_flags & ALIGN_SKB_FLAG) { - chop_len = dummy_flags & ALIGN_SKB_CHOP_LEN_MASK; - if (chop_len) { -@@ -2554,6 +2554,8 @@ static int brcmf_sdio_bus_txdata(struct - - /* Priority based enq */ - spin_lock_irqsave(&bus->txqlock, flags); -+ /* reset bus_flags in packet cb */ -+ *(u16 *)(pkt->cb) = 0; - if (!brcmf_c_prec_enq(bus->sdiodev->dev, &bus->txq, pkt, prec)) { - skb_pull(pkt, bus->tx_hdrlen); - brcmf_err("out of bus->txq !!!\n"); diff --git a/target/linux/sunxi/patches-3.14/232-1-dt-sun7i-add-wifi-to-cubietruck.patch b/target/linux/sunxi/patches-3.14/232-1-dt-sun7i-add-wifi-to-cubietruck.patch deleted file mode 100644 index 4b19579346..0000000000 --- a/target/linux/sunxi/patches-3.14/232-1-dt-sun7i-add-wifi-to-cubietruck.patch +++ /dev/null @@ -1,91 +0,0 @@ -From 3e7fc7d394db0783996519f2d5affde5152a628e Mon Sep 17 00:00:00 2001 -From: Chen-Yu Tsai <wens@csie.org> -Date: Thu, 26 Dec 2013 17:14:33 +0800 -Subject: [PATCH] ARM: dts: sun7i: add WiFi module to Cubietruck DTS - -The CubieTruck has an AMPAK AP6210 WiFi+Bluetooth module. The WiFi -part is a BCM43362 IC connected to MMC2 in the A20 SoC via SDIO. -The IC also takes a 32.768 KHz low power clock input, and a power -enable signal via GPIO. - -The WiFi module supports out-of-band interrupt signaling via GPIO, -but this is not supported in this patch. ---- - arch/arm/boot/dts/sun7i-a20-cubietruck.dts | 47 ++++++++++++++++++++++++++++++ - 1 file changed, 47 insertions(+) - ---- a/arch/arm/boot/dts/sun7i-a20-cubietruck.dts -+++ b/arch/arm/boot/dts/sun7i-a20-cubietruck.dts -@@ -28,6 +28,23 @@ - status = "okay"; - }; - -+ mmc3: mmc@01c12000 { -+ pinctrl-names = "default", "default"; -+ pinctrl-0 = <&mmc3_pins_a>; -+ pinctrl-1 = <&wifi_host_wake_pin>; -+ vmmc-supply = <®_vmmc3>; -+ non-removable; -+ status = "okay"; -+ -+ brcmf: bcrmf@0 { -+ /* out of band interrupt not working */ -+ /* compatible = "broadcom,bcm43362"; */ -+ interrupt-parent = <&pio>; -+ interrupts = <10 2>; /* EINT10 */ -+ status = "okay"; -+ }; -+ }; -+ - usbphy: phy@01c13400 { - usb1_vbus-supply = <®_usb1_vbus>; - usb2_vbus-supply = <®_usb2_vbus>; -@@ -56,6 +73,18 @@ - }; - - pinctrl@01c20800 { -+ mmc3_pins_a: mmc3@0 { -+ /* AP6210 requires pull-up */ -+ allwinner,pull = <1>; -+ }; -+ -+ vmmc3_pin_cubietruck: vmmc3_pin@0 { -+ allwinner,pins = "PH9"; -+ allwinner,function = "gpio_out"; -+ allwinner,drive = <0>; -+ allwinner,pull = <0>; -+ }; -+ - ahci_pwr_pin_cubietruck: ahci_pwr_pin@1 { - allwinner,pins = "PH12"; - allwinner,function = "gpio_out"; -@@ -99,6 +128,13 @@ - - /include/ "x-powers-axp209.dtsi" - }; -+ -+ wifi_host_wake_pin: wifi_host_wake_pin@0 { -+ allwinner,pins = "PH10"; -+ allwinner,function = "gpio_in"; -+ allwinner,drive = <0>; -+ allwinner,pull = <0>; -+ }; - }; - - i2c0: i2c@01c2ac00 { -@@ -189,4 +225,15 @@ - reg_usb2_vbus: usb2-vbus { - status = "okay"; - }; -+ -+ reg_vmmc3: vmmc3 { -+ compatible = "regulator-fixed"; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&vmmc3_pin_cubietruck>; -+ regulator-name = "vmmc3"; -+ regulator-min-microvolt = <3300000>; -+ regulator-max-microvolt = <3300000>; -+ enable-active-high; -+ gpio = <&pio 7 9 0>; -+ }; - }; diff --git a/target/linux/sunxi/patches-3.14/232-2-dt-sun7i-add-bluetooth-to-cubietruck.patch b/target/linux/sunxi/patches-3.14/232-2-dt-sun7i-add-bluetooth-to-cubietruck.patch deleted file mode 100644 index ce1858c893..0000000000 --- a/target/linux/sunxi/patches-3.14/232-2-dt-sun7i-add-bluetooth-to-cubietruck.patch +++ /dev/null @@ -1,73 +0,0 @@ -From 7ed66f828ad1ae46226ad7c1b56466d5ae6d67b9 Mon Sep 17 00:00:00 2001 -From: Chen-Yu Tsai <wens@csie.org> -Date: Thu, 26 Dec 2013 17:15:47 +0800 -Subject: [PATCH] ARM: dts: sun7i: add bluetooth module to CubieTruck DTS - -The CubieTruck has an AMPAK AP6210 WiFi+Bluetooth module. The -Bluetooth part is a BCM20710 IC connected to UART2 in the A20 -SoC. The IC also takes a 32.768 KHz low power clock input, a power -enable signal and a wake signal via GPIO. - -The Bluetooth module supports out-of-band interrupt signaling via -GPIO, but this is not supported in this patch. ---- - arch/arm/boot/dts/sun7i-a20-cubietruck.dts | 36 ++++++++++++++++++++++++++++++ - 1 file changed, 36 insertions(+) - ---- a/arch/arm/boot/dts/sun7i-a20-cubietruck.dts -+++ b/arch/arm/boot/dts/sun7i-a20-cubietruck.dts -@@ -135,6 +135,20 @@ - allwinner,drive = <0>; - allwinner,pull = <0>; - }; -+ -+ bt_pwr_pin: bt_pwr_pin@0 { -+ allwinner,pins = "PH18"; -+ allwinner,function = "gpio_out"; -+ allwinner,drive = <0>; -+ allwinner,pull = <0>; -+ }; -+ -+ bt_wake_pin: bt_wake_pin@0 { -+ allwinner,pins = "PH24"; -+ allwinner,function = "gpio_out"; -+ allwinner,drive = <0>; -+ allwinner,pull = <0>; -+ }; - }; - - i2c0: i2c@01c2ac00 { -@@ -167,6 +181,12 @@ - }; - }; - -+ uart2: serial@01c28800 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&uart2_pins_a>; -+ status = "okay"; -+ }; -+ - i2c0: i2c@01c2ac00 { - pinctrl-names = "default"; - pinctrl-0 = <&i2c0_pins_a>; -@@ -236,4 +256,20 @@ - enable-active-high; - gpio = <&pio 7 9 0>; - }; -+ -+ rfkill-switches { -+ compatible = "simple-bus"; -+ pinctrl-names = "default"; -+ -+ rfkill_bt { -+ compatible = "rfkill-gpio"; -+ pinctrl-0 = <&bt_pwr_pin>, <&clk_out_a_pins_a>; -+ rfkill-name = "bt"; -+ rfkill-type = <2>; -+ bt_shutdown-gpios = <0>, <&pio 7 18 0>; /* PH18 */ -+ bt_reset-gpios = <&pio 7 24 0>; /* PH24 */ -+ clocks = <&clk_out_a>; -+ clock-frequency = <32768>; -+ }; -+ }; - }; diff --git a/target/linux/sunxi/patches-3.14/250-pwm-add-driver.patch b/target/linux/sunxi/patches-3.14/250-pwm-add-driver.patch deleted file mode 100644 index d4af96faef..0000000000 --- a/target/linux/sunxi/patches-3.14/250-pwm-add-driver.patch +++ /dev/null @@ -1,369 +0,0 @@ ---- a/drivers/pwm/Kconfig -+++ b/drivers/pwm/Kconfig -@@ -187,6 +187,15 @@ config PWM_SPEAR - To compile this driver as a module, choose M here: the module - will be called pwm-spear. - -+config PWM_SUNXI -+ tristate "Allwinner PWM support" -+ depends on ARCH_SUNXI || COMPILE_TEST -+ help -+ Generic PWM framework driver for Allwinner SoCs. -+ -+ To compile this driver as a module, choose M here: the module -+ will be called pwm-sunxi. -+ - config PWM_TEGRA - tristate "NVIDIA Tegra PWM support" - depends on ARCH_TEGRA ---- a/drivers/pwm/Makefile -+++ b/drivers/pwm/Makefile -@@ -16,6 +16,7 @@ obj-$(CONFIG_PWM_PXA) += pwm-pxa.o - obj-$(CONFIG_PWM_RENESAS_TPU) += pwm-renesas-tpu.o - obj-$(CONFIG_PWM_SAMSUNG) += pwm-samsung.o - obj-$(CONFIG_PWM_SPEAR) += pwm-spear.o -+obj-$(CONFIG_PWM_SUNXI) += pwm-sunxi.o - obj-$(CONFIG_PWM_TEGRA) += pwm-tegra.o - obj-$(CONFIG_PWM_TIECAP) += pwm-tiecap.o - obj-$(CONFIG_PWM_TIEHRPWM) += pwm-tiehrpwm.o ---- /dev/null -+++ b/drivers/pwm/pwm-sunxi.c -@@ -0,0 +1,338 @@ -+/* -+ * Driver for Allwinner Pulse Width Modulation Controller -+ * -+ * Copyright (C) 2014 Alexandre Belloni <alexandre.belloni@free-electrons.com> -+ * -+ * Licensed under GPLv2. -+ */ -+ -+#include <linux/bitops.h> -+#include <linux/clk.h> -+#include <linux/err.h> -+#include <linux/io.h> -+#include <linux/of.h> -+#include <linux/of_device.h> -+#include <linux/platform_device.h> -+#include <linux/pwm.h> -+#include <linux/module.h> -+#include <linux/mutex.h> -+#include <linux/slab.h> -+ -+#define PWM_CTRL_REG 0x0 -+ -+#define PWM_CH_PRD_BASE 0x4 -+#define PWM_CH_PRD_OFF 0x4 -+#define PWM_CH_PRD(x) (PWM_CH_PRD_BASE + PWM_CH_PRD_OFF * (x)) -+ -+#define PWMCH_OFFSET 15 -+#define PWM_PRESCAL_MASK GENMASK(3, 0) -+#define PWM_PRESCAL_OFF 0 -+#define PWM_EN BIT(4) -+#define PWM_ACT_STATE BIT(5) -+#define PWM_CLK_GATING BIT(6) -+#define PWM_MODE BIT(7) -+#define PWM_PULSE BIT(8) -+#define PWM_BYPASS BIT(9) -+ -+#define PWM_RDY_BASE 28 -+#define PWM_RDY_OFF 1 -+#define PWM_RDY(x) BIT(PWM_RDY_BASE + PWM_RDY_OFF * (x)) -+ -+#define PWM_PRD_ACT_MASK GENMASK(7, 0) -+#define PWM_PRD(x) ((x - 1) << 16) -+#define PWM_PRD_MASK GENMASK(7, 0) -+ -+#define BIT_CH(bit, chan) (bit << (chan * PWMCH_OFFSET)) -+ -+u32 prescal_table[] = { 120, 180, 240, 360, 480, 0, 0, 0, -+ 12000, 24000, 36000, 48000, 72000, -+ 0, 0, 1 }; -+ -+struct sunxi_pwm_data { -+ bool has_rdy; -+}; -+ -+struct sunxi_pwm_chip { -+ struct pwm_chip chip; -+ struct clk *clk; -+ void __iomem *base; -+ struct mutex ctrl_lock; -+ const struct sunxi_pwm_data *data; -+}; -+ -+#define to_sunxi_pwm_chip(chip) container_of(chip, struct sunxi_pwm_chip, chip) -+ -+static inline u32 sunxi_pwm_readl(struct sunxi_pwm_chip *chip, -+ unsigned long offset) -+{ -+ return readl(chip->base + offset); -+} -+ -+static inline void sunxi_pwm_writel(struct sunxi_pwm_chip *chip, -+ unsigned long offset, unsigned long val) -+{ -+ writel(val, chip->base + offset); -+} -+ -+static int sunxi_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm, -+ int duty_ns, int period_ns) -+{ -+ struct sunxi_pwm_chip *sunxi_pwm = to_sunxi_pwm_chip(chip); -+ u32 clk_rate, prd, dty; -+ u64 div; -+ u32 val, clk_gate; -+ int i, ret; -+ -+ clk_rate = clk_get_rate(sunxi_pwm->clk); -+ -+ /* First, test without any divider */ -+ i = PWM_PRESCAL_MASK; -+ div = clk_rate * period_ns; -+ do_div(div, 1000000000); -+ if (div > PWM_PRD_MASK) { -+ /* Then go up from the first divider */ -+ for (i = 0; i < PWM_PRESCAL_MASK; i++) { -+ if (!prescal_table[i]) -+ continue; -+ div = clk_rate / prescal_table[i]; -+ div = div * period_ns; -+ do_div(div, 1000000000); -+ if (div <= PWM_PRD_MASK) -+ break; -+ } -+ } -+ -+ if (div > PWM_PRD_MASK) { -+ dev_err(chip->dev, "prescaler exceeds the maximum value\n"); -+ return -EINVAL; -+ } -+ -+ prd = div; -+ div *= duty_ns; -+ do_div(div, period_ns); -+ dty = div; -+ -+ ret = clk_prepare_enable(sunxi_pwm->clk); -+ if (ret) { -+ dev_err(chip->dev, "failed to enable PWM clock\n"); -+ return ret; -+ } -+ -+ mutex_lock(&sunxi_pwm->ctrl_lock); -+ val = sunxi_pwm_readl(sunxi_pwm, PWM_CTRL_REG); -+ -+ if (sunxi_pwm->data->has_rdy && (val & PWM_RDY(pwm->hwpwm))) { -+ mutex_unlock(&sunxi_pwm->ctrl_lock); -+ clk_disable_unprepare(sunxi_pwm->clk); -+ return -EBUSY; -+ } -+ -+ clk_gate = val & BIT_CH(PWM_CLK_GATING, pwm->hwpwm); -+ if (clk_gate) { -+ val &= ~BIT_CH(PWM_CLK_GATING, pwm->hwpwm); -+ sunxi_pwm_writel(sunxi_pwm, PWM_CTRL_REG, val); -+ } -+ -+ val = sunxi_pwm_readl(sunxi_pwm, PWM_CTRL_REG); -+ val &= ~BIT_CH(PWM_PRESCAL_MASK, pwm->hwpwm); -+ val |= i; -+ sunxi_pwm_writel(sunxi_pwm, PWM_CTRL_REG, val); -+ -+ sunxi_pwm_writel(sunxi_pwm, PWM_CH_PRD(pwm->hwpwm), dty | PWM_PRD(prd)); -+ -+ if (clk_gate) { -+ val = sunxi_pwm_readl(sunxi_pwm, PWM_CTRL_REG); -+ val |= clk_gate; -+ sunxi_pwm_writel(sunxi_pwm, PWM_CTRL_REG, val); -+ } -+ -+ mutex_unlock(&sunxi_pwm->ctrl_lock); -+ clk_disable_unprepare(sunxi_pwm->clk); -+ -+ return 0; -+} -+ -+static int sunxi_pwm_set_polarity(struct pwm_chip *chip, struct pwm_device *pwm, -+ enum pwm_polarity polarity) -+{ -+ struct sunxi_pwm_chip *sunxi_pwm = to_sunxi_pwm_chip(chip); -+ u32 val; -+ int ret; -+ -+ ret = clk_prepare_enable(sunxi_pwm->clk); -+ if (ret) { -+ dev_err(chip->dev, "failed to enable PWM clock\n"); -+ return ret; -+ } -+ -+ mutex_lock(&sunxi_pwm->ctrl_lock); -+ val = sunxi_pwm_readl(sunxi_pwm, PWM_CTRL_REG); -+ -+ if (polarity != PWM_POLARITY_NORMAL) -+ val &= ~BIT_CH(PWM_ACT_STATE, pwm->hwpwm); -+ else -+ val |= BIT_CH(PWM_ACT_STATE, pwm->hwpwm); -+ -+ -+ sunxi_pwm_writel(sunxi_pwm, PWM_CTRL_REG, val); -+ -+ mutex_unlock(&sunxi_pwm->ctrl_lock); -+ clk_disable_unprepare(sunxi_pwm->clk); -+ -+ return 0; -+} -+ -+static int sunxi_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm) -+{ -+ struct sunxi_pwm_chip *sunxi_pwm = to_sunxi_pwm_chip(chip); -+ u32 val; -+ int ret; -+ -+ ret = clk_prepare_enable(sunxi_pwm->clk); -+ if (ret) { -+ dev_err(chip->dev, "failed to enable PWM clock\n"); -+ return ret; -+ } -+ -+ mutex_lock(&sunxi_pwm->ctrl_lock); -+ val = sunxi_pwm_readl(sunxi_pwm, PWM_CTRL_REG); -+ val |= BIT_CH(PWM_EN, pwm->hwpwm); -+ val |= BIT_CH(PWM_CLK_GATING, pwm->hwpwm); -+ sunxi_pwm_writel(sunxi_pwm, PWM_CTRL_REG, val); -+ mutex_unlock(&sunxi_pwm->ctrl_lock); -+ -+ return 0; -+} -+ -+static void sunxi_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm) -+{ -+ struct sunxi_pwm_chip *sunxi_pwm = to_sunxi_pwm_chip(chip); -+ u32 val; -+ -+ mutex_lock(&sunxi_pwm->ctrl_lock); -+ val = sunxi_pwm_readl(sunxi_pwm, PWM_CTRL_REG); -+ val &= ~BIT_CH(PWM_EN, pwm->hwpwm); -+ val &= ~BIT_CH(PWM_CLK_GATING, pwm->hwpwm); -+ sunxi_pwm_writel(sunxi_pwm, PWM_CTRL_REG, val); -+ mutex_unlock(&sunxi_pwm->ctrl_lock); -+ -+ clk_disable_unprepare(sunxi_pwm->clk); -+} -+ -+static const struct pwm_ops sunxi_pwm_ops = { -+ .config = sunxi_pwm_config, -+ .set_polarity = sunxi_pwm_set_polarity, -+ .enable = sunxi_pwm_enable, -+ .disable = sunxi_pwm_disable, -+ .owner = THIS_MODULE, -+}; -+ -+static const struct sunxi_pwm_data sunxi_pwm_data_a10 = { -+ .has_rdy = false, -+}; -+ -+static const struct sunxi_pwm_data sunxi_pwm_data_a20 = { -+ .has_rdy = true, -+}; -+ -+static const struct of_device_id sunxi_pwm_dt_ids[] = { -+ { -+ .compatible = "allwinner,sun4i-a10-pwm", -+ .data = &sunxi_pwm_data_a10, -+ }, { -+ .compatible = "allwinner,sun7i-a20-pwm", -+ .data = &sunxi_pwm_data_a20, -+ }, { -+ /* sentinel */ -+ }, -+}; -+MODULE_DEVICE_TABLE(of, sunxi_pwm_dt_ids); -+ -+static int sunxi_pwm_probe(struct platform_device *pdev) -+{ -+ struct sunxi_pwm_chip *sunxi_pwm; -+ struct resource *res; -+ int ret; -+ -+ const struct of_device_id *match; -+ -+ match = of_match_device(sunxi_pwm_dt_ids, &pdev->dev); -+ if (!match || !match->data) -+ return -ENODEV; -+ -+ sunxi_pwm = devm_kzalloc(&pdev->dev, sizeof(*sunxi_pwm), GFP_KERNEL); -+ if (!sunxi_pwm) -+ return -ENOMEM; -+ -+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -+ sunxi_pwm->base = devm_ioremap_resource(&pdev->dev, res); -+ if (IS_ERR(sunxi_pwm->base)) -+ return PTR_ERR(sunxi_pwm->base); -+ -+ sunxi_pwm->clk = devm_clk_get(&pdev->dev, NULL); -+ if (IS_ERR(sunxi_pwm->clk)) -+ return PTR_ERR(sunxi_pwm->clk); -+ -+ sunxi_pwm->chip.dev = &pdev->dev; -+ sunxi_pwm->chip.ops = &sunxi_pwm_ops; -+ -+ sunxi_pwm->chip.base = -1; -+ sunxi_pwm->chip.npwm = 2; -+ sunxi_pwm->chip.can_sleep = true; -+ sunxi_pwm->chip.of_xlate = of_pwm_xlate_with_flags; -+ sunxi_pwm->chip.of_pwm_n_cells = 3; -+ sunxi_pwm->data = match->data; -+ -+ mutex_init(&sunxi_pwm->ctrl_lock); -+ -+ ret = clk_prepare_enable(sunxi_pwm->clk); -+ if (ret) { -+ dev_err(&pdev->dev, "failed to enable PWM clock\n"); -+ goto error; -+ } -+ -+ /* By default, the polarity is inversed, set it to normal */ -+ sunxi_pwm_writel(sunxi_pwm, PWM_CTRL_REG, -+ BIT_CH(PWM_ACT_STATE, 0) | -+ BIT_CH(PWM_ACT_STATE, 1)); -+ clk_disable_unprepare(sunxi_pwm->clk); -+ -+ ret = pwmchip_add(&sunxi_pwm->chip); -+ if (ret < 0) { -+ dev_err(&pdev->dev, "failed to add PWM chip %d\n", ret); -+ goto error; -+ } -+ -+ platform_set_drvdata(pdev, sunxi_pwm); -+ -+ return ret; -+ -+error: -+ mutex_destroy(&sunxi_pwm->ctrl_lock); -+ clk_disable_unprepare(sunxi_pwm->clk); -+ return ret; -+} -+ -+static int sunxi_pwm_remove(struct platform_device *pdev) -+{ -+ struct sunxi_pwm_chip *sunxi_pwm = platform_get_drvdata(pdev); -+ -+ mutex_destroy(&sunxi_pwm->ctrl_lock); -+ -+ return pwmchip_remove(&sunxi_pwm->chip); -+} -+ -+static struct platform_driver sunxi_pwm_driver = { -+ .driver = { -+ .name = "sunxi-pwm", -+ .of_match_table = sunxi_pwm_dt_ids, -+ }, -+ .probe = sunxi_pwm_probe, -+ .remove = sunxi_pwm_remove, -+}; -+module_platform_driver(sunxi_pwm_driver); -+ -+MODULE_ALIAS("platform:sunxi-pwm"); -+MODULE_AUTHOR("Alexandre Belloni <alexandre.belloni@free-electrons.com>"); -+MODULE_DESCRIPTION("Allwinner PWM driver"); -+MODULE_LICENSE("GPL v2"); diff --git a/target/linux/sunxi/patches-3.14/251-1-dt-sun4i-add-pinmux-for-pwm.patch b/target/linux/sunxi/patches-3.14/251-1-dt-sun4i-add-pinmux-for-pwm.patch deleted file mode 100644 index 5eb30b1a63..0000000000 --- a/target/linux/sunxi/patches-3.14/251-1-dt-sun4i-add-pinmux-for-pwm.patch +++ /dev/null @@ -1,36 +0,0 @@ -From 1d8e9db920352680e9091ec5d2873e90a4a53214 Mon Sep 17 00:00:00 2001 -From: Alexandre Belloni <alexandre.belloni@free-electrons.com> -Date: Mon, 28 Apr 2014 18:17:10 +0200 -Subject: [PATCH] ARM: sun4i: dt: add pinmux configuration for the PWM - -Add the pinctrl descriptions for both PWM channels of the Allwinner A10. - -Signed-off-by: Alexandre Belloni <alexandre.belloni@free-electrons.com> -Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com> ---- - arch/arm/boot/dts/sun4i-a10.dtsi | 14 ++++++++++++++ - 1 file changed, 14 insertions(+) - ---- a/arch/arm/boot/dts/sun4i-a10.dtsi -+++ b/arch/arm/boot/dts/sun4i-a10.dtsi -@@ -521,6 +521,20 @@ - #size-cells = <0>; - #gpio-cells = <3>; - -+ pwm0_pins_a: pwm0@0 { -+ allwinner,pins = "PB2"; -+ allwinner,function = "pwm"; -+ allwinner,drive = <0>; -+ allwinner,pull = <0>; -+ }; -+ -+ pwm1_pins_a: pwm1@0 { -+ allwinner,pins = "PI3"; -+ allwinner,function = "pwm"; -+ allwinner,drive = <0>; -+ allwinner,pull = <0>; -+ }; -+ - uart0_pins_a: uart0@0 { - allwinner,pins = "PB22", "PB23"; - allwinner,function = "uart0"; diff --git a/target/linux/sunxi/patches-3.14/251-2-dt-sun7i-add-pinmux-for-pwm.patch b/target/linux/sunxi/patches-3.14/251-2-dt-sun7i-add-pinmux-for-pwm.patch deleted file mode 100644 index 12062376ec..0000000000 --- a/target/linux/sunxi/patches-3.14/251-2-dt-sun7i-add-pinmux-for-pwm.patch +++ /dev/null @@ -1,36 +0,0 @@ -From cf34231072d53e643d6ef1baa95a8e9df644542e Mon Sep 17 00:00:00 2001 -From: Alexandre Belloni <alexandre.belloni@free-electrons.com> -Date: Mon, 28 Apr 2014 18:17:12 +0200 -Subject: [PATCH] ARM: sun7i: dt: add pinmux configuration for the PWM - -Add the pinctrl descriptions for both PWM channels of the Allwinner A20. - -Signed-off-by: Alexandre Belloni <alexandre.belloni@free-electrons.com> -Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com> ---- - arch/arm/boot/dts/sun7i-a20.dtsi | 14 ++++++++++++++ - 1 file changed, 14 insertions(+) - ---- a/arch/arm/boot/dts/sun7i-a20.dtsi -+++ b/arch/arm/boot/dts/sun7i-a20.dtsi -@@ -584,6 +584,20 @@ - #size-cells = <0>; - #gpio-cells = <3>; - -+ pwm0_pins_a: pwm0@0 { -+ allwinner,pins = "PB2"; -+ allwinner,function = "pwm"; -+ allwinner,drive = <0>; -+ allwinner,pull = <0>; -+ }; -+ -+ pwm1_pins_a: pwm1@0 { -+ allwinner,pins = "PI3"; -+ allwinner,function = "pwm"; -+ allwinner,drive = <0>; -+ allwinner,pull = <0>; -+ }; -+ - uart0_pins_a: uart0@0 { - allwinner,pins = "PB22", "PB23"; - allwinner,function = "uart0"; diff --git a/target/linux/sunxi/patches-3.14/252-1-dt-sun4i-add-pwm-support.patch b/target/linux/sunxi/patches-3.14/252-1-dt-sun4i-add-pwm-support.patch deleted file mode 100644 index 4b16ab2035..0000000000 --- a/target/linux/sunxi/patches-3.14/252-1-dt-sun4i-add-pwm-support.patch +++ /dev/null @@ -1,30 +0,0 @@ -From 25a4e0f1ac49c9ecafeba0d034806e25c491f012 Mon Sep 17 00:00:00 2001 -From: Alexandre Belloni <alexandre.belloni@free-electrons.com> -Date: Mon, 28 Apr 2014 18:17:11 +0200 -Subject: [PATCH] ARM: sun4i: dt: add PWM support - -Add the PWM bindings for the Allwinner A10. - -Signed-off-by: Alexandre Belloni <alexandre.belloni@free-electrons.com> -Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com> ---- - arch/arm/boot/dts/sun4i-a10.dtsi | 8 ++++++++ - 1 file changed, 8 insertions(+) - ---- a/arch/arm/boot/dts/sun4i-a10.dtsi -+++ b/arch/arm/boot/dts/sun4i-a10.dtsi -@@ -628,6 +628,14 @@ - status = "disabled"; - }; - -+ pwm: pwm@01c20e00 { -+ compatible = "allwinner,sun4i-a10-pwm"; -+ reg = <0x01c20e00 0xc>; -+ clocks = <&osc24M>; -+ #pwm-cells = <3>; -+ status = "disabled"; -+ }; -+ - sid: eeprom@01c23800 { - compatible = "allwinner,sun4i-sid"; - reg = <0x01c23800 0x10>; diff --git a/target/linux/sunxi/patches-3.14/252-2-dt-sun7i-add-pwm-support.patch b/target/linux/sunxi/patches-3.14/252-2-dt-sun7i-add-pwm-support.patch deleted file mode 100644 index dc9636b904..0000000000 --- a/target/linux/sunxi/patches-3.14/252-2-dt-sun7i-add-pwm-support.patch +++ /dev/null @@ -1,30 +0,0 @@ -From 216a4cc15c24d46a5b50b3f9a224576a69c1a83e Mon Sep 17 00:00:00 2001 -From: Alexandre Belloni <alexandre.belloni@free-electrons.com> -Date: Mon, 28 Apr 2014 18:17:13 +0200 -Subject: [PATCH] ARM: sun7i: dt: add PWM support - -Add the PWM bindings for the Allwinner A20. - -Signed-off-by: Alexandre Belloni <alexandre.belloni@free-electrons.com> -Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com> ---- - arch/arm/boot/dts/sun7i-a20.dtsi | 8 ++++++++ - 1 file changed, 8 insertions(+) - ---- a/arch/arm/boot/dts/sun7i-a20.dtsi -+++ b/arch/arm/boot/dts/sun7i-a20.dtsi -@@ -764,6 +764,14 @@ - status = "disabled"; - }; - -+ pwm: pwm@01c20e00 { -+ compatible = "allwinner,sun7i-a20-pwm"; -+ reg = <0x01c20e00 0xc>; -+ clocks = <&osc24M>; -+ #pwm-cells = <3>; -+ status = "disabled"; -+ }; -+ - sid: eeprom@01c23800 { - compatible = "allwinner,sun7i-a20-sid"; - reg = <0x01c23800 0x200>; diff --git a/target/linux/sunxi/patches-3.14/260-dt-sun7i-enable-arm-pmu.patch b/target/linux/sunxi/patches-3.14/260-dt-sun7i-enable-arm-pmu.patch deleted file mode 100644 index 4f703e7811..0000000000 --- a/target/linux/sunxi/patches-3.14/260-dt-sun7i-enable-arm-pmu.patch +++ /dev/null @@ -1,28 +0,0 @@ -From 531f223d1426a826c7da4908e1a5e8eb3d40d6ed Mon Sep 17 00:00:00 2001 -From: Maxime Ripard <maxime.ripard@free-electrons.com> -Date: Thu, 17 Apr 2014 21:54:41 +0200 -Subject: [PATCH] ARM: sun7i: Add ARM PMU in A20 DTSI - -Enable the performance monitoring unit found in the A20 SoCs. - -Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com> -Reviewed-by: Hans de Goede <hdegoede@redhat.com> ---- - arch/arm/boot/dts/sun7i-a20.dtsi | 6 ++++++ - 1 file changed, 6 insertions(+) - ---- a/arch/arm/boot/dts/sun7i-a20.dtsi -+++ b/arch/arm/boot/dts/sun7i-a20.dtsi -@@ -57,6 +57,12 @@ - <1 10 0xf08>; - }; - -+ pmu { -+ compatible = "arm,cortex-a7-pmu", "arm,cortex-a15-pmu"; -+ interrupts = <0 120 4>, -+ <0 121 4>; -+ }; -+ - clocks { - #address-cells = <1>; - #size-cells = <1>; diff --git a/target/linux/sunxi/patches-3.14/270-dt-sun7i-add-ss-to-a20.patch b/target/linux/sunxi/patches-3.14/270-dt-sun7i-add-ss-to-a20.patch deleted file mode 100644 index 11a6ed03f5..0000000000 --- a/target/linux/sunxi/patches-3.14/270-dt-sun7i-add-ss-to-a20.patch +++ /dev/null @@ -1,17 +0,0 @@ ---- a/arch/arm/boot/dts/sun7i-a20.dtsi -+++ b/arch/arm/boot/dts/sun7i-a20.dtsi -@@ -529,6 +529,14 @@ - status = "disabled"; - }; - -+ crypto: crypto-engine@01c15000 { -+ compatible = "allwinner,sun7i-a20-crypto"; -+ reg = <0x01c15000 0x1000>; -+ interrupts = <0 86 4>; -+ clocks = <&ahb_gates 5>, <&ss_clk>; -+ clock-names = "ahb", "mod"; -+ }; -+ - spi2: spi@01c17000 { - compatible = "allwinner,sun4i-a10-spi"; - reg = <0x01c17000 0x1000>; diff --git a/target/linux/sunxi/patches-3.14/271-crypto-add-ss.patch b/target/linux/sunxi/patches-3.14/271-crypto-add-ss.patch deleted file mode 100644 index a5e2d067a5..0000000000 --- a/target/linux/sunxi/patches-3.14/271-crypto-add-ss.patch +++ /dev/null @@ -1,1241 +0,0 @@ ---- a/drivers/crypto/Kconfig -+++ b/drivers/crypto/Kconfig -@@ -419,4 +419,21 @@ config CRYPTO_DEV_MXS_DCP - To compile this driver as a module, choose M here: the module - will be called mxs-dcp. - -+config CRYPTO_DEV_SUNXI_SS -+ tristate "Support for Allwinner Security System cryptographic accelerator" -+ depends on ARCH_SUNXI -+ select CRYPTO_MD5 -+ select CRYPTO_SHA1 -+ select CRYPTO_AES -+ select CRYPTO_DES -+ select CRYPTO_BLKCIPHER -+ help -+ Some Allwinner SoC have a crypto accelerator named -+ Security System. Select this if you want to use it. -+ The Security System handle AES/DES/3DES ciphers in CBC mode -+ and SHA1 and MD5 hash algorithms. -+ -+ To compile this driver as a module, choose M here: the module -+ will be called sunxi-ss. -+ - endif # CRYPTO_HW ---- a/drivers/crypto/Makefile -+++ b/drivers/crypto/Makefile -@@ -23,3 +23,4 @@ obj-$(CONFIG_CRYPTO_DEV_SAHARA) += sahar - obj-$(CONFIG_CRYPTO_DEV_TALITOS) += talitos.o - obj-$(CONFIG_CRYPTO_DEV_TEGRA_AES) += tegra-aes.o - obj-$(CONFIG_CRYPTO_DEV_UX500) += ux500/ -+obj-$(CONFIG_CRYPTO_DEV_SUNXI_SS) += sunxi-ss/ ---- /dev/null -+++ b/drivers/crypto/sunxi-ss/Makefile -@@ -0,0 +1,2 @@ -+obj-$(CONFIG_CRYPTO_DEV_SUNXI_SS) += sunxi-ss.o -+sunxi-ss-y += sunxi-ss-core.o sunxi-ss-hash.o sunxi-ss-cipher.o ---- /dev/null -+++ b/drivers/crypto/sunxi-ss/sunxi-ss-cipher.c -@@ -0,0 +1,461 @@ -+/* -+ * sunxi-ss-cipher.c - hardware cryptographic accelerator for Allwinner A20 SoC -+ * -+ * Copyright (C) 2013-2014 Corentin LABBE <clabbe.montjoie@gmail.com> -+ * -+ * This file add support for AES cipher with 128,192,256 bits -+ * keysize in CBC mode. -+ * -+ * You could find the datasheet at -+ * http://dl.linux-sunxi.org/A20/A20%20User%20Manual%202013-03-22.pdf -+ * -+ * 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 "sunxi-ss.h" -+ -+extern struct sunxi_ss_ctx *ss; -+ -+static int sunxi_ss_cipher(struct ablkcipher_request *areq, u32 mode) -+{ -+ struct crypto_ablkcipher *tfm = crypto_ablkcipher_reqtfm(areq); -+ struct sunxi_req_ctx *op = crypto_ablkcipher_ctx(tfm); -+ const char *cipher_type; -+ -+ cipher_type = crypto_tfm_alg_name(crypto_ablkcipher_tfm(tfm)); -+ -+ if (areq->nbytes == 0) { -+ mutex_unlock(&ss->lock); -+ return 0; -+ } -+ -+ if (areq->info == NULL) { -+ dev_err(ss->dev, "ERROR: Empty IV\n"); -+ mutex_unlock(&ss->lock); -+ return -EINVAL; -+ } -+ -+ if (areq->src == NULL || areq->dst == NULL) { -+ dev_err(ss->dev, "ERROR: Some SGs are NULL\n"); -+ mutex_unlock(&ss->lock); -+ return -EINVAL; -+ } -+ -+ if (strcmp("cbc(aes)", cipher_type) == 0) { -+ op->mode |= SS_OP_AES | SS_CBC | SS_ENABLED | mode; -+ return sunxi_ss_aes_poll(areq); -+ } -+ if (strcmp("cbc(des)", cipher_type) == 0) { -+ op->mode = SS_OP_DES | SS_CBC | SS_ENABLED | mode; -+ return sunxi_ss_des_poll(areq); -+ } -+ if (strcmp("cbc(des3_ede)", cipher_type) == 0) { -+ op->mode = SS_OP_3DES | SS_CBC | SS_ENABLED | mode; -+ return sunxi_ss_des_poll(areq); -+ } -+ dev_err(ss->dev, "ERROR: Cipher %s not handled\n", cipher_type); -+ mutex_unlock(&ss->lock); -+ return -EINVAL; -+} -+ -+int sunxi_ss_cipher_encrypt(struct ablkcipher_request *areq) -+{ -+ return sunxi_ss_cipher(areq, SS_ENCRYPTION); -+} -+ -+int sunxi_ss_cipher_decrypt(struct ablkcipher_request *areq) -+{ -+ return sunxi_ss_cipher(areq, SS_DECRYPTION); -+} -+ -+int sunxi_ss_cipher_init(struct crypto_tfm *tfm) -+{ -+ struct sunxi_req_ctx *op = crypto_tfm_ctx(tfm); -+ -+ mutex_lock(&ss->lock); -+ -+ memset(op, 0, sizeof(struct sunxi_req_ctx)); -+ return 0; -+} -+ -+int sunxi_ss_aes_poll(struct ablkcipher_request *areq) -+{ -+ u32 spaces; -+ struct crypto_ablkcipher *tfm = crypto_ablkcipher_reqtfm(areq); -+ struct sunxi_req_ctx *op = crypto_ablkcipher_ctx(tfm); -+ unsigned int ivsize = crypto_ablkcipher_ivsize(tfm); -+ /* when activating SS, the default FIFO space is 32 */ -+ u32 rx_cnt = 32; -+ u32 tx_cnt = 0; -+ u32 v; -+ int i; -+ struct scatterlist *in_sg; -+ struct scatterlist *out_sg; -+ void *src_addr; -+ void *dst_addr; -+ unsigned int ileft = areq->nbytes; -+ unsigned int oleft = areq->nbytes; -+ unsigned int sgileft = areq->src->length; -+ unsigned int sgoleft = areq->dst->length; -+ unsigned int todo; -+ u32 *src32; -+ u32 *dst32; -+ -+ in_sg = areq->src; -+ out_sg = areq->dst; -+ for (i = 0; i < op->keylen; i += 4) -+ writel(*(op->key + i/4), ss->base + SS_KEY0 + i); -+ if (areq->info != NULL) { -+ for (i = 0; i < 4 && i < ivsize / 4; i++) { -+ v = *(u32 *)(areq->info + i * 4); -+ writel(v, ss->base + SS_IV0 + i * 4); -+ } -+ } -+ writel(op->mode, ss->base + SS_CTL); -+ -+ /* If we have only one SG, we can use kmap_atomic */ -+ if (sg_next(in_sg) == NULL && sg_next(out_sg) == NULL) { -+ src_addr = kmap_atomic(sg_page(in_sg)) + in_sg->offset; -+ if (src_addr == NULL) { -+ dev_err(ss->dev, "kmap_atomic error for src SG\n"); -+ writel(0, ss->base + SS_CTL); -+ mutex_unlock(&ss->lock); -+ return -EINVAL; -+ } -+ dst_addr = kmap_atomic(sg_page(out_sg)) + out_sg->offset; -+ if (dst_addr == NULL) { -+ dev_err(ss->dev, "kmap_atomic error for dst SG\n"); -+ writel(0, ss->base + SS_CTL); -+ kunmap_atomic(src_addr); -+ mutex_unlock(&ss->lock); -+ return -EINVAL; -+ } -+ src32 = (u32 *)src_addr; -+ dst32 = (u32 *)dst_addr; -+ ileft = areq->nbytes / 4; -+ oleft = areq->nbytes / 4; -+ i = 0; -+ do { -+ if (ileft > 0 && rx_cnt > 0) { -+ todo = min(rx_cnt, ileft); -+ ileft -= todo; -+ do { -+ writel_relaxed(*src32++, -+ ss->base + -+ SS_RXFIFO); -+ todo--; -+ } while (todo > 0); -+ } -+ if (tx_cnt > 0) { -+ todo = min(tx_cnt, oleft); -+ oleft -= todo; -+ do { -+ *dst32++ = readl_relaxed(ss->base + -+ SS_TXFIFO); -+ todo--; -+ } while (todo > 0); -+ } -+ spaces = readl_relaxed(ss->base + SS_FCSR); -+ rx_cnt = SS_RXFIFO_SPACES(spaces); -+ tx_cnt = SS_TXFIFO_SPACES(spaces); -+ } while (oleft > 0); -+ writel(0, ss->base + SS_CTL); -+ kunmap_atomic(src_addr); -+ kunmap_atomic(dst_addr); -+ mutex_unlock(&ss->lock); -+ return 0; -+ } -+ -+ /* If we have more than one SG, we cannot use kmap_atomic since -+ * we hold the mapping too long -+ */ -+ src_addr = kmap(sg_page(in_sg)) + in_sg->offset; -+ if (src_addr == NULL) { -+ dev_err(ss->dev, "KMAP error for src SG\n"); -+ mutex_unlock(&ss->lock); -+ return -EINVAL; -+ } -+ dst_addr = kmap(sg_page(out_sg)) + out_sg->offset; -+ if (dst_addr == NULL) { -+ kunmap(sg_page(in_sg)); -+ dev_err(ss->dev, "KMAP error for dst SG\n"); -+ mutex_unlock(&ss->lock); -+ return -EINVAL; -+ } -+ src32 = (u32 *)src_addr; -+ dst32 = (u32 *)dst_addr; -+ ileft = areq->nbytes / 4; -+ oleft = areq->nbytes / 4; -+ sgileft = in_sg->length / 4; -+ sgoleft = out_sg->length / 4; -+ do { -+ spaces = readl_relaxed(ss->base + SS_FCSR); -+ rx_cnt = SS_RXFIFO_SPACES(spaces); -+ tx_cnt = SS_TXFIFO_SPACES(spaces); -+ todo = min3(rx_cnt, ileft, sgileft); -+ if (todo > 0) { -+ ileft -= todo; -+ sgileft -= todo; -+ } -+ while (todo > 0) { -+ writel_relaxed(*src32++, ss->base + SS_RXFIFO); -+ todo--; -+ } -+ if (in_sg != NULL && sgileft == 0 && ileft > 0) { -+ kunmap(sg_page(in_sg)); -+ in_sg = sg_next(in_sg); -+ while (in_sg != NULL && in_sg->length == 0) -+ in_sg = sg_next(in_sg); -+ if (in_sg != NULL && ileft > 0) { -+ src_addr = kmap(sg_page(in_sg)) + in_sg->offset; -+ if (src_addr == NULL) { -+ dev_err(ss->dev, "ERROR: KMAP for src SG\n"); -+ mutex_unlock(&ss->lock); -+ return -EINVAL; -+ } -+ src32 = src_addr; -+ sgileft = in_sg->length / 4; -+ } -+ } -+ /* do not test oleft since when oleft == 0 we have finished */ -+ todo = min3(tx_cnt, oleft, sgoleft); -+ if (todo > 0) { -+ oleft -= todo; -+ sgoleft -= todo; -+ } -+ while (todo > 0) { -+ *dst32++ = readl_relaxed(ss->base + SS_TXFIFO); -+ todo--; -+ } -+ if (out_sg != NULL && sgoleft == 0 && oleft >= 0) { -+ kunmap(sg_page(out_sg)); -+ out_sg = sg_next(out_sg); -+ while (out_sg != NULL && out_sg->length == 0) -+ out_sg = sg_next(out_sg); -+ if (out_sg != NULL && oleft > 0) { -+ dst_addr = kmap(sg_page(out_sg)) + -+ out_sg->offset; -+ if (dst_addr == NULL) { -+ dev_err(ss->dev, "KMAP error\n"); -+ mutex_unlock(&ss->lock); -+ return -EINVAL; -+ } -+ dst32 = dst_addr; -+ sgoleft = out_sg->length / 4; -+ } -+ } -+ } while (oleft > 0); -+ -+ writel(0, ss->base + SS_CTL); -+ mutex_unlock(&ss->lock); -+ return 0; -+} -+ -+/* Pure CPU way of doing DES/3DES with SS -+ * Since DES and 3DES SGs could be smaller than 4 bytes, I use sg_copy_to_buffer -+ * for "linearize" them. -+ * The problem with that is that I alloc (2 x areq->nbytes) for buf_in/buf_out -+ * TODO: change this system -+ * SGsrc -> buf_in -> SS -> buf_out -> SGdst */ -+int sunxi_ss_des_poll(struct ablkcipher_request *areq) -+{ -+ u32 value, spaces; -+ size_t nb_in_sg_tx, nb_in_sg_rx; -+ size_t ir, it; -+ struct crypto_ablkcipher *tfm = crypto_ablkcipher_reqtfm(areq); -+ struct sunxi_req_ctx *op = crypto_ablkcipher_ctx(tfm); -+ unsigned int ivsize = crypto_ablkcipher_ivsize(tfm); -+ u32 tx_cnt = 0; -+ u32 rx_cnt = 0; -+ u32 v; -+ int i; -+ int no_chunk = 1; -+ -+ /* if we have only SGs with size multiple of 4, -+ * we can use the SS AES function */ -+ struct scatterlist *in_sg; -+ struct scatterlist *out_sg; -+ -+ in_sg = areq->src; -+ out_sg = areq->dst; -+ -+ while (in_sg != NULL && no_chunk == 1) { -+ if ((in_sg->length % 4) != 0) -+ no_chunk = 0; -+ in_sg = sg_next(in_sg); -+ } -+ while (out_sg != NULL && no_chunk == 1) { -+ if ((out_sg->length % 4) != 0) -+ no_chunk = 0; -+ out_sg = sg_next(out_sg); -+ } -+ -+ if (no_chunk == 1) -+ return sunxi_ss_aes_poll(areq); -+ in_sg = areq->src; -+ out_sg = areq->dst; -+ -+ nb_in_sg_rx = sg_nents(in_sg); -+ nb_in_sg_tx = sg_nents(out_sg); -+ -+ mutex_lock(&ss->bufin_lock); -+ if (ss->buf_in == NULL) { -+ ss->buf_in = kmalloc(areq->nbytes, GFP_KERNEL); -+ ss->buf_in_size = areq->nbytes; -+ } else { -+ if (areq->nbytes > ss->buf_in_size) { -+ kfree(ss->buf_in); -+ ss->buf_in = kmalloc(areq->nbytes, GFP_KERNEL); -+ ss->buf_in_size = areq->nbytes; -+ } -+ } -+ if (ss->buf_in == NULL) { -+ ss->buf_in_size = 0; -+ mutex_unlock(&ss->bufin_lock); -+ dev_err(ss->dev, "Unable to allocate pages.\n"); -+ return -ENOMEM; -+ } -+ if (ss->buf_out == NULL) { -+ mutex_lock(&ss->bufout_lock); -+ ss->buf_out = kmalloc(areq->nbytes, GFP_KERNEL); -+ if (ss->buf_out == NULL) { -+ ss->buf_out_size = 0; -+ mutex_unlock(&ss->bufout_lock); -+ dev_err(ss->dev, "Unable to allocate pages.\n"); -+ return -ENOMEM; -+ } -+ ss->buf_out_size = areq->nbytes; -+ mutex_unlock(&ss->bufout_lock); -+ } else { -+ if (areq->nbytes > ss->buf_out_size) { -+ mutex_lock(&ss->bufout_lock); -+ kfree(ss->buf_out); -+ ss->buf_out = kmalloc(areq->nbytes, GFP_KERNEL); -+ if (ss->buf_out == NULL) { -+ ss->buf_out_size = 0; -+ mutex_unlock(&ss->bufout_lock); -+ dev_err(ss->dev, "Unable to allocate pages.\n"); -+ return -ENOMEM; -+ } -+ ss->buf_out_size = areq->nbytes; -+ mutex_unlock(&ss->bufout_lock); -+ } -+ } -+ -+ sg_copy_to_buffer(areq->src, nb_in_sg_rx, ss->buf_in, areq->nbytes); -+ -+ ir = 0; -+ it = 0; -+ -+ for (i = 0; i < op->keylen; i += 4) -+ writel(*(op->key + i/4), ss->base + SS_KEY0 + i); -+ if (areq->info != NULL) { -+ for (i = 0; i < 4 && i < ivsize / 4; i++) { -+ v = *(u32 *)(areq->info + i * 4); -+ writel(v, ss->base + SS_IV0 + i * 4); -+ } -+ } -+ writel(op->mode, ss->base + SS_CTL); -+ -+ do { -+ if (rx_cnt == 0 || tx_cnt == 0) { -+ spaces = readl(ss->base + SS_FCSR); -+ rx_cnt = SS_RXFIFO_SPACES(spaces); -+ tx_cnt = SS_TXFIFO_SPACES(spaces); -+ } -+ if (rx_cnt > 0 && ir < areq->nbytes) { -+ do { -+ value = *(u32 *)(ss->buf_in + ir); -+ writel(value, ss->base + SS_RXFIFO); -+ ir += 4; -+ rx_cnt--; -+ } while (rx_cnt > 0 && ir < areq->nbytes); -+ } -+ if (tx_cnt > 0 && it < areq->nbytes) { -+ do { -+ value = readl(ss->base + SS_TXFIFO); -+ *(u32 *)(ss->buf_out + it) = value; -+ it += 4; -+ tx_cnt--; -+ } while (tx_cnt > 0 && it < areq->nbytes); -+ } -+ if (ir == areq->nbytes) { -+ mutex_unlock(&ss->bufin_lock); -+ ir++; -+ } -+ } while (it < areq->nbytes); -+ -+ writel(0, ss->base + SS_CTL); -+ mutex_unlock(&ss->lock); -+ -+ /* a simple optimization, since we dont need the hardware for this copy -+ * we release the lock and do the copy. With that we gain 5/10% perf */ -+ mutex_lock(&ss->bufout_lock); -+ sg_copy_from_buffer(areq->dst, nb_in_sg_tx, ss->buf_out, areq->nbytes); -+ -+ mutex_unlock(&ss->bufout_lock); -+ return 0; -+} -+ -+/* check and set the AES key, prepare the mode to be used */ -+int sunxi_ss_aes_setkey(struct crypto_ablkcipher *tfm, const u8 *key, -+ unsigned int keylen) -+{ -+ struct sunxi_req_ctx *op = crypto_ablkcipher_ctx(tfm); -+ -+ switch (keylen) { -+ case 128 / 8: -+ op->mode = SS_AES_128BITS; -+ break; -+ case 192 / 8: -+ op->mode = SS_AES_192BITS; -+ break; -+ case 256 / 8: -+ op->mode = SS_AES_256BITS; -+ break; -+ default: -+ dev_err(ss->dev, "ERROR: Invalid keylen %u\n", keylen); -+ crypto_ablkcipher_set_flags(tfm, CRYPTO_TFM_RES_BAD_KEY_LEN); -+ mutex_unlock(&ss->lock); -+ return -EINVAL; -+ } -+ op->keylen = keylen; -+ memcpy(op->key, key, keylen); -+ return 0; -+} -+ -+/* check and set the DES key, prepare the mode to be used */ -+int sunxi_ss_des_setkey(struct crypto_ablkcipher *tfm, const u8 *key, -+ unsigned int keylen) -+{ -+ struct sunxi_req_ctx *op = crypto_ablkcipher_ctx(tfm); -+ -+ if (keylen != DES_KEY_SIZE) { -+ dev_err(ss->dev, "Invalid keylen %u\n", keylen); -+ crypto_ablkcipher_set_flags(tfm, CRYPTO_TFM_RES_BAD_KEY_LEN); -+ mutex_unlock(&ss->lock); -+ return -EINVAL; -+ } -+ op->keylen = keylen; -+ memcpy(op->key, key, keylen); -+ return 0; -+} -+ -+/* check and set the 3DES key, prepare the mode to be used */ -+int sunxi_ss_des3_setkey(struct crypto_ablkcipher *tfm, const u8 *key, -+ unsigned int keylen) -+{ -+ struct sunxi_req_ctx *op = crypto_ablkcipher_ctx(tfm); -+ -+ if (keylen != 3 * DES_KEY_SIZE) { -+ dev_err(ss->dev, "Invalid keylen %u\n", keylen); -+ crypto_ablkcipher_set_flags(tfm, CRYPTO_TFM_RES_BAD_KEY_LEN); -+ mutex_unlock(&ss->lock); -+ return -EINVAL; -+ } -+ op->keylen = keylen; -+ memcpy(op->key, key, keylen); -+ return 0; -+} ---- /dev/null -+++ b/drivers/crypto/sunxi-ss/sunxi-ss-core.c -@@ -0,0 +1,308 @@ -+/* -+ * sunxi-ss.c - hardware cryptographic accelerator for Allwinner A20 SoC -+ * -+ * Copyright (C) 2013-2014 Corentin LABBE <clabbe.montjoie@gmail.com> -+ * -+ * Core file which registers crypto algorithms supported by the SS. -+ * -+ * You could find the datasheet at -+ * http://dl.linux-sunxi.org/A20/A20%20User%20Manual%202013-03-22.pdf -+ * -+ * -+ * 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/clk.h> -+#include <linux/crypto.h> -+#include <linux/io.h> -+#include <linux/module.h> -+#include <linux/of.h> -+#include <linux/platform_device.h> -+#include <crypto/scatterwalk.h> -+#include <linux/scatterlist.h> -+#include <linux/interrupt.h> -+#include <linux/delay.h> -+ -+#include "sunxi-ss.h" -+ -+struct sunxi_ss_ctx *ss; -+ -+/* General notes: -+ * I cannot use a key/IV cache because each time one of these change ALL stuff -+ * need to be re-writed (rewrite SS_KEYX ans SS_IVX). -+ * And for example, with dm-crypt IV changes on each request. -+ * -+ * After each request the device must be disabled with a write of 0 in SS_CTL -+ * -+ * For performance reason, we use writel_relaxed/read_relaxed for all -+ * operations on RX and TX FIFO and also SS_FCSR. -+ * For all other registers, we use writel/readl. -+ * See http://permalink.gmane.org/gmane.linux.ports.arm.kernel/117644 -+ * and http://permalink.gmane.org/gmane.linux.ports.arm.kernel/117640 -+ * */ -+ -+static struct ahash_alg sunxi_md5_alg = { -+ .init = sunxi_hash_init, -+ .update = sunxi_hash_update, -+ .final = sunxi_hash_final, -+ .finup = sunxi_hash_finup, -+ .digest = sunxi_hash_digest, -+ .halg = { -+ .digestsize = MD5_DIGEST_SIZE, -+ .base = { -+ .cra_name = "md5", -+ .cra_driver_name = "md5-sunxi-ss", -+ .cra_priority = 300, -+ .cra_alignmask = 3, -+ .cra_flags = CRYPTO_ALG_TYPE_AHASH | CRYPTO_ALG_ASYNC, -+ .cra_blocksize = MD5_HMAC_BLOCK_SIZE, -+ .cra_ctxsize = sizeof(struct sunxi_req_ctx), -+ .cra_module = THIS_MODULE, -+ .cra_type = &crypto_ahash_type -+ } -+ } -+}; -+static struct ahash_alg sunxi_sha1_alg = { -+ .init = sunxi_hash_init, -+ .update = sunxi_hash_update, -+ .final = sunxi_hash_final, -+ .finup = sunxi_hash_finup, -+ .digest = sunxi_hash_digest, -+ .halg = { -+ .digestsize = SHA1_DIGEST_SIZE, -+ .base = { -+ .cra_name = "sha1", -+ .cra_driver_name = "sha1-sunxi-ss", -+ .cra_priority = 300, -+ .cra_alignmask = 3, -+ .cra_flags = CRYPTO_ALG_TYPE_AHASH | CRYPTO_ALG_ASYNC, -+ .cra_blocksize = SHA1_BLOCK_SIZE, -+ .cra_ctxsize = sizeof(struct sunxi_req_ctx), -+ .cra_module = THIS_MODULE, -+ .cra_type = &crypto_ahash_type -+ } -+ } -+}; -+ -+static struct crypto_alg sunxi_cipher_algs[] = { -+{ -+ .cra_name = "cbc(aes)", -+ .cra_driver_name = "cbc-aes-sunxi-ss", -+ .cra_priority = 300, -+ .cra_blocksize = AES_BLOCK_SIZE, -+ .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER, -+ .cra_ctxsize = sizeof(struct sunxi_req_ctx), -+ .cra_module = THIS_MODULE, -+ .cra_alignmask = 3, -+ .cra_type = &crypto_ablkcipher_type, -+ .cra_init = sunxi_ss_cipher_init, -+ .cra_u = { -+ .ablkcipher = { -+ .min_keysize = AES_MIN_KEY_SIZE, -+ .max_keysize = AES_MAX_KEY_SIZE, -+ .ivsize = AES_BLOCK_SIZE, -+ .setkey = sunxi_ss_aes_setkey, -+ .encrypt = sunxi_ss_cipher_encrypt, -+ .decrypt = sunxi_ss_cipher_decrypt, -+ } -+ } -+}, { -+ .cra_name = "cbc(des)", -+ .cra_driver_name = "cbc-des-sunxi-ss", -+ .cra_priority = 300, -+ .cra_blocksize = DES_BLOCK_SIZE, -+ .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER, -+ .cra_ctxsize = sizeof(struct sunxi_req_ctx), -+ .cra_module = THIS_MODULE, -+ .cra_alignmask = 3, -+ .cra_type = &crypto_ablkcipher_type, -+ .cra_init = sunxi_ss_cipher_init, -+ .cra_u.ablkcipher = { -+ .min_keysize = DES_KEY_SIZE, -+ .max_keysize = DES_KEY_SIZE, -+ .ivsize = DES_BLOCK_SIZE, -+ .setkey = sunxi_ss_des_setkey, -+ .encrypt = sunxi_ss_cipher_encrypt, -+ .decrypt = sunxi_ss_cipher_decrypt, -+ } -+}, { -+ .cra_name = "cbc(des3_ede)", -+ .cra_driver_name = "cbc-des3-sunxi-ss", -+ .cra_priority = 300, -+ .cra_blocksize = DES3_EDE_BLOCK_SIZE, -+ .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER, -+ .cra_ctxsize = sizeof(struct sunxi_req_ctx), -+ .cra_module = THIS_MODULE, -+ .cra_alignmask = 3, -+ .cra_type = &crypto_ablkcipher_type, -+ .cra_init = sunxi_ss_cipher_init, -+ .cra_u.ablkcipher = { -+ .min_keysize = DES3_EDE_KEY_SIZE, -+ .max_keysize = DES3_EDE_KEY_SIZE, -+ .ivsize = DES3_EDE_BLOCK_SIZE, -+ .setkey = sunxi_ss_des3_setkey, -+ .encrypt = sunxi_ss_cipher_encrypt, -+ .decrypt = sunxi_ss_cipher_decrypt, -+ } -+} -+}; -+ -+static int sunxi_ss_probe(struct platform_device *pdev) -+{ -+ struct resource *res; -+ u32 v; -+ int err; -+ unsigned long cr; -+ const unsigned long cr_ahb = 24 * 1000 * 1000; -+ const unsigned long cr_mod = 150 * 1000 * 1000; -+ -+ if (!pdev->dev.of_node) -+ return -ENODEV; -+ -+ ss = devm_kzalloc(&pdev->dev, sizeof(*ss), GFP_KERNEL); -+ if (ss == NULL) -+ return -ENOMEM; -+ -+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -+ ss->base = devm_ioremap_resource(&pdev->dev, res); -+ if (IS_ERR(ss->base)) { -+ dev_err(&pdev->dev, "Cannot request MMIO\n"); -+ return PTR_ERR(ss->base); -+ } -+ -+ ss->ssclk = devm_clk_get(&pdev->dev, "mod"); -+ if (IS_ERR(ss->ssclk)) { -+ err = PTR_ERR(ss->ssclk); -+ dev_err(&pdev->dev, "Cannot get SS clock err=%d\n", err); -+ return err; -+ } -+ dev_dbg(&pdev->dev, "clock ss acquired\n"); -+ -+ ss->busclk = devm_clk_get(&pdev->dev, "ahb"); -+ if (IS_ERR(ss->busclk)) { -+ err = PTR_ERR(ss->busclk); -+ dev_err(&pdev->dev, "Cannot get AHB SS clock err=%d\n", err); -+ return err; -+ } -+ dev_dbg(&pdev->dev, "clock ahb_ss acquired\n"); -+ -+ /* Enable the clocks */ -+ err = clk_prepare_enable(ss->busclk); -+ if (err != 0) { -+ dev_err(&pdev->dev, "Cannot prepare_enable busclk\n"); -+ return err; -+ } -+ err = clk_prepare_enable(ss->ssclk); -+ if (err != 0) { -+ dev_err(&pdev->dev, "Cannot prepare_enable ssclk\n"); -+ clk_disable_unprepare(ss->busclk); -+ return err; -+ } -+ -+ /* Check that clock have the correct rates gived in the datasheet */ -+ /* Try to set the clock to the maximum allowed */ -+ err = clk_set_rate(ss->ssclk, cr_mod); -+ if (err != 0) { -+ dev_err(&pdev->dev, "Cannot set clock rate to ssclk\n"); -+ clk_disable_unprepare(ss->ssclk); -+ clk_disable_unprepare(ss->busclk); -+ return err; -+ } -+ cr = clk_get_rate(ss->busclk); -+ if (cr >= cr_ahb) -+ dev_dbg(&pdev->dev, "Clock bus %lu (%lu MHz) (must be >= %lu)\n", -+ cr, cr / 1000000, cr_ahb); -+ else -+ dev_warn(&pdev->dev, "Clock bus %lu (%lu MHz) (must be >= %lu)\n", -+ cr, cr / 1000000, cr_ahb); -+ cr = clk_get_rate(ss->ssclk); -+ if (cr == cr_mod) -+ dev_dbg(&pdev->dev, "Clock ss %lu (%lu MHz) (must be <= %lu)\n", -+ cr, cr / 1000000, cr_mod); -+ else { -+ dev_warn(&pdev->dev, "Clock ss is at %lu (%lu MHz) (must be <= %lu)\n", -+ cr, cr / 1000000, cr_mod); -+ } -+ -+ /* TODO Does this information could be usefull ? */ -+ writel(SS_ENABLED, ss->base + SS_CTL); -+ v = readl(ss->base + SS_CTL); -+ v >>= 16; -+ v &= 0x07; -+ dev_info(&pdev->dev, "Die ID %d\n", v); -+ writel(0, ss->base + SS_CTL); -+ -+ ss->dev = &pdev->dev; -+ -+ mutex_init(&ss->lock); -+ mutex_init(&ss->bufin_lock); -+ mutex_init(&ss->bufout_lock); -+ -+ err = crypto_register_ahash(&sunxi_md5_alg); -+ if (err) -+ goto error_md5; -+ err = crypto_register_ahash(&sunxi_sha1_alg); -+ if (err) -+ goto error_sha1; -+ err = crypto_register_algs(sunxi_cipher_algs, -+ ARRAY_SIZE(sunxi_cipher_algs)); -+ if (err) -+ goto error_ciphers; -+ -+ return 0; -+error_ciphers: -+ crypto_unregister_ahash(&sunxi_sha1_alg); -+error_sha1: -+ crypto_unregister_ahash(&sunxi_md5_alg); -+error_md5: -+ clk_disable_unprepare(ss->ssclk); -+ clk_disable_unprepare(ss->busclk); -+ return err; -+} -+ -+static int __exit sunxi_ss_remove(struct platform_device *pdev) -+{ -+ if (!pdev->dev.of_node) -+ return 0; -+ -+ crypto_unregister_ahash(&sunxi_md5_alg); -+ crypto_unregister_ahash(&sunxi_sha1_alg); -+ crypto_unregister_algs(sunxi_cipher_algs, -+ ARRAY_SIZE(sunxi_cipher_algs)); -+ -+ if (ss->buf_in != NULL) -+ kfree(ss->buf_in); -+ if (ss->buf_out != NULL) -+ kfree(ss->buf_out); -+ -+ writel(0, ss->base + SS_CTL); -+ clk_disable_unprepare(ss->busclk); -+ clk_disable_unprepare(ss->ssclk); -+ return 0; -+} -+ -+/*============================================================================*/ -+/*============================================================================*/ -+static const struct of_device_id a20ss_crypto_of_match_table[] = { -+ { .compatible = "allwinner,sun7i-a20-crypto" }, -+ {} -+}; -+MODULE_DEVICE_TABLE(of, a20ss_crypto_of_match_table); -+ -+static struct platform_driver sunxi_ss_driver = { -+ .probe = sunxi_ss_probe, -+ .remove = __exit_p(sunxi_ss_remove), -+ .driver = { -+ .owner = THIS_MODULE, -+ .name = "sunxi-ss", -+ .of_match_table = a20ss_crypto_of_match_table, -+ }, -+}; -+ -+module_platform_driver(sunxi_ss_driver); -+ -+MODULE_DESCRIPTION("Allwinner Security System cryptographic accelerator"); -+MODULE_LICENSE("GPL"); -+MODULE_AUTHOR("Corentin LABBE <clabbe.montjoie@gmail.com>"); ---- /dev/null -+++ b/drivers/crypto/sunxi-ss/sunxi-ss-hash.c -@@ -0,0 +1,241 @@ -+/* -+ * sunxi-ss-hash.c - hardware cryptographic accelerator for Allwinner A20 SoC -+ * -+ * Copyright (C) 2013-2014 Corentin LABBE <clabbe.montjoie@gmail.com> -+ * -+ * This file add support for MD5 and SHA1. -+ * -+ * You could find the datasheet at -+ * http://dl.linux-sunxi.org/A20/A20%20User%20Manual%202013-03-22.pdf -+ * -+ * 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 "sunxi-ss.h" -+ -+extern struct sunxi_ss_ctx *ss; -+ -+/* sunxi_hash_init: initialize request context -+ * Activate the SS, and configure it for MD5 or SHA1 -+ */ -+int sunxi_hash_init(struct ahash_request *areq) -+{ -+ const char *hash_type; -+ struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq); -+ struct sunxi_req_ctx *op = crypto_ahash_ctx(tfm); -+ -+ mutex_lock(&ss->lock); -+ -+ hash_type = crypto_tfm_alg_name(areq->base.tfm); -+ -+ op->byte_count = 0; -+ op->nbwait = 0; -+ op->waitbuf = 0; -+ -+ /* Enable and configure SS for MD5 or SHA1 */ -+ if (strcmp(hash_type, "sha1") == 0) -+ op->mode = SS_OP_SHA1; -+ else -+ op->mode = SS_OP_MD5; -+ -+ writel(op->mode | SS_ENABLED, ss->base + SS_CTL); -+ return 0; -+} -+ -+/* -+ * sunxi_hash_update: update hash engine -+ * -+ * Could be used for both SHA1 and MD5 -+ * Write data by step of 32bits and put then in the SS. -+ * The remaining data is stored (nbwait bytes) in op->waitbuf -+ * As an optimisation, we do not check RXFIFO_SPACES, since SS handle -+ * the FIFO faster than our writes -+ */ -+int sunxi_hash_update(struct ahash_request *areq) -+{ -+ u32 v; -+ unsigned int i = 0;/* bytes read, to be compared to areq->nbytes */ -+ struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq); -+ struct sunxi_req_ctx *op = crypto_ahash_ctx(tfm); -+ struct scatterlist *in_sg; -+ unsigned int in_i = 0;/* advancement in the current SG */ -+ void *src_addr; -+ -+ u8 *waitbuf = (u8 *)(&op->waitbuf); -+ -+ if (areq->nbytes == 0) -+ return 0; -+ -+ in_sg = areq->src; -+ do { -+ src_addr = kmap(sg_page(in_sg)) + in_sg->offset; -+ /* step 1, if some bytes remains from last SG, -+ * try to complete them to 4 and sent its */ -+ if (op->nbwait > 0) { -+ while (op->nbwait < 4 && i < areq->nbytes && -+ in_i < in_sg->length) { -+ waitbuf[op->nbwait] = *(u8 *)(src_addr + in_i); -+ i++; -+ in_i++; -+ op->nbwait++; -+ } -+ if (op->nbwait == 4) { -+ writel(op->waitbuf, ss->base + SS_RXFIFO); -+ op->byte_count += 4; -+ op->nbwait = 0; -+ op->waitbuf = 0; -+ } -+ } -+ /* step 2, main loop, read data 4bytes at a time */ -+ while (i < areq->nbytes && areq->nbytes - i >= 4 && -+ in_i < in_sg->length && -+ in_sg->length - in_i >= 4) { -+ v = *(u32 *)(src_addr + in_i); -+ writel_relaxed(v, ss->base + SS_RXFIFO); -+ i += 4; -+ op->byte_count += 4; -+ in_i += 4; -+ } -+ /* step 3, if we have less than 4 bytes, copy them in waitbuf -+ * no need to check for op->nbwait < 4 since we cannot have -+ * more than 4 bytes remaining */ -+ if (in_i < in_sg->length && in_sg->length - in_i < 4 && -+ i < areq->nbytes) { -+ do { -+ waitbuf[op->nbwait] = *(u8 *)(src_addr + in_i); -+ op->nbwait++; -+ in_i++; -+ i++; -+ } while (in_i < in_sg->length && i < areq->nbytes); -+ } -+ /* we have finished the current SG, try next one */ -+ kunmap(sg_page(in_sg)); -+ in_sg = sg_next(in_sg); -+ in_i = 0; -+ } while (in_sg != NULL && i < areq->nbytes); -+ return 0; -+} -+ -+/* -+ * sunxi_hash_final: finalize hashing operation -+ * -+ * If we have some remaining bytes, send it. -+ * Then ask the SS for finalizing the hash -+ */ -+int sunxi_hash_final(struct ahash_request *areq) -+{ -+ u32 v; -+ unsigned int i; -+ int zeros; -+ unsigned int index, padlen; -+ __be64 bits; -+ struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq); -+ struct sunxi_req_ctx *op = crypto_ahash_ctx(tfm); -+ -+ if (op->nbwait > 0) { -+ op->waitbuf |= ((1 << 7) << (op->nbwait * 8)); -+ writel(op->waitbuf, ss->base + SS_RXFIFO); -+ } else { -+ writel((1 << 7), ss->base + SS_RXFIFO); -+ } -+ -+ /* number of space to pad to obtain 64o minus 8(size) minus 4 (final 1) -+ * example len=0 -+ * example len=56 -+ * */ -+ -+ /* we have already send 4 more byte of which nbwait data */ -+ if (op->mode == SS_OP_MD5) { -+ index = (op->byte_count + 4) & 0x3f; -+ op->byte_count += op->nbwait; -+ if (index > 56) -+ zeros = (120 - index) / 4; -+ else -+ zeros = (56 - index) / 4; -+ } else { -+ op->byte_count += op->nbwait; -+ index = op->byte_count & 0x3f; -+ padlen = (index < 56) ? (56 - index) : ((64+56) - index); -+ zeros = (padlen - 1) / 4; -+ } -+ for (i = 0; i < zeros; i++) -+ writel(0, ss->base + SS_RXFIFO); -+ -+ /* write the lenght */ -+ if (op->mode == SS_OP_SHA1) { -+ bits = cpu_to_be64(op->byte_count << 3); -+ writel(bits & 0xffffffff, ss->base + SS_RXFIFO); -+ writel((bits >> 32) & 0xffffffff, ss->base + SS_RXFIFO); -+ } else { -+ writel((op->byte_count << 3) & 0xffffffff, -+ ss->base + SS_RXFIFO); -+ writel((op->byte_count >> 29) & 0xffffffff, -+ ss->base + SS_RXFIFO); -+ } -+ -+ /* stop the hashing */ -+ v = readl(ss->base + SS_CTL); -+ v |= SS_DATA_END; -+ writel(v, ss->base + SS_CTL); -+ -+ /* check the end */ -+ /* The timeout could happend only in case of bad overcloking */ -+#define SS_TIMEOUT 100 -+ i = 0; -+ do { -+ v = readl(ss->base + SS_CTL); -+ i++; -+ } while (i < SS_TIMEOUT && (v & SS_DATA_END) > 0); -+ if (i >= SS_TIMEOUT) { -+ dev_err(ss->dev, "ERROR: hash end timeout %d>%d\n", -+ i, SS_TIMEOUT); -+ writel(0, ss->base + SS_CTL); -+ mutex_unlock(&ss->lock); -+ return -1; -+ } -+ -+ if (op->mode == SS_OP_SHA1) { -+ for (i = 0; i < 5; i++) { -+ v = cpu_to_be32(readl(ss->base + SS_MD0 + i * 4)); -+ memcpy(areq->result + i * 4, &v, 4); -+ } -+ } else { -+ for (i = 0; i < 4; i++) { -+ v = readl(ss->base + SS_MD0 + i * 4); -+ memcpy(areq->result + i * 4, &v, 4); -+ } -+ } -+ writel(0, ss->base + SS_CTL); -+ mutex_unlock(&ss->lock); -+ return 0; -+} -+ -+/* sunxi_hash_finup: finalize hashing operation after an update */ -+int sunxi_hash_finup(struct ahash_request *areq) -+{ -+ int err; -+ -+ err = sunxi_hash_update(areq); -+ if (err != 0) -+ return err; -+ -+ return sunxi_hash_final(areq); -+} -+ -+/* combo of init/update/final functions */ -+int sunxi_hash_digest(struct ahash_request *areq) -+{ -+ int err; -+ -+ err = sunxi_hash_init(areq); -+ if (err != 0) -+ return err; -+ -+ err = sunxi_hash_update(areq); -+ if (err != 0) -+ return err; -+ -+ return sunxi_hash_final(areq); -+} ---- /dev/null -+++ b/drivers/crypto/sunxi-ss/sunxi-ss.h -@@ -0,0 +1,183 @@ -+/* -+ * sunxi-ss.c - hardware cryptographic accelerator for Allwinner A20 SoC -+ * -+ * Copyright (C) 2013-2014 Corentin LABBE <clabbe.montjoie@gmail.com> -+ * -+ * Support AES cipher with 128,192,256 bits keysize. -+ * Support MD5 and SHA1 hash algorithms. -+ * Support DES and 3DES -+ * Support PRNG -+ * -+ * You could find the datasheet at -+ * http://dl.linux-sunxi.org/A20/A20%20User%20Manual%202013-03-22.pdf -+ * -+ * -+ * Licensed under the GPL-2. -+ */ -+ -+#include <linux/clk.h> -+#include <linux/crypto.h> -+#include <linux/io.h> -+#include <linux/module.h> -+#include <linux/of.h> -+#include <linux/platform_device.h> -+#include <crypto/scatterwalk.h> -+#include <linux/scatterlist.h> -+#include <linux/interrupt.h> -+#include <linux/delay.h> -+#include <crypto/md5.h> -+#include <crypto/sha.h> -+#include <crypto/hash.h> -+#include <crypto/internal/hash.h> -+#include <crypto/aes.h> -+#include <crypto/des.h> -+#include <crypto/internal/rng.h> -+ -+#define SS_CTL 0x00 -+#define SS_KEY0 0x04 -+#define SS_KEY1 0x08 -+#define SS_KEY2 0x0C -+#define SS_KEY3 0x10 -+#define SS_KEY4 0x14 -+#define SS_KEY5 0x18 -+#define SS_KEY6 0x1C -+#define SS_KEY7 0x20 -+ -+#define SS_IV0 0x24 -+#define SS_IV1 0x28 -+#define SS_IV2 0x2C -+#define SS_IV3 0x30 -+ -+#define SS_CNT0 0x34 -+#define SS_CNT1 0x38 -+#define SS_CNT2 0x3C -+#define SS_CNT3 0x40 -+ -+#define SS_FCSR 0x44 -+#define SS_ICSR 0x48 -+ -+#define SS_MD0 0x4C -+#define SS_MD1 0x50 -+#define SS_MD2 0x54 -+#define SS_MD3 0x58 -+#define SS_MD4 0x5C -+ -+#define SS_RXFIFO 0x200 -+#define SS_TXFIFO 0x204 -+ -+/* SS_CTL configuration values */ -+ -+/* PRNG generator mode - bit 15 */ -+#define SS_PRNG_ONESHOT (0 << 15) -+#define SS_PRNG_CONTINUE (1 << 15) -+ -+/* SS operation mode - bits 12-13 */ -+#define SS_ECB (0 << 12) -+#define SS_CBC (1 << 12) -+#define SS_CNT (2 << 12) -+ -+/* Counter width for CNT mode - bits 10-11 */ -+#define SS_CNT_16BITS (0 << 10) -+#define SS_CNT_32BITS (1 << 10) -+#define SS_CNT_64BITS (2 << 10) -+ -+/* Key size for AES - bits 8-9 */ -+#define SS_AES_128BITS (0 << 8) -+#define SS_AES_192BITS (1 << 8) -+#define SS_AES_256BITS (2 << 8) -+ -+/* Operation direction - bit 7 */ -+#define SS_ENCRYPTION (0 << 7) -+#define SS_DECRYPTION (1 << 7) -+ -+/* SS Method - bits 4-6 */ -+#define SS_OP_AES (0 << 4) -+#define SS_OP_DES (1 << 4) -+#define SS_OP_3DES (2 << 4) -+#define SS_OP_SHA1 (3 << 4) -+#define SS_OP_MD5 (4 << 4) -+#define SS_OP_PRNG (5 << 4) -+ -+/* Data end bit - bit 2 */ -+#define SS_DATA_END (1 << 2) -+ -+/* PRNG start bit - bit 1 */ -+#define SS_PRNG_START (1 << 1) -+ -+/* SS Enable bit - bit 0 */ -+#define SS_DISABLED (0 << 0) -+#define SS_ENABLED (1 << 0) -+ -+/* SS_FCSR configuration values */ -+/* RX FIFO status - bit 30 */ -+#define SS_RXFIFO_FREE (1 << 30) -+ -+/* RX FIFO empty spaces - bits 24-29 */ -+#define SS_RXFIFO_SPACES(val) (((val) >> 24) & 0x3f) -+ -+/* TX FIFO status - bit 22 */ -+#define SS_TXFIFO_AVAILABLE (1 << 22) -+ -+/* TX FIFO available spaces - bits 16-21 */ -+#define SS_TXFIFO_SPACES(val) (((val) >> 16) & 0x3f) -+ -+#define SS_RXFIFO_EMP_INT_PENDING (1 << 10) -+#define SS_TXFIFO_AVA_INT_PENDING (1 << 8) -+#define SS_RXFIFO_EMP_INT_ENABLE (1 << 2) -+#define SS_TXFIFO_AVA_INT_ENABLE (1 << 0) -+ -+/* SS_ICSR configuration values */ -+#define SS_ICS_DRQ_ENABLE (1 << 4) -+ -+struct sunxi_ss_ctx { -+ void __iomem *base; -+ int irq; -+ struct clk *busclk; -+ struct clk *ssclk; -+ struct device *dev; -+ struct resource *res; -+ void *buf_in; /* pointer to data to be uploaded to the device */ -+ size_t buf_in_size; /* size of buf_in */ -+ void *buf_out; -+ size_t buf_out_size; -+ struct mutex lock; /* control the use of the device */ -+ struct mutex bufout_lock; /* control the use of buf_out*/ -+ struct mutex bufin_lock; /* control the sue of buf_in*/ -+}; -+ -+struct sunxi_req_ctx { -+ u32 key[AES_MAX_KEY_SIZE / 4];/* divided by sizeof(u32) */ -+ u32 keylen; -+ u32 mode; -+ u64 byte_count; /* number of bytes "uploaded" to the device */ -+ u32 waitbuf; /* a partial word waiting to be completed and -+ uploaded to the device */ -+ /* number of bytes to be uploaded in the waitbuf word */ -+ unsigned int nbwait; -+}; -+ -+#define SS_SEED_LEN (192/8) -+#define SS_DATA_LEN (160/8) -+ -+struct prng_context { -+ u32 seed[SS_SEED_LEN/4]; -+ unsigned int slen; -+}; -+ -+int sunxi_hash_init(struct ahash_request *areq); -+int sunxi_hash_update(struct ahash_request *areq); -+int sunxi_hash_final(struct ahash_request *areq); -+int sunxi_hash_finup(struct ahash_request *areq); -+int sunxi_hash_digest(struct ahash_request *areq); -+ -+int sunxi_ss_aes_poll(struct ablkcipher_request *areq); -+int sunxi_ss_des_poll(struct ablkcipher_request *areq); -+int sunxi_ss_cipher_init(struct crypto_tfm *tfm); -+int sunxi_ss_cipher_encrypt(struct ablkcipher_request *areq); -+int sunxi_ss_cipher_decrypt(struct ablkcipher_request *areq); -+int sunxi_ss_aes_setkey(struct crypto_ablkcipher *tfm, const u8 *key, -+ unsigned int keylen); -+int sunxi_ss_des_setkey(struct crypto_ablkcipher *tfm, const u8 *key, -+ unsigned int keylen); -+int sunxi_ss_des3_setkey(struct crypto_ablkcipher *tfm, const u8 *key, -+ unsigned int keylen); diff --git a/target/linux/sunxi/patches-3.14/275-clk-sunxi-late-clock-fixes.patch b/target/linux/sunxi/patches-3.14/275-clk-sunxi-late-clock-fixes.patch deleted file mode 100644 index 5b0ca8d398..0000000000 --- a/target/linux/sunxi/patches-3.14/275-clk-sunxi-late-clock-fixes.patch +++ /dev/null @@ -1,29 +0,0 @@ ---- a/drivers/clk/sunxi/clk-sunxi.c -+++ b/drivers/clk/sunxi/clk-sunxi.c -@@ -299,7 +299,7 @@ static void sun4i_get_apb1_factors(u32 * - if (parent_rate < *freq) - *freq = parent_rate; - -- parent_rate = (parent_rate + (*freq - 1)) / *freq; -+ parent_rate = DIV_ROUND_UP(parent_rate, *freq); - - /* Invalid rate! */ - if (parent_rate > 32) -@@ -344,7 +344,7 @@ static void sun4i_get_mod0_factors(u32 * - if (*freq > parent_rate) - *freq = parent_rate; - -- div = parent_rate / *freq; -+ div = DIV_ROUND_UP(parent_rate, *freq); - - if (div < 16) - calcp = 0; -@@ -385,7 +385,7 @@ static void sun7i_a20_get_out_factors(u3 - if (*freq > parent_rate) - *freq = parent_rate; - -- div = parent_rate / *freq; -+ div = DIV_ROUND_UP(parent_rate, *freq); - - if (div < 32) - calcp = 0; diff --git a/target/linux/sunxi/patches-3.14/280-ir-add-driver.patch b/target/linux/sunxi/patches-3.14/280-ir-add-driver.patch deleted file mode 100644 index fe7bb535cf..0000000000 --- a/target/linux/sunxi/patches-3.14/280-ir-add-driver.patch +++ /dev/null @@ -1,363 +0,0 @@ -From 601b6a88cd14e655ccd246fe122cbf496a891cbb Mon Sep 17 00:00:00 2001 -From: Alexander Bersenev <bay@hackerdom.ru> -Date: Mon, 9 Jun 2014 00:08:10 +0600 -Subject: [PATCH] rc: add sunxi-ir driver - -This patch adds driver for sunxi IR controller. -It is based on Alexsey Shestacov's work based on the original driver -supplied by Allwinner. - -Signed-off-by: Alexander Bersenev <bay@hackerdom.ru> -Signed-off-by: Alexsey Shestacov <wingrime@linux-sunxi.org> ---- - drivers/media/rc/Kconfig | 10 ++ - drivers/media/rc/Makefile | 1 + - drivers/media/rc/sunxi-cir.c | 318 +++++++++++++++++++++++++++++++++++++++++++ - 3 files changed, 329 insertions(+) - create mode 100644 drivers/media/rc/sunxi-cir.c - ---- a/drivers/media/rc/Kconfig -+++ b/drivers/media/rc/Kconfig -@@ -332,4 +332,14 @@ config RC_ST - - If you're not sure, select N here. - -+config IR_SUNXI -+ tristate "SUNXI IR remote control" -+ depends on RC_CORE -+ depends on ARCH_SUNXI -+ ---help--- -+ Say Y if you want to use sunXi internal IR Controller -+ -+ To compile this driver as a module, choose M here: the module will -+ be called sunxi-ir. -+ - endif #RC_DEVICES ---- a/drivers/media/rc/Makefile -+++ b/drivers/media/rc/Makefile -@@ -31,3 +31,4 @@ obj-$(CONFIG_IR_GPIO_CIR) += gpio-ir-rec - obj-$(CONFIG_IR_IGUANA) += iguanair.o - obj-$(CONFIG_IR_TTUSBIR) += ttusbir.o - obj-$(CONFIG_RC_ST) += st_rc.o -+obj-$(CONFIG_IR_SUNXI) += sunxi-cir.o ---- /dev/null -+++ b/drivers/media/rc/sunxi-cir.c -@@ -0,0 +1,318 @@ -+/* -+ * Driver for Allwinner sunXi IR controller -+ * -+ * Copyright (C) 2014 Alexsey Shestacov <wingrime@linux-sunxi.org> -+ * Copyright (C) 2014 Alexander Bersenev <bay@hackerdom.ru> -+ * -+ * Based on sun5i-ir.c: -+ * Copyright (C) 2007-2012 Daniel Wang -+ * Allwinner Technology Co., Ltd. <www.allwinnertech.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. -+ */ -+ -+#include <linux/clk.h> -+#include <linux/interrupt.h> -+#include <linux/module.h> -+#include <linux/of_platform.h> -+#include <media/rc-core.h> -+ -+#define SUNXI_IR_DEV "sunxi-ir" -+ -+/* Registers */ -+/* IR Control */ -+#define SUNXI_IR_CTL_REG 0x00 -+/* Global Enable */ -+#define REG_CTL_GEN BIT(0) -+/* RX block enable */ -+#define REG_CTL_RXEN BIT(1) -+/* CIR mode */ -+#define REG_CTL_MD (BIT(4) | BIT(5)) -+ -+/* Rx Config */ -+#define SUNXI_IR_RXCTL_REG 0x10 -+/* Pulse Polarity Invert flag */ -+#define REG_RXCTL_RPPI BIT(2) -+ -+/* Rx Data */ -+#define SUNXI_IR_RXFIFO_REG 0x20 -+ -+/* Rx Interrupt Enable */ -+#define SUNXI_IR_RXINT_REG 0x2C -+/* Rx FIFO Overflow */ -+#define REG_RXINT_ROI_EN BIT(0) -+/* Rx Packet End */ -+#define REG_RXINT_RPEI_EN BIT(1) -+/* Rx FIFO Data Available */ -+#define REG_RXINT_RAI_EN BIT(4) -+ -+/* Rx FIFO available byte level */ -+#define REG_RXINT_RAL(val) (((val) << 8) & (GENMASK(11, 8))) -+ -+/* Rx Interrupt Status */ -+#define SUNXI_IR_RXSTA_REG 0x30 -+/* RX FIFO Get Available Counter */ -+#define REG_RXSTA_GET_AC(val) (((val) >> 8) & (GENMASK(5, 0))) -+/* Clear all interrupt status value */ -+#define REG_RXSTA_CLEARALL 0xff -+ -+/* IR Sample Config */ -+#define SUNXI_IR_CIR_REG 0x34 -+/* CIR_REG register noise threshold */ -+#define REG_CIR_NTHR(val) (((val) << 2) & (GENMASK(7, 2))) -+/* CIR_REG register idle threshold */ -+#define REG_CIR_ITHR(val) (((val) << 8) & (GENMASK(15, 8))) -+ -+/* Hardware supported fifo size */ -+#define SUNXI_IR_FIFO_SIZE 16 -+/* How many messages in FIFO trigger IRQ */ -+#define TRIGGER_LEVEL 8 -+/* Required frequency for IR0 or IR1 clock in CIR mode */ -+#define SUNXI_IR_BASE_CLK 8000000 -+/* Frequency after IR internal divider */ -+#define SUNXI_IR_CLK (SUNXI_IR_BASE_CLK / 64) -+/* Sample period in ns */ -+#define SUNXI_IR_SAMPLE (1000000000ul / SUNXI_IR_CLK) -+/* Noise threshold in samples */ -+#define SUNXI_IR_RXNOISE 1 -+/* Idle Threshold in samples */ -+#define SUNXI_IR_RXIDLE 20 -+/* Time after which device stops sending data in ms */ -+#define SUNXI_IR_TIMEOUT 120 -+ -+struct sunxi_ir { -+ spinlock_t ir_lock; -+ struct rc_dev *rc; -+ void __iomem *base; -+ int irq; -+ struct clk *clk; -+ struct clk *apb_clk; -+ const char *map_name; -+}; -+ -+static irqreturn_t sunxi_ir_irq(int irqno, void *dev_id) -+{ -+ unsigned long status; -+ unsigned char dt; -+ unsigned int cnt, rc; -+ struct sunxi_ir *ir = dev_id; -+ DEFINE_IR_RAW_EVENT(rawir); -+ -+ spin_lock(&ir->ir_lock); -+ -+ status = readl(ir->base + SUNXI_IR_RXSTA_REG); -+ -+ /* clean all pending statuses */ -+ writel(status | REG_RXSTA_CLEARALL, ir->base + SUNXI_IR_RXSTA_REG); -+ -+ if (status & REG_RXINT_RAI_EN) { -+ /* How many messages in fifo */ -+ rc = REG_RXSTA_GET_AC(status); -+ /* Sanity check */ -+ rc = rc > SUNXI_IR_FIFO_SIZE ? SUNXI_IR_FIFO_SIZE : rc; -+ /* If we have data */ -+ for (cnt = 0; cnt < rc; cnt++) { -+ /* for each bit in fifo */ -+ dt = readb(ir->base + SUNXI_IR_RXFIFO_REG); -+ rawir.pulse = (dt & 0x80) != 0; -+ rawir.duration = ((dt & 0x7f) + 1) * SUNXI_IR_SAMPLE; -+ ir_raw_event_store_with_filter(ir->rc, &rawir); -+ } -+ } -+ -+ if (status & REG_RXINT_ROI_EN) { -+ ir_raw_event_reset(ir->rc); -+ } else if (status & REG_RXINT_RPEI_EN) { -+ ir_raw_event_set_idle(ir->rc, true); -+ ir_raw_event_handle(ir->rc); -+ } -+ -+ spin_unlock(&ir->ir_lock); -+ -+ return IRQ_HANDLED; -+} -+ -+static int sunxi_ir_probe(struct platform_device *pdev) -+{ -+ int ret = 0; -+ unsigned long tmp = 0; -+ -+ struct device *dev = &pdev->dev; -+ struct device_node *dn = dev->of_node; -+ struct resource *res; -+ struct sunxi_ir *ir; -+ -+ ir = devm_kzalloc(dev, sizeof(struct sunxi_ir), GFP_KERNEL); -+ if (!ir) -+ return -ENOMEM; -+ -+ /* Clock */ -+ ir->apb_clk = devm_clk_get(dev, "apb"); -+ if (IS_ERR(ir->apb_clk)) { -+ dev_err(dev, "failed to get a apb clock.\n"); -+ return PTR_ERR(ir->apb_clk); -+ } -+ ir->clk = devm_clk_get(dev, "ir"); -+ if (IS_ERR(ir->clk)) { -+ dev_err(dev, "failed to get a ir clock.\n"); -+ return PTR_ERR(ir->clk); -+ } -+ -+ ret = clk_set_rate(ir->clk, SUNXI_IR_BASE_CLK); -+ if (ret) { -+ dev_err(dev, "set ir base clock failed!\n"); -+ return ret; -+ } -+ -+ if (clk_prepare_enable(ir->apb_clk)) { -+ dev_err(dev, "try to enable apb_ir_clk failed\n"); -+ return -EINVAL; -+ } -+ -+ if (clk_prepare_enable(ir->clk)) { -+ dev_err(dev, "try to enable ir_clk failed\n"); -+ ret = -EINVAL; -+ goto exit_clkdisable_apb_clk; -+ } -+ -+ /* IO */ -+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -+ ir->base = devm_ioremap_resource(dev, res); -+ if (IS_ERR(ir->base)) { -+ dev_err(dev, "failed to map registers\n"); -+ ret = PTR_ERR(ir->base); -+ goto exit_clkdisable_clk; -+ } -+ -+ ir->rc = rc_allocate_device(); -+ if (!ir->rc) { -+ dev_err(dev, "failed to allocate device\n"); -+ ret = -ENOMEM; -+ goto exit_clkdisable_clk; -+ } -+ -+ ir->rc->priv = ir; -+ ir->rc->input_name = SUNXI_IR_DEV; -+ ir->rc->input_phys = "sunxi-ir/input0"; -+ ir->rc->input_id.bustype = BUS_HOST; -+ ir->rc->input_id.vendor = 0x0001; -+ ir->rc->input_id.product = 0x0001; -+ ir->rc->input_id.version = 0x0100; -+ ir->map_name = of_get_property(dn, "linux,rc-map-name", NULL); -+ ir->rc->map_name = ir->map_name ?: RC_MAP_EMPTY; -+ ir->rc->dev.parent = dev; -+ ir->rc->driver_type = RC_DRIVER_IR_RAW; -+ rc_set_allowed_protocols(ir->rc, RC_BIT_ALL); -+ ir->rc->rx_resolution = SUNXI_IR_SAMPLE; -+ ir->rc->timeout = MS_TO_NS(SUNXI_IR_TIMEOUT); -+ ir->rc->driver_name = SUNXI_IR_DEV; -+ -+ ret = rc_register_device(ir->rc); -+ if (ret) { -+ dev_err(dev, "failed to register rc device\n"); -+ goto exit_free_dev; -+ } -+ -+ platform_set_drvdata(pdev, ir); -+ -+ /* IRQ */ -+ ir->irq = platform_get_irq(pdev, 0); -+ if (ir->irq < 0) { -+ dev_err(dev, "no irq resource\n"); -+ ret = ir->irq; -+ goto exit_free_dev; -+ } -+ -+ ret = devm_request_irq(dev, ir->irq, sunxi_ir_irq, 0, SUNXI_IR_DEV, ir); -+ if (ret) { -+ dev_err(dev, "failed request irq\n"); -+ goto exit_free_dev; -+ } -+ -+ /* Enable CIR Mode */ -+ writel(REG_CTL_MD, ir->base+SUNXI_IR_CTL_REG); -+ -+ /* Set noise threshold and idle threshold */ -+ writel(REG_CIR_NTHR(SUNXI_IR_RXNOISE)|REG_CIR_ITHR(SUNXI_IR_RXIDLE), -+ ir->base + SUNXI_IR_CIR_REG); -+ -+ /* Invert Input Signal */ -+ writel(REG_RXCTL_RPPI, ir->base + SUNXI_IR_RXCTL_REG); -+ -+ /* Clear All Rx Interrupt Status */ -+ writel(REG_RXSTA_CLEARALL, ir->base + SUNXI_IR_RXSTA_REG); -+ -+ /* -+ * Enable IRQ on overflow, packet end, FIFO available with trigger -+ * level -+ */ -+ writel(REG_RXINT_ROI_EN | REG_RXINT_RPEI_EN | -+ REG_RXINT_RAI_EN | REG_RXINT_RAL(TRIGGER_LEVEL - 1), -+ ir->base + SUNXI_IR_RXINT_REG); -+ -+ /* Enable IR Module */ -+ tmp = readl(ir->base + SUNXI_IR_CTL_REG); -+ writel(tmp | REG_CTL_GEN | REG_CTL_RXEN, ir->base + SUNXI_IR_CTL_REG); -+ -+ dev_info(dev, "initialized sunXi IR driver\n"); -+ return 0; -+ -+exit_free_dev: -+ rc_free_device(ir->rc); -+exit_clkdisable_clk: -+ clk_disable_unprepare(ir->clk); -+exit_clkdisable_apb_clk: -+ clk_disable_unprepare(ir->apb_clk); -+ -+ return ret; -+} -+ -+static int sunxi_ir_remove(struct platform_device *pdev) -+{ -+ unsigned long flags; -+ struct sunxi_ir *ir = platform_get_drvdata(pdev); -+ -+ clk_disable_unprepare(ir->clk); -+ clk_disable_unprepare(ir->apb_clk); -+ -+ spin_lock_irqsave(&ir->ir_lock, flags); -+ /* disable IR IRQ */ -+ writel(0, ir->base + SUNXI_IR_RXINT_REG); -+ /* clear All Rx Interrupt Status */ -+ writel(REG_RXSTA_CLEARALL, ir->base + SUNXI_IR_RXSTA_REG); -+ /* disable IR */ -+ writel(0, ir->base + SUNXI_IR_CTL_REG); -+ spin_unlock_irqrestore(&ir->ir_lock, flags); -+ -+ rc_unregister_device(ir->rc); -+ return 0; -+} -+ -+static const struct of_device_id sunxi_ir_match[] = { -+ { .compatible = "allwinner,sun7i-a20-ir", }, -+ {}, -+}; -+ -+static struct platform_driver sunxi_ir_driver = { -+ .probe = sunxi_ir_probe, -+ .remove = sunxi_ir_remove, -+ .driver = { -+ .name = SUNXI_IR_DEV, -+ .owner = THIS_MODULE, -+ .of_match_table = sunxi_ir_match, -+ }, -+}; -+ -+module_platform_driver(sunxi_ir_driver); -+ -+MODULE_DESCRIPTION("Allwinner sunXi IR controller driver"); -+MODULE_AUTHOR("Alexsey Shestacov <wingrime@linux-sunxi.org>"); -+MODULE_LICENSE("GPL"); diff --git a/target/linux/sunxi/patches-3.14/281-dt-sun7i-add-ir-pins.patch b/target/linux/sunxi/patches-3.14/281-dt-sun7i-add-ir-pins.patch deleted file mode 100644 index 2389cf8859..0000000000 --- a/target/linux/sunxi/patches-3.14/281-dt-sun7i-add-ir-pins.patch +++ /dev/null @@ -1,36 +0,0 @@ -From 7720fe5faadae243806833c7a7ec5d15bae244c4 Mon Sep 17 00:00:00 2001 -From: Alexander Bersenev <bay@hackerdom.ru> -Date: Mon, 9 Jun 2014 00:08:11 +0600 -Subject: [PATCH] ARM: sunxi: Add pins for IR controller on A20 to dtsi - -This patch adds pins for two IR controllers on A20 - -Signed-off-by: Alexander Bersenev <bay@hackerdom.ru> -Signed-off-by: Alexsey Shestacov <wingrime@linux-sunxi.org> ---- - arch/arm/boot/dts/sun7i-a20.dtsi | 14 ++++++++++++++ - 1 file changed, 14 insertions(+) - ---- a/arch/arm/boot/dts/sun7i-a20.dtsi -+++ b/arch/arm/boot/dts/sun7i-a20.dtsi -@@ -746,6 +746,20 @@ - allwinner,drive = <2>; - allwinner,pull = <0>; - }; -+ -+ ir0_pins_a: ir0@0 { -+ allwinner,pins = "PB3","PB4"; -+ allwinner,function = "ir0"; -+ allwinner,drive = <0>; -+ allwinner,pull = <0>; -+ }; -+ -+ ir1_pins_a: ir1@0 { -+ allwinner,pins = "PB22","PB23"; -+ allwinner,function = "ir1"; -+ allwinner,drive = <0>; -+ allwinner,pull = <0>; -+ }; - }; - - timer@01c20c00 { diff --git a/target/linux/sunxi/patches-3.14/282-dt-sun7i-add-ir-ctrlers.patch b/target/linux/sunxi/patches-3.14/282-dt-sun7i-add-ir-ctrlers.patch deleted file mode 100644 index f5763badd5..0000000000 --- a/target/linux/sunxi/patches-3.14/282-dt-sun7i-add-ir-ctrlers.patch +++ /dev/null @@ -1,40 +0,0 @@ -From 0af3258f87d590864187b0187c7aa7428801ef80 Mon Sep 17 00:00:00 2001 -From: Alexander Bersenev <bay@hackerdom.ru> -Date: Mon, 9 Jun 2014 00:08:12 +0600 -Subject: [PATCH] ARM: sunxi: Add IR controllers on A20 to dtsi - -This patch adds records for two IR controllers on A20 - -Signed-off-by: Alexander Bersenev <bay@hackerdom.ru> -Signed-off-by: Alexsey Shestacov <wingrime@linux-sunxi.org> ---- - arch/arm/boot/dts/sun7i-a20.dtsi | 18 ++++++++++++++++++ - 1 file changed, 18 insertions(+) - ---- a/arch/arm/boot/dts/sun7i-a20.dtsi -+++ b/arch/arm/boot/dts/sun7i-a20.dtsi -@@ -785,6 +785,24 @@ - interrupts = <0 24 4>; - }; - -+ ir0: ir@01c21800 { -+ compatible = "allwinner,sun7i-a20-ir"; -+ clocks = <&apb0_gates 6>, <&ir0_clk>; -+ clock-names = "apb", "ir"; -+ interrupts = <0 5 4>; -+ reg = <0x01c21800 0x40>; -+ status = "disabled"; -+ }; -+ -+ ir1: ir@01c21c00 { -+ compatible = "allwinner,sun7i-a20-ir"; -+ clocks = <&apb0_gates 7>, <&ir1_clk>; -+ clock-names = "apb", "ir"; -+ interrupts = <0 6 4>; -+ reg = <0x01c21c00 0x40>; -+ status = "disabled"; -+ }; -+ - lradc: lradc@01c22800 { - compatible = "allwinner,sun4i-lradc-keys"; - reg = <0x01c22800 0x100>; diff --git a/target/linux/sunxi/patches-3.14/283-dt-sun7i-add-ir-to-cb2-cbt.patch b/target/linux/sunxi/patches-3.14/283-dt-sun7i-add-ir-to-cb2-cbt.patch deleted file mode 100644 index aceb56697e..0000000000 --- a/target/linux/sunxi/patches-3.14/283-dt-sun7i-add-ir-to-cb2-cbt.patch +++ /dev/null @@ -1,47 +0,0 @@ -From 05cffcda932b0914d78a08891c13e61593a6ce02 Mon Sep 17 00:00:00 2001 -From: Alexander Bersenev <bay@hackerdom.ru> -Date: Mon, 9 Jun 2014 00:08:13 +0600 -Subject: [PATCH] ARM: sunxi: Enable IR controller on cubieboard 2 and - cubietruck in dts - -This patch enables two IR devices in dts: -- One IR device physically found on Cubieboard 2 -- One IR device physically found on Cubietruck - -Signed-off-by: Alexander Bersenev <bay@hackerdom.ru> -Signed-off-by: Alexsey Shestacov <wingrime@linux-sunxi.org> ---- - arch/arm/boot/dts/sun7i-a20-cubieboard2.dts | 6 ++++++ - arch/arm/boot/dts/sun7i-a20-cubietruck.dts | 6 ++++++ - 2 files changed, 12 insertions(+) - ---- a/arch/arm/boot/dts/sun7i-a20-cubieboard2.dts -+++ b/arch/arm/boot/dts/sun7i-a20-cubieboard2.dts -@@ -64,6 +64,12 @@ - }; - }; - -+ ir0: ir@01c21800 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&ir0_pins_a>; -+ status = "okay"; -+ }; -+ - uart0: serial@01c28000 { - pinctrl-names = "default"; - pinctrl-0 = <&uart0_pins_a>; ---- a/arch/arm/boot/dts/sun7i-a20-cubietruck.dts -+++ b/arch/arm/boot/dts/sun7i-a20-cubietruck.dts -@@ -114,6 +114,12 @@ - }; - }; - -+ ir0: ir@01c21800 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&ir0_pins_a>; -+ status = "okay"; -+ }; -+ - uart0: serial@01c28000 { - pinctrl-names = "default"; - pinctrl-0 = <&uart0_pins_a>; diff --git a/target/linux/sunxi/patches-3.14/284-ir-backports-from-3.15.patch b/target/linux/sunxi/patches-3.14/284-ir-backports-from-3.15.patch deleted file mode 100644 index 9e703e7dce..0000000000 --- a/target/linux/sunxi/patches-3.14/284-ir-backports-from-3.15.patch +++ /dev/null @@ -1,1210 +0,0 @@ -From 00942d1a1bd93ac108c1b92d504c568a37be1833 Mon Sep 17 00:00:00 2001 -From: James Hogan <james.hogan@imgtec.com> -Date: Fri, 17 Jan 2014 10:58:49 -0300 -Subject: [PATCH] [media] media: rc: add sysfs scancode filtering interface - -Add and document a generic sysfs based scancode filtering interface for -making use of IR data matching hardware to filter out uninteresting -scancodes. Two filters exist, one for normal operation and one for -filtering scancodes which are permitted to wake the system from suspend. - -The following files are added to /sys/class/rc/rc?/: - - filter: normal scancode filter value - - filter_mask: normal scancode filter mask - - wakeup_filter: wakeup scancode filter value - - wakeup_filter_mask: wakeup scancode filter mask - -A new s_filter() driver callback is added which must arrange for the -specified filter to be applied at the right time. Drivers can convert -the scancode filter into a raw IR data filter, which can be applied -immediately or later (for wake up filters). - -Signed-off-by: James Hogan <james.hogan@imgtec.com> -Cc: Mauro Carvalho Chehab <m.chehab@samsung.com> -Cc: linux-media@vger.kernel.org -Cc: Rob Landley <rob@landley.net> -Cc: linux-doc@vger.kernel.org -Signed-off-by: Mauro Carvalho Chehab <m.chehab@samsung.com> ---- - Documentation/ABI/testing/sysfs-class-rc | 58 +++++++++++++ - drivers/media/rc/rc-main.c | 136 +++++++++++++++++++++++++++++++ - include/media/rc-core.h | 29 +++++++ - 3 files changed, 223 insertions(+) - -From 7b802ce7e8c67510389fdbbe29edd87a75df3a93 Mon Sep 17 00:00:00 2001 -From: James Hogan <james.hogan@imgtec.com> -Date: Mon, 10 Feb 2014 18:31:56 -0300 -Subject: [PATCH] [media] rc-main: store_filter: pass errors to userland -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Propagate errors returned by drivers from the s_filter callback back to -userland when updating scancode filters. This allows userland to see -when the filter couldn't be updated, usually because it's not a valid -filter for the hardware. - -Previously the filter was being updated conditionally on success of -s_filter, but the write always reported success back to userland. - -Reported-by: Antti Seppälä <a.seppala@gmail.com> -Signed-off-by: James Hogan <james.hogan@imgtec.com> -Signed-off-by: Mauro Carvalho Chehab <m.chehab@samsung.com> ---- - drivers/media/rc/rc-main.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -From b8c7d915087c97a21fa415fa0e860e59739da202 Mon Sep 17 00:00:00 2001 -From: James Hogan <james.hogan@imgtec.com> -Date: Fri, 28 Feb 2014 20:17:02 -0300 -Subject: [PATCH] [media] rc-main: add generic scancode filtering -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Add generic scancode filtering of RC input events, and fall back to -permitting any RC_FILTER_NORMAL scancode filter to be set if no s_filter -callback exists. This allows raw IR decoder events to be filtered, and -potentially allows hardware decoders to set looser filters and rely on -generic code to filter out the corner cases. - -Signed-off-by: James Hogan <james.hogan@imgtec.com> -Reviewed-by: Antti Seppälä <a.seppala@gmail.com> -Signed-off-by: Mauro Carvalho Chehab <m.chehab@samsung.com> ---- - drivers/media/rc/rc-main.c | 20 +++++++++++++------- - 1 file changed, 13 insertions(+), 7 deletions(-) - -From 1a1934fab0c920f0d3bceeb60c9fe2dae8a56be9 Mon Sep 17 00:00:00 2001 -From: James Hogan <james.hogan@imgtec.com> -Date: Fri, 28 Feb 2014 20:17:03 -0300 -Subject: [PATCH] [media] rc: abstract access to allowed/enabled protocols -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -The allowed and enabled protocol masks need to be expanded to be per -filter type in order to support wakeup filter protocol selection. To -ease that process abstract access to the rc_dev::allowed_protos and -rc_dev::enabled_protocols members with inline functions. - -Signed-off-by: James Hogan <james.hogan@imgtec.com> -Reviewed-by: Antti Seppälä <a.seppala@gmail.com> -Signed-off-by: Mauro Carvalho Chehab <m.chehab@samsung.com> ---- - drivers/hid/hid-picolcd_cir.c | 2 +- - drivers/media/common/siano/smsir.c | 2 +- - drivers/media/i2c/ir-kbd-i2c.c | 4 ++-- - drivers/media/pci/cx23885/cx23885-input.c | 2 +- - drivers/media/pci/cx88/cx88-input.c | 2 +- - drivers/media/rc/ati_remote.c | 2 +- - drivers/media/rc/ene_ir.c | 2 +- - drivers/media/rc/fintek-cir.c | 2 +- - drivers/media/rc/gpio-ir-recv.c | 4 ++-- - drivers/media/rc/iguanair.c | 2 +- - drivers/media/rc/imon.c | 7 ++++--- - drivers/media/rc/ir-jvc-decoder.c | 2 +- - drivers/media/rc/ir-lirc-codec.c | 2 +- - drivers/media/rc/ir-mce_kbd-decoder.c | 2 +- - drivers/media/rc/ir-nec-decoder.c | 2 +- - drivers/media/rc/ir-raw.c | 2 +- - drivers/media/rc/ir-rc5-decoder.c | 6 +++--- - drivers/media/rc/ir-rc5-sz-decoder.c | 2 +- - drivers/media/rc/ir-rc6-decoder.c | 6 +++--- - drivers/media/rc/ir-sanyo-decoder.c | 2 +- - drivers/media/rc/ir-sharp-decoder.c | 2 +- - drivers/media/rc/ir-sony-decoder.c | 10 +++++----- - drivers/media/rc/ite-cir.c | 2 +- - drivers/media/rc/mceusb.c | 2 +- - drivers/media/rc/nuvoton-cir.c | 2 +- - drivers/media/rc/rc-loopback.c | 2 +- - drivers/media/rc/redrat3.c | 2 +- - drivers/media/rc/st_rc.c | 2 +- - drivers/media/rc/streamzap.c | 2 +- - drivers/media/rc/ttusbir.c | 2 +- - drivers/media/rc/winbond-cir.c | 2 +- - drivers/media/usb/dvb-usb-v2/dvb_usb_core.c | 2 +- - drivers/media/usb/dvb-usb/dvb-usb-remote.c | 2 +- - drivers/media/usb/em28xx/em28xx-input.c | 8 ++++---- - drivers/media/usb/tm6000/tm6000-input.c | 2 +- - include/media/rc-core.h | 22 ++++++++++++++++++++++ - 36 files changed, 73 insertions(+), 50 deletions(-) - -From acff5f24732acc8a55d0a0f0ee1d19442267df63 Mon Sep 17 00:00:00 2001 -From: James Hogan <james.hogan@imgtec.com> -Date: Fri, 28 Feb 2014 20:17:04 -0300 -Subject: [PATCH] [media] rc: add allowed/enabled wakeup protocol masks -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Only a single allowed and enabled protocol mask currently exists in -struct rc_dev, however to support a separate wakeup filter protocol two -of each are needed, ideally as an array. - -Therefore make both rc_dev::allowed_protos and rc_dev::enabled_protocols -arrays, update all users to reference the first element -(RC_FILTER_NORMAL), and add a couple more helper functions for drivers -to use for setting the allowed and enabled wakeup protocols. - -We also rename allowed_protos to allowed_protocols while we're at it, -which is more consistent with enabled_protocols. - -Signed-off-by: James Hogan <james.hogan@imgtec.com> -Reviewed-by: Antti Seppälä <a.seppala@gmail.com> -Signed-off-by: Mauro Carvalho Chehab <m.chehab@samsung.com> ---- - drivers/media/rc/rc-main.c | 10 +++++----- - include/media/rc-core.h | 32 ++++++++++++++++++++++++-------- - 2 files changed, 29 insertions(+), 13 deletions(-) - -From ab88c66deace78989aa71cb139284cf7fb227ba4 Mon Sep 17 00:00:00 2001 -From: James Hogan <james.hogan@imgtec.com> -Date: Fri, 28 Feb 2014 20:17:05 -0300 -Subject: [PATCH] [media] rc: add wakeup_protocols sysfs file -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Add a wakeup_protocols sysfs file which controls the new -rc_dev::enabled_protocols[RC_FILTER_WAKEUP], which is the mask of -protocols that are used for the wakeup filter. - -A new RC driver callback change_wakeup_protocol() is called to change -the wakeup protocol mask. - -Signed-off-by: James Hogan <james.hogan@imgtec.com> -Reviewed-by: Antti Seppälä <a.seppala@gmail.com> -Signed-off-by: Mauro Carvalho Chehab <m.chehab@samsung.com> ---- - Documentation/ABI/testing/sysfs-class-rc | 23 +++++- - .../DocBook/media/v4l/remote_controllers.xml | 20 +++++- - drivers/media/rc/rc-main.c | 82 +++++++++++++--------- - include/media/rc-core.h | 3 + - 4 files changed, 90 insertions(+), 38 deletions(-) - -From 6bea25af147fcddcd8fd4557f4184c847c5c6ffd Mon Sep 17 00:00:00 2001 -From: James Hogan <james.hogan@imgtec.com> -Date: Fri, 28 Feb 2014 20:17:06 -0300 -Subject: [PATCH] [media] rc-main: automatically refresh filter on protocol - change -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -When either of the normal or wakeup filter protocols are changed, -refresh the corresponding scancode filter, i.e. try and set the same -scancode filter with the new protocol. If that fails clear the filter -instead. - -If no protocol was selected the filter is just cleared, and if no -s_filter callback exists the filter is left unmodified. - -Similarly clear the filter mask when the filter is set if no protocol is -currently selected. - -This simplifies driver code which no longer has to explicitly worry -about modifying the filter on a protocol change. This also allows the -change_wakeup_protocol callback to be omitted entirely if there is only -a single available wakeup protocol at a time, since selecting no -protocol will automatically clear the wakeup filter, disabling wakeup. - -Signed-off-by: James Hogan <james.hogan@imgtec.com> -Reviewed-by: Antti Seppälä <a.seppala@gmail.com> -Signed-off-by: Mauro Carvalho Chehab <m.chehab@samsung.com> ---- - drivers/media/rc/rc-main.c | 41 +++++++++++++++++++++++++++++++++++++++-- - 1 file changed, 39 insertions(+), 2 deletions(-) - -From 262912335c823a2bbcc87003ee55d62cc27f4e48 Mon Sep 17 00:00:00 2001 -From: James Hogan <james.hogan@imgtec.com> -Date: Sat, 1 Mar 2014 19:52:25 -0300 -Subject: [PATCH] [media] rc-main: fix missing unlock if no devno left - -While playing with make coccicheck I noticed this message: -drivers/media/rc/rc-main.c:1245:3-9: preceding lock on line 1238 - -It was introduced by commit 587d1b06e07b ([media] rc-core: reuse device -numbers) which returns -ENOMEM after a mutex_lock without first -unlocking it when there are no more device numbers left. The added code -doesn't depend on the device lock, so move it before the lock is taken. - -Signed-off-by: James Hogan <james.hogan@imgtec.com> -Signed-off-by: Mauro Carvalho Chehab <m.chehab@samsung.com> ---- - drivers/media/rc/rc-main.c | 16 ++++++++-------- - 1 file changed, 8 insertions(+), 8 deletions(-) - ---- a/drivers/hid/hid-picolcd_cir.c -+++ b/drivers/hid/hid-picolcd_cir.c -@@ -114,7 +114,7 @@ int picolcd_init_cir(struct picolcd_data - - rdev->priv = data; - rdev->driver_type = RC_DRIVER_IR_RAW; -- rdev->allowed_protos = RC_BIT_ALL; -+ rc_set_allowed_protocols(rdev, RC_BIT_ALL); - rdev->open = picolcd_cir_open; - rdev->close = picolcd_cir_close; - rdev->input_name = data->hdev->name; ---- a/drivers/media/common/siano/smsir.c -+++ b/drivers/media/common/siano/smsir.c -@@ -88,7 +88,7 @@ int sms_ir_init(struct smscore_device_t - - dev->priv = coredev; - dev->driver_type = RC_DRIVER_IR_RAW; -- dev->allowed_protos = RC_BIT_ALL; -+ rc_set_allowed_protocols(dev, RC_BIT_ALL); - dev->map_name = sms_get_board(board_id)->rc_codes; - dev->driver_name = MODULE_NAME; - ---- a/drivers/media/i2c/ir-kbd-i2c.c -+++ b/drivers/media/i2c/ir-kbd-i2c.c -@@ -431,8 +431,8 @@ static int ir_probe(struct i2c_client *c - * Initialize the other fields of rc_dev - */ - rc->map_name = ir->ir_codes; -- rc->allowed_protos = rc_type; -- rc->enabled_protocols = rc_type; -+ rc_set_allowed_protocols(rc, rc_type); -+ rc_set_enabled_protocols(rc, rc_type); - if (!rc->driver_name) - rc->driver_name = MODULE_NAME; - ---- a/drivers/media/pci/cx23885/cx23885-input.c -+++ b/drivers/media/pci/cx23885/cx23885-input.c -@@ -346,7 +346,7 @@ int cx23885_input_init(struct cx23885_de - } - rc->dev.parent = &dev->pci->dev; - rc->driver_type = driver_type; -- rc->allowed_protos = allowed_protos; -+ rc_set_allowed_protocols(rc, allowed_protos); - rc->priv = kernel_ir; - rc->open = cx23885_input_ir_open; - rc->close = cx23885_input_ir_close; ---- a/drivers/media/pci/cx88/cx88-input.c -+++ b/drivers/media/pci/cx88/cx88-input.c -@@ -469,7 +469,7 @@ int cx88_ir_init(struct cx88_core *core, - dev->timeout = 10 * 1000 * 1000; /* 10 ms */ - } else { - dev->driver_type = RC_DRIVER_SCANCODE; -- dev->allowed_protos = rc_type; -+ rc_set_allowed_protocols(dev, rc_type); - } - - ir->core = core; ---- a/drivers/media/rc/ati_remote.c -+++ b/drivers/media/rc/ati_remote.c -@@ -784,7 +784,7 @@ static void ati_remote_rc_init(struct at - - rdev->priv = ati_remote; - rdev->driver_type = RC_DRIVER_SCANCODE; -- rdev->allowed_protos = RC_BIT_OTHER; -+ rc_set_allowed_protocols(rdev, RC_BIT_OTHER); - rdev->driver_name = "ati_remote"; - - rdev->open = ati_remote_rc_open; ---- a/drivers/media/rc/ene_ir.c -+++ b/drivers/media/rc/ene_ir.c -@@ -1059,7 +1059,7 @@ static int ene_probe(struct pnp_dev *pnp - learning_mode_force = false; - - rdev->driver_type = RC_DRIVER_IR_RAW; -- rdev->allowed_protos = RC_BIT_ALL; -+ rc_set_allowed_protocols(rdev, RC_BIT_ALL); - rdev->priv = dev; - rdev->open = ene_open; - rdev->close = ene_close; ---- a/drivers/media/rc/fintek-cir.c -+++ b/drivers/media/rc/fintek-cir.c -@@ -541,7 +541,7 @@ static int fintek_probe(struct pnp_dev * - /* Set up the rc device */ - rdev->priv = fintek; - rdev->driver_type = RC_DRIVER_IR_RAW; -- rdev->allowed_protos = RC_BIT_ALL; -+ rc_set_allowed_protocols(rdev, RC_BIT_ALL); - rdev->open = fintek_open; - rdev->close = fintek_close; - rdev->input_name = FINTEK_DESCRIPTION; ---- a/drivers/media/rc/gpio-ir-recv.c -+++ b/drivers/media/rc/gpio-ir-recv.c -@@ -145,9 +145,9 @@ static int gpio_ir_recv_probe(struct pla - rcdev->dev.parent = &pdev->dev; - rcdev->driver_name = GPIO_IR_DRIVER_NAME; - if (pdata->allowed_protos) -- rcdev->allowed_protos = pdata->allowed_protos; -+ rc_set_allowed_protocols(rcdev, pdata->allowed_protos); - else -- rcdev->allowed_protos = RC_BIT_ALL; -+ rc_set_allowed_protocols(rcdev, RC_BIT_ALL); - rcdev->map_name = pdata->map_name ?: RC_MAP_EMPTY; - - gpio_dev->rcdev = rcdev; ---- a/drivers/media/rc/iguanair.c -+++ b/drivers/media/rc/iguanair.c -@@ -494,7 +494,7 @@ static int iguanair_probe(struct usb_int - usb_to_input_id(ir->udev, &rc->input_id); - rc->dev.parent = &intf->dev; - rc->driver_type = RC_DRIVER_IR_RAW; -- rc->allowed_protos = RC_BIT_ALL; -+ rc_set_allowed_protocols(rc, RC_BIT_ALL); - rc->priv = ir; - rc->open = iguanair_open; - rc->close = iguanair_close; ---- a/drivers/media/rc/imon.c -+++ b/drivers/media/rc/imon.c -@@ -1017,7 +1017,7 @@ static int imon_ir_change_protocol(struc - unsigned char ir_proto_packet[] = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x86 }; - -- if (*rc_type && !(*rc_type & rc->allowed_protos)) -+ if (*rc_type && !rc_protocols_allowed(rc, *rc_type)) - dev_warn(dev, "Looks like you're trying to use an IR protocol " - "this device does not support\n"); - -@@ -1867,7 +1867,8 @@ static struct rc_dev *imon_init_rdev(str - - rdev->priv = ictx; - rdev->driver_type = RC_DRIVER_SCANCODE; -- rdev->allowed_protos = RC_BIT_OTHER | RC_BIT_RC6_MCE; /* iMON PAD or MCE */ -+ /* iMON PAD or MCE */ -+ rc_set_allowed_protocols(rdev, RC_BIT_OTHER | RC_BIT_RC6_MCE); - rdev->change_protocol = imon_ir_change_protocol; - rdev->driver_name = MOD_NAME; - -@@ -1880,7 +1881,7 @@ static struct rc_dev *imon_init_rdev(str - - if (ictx->product == 0xffdc) { - imon_get_ffdc_type(ictx); -- rdev->allowed_protos = ictx->rc_type; -+ rc_set_allowed_protocols(rdev, ictx->rc_type); - } - - imon_set_display_type(ictx); ---- a/drivers/media/rc/ir-jvc-decoder.c -+++ b/drivers/media/rc/ir-jvc-decoder.c -@@ -47,7 +47,7 @@ static int ir_jvc_decode(struct rc_dev * - { - struct jvc_dec *data = &dev->raw->jvc; - -- if (!(dev->enabled_protocols & RC_BIT_JVC)) -+ if (!rc_protocols_enabled(dev, RC_BIT_JVC)) - return 0; - - if (!is_timing_event(ev)) { ---- a/drivers/media/rc/ir-lirc-codec.c -+++ b/drivers/media/rc/ir-lirc-codec.c -@@ -35,7 +35,7 @@ static int ir_lirc_decode(struct rc_dev - struct lirc_codec *lirc = &dev->raw->lirc; - int sample; - -- if (!(dev->enabled_protocols & RC_BIT_LIRC)) -+ if (!rc_protocols_enabled(dev, RC_BIT_LIRC)) - return 0; - - if (!dev->raw->lirc.drv || !dev->raw->lirc.drv->rbuf) ---- a/drivers/media/rc/ir-mce_kbd-decoder.c -+++ b/drivers/media/rc/ir-mce_kbd-decoder.c -@@ -216,7 +216,7 @@ static int ir_mce_kbd_decode(struct rc_d - u32 scancode; - unsigned long delay; - -- if (!(dev->enabled_protocols & RC_BIT_MCE_KBD)) -+ if (!rc_protocols_enabled(dev, RC_BIT_MCE_KBD)) - return 0; - - if (!is_timing_event(ev)) { ---- a/drivers/media/rc/ir-nec-decoder.c -+++ b/drivers/media/rc/ir-nec-decoder.c -@@ -52,7 +52,7 @@ static int ir_nec_decode(struct rc_dev * - u8 address, not_address, command, not_command; - bool send_32bits = false; - -- if (!(dev->enabled_protocols & RC_BIT_NEC)) -+ if (!rc_protocols_enabled(dev, RC_BIT_NEC)) - return 0; - - if (!is_timing_event(ev)) { ---- a/drivers/media/rc/ir-raw.c -+++ b/drivers/media/rc/ir-raw.c -@@ -256,7 +256,7 @@ int ir_raw_event_register(struct rc_dev - return -ENOMEM; - - dev->raw->dev = dev; -- dev->enabled_protocols = ~0; -+ rc_set_enabled_protocols(dev, ~0); - rc = kfifo_alloc(&dev->raw->kfifo, - sizeof(struct ir_raw_event) * MAX_IR_EVENT_SIZE, - GFP_KERNEL); ---- a/drivers/media/rc/ir-rc5-decoder.c -+++ b/drivers/media/rc/ir-rc5-decoder.c -@@ -52,7 +52,7 @@ static int ir_rc5_decode(struct rc_dev * - u8 toggle; - u32 scancode; - -- if (!(dev->enabled_protocols & (RC_BIT_RC5 | RC_BIT_RC5X))) -+ if (!rc_protocols_enabled(dev, RC_BIT_RC5 | RC_BIT_RC5X)) - return 0; - - if (!is_timing_event(ev)) { -@@ -128,7 +128,7 @@ again: - if (data->wanted_bits == RC5X_NBITS) { - /* RC5X */ - u8 xdata, command, system; -- if (!(dev->enabled_protocols & RC_BIT_RC5X)) { -+ if (!rc_protocols_enabled(dev, RC_BIT_RC5X)) { - data->state = STATE_INACTIVE; - return 0; - } -@@ -145,7 +145,7 @@ again: - } else { - /* RC5 */ - u8 command, system; -- if (!(dev->enabled_protocols & RC_BIT_RC5)) { -+ if (!rc_protocols_enabled(dev, RC_BIT_RC5)) { - data->state = STATE_INACTIVE; - return 0; - } ---- a/drivers/media/rc/ir-rc5-sz-decoder.c -+++ b/drivers/media/rc/ir-rc5-sz-decoder.c -@@ -48,7 +48,7 @@ static int ir_rc5_sz_decode(struct rc_de - u8 toggle, command, system; - u32 scancode; - -- if (!(dev->enabled_protocols & RC_BIT_RC5_SZ)) -+ if (!rc_protocols_enabled(dev, RC_BIT_RC5_SZ)) - return 0; - - if (!is_timing_event(ev)) { ---- a/drivers/media/rc/ir-rc6-decoder.c -+++ b/drivers/media/rc/ir-rc6-decoder.c -@@ -89,9 +89,9 @@ static int ir_rc6_decode(struct rc_dev * - u32 scancode; - u8 toggle; - -- if (!(dev->enabled_protocols & -- (RC_BIT_RC6_0 | RC_BIT_RC6_6A_20 | RC_BIT_RC6_6A_24 | -- RC_BIT_RC6_6A_32 | RC_BIT_RC6_MCE))) -+ if (!rc_protocols_enabled(dev, RC_BIT_RC6_0 | RC_BIT_RC6_6A_20 | -+ RC_BIT_RC6_6A_24 | RC_BIT_RC6_6A_32 | -+ RC_BIT_RC6_MCE)) - return 0; - - if (!is_timing_event(ev)) { ---- a/drivers/media/rc/ir-sanyo-decoder.c -+++ b/drivers/media/rc/ir-sanyo-decoder.c -@@ -58,7 +58,7 @@ static int ir_sanyo_decode(struct rc_dev - u32 scancode; - u8 address, command, not_command; - -- if (!(dev->enabled_protocols & RC_BIT_SANYO)) -+ if (!rc_protocols_enabled(dev, RC_BIT_SANYO)) - return 0; - - if (!is_timing_event(ev)) { ---- a/drivers/media/rc/ir-sony-decoder.c -+++ b/drivers/media/rc/ir-sony-decoder.c -@@ -45,8 +45,8 @@ static int ir_sony_decode(struct rc_dev - u32 scancode; - u8 device, subdevice, function; - -- if (!(dev->enabled_protocols & -- (RC_BIT_SONY12 | RC_BIT_SONY15 | RC_BIT_SONY20))) -+ if (!rc_protocols_enabled(dev, RC_BIT_SONY12 | RC_BIT_SONY15 | -+ RC_BIT_SONY20)) - return 0; - - if (!is_timing_event(ev)) { -@@ -124,7 +124,7 @@ static int ir_sony_decode(struct rc_dev - - switch (data->count) { - case 12: -- if (!(dev->enabled_protocols & RC_BIT_SONY12)) { -+ if (!rc_protocols_enabled(dev, RC_BIT_SONY12)) { - data->state = STATE_INACTIVE; - return 0; - } -@@ -133,7 +133,7 @@ static int ir_sony_decode(struct rc_dev - function = bitrev8((data->bits >> 4) & 0xFE); - break; - case 15: -- if (!(dev->enabled_protocols & RC_BIT_SONY15)) { -+ if (!rc_protocols_enabled(dev, RC_BIT_SONY15)) { - data->state = STATE_INACTIVE; - return 0; - } -@@ -142,7 +142,7 @@ static int ir_sony_decode(struct rc_dev - function = bitrev8((data->bits >> 7) & 0xFE); - break; - case 20: -- if (!(dev->enabled_protocols & RC_BIT_SONY20)) { -+ if (!rc_protocols_enabled(dev, RC_BIT_SONY20)) { - data->state = STATE_INACTIVE; - return 0; - } ---- a/drivers/media/rc/ite-cir.c -+++ b/drivers/media/rc/ite-cir.c -@@ -1563,7 +1563,7 @@ static int ite_probe(struct pnp_dev *pde - /* set up ir-core props */ - rdev->priv = itdev; - rdev->driver_type = RC_DRIVER_IR_RAW; -- rdev->allowed_protos = RC_BIT_ALL; -+ rc_set_allowed_protocols(rdev, RC_BIT_ALL); - rdev->open = ite_open; - rdev->close = ite_close; - rdev->s_idle = ite_s_idle; ---- a/drivers/media/rc/mceusb.c -+++ b/drivers/media/rc/mceusb.c -@@ -1217,7 +1217,7 @@ static struct rc_dev *mceusb_init_rc_dev - rc->dev.parent = dev; - rc->priv = ir; - rc->driver_type = RC_DRIVER_IR_RAW; -- rc->allowed_protos = RC_BIT_ALL; -+ rc_set_allowed_protocols(rc, RC_BIT_ALL); - rc->timeout = MS_TO_NS(100); - if (!ir->flags.no_tx) { - rc->s_tx_mask = mceusb_set_tx_mask; ---- a/drivers/media/rc/nuvoton-cir.c -+++ b/drivers/media/rc/nuvoton-cir.c -@@ -1042,7 +1042,7 @@ static int nvt_probe(struct pnp_dev *pde - /* Set up the rc device */ - rdev->priv = nvt; - rdev->driver_type = RC_DRIVER_IR_RAW; -- rdev->allowed_protos = RC_BIT_ALL; -+ rc_set_allowed_protocols(rdev, RC_BIT_ALL); - rdev->open = nvt_open; - rdev->close = nvt_close; - rdev->tx_ir = nvt_tx_ir; ---- a/drivers/media/rc/rc-loopback.c -+++ b/drivers/media/rc/rc-loopback.c -@@ -195,7 +195,7 @@ static int __init loop_init(void) - rc->map_name = RC_MAP_EMPTY; - rc->priv = &loopdev; - rc->driver_type = RC_DRIVER_IR_RAW; -- rc->allowed_protos = RC_BIT_ALL; -+ rc_set_allowed_protocols(rc, RC_BIT_ALL); - rc->timeout = 100 * 1000 * 1000; /* 100 ms */ - rc->min_timeout = 1; - rc->max_timeout = UINT_MAX; ---- a/drivers/media/rc/rc-main.c -+++ b/drivers/media/rc/rc-main.c -@@ -633,6 +633,7 @@ EXPORT_SYMBOL_GPL(rc_repeat); - static void ir_do_keydown(struct rc_dev *dev, int scancode, - u32 keycode, u8 toggle) - { -+ struct rc_scancode_filter *filter; - bool new_event = !dev->keypressed || - dev->last_scancode != scancode || - dev->last_toggle != toggle; -@@ -640,6 +641,11 @@ static void ir_do_keydown(struct rc_dev - if (new_event && dev->keypressed) - ir_do_keyup(dev, false); - -+ /* Generic scancode filtering */ -+ filter = &dev->scancode_filters[RC_FILTER_NORMAL]; -+ if (filter->mask && ((scancode ^ filter->data) & filter->mask)) -+ return; -+ - input_event(dev->input_dev, EV_MSC, MSC_SCAN, scancode); - - if (new_event && keycode != KEY_RESERVED) { -@@ -795,13 +801,38 @@ static struct { - }; - - /** -- * show_protocols() - shows the current IR protocol(s) -+ * struct rc_filter_attribute - Device attribute relating to a filter type. -+ * @attr: Device attribute. -+ * @type: Filter type. -+ * @mask: false for filter value, true for filter mask. -+ */ -+struct rc_filter_attribute { -+ struct device_attribute attr; -+ enum rc_filter_type type; -+ bool mask; -+}; -+#define to_rc_filter_attr(a) container_of(a, struct rc_filter_attribute, attr) -+ -+#define RC_PROTO_ATTR(_name, _mode, _show, _store, _type) \ -+ struct rc_filter_attribute dev_attr_##_name = { \ -+ .attr = __ATTR(_name, _mode, _show, _store), \ -+ .type = (_type), \ -+ } -+#define RC_FILTER_ATTR(_name, _mode, _show, _store, _type, _mask) \ -+ struct rc_filter_attribute dev_attr_##_name = { \ -+ .attr = __ATTR(_name, _mode, _show, _store), \ -+ .type = (_type), \ -+ .mask = (_mask), \ -+ } -+ -+/** -+ * show_protocols() - shows the current/wakeup IR protocol(s) - * @device: the device descriptor - * @mattr: the device attribute struct (unused) - * @buf: a pointer to the output buffer - * - * This routine is a callback routine for input read the IR protocol type(s). -- * it is trigged by reading /sys/class/rc/rc?/protocols. -+ * it is trigged by reading /sys/class/rc/rc?/[wakeup_]protocols. - * It returns the protocol names of supported protocols. - * Enabled protocols are printed in brackets. - * -@@ -812,6 +843,7 @@ static ssize_t show_protocols(struct dev - struct device_attribute *mattr, char *buf) - { - struct rc_dev *dev = to_rc_dev(device); -+ struct rc_filter_attribute *fattr = to_rc_filter_attr(mattr); - u64 allowed, enabled; - char *tmp = buf; - int i; -@@ -822,9 +854,10 @@ static ssize_t show_protocols(struct dev - - mutex_lock(&dev->lock); - -- enabled = dev->enabled_protocols; -- if (dev->driver_type == RC_DRIVER_SCANCODE) -- allowed = dev->allowed_protos; -+ enabled = dev->enabled_protocols[fattr->type]; -+ if (dev->driver_type == RC_DRIVER_SCANCODE || -+ fattr->type == RC_FILTER_WAKEUP) -+ allowed = dev->allowed_protocols[fattr->type]; - else if (dev->raw) - allowed = ir_raw_get_allowed_protocols(); - else { -@@ -856,14 +889,14 @@ static ssize_t show_protocols(struct dev - } - - /** -- * store_protocols() - changes the current IR protocol(s) -+ * store_protocols() - changes the current/wakeup IR protocol(s) - * @device: the device descriptor - * @mattr: the device attribute struct (unused) - * @buf: a pointer to the input buffer - * @len: length of the input buffer - * - * This routine is for changing the IR protocol type. -- * It is trigged by writing to /sys/class/rc/rc?/protocols. -+ * It is trigged by writing to /sys/class/rc/rc?/[wakeup_]protocols. - * Writing "+proto" will add a protocol to the list of enabled protocols. - * Writing "-proto" will remove a protocol from the list of enabled protocols. - * Writing "proto" will enable only "proto". -@@ -880,12 +913,15 @@ static ssize_t store_protocols(struct de - size_t len) - { - struct rc_dev *dev = to_rc_dev(device); -+ struct rc_filter_attribute *fattr = to_rc_filter_attr(mattr); - bool enable, disable; - const char *tmp; -- u64 type; -+ u64 old_type, type; - u64 mask; - int rc, i, count = 0; - ssize_t ret; -+ int (*change_protocol)(struct rc_dev *dev, u64 *rc_type); -+ struct rc_scancode_filter local_filter, *filter; - - /* Device is being removed */ - if (!dev) -@@ -898,7 +934,8 @@ static ssize_t store_protocols(struct de - ret = -EINVAL; - goto out; - } -- type = dev->enabled_protocols; -+ old_type = dev->enabled_protocols[fattr->type]; -+ type = old_type; - - while ((tmp = strsep((char **) &data, " \n")) != NULL) { - if (!*tmp) -@@ -946,8 +983,10 @@ static ssize_t store_protocols(struct de - goto out; - } - -- if (dev->change_protocol) { -- rc = dev->change_protocol(dev, &type); -+ change_protocol = (fattr->type == RC_FILTER_NORMAL) -+ ? dev->change_protocol : dev->change_wakeup_protocol; -+ if (change_protocol) { -+ rc = change_protocol(dev, &type); - if (rc < 0) { - IR_dprintk(1, "Error setting protocols to 0x%llx\n", - (long long)type); -@@ -956,10 +995,40 @@ static ssize_t store_protocols(struct de - } - } - -- dev->enabled_protocols = type; -+ dev->enabled_protocols[fattr->type] = type; - IR_dprintk(1, "Current protocol(s): 0x%llx\n", - (long long)type); - -+ /* -+ * If the protocol is changed the filter needs updating. -+ * Try setting the same filter with the new protocol (if any). -+ * Fall back to clearing the filter. -+ */ -+ filter = &dev->scancode_filters[fattr->type]; -+ if (old_type != type && filter->mask) { -+ local_filter = *filter; -+ if (!type) { -+ /* no protocol => clear filter */ -+ ret = -1; -+ } else if (!dev->s_filter) { -+ /* generic filtering => accept any filter */ -+ ret = 0; -+ } else { -+ /* hardware filtering => try setting, otherwise clear */ -+ ret = dev->s_filter(dev, fattr->type, &local_filter); -+ } -+ if (ret < 0) { -+ /* clear the filter */ -+ local_filter.data = 0; -+ local_filter.mask = 0; -+ if (dev->s_filter) -+ dev->s_filter(dev, fattr->type, &local_filter); -+ } -+ -+ /* commit the new filter */ -+ *filter = local_filter; -+ } -+ - ret = len; - - out: -@@ -967,6 +1036,115 @@ out: - return ret; - } - -+/** -+ * show_filter() - shows the current scancode filter value or mask -+ * @device: the device descriptor -+ * @attr: the device attribute struct -+ * @buf: a pointer to the output buffer -+ * -+ * This routine is a callback routine to read a scancode filter value or mask. -+ * It is trigged by reading /sys/class/rc/rc?/[wakeup_]filter[_mask]. -+ * It prints the current scancode filter value or mask of the appropriate filter -+ * type in hexadecimal into @buf and returns the size of the buffer. -+ * -+ * Bits of the filter value corresponding to set bits in the filter mask are -+ * compared against input scancodes and non-matching scancodes are discarded. -+ * -+ * dev->lock is taken to guard against races between device registration, -+ * store_filter and show_filter. -+ */ -+static ssize_t show_filter(struct device *device, -+ struct device_attribute *attr, -+ char *buf) -+{ -+ struct rc_dev *dev = to_rc_dev(device); -+ struct rc_filter_attribute *fattr = to_rc_filter_attr(attr); -+ u32 val; -+ -+ /* Device is being removed */ -+ if (!dev) -+ return -EINVAL; -+ -+ mutex_lock(&dev->lock); -+ if (fattr->mask) -+ val = dev->scancode_filters[fattr->type].mask; -+ else -+ val = dev->scancode_filters[fattr->type].data; -+ mutex_unlock(&dev->lock); -+ -+ return sprintf(buf, "%#x\n", val); -+} -+ -+/** -+ * store_filter() - changes the scancode filter value -+ * @device: the device descriptor -+ * @attr: the device attribute struct -+ * @buf: a pointer to the input buffer -+ * @len: length of the input buffer -+ * -+ * This routine is for changing a scancode filter value or mask. -+ * It is trigged by writing to /sys/class/rc/rc?/[wakeup_]filter[_mask]. -+ * Returns -EINVAL if an invalid filter value for the current protocol was -+ * specified or if scancode filtering is not supported by the driver, otherwise -+ * returns @len. -+ * -+ * Bits of the filter value corresponding to set bits in the filter mask are -+ * compared against input scancodes and non-matching scancodes are discarded. -+ * -+ * dev->lock is taken to guard against races between device registration, -+ * store_filter and show_filter. -+ */ -+static ssize_t store_filter(struct device *device, -+ struct device_attribute *attr, -+ const char *buf, -+ size_t count) -+{ -+ struct rc_dev *dev = to_rc_dev(device); -+ struct rc_filter_attribute *fattr = to_rc_filter_attr(attr); -+ struct rc_scancode_filter local_filter, *filter; -+ int ret; -+ unsigned long val; -+ -+ /* Device is being removed */ -+ if (!dev) -+ return -EINVAL; -+ -+ ret = kstrtoul(buf, 0, &val); -+ if (ret < 0) -+ return ret; -+ -+ /* Scancode filter not supported (but still accept 0) */ -+ if (!dev->s_filter && fattr->type != RC_FILTER_NORMAL) -+ return val ? -EINVAL : count; -+ -+ mutex_lock(&dev->lock); -+ -+ /* Tell the driver about the new filter */ -+ filter = &dev->scancode_filters[fattr->type]; -+ local_filter = *filter; -+ if (fattr->mask) -+ local_filter.mask = val; -+ else -+ local_filter.data = val; -+ if (!dev->enabled_protocols[fattr->type] && local_filter.mask) { -+ /* refuse to set a filter unless a protocol is enabled */ -+ ret = -EINVAL; -+ goto unlock; -+ } -+ if (dev->s_filter) { -+ ret = dev->s_filter(dev, fattr->type, &local_filter); -+ if (ret < 0) -+ goto unlock; -+ } -+ -+ /* Success, commit the new filter */ -+ *filter = local_filter; -+ -+unlock: -+ mutex_unlock(&dev->lock); -+ return (ret < 0) ? ret : count; -+} -+ - static void rc_dev_release(struct device *device) - { - } -@@ -996,11 +1174,26 @@ static int rc_dev_uevent(struct device * - /* - * Static device attribute struct with the sysfs attributes for IR's - */ --static DEVICE_ATTR(protocols, S_IRUGO | S_IWUSR, -- show_protocols, store_protocols); -+static RC_PROTO_ATTR(protocols, S_IRUGO | S_IWUSR, -+ show_protocols, store_protocols, RC_FILTER_NORMAL); -+static RC_PROTO_ATTR(wakeup_protocols, S_IRUGO | S_IWUSR, -+ show_protocols, store_protocols, RC_FILTER_WAKEUP); -+static RC_FILTER_ATTR(filter, S_IRUGO|S_IWUSR, -+ show_filter, store_filter, RC_FILTER_NORMAL, false); -+static RC_FILTER_ATTR(filter_mask, S_IRUGO|S_IWUSR, -+ show_filter, store_filter, RC_FILTER_NORMAL, true); -+static RC_FILTER_ATTR(wakeup_filter, S_IRUGO|S_IWUSR, -+ show_filter, store_filter, RC_FILTER_WAKEUP, false); -+static RC_FILTER_ATTR(wakeup_filter_mask, S_IRUGO|S_IWUSR, -+ show_filter, store_filter, RC_FILTER_WAKEUP, true); - - static struct attribute *rc_dev_attrs[] = { -- &dev_attr_protocols.attr, -+ &dev_attr_protocols.attr.attr, -+ &dev_attr_wakeup_protocols.attr.attr, -+ &dev_attr_filter.attr.attr, -+ &dev_attr_filter_mask.attr.attr, -+ &dev_attr_wakeup_filter.attr.attr, -+ &dev_attr_wakeup_filter_mask.attr.attr, - NULL, - }; - -@@ -1091,14 +1284,6 @@ int rc_register_device(struct rc_dev *de - if (dev->close) - dev->input_dev->close = ir_close; - -- /* -- * Take the lock here, as the device sysfs node will appear -- * when device_add() is called, which may trigger an ir-keytable udev -- * rule, which will in turn call show_protocols and access -- * dev->enabled_protocols before it has been initialized. -- */ -- mutex_lock(&dev->lock); -- - do { - devno = find_first_zero_bit(ir_core_dev_number, - IRRCV_NUM_DEVICES); -@@ -1107,6 +1292,14 @@ int rc_register_device(struct rc_dev *de - return -ENOMEM; - } while (test_and_set_bit(devno, ir_core_dev_number)); - -+ /* -+ * Take the lock here, as the device sysfs node will appear -+ * when device_add() is called, which may trigger an ir-keytable udev -+ * rule, which will in turn call show_protocols and access -+ * dev->enabled_protocols before it has been initialized. -+ */ -+ mutex_lock(&dev->lock); -+ - dev->devno = devno; - dev_set_name(&dev->dev, "rc%ld", dev->devno); - dev_set_drvdata(&dev->dev, dev); -@@ -1172,7 +1365,7 @@ int rc_register_device(struct rc_dev *de - rc = dev->change_protocol(dev, &rc_type); - if (rc < 0) - goto out_raw; -- dev->enabled_protocols = rc_type; -+ dev->enabled_protocols[RC_FILTER_NORMAL] = rc_type; - } - - mutex_unlock(&dev->lock); ---- a/drivers/media/rc/redrat3.c -+++ b/drivers/media/rc/redrat3.c -@@ -922,7 +922,7 @@ static struct rc_dev *redrat3_init_rc_de - rc->dev.parent = dev; - rc->priv = rr3; - rc->driver_type = RC_DRIVER_IR_RAW; -- rc->allowed_protos = RC_BIT_ALL; -+ rc_set_allowed_protocols(rc, RC_BIT_ALL); - rc->timeout = US_TO_NS(2750); - rc->tx_ir = redrat3_transmit_ir; - rc->s_tx_carrier = redrat3_set_tx_carrier; ---- a/drivers/media/rc/st_rc.c -+++ b/drivers/media/rc/st_rc.c -@@ -287,7 +287,7 @@ static int st_rc_probe(struct platform_d - st_rc_hardware_init(rc_dev); - - rdev->driver_type = RC_DRIVER_IR_RAW; -- rdev->allowed_protos = RC_BIT_ALL; -+ rc_set_allowed_protocols(rdev, RC_BIT_ALL); - /* rx sampling rate is 10Mhz */ - rdev->rx_resolution = 100; - rdev->timeout = US_TO_NS(MAX_SYMB_TIME); ---- a/drivers/media/rc/streamzap.c -+++ b/drivers/media/rc/streamzap.c -@@ -322,7 +322,7 @@ static struct rc_dev *streamzap_init_rc_ - rdev->dev.parent = dev; - rdev->priv = sz; - rdev->driver_type = RC_DRIVER_IR_RAW; -- rdev->allowed_protos = RC_BIT_ALL; -+ rc_set_allowed_protocols(rdev, RC_BIT_ALL); - rdev->driver_name = DRIVER_NAME; - rdev->map_name = RC_MAP_STREAMZAP; - ---- a/drivers/media/rc/ttusbir.c -+++ b/drivers/media/rc/ttusbir.c -@@ -318,7 +318,7 @@ static int ttusbir_probe(struct usb_inte - usb_to_input_id(tt->udev, &rc->input_id); - rc->dev.parent = &intf->dev; - rc->driver_type = RC_DRIVER_IR_RAW; -- rc->allowed_protos = RC_BIT_ALL; -+ rc_set_allowed_protocols(rc, RC_BIT_ALL); - rc->priv = tt; - rc->driver_name = DRIVER_NAME; - rc->map_name = RC_MAP_TT_1500; ---- a/drivers/media/rc/winbond-cir.c -+++ b/drivers/media/rc/winbond-cir.c -@@ -1082,7 +1082,7 @@ wbcir_probe(struct pnp_dev *device, cons - data->dev->dev.parent = &device->dev; - data->dev->timeout = MS_TO_NS(100); - data->dev->rx_resolution = US_TO_NS(2); -- data->dev->allowed_protos = RC_BIT_ALL; -+ rc_set_allowed_protocols(data->dev, RC_BIT_ALL); - - err = rc_register_device(data->dev); - if (err) ---- a/drivers/media/usb/dvb-usb/dvb-usb-remote.c -+++ b/drivers/media/usb/dvb-usb/dvb-usb-remote.c -@@ -272,7 +272,7 @@ static int rc_core_dvb_usb_remote_init(s - dev->driver_name = d->props.rc.core.module_name; - dev->map_name = d->props.rc.core.rc_codes; - dev->change_protocol = d->props.rc.core.change_protocol; -- dev->allowed_protos = d->props.rc.core.allowed_protos; -+ rc_set_allowed_protocols(dev, d->props.rc.core.allowed_protos); - dev->driver_type = d->props.rc.core.driver_type; - usb_to_input_id(d->udev, &dev->input_id); - dev->input_name = "IR-receiver inside an USB DVB receiver"; ---- a/drivers/media/usb/dvb-usb-v2/dvb_usb_core.c -+++ b/drivers/media/usb/dvb-usb-v2/dvb_usb_core.c -@@ -164,7 +164,7 @@ static int dvb_usbv2_remote_init(struct - dev->driver_name = (char *) d->props->driver_name; - dev->map_name = d->rc.map_name; - dev->driver_type = d->rc.driver_type; -- dev->allowed_protos = d->rc.allowed_protos; -+ rc_set_allowed_protocols(dev, d->rc.allowed_protos); - dev->change_protocol = d->rc.change_protocol; - dev->priv = d; - ---- a/drivers/media/usb/em28xx/em28xx-input.c -+++ b/drivers/media/usb/em28xx/em28xx-input.c -@@ -725,7 +725,7 @@ static int em28xx_ir_init(struct em28xx - case EM2820_BOARD_HAUPPAUGE_WINTV_USB_2: - rc->map_name = RC_MAP_HAUPPAUGE; - ir->get_key_i2c = em28xx_get_key_em_haup; -- rc->allowed_protos = RC_BIT_RC5; -+ rc_set_allowed_protocols(rc, RC_BIT_RC5); - break; - case EM2820_BOARD_LEADTEK_WINFAST_USBII_DELUXE: - rc->map_name = RC_MAP_WINFAST_USBII_DELUXE; -@@ -741,7 +741,7 @@ static int em28xx_ir_init(struct em28xx - switch (dev->chip_id) { - case CHIP_ID_EM2860: - case CHIP_ID_EM2883: -- rc->allowed_protos = RC_BIT_RC5 | RC_BIT_NEC; -+ rc_set_allowed_protocols(rc, RC_BIT_RC5 | RC_BIT_NEC); - ir->get_key = default_polling_getkey; - break; - case CHIP_ID_EM2884: -@@ -749,8 +749,8 @@ static int em28xx_ir_init(struct em28xx - case CHIP_ID_EM28174: - case CHIP_ID_EM28178: - ir->get_key = em2874_polling_getkey; -- rc->allowed_protos = RC_BIT_RC5 | RC_BIT_NEC | -- RC_BIT_RC6_0; -+ rc_set_allowed_protocols(rc, RC_BIT_RC5 | RC_BIT_NEC | -+ RC_BIT_RC6_0); - break; - default: - err = -ENODEV; ---- a/drivers/media/usb/tm6000/tm6000-input.c -+++ b/drivers/media/usb/tm6000/tm6000-input.c -@@ -422,7 +422,7 @@ int tm6000_ir_init(struct tm6000_core *d - ir->rc = rc; - - /* input setup */ -- rc->allowed_protos = RC_BIT_RC5 | RC_BIT_NEC; -+ rc_set_allowed_protocols(rc, RC_BIT_RC5 | RC_BIT_NEC); - /* Neded, in order to support NEC remotes with 24 or 32 bits */ - rc->scanmask = 0xffff; - rc->priv = ir; ---- a/include/media/rc-core.h -+++ b/include/media/rc-core.h -@@ -35,6 +35,29 @@ enum rc_driver_type { - }; - - /** -+ * struct rc_scancode_filter - Filter scan codes. -+ * @data: Scancode data to match. -+ * @mask: Mask of bits of scancode to compare. -+ */ -+struct rc_scancode_filter { -+ u32 data; -+ u32 mask; -+}; -+ -+/** -+ * enum rc_filter_type - Filter type constants. -+ * @RC_FILTER_NORMAL: Filter for normal operation. -+ * @RC_FILTER_WAKEUP: Filter for waking from suspend. -+ * @RC_FILTER_MAX: Number of filter types. -+ */ -+enum rc_filter_type { -+ RC_FILTER_NORMAL = 0, -+ RC_FILTER_WAKEUP, -+ -+ RC_FILTER_MAX -+}; -+ -+/** - * struct rc_dev - represents a remote control device - * @dev: driver model's view of this device - * @input_name: name of the input child device -@@ -50,8 +73,10 @@ enum rc_driver_type { - * @input_dev: the input child device used to communicate events to userspace - * @driver_type: specifies if protocol decoding is done in hardware or software - * @idle: used to keep track of RX state -- * @allowed_protos: bitmask with the supported RC_BIT_* protocols -- * @enabled_protocols: bitmask with the enabled RC_BIT_* protocols -+ * @allowed_protocols: bitmask with the supported RC_BIT_* protocols for each -+ * filter type -+ * @enabled_protocols: bitmask with the enabled RC_BIT_* protocols for each -+ * filter type - * @scanmask: some hardware decoders are not capable of providing the full - * scancode to the application. As this is a hardware limit, we can't do - * anything with it. Yet, as the same keycode table can be used with other -@@ -70,7 +95,10 @@ enum rc_driver_type { - * @max_timeout: maximum timeout supported by device - * @rx_resolution : resolution (in ns) of input sampler - * @tx_resolution: resolution (in ns) of output sampler -+ * @scancode_filters: scancode filters (indexed by enum rc_filter_type) - * @change_protocol: allow changing the protocol used on hardware decoders -+ * @change_wakeup_protocol: allow changing the protocol used for wakeup -+ * filtering - * @open: callback to allow drivers to enable polling/irq when IR input device - * is opened. - * @close: callback to allow drivers to disable polling/irq when IR input device -@@ -84,6 +112,7 @@ enum rc_driver_type { - * device doesn't interrupt host until it sees IR pulses - * @s_learning_mode: enable wide band receiver used for learning - * @s_carrier_report: enable carrier reports -+ * @s_filter: set the scancode filter of a given type - */ - struct rc_dev { - struct device dev; -@@ -99,8 +128,8 @@ struct rc_dev { - struct input_dev *input_dev; - enum rc_driver_type driver_type; - bool idle; -- u64 allowed_protos; -- u64 enabled_protocols; -+ u64 allowed_protocols[RC_FILTER_MAX]; -+ u64 enabled_protocols[RC_FILTER_MAX]; - u32 users; - u32 scanmask; - void *priv; -@@ -116,7 +145,9 @@ struct rc_dev { - u32 max_timeout; - u32 rx_resolution; - u32 tx_resolution; -+ struct rc_scancode_filter scancode_filters[RC_FILTER_MAX]; - int (*change_protocol)(struct rc_dev *dev, u64 *rc_type); -+ int (*change_wakeup_protocol)(struct rc_dev *dev, u64 *rc_type); - int (*open)(struct rc_dev *dev); - void (*close)(struct rc_dev *dev); - int (*s_tx_mask)(struct rc_dev *dev, u32 mask); -@@ -127,10 +158,49 @@ struct rc_dev { - void (*s_idle)(struct rc_dev *dev, bool enable); - int (*s_learning_mode)(struct rc_dev *dev, int enable); - int (*s_carrier_report) (struct rc_dev *dev, int enable); -+ int (*s_filter)(struct rc_dev *dev, -+ enum rc_filter_type type, -+ struct rc_scancode_filter *filter); - }; - - #define to_rc_dev(d) container_of(d, struct rc_dev, dev) - -+static inline bool rc_protocols_allowed(struct rc_dev *rdev, u64 protos) -+{ -+ return rdev->allowed_protocols[RC_FILTER_NORMAL] & protos; -+} -+ -+/* should be called prior to registration or with mutex held */ -+static inline void rc_set_allowed_protocols(struct rc_dev *rdev, u64 protos) -+{ -+ rdev->allowed_protocols[RC_FILTER_NORMAL] = protos; -+} -+ -+static inline bool rc_protocols_enabled(struct rc_dev *rdev, u64 protos) -+{ -+ return rdev->enabled_protocols[RC_FILTER_NORMAL] & protos; -+} -+ -+/* should be called prior to registration or with mutex held */ -+static inline void rc_set_enabled_protocols(struct rc_dev *rdev, u64 protos) -+{ -+ rdev->enabled_protocols[RC_FILTER_NORMAL] = protos; -+} -+ -+/* should be called prior to registration or with mutex held */ -+static inline void rc_set_allowed_wakeup_protocols(struct rc_dev *rdev, -+ u64 protos) -+{ -+ rdev->allowed_protocols[RC_FILTER_WAKEUP] = protos; -+} -+ -+/* should be called prior to registration or with mutex held */ -+static inline void rc_set_enabled_wakeup_protocols(struct rc_dev *rdev, -+ u64 protos) -+{ -+ rdev->enabled_protocols[RC_FILTER_WAKEUP] = protos; -+} -+ - /* - * From rc-main.c - * Those functions can be used on any type of Remote Controller. They diff --git a/target/linux/sunxi/patches-3.14/300-1-dt-sun7i-add-pcduino3.patch b/target/linux/sunxi/patches-3.14/300-1-dt-sun7i-add-pcduino3.patch deleted file mode 100644 index 9b844262ab..0000000000 --- a/target/linux/sunxi/patches-3.14/300-1-dt-sun7i-add-pcduino3.patch +++ /dev/null @@ -1,39 +0,0 @@ -From c6c022c42e6b9115cbc36dce3f9100b90c2d2b06 Mon Sep 17 00:00:00 2001 -From: Zoltan HERPAI <wigyori@uid0.hu> -Date: Tue, 20 May 2014 22:28:49 +0200 -Subject: [PATCH] ARM: sun7i: dt: Add board support for LinkSprite pcDuino V3 - -The LinkSprite pcDuino V3 is an A20-based revision of the -earlier pcDuinos. This series will add support for the board, -along with some of its devices where the driver is accepted or -soon-to-be-accepted into mainline. - -Changes since v2: - - update MMC entry to comply with upstream - - unify the 4 patches into one - -Changes since v1: - - fix cosmetic issues - - fix i2c entry - - remove unnecessary input bindings include - - add MMC support - -Signed-off-by: Zoltan HERPAI <wigyori@uid0.hu> ---- - arch/arm/boot/dts/Makefile | 3 +- - arch/arm/boot/dts/sun7i-a20-pcduino3.dts | 119 +++++++++++++++++++++++++++++++ - 2 files changed, 121 insertions(+), 1 deletion(-) - create mode 100644 arch/arm/boot/dts/sun7i-a20-pcduino3.dts - ---- a/arch/arm/boot/dts/Makefile -+++ b/arch/arm/boot/dts/Makefile -@@ -292,7 +292,8 @@ dtb-$(CONFIG_ARCH_SUNXI) += \ - sun6i-a31-colombus.dtb \ - sun7i-a20-cubieboard2.dtb \ - sun7i-a20-cubietruck.dtb \ -- sun7i-a20-olinuxino-micro.dtb -+ sun7i-a20-olinuxino-micro.dtb \ -+ sun7i-a20-pcduino3.dtb - dtb-$(CONFIG_ARCH_TEGRA) += tegra20-harmony.dtb \ - tegra20-iris-512.dtb \ - tegra20-medcom-wide.dtb \ diff --git a/target/linux/sunxi/patches-3.14/300-2-dt-sun7i-add-pcduino3-dts.patch b/target/linux/sunxi/patches-3.14/300-2-dt-sun7i-add-pcduino3-dts.patch deleted file mode 100644 index bb2b923d2f..0000000000 --- a/target/linux/sunxi/patches-3.14/300-2-dt-sun7i-add-pcduino3-dts.patch +++ /dev/null @@ -1,156 +0,0 @@ ---- /dev/null -+++ b/arch/arm/boot/dts/sun7i-a20-pcduino3.dts -@@ -0,0 +1,153 @@ -+/* -+ * Copyright 2014 Zoltan HERPAI -+ * Zoltan HERPAI <wigyori@uid0.hu> -+ * -+ * 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/ "sun7i-a20.dtsi" -+/include/ "sunxi-ahci-reg.dtsi" -+/include/ "sun4i-a10-usb-vbus-reg.dtsi" -+#include <dt-bindings/input/input.h> -+ -+/ { -+ model = "LinkSprite pcDuino V3"; -+ compatible = "linksprite,a20-pcduino", "allwinner,sun7i-a20"; -+ -+ aliases { -+ spi0 = &spi1; -+ spi1 = &spi2; -+ }; -+ -+ soc@01c00000 { -+ spi1: spi@01c06000 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&spi1_pins_a>; -+ status = "okay"; -+ }; -+ -+ spi2: spi@01c17000 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&spi2_pins_a>; -+ status = "okay"; -+ }; -+ -+ mmc0: mmc@01c0f000 { -+ pinctrl-names = "default", "default"; -+ pinctrl-0 = <&mmc0_pins_a>; -+ pinctrl-1 = <&mmc0_cd_pin_reference_design>; -+ cd-gpios = <&pio 7 1 0>; /* PH1 */ -+ status = "okay"; -+ }; -+ -+ usbphy: phy@01c13400 { -+ usb1_vbus-supply = <®_usb1_vbus>; -+ usb2_vbus-supply = <®_usb2_vbus>; -+ status = "okay"; -+ }; -+ -+ ehci0: usb@01c14000 { -+ status = "okay"; -+ }; -+ -+ ohci0: usb@01c14400 { -+ status = "okay"; -+ }; -+ -+ ahci: sata@01c18000 { -+ target-supply = <®_ahci_5v>; -+ status = "okay"; -+ }; -+ -+ ehci1: usb@01c1c000 { -+ status = "okay"; -+ }; -+ -+ ohci1: usb@01c1c400 { -+ status = "okay"; -+ }; -+ -+ pinctrl@01c20800 { -+ led_pins_pcduino3: led_pins@0 { -+ allwinner,pins = "PH2"; -+ allwinner,function = "gpio_out"; -+ allwinner,drive = <1>; -+ allwinner,pull = <0>; -+ }; -+ }; -+ -+ lradc: lradc@01c22800 { -+ allwinner,chan0-step = <200>; -+ linux,chan0-keycodes = <KEY_VOLUMEUP KEY_VOLUMEDOWN -+ KEY_MENU KEY_SEARCH KEY_HOME -+ KEY_ESC KEY_ENTER>; -+ status = "okay"; -+ }; -+ -+ uart0: serial@01c28000 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&uart0_pins_a>; -+ status = "okay"; -+ }; -+ -+ uart6: serial@01c29800 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&uart6_pins_a>; -+ status = "okay"; -+ }; -+ -+ uart7: serial@01c29c00 { -+ pinctrl-names = "default"; -+ 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"; -+ }; -+ -+ gmac: ethernet@01c50000 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&gmac_pins_mii_a>; -+ phy = <&phy1>; -+ phy-mode = "mii"; -+ status = "okay"; -+ -+ phy1: ethernet-phy@1 { -+ reg = <1>; -+ }; -+ }; -+ }; -+ -+ leds { -+ compatible = "gpio-leds"; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&led_pins_pcduino3>; -+ -+ green { -+ label = "a20-pcduino:green:usr"; -+ gpios = <&pio 7 2 0>; -+ default-state = "on"; -+ }; -+ }; -+}; diff --git a/target/linux/sunxi/patches-3.14/301-dt-sun7i-update-pcduino3.patch b/target/linux/sunxi/patches-3.14/301-dt-sun7i-update-pcduino3.patch deleted file mode 100644 index 7dfc95a975..0000000000 --- a/target/linux/sunxi/patches-3.14/301-dt-sun7i-update-pcduino3.patch +++ /dev/null @@ -1,12 +0,0 @@ ---- a/arch/arm/boot/dts/sun7i-a20-pcduino3.dts -+++ b/arch/arm/boot/dts/sun7i-a20-pcduino3.dts -@@ -12,8 +12,7 @@ - - /dts-v1/; - /include/ "sun7i-a20.dtsi" --/include/ "sunxi-ahci-reg.dtsi" --/include/ "sun4i-a10-usb-vbus-reg.dtsi" -+/include/ "sunxi-common-regulators.dtsi" - #include <dt-bindings/input/input.h> - - / { diff --git a/target/linux/sunxi/patches-3.14/302-1-dt-sun7i-add-bananapi-Makefile.patch b/target/linux/sunxi/patches-3.14/302-1-dt-sun7i-add-bananapi-Makefile.patch deleted file mode 100644 index 88fad31536..0000000000 --- a/target/linux/sunxi/patches-3.14/302-1-dt-sun7i-add-bananapi-Makefile.patch +++ /dev/null @@ -1,10 +0,0 @@ ---- a/arch/arm/boot/dts/Makefile -+++ b/arch/arm/boot/dts/Makefile -@@ -290,6 +290,7 @@ dtb-$(CONFIG_ARCH_SUNXI) += \ - sun5i-a13-olinuxino.dtb \ - sun5i-a13-olinuxino-micro.dtb \ - sun6i-a31-colombus.dtb \ -+ sun7i-a20-bananapi.dtb \ - sun7i-a20-cubieboard2.dtb \ - sun7i-a20-cubietruck.dtb \ - sun7i-a20-olinuxino-micro.dtb \ diff --git a/target/linux/sunxi/patches-3.14/302-2-dt-sun7i-add-bananapi-dts.patch b/target/linux/sunxi/patches-3.14/302-2-dt-sun7i-add-bananapi-dts.patch deleted file mode 100644 index aea9992410..0000000000 --- a/target/linux/sunxi/patches-3.14/302-2-dt-sun7i-add-bananapi-dts.patch +++ /dev/null @@ -1,163 +0,0 @@ ---- /dev/null -+++ b/arch/arm/boot/dts/sun7i-a20-bananapi.dts -@@ -0,0 +1,160 @@ -+/* -+ * Copyright 2014 Zoltan HERPAI -+ * Zoltan HERPAI <wigyori@uid0.hu> -+ * -+ * 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/ "sun7i-a20.dtsi" -+/include/ "sunxi-ahci-reg.dtsi" -+/include/ "sun4i-a10-usb-vbus-reg.dtsi" -+#include <dt-bindings/input/input.h> -+ -+/ { -+ model = "Lemaker bananaPi"; -+ compatible = "lemaker,bananapi", "allwinner,sun7i-a20"; -+ -+ aliases { -+ spi0 = &spi1; -+ spi1 = &spi2; -+ }; -+ -+ soc@01c00000 { -+ spi1: spi@01c06000 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&spi1_pins_a>; -+ status = "okay"; -+ }; -+ -+ spi2: spi@01c17000 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&spi2_pins_a>; -+ status = "okay"; -+ }; -+ -+ mmc0: mmc@01c0f000 { -+ pinctrl-names = "default", "default"; -+ pinctrl-0 = <&mmc0_pins_a>; -+ pinctrl-1 = <&mmc0_cd_pin_bananapi>; -+ cd-gpios = <&pio 7 10 0>; /* PH10 */ -+ status = "okay"; -+ }; -+ -+ usbphy: phy@01c13400 { -+ usb1_vbus-supply = <®_usb1_vbus>; -+ usb2_vbus-supply = <®_usb2_vbus>; -+ status = "okay"; -+ }; -+ -+ ehci0: usb@01c14000 { -+ status = "okay"; -+ }; -+ -+ ohci0: usb@01c14400 { -+ status = "okay"; -+ }; -+ -+ ahci: sata@01c18000 { -+ target-supply = <®_ahci_5v>; -+ status = "okay"; -+ }; -+ -+ ehci1: usb@01c1c000 { -+ status = "okay"; -+ }; -+ -+ ohci1: usb@01c1c400 { -+ status = "okay"; -+ }; -+ -+ pinctrl@01c20800 { -+ led_pins_bananapi: led_pins@0 { -+ allwinner,pins = "PH24"; -+ allwinner,function = "gpio_out"; -+ allwinner,drive = <0>; -+ allwinner,pull = <0>; -+ }; -+ -+ mmc0_cd_pin_bananapi: mmc0_cd_pin@0 { -+ allwinner,pins = "PH10"; -+ allwinner,function = "gpio_in"; -+ allwinner,drive = <0>; -+ allwinner,pull = <1>; -+ }; -+ }; -+ -+ lradc: lradc@01c22800 { -+ allwinner,chan0-step = <200>; -+ linux,chan0-keycodes = <KEY_VOLUMEUP KEY_VOLUMEDOWN -+ KEY_MENU KEY_SEARCH KEY_HOME -+ KEY_ESC KEY_ENTER>; -+ status = "okay"; -+ }; -+ -+ uart0: serial@01c28000 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&uart0_pins_a>; -+ status = "okay"; -+ }; -+ -+ uart6: serial@01c29800 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&uart6_pins_a>; -+ status = "okay"; -+ }; -+ -+ uart7: serial@01c29c00 { -+ pinctrl-names = "default"; -+ 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"; -+ }; -+ -+ gmac: ethernet@01c50000 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&gmac_pins_mii_a>; -+ phy = <&phy1>; -+ phy-mode = "mii"; -+ status = "okay"; -+ -+ phy1: ethernet-phy@1 { -+ reg = <1>; -+ }; -+ }; -+ }; -+ -+ leds { -+ compatible = "gpio-leds"; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&led_pins_bananapi>; -+ -+ green { -+ label = "bananapi:green:usr"; -+ gpios = <&pio 7 24 0>; -+ linux,default-trigger = "heartbeat"; -+ }; -+ }; -+}; diff --git a/target/linux/sunxi/patches-3.14/303-dt-sun7i-update-bananapi.patch b/target/linux/sunxi/patches-3.14/303-dt-sun7i-update-bananapi.patch deleted file mode 100644 index 60ea0ebe88..0000000000 --- a/target/linux/sunxi/patches-3.14/303-dt-sun7i-update-bananapi.patch +++ /dev/null @@ -1,12 +0,0 @@ ---- a/arch/arm/boot/dts/sun7i-a20-bananapi.dts -+++ b/arch/arm/boot/dts/sun7i-a20-bananapi.dts -@@ -12,8 +12,7 @@ - - /dts-v1/; - /include/ "sun7i-a20.dtsi" --/include/ "sunxi-ahci-reg.dtsi" --/include/ "sun4i-a10-usb-vbus-reg.dtsi" -+/include/ "sunxi-common-regulators.dtsi" - #include <dt-bindings/input/input.h> - - / { diff --git a/target/linux/sunxi/patches-3.14/304-dt-sun7i-update-pcduino3-add-regulators.patch b/target/linux/sunxi/patches-3.14/304-dt-sun7i-update-pcduino3-add-regulators.patch deleted file mode 100644 index 619deaa644..0000000000 --- a/target/linux/sunxi/patches-3.14/304-dt-sun7i-update-pcduino3-add-regulators.patch +++ /dev/null @@ -1,20 +0,0 @@ ---- a/arch/arm/boot/dts/sun7i-a20-pcduino3.dts -+++ b/arch/arm/boot/dts/sun7i-a20-pcduino3.dts -@@ -149,4 +149,17 @@ - default-state = "on"; - }; - }; -+ -+ reg_ahci_5v: ahci-5v { -+ status = "okay"; -+ }; -+ -+ reg_usb1_vbus: usb1-vbus { -+ status = "okay"; -+ }; -+ -+ reg_usb2_vbus: usb2-vbus { -+ status = "okay"; -+ }; -+ - }; diff --git a/target/linux/sunxi/patches-3.14/305-dt-sun7i-update-bananapi-add-regulators.patch b/target/linux/sunxi/patches-3.14/305-dt-sun7i-update-bananapi-add-regulators.patch deleted file mode 100644 index 8eced4939a..0000000000 --- a/target/linux/sunxi/patches-3.14/305-dt-sun7i-update-bananapi-add-regulators.patch +++ /dev/null @@ -1,20 +0,0 @@ ---- a/arch/arm/boot/dts/sun7i-a20-bananapi.dts -+++ b/arch/arm/boot/dts/sun7i-a20-bananapi.dts -@@ -156,4 +156,17 @@ - default-state = "on"; - }; - }; -+ -+ reg_ahci_5v: ahci-5v { -+ status = "okay"; -+ }; -+ -+ reg_usb1_vbus: usb1-vbus { -+ status = "okay"; -+ }; -+ -+ reg_usb2_vbus: usb2-vbus { -+ status = "okay"; -+ }; -+ - }; diff --git a/target/linux/sunxi/patches-3.14/306-dt-sun7i-fix-gmac-on-bananapi.patch b/target/linux/sunxi/patches-3.14/306-dt-sun7i-fix-gmac-on-bananapi.patch deleted file mode 100644 index 19934eacbe..0000000000 --- a/target/linux/sunxi/patches-3.14/306-dt-sun7i-fix-gmac-on-bananapi.patch +++ /dev/null @@ -1,46 +0,0 @@ ---- a/arch/arm/boot/dts/sun7i-a20-bananapi.dts -+++ b/arch/arm/boot/dts/sun7i-a20-bananapi.dts -@@ -86,6 +86,13 @@ - allwinner,drive = <0>; - allwinner,pull = <1>; - }; -+ -+ gmac_power_pin_bananapi: gmac_power_pin@0 { -+ allwinner,pins = "PH23"; -+ allwinner,function = "gpio_out"; -+ allwinner,drive = <0>; -+ allwinner,pull = <0>; -+ }; - }; - - lradc: lradc@01c22800 { -@@ -134,9 +141,10 @@ - - gmac: ethernet@01c50000 { - pinctrl-names = "default"; -- pinctrl-0 = <&gmac_pins_mii_a>; -+ pinctrl-0 = <&gmac_pins_rgmii_a>; - phy = <&phy1>; -- phy-mode = "mii"; -+ phy-mode = "rgmii"; -+ phy-supply = <®_gmac_3v3>; - status = "okay"; - - phy1: ethernet-phy@1 { -@@ -169,4 +177,16 @@ - status = "okay"; - }; - -+ reg_gmac_3v3: gmac-3v3 { -+ compatible = "regulator-fixed"; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&gmac_power_pin_bananapi>; -+ regulator-name = "gmac-3v3"; -+ regulator-min-microvolt = <3300000>; -+ regulator-max-microvolt = <3300000>; -+ startup-delay-us = <50000>; -+ enable-active-high; -+ gpio = <&pio 7 23 0>; -+ status = "okay"; -+ }; - }; diff --git a/target/linux/sunxi/patches-3.14/307-dt-sun7i-add-axp209-to-bananapi.patch b/target/linux/sunxi/patches-3.14/307-dt-sun7i-add-axp209-to-bananapi.patch deleted file mode 100644 index fd8bfa549b..0000000000 --- a/target/linux/sunxi/patches-3.14/307-dt-sun7i-add-axp209-to-bananapi.patch +++ /dev/null @@ -1,17 +0,0 @@ ---- a/arch/arm/boot/dts/sun7i-a20-bananapi.dts -+++ b/arch/arm/boot/dts/sun7i-a20-bananapi.dts -@@ -125,6 +125,14 @@ - pinctrl-names = "default"; - pinctrl-0 = <&i2c0_pins_a>; - status = "okay"; -+ -+ axp: axp20x@34 { -+ reg = <0x34>; -+ interrupt-parent = <&nmi_intc>; -+ interrupts = <0 8>; -+ axp,system-power-controller; -+ /include/ "x-powers-axp209.dtsi" -+ }; - }; - - i2c1: i2c@01c2b000 { diff --git a/target/linux/sunxi/patches-3.14/308-dt-sun7i-add-axp209-to-pcduino3.patch b/target/linux/sunxi/patches-3.14/308-dt-sun7i-add-axp209-to-pcduino3.patch deleted file mode 100644 index e091bf07b9..0000000000 --- a/target/linux/sunxi/patches-3.14/308-dt-sun7i-add-axp209-to-pcduino3.patch +++ /dev/null @@ -1,17 +0,0 @@ ---- a/arch/arm/boot/dts/sun7i-a20-pcduino3.dts -+++ b/arch/arm/boot/dts/sun7i-a20-pcduino3.dts -@@ -111,6 +111,14 @@ - pinctrl-names = "default"; - pinctrl-0 = <&i2c0_pins_a>; - status = "okay"; -+ -+ axp: axp20x@34 { -+ reg = <0x34>; -+ interrupt-parent = <&nmi_intc>; -+ interrupts = <0 8>; -+ axp,system-power-controller; -+ /include/ "x-powers-axp209.dtsi" -+ }; - }; - - i2c1: i2c@01c2b000 { diff --git a/target/linux/sunxi/patches-3.14/309-dt-sun7i-add-ir-to-bananapi.patch b/target/linux/sunxi/patches-3.14/309-dt-sun7i-add-ir-to-bananapi.patch deleted file mode 100644 index 209b5ea5b0..0000000000 --- a/target/linux/sunxi/patches-3.14/309-dt-sun7i-add-ir-to-bananapi.patch +++ /dev/null @@ -1,32 +0,0 @@ -From 05cffcda932b0914d78a08891c13e61593a6ce02 Mon Sep 17 00:00:00 2001 -From: Alexander Bersenev <bay@hackerdom.ru> -Date: Mon, 9 Jun 2014 00:08:13 +0600 -Subject: [PATCH] ARM: sunxi: Enable IR controller on cubieboard 2 and - cubietruck in dts - -This patch enables two IR devices in dts: -- One IR device physically found on Cubieboard 2 -- One IR device physically found on Cubietruck - -Signed-off-by: Alexander Bersenev <bay@hackerdom.ru> -Signed-off-by: Alexsey Shestacov <wingrime@linux-sunxi.org> ---- - arch/arm/boot/dts/sun7i-a20-bananapi.dts | 6 ++++++ - arch/arm/boot/dts/sun7i-a20-cubietruck.dts | 6 ++++++ - 2 files changed, 12 insertions(+) - ---- a/arch/arm/boot/dts/sun7i-a20-bananapi.dts -+++ b/arch/arm/boot/dts/sun7i-a20-bananapi.dts -@@ -103,6 +103,12 @@ - status = "okay"; - }; - -+ ir0: ir@01c21800 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&ir0_pins_a>; -+ status = "okay"; -+ }; -+ - uart0: serial@01c28000 { - pinctrl-names = "default"; - pinctrl-0 = <&uart0_pins_a>; diff --git a/target/linux/sunxi/patches-3.14/310-dt-sun7i-add-a20-olinuxino-lime.patch b/target/linux/sunxi/patches-3.14/310-dt-sun7i-add-a20-olinuxino-lime.patch deleted file mode 100644 index 2406710575..0000000000 --- a/target/linux/sunxi/patches-3.14/310-dt-sun7i-add-a20-olinuxino-lime.patch +++ /dev/null @@ -1,159 +0,0 @@ -From a71b4438af8242f383906071205db95a8b8e7b6d Mon Sep 17 00:00:00 2001 -From: FUKAUMI Naoki <naobsd@gmail.com> -Date: Wed, 20 Aug 2014 14:25:03 +0900 -Subject: ARM: sun7i: Add support for Olimex A20-OLinuXino-LIME - -This patch adds support for Olimex A20-OLinuXino-LIME board. - -Signed-off-by: FUKAUMI Naoki <naobsd@gmail.com> -Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com> - ---- a/arch/arm/boot/dts/Makefile -+++ b/arch/arm/boot/dts/Makefile -@@ -293,6 +293,7 @@ dtb-$(CONFIG_ARCH_SUNXI) += \ - sun7i-a20-bananapi.dtb \ - sun7i-a20-cubieboard2.dtb \ - sun7i-a20-cubietruck.dtb \ -+ sun7i-a20-olinuxino-lime.dtb \ - sun7i-a20-olinuxino-micro.dtb \ - sun7i-a20-pcduino3.dtb - dtb-$(CONFIG_ARCH_TEGRA) += tegra20-harmony.dtb \ ---- /dev/null -+++ b/arch/arm/boot/dts/sun7i-a20-olinuxino-lime.dts -@@ -0,0 +1,136 @@ -+/* -+ * This is based on sun4i-a10-olinuxino-lime.dts -+ * -+ * Copyright 2014 - Hans de Goede <hdegoede@redhat.com> -+ * Copyright (c) 2014 FUKAUMI Naoki <naobsd@gmail.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/ "sun7i-a20.dtsi" -+/include/ "sunxi-common-regulators.dtsi" -+ -+/ { -+ model = "Olimex A20-OLinuXino-LIME"; -+ compatible = "olimex,a20-olinuxino-lime", "allwinner,sun7i-a20"; -+ -+ soc@01c00000 { -+ mmc0: mmc@01c0f000 { -+ pinctrl-names = "default", "default"; -+ pinctrl-0 = <&mmc0_pins_a>; -+ pinctrl-1 = <&mmc0_cd_pin_reference_design>; -+ cd-gpios = <&pio 7 1 0>; /* PH1 */ -+ cd-mode = <1>; -+ status = "okay"; -+ }; -+ -+ usbphy: phy@01c13400 { -+ usb1_vbus-supply = <®_usb1_vbus>; -+ usb2_vbus-supply = <®_usb2_vbus>; -+ status = "okay"; -+ }; -+ -+ ehci0: usb@01c14000 { -+ status = "okay"; -+ }; -+ -+ ohci0: usb@01c14400 { -+ status = "okay"; -+ }; -+ -+ ahci: sata@01c18000 { -+ target-supply = <®_ahci_5v>; -+ status = "okay"; -+ }; -+ -+ ehci1: usb@01c1c000 { -+ status = "okay"; -+ }; -+ -+ ohci1: usb@01c1c400 { -+ status = "okay"; -+ }; -+ -+ pinctrl@01c20800 { -+ ahci_pwr_pin_olinuxinolime: ahci_pwr_pin@1 { -+ allwinner,pins = "PC3"; -+ allwinner,function = "gpio_out"; -+ allwinner,drive = <0>; -+ allwinner,pull = <0>; -+ }; -+ -+ led_pins_olinuxinolime: led_pins@0 { -+ allwinner,pins = "PH2"; -+ allwinner,function = "gpio_out"; -+ allwinner,drive = <1>; -+ allwinner,pull = <0>; -+ }; -+ }; -+ -+ uart0: serial@01c28000 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&uart0_pins_a>; -+ status = "okay"; -+ }; -+ -+ i2c0: i2c@01c2ac00 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&i2c0_pins_a>; -+ status = "okay"; -+ -+ axp: axp20x@34 { -+ reg = <0x34>; -+ interrupt-parent = <&nmi_intc>; -+ interrupts = <0 8>; -+ -+ axp,system-power-controller; -+ -+ /include/ "x-powers-axp209.dtsi" -+ }; -+ }; -+ -+ gmac: ethernet@01c50000 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&gmac_pins_mii_a>; -+ phy = <&phy1>; -+ phy-mode = "mii"; -+ status = "okay"; -+ -+ phy1: ethernet-phy@1 { -+ reg = <1>; -+ }; -+ }; -+ }; -+ -+ leds { -+ compatible = "gpio-leds"; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&led_pins_olinuxinolime>; -+ -+ green { -+ label = "a20-olinuxino-lime:green:usr"; -+ gpios = <&pio 7 2 0>; -+ default-state = "on"; -+ }; -+ }; -+ -+ reg_ahci_5v: ahci-5v { -+ pinctrl-0 = <&ahci_pwr_pin_olinuxinolime>; -+ gpio = <&pio 2 3 0>; -+ status = "okay"; -+ }; -+ -+ reg_usb1_vbus: usb1-vbus { -+ status = "okay"; -+ }; -+ -+ reg_usb2_vbus: usb2-vbus { -+ status = "okay"; -+ }; -+}; |