diff --git a/target/linux/ipq806x/Makefile b/target/linux/ipq806x/Makefile
index 875bb9c..f07c87d 100644
--- a/target/linux/ipq806x/Makefile
+++ b/target/linux/ipq806x/Makefile
@@ -9,7 +9,7 @@ FEATURES:=squashfs
 CPU_TYPE:=cortex-a7
 MAINTAINER:=John Crispin <blogic@openwrt.org>
 
-KERNEL_PATCHVER:=3.14
+KERNEL_PATCHVER:=3.18
 
 KERNELNAME:=Image dtbs
 
diff --git a/target/linux/ipq806x/config-3.18 b/target/linux/ipq806x/config-3.18
new file mode 100644
index 0000000..d45862b
--- /dev/null
+++ b/target/linux/ipq806x/config-3.18
@@ -0,0 +1,369 @@
+CONFIG_ALIGNMENT_TRAP=y
+# CONFIG_AMBA_PL08X is not set
+# CONFIG_APM_EMULATION is not set
+CONFIG_APQ_GCC_8084=y
+CONFIG_APQ_MMCC_8084=y
+CONFIG_ARCH_BINFMT_ELF_RANDOMIZE_PIE=y
+CONFIG_ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE=y
+CONFIG_ARCH_HAS_SG_CHAIN=y
+CONFIG_ARCH_HAS_TICK_BROADCAST=y
+CONFIG_ARCH_HAVE_CUSTOM_GPIO_H=y
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
+CONFIG_ARCH_MIGHT_HAVE_PC_PARPORT=y
+CONFIG_ARCH_MSM8960=y
+CONFIG_ARCH_MSM8974=y
+CONFIG_ARCH_MSM8X60=y
+CONFIG_ARCH_MULTIPLATFORM=y
+# CONFIG_ARCH_MULTI_CPU_AUTO is not set
+CONFIG_ARCH_MULTI_V6_V7=y
+CONFIG_ARCH_MULTI_V7=y
+# CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED is not set
+CONFIG_ARCH_NR_GPIO=0
+CONFIG_ARCH_QCOM=y
+CONFIG_ARCH_REQUIRE_GPIOLIB=y
+# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
+# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
+CONFIG_ARCH_SUPPORTS_ATOMIC_RMW=y
+CONFIG_ARCH_SUPPORTS_UPROBES=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_ARCH_WANT_OPTIONAL_GPIOLIB=y
+CONFIG_ARM=y
+CONFIG_ARM_AMBA=y
+CONFIG_ARM_ARCH_TIMER=y
+CONFIG_ARM_ARCH_TIMER_EVTSTREAM=y
+CONFIG_ARM_CPU_SUSPEND=y
+CONFIG_ARM_GIC=y
+CONFIG_ARM_HAS_SG_CHAIN=y
+CONFIG_ARM_L1_CACHE_SHIFT=6
+CONFIG_ARM_L1_CACHE_SHIFT_6=y
+# CONFIG_ARM_LPAE is not set
+CONFIG_ARM_PATCH_PHYS_VIRT=y
+# CONFIG_ARM_SP805_WATCHDOG is not set
+CONFIG_ARM_THUMB=y
+# CONFIG_ARM_THUMBEE is not set
+CONFIG_ARM_UNWIND=y
+CONFIG_ARM_VIRT_EXT=y
+CONFIG_AUTO_ZRELADDR=y
+# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
+CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
+CONFIG_BOUNCE=y
+CONFIG_BUILD_BIN2C=y
+# CONFIG_CACHE_L2X0 is not set
+CONFIG_CLEANCACHE=y
+CONFIG_CLKDEV_LOOKUP=y
+CONFIG_CLKSRC_OF=y
+CONFIG_CLKSRC_QCOM=y
+CONFIG_CLONE_BACKWARDS=y
+CONFIG_COMMON_CLK=y
+CONFIG_COMMON_CLK_QCOM=y
+CONFIG_COMPACTION=y
+CONFIG_COREDUMP=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_PM=y
+CONFIG_CPU_RMAP=y
+CONFIG_CPU_TLB_V7=y
+CONFIG_CPU_V7=y
+CONFIG_CRC16=y
+# CONFIG_CRC32_SARWATE is not set
+CONFIG_CRC32_SLICEBY8=y
+CONFIG_CROSS_MEMORY_ATTACH=y
+# CONFIG_CRYPTO_SHA1_ARM_NEON is not set
+# CONFIG_CRYPTO_SHA512_ARM_NEON is not set
+CONFIG_CRYPTO_XZ=y
+CONFIG_DCACHE_WORD_ACCESS=y
+CONFIG_DEBUG_BUGVERBOSE=y
+CONFIG_DEBUG_GPIO=y
+CONFIG_DEBUG_LL_INCLUDE="mach/debug-macro.S"
+CONFIG_DEBUG_PREEMPT=y
+# CONFIG_DEBUG_UART_8250 is not set
+# CONFIG_DEBUG_UART_PL01X is not set
+# CONFIG_DEBUG_USER is not set
+CONFIG_DECOMPRESS_GZIP=y
+CONFIG_DMADEVICES=y
+CONFIG_DMA_ENGINE=y
+CONFIG_DMA_OF=y
+CONFIG_DMA_VIRTUAL_CHANNELS=y
+CONFIG_DTC=y
+# CONFIG_DW_DMAC_CORE is not set
+# CONFIG_DW_DMAC_PCI is not set
+CONFIG_DYNAMIC_DEBUG=y
+# CONFIG_EMAC_ROCKCHIP is not set
+CONFIG_FREEZER=y
+CONFIG_GENERIC_ALLOCATOR=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_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_GPIOLIB_IRQCHIP=y
+CONFIG_GPIO_DEVRES=y
+# CONFIG_GPIO_MSM_V2 is not set
+CONFIG_GPIO_SYSFS=y
+CONFIG_HANDLE_DOMAIN_IRQ=y
+CONFIG_HARDIRQS_SW_RESEND=y
+CONFIG_HAS_DMA=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT_MAP=y
+# CONFIG_HAVE_64BIT_ALIGNED_ACCESS is not set
+CONFIG_HAVE_ARCH_AUDITSYSCALL=y
+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_IDE=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_MOD_ARCH_SPECIFIC=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=y
+CONFIG_HOTPLUG_CPU=y
+CONFIG_HWMON=y
+CONFIG_HW_RANDOM=y
+CONFIG_HW_RANDOM_MSM=y
+CONFIG_HZ_FIXED=0
+CONFIG_I2C=y
+CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_COMPAT=y
+CONFIG_I2C_HELPER_AUTO=y
+CONFIG_I2C_QUP=y
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_IOMMU_API=y
+CONFIG_IOMMU_HELPER=y
+CONFIG_IOMMU_PGTABLES_L2=y
+CONFIG_IOMMU_SUPPORT=y
+CONFIG_IPQ_GCC_806X=y
+CONFIG_IRQCHIP=y
+CONFIG_IRQ_DOMAIN=y
+CONFIG_IRQ_FORCED_THREADING=y
+CONFIG_IRQ_WORK=y
+CONFIG_KERNFS=y
+# CONFIG_LEDS_REGULATOR is not set
+CONFIG_LIBFDT=y
+CONFIG_LOCKUP_DETECTOR=y
+CONFIG_LZO_COMPRESS=y
+CONFIG_LZO_DECOMPRESS=y
+CONFIG_MDIO_BITBANG=y
+CONFIG_MDIO_BOARDINFO=y
+CONFIG_MDIO_GPIO=y
+# CONFIG_MFD_SPMI_PMIC is not set
+CONFIG_MIGHT_HAVE_CACHE_L2X0=y
+CONFIG_MIGHT_HAVE_PCI=y
+CONFIG_MIGRATION=y
+CONFIG_MODULES_USE_ELF_REL=y
+CONFIG_MSM_GCC_8660=y
+CONFIG_MSM_GCC_8960=y
+CONFIG_MSM_GCC_8974=y
+CONFIG_MSM_IOMMU=y
+CONFIG_MSM_MMCC_8960=y
+CONFIG_MSM_MMCC_8974=y
+CONFIG_MTD_CMDLINE_PARTS=y
+CONFIG_MTD_SPLIT_SUPPORT=y
+CONFIG_MULTI_IRQ_HANDLER=y
+CONFIG_MUTEX_SPIN_ON_OWNER=y
+CONFIG_NEED_DMA_MAP_STATE=y
+CONFIG_NEON=y
+CONFIG_NET_FLOW_LIMIT=y
+CONFIG_NET_VENDOR_WIZNET=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_ADDRESS_PCI=y
+CONFIG_OF_EARLY_FLATTREE=y
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_GPIO=y
+CONFIG_OF_IOMMU=y
+CONFIG_OF_IRQ=y
+CONFIG_OF_MDIO=y
+CONFIG_OF_MTD=y
+CONFIG_OF_NET=y
+CONFIG_OF_PCI=y
+CONFIG_OF_PCI_IRQ=y
+CONFIG_OF_RESERVED_MEM=y
+CONFIG_OLD_SIGACTION=y
+CONFIG_OLD_SIGSUSPEND3=y
+CONFIG_PAGEFLAGS_EXTENDED=y
+CONFIG_PAGE_OFFSET=0xC0000000
+CONFIG_PCI=y
+CONFIG_PCI_MSI=y
+CONFIG_PERF_EVENTS=y
+CONFIG_PERF_USE_VMALLOC=y
+CONFIG_PHYLIB=y
+# CONFIG_PHY_QCOM_APQ8064_SATA is not set
+CONFIG_PHY_QCOM_IPQ806X_SATA=y
+CONFIG_PINCTRL=y
+CONFIG_PINCTRL_APQ8064=y
+# CONFIG_PINCTRL_APQ8084 is not set
+CONFIG_PINCTRL_IPQ8064=y
+CONFIG_PINCTRL_MSM=y
+# CONFIG_PINCTRL_MSM8960 is not set
+CONFIG_PINCTRL_MSM8X74=y
+# CONFIG_PL330_DMA is not set
+CONFIG_PM=y
+CONFIG_PM_CLK=y
+# CONFIG_PM_DEBUG is not set
+CONFIG_PM_SLEEP=y
+CONFIG_PM_SLEEP_SMP=y
+CONFIG_POWER_RESET=y
+# CONFIG_POWER_RESET_BRCMSTB is not set
+# CONFIG_POWER_RESET_GPIO is not set
+# CONFIG_POWER_RESET_GPIO_RESTART is not set
+# CONFIG_POWER_RESET_LTC2952 is not set
+CONFIG_POWER_RESET_MSM=y
+# CONFIG_POWER_RESET_SYSCON is not set
+CONFIG_POWER_SUPPLY=y
+CONFIG_PREEMPT=y
+CONFIG_PREEMPT_COUNT=y
+# CONFIG_PREEMPT_NONE is not set
+CONFIG_PREEMPT_RCU=y
+CONFIG_PRINTK_TIME=y
+CONFIG_PROC_PAGE_MONITOR=y
+CONFIG_QCOM_BAM_DMA=y
+CONFIG_QCOM_GSBI=y
+CONFIG_QCOM_SCM=y
+# CONFIG_QCOM_WDT is not set
+# CONFIG_RCU_BOOST is not set
+CONFIG_RCU_CPU_STALL_TIMEOUT=21
+CONFIG_RCU_CPU_STALL_VERBOSE=y
+CONFIG_RCU_STALL_COMMON=y
+CONFIG_RD_GZIP=y
+CONFIG_REGMAP=y
+CONFIG_REGMAP_MMIO=y
+CONFIG_REGULATOR=y
+# CONFIG_REGULATOR_DEBUG is not set
+# CONFIG_REGULATOR_USERSPACE_CONSUMER is not set
+CONFIG_RESET_CONTROLLER=y
+CONFIG_RFS_ACCEL=y
+CONFIG_RPS=y
+CONFIG_RTC_CLASS=y
+# CONFIG_RTC_DRV_CMOS is not set
+CONFIG_RWSEM_SPIN_ON_OWNER=y
+CONFIG_RWSEM_XCHGADD_ALGORITHM=y
+CONFIG_SCHED_HRTICK=y
+# CONFIG_SCSI_DMA is not set
+# CONFIG_SERIAL_AMBA_PL010 is not set
+# CONFIG_SERIAL_AMBA_PL011 is not set
+CONFIG_SERIAL_MSM=y
+CONFIG_SERIAL_MSM_CONSOLE=y
+# CONFIG_SLAB is not set
+CONFIG_SLUB=y
+CONFIG_SLUB_CPU_PARTIAL=y
+CONFIG_SMP=y
+CONFIG_SMP_ON_UP=y
+CONFIG_SPARSE_IRQ=y
+CONFIG_SPI=y
+CONFIG_SPI_MASTER=y
+CONFIG_SPI_QUP=y
+CONFIG_SPMI=y
+CONFIG_SPMI_MSM_PMIC_ARB=y
+CONFIG_STOP_MACHINE=y
+# CONFIG_STRIP_ASM_SYMS is not set
+CONFIG_SUSPEND=y
+CONFIG_SUSPEND_FREEZER=y
+CONFIG_SWCONFIG=y
+CONFIG_SWIOTLB=y
+CONFIG_SWP_EMULATE=y
+CONFIG_SYS_SUPPORTS_APM_EMULATION=y
+CONFIG_THERMAL=y
+# CONFIG_THERMAL_DEFAULT_GOV_FAIR_SHARE is not set
+CONFIG_THERMAL_DEFAULT_GOV_STEP_WISE=y
+# CONFIG_THERMAL_DEFAULT_GOV_USER_SPACE is not set
+# CONFIG_THERMAL_EMULATION is not set
+# CONFIG_THERMAL_GOV_FAIR_SHARE is not set
+CONFIG_THERMAL_GOV_STEP_WISE=y
+# CONFIG_THERMAL_GOV_USER_SPACE is not set
+CONFIG_THERMAL_HWMON=y
+CONFIG_THERMAL_OF=y
+# CONFIG_THUMB2_KERNEL is not set
+CONFIG_TICK_CPU_ACCOUNTING=y
+CONFIG_TIMER_STATS=y
+CONFIG_TREE_PREEMPT_RCU=y
+CONFIG_UEVENT_HELPER_PATH=""
+CONFIG_UID16=y
+CONFIG_UNCOMPRESS_INCLUDE="debug/uncompress.h"
+CONFIG_UNINLINE_SPIN_UNLOCK=y
+CONFIG_USE_OF=y
+CONFIG_VECTORS_BASE=0xffff0000
+# CONFIG_VFIO is not set
+CONFIG_VFP=y
+CONFIG_VFPv3=y
+CONFIG_VM_EVENT_COUNTERS=y
+# CONFIG_WIZNET_W5100 is not set
+# CONFIG_WIZNET_W5300 is not set
+# CONFIG_WL_TI is not set
+# CONFIG_WQ_POWER_EFFICIENT_DEFAULT is not set
+# CONFIG_XEN is not set
+CONFIG_XPS=y
+CONFIG_XZ_DEC_ARM=y
+CONFIG_XZ_DEC_BCJ=y
+CONFIG_ZBOOT_ROM_BSS=0
+CONFIG_ZBOOT_ROM_TEXT=0
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZONE_DMA_FLAG=0
diff --git a/target/linux/ipq806x/patches/0001-ARM-dts-msm-split-out-msm8660-and-msm8960-soc-into-d.patch b/target/linux/ipq806x/patches/0001-ARM-dts-msm-split-out-msm8660-and-msm8960-soc-into-d.patch
deleted file mode 100644
index 97c89b2..0000000
--- a/target/linux/ipq806x/patches/0001-ARM-dts-msm-split-out-msm8660-and-msm8960-soc-into-d.patch
+++ /dev/null
@@ -1,300 +0,0 @@
-From 3cdba35369b404875849008ea97cf1705e6060ed Mon Sep 17 00:00:00 2001
-From: Kumar Gala <galak@codeaurora.org>
-Date: Thu, 23 Jan 2014 14:09:54 -0600
-Subject: [PATCH 001/182] ARM: dts: msm: split out msm8660 and msm8960 soc
- into dts include
-
-Pull the SoC device tree bits into their own files so other boards based
-on these SoCs can include them and reduce duplication across a number of
-boards.
-
-Signed-off-by: Kumar Gala <galak@codeaurora.org>
----
- arch/arm/boot/dts/qcom-msm8660-surf.dts |   59 +-------------------------
- arch/arm/boot/dts/qcom-msm8660.dtsi     |   63 ++++++++++++++++++++++++++++
- arch/arm/boot/dts/qcom-msm8960-cdp.dts  |   66 +----------------------------
- arch/arm/boot/dts/qcom-msm8960.dtsi     |   70 +++++++++++++++++++++++++++++++
- 4 files changed, 135 insertions(+), 123 deletions(-)
- create mode 100644 arch/arm/boot/dts/qcom-msm8660.dtsi
- create mode 100644 arch/arm/boot/dts/qcom-msm8960.dtsi
-
---- a/arch/arm/boot/dts/qcom-msm8660-surf.dts
-+++ b/arch/arm/boot/dts/qcom-msm8660-surf.dts
-@@ -1,63 +1,6 @@
--/dts-v1/;
--
--/include/ "skeleton.dtsi"
--
--#include <dt-bindings/clock/qcom,gcc-msm8660.h>
-+#include "qcom-msm8660.dtsi"
- 
- / {
- 	model = "Qualcomm MSM8660 SURF";
- 	compatible = "qcom,msm8660-surf", "qcom,msm8660";
--	interrupt-parent = <&intc>;
--
--	intc: interrupt-controller@2080000 {
--		compatible = "qcom,msm-8660-qgic";
--		interrupt-controller;
--		#interrupt-cells = <3>;
--		reg = < 0x02080000 0x1000 >,
--		      < 0x02081000 0x1000 >;
--	};
--
--	timer@2000000 {
--		compatible = "qcom,scss-timer", "qcom,msm-timer";
--		interrupts = <1 0 0x301>,
--			     <1 1 0x301>,
--			     <1 2 0x301>;
--		reg = <0x02000000 0x100>;
--		clock-frequency = <27000000>,
--				  <32768>;
--		cpu-offset = <0x40000>;
--	};
--
--	msmgpio: gpio@800000 {
--		compatible = "qcom,msm-gpio";
--		reg = <0x00800000 0x4000>;
--		gpio-controller;
--		#gpio-cells = <2>;
--		ngpio = <173>;
--		interrupts = <0 16 0x4>;
--		interrupt-controller;
--		#interrupt-cells = <2>;
--	};
--
--	gcc: clock-controller@900000 {
--		compatible = "qcom,gcc-msm8660";
--		#clock-cells = <1>;
--		#reset-cells = <1>;
--		reg = <0x900000 0x4000>;
--	};
--
--	serial@19c40000 {
--		compatible = "qcom,msm-uartdm-v1.3", "qcom,msm-uartdm";
--		reg = <0x19c40000 0x1000>,
--		      <0x19c00000 0x1000>;
--		interrupts = <0 195 0x0>;
--		clocks = <&gcc GSBI12_UART_CLK>, <&gcc GSBI12_H_CLK>;
--		clock-names = "core", "iface";
--	};
--
--	qcom,ssbi@500000 {
--		compatible = "qcom,ssbi";
--		reg = <0x500000 0x1000>;
--		qcom,controller-type = "pmic-arbiter";
--	};
- };
---- /dev/null
-+++ b/arch/arm/boot/dts/qcom-msm8660.dtsi
-@@ -0,0 +1,63 @@
-+/dts-v1/;
-+
-+/include/ "skeleton.dtsi"
-+
-+#include <dt-bindings/clock/qcom,gcc-msm8660.h>
-+
-+/ {
-+	model = "Qualcomm MSM8660";
-+	compatible = "qcom,msm8660";
-+	interrupt-parent = <&intc>;
-+
-+	intc: interrupt-controller@2080000 {
-+		compatible = "qcom,msm-8660-qgic";
-+		interrupt-controller;
-+		#interrupt-cells = <3>;
-+		reg = < 0x02080000 0x1000 >,
-+		      < 0x02081000 0x1000 >;
-+	};
-+
-+	timer@2000000 {
-+		compatible = "qcom,scss-timer", "qcom,msm-timer";
-+		interrupts = <1 0 0x301>,
-+			     <1 1 0x301>,
-+			     <1 2 0x301>;
-+		reg = <0x02000000 0x100>;
-+		clock-frequency = <27000000>,
-+				  <32768>;
-+		cpu-offset = <0x40000>;
-+	};
-+
-+	msmgpio: gpio@800000 {
-+		compatible = "qcom,msm-gpio";
-+		reg = <0x00800000 0x4000>;
-+		gpio-controller;
-+		#gpio-cells = <2>;
-+		ngpio = <173>;
-+		interrupts = <0 16 0x4>;
-+		interrupt-controller;
-+		#interrupt-cells = <2>;
-+	};
-+
-+	gcc: clock-controller@900000 {
-+		compatible = "qcom,gcc-msm8660";
-+		#clock-cells = <1>;
-+		#reset-cells = <1>;
-+		reg = <0x900000 0x4000>;
-+	};
-+
-+	serial@19c40000 {
-+		compatible = "qcom,msm-uartdm-v1.3", "qcom,msm-uartdm";
-+		reg = <0x19c40000 0x1000>,
-+		      <0x19c00000 0x1000>;
-+		interrupts = <0 195 0x0>;
-+		clocks = <&gcc GSBI12_UART_CLK>, <&gcc GSBI12_H_CLK>;
-+		clock-names = "core", "iface";
-+	};
-+
-+	qcom,ssbi@500000 {
-+		compatible = "qcom,ssbi";
-+		reg = <0x500000 0x1000>;
-+		qcom,controller-type = "pmic-arbiter";
-+	};
-+};
---- a/arch/arm/boot/dts/qcom-msm8960-cdp.dts
-+++ b/arch/arm/boot/dts/qcom-msm8960-cdp.dts
-@@ -1,70 +1,6 @@
--/dts-v1/;
--
--/include/ "skeleton.dtsi"
--
--#include <dt-bindings/clock/qcom,gcc-msm8960.h>
-+#include "qcom-msm8960.dtsi"
- 
- / {
- 	model = "Qualcomm MSM8960 CDP";
- 	compatible = "qcom,msm8960-cdp", "qcom,msm8960";
--	interrupt-parent = <&intc>;
--
--	intc: interrupt-controller@2000000 {
--		compatible = "qcom,msm-qgic2";
--		interrupt-controller;
--		#interrupt-cells = <3>;
--		reg = < 0x02000000 0x1000 >,
--		      < 0x02002000 0x1000 >;
--	};
--
--	timer@200a000 {
--		compatible = "qcom,kpss-timer", "qcom,msm-timer";
--		interrupts = <1 1 0x301>,
--			     <1 2 0x301>,
--			     <1 3 0x301>;
--		reg = <0x0200a000 0x100>;
--		clock-frequency = <27000000>,
--				  <32768>;
--		cpu-offset = <0x80000>;
--	};
--
--	msmgpio: gpio@800000 {
--		compatible = "qcom,msm-gpio";
--		gpio-controller;
--		#gpio-cells = <2>;
--		ngpio = <150>;
--		interrupts = <0 16 0x4>;
--		interrupt-controller;
--		#interrupt-cells = <2>;
--		reg = <0x800000 0x4000>;
--	};
--
--	gcc: clock-controller@900000 {
--		compatible = "qcom,gcc-msm8960";
--		#clock-cells = <1>;
--		#reset-cells = <1>;
--		reg = <0x900000 0x4000>;
--	};
--
--	clock-controller@4000000 {
--		compatible = "qcom,mmcc-msm8960";
--		reg = <0x4000000 0x1000>;
--		#clock-cells = <1>;
--		#reset-cells = <1>;
--	};
--
--	serial@16440000 {
--		compatible = "qcom,msm-uartdm-v1.3", "qcom,msm-uartdm";
--		reg = <0x16440000 0x1000>,
--		      <0x16400000 0x1000>;
--		interrupts = <0 154 0x0>;
--		clocks = <&gcc GSBI5_UART_CLK>, <&gcc GSBI5_H_CLK>;
--		clock-names = "core", "iface";
--	};
--
--	qcom,ssbi@500000 {
--		compatible = "qcom,ssbi";
--		reg = <0x500000 0x1000>;
--		qcom,controller-type = "pmic-arbiter";
--	};
- };
---- /dev/null
-+++ b/arch/arm/boot/dts/qcom-msm8960.dtsi
-@@ -0,0 +1,70 @@
-+/dts-v1/;
-+
-+/include/ "skeleton.dtsi"
-+
-+#include <dt-bindings/clock/qcom,gcc-msm8960.h>
-+
-+/ {
-+	model = "Qualcomm MSM8960";
-+	compatible = "qcom,msm8960";
-+	interrupt-parent = <&intc>;
-+
-+	intc: interrupt-controller@2000000 {
-+		compatible = "qcom,msm-qgic2";
-+		interrupt-controller;
-+		#interrupt-cells = <3>;
-+		reg = < 0x02000000 0x1000 >,
-+		      < 0x02002000 0x1000 >;
-+	};
-+
-+	timer@200a000 {
-+		compatible = "qcom,kpss-timer", "qcom,msm-timer";
-+		interrupts = <1 1 0x301>,
-+			     <1 2 0x301>,
-+			     <1 3 0x301>;
-+		reg = <0x0200a000 0x100>;
-+		clock-frequency = <27000000>,
-+				  <32768>;
-+		cpu-offset = <0x80000>;
-+	};
-+
-+	msmgpio: gpio@800000 {
-+		compatible = "qcom,msm-gpio";
-+		gpio-controller;
-+		#gpio-cells = <2>;
-+		ngpio = <150>;
-+		interrupts = <0 16 0x4>;
-+		interrupt-controller;
-+		#interrupt-cells = <2>;
-+		reg = <0x800000 0x4000>;
-+	};
-+
-+	gcc: clock-controller@900000 {
-+		compatible = "qcom,gcc-msm8960";
-+		#clock-cells = <1>;
-+		#reset-cells = <1>;
-+		reg = <0x900000 0x4000>;
-+	};
-+
-+	clock-controller@4000000 {
-+		compatible = "qcom,mmcc-msm8960";
-+		reg = <0x4000000 0x1000>;
-+		#clock-cells = <1>;
-+		#reset-cells = <1>;
-+	};
-+
-+	serial@16440000 {
-+		compatible = "qcom,msm-uartdm-v1.3", "qcom,msm-uartdm";
-+		reg = <0x16440000 0x1000>,
-+		      <0x16400000 0x1000>;
-+		interrupts = <0 154 0x0>;
-+		clocks = <&gcc GSBI5_UART_CLK>, <&gcc GSBI5_H_CLK>;
-+		clock-names = "core", "iface";
-+	};
-+
-+	qcom,ssbi@500000 {
-+		compatible = "qcom,ssbi";
-+		reg = <0x500000 0x1000>;
-+		qcom,controller-type = "pmic-arbiter";
-+	};
-+};
diff --git a/target/linux/ipq806x/patches/0002-ARM-msm-Remove-pen_release-usage.patch b/target/linux/ipq806x/patches/0002-ARM-msm-Remove-pen_release-usage.patch
deleted file mode 100644
index 19eaae6..0000000
--- a/target/linux/ipq806x/patches/0002-ARM-msm-Remove-pen_release-usage.patch
+++ /dev/null
@@ -1,211 +0,0 @@
-From 18d53dfa103e63154fb8e548d55016d6ad210d28 Mon Sep 17 00:00:00 2001
-From: Rohit Vaswani <rvaswani@codeaurora.org>
-Date: Fri, 21 Jun 2013 12:17:37 -0700
-Subject: [PATCH 002/182] ARM: msm: Remove pen_release usage
-
-pen_release is no longer required as the synchronization
-is now managed by generic arm code.
-This is done as suggested in https://lkml.org/lkml/2013/6/4/184
-
-Cc: Russell King <linux@arm.linux.org.uk>
-Signed-off-by: Rohit Vaswani <rvaswani@codeaurora.org>
-Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
-Signed-off-by: Kumar Gala <galak@codeaurora.org>
----
- arch/arm/mach-msm/Makefile  |    2 +-
- arch/arm/mach-msm/headsmp.S |   39 ---------------------------------------
- arch/arm/mach-msm/hotplug.c |   31 ++++---------------------------
- arch/arm/mach-msm/platsmp.c |   37 +++----------------------------------
- 4 files changed, 8 insertions(+), 101 deletions(-)
- delete mode 100644 arch/arm/mach-msm/headsmp.S
-
---- a/arch/arm/mach-msm/Makefile
-+++ b/arch/arm/mach-msm/Makefile
-@@ -19,7 +19,7 @@ obj-$(CONFIG_MSM_SCM) += scm.o scm-boot.
- CFLAGS_scm.o :=$(call as-instr,.arch_extension sec,-DREQUIRES_SEC=1)
- 
- obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o
--obj-$(CONFIG_SMP) += headsmp.o platsmp.o
-+obj-$(CONFIG_SMP) += platsmp.o
- 
- obj-$(CONFIG_MACH_TROUT) += board-trout.o board-trout-gpio.o board-trout-mmc.o devices-msm7x00.o
- obj-$(CONFIG_MACH_TROUT) += board-trout.o board-trout-gpio.o board-trout-mmc.o board-trout-panel.o devices-msm7x00.o
---- a/arch/arm/mach-msm/headsmp.S
-+++ /dev/null
-@@ -1,39 +0,0 @@
--/*
-- *  linux/arch/arm/mach-realview/headsmp.S
-- *
-- *  Copyright (c) 2003 ARM Limited
-- *  All Rights Reserved
-- *
-- * 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/linkage.h>
--#include <linux/init.h>
--
--/*
-- * MSM specific entry point for secondary CPUs.  This provides
-- * a "holding pen" into which all secondary cores are held until we're
-- * ready for them to initialise.
-- */
--ENTRY(msm_secondary_startup)
--	mrc	p15, 0, r0, c0, c0, 5
--	and	r0, r0, #15
--	adr	r4, 1f
--	ldmia	r4, {r5, r6}
--	sub	r4, r4, r5
--	add	r6, r6, r4
--pen:	ldr	r7, [r6]
--	cmp	r7, r0
--	bne	pen
--
--	/*
--	 * we've been released from the holding pen: secondary_stack
--	 * should now contain the SVC stack for this core
--	 */
--	b	secondary_startup
--ENDPROC(msm_secondary_startup)
--
--	.align
--1:	.long	.
--	.long	pen_release
---- a/arch/arm/mach-msm/hotplug.c
-+++ b/arch/arm/mach-msm/hotplug.c
-@@ -24,33 +24,10 @@ static inline void cpu_leave_lowpower(vo
- 
- static inline void platform_do_lowpower(unsigned int cpu)
- {
--	/* Just enter wfi for now. TODO: Properly shut off the cpu. */
--	for (;;) {
--		/*
--		 * here's the WFI
--		 */
--		asm("wfi"
--		    :
--		    :
--		    : "memory", "cc");
--
--		if (pen_release == cpu_logical_map(cpu)) {
--			/*
--			 * OK, proper wakeup, we're done
--			 */
--			break;
--		}
--
--		/*
--		 * getting here, means that we have come out of WFI without
--		 * having been woken up - this shouldn't happen
--		 *
--		 * The trouble is, letting people know about this is not really
--		 * possible, since we are currently running incoherently, and
--		 * therefore cannot safely call printk() or anything else
--		 */
--		pr_debug("CPU%u: spurious wakeup call\n", cpu);
--	}
-+	asm("wfi"
-+	    :
-+	    :
-+	    : "memory", "cc");
- }
- 
- /*
---- a/arch/arm/mach-msm/platsmp.c
-+++ b/arch/arm/mach-msm/platsmp.c
-@@ -12,13 +12,10 @@
- #include <linux/errno.h>
- #include <linux/delay.h>
- #include <linux/device.h>
--#include <linux/jiffies.h>
- #include <linux/smp.h>
- #include <linux/io.h>
- 
--#include <asm/cacheflush.h>
- #include <asm/cputype.h>
--#include <asm/mach-types.h>
- #include <asm/smp_plat.h>
- 
- #include "scm-boot.h"
-@@ -28,7 +25,7 @@
- #define SCSS_CPU1CORE_RESET 0xD80
- #define SCSS_DBG_STATUS_CORE_PWRDUP 0xE64
- 
--extern void msm_secondary_startup(void);
-+extern void secondary_startup(void);
- 
- static DEFINE_SPINLOCK(boot_lock);
- 
-@@ -41,13 +38,6 @@ static inline int get_core_count(void)
- static void msm_secondary_init(unsigned int cpu)
- {
- 	/*
--	 * let the primary processor know we're out of the
--	 * pen, then head off into the C entry point
--	 */
--	pen_release = -1;
--	smp_wmb();
--
--	/*
- 	 * Synchronise with the boot thread.
- 	 */
- 	spin_lock(&boot_lock);
-@@ -57,7 +47,7 @@ static void msm_secondary_init(unsigned
- static void prepare_cold_cpu(unsigned int cpu)
- {
- 	int ret;
--	ret = scm_set_boot_addr(virt_to_phys(msm_secondary_startup),
-+	ret = scm_set_boot_addr(virt_to_phys(secondary_startup),
- 				SCM_FLAG_COLDBOOT_CPU1);
- 	if (ret == 0) {
- 		void __iomem *sc1_base_ptr;
-@@ -75,7 +65,6 @@ static void prepare_cold_cpu(unsigned in
- 
- static int msm_boot_secondary(unsigned int cpu, struct task_struct *idle)
- {
--	unsigned long timeout;
- 	static int cold_boot_done;
- 
- 	/* Only need to bring cpu out of reset this way once */
-@@ -91,39 +80,19 @@ static int msm_boot_secondary(unsigned i
- 	spin_lock(&boot_lock);
- 
- 	/*
--	 * The secondary processor is waiting to be released from
--	 * the holding pen - release it, then wait for it to flag
--	 * that it has been released by resetting pen_release.
--	 *
--	 * Note that "pen_release" is the hardware CPU ID, whereas
--	 * "cpu" is Linux's internal ID.
--	 */
--	pen_release = cpu_logical_map(cpu);
--	sync_cache_w(&pen_release);
--
--	/*
- 	 * Send the secondary CPU a soft interrupt, thereby causing
- 	 * the boot monitor to read the system wide flags register,
- 	 * and branch to the address found there.
- 	 */
- 	arch_send_wakeup_ipi_mask(cpumask_of(cpu));
- 
--	timeout = jiffies + (1 * HZ);
--	while (time_before(jiffies, timeout)) {
--		smp_rmb();
--		if (pen_release == -1)
--			break;
--
--		udelay(10);
--	}
--
- 	/*
- 	 * now the secondary core is starting up let it run its
- 	 * calibrations, then wait for it to finish
- 	 */
- 	spin_unlock(&boot_lock);
- 
--	return pen_release != -1 ? -ENOSYS : 0;
-+	return 0;
- }
- 
- /*
diff --git a/target/linux/ipq806x/patches/0003-ARM-msm-kill-off-hotplug.c.patch b/target/linux/ipq806x/patches/0003-ARM-msm-kill-off-hotplug.c.patch
deleted file mode 100644
index 79aa96f..0000000
--- a/target/linux/ipq806x/patches/0003-ARM-msm-kill-off-hotplug.c.patch
+++ /dev/null
@@ -1,108 +0,0 @@
-From b5a3a19e3efa6238c6a00a8f36a8ab2c25eeebc3 Mon Sep 17 00:00:00 2001
-From: Kumar Gala <galak@codeaurora.org>
-Date: Fri, 31 Jan 2014 13:48:29 -0600
-Subject: [PATCH 003/182] ARM: msm: kill off hotplug.c
-
-Right now hotplug.c only really implements msm_cpu_die as a wfi.  Just
-move that implementation into platsmp.c.  At the same time we use the
-existing wfi() instead of inline asm.
-
-Signed-off-by: Kumar Gala <galak@codeaurora.org>
----
- arch/arm/mach-msm/Makefile  |    1 -
- arch/arm/mach-msm/common.h  |    1 -
- arch/arm/mach-msm/hotplug.c |   51 -------------------------------------------
- arch/arm/mach-msm/platsmp.c |    7 ++++++
- 4 files changed, 7 insertions(+), 53 deletions(-)
- delete mode 100644 arch/arm/mach-msm/hotplug.c
-
---- a/arch/arm/mach-msm/Makefile
-+++ b/arch/arm/mach-msm/Makefile
-@@ -18,7 +18,6 @@ obj-$(CONFIG_MSM_SCM) += scm.o scm-boot.
- 
- CFLAGS_scm.o :=$(call as-instr,.arch_extension sec,-DREQUIRES_SEC=1)
- 
--obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o
- obj-$(CONFIG_SMP) += platsmp.o
- 
- obj-$(CONFIG_MACH_TROUT) += board-trout.o board-trout-gpio.o board-trout-mmc.o devices-msm7x00.o
---- a/arch/arm/mach-msm/common.h
-+++ b/arch/arm/mach-msm/common.h
-@@ -24,7 +24,6 @@ extern void __iomem *__msm_ioremap_calle
- 					  unsigned int mtype, void *caller);
- 
- extern struct smp_operations msm_smp_ops;
--extern void msm_cpu_die(unsigned int cpu);
- 
- struct msm_mmc_platform_data;
- 
---- a/arch/arm/mach-msm/hotplug.c
-+++ /dev/null
-@@ -1,51 +0,0 @@
--/*
-- *  Copyright (C) 2002 ARM Ltd.
-- *  All Rights Reserved
-- *
-- * 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/kernel.h>
--#include <linux/errno.h>
--#include <linux/smp.h>
--
--#include <asm/smp_plat.h>
--
--#include "common.h"
--
--static inline void cpu_enter_lowpower(void)
--{
--}
--
--static inline void cpu_leave_lowpower(void)
--{
--}
--
--static inline void platform_do_lowpower(unsigned int cpu)
--{
--	asm("wfi"
--	    :
--	    :
--	    : "memory", "cc");
--}
--
--/*
-- * platform-specific code to shutdown a CPU
-- *
-- * Called with IRQs disabled
-- */
--void __ref msm_cpu_die(unsigned int cpu)
--{
--	/*
--	 * we're ready for shutdown now, so do it
--	 */
--	cpu_enter_lowpower();
--	platform_do_lowpower(cpu);
--
--	/*
--	 * bring this CPU back into the world of cache
--	 * coherency, and then restore interrupts
--	 */
--	cpu_leave_lowpower();
--}
---- a/arch/arm/mach-msm/platsmp.c
-+++ b/arch/arm/mach-msm/platsmp.c
-@@ -29,6 +29,13 @@ extern void secondary_startup(void);
- 
- static DEFINE_SPINLOCK(boot_lock);
- 
-+#ifdef CONFIG_HOTPLUG_CPU
-+static void __ref msm_cpu_die(unsigned int cpu)
-+{
-+	wfi();
-+}
-+#endif
-+
- static inline int get_core_count(void)
- {
- 	/* 1 + the PART[1:0] field of MIDR */
diff --git a/target/linux/ipq806x/patches/0004-clocksource-qcom-Move-clocksource-code-out-of-mach-m.patch b/target/linux/ipq806x/patches/0004-clocksource-qcom-Move-clocksource-code-out-of-mach-m.patch
deleted file mode 100644
index c726d3f..0000000
--- a/target/linux/ipq806x/patches/0004-clocksource-qcom-Move-clocksource-code-out-of-mach-m.patch
+++ /dev/null
@@ -1,771 +0,0 @@
-From 00009eabeb2074bef5c89e576a7a6d827c12c3d9 Mon Sep 17 00:00:00 2001
-From: Kumar Gala <galak@codeaurora.org>
-Date: Wed, 29 Jan 2014 16:17:30 -0600
-Subject: [PATCH 004/182] clocksource: qcom: Move clocksource code out of
- mach-msm
-
-We intend to share the clocksource code for MSM platforms between legacy
-and multiplatform supported qcom SoCs.
-
-Acked-by: Olof Johansson <olof@lixom.net>
-Signed-off-by: Kumar Gala <galak@codeaurora.org>
----
- arch/arm/mach-msm/Kconfig        |   13 +-
- arch/arm/mach-msm/Makefile       |    1 -
- arch/arm/mach-msm/timer.c        |  333 --------------------------------------
- drivers/clocksource/Kconfig      |    3 +
- drivers/clocksource/Makefile     |    1 +
- drivers/clocksource/qcom-timer.c |  329 +++++++++++++++++++++++++++++++++++++
- 6 files changed, 338 insertions(+), 342 deletions(-)
- delete mode 100644 arch/arm/mach-msm/timer.c
- create mode 100644 drivers/clocksource/qcom-timer.c
-
---- a/arch/arm/mach-msm/Kconfig
-+++ b/arch/arm/mach-msm/Kconfig
-@@ -21,7 +21,7 @@ config ARCH_MSM8X60
- 	select CPU_V7
- 	select HAVE_SMP
- 	select MSM_SCM if SMP
--	select MSM_TIMER
-+	select CLKSRC_QCOM
- 
- config ARCH_MSM8960
- 	bool "Enable support for MSM8960"
-@@ -29,7 +29,7 @@ config ARCH_MSM8960
- 	select CPU_V7
- 	select HAVE_SMP
- 	select MSM_SCM if SMP
--	select MSM_TIMER
-+	select CLKSRC_QCOM
- 
- config ARCH_MSM8974
- 	bool "Enable support for MSM8974"
-@@ -54,7 +54,7 @@ config ARCH_MSM7X00A
- 	select MACH_TROUT if !MACH_HALIBUT
- 	select MSM_PROC_COMM
- 	select MSM_SMD
--	select MSM_TIMER
-+	select CLKSRC_QCOM
- 	select MSM_SMD_PKG3
- 
- config ARCH_MSM7X30
-@@ -66,7 +66,7 @@ config ARCH_MSM7X30
- 	select MSM_GPIOMUX
- 	select MSM_PROC_COMM
- 	select MSM_SMD
--	select MSM_TIMER
-+	select CLKSRC_QCOM
- 	select MSM_VIC
- 
- config ARCH_QSD8X50
-@@ -78,7 +78,7 @@ config ARCH_QSD8X50
- 	select MSM_GPIOMUX
- 	select MSM_PROC_COMM
- 	select MSM_SMD
--	select MSM_TIMER
-+	select CLKSRC_QCOM
- 	select MSM_VIC
- 
- endchoice
-@@ -153,7 +153,4 @@ config MSM_GPIOMUX
- config MSM_SCM
- 	bool
- 
--config MSM_TIMER
--	bool
--
- endif
---- a/arch/arm/mach-msm/Makefile
-+++ b/arch/arm/mach-msm/Makefile
-@@ -1,4 +1,3 @@
--obj-$(CONFIG_MSM_TIMER) += timer.o
- obj-$(CONFIG_MSM_PROC_COMM) += clock.o
- 
- obj-$(CONFIG_MSM_VIC) += irq-vic.o
---- a/arch/arm/mach-msm/timer.c
-+++ /dev/null
-@@ -1,333 +0,0 @@
--/*
-- *
-- * Copyright (C) 2007 Google, Inc.
-- * Copyright (c) 2009-2012, The Linux Foundation. All rights reserved.
-- *
-- * This software is licensed under the terms of the GNU General Public
-- * License version 2, as published by the Free Software Foundation, and
-- * may be copied, distributed, and modified under those terms.
-- *
-- * 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/clocksource.h>
--#include <linux/clockchips.h>
--#include <linux/cpu.h>
--#include <linux/init.h>
--#include <linux/interrupt.h>
--#include <linux/irq.h>
--#include <linux/io.h>
--#include <linux/of.h>
--#include <linux/of_address.h>
--#include <linux/of_irq.h>
--#include <linux/sched_clock.h>
--
--#include <asm/mach/time.h>
--
--#include "common.h"
--
--#define TIMER_MATCH_VAL			0x0000
--#define TIMER_COUNT_VAL			0x0004
--#define TIMER_ENABLE			0x0008
--#define TIMER_ENABLE_CLR_ON_MATCH_EN	BIT(1)
--#define TIMER_ENABLE_EN			BIT(0)
--#define TIMER_CLEAR			0x000C
--#define DGT_CLK_CTL			0x10
--#define DGT_CLK_CTL_DIV_4		0x3
--#define TIMER_STS_GPT0_CLR_PEND		BIT(10)
--
--#define GPT_HZ 32768
--
--#define MSM_DGT_SHIFT 5
--
--static void __iomem *event_base;
--static void __iomem *sts_base;
--
--static irqreturn_t msm_timer_interrupt(int irq, void *dev_id)
--{
--	struct clock_event_device *evt = dev_id;
--	/* Stop the timer tick */
--	if (evt->mode == CLOCK_EVT_MODE_ONESHOT) {
--		u32 ctrl = readl_relaxed(event_base + TIMER_ENABLE);
--		ctrl &= ~TIMER_ENABLE_EN;
--		writel_relaxed(ctrl, event_base + TIMER_ENABLE);
--	}
--	evt->event_handler(evt);
--	return IRQ_HANDLED;
--}
--
--static int msm_timer_set_next_event(unsigned long cycles,
--				    struct clock_event_device *evt)
--{
--	u32 ctrl = readl_relaxed(event_base + TIMER_ENABLE);
--
--	ctrl &= ~TIMER_ENABLE_EN;
--	writel_relaxed(ctrl, event_base + TIMER_ENABLE);
--
--	writel_relaxed(ctrl, event_base + TIMER_CLEAR);
--	writel_relaxed(cycles, event_base + TIMER_MATCH_VAL);
--
--	if (sts_base)
--		while (readl_relaxed(sts_base) & TIMER_STS_GPT0_CLR_PEND)
--			cpu_relax();
--
--	writel_relaxed(ctrl | TIMER_ENABLE_EN, event_base + TIMER_ENABLE);
--	return 0;
--}
--
--static void msm_timer_set_mode(enum clock_event_mode mode,
--			      struct clock_event_device *evt)
--{
--	u32 ctrl;
--
--	ctrl = readl_relaxed(event_base + TIMER_ENABLE);
--	ctrl &= ~(TIMER_ENABLE_EN | TIMER_ENABLE_CLR_ON_MATCH_EN);
--
--	switch (mode) {
--	case CLOCK_EVT_MODE_RESUME:
--	case CLOCK_EVT_MODE_PERIODIC:
--		break;
--	case CLOCK_EVT_MODE_ONESHOT:
--		/* Timer is enabled in set_next_event */
--		break;
--	case CLOCK_EVT_MODE_UNUSED:
--	case CLOCK_EVT_MODE_SHUTDOWN:
--		break;
--	}
--	writel_relaxed(ctrl, event_base + TIMER_ENABLE);
--}
--
--static struct clock_event_device __percpu *msm_evt;
--
--static void __iomem *source_base;
--
--static notrace cycle_t msm_read_timer_count(struct clocksource *cs)
--{
--	return readl_relaxed(source_base + TIMER_COUNT_VAL);
--}
--
--static notrace cycle_t msm_read_timer_count_shift(struct clocksource *cs)
--{
--	/*
--	 * Shift timer count down by a constant due to unreliable lower bits
--	 * on some targets.
--	 */
--	return msm_read_timer_count(cs) >> MSM_DGT_SHIFT;
--}
--
--static struct clocksource msm_clocksource = {
--	.name	= "dg_timer",
--	.rating	= 300,
--	.read	= msm_read_timer_count,
--	.mask	= CLOCKSOURCE_MASK(32),
--	.flags	= CLOCK_SOURCE_IS_CONTINUOUS,
--};
--
--static int msm_timer_irq;
--static int msm_timer_has_ppi;
--
--static int msm_local_timer_setup(struct clock_event_device *evt)
--{
--	int cpu = smp_processor_id();
--	int err;
--
--	evt->irq = msm_timer_irq;
--	evt->name = "msm_timer";
--	evt->features = CLOCK_EVT_FEAT_ONESHOT;
--	evt->rating = 200;
--	evt->set_mode = msm_timer_set_mode;
--	evt->set_next_event = msm_timer_set_next_event;
--	evt->cpumask = cpumask_of(cpu);
--
--	clockevents_config_and_register(evt, GPT_HZ, 4, 0xffffffff);
--
--	if (msm_timer_has_ppi) {
--		enable_percpu_irq(evt->irq, IRQ_TYPE_EDGE_RISING);
--	} else {
--		err = request_irq(evt->irq, msm_timer_interrupt,
--				IRQF_TIMER | IRQF_NOBALANCING |
--				IRQF_TRIGGER_RISING, "gp_timer", evt);
--		if (err)
--			pr_err("request_irq failed\n");
--	}
--
--	return 0;
--}
--
--static void msm_local_timer_stop(struct clock_event_device *evt)
--{
--	evt->set_mode(CLOCK_EVT_MODE_UNUSED, evt);
--	disable_percpu_irq(evt->irq);
--}
--
--static int msm_timer_cpu_notify(struct notifier_block *self,
--					   unsigned long action, void *hcpu)
--{
--	/*
--	 * Grab cpu pointer in each case to avoid spurious
--	 * preemptible warnings
--	 */
--	switch (action & ~CPU_TASKS_FROZEN) {
--	case CPU_STARTING:
--		msm_local_timer_setup(this_cpu_ptr(msm_evt));
--		break;
--	case CPU_DYING:
--		msm_local_timer_stop(this_cpu_ptr(msm_evt));
--		break;
--	}
--
--	return NOTIFY_OK;
--}
--
--static struct notifier_block msm_timer_cpu_nb = {
--	.notifier_call = msm_timer_cpu_notify,
--};
--
--static u64 notrace msm_sched_clock_read(void)
--{
--	return msm_clocksource.read(&msm_clocksource);
--}
--
--static void __init msm_timer_init(u32 dgt_hz, int sched_bits, int irq,
--				  bool percpu)
--{
--	struct clocksource *cs = &msm_clocksource;
--	int res = 0;
--
--	msm_timer_irq = irq;
--	msm_timer_has_ppi = percpu;
--
--	msm_evt = alloc_percpu(struct clock_event_device);
--	if (!msm_evt) {
--		pr_err("memory allocation failed for clockevents\n");
--		goto err;
--	}
--
--	if (percpu)
--		res = request_percpu_irq(irq, msm_timer_interrupt,
--					 "gp_timer", msm_evt);
--
--	if (res) {
--		pr_err("request_percpu_irq failed\n");
--	} else {
--		res = register_cpu_notifier(&msm_timer_cpu_nb);
--		if (res) {
--			free_percpu_irq(irq, msm_evt);
--			goto err;
--		}
--
--		/* Immediately configure the timer on the boot CPU */
--		msm_local_timer_setup(__this_cpu_ptr(msm_evt));
--	}
--
--err:
--	writel_relaxed(TIMER_ENABLE_EN, source_base + TIMER_ENABLE);
--	res = clocksource_register_hz(cs, dgt_hz);
--	if (res)
--		pr_err("clocksource_register failed\n");
--	sched_clock_register(msm_sched_clock_read, sched_bits, dgt_hz);
--}
--
--#ifdef CONFIG_OF
--static void __init msm_dt_timer_init(struct device_node *np)
--{
--	u32 freq;
--	int irq;
--	struct resource res;
--	u32 percpu_offset;
--	void __iomem *base;
--	void __iomem *cpu0_base;
--
--	base = of_iomap(np, 0);
--	if (!base) {
--		pr_err("Failed to map event base\n");
--		return;
--	}
--
--	/* We use GPT0 for the clockevent */
--	irq = irq_of_parse_and_map(np, 1);
--	if (irq <= 0) {
--		pr_err("Can't get irq\n");
--		return;
--	}
--
--	/* We use CPU0's DGT for the clocksource */
--	if (of_property_read_u32(np, "cpu-offset", &percpu_offset))
--		percpu_offset = 0;
--
--	if (of_address_to_resource(np, 0, &res)) {
--		pr_err("Failed to parse DGT resource\n");
--		return;
--	}
--
--	cpu0_base = ioremap(res.start + percpu_offset, resource_size(&res));
--	if (!cpu0_base) {
--		pr_err("Failed to map source base\n");
--		return;
--	}
--
--	if (of_property_read_u32(np, "clock-frequency", &freq)) {
--		pr_err("Unknown frequency\n");
--		return;
--	}
--
--	event_base = base + 0x4;
--	sts_base = base + 0x88;
--	source_base = cpu0_base + 0x24;
--	freq /= 4;
--	writel_relaxed(DGT_CLK_CTL_DIV_4, source_base + DGT_CLK_CTL);
--
--	msm_timer_init(freq, 32, irq, !!percpu_offset);
--}
--CLOCKSOURCE_OF_DECLARE(kpss_timer, "qcom,kpss-timer", msm_dt_timer_init);
--CLOCKSOURCE_OF_DECLARE(scss_timer, "qcom,scss-timer", msm_dt_timer_init);
--#endif
--
--static int __init msm_timer_map(phys_addr_t addr, u32 event, u32 source,
--				u32 sts)
--{
--	void __iomem *base;
--
--	base = ioremap(addr, SZ_256);
--	if (!base) {
--		pr_err("Failed to map timer base\n");
--		return -ENOMEM;
--	}
--	event_base = base + event;
--	source_base = base + source;
--	if (sts)
--		sts_base = base + sts;
--
--	return 0;
--}
--
--void __init msm7x01_timer_init(void)
--{
--	struct clocksource *cs = &msm_clocksource;
--
--	if (msm_timer_map(0xc0100000, 0x0, 0x10, 0x0))
--		return;
--	cs->read = msm_read_timer_count_shift;
--	cs->mask = CLOCKSOURCE_MASK((32 - MSM_DGT_SHIFT));
--	/* 600 KHz */
--	msm_timer_init(19200000 >> MSM_DGT_SHIFT, 32 - MSM_DGT_SHIFT, 7,
--			false);
--}
--
--void __init msm7x30_timer_init(void)
--{
--	if (msm_timer_map(0xc0100000, 0x4, 0x24, 0x80))
--		return;
--	msm_timer_init(24576000 / 4, 32, 1, false);
--}
--
--void __init qsd8x50_timer_init(void)
--{
--	if (msm_timer_map(0xAC100000, 0x0, 0x10, 0x34))
--		return;
--	msm_timer_init(19200000 / 4, 32, 7, false);
--}
---- a/drivers/clocksource/Kconfig
-+++ b/drivers/clocksource/Kconfig
-@@ -140,3 +140,6 @@ config VF_PIT_TIMER
- 	bool
- 	help
- 	  Support for Period Interrupt Timer on Freescale Vybrid Family SoCs.
-+
-+config CLKSRC_QCOM
-+	bool
---- a/drivers/clocksource/Makefile
-+++ b/drivers/clocksource/Makefile
-@@ -32,6 +32,7 @@ obj-$(CONFIG_CLKSRC_EFM32)	+= time-efm32
- obj-$(CONFIG_CLKSRC_EXYNOS_MCT)	+= exynos_mct.o
- obj-$(CONFIG_CLKSRC_SAMSUNG_PWM)	+= samsung_pwm_timer.o
- obj-$(CONFIG_VF_PIT_TIMER)	+= vf_pit_timer.o
-+obj-$(CONFIG_CLKSRC_QCOM)	+= qcom-timer.o
- 
- obj-$(CONFIG_ARM_ARCH_TIMER)		+= arm_arch_timer.o
- obj-$(CONFIG_ARM_GLOBAL_TIMER)		+= arm_global_timer.o
---- /dev/null
-+++ b/drivers/clocksource/qcom-timer.c
-@@ -0,0 +1,329 @@
-+/*
-+ *
-+ * Copyright (C) 2007 Google, Inc.
-+ * Copyright (c) 2009-2012,2014, The Linux Foundation. All rights reserved.
-+ *
-+ * This software is licensed under the terms of the GNU General Public
-+ * License version 2, as published by the Free Software Foundation, and
-+ * may be copied, distributed, and modified under those terms.
-+ *
-+ * 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/clocksource.h>
-+#include <linux/clockchips.h>
-+#include <linux/cpu.h>
-+#include <linux/init.h>
-+#include <linux/interrupt.h>
-+#include <linux/irq.h>
-+#include <linux/io.h>
-+#include <linux/of.h>
-+#include <linux/of_address.h>
-+#include <linux/of_irq.h>
-+#include <linux/sched_clock.h>
-+
-+#define TIMER_MATCH_VAL			0x0000
-+#define TIMER_COUNT_VAL			0x0004
-+#define TIMER_ENABLE			0x0008
-+#define TIMER_ENABLE_CLR_ON_MATCH_EN	BIT(1)
-+#define TIMER_ENABLE_EN			BIT(0)
-+#define TIMER_CLEAR			0x000C
-+#define DGT_CLK_CTL			0x10
-+#define DGT_CLK_CTL_DIV_4		0x3
-+#define TIMER_STS_GPT0_CLR_PEND		BIT(10)
-+
-+#define GPT_HZ 32768
-+
-+#define MSM_DGT_SHIFT 5
-+
-+static void __iomem *event_base;
-+static void __iomem *sts_base;
-+
-+static irqreturn_t msm_timer_interrupt(int irq, void *dev_id)
-+{
-+	struct clock_event_device *evt = dev_id;
-+	/* Stop the timer tick */
-+	if (evt->mode == CLOCK_EVT_MODE_ONESHOT) {
-+		u32 ctrl = readl_relaxed(event_base + TIMER_ENABLE);
-+		ctrl &= ~TIMER_ENABLE_EN;
-+		writel_relaxed(ctrl, event_base + TIMER_ENABLE);
-+	}
-+	evt->event_handler(evt);
-+	return IRQ_HANDLED;
-+}
-+
-+static int msm_timer_set_next_event(unsigned long cycles,
-+				    struct clock_event_device *evt)
-+{
-+	u32 ctrl = readl_relaxed(event_base + TIMER_ENABLE);
-+
-+	ctrl &= ~TIMER_ENABLE_EN;
-+	writel_relaxed(ctrl, event_base + TIMER_ENABLE);
-+
-+	writel_relaxed(ctrl, event_base + TIMER_CLEAR);
-+	writel_relaxed(cycles, event_base + TIMER_MATCH_VAL);
-+
-+	if (sts_base)
-+		while (readl_relaxed(sts_base) & TIMER_STS_GPT0_CLR_PEND)
-+			cpu_relax();
-+
-+	writel_relaxed(ctrl | TIMER_ENABLE_EN, event_base + TIMER_ENABLE);
-+	return 0;
-+}
-+
-+static void msm_timer_set_mode(enum clock_event_mode mode,
-+			      struct clock_event_device *evt)
-+{
-+	u32 ctrl;
-+
-+	ctrl = readl_relaxed(event_base + TIMER_ENABLE);
-+	ctrl &= ~(TIMER_ENABLE_EN | TIMER_ENABLE_CLR_ON_MATCH_EN);
-+
-+	switch (mode) {
-+	case CLOCK_EVT_MODE_RESUME:
-+	case CLOCK_EVT_MODE_PERIODIC:
-+		break;
-+	case CLOCK_EVT_MODE_ONESHOT:
-+		/* Timer is enabled in set_next_event */
-+		break;
-+	case CLOCK_EVT_MODE_UNUSED:
-+	case CLOCK_EVT_MODE_SHUTDOWN:
-+		break;
-+	}
-+	writel_relaxed(ctrl, event_base + TIMER_ENABLE);
-+}
-+
-+static struct clock_event_device __percpu *msm_evt;
-+
-+static void __iomem *source_base;
-+
-+static notrace cycle_t msm_read_timer_count(struct clocksource *cs)
-+{
-+	return readl_relaxed(source_base + TIMER_COUNT_VAL);
-+}
-+
-+static notrace cycle_t msm_read_timer_count_shift(struct clocksource *cs)
-+{
-+	/*
-+	 * Shift timer count down by a constant due to unreliable lower bits
-+	 * on some targets.
-+	 */
-+	return msm_read_timer_count(cs) >> MSM_DGT_SHIFT;
-+}
-+
-+static struct clocksource msm_clocksource = {
-+	.name	= "dg_timer",
-+	.rating	= 300,
-+	.read	= msm_read_timer_count,
-+	.mask	= CLOCKSOURCE_MASK(32),
-+	.flags	= CLOCK_SOURCE_IS_CONTINUOUS,
-+};
-+
-+static int msm_timer_irq;
-+static int msm_timer_has_ppi;
-+
-+static int msm_local_timer_setup(struct clock_event_device *evt)
-+{
-+	int cpu = smp_processor_id();
-+	int err;
-+
-+	evt->irq = msm_timer_irq;
-+	evt->name = "msm_timer";
-+	evt->features = CLOCK_EVT_FEAT_ONESHOT;
-+	evt->rating = 200;
-+	evt->set_mode = msm_timer_set_mode;
-+	evt->set_next_event = msm_timer_set_next_event;
-+	evt->cpumask = cpumask_of(cpu);
-+
-+	clockevents_config_and_register(evt, GPT_HZ, 4, 0xffffffff);
-+
-+	if (msm_timer_has_ppi) {
-+		enable_percpu_irq(evt->irq, IRQ_TYPE_EDGE_RISING);
-+	} else {
-+		err = request_irq(evt->irq, msm_timer_interrupt,
-+				IRQF_TIMER | IRQF_NOBALANCING |
-+				IRQF_TRIGGER_RISING, "gp_timer", evt);
-+		if (err)
-+			pr_err("request_irq failed\n");
-+	}
-+
-+	return 0;
-+}
-+
-+static void msm_local_timer_stop(struct clock_event_device *evt)
-+{
-+	evt->set_mode(CLOCK_EVT_MODE_UNUSED, evt);
-+	disable_percpu_irq(evt->irq);
-+}
-+
-+static int msm_timer_cpu_notify(struct notifier_block *self,
-+					   unsigned long action, void *hcpu)
-+{
-+	/*
-+	 * Grab cpu pointer in each case to avoid spurious
-+	 * preemptible warnings
-+	 */
-+	switch (action & ~CPU_TASKS_FROZEN) {
-+	case CPU_STARTING:
-+		msm_local_timer_setup(this_cpu_ptr(msm_evt));
-+		break;
-+	case CPU_DYING:
-+		msm_local_timer_stop(this_cpu_ptr(msm_evt));
-+		break;
-+	}
-+
-+	return NOTIFY_OK;
-+}
-+
-+static struct notifier_block msm_timer_cpu_nb = {
-+	.notifier_call = msm_timer_cpu_notify,
-+};
-+
-+static u64 notrace msm_sched_clock_read(void)
-+{
-+	return msm_clocksource.read(&msm_clocksource);
-+}
-+
-+static void __init msm_timer_init(u32 dgt_hz, int sched_bits, int irq,
-+				  bool percpu)
-+{
-+	struct clocksource *cs = &msm_clocksource;
-+	int res = 0;
-+
-+	msm_timer_irq = irq;
-+	msm_timer_has_ppi = percpu;
-+
-+	msm_evt = alloc_percpu(struct clock_event_device);
-+	if (!msm_evt) {
-+		pr_err("memory allocation failed for clockevents\n");
-+		goto err;
-+	}
-+
-+	if (percpu)
-+		res = request_percpu_irq(irq, msm_timer_interrupt,
-+					 "gp_timer", msm_evt);
-+
-+	if (res) {
-+		pr_err("request_percpu_irq failed\n");
-+	} else {
-+		res = register_cpu_notifier(&msm_timer_cpu_nb);
-+		if (res) {
-+			free_percpu_irq(irq, msm_evt);
-+			goto err;
-+		}
-+
-+		/* Immediately configure the timer on the boot CPU */
-+		msm_local_timer_setup(__this_cpu_ptr(msm_evt));
-+	}
-+
-+err:
-+	writel_relaxed(TIMER_ENABLE_EN, source_base + TIMER_ENABLE);
-+	res = clocksource_register_hz(cs, dgt_hz);
-+	if (res)
-+		pr_err("clocksource_register failed\n");
-+	sched_clock_register(msm_sched_clock_read, sched_bits, dgt_hz);
-+}
-+
-+#ifdef CONFIG_OF
-+static void __init msm_dt_timer_init(struct device_node *np)
-+{
-+	u32 freq;
-+	int irq;
-+	struct resource res;
-+	u32 percpu_offset;
-+	void __iomem *base;
-+	void __iomem *cpu0_base;
-+
-+	base = of_iomap(np, 0);
-+	if (!base) {
-+		pr_err("Failed to map event base\n");
-+		return;
-+	}
-+
-+	/* We use GPT0 for the clockevent */
-+	irq = irq_of_parse_and_map(np, 1);
-+	if (irq <= 0) {
-+		pr_err("Can't get irq\n");
-+		return;
-+	}
-+
-+	/* We use CPU0's DGT for the clocksource */
-+	if (of_property_read_u32(np, "cpu-offset", &percpu_offset))
-+		percpu_offset = 0;
-+
-+	if (of_address_to_resource(np, 0, &res)) {
-+		pr_err("Failed to parse DGT resource\n");
-+		return;
-+	}
-+
-+	cpu0_base = ioremap(res.start + percpu_offset, resource_size(&res));
-+	if (!cpu0_base) {
-+		pr_err("Failed to map source base\n");
-+		return;
-+	}
-+
-+	if (of_property_read_u32(np, "clock-frequency", &freq)) {
-+		pr_err("Unknown frequency\n");
-+		return;
-+	}
-+
-+	event_base = base + 0x4;
-+	sts_base = base + 0x88;
-+	source_base = cpu0_base + 0x24;
-+	freq /= 4;
-+	writel_relaxed(DGT_CLK_CTL_DIV_4, source_base + DGT_CLK_CTL);
-+
-+	msm_timer_init(freq, 32, irq, !!percpu_offset);
-+}
-+CLOCKSOURCE_OF_DECLARE(kpss_timer, "qcom,kpss-timer", msm_dt_timer_init);
-+CLOCKSOURCE_OF_DECLARE(scss_timer, "qcom,scss-timer", msm_dt_timer_init);
-+#endif
-+
-+static int __init msm_timer_map(phys_addr_t addr, u32 event, u32 source,
-+				u32 sts)
-+{
-+	void __iomem *base;
-+
-+	base = ioremap(addr, SZ_256);
-+	if (!base) {
-+		pr_err("Failed to map timer base\n");
-+		return -ENOMEM;
-+	}
-+	event_base = base + event;
-+	source_base = base + source;
-+	if (sts)
-+		sts_base = base + sts;
-+
-+	return 0;
-+}
-+
-+void __init msm7x01_timer_init(void)
-+{
-+	struct clocksource *cs = &msm_clocksource;
-+
-+	if (msm_timer_map(0xc0100000, 0x0, 0x10, 0x0))
-+		return;
-+	cs->read = msm_read_timer_count_shift;
-+	cs->mask = CLOCKSOURCE_MASK((32 - MSM_DGT_SHIFT));
-+	/* 600 KHz */
-+	msm_timer_init(19200000 >> MSM_DGT_SHIFT, 32 - MSM_DGT_SHIFT, 7,
-+			false);
-+}
-+
-+void __init msm7x30_timer_init(void)
-+{
-+	if (msm_timer_map(0xc0100000, 0x4, 0x24, 0x80))
-+		return;
-+	msm_timer_init(24576000 / 4, 32, 1, false);
-+}
-+
-+void __init qsd8x50_timer_init(void)
-+{
-+	if (msm_timer_map(0xAC100000, 0x0, 0x10, 0x34))
-+		return;
-+	msm_timer_init(19200000 / 4, 32, 7, false);
-+}
diff --git a/target/linux/ipq806x/patches/0005-ARM-qcom-Split-Qualcomm-support-into-legacy-and-mult.patch b/target/linux/ipq806x/patches/0005-ARM-qcom-Split-Qualcomm-support-into-legacy-and-mult.patch
deleted file mode 100644
index 4cd4c47..0000000
--- a/target/linux/ipq806x/patches/0005-ARM-qcom-Split-Qualcomm-support-into-legacy-and-mult.patch
+++ /dev/null
@@ -1,1423 +0,0 @@
-From 8c2a00c0129d6f718245f7a613c2bb28976b7973 Mon Sep 17 00:00:00 2001
-From: Kumar Gala <galak@codeaurora.org>
-Date: Tue, 21 Jan 2014 17:14:10 -0600
-Subject: [PATCH 005/182] ARM: qcom: Split Qualcomm support into legacy and
- multiplatform
-
-Introduce a new mach-qcom that will support SoCs that intend to be
-multiplatform compatible while keeping mach-msm to legacy SoC/board
-support that will not transition over to multiplatform.
-
-As part of this, we move support for MSM8X60, MSM8960 and MSM8974 over
-to mach-qcom.
-
-Signed-off-by: Kumar Gala <galak@codeaurora.org>
----
- MAINTAINERS                   |    8 ++
- arch/arm/Kconfig              |    7 +-
- arch/arm/Kconfig.debug        |    2 +-
- arch/arm/Makefile             |    1 +
- arch/arm/boot/dts/Makefile    |    6 +-
- arch/arm/mach-msm/Kconfig     |   45 +------
- arch/arm/mach-msm/Makefile    |    6 -
- arch/arm/mach-msm/board-dt.c  |   41 ------
- arch/arm/mach-msm/platsmp.c   |  137 -------------------
- arch/arm/mach-msm/scm-boot.c  |   39 ------
- arch/arm/mach-msm/scm-boot.h  |   22 ---
- arch/arm/mach-msm/scm.c       |  299 -----------------------------------------
- arch/arm/mach-msm/scm.h       |   25 ----
- arch/arm/mach-qcom/Kconfig    |   33 +++++
- arch/arm/mach-qcom/Makefile   |    5 +
- arch/arm/mach-qcom/board.c    |   40 ++++++
- arch/arm/mach-qcom/platsmp.c  |  137 +++++++++++++++++++
- arch/arm/mach-qcom/scm-boot.c |   39 ++++++
- arch/arm/mach-qcom/scm-boot.h |   22 +++
- arch/arm/mach-qcom/scm.c      |  299 +++++++++++++++++++++++++++++++++++++++++
- arch/arm/mach-qcom/scm.h      |   25 ++++
- 21 files changed, 619 insertions(+), 619 deletions(-)
- delete mode 100644 arch/arm/mach-msm/board-dt.c
- delete mode 100644 arch/arm/mach-msm/platsmp.c
- delete mode 100644 arch/arm/mach-msm/scm-boot.c
- delete mode 100644 arch/arm/mach-msm/scm-boot.h
- delete mode 100644 arch/arm/mach-msm/scm.c
- delete mode 100644 arch/arm/mach-msm/scm.h
- create mode 100644 arch/arm/mach-qcom/Kconfig
- create mode 100644 arch/arm/mach-qcom/Makefile
- create mode 100644 arch/arm/mach-qcom/board.c
- create mode 100644 arch/arm/mach-qcom/platsmp.c
- create mode 100644 arch/arm/mach-qcom/scm-boot.c
- create mode 100644 arch/arm/mach-qcom/scm-boot.h
- create mode 100644 arch/arm/mach-qcom/scm.c
- create mode 100644 arch/arm/mach-qcom/scm.h
-
---- a/MAINTAINERS
-+++ b/MAINTAINERS
-@@ -1168,6 +1168,14 @@ L:	linux-arm-kernel@lists.infradead.org
- W:	http://www.arm.linux.org.uk/
- S:	Maintained
- 
-+ARM/QUALCOMM SUPPORT
-+M:	Kumar Gala <galak@codeaurora.org>
-+M:	David Brown <davidb@codeaurora.org>
-+L:	linux-arm-msm@vger.kernel.org
-+S:	Maintained
-+F:	arch/arm/mach-qcom/
-+T:	git git://git.kernel.org/pub/scm/linux/kernel/git/galak/linux-qcom.git
-+
- ARM/RADISYS ENP2611 MACHINE SUPPORT
- M:	Lennert Buytenhek <kernel@wantstofly.org>
- L:	linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
---- a/arch/arm/Kconfig
-+++ b/arch/arm/Kconfig
-@@ -658,9 +658,8 @@ config ARCH_PXA
- 	help
- 	  Support for Intel/Marvell's PXA2xx/PXA3xx processor line.
- 
--config ARCH_MSM_NODT
--	bool "Qualcomm MSM"
--	select ARCH_MSM
-+config ARCH_MSM
-+	bool "Qualcomm MSM (non-multiplatform)"
- 	select ARCH_REQUIRE_GPIOLIB
- 	select COMMON_CLK
- 	select GENERIC_CLOCKEVENTS
-@@ -1006,6 +1005,8 @@ source "arch/arm/plat-pxa/Kconfig"
- 
- source "arch/arm/mach-mmp/Kconfig"
- 
-+source "arch/arm/mach-qcom/Kconfig"
-+
- source "arch/arm/mach-realview/Kconfig"
- 
- source "arch/arm/mach-rockchip/Kconfig"
---- a/arch/arm/Kconfig.debug
-+++ b/arch/arm/Kconfig.debug
-@@ -956,7 +956,7 @@ config DEBUG_STI_UART
- 
- config DEBUG_MSM_UART
- 	bool
--	depends on ARCH_MSM
-+	depends on ARCH_MSM || ARCH_QCOM
- 
- config DEBUG_LL_INCLUDE
- 	string
---- a/arch/arm/Makefile
-+++ b/arch/arm/Makefile
-@@ -185,6 +185,7 @@ machine-$(CONFIG_ARCH_OMAP2PLUS)	+= omap
- machine-$(CONFIG_ARCH_ORION5X)		+= orion5x
- machine-$(CONFIG_ARCH_PICOXCELL)	+= picoxcell
- machine-$(CONFIG_ARCH_PXA)		+= pxa
-+machine-$(CONFIG_ARCH_QCOM)		+= qcom
- machine-$(CONFIG_ARCH_REALVIEW)		+= realview
- machine-$(CONFIG_ARCH_ROCKCHIP)		+= rockchip
- machine-$(CONFIG_ARCH_RPC)		+= rpc
---- a/arch/arm/boot/dts/Makefile
-+++ b/arch/arm/boot/dts/Makefile
-@@ -119,9 +119,6 @@ dtb-$(CONFIG_ARCH_KIRKWOOD) += kirkwood-
- 	kirkwood-ts219-6282.dtb
- dtb-$(CONFIG_ARCH_MARCO) += marco-evb.dtb
- dtb-$(CONFIG_ARCH_MOXART) += moxart-uc7112lx.dtb
--dtb-$(CONFIG_ARCH_MSM) += qcom-msm8660-surf.dtb \
--	qcom-msm8960-cdp.dtb \
--	qcom-apq8074-dragonboard.dtb
- dtb-$(CONFIG_ARCH_MVEBU) += armada-370-db.dtb \
- 	armada-370-mirabox.dtb \
- 	armada-370-netgear-rn102.dtb \
-@@ -234,6 +231,9 @@ dtb-$(CONFIG_ARCH_OMAP2PLUS) += omap2420
- 	dra7-evm.dtb
- dtb-$(CONFIG_ARCH_ORION5X) += orion5x-lacie-ethernet-disk-mini-v2.dtb
- dtb-$(CONFIG_ARCH_PRIMA2) += prima2-evb.dtb
-+dtb-$(CONFIG_ARCH_QCOM) += qcom-msm8660-surf.dtb \
-+	qcom-msm8960-cdp.dtb \
-+	qcom-apq8074-dragonboard.dtb
- dtb-$(CONFIG_ARCH_U8500) += ste-snowball.dtb \
- 	ste-hrefprev60-stuib.dtb \
- 	ste-hrefprev60-tvk.dtb \
---- a/arch/arm/mach-msm/Kconfig
-+++ b/arch/arm/mach-msm/Kconfig
-@@ -1,50 +1,9 @@
--config ARCH_MSM
--	bool
--
--config ARCH_MSM_DT
--	bool "Qualcomm MSM DT Support" if ARCH_MULTI_V7
--	select ARCH_MSM
--	select ARCH_REQUIRE_GPIOLIB
--	select CLKSRC_OF
--	select GENERIC_CLOCKEVENTS
--	help
--	  Support for Qualcomm's devicetree based MSM systems.
--
- if ARCH_MSM
- 
--menu "Qualcomm MSM SoC Selection"
--	depends on ARCH_MSM_DT
--
--config ARCH_MSM8X60
--	bool "Enable support for MSM8X60"
--	select ARM_GIC
--	select CPU_V7
--	select HAVE_SMP
--	select MSM_SCM if SMP
--	select CLKSRC_QCOM
--
--config ARCH_MSM8960
--	bool "Enable support for MSM8960"
--	select ARM_GIC
--	select CPU_V7
--	select HAVE_SMP
--	select MSM_SCM if SMP
--	select CLKSRC_QCOM
--
--config ARCH_MSM8974
--	bool "Enable support for MSM8974"
--	select ARM_GIC
--	select CPU_V7
--	select HAVE_ARM_ARCH_TIMER
--	select HAVE_SMP
--	select MSM_SCM if SMP
--
--endmenu
--
- choice
- 	prompt "Qualcomm MSM SoC Type"
- 	default ARCH_MSM7X00A
--	depends on ARCH_MSM_NODT
-+	depends on ARCH_MSM
- 
- config ARCH_MSM7X00A
- 	bool "MSM7x00A / MSM7x01A"
-@@ -99,7 +58,7 @@ config  MSM_VIC
- 	bool
- 
- menu "Qualcomm MSM Board Type"
--	depends on ARCH_MSM_NODT
-+	depends on ARCH_MSM
- 
- config MACH_HALIBUT
- 	depends on ARCH_MSM
---- a/arch/arm/mach-msm/Makefile
-+++ b/arch/arm/mach-msm/Makefile
-@@ -13,17 +13,11 @@ obj-$(CONFIG_ARCH_QSD8X50) += dma.o io.o
- 
- obj-$(CONFIG_MSM_SMD) += smd.o smd_debug.o
- obj-$(CONFIG_MSM_SMD) += last_radio_log.o
--obj-$(CONFIG_MSM_SCM) += scm.o scm-boot.o
--
--CFLAGS_scm.o :=$(call as-instr,.arch_extension sec,-DREQUIRES_SEC=1)
--
--obj-$(CONFIG_SMP) += platsmp.o
- 
- obj-$(CONFIG_MACH_TROUT) += board-trout.o board-trout-gpio.o board-trout-mmc.o devices-msm7x00.o
- obj-$(CONFIG_MACH_TROUT) += board-trout.o board-trout-gpio.o board-trout-mmc.o board-trout-panel.o devices-msm7x00.o
- obj-$(CONFIG_MACH_HALIBUT) += board-halibut.o devices-msm7x00.o
- obj-$(CONFIG_ARCH_MSM7X30) += board-msm7x30.o devices-msm7x30.o
- obj-$(CONFIG_ARCH_QSD8X50) += board-qsd8x50.o devices-qsd8x50.o
--obj-$(CONFIG_ARCH_MSM_DT) += board-dt.o
- obj-$(CONFIG_MSM_GPIOMUX) += gpiomux.o
- obj-$(CONFIG_ARCH_QSD8X50) += gpiomux-8x50.o
---- a/arch/arm/mach-msm/board-dt.c
-+++ /dev/null
-@@ -1,41 +0,0 @@
--/* Copyright (c) 2010-2012,2013 The Linux Foundation. All rights reserved.
-- *
-- * This program is free software; you can redistribute it and/or modify
-- * it under the terms of the GNU General Public License version 2 and
-- * only version 2 as published by the Free Software Foundation.
-- *
-- * 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/init.h>
--#include <linux/of.h>
--#include <linux/of_platform.h>
--
--#include <asm/mach/arch.h>
--#include <asm/mach/map.h>
--
--#include "common.h"
--
--static const char * const msm_dt_match[] __initconst = {
--	"qcom,msm8660-fluid",
--	"qcom,msm8660-surf",
--	"qcom,msm8960-cdp",
--	NULL
--};
--
--static const char * const apq8074_dt_match[] __initconst = {
--	"qcom,apq8074-dragonboard",
--	NULL
--};
--
--DT_MACHINE_START(MSM_DT, "Qualcomm MSM (Flattened Device Tree)")
--	.smp = smp_ops(msm_smp_ops),
--	.dt_compat = msm_dt_match,
--MACHINE_END
--
--DT_MACHINE_START(APQ_DT, "Qualcomm MSM (Flattened Device Tree)")
--	.dt_compat = apq8074_dt_match,
--MACHINE_END
---- a/arch/arm/mach-msm/platsmp.c
-+++ /dev/null
-@@ -1,137 +0,0 @@
--/*
-- *  Copyright (C) 2002 ARM Ltd.
-- *  All Rights Reserved
-- *  Copyright (c) 2010, Code Aurora Forum. All rights reserved.
-- *
-- * 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/init.h>
--#include <linux/errno.h>
--#include <linux/delay.h>
--#include <linux/device.h>
--#include <linux/smp.h>
--#include <linux/io.h>
--
--#include <asm/cputype.h>
--#include <asm/smp_plat.h>
--
--#include "scm-boot.h"
--#include "common.h"
--
--#define VDD_SC1_ARRAY_CLAMP_GFS_CTL 0x15A0
--#define SCSS_CPU1CORE_RESET 0xD80
--#define SCSS_DBG_STATUS_CORE_PWRDUP 0xE64
--
--extern void secondary_startup(void);
--
--static DEFINE_SPINLOCK(boot_lock);
--
--#ifdef CONFIG_HOTPLUG_CPU
--static void __ref msm_cpu_die(unsigned int cpu)
--{
--	wfi();
--}
--#endif
--
--static inline int get_core_count(void)
--{
--	/* 1 + the PART[1:0] field of MIDR */
--	return ((read_cpuid_id() >> 4) & 3) + 1;
--}
--
--static void msm_secondary_init(unsigned int cpu)
--{
--	/*
--	 * Synchronise with the boot thread.
--	 */
--	spin_lock(&boot_lock);
--	spin_unlock(&boot_lock);
--}
--
--static void prepare_cold_cpu(unsigned int cpu)
--{
--	int ret;
--	ret = scm_set_boot_addr(virt_to_phys(secondary_startup),
--				SCM_FLAG_COLDBOOT_CPU1);
--	if (ret == 0) {
--		void __iomem *sc1_base_ptr;
--		sc1_base_ptr = ioremap_nocache(0x00902000, SZ_4K*2);
--		if (sc1_base_ptr) {
--			writel(0, sc1_base_ptr + VDD_SC1_ARRAY_CLAMP_GFS_CTL);
--			writel(0, sc1_base_ptr + SCSS_CPU1CORE_RESET);
--			writel(3, sc1_base_ptr + SCSS_DBG_STATUS_CORE_PWRDUP);
--			iounmap(sc1_base_ptr);
--		}
--	} else
--		printk(KERN_DEBUG "Failed to set secondary core boot "
--				  "address\n");
--}
--
--static int msm_boot_secondary(unsigned int cpu, struct task_struct *idle)
--{
--	static int cold_boot_done;
--
--	/* Only need to bring cpu out of reset this way once */
--	if (cold_boot_done == false) {
--		prepare_cold_cpu(cpu);
--		cold_boot_done = true;
--	}
--
--	/*
--	 * set synchronisation state between this boot processor
--	 * and the secondary one
--	 */
--	spin_lock(&boot_lock);
--
--	/*
--	 * Send the secondary CPU a soft interrupt, thereby causing
--	 * the boot monitor to read the system wide flags register,
--	 * and branch to the address found there.
--	 */
--	arch_send_wakeup_ipi_mask(cpumask_of(cpu));
--
--	/*
--	 * now the secondary core is starting up let it run its
--	 * calibrations, then wait for it to finish
--	 */
--	spin_unlock(&boot_lock);
--
--	return 0;
--}
--
--/*
-- * Initialise the CPU possible map early - this describes the CPUs
-- * which may be present or become present in the system. The msm8x60
-- * does not support the ARM SCU, so just set the possible cpu mask to
-- * NR_CPUS.
-- */
--static void __init msm_smp_init_cpus(void)
--{
--	unsigned int i, ncores = get_core_count();
--
--	if (ncores > nr_cpu_ids) {
--		pr_warn("SMP: %u cores greater than maximum (%u), clipping\n",
--			ncores, nr_cpu_ids);
--		ncores = nr_cpu_ids;
--	}
--
--	for (i = 0; i < ncores; i++)
--		set_cpu_possible(i, true);
--}
--
--static void __init msm_smp_prepare_cpus(unsigned int max_cpus)
--{
--}
--
--struct smp_operations msm_smp_ops __initdata = {
--	.smp_init_cpus		= msm_smp_init_cpus,
--	.smp_prepare_cpus	= msm_smp_prepare_cpus,
--	.smp_secondary_init	= msm_secondary_init,
--	.smp_boot_secondary	= msm_boot_secondary,
--#ifdef CONFIG_HOTPLUG_CPU
--	.cpu_die		= msm_cpu_die,
--#endif
--};
---- a/arch/arm/mach-msm/scm-boot.c
-+++ /dev/null
-@@ -1,39 +0,0 @@
--/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
-- *
-- * This program is free software; you can redistribute it and/or modify
-- * it under the terms of the GNU General Public License version 2 and
-- * only version 2 as published by the Free Software Foundation.
-- *
-- * This program is distributed in the hope that it will be useful,
-- * but WITHOUT ANY WARRANTY; without even the implied warranty of
-- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-- * GNU General Public License for more details.
-- *
-- * You should have received a copy of the GNU General Public License
-- * along with this program; if not, write to the Free Software
-- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
-- * 02110-1301, USA.
-- */
--
--#include <linux/module.h>
--#include <linux/slab.h>
--
--#include "scm.h"
--#include "scm-boot.h"
--
--/*
-- * Set the cold/warm boot address for one of the CPU cores.
-- */
--int scm_set_boot_addr(phys_addr_t addr, int flags)
--{
--	struct {
--		unsigned int flags;
--		phys_addr_t  addr;
--	} cmd;
--
--	cmd.addr = addr;
--	cmd.flags = flags;
--	return scm_call(SCM_SVC_BOOT, SCM_BOOT_ADDR,
--			&cmd, sizeof(cmd), NULL, 0);
--}
--EXPORT_SYMBOL(scm_set_boot_addr);
---- a/arch/arm/mach-msm/scm-boot.h
-+++ /dev/null
-@@ -1,22 +0,0 @@
--/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
-- *
-- * This program is free software; you can redistribute it and/or modify
-- * it under the terms of the GNU General Public License version 2 and
-- * only version 2 as published by the Free Software Foundation.
-- *
-- * 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 __MACH_SCM_BOOT_H
--#define __MACH_SCM_BOOT_H
--
--#define SCM_BOOT_ADDR			0x1
--#define SCM_FLAG_COLDBOOT_CPU1		0x1
--#define SCM_FLAG_WARMBOOT_CPU1		0x2
--#define SCM_FLAG_WARMBOOT_CPU0		0x4
--
--int scm_set_boot_addr(phys_addr_t addr, int flags);
--
--#endif
---- a/arch/arm/mach-msm/scm.c
-+++ /dev/null
-@@ -1,299 +0,0 @@
--/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
-- *
-- * This program is free software; you can redistribute it and/or modify
-- * it under the terms of the GNU General Public License version 2 and
-- * only version 2 as published by the Free Software Foundation.
-- *
-- * This program is distributed in the hope that it will be useful,
-- * but WITHOUT ANY WARRANTY; without even the implied warranty of
-- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-- * GNU General Public License for more details.
-- *
-- * You should have received a copy of the GNU General Public License
-- * along with this program; if not, write to the Free Software
-- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
-- * 02110-1301, USA.
-- */
--
--#include <linux/slab.h>
--#include <linux/io.h>
--#include <linux/module.h>
--#include <linux/mutex.h>
--#include <linux/errno.h>
--#include <linux/err.h>
--
--#include <asm/cacheflush.h>
--
--#include "scm.h"
--
--/* Cache line size for msm8x60 */
--#define CACHELINESIZE 32
--
--#define SCM_ENOMEM		-5
--#define SCM_EOPNOTSUPP		-4
--#define SCM_EINVAL_ADDR		-3
--#define SCM_EINVAL_ARG		-2
--#define SCM_ERROR		-1
--#define SCM_INTERRUPTED		1
--
--static DEFINE_MUTEX(scm_lock);
--
--/**
-- * struct scm_command - one SCM command buffer
-- * @len: total available memory for command and response
-- * @buf_offset: start of command buffer
-- * @resp_hdr_offset: start of response buffer
-- * @id: command to be executed
-- * @buf: buffer returned from scm_get_command_buffer()
-- *
-- * An SCM command is laid out in memory as follows:
-- *
-- *	------------------- <--- struct scm_command
-- *	| command header  |
-- *	------------------- <--- scm_get_command_buffer()
-- *	| command buffer  |
-- *	------------------- <--- struct scm_response and
-- *	| response header |      scm_command_to_response()
-- *	------------------- <--- scm_get_response_buffer()
-- *	| response buffer |
-- *	-------------------
-- *
-- * There can be arbitrary padding between the headers and buffers so
-- * you should always use the appropriate scm_get_*_buffer() routines
-- * to access the buffers in a safe manner.
-- */
--struct scm_command {
--	u32	len;
--	u32	buf_offset;
--	u32	resp_hdr_offset;
--	u32	id;
--	u32	buf[0];
--};
--
--/**
-- * struct scm_response - one SCM response buffer
-- * @len: total available memory for response
-- * @buf_offset: start of response data relative to start of scm_response
-- * @is_complete: indicates if the command has finished processing
-- */
--struct scm_response {
--	u32	len;
--	u32	buf_offset;
--	u32	is_complete;
--};
--
--/**
-- * alloc_scm_command() - Allocate an SCM command
-- * @cmd_size: size of the command buffer
-- * @resp_size: size of the response buffer
-- *
-- * Allocate an SCM command, including enough room for the command
-- * and response headers as well as the command and response buffers.
-- *
-- * Returns a valid &scm_command on success or %NULL if the allocation fails.
-- */
--static struct scm_command *alloc_scm_command(size_t cmd_size, size_t resp_size)
--{
--	struct scm_command *cmd;
--	size_t len = sizeof(*cmd) + sizeof(struct scm_response) + cmd_size +
--		resp_size;
--
--	cmd = kzalloc(PAGE_ALIGN(len), GFP_KERNEL);
--	if (cmd) {
--		cmd->len = len;
--		cmd->buf_offset = offsetof(struct scm_command, buf);
--		cmd->resp_hdr_offset = cmd->buf_offset + cmd_size;
--	}
--	return cmd;
--}
--
--/**
-- * free_scm_command() - Free an SCM command
-- * @cmd: command to free
-- *
-- * Free an SCM command.
-- */
--static inline void free_scm_command(struct scm_command *cmd)
--{
--	kfree(cmd);
--}
--
--/**
-- * scm_command_to_response() - Get a pointer to a scm_response
-- * @cmd: command
-- *
-- * Returns a pointer to a response for a command.
-- */
--static inline struct scm_response *scm_command_to_response(
--		const struct scm_command *cmd)
--{
--	return (void *)cmd + cmd->resp_hdr_offset;
--}
--
--/**
-- * scm_get_command_buffer() - Get a pointer to a command buffer
-- * @cmd: command
-- *
-- * Returns a pointer to the command buffer of a command.
-- */
--static inline void *scm_get_command_buffer(const struct scm_command *cmd)
--{
--	return (void *)cmd->buf;
--}
--
--/**
-- * scm_get_response_buffer() - Get a pointer to a response buffer
-- * @rsp: response
-- *
-- * Returns a pointer to a response buffer of a response.
-- */
--static inline void *scm_get_response_buffer(const struct scm_response *rsp)
--{
--	return (void *)rsp + rsp->buf_offset;
--}
--
--static int scm_remap_error(int err)
--{
--	switch (err) {
--	case SCM_ERROR:
--		return -EIO;
--	case SCM_EINVAL_ADDR:
--	case SCM_EINVAL_ARG:
--		return -EINVAL;
--	case SCM_EOPNOTSUPP:
--		return -EOPNOTSUPP;
--	case SCM_ENOMEM:
--		return -ENOMEM;
--	}
--	return -EINVAL;
--}
--
--static u32 smc(u32 cmd_addr)
--{
--	int context_id;
--	register u32 r0 asm("r0") = 1;
--	register u32 r1 asm("r1") = (u32)&context_id;
--	register u32 r2 asm("r2") = cmd_addr;
--	do {
--		asm volatile(
--			__asmeq("%0", "r0")
--			__asmeq("%1", "r0")
--			__asmeq("%2", "r1")
--			__asmeq("%3", "r2")
--#ifdef REQUIRES_SEC
--			".arch_extension sec\n"
--#endif
--			"smc	#0	@ switch to secure world\n"
--			: "=r" (r0)
--			: "r" (r0), "r" (r1), "r" (r2)
--			: "r3");
--	} while (r0 == SCM_INTERRUPTED);
--
--	return r0;
--}
--
--static int __scm_call(const struct scm_command *cmd)
--{
--	int ret;
--	u32 cmd_addr = virt_to_phys(cmd);
--
--	/*
--	 * Flush the entire cache here so callers don't have to remember
--	 * to flush the cache when passing physical addresses to the secure
--	 * side in the buffer.
--	 */
--	flush_cache_all();
--	ret = smc(cmd_addr);
--	if (ret < 0)
--		ret = scm_remap_error(ret);
--
--	return ret;
--}
--
--/**
-- * scm_call() - Send an SCM command
-- * @svc_id: service identifier
-- * @cmd_id: command identifier
-- * @cmd_buf: command buffer
-- * @cmd_len: length of the command buffer
-- * @resp_buf: response buffer
-- * @resp_len: length of the response buffer
-- *
-- * Sends a command to the SCM and waits for the command to finish processing.
-- */
--int scm_call(u32 svc_id, u32 cmd_id, const void *cmd_buf, size_t cmd_len,
--		void *resp_buf, size_t resp_len)
--{
--	int ret;
--	struct scm_command *cmd;
--	struct scm_response *rsp;
--
--	cmd = alloc_scm_command(cmd_len, resp_len);
--	if (!cmd)
--		return -ENOMEM;
--
--	cmd->id = (svc_id << 10) | cmd_id;
--	if (cmd_buf)
--		memcpy(scm_get_command_buffer(cmd), cmd_buf, cmd_len);
--
--	mutex_lock(&scm_lock);
--	ret = __scm_call(cmd);
--	mutex_unlock(&scm_lock);
--	if (ret)
--		goto out;
--
--	rsp = scm_command_to_response(cmd);
--	do {
--		u32 start = (u32)rsp;
--		u32 end = (u32)scm_get_response_buffer(rsp) + resp_len;
--		start &= ~(CACHELINESIZE - 1);
--		while (start < end) {
--			asm ("mcr p15, 0, %0, c7, c6, 1" : : "r" (start)
--			     : "memory");
--			start += CACHELINESIZE;
--		}
--	} while (!rsp->is_complete);
--
--	if (resp_buf)
--		memcpy(resp_buf, scm_get_response_buffer(rsp), resp_len);
--out:
--	free_scm_command(cmd);
--	return ret;
--}
--EXPORT_SYMBOL(scm_call);
--
--u32 scm_get_version(void)
--{
--	int context_id;
--	static u32 version = -1;
--	register u32 r0 asm("r0");
--	register u32 r1 asm("r1");
--
--	if (version != -1)
--		return version;
--
--	mutex_lock(&scm_lock);
--
--	r0 = 0x1 << 8;
--	r1 = (u32)&context_id;
--	do {
--		asm volatile(
--			__asmeq("%0", "r0")
--			__asmeq("%1", "r1")
--			__asmeq("%2", "r0")
--			__asmeq("%3", "r1")
--#ifdef REQUIRES_SEC
--			".arch_extension sec\n"
--#endif
--			"smc	#0	@ switch to secure world\n"
--			: "=r" (r0), "=r" (r1)
--			: "r" (r0), "r" (r1)
--			: "r2", "r3");
--	} while (r0 == SCM_INTERRUPTED);
--
--	version = r1;
--	mutex_unlock(&scm_lock);
--
--	return version;
--}
--EXPORT_SYMBOL(scm_get_version);
---- a/arch/arm/mach-msm/scm.h
-+++ /dev/null
-@@ -1,25 +0,0 @@
--/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
-- *
-- * This program is free software; you can redistribute it and/or modify
-- * it under the terms of the GNU General Public License version 2 and
-- * only version 2 as published by the Free Software Foundation.
-- *
-- * 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 __MACH_SCM_H
--#define __MACH_SCM_H
--
--#define SCM_SVC_BOOT			0x1
--#define SCM_SVC_PIL			0x2
--
--extern int scm_call(u32 svc_id, u32 cmd_id, const void *cmd_buf, size_t cmd_len,
--		void *resp_buf, size_t resp_len);
--
--#define SCM_VERSION(major, minor) (((major) << 16) | ((minor) & 0xFF))
--
--extern u32 scm_get_version(void);
--
--#endif
---- /dev/null
-+++ b/arch/arm/mach-qcom/Kconfig
-@@ -0,0 +1,33 @@
-+config ARCH_QCOM
-+	bool "Qualcomm Support" if ARCH_MULTI_V7
-+	select ARCH_REQUIRE_GPIOLIB
-+	select ARM_GIC
-+	select CLKSRC_OF
-+	select GENERIC_CLOCKEVENTS
-+	select HAVE_SMP
-+	select QCOM_SCM if SMP
-+	help
-+	  Support for Qualcomm's devicetree based systems.
-+
-+if ARCH_QCOM
-+
-+menu "Qualcomm SoC Selection"
-+
-+config ARCH_MSM8X60
-+	bool "Enable support for MSM8X60"
-+	select CLKSRC_QCOM
-+
-+config ARCH_MSM8960
-+	bool "Enable support for MSM8960"
-+	select CLKSRC_QCOM
-+
-+config ARCH_MSM8974
-+	bool "Enable support for MSM8974"
-+	select HAVE_ARM_ARCH_TIMER
-+
-+endmenu
-+
-+config QCOM_SCM
-+	bool
-+
-+endif
---- /dev/null
-+++ b/arch/arm/mach-qcom/Makefile
-@@ -0,0 +1,5 @@
-+obj-y			:= board.o
-+obj-$(CONFIG_SMP)	+= platsmp.o
-+obj-$(CONFIG_QCOM_SCM)	+= scm.o scm-boot.o
-+
-+CFLAGS_scm.o :=$(call as-instr,.arch_extension sec,-DREQUIRES_SEC=1)
---- /dev/null
-+++ b/arch/arm/mach-qcom/board.c
-@@ -0,0 +1,40 @@
-+/* Copyright (c) 2010-2014 The Linux Foundation. All rights reserved.
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 and
-+ * only version 2 as published by the Free Software Foundation.
-+ *
-+ * 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/init.h>
-+#include <linux/of.h>
-+#include <linux/of_platform.h>
-+
-+#include <asm/mach/arch.h>
-+#include <asm/mach/map.h>
-+
-+extern struct smp_operations msm_smp_ops;
-+
-+static const char * const qcom_dt_match[] __initconst = {
-+	"qcom,msm8660-surf",
-+	"qcom,msm8960-cdp",
-+	NULL
-+};
-+
-+static const char * const apq8074_dt_match[] __initconst = {
-+	"qcom,apq8074-dragonboard",
-+	NULL
-+};
-+
-+DT_MACHINE_START(QCOM_DT, "Qualcomm (Flattened Device Tree)")
-+	.smp = smp_ops(msm_smp_ops),
-+	.dt_compat = qcom_dt_match,
-+MACHINE_END
-+
-+DT_MACHINE_START(APQ_DT, "Qualcomm (Flattened Device Tree)")
-+	.dt_compat = apq8074_dt_match,
-+MACHINE_END
---- /dev/null
-+++ b/arch/arm/mach-qcom/platsmp.c
-@@ -0,0 +1,137 @@
-+/*
-+ *  Copyright (C) 2002 ARM Ltd.
-+ *  All Rights Reserved
-+ *  Copyright (c) 2010, Code Aurora Forum. All rights reserved.
-+ *  Copyright (c) 2014 The Linux Foundation. All rights reserved.
-+ *
-+ * 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/init.h>
-+#include <linux/errno.h>
-+#include <linux/delay.h>
-+#include <linux/device.h>
-+#include <linux/smp.h>
-+#include <linux/io.h>
-+
-+#include <asm/cputype.h>
-+#include <asm/smp_plat.h>
-+
-+#include "scm-boot.h"
-+
-+#define VDD_SC1_ARRAY_CLAMP_GFS_CTL 0x15A0
-+#define SCSS_CPU1CORE_RESET 0xD80
-+#define SCSS_DBG_STATUS_CORE_PWRDUP 0xE64
-+
-+extern void secondary_startup(void);
-+
-+static DEFINE_SPINLOCK(boot_lock);
-+
-+#ifdef CONFIG_HOTPLUG_CPU
-+static void __ref msm_cpu_die(unsigned int cpu)
-+{
-+	wfi();
-+}
-+#endif
-+
-+static inline int get_core_count(void)
-+{
-+	/* 1 + the PART[1:0] field of MIDR */
-+	return ((read_cpuid_id() >> 4) & 3) + 1;
-+}
-+
-+static void msm_secondary_init(unsigned int cpu)
-+{
-+	/*
-+	 * Synchronise with the boot thread.
-+	 */
-+	spin_lock(&boot_lock);
-+	spin_unlock(&boot_lock);
-+}
-+
-+static void prepare_cold_cpu(unsigned int cpu)
-+{
-+	int ret;
-+	ret = scm_set_boot_addr(virt_to_phys(secondary_startup),
-+				SCM_FLAG_COLDBOOT_CPU1);
-+	if (ret == 0) {
-+		void __iomem *sc1_base_ptr;
-+		sc1_base_ptr = ioremap_nocache(0x00902000, SZ_4K*2);
-+		if (sc1_base_ptr) {
-+			writel(0, sc1_base_ptr + VDD_SC1_ARRAY_CLAMP_GFS_CTL);
-+			writel(0, sc1_base_ptr + SCSS_CPU1CORE_RESET);
-+			writel(3, sc1_base_ptr + SCSS_DBG_STATUS_CORE_PWRDUP);
-+			iounmap(sc1_base_ptr);
-+		}
-+	} else
-+		printk(KERN_DEBUG "Failed to set secondary core boot "
-+				  "address\n");
-+}
-+
-+static int msm_boot_secondary(unsigned int cpu, struct task_struct *idle)
-+{
-+	static int cold_boot_done;
-+
-+	/* Only need to bring cpu out of reset this way once */
-+	if (cold_boot_done == false) {
-+		prepare_cold_cpu(cpu);
-+		cold_boot_done = true;
-+	}
-+
-+	/*
-+	 * set synchronisation state between this boot processor
-+	 * and the secondary one
-+	 */
-+	spin_lock(&boot_lock);
-+
-+	/*
-+	 * Send the secondary CPU a soft interrupt, thereby causing
-+	 * the boot monitor to read the system wide flags register,
-+	 * and branch to the address found there.
-+	 */
-+	arch_send_wakeup_ipi_mask(cpumask_of(cpu));
-+
-+	/*
-+	 * now the secondary core is starting up let it run its
-+	 * calibrations, then wait for it to finish
-+	 */
-+	spin_unlock(&boot_lock);
-+
-+	return 0;
-+}
-+
-+/*
-+ * Initialise the CPU possible map early - this describes the CPUs
-+ * which may be present or become present in the system. The msm8x60
-+ * does not support the ARM SCU, so just set the possible cpu mask to
-+ * NR_CPUS.
-+ */
-+static void __init msm_smp_init_cpus(void)
-+{
-+	unsigned int i, ncores = get_core_count();
-+
-+	if (ncores > nr_cpu_ids) {
-+		pr_warn("SMP: %u cores greater than maximum (%u), clipping\n",
-+			ncores, nr_cpu_ids);
-+		ncores = nr_cpu_ids;
-+	}
-+
-+	for (i = 0; i < ncores; i++)
-+		set_cpu_possible(i, true);
-+}
-+
-+static void __init msm_smp_prepare_cpus(unsigned int max_cpus)
-+{
-+}
-+
-+struct smp_operations msm_smp_ops __initdata = {
-+	.smp_init_cpus		= msm_smp_init_cpus,
-+	.smp_prepare_cpus	= msm_smp_prepare_cpus,
-+	.smp_secondary_init	= msm_secondary_init,
-+	.smp_boot_secondary	= msm_boot_secondary,
-+#ifdef CONFIG_HOTPLUG_CPU
-+	.cpu_die		= msm_cpu_die,
-+#endif
-+};
---- /dev/null
-+++ b/arch/arm/mach-qcom/scm-boot.c
-@@ -0,0 +1,39 @@
-+/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 and
-+ * only version 2 as published by the Free Software Foundation.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, write to the Free Software
-+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
-+ * 02110-1301, USA.
-+ */
-+
-+#include <linux/module.h>
-+#include <linux/slab.h>
-+
-+#include "scm.h"
-+#include "scm-boot.h"
-+
-+/*
-+ * Set the cold/warm boot address for one of the CPU cores.
-+ */
-+int scm_set_boot_addr(phys_addr_t addr, int flags)
-+{
-+	struct {
-+		unsigned int flags;
-+		phys_addr_t  addr;
-+	} cmd;
-+
-+	cmd.addr = addr;
-+	cmd.flags = flags;
-+	return scm_call(SCM_SVC_BOOT, SCM_BOOT_ADDR,
-+			&cmd, sizeof(cmd), NULL, 0);
-+}
-+EXPORT_SYMBOL(scm_set_boot_addr);
---- /dev/null
-+++ b/arch/arm/mach-qcom/scm-boot.h
-@@ -0,0 +1,22 @@
-+/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 and
-+ * only version 2 as published by the Free Software Foundation.
-+ *
-+ * 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 __MACH_SCM_BOOT_H
-+#define __MACH_SCM_BOOT_H
-+
-+#define SCM_BOOT_ADDR			0x1
-+#define SCM_FLAG_COLDBOOT_CPU1		0x1
-+#define SCM_FLAG_WARMBOOT_CPU1		0x2
-+#define SCM_FLAG_WARMBOOT_CPU0		0x4
-+
-+int scm_set_boot_addr(phys_addr_t addr, int flags);
-+
-+#endif
---- /dev/null
-+++ b/arch/arm/mach-qcom/scm.c
-@@ -0,0 +1,299 @@
-+/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 and
-+ * only version 2 as published by the Free Software Foundation.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, write to the Free Software
-+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
-+ * 02110-1301, USA.
-+ */
-+
-+#include <linux/slab.h>
-+#include <linux/io.h>
-+#include <linux/module.h>
-+#include <linux/mutex.h>
-+#include <linux/errno.h>
-+#include <linux/err.h>
-+
-+#include <asm/cacheflush.h>
-+
-+#include "scm.h"
-+
-+/* Cache line size for msm8x60 */
-+#define CACHELINESIZE 32
-+
-+#define SCM_ENOMEM		-5
-+#define SCM_EOPNOTSUPP		-4
-+#define SCM_EINVAL_ADDR		-3
-+#define SCM_EINVAL_ARG		-2
-+#define SCM_ERROR		-1
-+#define SCM_INTERRUPTED		1
-+
-+static DEFINE_MUTEX(scm_lock);
-+
-+/**
-+ * struct scm_command - one SCM command buffer
-+ * @len: total available memory for command and response
-+ * @buf_offset: start of command buffer
-+ * @resp_hdr_offset: start of response buffer
-+ * @id: command to be executed
-+ * @buf: buffer returned from scm_get_command_buffer()
-+ *
-+ * An SCM command is laid out in memory as follows:
-+ *
-+ *	------------------- <--- struct scm_command
-+ *	| command header  |
-+ *	------------------- <--- scm_get_command_buffer()
-+ *	| command buffer  |
-+ *	------------------- <--- struct scm_response and
-+ *	| response header |      scm_command_to_response()
-+ *	------------------- <--- scm_get_response_buffer()
-+ *	| response buffer |
-+ *	-------------------
-+ *
-+ * There can be arbitrary padding between the headers and buffers so
-+ * you should always use the appropriate scm_get_*_buffer() routines
-+ * to access the buffers in a safe manner.
-+ */
-+struct scm_command {
-+	u32	len;
-+	u32	buf_offset;
-+	u32	resp_hdr_offset;
-+	u32	id;
-+	u32	buf[0];
-+};
-+
-+/**
-+ * struct scm_response - one SCM response buffer
-+ * @len: total available memory for response
-+ * @buf_offset: start of response data relative to start of scm_response
-+ * @is_complete: indicates if the command has finished processing
-+ */
-+struct scm_response {
-+	u32	len;
-+	u32	buf_offset;
-+	u32	is_complete;
-+};
-+
-+/**
-+ * alloc_scm_command() - Allocate an SCM command
-+ * @cmd_size: size of the command buffer
-+ * @resp_size: size of the response buffer
-+ *
-+ * Allocate an SCM command, including enough room for the command
-+ * and response headers as well as the command and response buffers.
-+ *
-+ * Returns a valid &scm_command on success or %NULL if the allocation fails.
-+ */
-+static struct scm_command *alloc_scm_command(size_t cmd_size, size_t resp_size)
-+{
-+	struct scm_command *cmd;
-+	size_t len = sizeof(*cmd) + sizeof(struct scm_response) + cmd_size +
-+		resp_size;
-+
-+	cmd = kzalloc(PAGE_ALIGN(len), GFP_KERNEL);
-+	if (cmd) {
-+		cmd->len = len;
-+		cmd->buf_offset = offsetof(struct scm_command, buf);
-+		cmd->resp_hdr_offset = cmd->buf_offset + cmd_size;
-+	}
-+	return cmd;
-+}
-+
-+/**
-+ * free_scm_command() - Free an SCM command
-+ * @cmd: command to free
-+ *
-+ * Free an SCM command.
-+ */
-+static inline void free_scm_command(struct scm_command *cmd)
-+{
-+	kfree(cmd);
-+}
-+
-+/**
-+ * scm_command_to_response() - Get a pointer to a scm_response
-+ * @cmd: command
-+ *
-+ * Returns a pointer to a response for a command.
-+ */
-+static inline struct scm_response *scm_command_to_response(
-+		const struct scm_command *cmd)
-+{
-+	return (void *)cmd + cmd->resp_hdr_offset;
-+}
-+
-+/**
-+ * scm_get_command_buffer() - Get a pointer to a command buffer
-+ * @cmd: command
-+ *
-+ * Returns a pointer to the command buffer of a command.
-+ */
-+static inline void *scm_get_command_buffer(const struct scm_command *cmd)
-+{
-+	return (void *)cmd->buf;
-+}
-+
-+/**
-+ * scm_get_response_buffer() - Get a pointer to a response buffer
-+ * @rsp: response
-+ *
-+ * Returns a pointer to a response buffer of a response.
-+ */
-+static inline void *scm_get_response_buffer(const struct scm_response *rsp)
-+{
-+	return (void *)rsp + rsp->buf_offset;
-+}
-+
-+static int scm_remap_error(int err)
-+{
-+	switch (err) {
-+	case SCM_ERROR:
-+		return -EIO;
-+	case SCM_EINVAL_ADDR:
-+	case SCM_EINVAL_ARG:
-+		return -EINVAL;
-+	case SCM_EOPNOTSUPP:
-+		return -EOPNOTSUPP;
-+	case SCM_ENOMEM:
-+		return -ENOMEM;
-+	}
-+	return -EINVAL;
-+}
-+
-+static u32 smc(u32 cmd_addr)
-+{
-+	int context_id;
-+	register u32 r0 asm("r0") = 1;
-+	register u32 r1 asm("r1") = (u32)&context_id;
-+	register u32 r2 asm("r2") = cmd_addr;
-+	do {
-+		asm volatile(
-+			__asmeq("%0", "r0")
-+			__asmeq("%1", "r0")
-+			__asmeq("%2", "r1")
-+			__asmeq("%3", "r2")
-+#ifdef REQUIRES_SEC
-+			".arch_extension sec\n"
-+#endif
-+			"smc	#0	@ switch to secure world\n"
-+			: "=r" (r0)
-+			: "r" (r0), "r" (r1), "r" (r2)
-+			: "r3");
-+	} while (r0 == SCM_INTERRUPTED);
-+
-+	return r0;
-+}
-+
-+static int __scm_call(const struct scm_command *cmd)
-+{
-+	int ret;
-+	u32 cmd_addr = virt_to_phys(cmd);
-+
-+	/*
-+	 * Flush the entire cache here so callers don't have to remember
-+	 * to flush the cache when passing physical addresses to the secure
-+	 * side in the buffer.
-+	 */
-+	flush_cache_all();
-+	ret = smc(cmd_addr);
-+	if (ret < 0)
-+		ret = scm_remap_error(ret);
-+
-+	return ret;
-+}
-+
-+/**
-+ * scm_call() - Send an SCM command
-+ * @svc_id: service identifier
-+ * @cmd_id: command identifier
-+ * @cmd_buf: command buffer
-+ * @cmd_len: length of the command buffer
-+ * @resp_buf: response buffer
-+ * @resp_len: length of the response buffer
-+ *
-+ * Sends a command to the SCM and waits for the command to finish processing.
-+ */
-+int scm_call(u32 svc_id, u32 cmd_id, const void *cmd_buf, size_t cmd_len,
-+		void *resp_buf, size_t resp_len)
-+{
-+	int ret;
-+	struct scm_command *cmd;
-+	struct scm_response *rsp;
-+
-+	cmd = alloc_scm_command(cmd_len, resp_len);
-+	if (!cmd)
-+		return -ENOMEM;
-+
-+	cmd->id = (svc_id << 10) | cmd_id;
-+	if (cmd_buf)
-+		memcpy(scm_get_command_buffer(cmd), cmd_buf, cmd_len);
-+
-+	mutex_lock(&scm_lock);
-+	ret = __scm_call(cmd);
-+	mutex_unlock(&scm_lock);
-+	if (ret)
-+		goto out;
-+
-+	rsp = scm_command_to_response(cmd);
-+	do {
-+		u32 start = (u32)rsp;
-+		u32 end = (u32)scm_get_response_buffer(rsp) + resp_len;
-+		start &= ~(CACHELINESIZE - 1);
-+		while (start < end) {
-+			asm ("mcr p15, 0, %0, c7, c6, 1" : : "r" (start)
-+			     : "memory");
-+			start += CACHELINESIZE;
-+		}
-+	} while (!rsp->is_complete);
-+
-+	if (resp_buf)
-+		memcpy(resp_buf, scm_get_response_buffer(rsp), resp_len);
-+out:
-+	free_scm_command(cmd);
-+	return ret;
-+}
-+EXPORT_SYMBOL(scm_call);
-+
-+u32 scm_get_version(void)
-+{
-+	int context_id;
-+	static u32 version = -1;
-+	register u32 r0 asm("r0");
-+	register u32 r1 asm("r1");
-+
-+	if (version != -1)
-+		return version;
-+
-+	mutex_lock(&scm_lock);
-+
-+	r0 = 0x1 << 8;
-+	r1 = (u32)&context_id;
-+	do {
-+		asm volatile(
-+			__asmeq("%0", "r0")
-+			__asmeq("%1", "r1")
-+			__asmeq("%2", "r0")
-+			__asmeq("%3", "r1")
-+#ifdef REQUIRES_SEC
-+			".arch_extension sec\n"
-+#endif
-+			"smc	#0	@ switch to secure world\n"
-+			: "=r" (r0), "=r" (r1)
-+			: "r" (r0), "r" (r1)
-+			: "r2", "r3");
-+	} while (r0 == SCM_INTERRUPTED);
-+
-+	version = r1;
-+	mutex_unlock(&scm_lock);
-+
-+	return version;
-+}
-+EXPORT_SYMBOL(scm_get_version);
---- /dev/null
-+++ b/arch/arm/mach-qcom/scm.h
-@@ -0,0 +1,25 @@
-+/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 and
-+ * only version 2 as published by the Free Software Foundation.
-+ *
-+ * 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 __MACH_SCM_H
-+#define __MACH_SCM_H
-+
-+#define SCM_SVC_BOOT			0x1
-+#define SCM_SVC_PIL			0x2
-+
-+extern int scm_call(u32 svc_id, u32 cmd_id, const void *cmd_buf, size_t cmd_len,
-+		void *resp_buf, size_t resp_len);
-+
-+#define SCM_VERSION(major, minor) (((major) << 16) | ((minor) & 0xFF))
-+
-+extern u32 scm_get_version(void);
-+
-+#endif
diff --git a/target/linux/ipq806x/patches/0006-clocksource-qcom-split-building-of-legacy-vs-multipl.patch b/target/linux/ipq806x/patches/0006-clocksource-qcom-split-building-of-legacy-vs-multipl.patch
deleted file mode 100644
index 79603f8..0000000
--- a/target/linux/ipq806x/patches/0006-clocksource-qcom-split-building-of-legacy-vs-multipl.patch
+++ /dev/null
@@ -1,73 +0,0 @@
-From 085d4b834dfced8580aab74707e30699b63e7c36 Mon Sep 17 00:00:00 2001
-From: Kumar Gala <galak@codeaurora.org>
-Date: Wed, 29 Jan 2014 17:01:37 -0600
-Subject: [PATCH 006/182] clocksource: qcom: split building of legacy vs
- multiplatform support
-
-The majority of the clocksource code for the Qualcomm platform is shared
-between newer (multiplatform) and older platforms.  However there is a bit
-of code that isn't, so only build it for the appropriate config.
-
-Acked-by: Olof Johansson <olof@lixom.net>
-Signed-off-by: Kumar Gala <galak@codeaurora.org>
----
- drivers/clocksource/qcom-timer.c |   23 ++++++++++++-----------
- 1 file changed, 12 insertions(+), 11 deletions(-)
-
---- a/drivers/clocksource/qcom-timer.c
-+++ b/drivers/clocksource/qcom-timer.c
-@@ -106,15 +106,6 @@ static notrace cycle_t msm_read_timer_co
- 	return readl_relaxed(source_base + TIMER_COUNT_VAL);
- }
- 
--static notrace cycle_t msm_read_timer_count_shift(struct clocksource *cs)
--{
--	/*
--	 * Shift timer count down by a constant due to unreliable lower bits
--	 * on some targets.
--	 */
--	return msm_read_timer_count(cs) >> MSM_DGT_SHIFT;
--}
--
- static struct clocksource msm_clocksource = {
- 	.name	= "dg_timer",
- 	.rating	= 300,
-@@ -228,7 +219,7 @@ err:
- 	sched_clock_register(msm_sched_clock_read, sched_bits, dgt_hz);
- }
- 
--#ifdef CONFIG_OF
-+#ifdef CONFIG_ARCH_QCOM
- static void __init msm_dt_timer_init(struct device_node *np)
- {
- 	u32 freq;
-@@ -281,7 +272,7 @@ static void __init msm_dt_timer_init(str
- }
- CLOCKSOURCE_OF_DECLARE(kpss_timer, "qcom,kpss-timer", msm_dt_timer_init);
- CLOCKSOURCE_OF_DECLARE(scss_timer, "qcom,scss-timer", msm_dt_timer_init);
--#endif
-+#else
- 
- static int __init msm_timer_map(phys_addr_t addr, u32 event, u32 source,
- 				u32 sts)
-@@ -301,6 +292,15 @@ static int __init msm_timer_map(phys_add
- 	return 0;
- }
- 
-+static notrace cycle_t msm_read_timer_count_shift(struct clocksource *cs)
-+{
-+	/*
-+	 * Shift timer count down by a constant due to unreliable lower bits
-+	 * on some targets.
-+	 */
-+	return msm_read_timer_count(cs) >> MSM_DGT_SHIFT;
-+}
-+
- void __init msm7x01_timer_init(void)
- {
- 	struct clocksource *cs = &msm_clocksource;
-@@ -327,3 +327,4 @@ void __init qsd8x50_timer_init(void)
- 		return;
- 	msm_timer_init(19200000 / 4, 32, 7, false);
- }
-+#endif
diff --git a/target/linux/ipq806x/patches/0007-ARM-qcom-Rename-various-msm-prefixed-functions-to-qc.patch b/target/linux/ipq806x/patches/0007-ARM-qcom-Rename-various-msm-prefixed-functions-to-qc.patch
deleted file mode 100644
index cab5bcd..0000000
--- a/target/linux/ipq806x/patches/0007-ARM-qcom-Rename-various-msm-prefixed-functions-to-qc.patch
+++ /dev/null
@@ -1,98 +0,0 @@
-From 35eb6f73546d3b9475652a38fa641bd1a05a1ea1 Mon Sep 17 00:00:00 2001
-From: Kumar Gala <galak@codeaurora.org>
-Date: Tue, 4 Feb 2014 15:38:45 -0600
-Subject: [PATCH 007/182] ARM: qcom: Rename various msm prefixed functions to
- qcom
-
-As mach-qcom will support a number of different Qualcomm SoC platforms
-we replace the msm prefix on function names with qcom to be a bit more
-generic.
-
-Signed-off-by: Kumar Gala <galak@codeaurora.org>
----
- arch/arm/mach-qcom/board.c   |    4 ++--
- arch/arm/mach-qcom/platsmp.c |   22 +++++++++++-----------
- 2 files changed, 13 insertions(+), 13 deletions(-)
-
---- a/arch/arm/mach-qcom/board.c
-+++ b/arch/arm/mach-qcom/board.c
-@@ -17,7 +17,7 @@
- #include <asm/mach/arch.h>
- #include <asm/mach/map.h>
- 
--extern struct smp_operations msm_smp_ops;
-+extern struct smp_operations qcom_smp_ops;
- 
- static const char * const qcom_dt_match[] __initconst = {
- 	"qcom,msm8660-surf",
-@@ -31,7 +31,7 @@ static const char * const apq8074_dt_mat
- };
- 
- DT_MACHINE_START(QCOM_DT, "Qualcomm (Flattened Device Tree)")
--	.smp = smp_ops(msm_smp_ops),
-+	.smp = smp_ops(qcom_smp_ops),
- 	.dt_compat = qcom_dt_match,
- MACHINE_END
- 
---- a/arch/arm/mach-qcom/platsmp.c
-+++ b/arch/arm/mach-qcom/platsmp.c
-@@ -30,7 +30,7 @@ extern void secondary_startup(void);
- static DEFINE_SPINLOCK(boot_lock);
- 
- #ifdef CONFIG_HOTPLUG_CPU
--static void __ref msm_cpu_die(unsigned int cpu)
-+static void __ref qcom_cpu_die(unsigned int cpu)
- {
- 	wfi();
- }
-@@ -42,7 +42,7 @@ static inline int get_core_count(void)
- 	return ((read_cpuid_id() >> 4) & 3) + 1;
- }
- 
--static void msm_secondary_init(unsigned int cpu)
-+static void qcom_secondary_init(unsigned int cpu)
- {
- 	/*
- 	 * Synchronise with the boot thread.
-@@ -70,7 +70,7 @@ static void prepare_cold_cpu(unsigned in
- 				  "address\n");
- }
- 
--static int msm_boot_secondary(unsigned int cpu, struct task_struct *idle)
-+static int qcom_boot_secondary(unsigned int cpu, struct task_struct *idle)
- {
- 	static int cold_boot_done;
- 
-@@ -108,7 +108,7 @@ static int msm_boot_secondary(unsigned i
-  * does not support the ARM SCU, so just set the possible cpu mask to
-  * NR_CPUS.
-  */
--static void __init msm_smp_init_cpus(void)
-+static void __init qcom_smp_init_cpus(void)
- {
- 	unsigned int i, ncores = get_core_count();
- 
-@@ -122,16 +122,16 @@ static void __init msm_smp_init_cpus(voi
- 		set_cpu_possible(i, true);
- }
- 
--static void __init msm_smp_prepare_cpus(unsigned int max_cpus)
-+static void __init qcom_smp_prepare_cpus(unsigned int max_cpus)
- {
- }
- 
--struct smp_operations msm_smp_ops __initdata = {
--	.smp_init_cpus		= msm_smp_init_cpus,
--	.smp_prepare_cpus	= msm_smp_prepare_cpus,
--	.smp_secondary_init	= msm_secondary_init,
--	.smp_boot_secondary	= msm_boot_secondary,
-+struct smp_operations qcom_smp_ops __initdata = {
-+	.smp_init_cpus		= qcom_smp_init_cpus,
-+	.smp_prepare_cpus	= qcom_smp_prepare_cpus,
-+	.smp_secondary_init	= qcom_secondary_init,
-+	.smp_boot_secondary	= qcom_boot_secondary,
- #ifdef CONFIG_HOTPLUG_CPU
--	.cpu_die		= msm_cpu_die,
-+	.cpu_die		= qcom_cpu_die,
- #endif
- };
diff --git a/target/linux/ipq806x/patches/0008-ARM-Introduce-CPU_METHOD_OF_DECLARE-for-cpu-hotplug-.patch b/target/linux/ipq806x/patches/0008-ARM-Introduce-CPU_METHOD_OF_DECLARE-for-cpu-hotplug-.patch
deleted file mode 100644
index b4a8b4b..0000000
--- a/target/linux/ipq806x/patches/0008-ARM-Introduce-CPU_METHOD_OF_DECLARE-for-cpu-hotplug-.patch
+++ /dev/null
@@ -1,150 +0,0 @@
-From 48f17325fef9cbebc5cb39aa78f4c1caff5d7b16 Mon Sep 17 00:00:00 2001
-From: Stephen Boyd <sboyd@codeaurora.org>
-Date: Wed, 30 Oct 2013 18:21:09 -0700
-Subject: [PATCH 008/182] ARM: Introduce CPU_METHOD_OF_DECLARE() for cpu
- hotplug/smp
-
-The goal of multi-platform kernels is to remove the need for mach
-directories and machine descriptors. To further that goal,
-introduce CPU_METHOD_OF_DECLARE() to allow cpu hotplug/smp
-support to be separated from the machine descriptors.
-Implementers should specify an enable-method property in their
-cpus node and then implement a matching set of smp_ops in their
-hotplug/smp code, wiring it up with the CPU_METHOD_OF_DECLARE()
-macro. When the kernel is compiled we'll collect all the
-enable-method smp_ops into one section for use at boot.
-
-At boot time we'll look for an enable-method in each cpu node and
-try to match that against all known CPU enable methods in the
-kernel. If there are no enable-methods in the cpu nodes we
-fallback to the cpus node and try to use any enable-method found
-there. If that doesn't work we fall back to the old way of using
-the machine descriptor.
-
-Acked-by: Mark Rutland <mark.rutland@arm.com>
-Cc: Russell King <linux@arm.linux.org.uk>
-Cc: <devicetree@vger.kernel.org>
-Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
-Signed-off-by: Kumar Gala <galak@codeaurora.org>
----
- arch/arm/include/asm/smp.h        |    9 +++++++++
- arch/arm/kernel/devtree.c         |   40 +++++++++++++++++++++++++++++++++++++
- include/asm-generic/vmlinux.lds.h |   10 ++++++++++
- 3 files changed, 59 insertions(+)
-
---- a/arch/arm/include/asm/smp.h
-+++ b/arch/arm/include/asm/smp.h
-@@ -114,6 +114,15 @@ struct smp_operations {
- #endif
- };
- 
-+struct of_cpu_method {
-+	const char *method;
-+	struct smp_operations *ops;
-+};
-+
-+#define CPU_METHOD_OF_DECLARE(name, _method, _ops)			\
-+	static const struct of_cpu_method __cpu_method_of_table_##name	\
-+		__used __section(__cpu_method_of_table)			\
-+		= { .method = _method, .ops = _ops }
- /*
-  * set platform specific SMP operations
-  */
---- a/arch/arm/kernel/devtree.c
-+++ b/arch/arm/kernel/devtree.c
-@@ -18,6 +18,7 @@
- #include <linux/of_fdt.h>
- #include <linux/of_irq.h>
- #include <linux/of_platform.h>
-+#include <linux/smp.h>
- 
- #include <asm/cputype.h>
- #include <asm/setup.h>
-@@ -63,6 +64,34 @@ void __init arm_dt_memblock_reserve(void
- 	}
- }
- 
-+#ifdef CONFIG_SMP
-+extern struct of_cpu_method __cpu_method_of_table_begin[];
-+extern struct of_cpu_method __cpu_method_of_table_end[];
-+
-+static int __init set_smp_ops_by_method(struct device_node *node)
-+{
-+	const char *method;
-+	struct of_cpu_method *m = __cpu_method_of_table_begin;
-+
-+	if (of_property_read_string(node, "enable-method", &method))
-+		return 0;
-+
-+	for (; m < __cpu_method_of_table_end; m++)
-+		if (!strcmp(m->method, method)) {
-+			smp_set_ops(m->ops);
-+			return 1;
-+		}
-+
-+	return 0;
-+}
-+#else
-+static inline int set_smp_ops_by_method(struct device_node *node)
-+{
-+	return 1;
-+}
-+#endif
-+
-+
- /*
-  * arm_dt_init_cpu_maps - Function retrieves cpu nodes from the device tree
-  * and builds the cpu logical map array containing MPIDR values related to
-@@ -79,6 +108,7 @@ void __init arm_dt_init_cpu_maps(void)
- 	 * read as 0.
- 	 */
- 	struct device_node *cpu, *cpus;
-+	int found_method = 0;
- 	u32 i, j, cpuidx = 1;
- 	u32 mpidr = is_smp() ? read_cpuid_mpidr() & MPIDR_HWID_BITMASK : 0;
- 
-@@ -150,8 +180,18 @@ void __init arm_dt_init_cpu_maps(void)
- 		}
- 
- 		tmp_map[i] = hwid;
-+
-+		if (!found_method)
-+			found_method = set_smp_ops_by_method(cpu);
- 	}
- 
-+	/*
-+	 * Fallback to an enable-method in the cpus node if nothing found in
-+	 * a cpu node.
-+	 */
-+	if (!found_method)
-+		set_smp_ops_by_method(cpus);
-+
- 	if (!bootcpu_valid) {
- 		pr_warn("DT missing boot CPU MPIDR[23:0], fall back to default cpu_logical_map\n");
- 		return;
---- a/include/asm-generic/vmlinux.lds.h
-+++ b/include/asm-generic/vmlinux.lds.h
-@@ -177,6 +177,15 @@
- #define CLK_OF_TABLES()
- #endif
- 
-+#ifdef CONFIG_SMP
-+#define CPU_METHOD_OF_TABLES() . = ALIGN(8);				    \
-+			   VMLINUX_SYMBOL(__cpu_method_of_table_begin) = .; \
-+			   *(__cpu_method_of_table)			    \
-+			   VMLINUX_SYMBOL(__cpu_method_of_table_end) = .;
-+#else
-+#define CPU_METHOD_OF_TABLES()
-+#endif
-+
- #define KERNEL_DTB()							\
- 	STRUCT_ALIGN();							\
- 	VMLINUX_SYMBOL(__dtb_start) = .;				\
-@@ -502,6 +511,7 @@
- 	MEM_DISCARD(init.rodata)					\
- 	CLK_OF_TABLES()							\
- 	CLKSRC_OF_TABLES()						\
-+	CPU_METHOD_OF_TABLES()						\
- 	KERNEL_DTB()							\
- 	IRQCHIP_OF_MATCH_TABLE()
- 
diff --git a/target/linux/ipq806x/patches/0009-ARM-qcom-Re-organize-platsmp-to-make-it-extensible.patch b/target/linux/ipq806x/patches/0009-ARM-qcom-Re-organize-platsmp-to-make-it-extensible.patch
deleted file mode 100644
index 4bab4c9..0000000
--- a/target/linux/ipq806x/patches/0009-ARM-qcom-Re-organize-platsmp-to-make-it-extensible.patch
+++ /dev/null
@@ -1,241 +0,0 @@
-From 391848e75f8b0ba14816da1ac8f2d838fd0d5744 Mon Sep 17 00:00:00 2001
-From: Rohit Vaswani <rvaswani@codeaurora.org>
-Date: Tue, 21 May 2013 19:13:29 -0700
-Subject: [PATCH 009/182] ARM: qcom: Re-organize platsmp to make it extensible
-
-This makes it easy to add SMP support for new devices by keying
-on a device node for the release sequence. We add the
-enable-method property for the cpus property to specify that we
-want to use the gcc-msm8660 release sequence (which is going to
-look for the global clock controller device node to map some
-Scorpion specific power and control registers). We also remove
-the nr_cpus detection code as that is done generically in the DT
-CPU detection code.
-
-Signed-off-by: Rohit Vaswani <rvaswani@codeaurora.org>
-[sboyd: Port to CPU_METHOD_OF_DECLARE]
-Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
-Signed-off-by: Kumar Gala <galak@codeaurora.org>
----
- arch/arm/mach-msm/common.h   |    2 -
- arch/arm/mach-qcom/board.c   |   14 -----
- arch/arm/mach-qcom/platsmp.c |  118 +++++++++++++++++++++++-------------------
- 3 files changed, 65 insertions(+), 69 deletions(-)
-
---- a/arch/arm/mach-msm/common.h
-+++ b/arch/arm/mach-msm/common.h
-@@ -23,8 +23,6 @@ extern void msm_map_qsd8x50_io(void);
- extern void __iomem *__msm_ioremap_caller(phys_addr_t phys_addr, size_t size,
- 					  unsigned int mtype, void *caller);
- 
--extern struct smp_operations msm_smp_ops;
--
- struct msm_mmc_platform_data;
- 
- extern void msm_add_devices(void);
---- a/arch/arm/mach-qcom/board.c
-+++ b/arch/arm/mach-qcom/board.c
-@@ -11,30 +11,16 @@
-  */
- 
- #include <linux/init.h>
--#include <linux/of.h>
--#include <linux/of_platform.h>
- 
- #include <asm/mach/arch.h>
--#include <asm/mach/map.h>
--
--extern struct smp_operations qcom_smp_ops;
- 
- static const char * const qcom_dt_match[] __initconst = {
- 	"qcom,msm8660-surf",
- 	"qcom,msm8960-cdp",
--	NULL
--};
--
--static const char * const apq8074_dt_match[] __initconst = {
- 	"qcom,apq8074-dragonboard",
- 	NULL
- };
- 
- DT_MACHINE_START(QCOM_DT, "Qualcomm (Flattened Device Tree)")
--	.smp = smp_ops(qcom_smp_ops),
- 	.dt_compat = qcom_dt_match,
- MACHINE_END
--
--DT_MACHINE_START(APQ_DT, "Qualcomm (Flattened Device Tree)")
--	.dt_compat = apq8074_dt_match,
--MACHINE_END
---- a/arch/arm/mach-qcom/platsmp.c
-+++ b/arch/arm/mach-qcom/platsmp.c
-@@ -13,17 +13,18 @@
- #include <linux/errno.h>
- #include <linux/delay.h>
- #include <linux/device.h>
-+#include <linux/of.h>
-+#include <linux/of_address.h>
- #include <linux/smp.h>
- #include <linux/io.h>
- 
--#include <asm/cputype.h>
- #include <asm/smp_plat.h>
- 
- #include "scm-boot.h"
- 
--#define VDD_SC1_ARRAY_CLAMP_GFS_CTL 0x15A0
--#define SCSS_CPU1CORE_RESET 0xD80
--#define SCSS_DBG_STATUS_CORE_PWRDUP 0xE64
-+#define VDD_SC1_ARRAY_CLAMP_GFS_CTL	0x35a0
-+#define SCSS_CPU1CORE_RESET		0x2d80
-+#define SCSS_DBG_STATUS_CORE_PWRDUP	0x2e64
- 
- extern void secondary_startup(void);
- 
-@@ -36,12 +37,6 @@ static void __ref qcom_cpu_die(unsigned
- }
- #endif
- 
--static inline int get_core_count(void)
--{
--	/* 1 + the PART[1:0] field of MIDR */
--	return ((read_cpuid_id() >> 4) & 3) + 1;
--}
--
- static void qcom_secondary_init(unsigned int cpu)
- {
- 	/*
-@@ -51,33 +46,41 @@ static void qcom_secondary_init(unsigned
- 	spin_unlock(&boot_lock);
- }
- 
--static void prepare_cold_cpu(unsigned int cpu)
-+static int scss_release_secondary(unsigned int cpu)
- {
--	int ret;
--	ret = scm_set_boot_addr(virt_to_phys(secondary_startup),
--				SCM_FLAG_COLDBOOT_CPU1);
--	if (ret == 0) {
--		void __iomem *sc1_base_ptr;
--		sc1_base_ptr = ioremap_nocache(0x00902000, SZ_4K*2);
--		if (sc1_base_ptr) {
--			writel(0, sc1_base_ptr + VDD_SC1_ARRAY_CLAMP_GFS_CTL);
--			writel(0, sc1_base_ptr + SCSS_CPU1CORE_RESET);
--			writel(3, sc1_base_ptr + SCSS_DBG_STATUS_CORE_PWRDUP);
--			iounmap(sc1_base_ptr);
--		}
--	} else
--		printk(KERN_DEBUG "Failed to set secondary core boot "
--				  "address\n");
-+	struct device_node *node;
-+	void __iomem *base;
-+
-+	node = of_find_compatible_node(NULL, NULL, "qcom,gcc-msm8660");
-+	if (!node) {
-+		pr_err("%s: can't find node\n", __func__);
-+		return -ENXIO;
-+	}
-+
-+	base = of_iomap(node, 0);
-+	of_node_put(node);
-+	if (!base)
-+		return -ENOMEM;
-+
-+	writel_relaxed(0, base + VDD_SC1_ARRAY_CLAMP_GFS_CTL);
-+	writel_relaxed(0, base + SCSS_CPU1CORE_RESET);
-+	writel_relaxed(3, base + SCSS_DBG_STATUS_CORE_PWRDUP);
-+	mb();
-+	iounmap(base);
-+
-+	return 0;
- }
- 
--static int qcom_boot_secondary(unsigned int cpu, struct task_struct *idle)
-+static DEFINE_PER_CPU(int, cold_boot_done);
-+
-+static int qcom_boot_secondary(unsigned int cpu, int (*func)(unsigned int))
- {
--	static int cold_boot_done;
-+	int ret = 0;
- 
--	/* Only need to bring cpu out of reset this way once */
--	if (cold_boot_done == false) {
--		prepare_cold_cpu(cpu);
--		cold_boot_done = true;
-+	if (!per_cpu(cold_boot_done, cpu)) {
-+		ret = func(cpu);
-+		if (!ret)
-+			per_cpu(cold_boot_done, cpu) = true;
- 	}
- 
- 	/*
-@@ -99,39 +102,48 @@ static int qcom_boot_secondary(unsigned
- 	 */
- 	spin_unlock(&boot_lock);
- 
--	return 0;
-+	return ret;
- }
- 
--/*
-- * Initialise the CPU possible map early - this describes the CPUs
-- * which may be present or become present in the system. The msm8x60
-- * does not support the ARM SCU, so just set the possible cpu mask to
-- * NR_CPUS.
-- */
--static void __init qcom_smp_init_cpus(void)
--{
--	unsigned int i, ncores = get_core_count();
--
--	if (ncores > nr_cpu_ids) {
--		pr_warn("SMP: %u cores greater than maximum (%u), clipping\n",
--			ncores, nr_cpu_ids);
--		ncores = nr_cpu_ids;
--	}
--
--	for (i = 0; i < ncores; i++)
--		set_cpu_possible(i, true);
-+static int msm8660_boot_secondary(unsigned int cpu, struct task_struct *idle)
-+{
-+	return qcom_boot_secondary(cpu, scss_release_secondary);
- }
- 
- static void __init qcom_smp_prepare_cpus(unsigned int max_cpus)
- {
-+	int cpu, map;
-+	unsigned int flags = 0;
-+	static const int cold_boot_flags[] = {
-+		0,
-+		SCM_FLAG_COLDBOOT_CPU1,
-+	};
-+
-+	for_each_present_cpu(cpu) {
-+		map = cpu_logical_map(cpu);
-+		if (WARN_ON(map >= ARRAY_SIZE(cold_boot_flags))) {
-+			set_cpu_present(cpu, false);
-+			continue;
-+		}
-+		flags |= cold_boot_flags[map];
-+	}
-+
-+	if (scm_set_boot_addr(virt_to_phys(secondary_startup), flags)) {
-+		for_each_present_cpu(cpu) {
-+			if (cpu == smp_processor_id())
-+				continue;
-+			set_cpu_present(cpu, false);
-+		}
-+		pr_warn("Failed to set CPU boot address, disabling SMP\n");
-+	}
- }
- 
--struct smp_operations qcom_smp_ops __initdata = {
--	.smp_init_cpus		= qcom_smp_init_cpus,
-+static struct smp_operations smp_msm8660_ops __initdata = {
- 	.smp_prepare_cpus	= qcom_smp_prepare_cpus,
- 	.smp_secondary_init	= qcom_secondary_init,
--	.smp_boot_secondary	= qcom_boot_secondary,
-+	.smp_boot_secondary	= msm8660_boot_secondary,
- #ifdef CONFIG_HOTPLUG_CPU
- 	.cpu_die		= qcom_cpu_die,
- #endif
- };
-+CPU_METHOD_OF_DECLARE(qcom_smp, "qcom,gcc-msm8660", &smp_msm8660_ops);
diff --git a/target/linux/ipq806x/patches/0010-devicetree-bindings-Document-Krait-Scorpion-cpus-and.patch b/target/linux/ipq806x/patches/0010-devicetree-bindings-Document-Krait-Scorpion-cpus-and.patch
deleted file mode 100644
index 751aa85..0000000
--- a/target/linux/ipq806x/patches/0010-devicetree-bindings-Document-Krait-Scorpion-cpus-and.patch
+++ /dev/null
@@ -1,65 +0,0 @@
-From 236d07c7bb0c758ea40ea0110d37306d2e7d9a4b Mon Sep 17 00:00:00 2001
-From: Rohit Vaswani <rvaswani@codeaurora.org>
-Date: Thu, 31 Oct 2013 17:26:33 -0700
-Subject: [PATCH 010/182] devicetree: bindings: Document Krait/Scorpion cpus
- and enable-method
-
-Scorpion and Krait don't use the spin-table enable-method.
-Instead they rely on mmio register accesses to enable power and
-clocks to bring CPUs out of reset. Document their enable-methods.
-
-Cc: <devicetree@vger.kernel.org>
-Signed-off-by: Rohit Vaswani <rvaswani@codeaurora.org>
-[sboyd: Split off into separate patch, renamed methods to
-match compatible nodes]
-Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
-Signed-off-by: Kumar Gala <galak@codeaurora.org>
----
- Documentation/devicetree/bindings/arm/cpus.txt |   25 +++++++++++++++++++++++-
- 1 file changed, 24 insertions(+), 1 deletion(-)
-
---- a/Documentation/devicetree/bindings/arm/cpus.txt
-+++ b/Documentation/devicetree/bindings/arm/cpus.txt
-@@ -180,7 +180,11 @@ nodes to be present and contain the prop
- 			  be one of:
- 			     "spin-table"
- 			     "psci"
--			# On ARM 32-bit systems this property is optional.
-+			# On ARM 32-bit systems this property is optional and
-+			  can be one of:
-+			    "qcom,gcc-msm8660"
-+			    "qcom,kpss-acc-v1"
-+			    "qcom,kpss-acc-v2"
- 
- 	- cpu-release-addr
- 		Usage: required for systems that have an "enable-method"
-@@ -191,6 +195,21 @@ nodes to be present and contain the prop
- 			  property identifying a 64-bit zero-initialised
- 			  memory location.
- 
-+	- qcom,saw
-+		Usage: required for systems that have an "enable-method"
-+		       property value of "qcom,kpss-acc-v1" or
-+		       "qcom,kpss-acc-v2"
-+		Value type: <phandle>
-+		Definition: Specifies the SAW[1] node associated with this CPU.
-+
-+	- qcom,acc
-+		Usage: required for systems that have an "enable-method"
-+		       property value of "qcom,kpss-acc-v1" or
-+		       "qcom,kpss-acc-v2"
-+		Value type: <phandle>
-+		Definition: Specifies the ACC[2] node associated with this CPU.
-+
-+
- Example 1 (dual-cluster big.LITTLE system 32-bit):
- 
- 	cpus {
-@@ -382,3 +401,7 @@ cpus {
- 		cpu-release-addr = <0 0x20000000>;
- 	};
- };
-+
-+--
-+[1] arm/msm/qcom,saw2.txt
-+[2] arm/msm/qcom,kpss-acc.txt
diff --git a/target/linux/ipq806x/patches/0011-devicetree-bindings-Document-qcom-kpss-acc.patch b/target/linux/ipq806x/patches/0011-devicetree-bindings-Document-qcom-kpss-acc.patch
deleted file mode 100644
index dfd4c32..0000000
--- a/target/linux/ipq806x/patches/0011-devicetree-bindings-Document-qcom-kpss-acc.patch
+++ /dev/null
@@ -1,49 +0,0 @@
-From 3a4fe9a3a4aff8b1f1c3685bc9b6adbe739d7367 Mon Sep 17 00:00:00 2001
-From: Stephen Boyd <sboyd@codeaurora.org>
-Date: Thu, 31 Oct 2013 18:20:30 -0700
-Subject: [PATCH 011/182] devicetree: bindings: Document qcom,kpss-acc
-
-The kpss acc binding describes the clock, reset, and power domain
-controller for a Krait CPU.
-
-Cc: <devicetree@vger.kernel.org>
-Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
-Signed-off-by: Kumar Gala <galak@codeaurora.org>
----
- .../devicetree/bindings/arm/msm/qcom,kpss-acc.txt  |   30 ++++++++++++++++++++
- 1 file changed, 30 insertions(+)
- create mode 100644 Documentation/devicetree/bindings/arm/msm/qcom,kpss-acc.txt
-
---- /dev/null
-+++ b/Documentation/devicetree/bindings/arm/msm/qcom,kpss-acc.txt
-@@ -0,0 +1,30 @@
-+Krait Processor Sub-system (KPSS) Application Clock Controller (ACC)
-+
-+The KPSS ACC provides clock, power domain, and reset control to a Krait CPU.
-+There is one ACC register region per CPU within the KPSS remapped region as
-+well as an alias register region that remaps accesses to the ACC associated
-+with the CPU accessing the region.
-+
-+PROPERTIES
-+
-+- compatible:
-+	Usage: required
-+	Value type: <string>
-+	Definition: should be one of:
-+			"qcom,kpss-acc-v1"
-+			"qcom,kpss-acc-v2"
-+
-+- reg:
-+	Usage: required
-+	Value type: <prop-encoded-array>
-+	Definition: the first element specifies the base address and size of
-+		    the register region. An optional second element specifies
-+		    the base address and size of the alias register region.
-+
-+Example:
-+
-+	clock-controller@2088000 {
-+		compatible = "qcom,kpss-acc-v2";
-+		reg = <0x02088000 0x1000>,
-+		      <0x02008000 0x1000>;
-+	};
diff --git a/target/linux/ipq806x/patches/0012-devicetree-bindings-Document-qcom-saw2-node.patch b/target/linux/ipq806x/patches/0012-devicetree-bindings-Document-qcom-saw2-node.patch
deleted file mode 100644
index 79aaf2d..0000000
--- a/target/linux/ipq806x/patches/0012-devicetree-bindings-Document-qcom-saw2-node.patch
+++ /dev/null
@@ -1,54 +0,0 @@
-From 17adce4d3de1fca7761607d572f4979557f0f604 Mon Sep 17 00:00:00 2001
-From: Stephen Boyd <sboyd@codeaurora.org>
-Date: Thu, 31 Oct 2013 18:20:30 -0700
-Subject: [PATCH 012/182] devicetree: bindings: Document qcom,saw2 node
-
-The saw2 binding describes the SPM/AVS wrapper hardware used to
-control the regulator supplying voltage to the Krait CPUs.
-
-Cc: <devicetree@vger.kernel.org>
-Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
-Signed-off-by: Kumar Gala <galak@codeaurora.org>
----
- .../devicetree/bindings/arm/msm/qcom,saw2.txt      |   35 ++++++++++++++++++++
- 1 file changed, 35 insertions(+)
- create mode 100644 Documentation/devicetree/bindings/arm/msm/qcom,saw2.txt
-
---- /dev/null
-+++ b/Documentation/devicetree/bindings/arm/msm/qcom,saw2.txt
-@@ -0,0 +1,35 @@
-+SPM AVS Wrapper 2 (SAW2)
-+
-+The SAW2 is a wrapper around the Subsystem Power Manager (SPM) and the
-+Adaptive Voltage Scaling (AVS) hardware. The SPM is a programmable
-+micro-controller that transitions a piece of hardware (like a processor or
-+subsystem) into and out of low power modes via a direct connection to
-+the PMIC. It can also be wired up to interact with other processors in the
-+system, notifying them when a low power state is entered or exited.
-+
-+PROPERTIES
-+
-+- compatible:
-+	Usage: required
-+	Value type: <string>
-+	Definition: shall contain "qcom,saw2". A more specific value should be
-+		    one of:
-+			 "qcom,saw2-v1"
-+			 "qcom,saw2-v1.1"
-+			 "qcom,saw2-v2"
-+			 "qcom,saw2-v2.1"
-+
-+- reg:
-+	Usage: required
-+	Value type: <prop-encoded-array>
-+	Definition: the first element specifies the base address and size of
-+		    the register region. An optional second element specifies
-+		    the base address and size of the alias register region.
-+
-+
-+Example:
-+
-+	regulator@2099000 {
-+		compatible = "qcom,saw2";
-+		reg = <0x02099000 0x1000>, <0x02009000 0x1000>;
-+	};
diff --git a/target/linux/ipq806x/patches/0013-ARM-qcom-Add-SMP-support-for-KPSSv1.patch b/target/linux/ipq806x/patches/0013-ARM-qcom-Add-SMP-support-for-KPSSv1.patch
deleted file mode 100644
index e1d9ae1..0000000
--- a/target/linux/ipq806x/patches/0013-ARM-qcom-Add-SMP-support-for-KPSSv1.patch
+++ /dev/null
@@ -1,174 +0,0 @@
-From 8e843640b3c4a43b963332fdc7b233948ad25a5b Mon Sep 17 00:00:00 2001
-From: Rohit Vaswani <rvaswani@codeaurora.org>
-Date: Tue, 21 May 2013 19:13:50 -0700
-Subject: [PATCH 013/182] ARM: qcom: Add SMP support for KPSSv1
-
-Implement support for the Krait CPU release sequence when the
-CPUs are part of the first version of the krait processor
-subsystem.
-
-Signed-off-by: Rohit Vaswani <rvaswani@codeaurora.org>
-Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
-Signed-off-by: Kumar Gala <galak@codeaurora.org>
----
- arch/arm/mach-qcom/platsmp.c  |  106 +++++++++++++++++++++++++++++++++++++++++
- arch/arm/mach-qcom/scm-boot.h |    8 ++--
- 2 files changed, 111 insertions(+), 3 deletions(-)
-
---- a/arch/arm/mach-qcom/platsmp.c
-+++ b/arch/arm/mach-qcom/platsmp.c
-@@ -26,6 +26,16 @@
- #define SCSS_CPU1CORE_RESET		0x2d80
- #define SCSS_DBG_STATUS_CORE_PWRDUP	0x2e64
- 
-+#define APCS_CPU_PWR_CTL	0x04
-+#define PLL_CLAMP		BIT(8)
-+#define CORE_PWRD_UP		BIT(7)
-+#define COREPOR_RST		BIT(5)
-+#define CORE_RST		BIT(4)
-+#define L2DT_SLP		BIT(3)
-+#define CLAMP			BIT(0)
-+
-+#define APCS_SAW2_VCTL		0x14
-+
- extern void secondary_startup(void);
- 
- static DEFINE_SPINLOCK(boot_lock);
-@@ -71,6 +81,85 @@ static int scss_release_secondary(unsign
- 	return 0;
- }
- 
-+static int kpssv1_release_secondary(unsigned int cpu)
-+{
-+	int ret = 0;
-+	void __iomem *reg, *saw_reg;
-+	struct device_node *cpu_node, *acc_node, *saw_node;
-+	u32 val;
-+
-+	cpu_node = of_get_cpu_node(cpu, NULL);
-+	if (!cpu_node)
-+		return -ENODEV;
-+
-+	acc_node = of_parse_phandle(cpu_node, "qcom,acc", 0);
-+	if (!acc_node) {
-+		ret = -ENODEV;
-+		goto out_acc;
-+	}
-+
-+	saw_node = of_parse_phandle(cpu_node, "qcom,saw", 0);
-+	if (!saw_node) {
-+		ret = -ENODEV;
-+		goto out_saw;
-+	}
-+
-+	reg = of_iomap(acc_node, 0);
-+	if (!reg) {
-+		ret = -ENOMEM;
-+		goto out_acc_map;
-+	}
-+
-+	saw_reg = of_iomap(saw_node, 0);
-+	if (!saw_reg) {
-+		ret = -ENOMEM;
-+		goto out_saw_map;
-+	}
-+
-+	/* Turn on CPU rail */
-+	writel_relaxed(0xA4, saw_reg + APCS_SAW2_VCTL);
-+	mb();
-+	udelay(512);
-+
-+	/* Krait bring-up sequence */
-+	val = PLL_CLAMP | L2DT_SLP | CLAMP;
-+	writel_relaxed(val, reg + APCS_CPU_PWR_CTL);
-+	val &= ~L2DT_SLP;
-+	writel_relaxed(val, reg + APCS_CPU_PWR_CTL);
-+	mb();
-+	ndelay(300);
-+
-+	val |= COREPOR_RST;
-+	writel_relaxed(val, reg + APCS_CPU_PWR_CTL);
-+	mb();
-+	udelay(2);
-+
-+	val &= ~CLAMP;
-+	writel_relaxed(val, reg + APCS_CPU_PWR_CTL);
-+	mb();
-+	udelay(2);
-+
-+	val &= ~COREPOR_RST;
-+	writel_relaxed(val, reg + APCS_CPU_PWR_CTL);
-+	mb();
-+	udelay(100);
-+
-+	val |= CORE_PWRD_UP;
-+	writel_relaxed(val, reg + APCS_CPU_PWR_CTL);
-+	mb();
-+
-+	iounmap(saw_reg);
-+out_saw_map:
-+	iounmap(reg);
-+out_acc_map:
-+	of_node_put(saw_node);
-+out_saw:
-+	of_node_put(acc_node);
-+out_acc:
-+	of_node_put(cpu_node);
-+	return ret;
-+}
-+
- static DEFINE_PER_CPU(int, cold_boot_done);
- 
- static int qcom_boot_secondary(unsigned int cpu, int (*func)(unsigned int))
-@@ -110,6 +199,11 @@ static int msm8660_boot_secondary(unsign
- 	return qcom_boot_secondary(cpu, scss_release_secondary);
- }
- 
-+static int kpssv1_boot_secondary(unsigned int cpu, struct task_struct *idle)
-+{
-+	return qcom_boot_secondary(cpu, kpssv1_release_secondary);
-+}
-+
- static void __init qcom_smp_prepare_cpus(unsigned int max_cpus)
- {
- 	int cpu, map;
-@@ -117,6 +211,8 @@ static void __init qcom_smp_prepare_cpus
- 	static const int cold_boot_flags[] = {
- 		0,
- 		SCM_FLAG_COLDBOOT_CPU1,
-+		SCM_FLAG_COLDBOOT_CPU2,
-+		SCM_FLAG_COLDBOOT_CPU3,
- 	};
- 
- 	for_each_present_cpu(cpu) {
-@@ -147,3 +243,13 @@ static struct smp_operations smp_msm8660
- #endif
- };
- CPU_METHOD_OF_DECLARE(qcom_smp, "qcom,gcc-msm8660", &smp_msm8660_ops);
-+
-+static struct smp_operations qcom_smp_kpssv1_ops __initdata = {
-+	.smp_prepare_cpus	= qcom_smp_prepare_cpus,
-+	.smp_secondary_init	= qcom_secondary_init,
-+	.smp_boot_secondary	= kpssv1_boot_secondary,
-+#ifdef CONFIG_HOTPLUG_CPU
-+	.cpu_die		= qcom_cpu_die,
-+#endif
-+};
-+CPU_METHOD_OF_DECLARE(qcom_smp_kpssv1, "qcom,kpss-acc-v1", &qcom_smp_kpssv1_ops);
---- a/arch/arm/mach-qcom/scm-boot.h
-+++ b/arch/arm/mach-qcom/scm-boot.h
-@@ -13,9 +13,11 @@
- #define __MACH_SCM_BOOT_H
- 
- #define SCM_BOOT_ADDR			0x1
--#define SCM_FLAG_COLDBOOT_CPU1		0x1
--#define SCM_FLAG_WARMBOOT_CPU1		0x2
--#define SCM_FLAG_WARMBOOT_CPU0		0x4
-+#define SCM_FLAG_COLDBOOT_CPU1		0x01
-+#define SCM_FLAG_COLDBOOT_CPU2		0x08
-+#define SCM_FLAG_COLDBOOT_CPU3		0x20
-+#define SCM_FLAG_WARMBOOT_CPU0		0x04
-+#define SCM_FLAG_WARMBOOT_CPU1		0x02
- 
- int scm_set_boot_addr(phys_addr_t addr, int flags);
- 
diff --git a/target/linux/ipq806x/patches/0014-ARM-qcom-Add-SMP-support-for-KPSSv2.patch b/target/linux/ipq806x/patches/0014-ARM-qcom-Add-SMP-support-for-KPSSv2.patch
deleted file mode 100644
index 8f8ae49..0000000
--- a/target/linux/ipq806x/patches/0014-ARM-qcom-Add-SMP-support-for-KPSSv2.patch
+++ /dev/null
@@ -1,167 +0,0 @@
-From eb07c23d45ddf10fa89296e6c6c6aed553d8bbf5 Mon Sep 17 00:00:00 2001
-From: Rohit Vaswani <rvaswani@codeaurora.org>
-Date: Fri, 21 Jun 2013 17:09:13 -0700
-Subject: [PATCH 014/182] ARM: qcom: Add SMP support for KPSSv2
-
-Implement support for the Krait CPU release sequence when the
-CPUs are part of the second version of the Krait processor
-subsystem.
-
-Signed-off-by: Rohit Vaswani <rvaswani@codeaurora.org>
-Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
-Signed-off-by: Kumar Gala <galak@codeaurora.org>
----
- arch/arm/mach-qcom/platsmp.c |  123 ++++++++++++++++++++++++++++++++++++++++++
- 1 file changed, 123 insertions(+)
-
---- a/arch/arm/mach-qcom/platsmp.c
-+++ b/arch/arm/mach-qcom/platsmp.c
-@@ -34,7 +34,15 @@
- #define L2DT_SLP		BIT(3)
- #define CLAMP			BIT(0)
- 
-+#define APC_PWR_GATE_CTL	0x14
-+#define BHS_CNT_SHIFT		24
-+#define LDO_PWR_DWN_SHIFT	16
-+#define LDO_BYP_SHIFT		8
-+#define BHS_SEG_SHIFT		1
-+#define BHS_EN			BIT(0)
-+
- #define APCS_SAW2_VCTL		0x14
-+#define APCS_SAW2_2_VCTL	0x1c
- 
- extern void secondary_startup(void);
- 
-@@ -160,6 +168,106 @@ out_acc:
- 	return ret;
- }
- 
-+static int kpssv2_release_secondary(unsigned int cpu)
-+{
-+	void __iomem *reg;
-+	struct device_node *cpu_node, *l2_node, *acc_node, *saw_node;
-+	void __iomem *l2_saw_base;
-+	unsigned reg_val;
-+	int ret;
-+
-+	cpu_node = of_get_cpu_node(cpu, NULL);
-+	if (!cpu_node)
-+		return -ENODEV;
-+
-+	acc_node = of_parse_phandle(cpu_node, "qcom,acc", 0);
-+	if (!acc_node) {
-+		ret = -ENODEV;
-+		goto out_acc;
-+	}
-+
-+	l2_node = of_parse_phandle(cpu_node, "next-level-cache", 0);
-+	if (!l2_node) {
-+		ret = -ENODEV;
-+		goto out_l2;
-+	}
-+
-+	saw_node = of_parse_phandle(l2_node, "qcom,saw", 0);
-+	if (!saw_node) {
-+		ret = -ENODEV;
-+		goto out_saw;
-+	}
-+
-+	reg = of_iomap(acc_node, 0);
-+	if (!reg) {
-+		ret = -ENOMEM;
-+		goto out_map;
-+	}
-+
-+	l2_saw_base = of_iomap(saw_node, 0);
-+	if (!l2_saw_base) {
-+		ret = -ENOMEM;
-+		goto out_saw_map;
-+	}
-+
-+	/* Turn on the BHS, turn off LDO Bypass and power down LDO */
-+	reg_val = (64 << BHS_CNT_SHIFT) | (0x3f << LDO_PWR_DWN_SHIFT) | BHS_EN;
-+	writel_relaxed(reg_val, reg + APC_PWR_GATE_CTL);
-+	mb();
-+	/* wait for the BHS to settle */
-+	udelay(1);
-+
-+	/* Turn on BHS segments */
-+	reg_val |= 0x3f << BHS_SEG_SHIFT;
-+	writel_relaxed(reg_val, reg + APC_PWR_GATE_CTL);
-+	mb();
-+	 /* wait for the BHS to settle */
-+	udelay(1);
-+
-+	/* Finally turn on the bypass so that BHS supplies power */
-+	reg_val |= 0x3f << LDO_BYP_SHIFT;
-+	writel_relaxed(reg_val, reg + APC_PWR_GATE_CTL);
-+
-+	/* enable max phases */
-+	writel_relaxed(0x10003, l2_saw_base + APCS_SAW2_2_VCTL);
-+	mb();
-+	udelay(50);
-+
-+	reg_val = COREPOR_RST | CLAMP;
-+	writel_relaxed(reg_val, reg + APCS_CPU_PWR_CTL);
-+	mb();
-+	udelay(2);
-+
-+	reg_val &= ~CLAMP;
-+	writel_relaxed(reg_val, reg + APCS_CPU_PWR_CTL);
-+	mb();
-+	udelay(2);
-+
-+	reg_val &= ~COREPOR_RST;
-+	writel_relaxed(reg_val, reg + APCS_CPU_PWR_CTL);
-+	mb();
-+
-+	reg_val |= CORE_PWRD_UP;
-+	writel_relaxed(reg_val, reg + APCS_CPU_PWR_CTL);
-+	mb();
-+
-+	ret = 0;
-+
-+	iounmap(l2_saw_base);
-+out_saw_map:
-+	iounmap(reg);
-+out_map:
-+	of_node_put(saw_node);
-+out_saw:
-+	of_node_put(l2_node);
-+out_l2:
-+	of_node_put(acc_node);
-+out_acc:
-+	of_node_put(cpu_node);
-+
-+	return ret;
-+}
-+
- static DEFINE_PER_CPU(int, cold_boot_done);
- 
- static int qcom_boot_secondary(unsigned int cpu, int (*func)(unsigned int))
-@@ -204,6 +312,11 @@ static int kpssv1_boot_secondary(unsigne
- 	return qcom_boot_secondary(cpu, kpssv1_release_secondary);
- }
- 
-+static int kpssv2_boot_secondary(unsigned int cpu, struct task_struct *idle)
-+{
-+	return qcom_boot_secondary(cpu, kpssv2_release_secondary);
-+}
-+
- static void __init qcom_smp_prepare_cpus(unsigned int max_cpus)
- {
- 	int cpu, map;
-@@ -253,3 +366,13 @@ static struct smp_operations qcom_smp_kp
- #endif
- };
- CPU_METHOD_OF_DECLARE(qcom_smp_kpssv1, "qcom,kpss-acc-v1", &qcom_smp_kpssv1_ops);
-+
-+static struct smp_operations qcom_smp_kpssv2_ops __initdata = {
-+	.smp_prepare_cpus	= qcom_smp_prepare_cpus,
-+	.smp_secondary_init	= qcom_secondary_init,
-+	.smp_boot_secondary	= kpssv2_boot_secondary,
-+#ifdef CONFIG_HOTPLUG_CPU
-+	.cpu_die		= qcom_cpu_die,
-+#endif
-+};
-+CPU_METHOD_OF_DECLARE(qcom_smp_kpssv2, "qcom,kpss-acc-v2", &qcom_smp_kpssv2_ops);
diff --git a/target/linux/ipq806x/patches/0015-tty-serial-msm-Enable-building-msm_serial-for-ARCH_Q.patch b/target/linux/ipq806x/patches/0015-tty-serial-msm-Enable-building-msm_serial-for-ARCH_Q.patch
deleted file mode 100644
index 33870dc..0000000
--- a/target/linux/ipq806x/patches/0015-tty-serial-msm-Enable-building-msm_serial-for-ARCH_Q.patch
+++ /dev/null
@@ -1,27 +0,0 @@
-From 17368813d4182894c6d58b66f9fccd339364de8f Mon Sep 17 00:00:00 2001
-From: Kumar Gala <galak@codeaurora.org>
-Date: Wed, 29 Jan 2014 17:23:06 -0600
-Subject: [PATCH 015/182] tty: serial: msm: Enable building msm_serial for
- ARCH_QCOM
-
-We've split Qualcomm MSM support into legacy and multiplatform.  So add
-the ability to build the serial driver on the newer ARCH_QCOM
-multiplatform.
-
-Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-Signed-off-by: Kumar Gala <galak@codeaurora.org>
----
- drivers/tty/serial/Kconfig |    2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/drivers/tty/serial/Kconfig
-+++ b/drivers/tty/serial/Kconfig
-@@ -1024,7 +1024,7 @@ config SERIAL_SGI_IOC3
- 
- config SERIAL_MSM
- 	bool "MSM on-chip serial port support"
--	depends on ARCH_MSM
-+	depends on ARCH_MSM || ARCH_QCOM
- 	select SERIAL_CORE
- 
- config SERIAL_MSM_CONSOLE
diff --git a/target/linux/ipq806x/patches/0016-drm-msm-drop-ARCH_MSM-Kconfig-depend.patch b/target/linux/ipq806x/patches/0016-drm-msm-drop-ARCH_MSM-Kconfig-depend.patch
deleted file mode 100644
index b80ad91..0000000
--- a/target/linux/ipq806x/patches/0016-drm-msm-drop-ARCH_MSM-Kconfig-depend.patch
+++ /dev/null
@@ -1,28 +0,0 @@
-From aa3cf89746c43172517378224277ba961c46e28c Mon Sep 17 00:00:00 2001
-From: Kumar Gala <galak@codeaurora.org>
-Date: Thu, 30 Jan 2014 14:45:05 -0600
-Subject: [PATCH 016/182] drm/msm: drop ARCH_MSM Kconfig depend
-
-The ARCH_MSM depend is redundant with ARCH_MSM8960, so we can remove it.
-Additionally, we are splitting Qualcomm MSM support into legacy (ARCH_MSM)
-and multiplatform (ARCH_QCOM).  The MSM8960 with be ARCH_QCOM going forward
-so dropping ARCH_MSM will work properly for the new ARCH_QCOM multiplatform
-build.
-
-Acked-by: Rob Clark <robdclark@gmail.com>
-Signed-off-by: Kumar Gala <galak@codeaurora.org>
----
- drivers/gpu/drm/msm/Kconfig |    2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/drivers/gpu/drm/msm/Kconfig
-+++ b/drivers/gpu/drm/msm/Kconfig
-@@ -3,7 +3,7 @@ config DRM_MSM
- 	tristate "MSM DRM"
- 	depends on DRM
- 	depends on MSM_IOMMU
--	depends on (ARCH_MSM && ARCH_MSM8960) || (ARM && COMPILE_TEST)
-+	depends on ARCH_MSM8960 || (ARM && COMPILE_TEST)
- 	select DRM_KMS_HELPER
- 	select SHMEM
- 	select TMPFS
diff --git a/target/linux/ipq806x/patches/0017-power-reset-msm-switch-Kconfig-to-ARCH_QCOM-depends.patch b/target/linux/ipq806x/patches/0017-power-reset-msm-switch-Kconfig-to-ARCH_QCOM-depends.patch
deleted file mode 100644
index cf33efd..0000000
--- a/target/linux/ipq806x/patches/0017-power-reset-msm-switch-Kconfig-to-ARCH_QCOM-depends.patch
+++ /dev/null
@@ -1,27 +0,0 @@
-From 6e8707828be07397ee8ee437a6ef1b8f73f82287 Mon Sep 17 00:00:00 2001
-From: Kumar Gala <galak@codeaurora.org>
-Date: Thu, 30 Jan 2014 14:46:08 -0600
-Subject: [PATCH 017/182] power: reset: msm - switch Kconfig to ARCH_QCOM
- depends
-
-We've split Qualcomm MSM support into legacy and multiplatform.  The reset
-driver is only relevant on the multiplatform supported SoCs so switch the
-Kconfig depends to ARCH_QCOM.
-
-Acked-by: Dmitry Eremin-Solenikov
-Signed-off-by: Kumar Gala <galak@codeaurora.org>
----
- drivers/power/reset/Kconfig |    2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/drivers/power/reset/Kconfig
-+++ b/drivers/power/reset/Kconfig
-@@ -22,7 +22,7 @@ config POWER_RESET_GPIO
- 
- config POWER_RESET_MSM
- 	bool "Qualcomm MSM power-off driver"
--	depends on POWER_RESET && ARCH_MSM
-+	depends on POWER_RESET && ARCH_QCOM
- 	help
- 	  Power off and restart support for Qualcomm boards.
- 
diff --git a/target/linux/ipq806x/patches/0018-hwrng-msm-switch-Kconfig-to-ARCH_QCOM-depends.patch b/target/linux/ipq806x/patches/0018-hwrng-msm-switch-Kconfig-to-ARCH_QCOM-depends.patch
deleted file mode 100644
index 89cb8ac..0000000
--- a/target/linux/ipq806x/patches/0018-hwrng-msm-switch-Kconfig-to-ARCH_QCOM-depends.patch
+++ /dev/null
@@ -1,33 +0,0 @@
-From 4aa784548190c69d946b4dfbc0592a3ed7cd18da Mon Sep 17 00:00:00 2001
-From: Kumar Gala <galak@codeaurora.org>
-Date: Thu, 30 Jan 2014 14:43:49 -0600
-Subject: [PATCH 018/182] hwrng: msm: switch Kconfig to ARCH_QCOM depends
-
-We've split Qualcomm MSM support into legacy and multiplatform.  The RNG
-driver is only relevant on the multiplatform supported SoCs so switch the
-Kconfig depends to ARCH_QCOM.
-
-Acked-by: Herbert Xu <herbert@gondor.apana.org.au>
-CC: Stanimir Varbanov <svarbanov@mm-sol.com>
-Signed-off-by: Kumar Gala <galak@codeaurora.org>
----
- drivers/char/hw_random/Kconfig |    6 +++---
- 1 file changed, 3 insertions(+), 3 deletions(-)
-
---- a/drivers/char/hw_random/Kconfig
-+++ b/drivers/char/hw_random/Kconfig
-@@ -342,11 +342,11 @@ config HW_RANDOM_TPM
- 	  If unsure, say Y.
- 
- config HW_RANDOM_MSM
--	tristate "Qualcomm MSM Random Number Generator support"
--	depends on HW_RANDOM && ARCH_MSM
-+	tristate "Qualcomm SoCs Random Number Generator support"
-+	depends on HW_RANDOM && ARCH_QCOM
- 	---help---
- 	  This driver provides kernel-side support for the Random Number
--	  Generator hardware found on Qualcomm MSM SoCs.
-+	  Generator hardware found on Qualcomm SoCs.
- 
- 	  To compile this driver as a module, choose M here. the
- 	  module will be called msm-rng.
diff --git a/target/linux/ipq806x/patches/0019-gpio-msm-switch-Kconfig-to-ARCH_QCOM-depends.patch b/target/linux/ipq806x/patches/0019-gpio-msm-switch-Kconfig-to-ARCH_QCOM-depends.patch
deleted file mode 100644
index 1ead84b..0000000
--- a/target/linux/ipq806x/patches/0019-gpio-msm-switch-Kconfig-to-ARCH_QCOM-depends.patch
+++ /dev/null
@@ -1,27 +0,0 @@
-From 87d52cc8a390c5b208b6f0bddd90a2d01c906616 Mon Sep 17 00:00:00 2001
-From: Kumar Gala <galak@codeaurora.org>
-Date: Tue, 11 Feb 2014 14:08:06 -0600
-Subject: [PATCH 019/182] gpio: msm: switch Kconfig to ARCH_QCOM depends
-
-We've split Qualcomm MSM support into legacy and multiplatform.  The gpio
-msm-v2 driver is only relevant on the multiplatform supported SoCs so
-switch the Kconfig depends to ARCH_QCOM.
-
-CC: Linus Walleij <linus.walleij@linaro.org>
-Acked-by: Alexandre Courbot <gnurou@gmail.com>
-Signed-off-by: Kumar Gala <galak@codeaurora.org>
----
- drivers/gpio/Kconfig |    2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/drivers/gpio/Kconfig
-+++ b/drivers/gpio/Kconfig
-@@ -192,7 +192,7 @@ config GPIO_MSM_V1
- 
- config GPIO_MSM_V2
- 	tristate "Qualcomm MSM GPIO v2"
--	depends on GPIOLIB && OF && ARCH_MSM
-+	depends on GPIOLIB && OF && ARCH_QCOM
- 	help
- 	  Say yes here to support the GPIO interface on ARM v7 based
- 	  Qualcomm MSM chips.  Most of the pins on the MSM can be
diff --git a/target/linux/ipq806x/patches/0020-ARM-qcom-Enable-basic-support-for-Qualcomm-platforms.patch b/target/linux/ipq806x/patches/0020-ARM-qcom-Enable-basic-support-for-Qualcomm-platforms.patch
deleted file mode 100644
index 7c1cb29..0000000
--- a/target/linux/ipq806x/patches/0020-ARM-qcom-Enable-basic-support-for-Qualcomm-platforms.patch
+++ /dev/null
@@ -1,49 +0,0 @@
-From a2f356a6d49f459a2dd681fe4a7c6a55aeb8893f Mon Sep 17 00:00:00 2001
-From: Kumar Gala <galak@codeaurora.org>
-Date: Tue, 25 Feb 2014 14:34:05 -0600
-Subject: [PATCH 020/182] ARM: qcom: Enable basic support for Qualcomm
- platforms in multi_v7_defconfig
-
-Enable support for the MSM8x60, MSM8960, and MSM8974 SoCs, clocks and
-serial console as part of the standard multi_v7_defconfig.
-
-Signed-off-by: Kumar Gala <galak@codeaurora.org>
-[khilman: removed non-qcom changes]
-Signed-off-by: Kevin Hilman <khilman@linaro.org>
----
- arch/arm/configs/multi_v7_defconfig |   10 ++++++++++
- 1 file changed, 10 insertions(+)
-
---- a/arch/arm/configs/multi_v7_defconfig
-+++ b/arch/arm/configs/multi_v7_defconfig
-@@ -31,6 +31,10 @@ CONFIG_SOC_OMAP5=y
- CONFIG_SOC_AM33XX=y
- CONFIG_SOC_DRA7XX=y
- CONFIG_SOC_AM43XX=y
-+CONFIG_ARCH_QCOM=y
-+CONFIG_ARCH_MSM8X60=y
-+CONFIG_ARCH_MSM8960=y
-+CONFIG_ARCH_MSM8974=y
- CONFIG_ARCH_ROCKCHIP=y
- CONFIG_ARCH_SOCFPGA=y
- CONFIG_PLAT_SPEAR=y
-@@ -146,6 +150,8 @@ CONFIG_SERIAL_SIRFSOC_CONSOLE=y
- CONFIG_SERIAL_TEGRA=y
- CONFIG_SERIAL_IMX=y
- CONFIG_SERIAL_IMX_CONSOLE=y
-+CONFIG_SERIAL_MSM=y
-+CONFIG_SERIAL_MSM_CONSOLE=y
- CONFIG_SERIAL_VT8500=y
- CONFIG_SERIAL_VT8500_CONSOLE=y
- CONFIG_SERIAL_OF_PLATFORM=y
-@@ -294,6 +300,10 @@ CONFIG_MFD_NVEC=y
- CONFIG_KEYBOARD_NVEC=y
- CONFIG_SERIO_NVEC_PS2=y
- CONFIG_NVEC_POWER=y
-+CONFIG_COMMON_CLK_QCOM=y
-+CONFIG_MSM_GCC_8660=y
-+CONFIG_MSM_MMCC_8960=y
-+CONFIG_MSM_MMCC_8974=y
- CONFIG_TEGRA_IOMMU_GART=y
- CONFIG_TEGRA_IOMMU_SMMU=y
- CONFIG_MEMORY=y
diff --git a/target/linux/ipq806x/patches/0021-ARM-dts-qcom-Add-nodes-necessary-for-SMP-boot.patch b/target/linux/ipq806x/patches/0021-ARM-dts-qcom-Add-nodes-necessary-for-SMP-boot.patch
deleted file mode 100644
index 232f2ef..0000000
--- a/target/linux/ipq806x/patches/0021-ARM-dts-qcom-Add-nodes-necessary-for-SMP-boot.patch
+++ /dev/null
@@ -1,205 +0,0 @@
-From 5a054211d9380cef5a09da7c5e815c827f330a96 Mon Sep 17 00:00:00 2001
-From: Rohit Vaswani <rvaswani@codeaurora.org>
-Date: Fri, 1 Nov 2013 10:10:40 -0700
-Subject: [PATCH 021/182] ARM: dts: qcom: Add nodes necessary for SMP boot
-
-Add the necessary nodes to support SMP on MSM8660, MSM8960, and
-MSM8974/APQ8074. While we're here also add in the error
-interrupts for the Krait cache error detection.
-
-Signed-off-by: Rohit Vaswani <rvaswani@codeaurora.org>
-[sboyd: Split into separate patch, add error interrupts]
-Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
-Signed-off-by: Kumar Gala <galak@codeaurora.org>
----
- arch/arm/boot/dts/qcom-msm8660.dtsi |   24 ++++++++++++
- arch/arm/boot/dts/qcom-msm8960.dtsi |   52 ++++++++++++++++++++++++++
- arch/arm/boot/dts/qcom-msm8974.dtsi |   69 +++++++++++++++++++++++++++++++++++
- 3 files changed, 145 insertions(+)
-
---- a/arch/arm/boot/dts/qcom-msm8660.dtsi
-+++ b/arch/arm/boot/dts/qcom-msm8660.dtsi
-@@ -9,6 +9,30 @@
- 	compatible = "qcom,msm8660";
- 	interrupt-parent = <&intc>;
- 
-+	cpus {
-+		#address-cells = <1>;
-+		#size-cells = <0>;
-+		compatible = "qcom,scorpion";
-+		enable-method = "qcom,gcc-msm8660";
-+
-+		cpu@0 {
-+			device_type = "cpu";
-+			reg = <0>;
-+			next-level-cache = <&L2>;
-+		};
-+
-+		cpu@1 {
-+			device_type = "cpu";
-+			reg = <1>;
-+			next-level-cache = <&L2>;
-+		};
-+
-+		L2: l2-cache {
-+			compatible = "cache";
-+			cache-level = <2>;
-+		};
-+	};
-+
- 	intc: interrupt-controller@2080000 {
- 		compatible = "qcom,msm-8660-qgic";
- 		interrupt-controller;
---- a/arch/arm/boot/dts/qcom-msm8960.dtsi
-+++ b/arch/arm/boot/dts/qcom-msm8960.dtsi
-@@ -9,6 +9,36 @@
- 	compatible = "qcom,msm8960";
- 	interrupt-parent = <&intc>;
- 
-+	cpus {
-+		#address-cells = <1>;
-+		#size-cells = <0>;
-+		interrupts = <1 14 0x304>;
-+		compatible = "qcom,krait";
-+		enable-method = "qcom,kpss-acc-v1";
-+
-+		cpu@0 {
-+			device_type = "cpu";
-+			reg = <0>;
-+			next-level-cache = <&L2>;
-+			qcom,acc = <&acc0>;
-+			qcom,saw = <&saw0>;
-+		};
-+
-+		cpu@1 {
-+			device_type = "cpu";
-+			reg = <1>;
-+			next-level-cache = <&L2>;
-+			qcom,acc = <&acc1>;
-+			qcom,saw = <&saw1>;
-+		};
-+
-+		L2: l2-cache {
-+			compatible = "cache";
-+			cache-level = <2>;
-+			interrupts = <0 2 0x4>;
-+		};
-+	};
-+
- 	intc: interrupt-controller@2000000 {
- 		compatible = "qcom,msm-qgic2";
- 		interrupt-controller;
-@@ -53,6 +83,28 @@
- 		#reset-cells = <1>;
- 	};
- 
-+	acc0: clock-controller@2088000 {
-+		compatible = "qcom,kpss-acc-v1";
-+		reg = <0x02088000 0x1000>, <0x02008000 0x1000>;
-+	};
-+
-+	acc1: clock-controller@2098000 {
-+		compatible = "qcom,kpss-acc-v1";
-+		reg = <0x02098000 0x1000>, <0x02008000 0x1000>;
-+	};
-+
-+	saw0: regulator@2089000 {
-+		compatible = "qcom,saw2";
-+		reg = <0x02089000 0x1000>, <0x02009000 0x1000>;
-+		regulator;
-+	};
-+
-+	saw1: regulator@2099000 {
-+		compatible = "qcom,saw2";
-+		reg = <0x02099000 0x1000>, <0x02009000 0x1000>;
-+		regulator;
-+	};
-+
- 	serial@16440000 {
- 		compatible = "qcom,msm-uartdm-v1.3", "qcom,msm-uartdm";
- 		reg = <0x16440000 0x1000>,
---- a/arch/arm/boot/dts/qcom-msm8974.dtsi
-+++ b/arch/arm/boot/dts/qcom-msm8974.dtsi
-@@ -9,6 +9,49 @@
- 	compatible = "qcom,msm8974";
- 	interrupt-parent = <&intc>;
- 
-+	cpus {
-+		#address-cells = <1>;
-+		#size-cells = <0>;
-+		interrupts = <1 9 0xf04>;
-+		compatible = "qcom,krait";
-+		enable-method = "qcom,kpss-acc-v2";
-+
-+		cpu@0 {
-+			device_type = "cpu";
-+			reg = <0>;
-+			next-level-cache = <&L2>;
-+			qcom,acc = <&acc0>;
-+		};
-+
-+		cpu@1 {
-+			device_type = "cpu";
-+			reg = <1>;
-+			next-level-cache = <&L2>;
-+			qcom,acc = <&acc1>;
-+		};
-+
-+		cpu@2 {
-+			device_type = "cpu";
-+			reg = <2>;
-+			next-level-cache = <&L2>;
-+			qcom,acc = <&acc2>;
-+		};
-+
-+		cpu@3 {
-+			device_type = "cpu";
-+			reg = <3>;
-+			next-level-cache = <&L2>;
-+			qcom,acc = <&acc3>;
-+		};
-+
-+		L2: l2-cache {
-+			compatible = "cache";
-+			cache-level = <2>;
-+			interrupts = <0 2 0x4>;
-+			qcom,saw = <&saw_l2>;
-+		};
-+	};
-+
- 	soc: soc {
- 		#address-cells = <1>;
- 		#size-cells = <1>;
-@@ -91,6 +134,32 @@
- 			};
- 		};
- 
-+		saw_l2: regulator@f9012000 {
-+			compatible = "qcom,saw2";
-+			reg = <0xf9012000 0x1000>;
-+			regulator;
-+		};
-+
-+		acc0: clock-controller@f9088000 {
-+			compatible = "qcom,kpss-acc-v2";
-+			reg = <0xf9088000 0x1000>, <0xf9008000 0x1000>;
-+		};
-+
-+		acc1: clock-controller@f9098000 {
-+			compatible = "qcom,kpss-acc-v2";
-+			reg = <0xf9098000 0x1000>, <0xf9008000 0x1000>;
-+		};
-+
-+		acc2: clock-controller@f90a8000 {
-+			compatible = "qcom,kpss-acc-v2";
-+			reg = <0xf90a8000 0x1000>, <0xf9008000 0x1000>;
-+		};
-+
-+		acc3: clock-controller@f90b8000 {
-+			compatible = "qcom,kpss-acc-v2";
-+			reg = <0xf90b8000 0x1000>, <0xf9008000 0x1000>;
-+		};
-+
- 		restart@fc4ab000 {
- 			compatible = "qcom,pshold";
- 			reg = <0xfc4ab000 0x4>;
diff --git a/target/linux/ipq806x/patches/0022-ARM-dts-qcom-Add-RNG-device-tree-node.patch b/target/linux/ipq806x/patches/0022-ARM-dts-qcom-Add-RNG-device-tree-node.patch
deleted file mode 100644
index 76cff02..0000000
--- a/target/linux/ipq806x/patches/0022-ARM-dts-qcom-Add-RNG-device-tree-node.patch
+++ /dev/null
@@ -1,30 +0,0 @@
-From b0f93ef8f790e77049b6149416ef0ba05cce7089 Mon Sep 17 00:00:00 2001
-From: Stanimir Varbanov <svarbanov@mm-sol.com>
-Date: Fri, 7 Feb 2014 11:23:07 +0200
-Subject: [PATCH 022/182] ARM: dts: qcom: Add RNG device tree node
-
-Add the necessary DT node to probe the rng driver on
-msm8974 platforms.
-
-Signed-off-by: Stanimir Varbanov <svarbanov@mm-sol.com>
-Acked-by: Stephen Boyd <sboyd@codeaurora.org>
-Signed-off-by: Kumar Gala <galak@codeaurora.org>
----
- arch/arm/boot/dts/qcom-msm8974.dtsi |    7 +++++++
- 1 file changed, 7 insertions(+)
-
---- a/arch/arm/boot/dts/qcom-msm8974.dtsi
-+++ b/arch/arm/boot/dts/qcom-msm8974.dtsi
-@@ -186,5 +186,12 @@
- 			clocks = <&gcc GCC_BLSP1_UART2_APPS_CLK>, <&gcc GCC_BLSP1_AHB_CLK>;
- 			clock-names = "core", "iface";
- 		};
-+
-+		rng@f9bff000 {
-+			compatible = "qcom,prng";
-+			reg = <0xf9bff000 0x200>;
-+			clocks = <&gcc GCC_PRNG_AHB_CLK>;
-+			clock-names = "core";
-+		};
- 	};
- };
diff --git a/target/linux/ipq806x/patches/0023-ARM-dts-qcom-msm8960-cdp-Add-RNG-device-tree-node.patch b/target/linux/ipq806x/patches/0023-ARM-dts-qcom-msm8960-cdp-Add-RNG-device-tree-node.patch
deleted file mode 100644
index 36206d4..0000000
--- a/target/linux/ipq806x/patches/0023-ARM-dts-qcom-msm8960-cdp-Add-RNG-device-tree-node.patch
+++ /dev/null
@@ -1,29 +0,0 @@
-From 82bedcd5ad0b3ac8fe78f4be25b2ffa0691d7804 Mon Sep 17 00:00:00 2001
-From: Stanimir Varbanov <svarbanov@mm-sol.com>
-Date: Wed, 19 Feb 2014 16:33:06 +0200
-Subject: [PATCH 023/182] ARM: dts: qcom-msm8960-cdp: Add RNG device tree node
-
-Add the necessary DT node to probe the rng driver on
-msm8960-cdp platform.
-
-Signed-off-by: Stanimir Varbanov <svarbanov@mm-sol.com>
-Tested-by: Stephen Boyd <sboyd@codeaurora.org>
-Signed-off-by: Kumar Gala <galak@codeaurora.org>
----
- arch/arm/boot/dts/qcom-msm8960.dtsi |    7 +++++++
- 1 file changed, 7 insertions(+)
-
---- a/arch/arm/boot/dts/qcom-msm8960.dtsi
-+++ b/arch/arm/boot/dts/qcom-msm8960.dtsi
-@@ -119,4 +119,11 @@
- 		reg = <0x500000 0x1000>;
- 		qcom,controller-type = "pmic-arbiter";
- 	};
-+
-+	rng@1a500000 {
-+		compatible = "qcom,prng";
-+		reg = <0x1a500000 0x200>;
-+		clocks = <&gcc PRNG_CLK>;
-+		clock-names = "core";
-+	};
- };
diff --git a/target/linux/ipq806x/patches/0024-ARM-dts-msm-Add-krait-pmu-to-platforms-with-Krait-CP.patch b/target/linux/ipq806x/patches/0024-ARM-dts-msm-Add-krait-pmu-to-platforms-with-Krait-CP.patch
deleted file mode 100644
index b0cefc2..0000000
--- a/target/linux/ipq806x/patches/0024-ARM-dts-msm-Add-krait-pmu-to-platforms-with-Krait-CP.patch
+++ /dev/null
@@ -1,46 +0,0 @@
-From 02c987fb8a3607ab6e0ead0e5aaa7da753ce9537 Mon Sep 17 00:00:00 2001
-From: Stephen Boyd <sboyd@codeaurora.org>
-Date: Fri, 21 Feb 2014 11:09:50 +0000
-Subject: [PATCH 024/182] ARM: dts: msm: Add krait-pmu to platforms with Krait
- CPUs
-
-Allows us to probe the performance counters on Krait CPUs.
-
-Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
-Signed-off-by: Will Deacon <will.deacon@arm.com>
-[olof: Moved 8960 contents to the dtsi instead]
-Signed-off-by: Olof Johansson <olof@lixom.net>
----
- arch/arm/boot/dts/qcom-msm8960.dtsi |    6 ++++++
- arch/arm/boot/dts/qcom-msm8974.dtsi |    5 +++++
- 2 files changed, 11 insertions(+)
-
---- a/arch/arm/boot/dts/qcom-msm8960.dtsi
-+++ b/arch/arm/boot/dts/qcom-msm8960.dtsi
-@@ -39,6 +39,12 @@
- 		};
- 	};
- 
-+	cpu-pmu {
-+		compatible = "qcom,krait-pmu";
-+		interrupts = <1 10 0x304>;
-+		qcom,no-pc-write;
-+	};
-+
- 	intc: interrupt-controller@2000000 {
- 		compatible = "qcom,msm-qgic2";
- 		interrupt-controller;
---- a/arch/arm/boot/dts/qcom-msm8974.dtsi
-+++ b/arch/arm/boot/dts/qcom-msm8974.dtsi
-@@ -52,6 +52,11 @@
- 		};
- 	};
- 
-+	cpu-pmu {
-+		compatible = "qcom,krait-pmu";
-+		interrupts = <1 7 0xf04>;
-+	};
-+
- 	soc: soc {
- 		#address-cells = <1>;
- 		#size-cells = <1>;
diff --git a/target/linux/ipq806x/patches/0025-pinctrl-msm-drop-wake_irqs-bitmap.patch b/target/linux/ipq806x/patches/0025-pinctrl-msm-drop-wake_irqs-bitmap.patch
deleted file mode 100644
index d0771ff..0000000
--- a/target/linux/ipq806x/patches/0025-pinctrl-msm-drop-wake_irqs-bitmap.patch
+++ /dev/null
@@ -1,66 +0,0 @@
-From ef8eb0991f291df12c12477648235f955cc388b0 Mon Sep 17 00:00:00 2001
-From: Josh Cartwright <joshc@codeaurora.org>
-Date: Wed, 5 Mar 2014 13:33:08 -0600
-Subject: [PATCH 025/182] pinctrl: msm: drop wake_irqs bitmap
-
-Currently, the wake_irqs bitmap is used to track whether there are any
-gpio's which are configured as wake irqs, and uses this to determine
-whether or not to call enable_irq_wake()/disable_irq_wake() on the
-summary interrupt.
-
-However, the genirq core already handles this case, by maintaining a
-'wake_count' per irq_desc, and only calling into the controlling
-irq_chip when wake_count transitions 0 <-> 1.
-
-Drop this bitmap, and unconditionally call irq_set_irq_wake() on the
-summary interrupt.
-
-Signed-off-by: Josh Cartwright <joshc@codeaurora.org>
-Acked-by: Bjorn Andersson <bjorn.andersson@sonymobile.com>
-Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
----
- drivers/pinctrl/pinctrl-msm.c |   14 +-------------
- 1 file changed, 1 insertion(+), 13 deletions(-)
-
---- a/drivers/pinctrl/pinctrl-msm.c
-+++ b/drivers/pinctrl/pinctrl-msm.c
-@@ -50,7 +50,6 @@
-  * @enabled_irqs:   Bitmap of currently enabled irqs.
-  * @dual_edge_irqs: Bitmap of irqs that need sw emulated dual edge
-  *                  detection.
-- * @wake_irqs:      Bitmap of irqs with requested as wakeup source.
-  * @soc;            Reference to soc_data of platform specific data.
-  * @regs:           Base address for the TLMM register map.
-  */
-@@ -65,7 +64,6 @@ struct msm_pinctrl {
- 
- 	DECLARE_BITMAP(dual_edge_irqs, MAX_NR_GPIO);
- 	DECLARE_BITMAP(enabled_irqs, MAX_NR_GPIO);
--	DECLARE_BITMAP(wake_irqs, MAX_NR_GPIO);
- 
- 	const struct msm_pinctrl_soc_data *soc;
- 	void __iomem *regs;
-@@ -783,22 +781,12 @@ static int msm_gpio_irq_set_wake(struct
- {
- 	struct msm_pinctrl *pctrl;
- 	unsigned long flags;
--	unsigned ngpio;
- 
- 	pctrl = irq_data_get_irq_chip_data(d);
--	ngpio = pctrl->chip.ngpio;
- 
- 	spin_lock_irqsave(&pctrl->lock, flags);
- 
--	if (on) {
--		if (bitmap_empty(pctrl->wake_irqs, ngpio))
--			enable_irq_wake(pctrl->irq);
--		set_bit(d->hwirq, pctrl->wake_irqs);
--	} else {
--		clear_bit(d->hwirq, pctrl->wake_irqs);
--		if (bitmap_empty(pctrl->wake_irqs, ngpio))
--			disable_irq_wake(pctrl->irq);
--	}
-+	irq_set_irq_wake(pctrl->irq, on);
- 
- 	spin_unlock_irqrestore(&pctrl->lock, flags);
- 
diff --git a/target/linux/ipq806x/patches/0026-pinctrl-msm-Silence-recursive-lockdep-warning.patch b/target/linux/ipq806x/patches/0026-pinctrl-msm-Silence-recursive-lockdep-warning.patch
deleted file mode 100644
index fe5008e..0000000
--- a/target/linux/ipq806x/patches/0026-pinctrl-msm-Silence-recursive-lockdep-warning.patch
+++ /dev/null
@@ -1,68 +0,0 @@
-From 9588c91936434166007c3a15ad7f4e2f3729c5e7 Mon Sep 17 00:00:00 2001
-From: Stephen Boyd <sboyd@codeaurora.org>
-Date: Thu, 6 Mar 2014 22:44:40 -0800
-Subject: [PATCH 026/182] pinctrl: msm: Silence recursive lockdep warning
-
-If a driver calls enable_irq_wake() on a gpio turned interrupt
-from the msm pinctrl driver we'll get a lockdep warning like so:
-
-=============================================
-[ INFO: possible recursive locking detected ]
-3.14.0-rc3 #2 Not tainted
----------------------------------------------
-modprobe/52 is trying to acquire lock:
- (&irq_desc_lock_class){-.....}, at: [<c026aea0>] __irq_get_desc_lock+0x48/0x88
-
-but task is already holding lock:
- (&irq_desc_lock_class){-.....}, at: [<c026aea0>] __irq_get_desc_lock+0x48/0x88
-
-other info that might help us debug this:
- Possible unsafe locking scenario:
-
-       CPU0
-       ----
-  lock(&irq_desc_lock_class);
-  lock(&irq_desc_lock_class);
-
- *** DEADLOCK ***
-
- May be due to missing lock nesting notation
-
-4 locks held by modprobe/52:
- #0:  (&__lockdep_no_validate__){......}, at: [<c04f2864>] __driver_attach+0x48/0x98
- #1:  (&__lockdep_no_validate__){......}, at: [<c04f2874>] __driver_attach+0x58/0x98
- #2:  (&irq_desc_lock_class){-.....}, at: [<c026aea0>] __irq_get_desc_lock+0x48/0x88
- #3:  (&(&pctrl->lock)->rlock){......}, at: [<c04bb4b8>] msm_gpio_irq_set_wake+0x20/0xa8
-
-Silence it by putting the gpios into their own lock class.
-
-Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
-Acked-by: Bjorn Andersson <bjorn.andersson@sonymobile.com>
-Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
----
- drivers/pinctrl/pinctrl-msm.c |    7 +++++++
- 1 file changed, 7 insertions(+)
-
---- a/drivers/pinctrl/pinctrl-msm.c
-+++ b/drivers/pinctrl/pinctrl-msm.c
-@@ -857,6 +857,12 @@ static void msm_gpio_irq_handler(unsigne
- 	chained_irq_exit(chip, desc);
- }
- 
-+/*
-+ * This lock class tells lockdep that GPIO irqs are in a different
-+ * category than their parents, so it won't report false recursion.
-+ */
-+static struct lock_class_key gpio_lock_class;
-+
- static int msm_gpio_init(struct msm_pinctrl *pctrl)
- {
- 	struct gpio_chip *chip;
-@@ -895,6 +901,7 @@ static int msm_gpio_init(struct msm_pinc
- 
- 	for (i = 0; i < chip->ngpio; i++) {
- 		irq = irq_create_mapping(pctrl->domain, i);
-+		irq_set_lockdep_class(irq, &gpio_lock_class);
- 		irq_set_chip_and_handler(irq, &msm_gpio_irq_chip, handle_edge_irq);
- 		irq_set_chip_data(irq, pctrl);
- 	}
diff --git a/target/linux/ipq806x/patches/0027-pinctrl-msm-Check-for-ngpios-MAX_NR_GPIO.patch b/target/linux/ipq806x/patches/0027-pinctrl-msm-Check-for-ngpios-MAX_NR_GPIO.patch
deleted file mode 100644
index 7cf4b14..0000000
--- a/target/linux/ipq806x/patches/0027-pinctrl-msm-Check-for-ngpios-MAX_NR_GPIO.patch
+++ /dev/null
@@ -1,34 +0,0 @@
-From 8341db7b05b688e8e5a93acd0e80b40be409d037 Mon Sep 17 00:00:00 2001
-From: Stephen Boyd <sboyd@codeaurora.org>
-Date: Thu, 6 Mar 2014 22:44:41 -0800
-Subject: [PATCH 027/182] pinctrl: msm: Check for ngpios > MAX_NR_GPIO
-
-Fail the probe and print a warning if SoC specific drivers have
-more GPIOs than there can be accounted for in the static bitmaps.
-This should avoid silent corruption/failures in the future.
-
-Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
-Acked-by: Bjorn Andersson <bjorn.andersson@sonymobile.com>
-Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
----
- drivers/pinctrl/pinctrl-msm.c |    6 +++++-
- 1 file changed, 5 insertions(+), 1 deletion(-)
-
---- a/drivers/pinctrl/pinctrl-msm.c
-+++ b/drivers/pinctrl/pinctrl-msm.c
-@@ -870,10 +870,14 @@ static int msm_gpio_init(struct msm_pinc
- 	int ret;
- 	int i;
- 	int r;
-+	unsigned ngpio = pctrl->soc->ngpios;
-+
-+	if (WARN_ON(ngpio > MAX_NR_GPIO))
-+		return -EINVAL;
- 
- 	chip = &pctrl->chip;
- 	chip->base = 0;
--	chip->ngpio = pctrl->soc->ngpios;
-+	chip->ngpio = ngpio;
- 	chip->label = dev_name(pctrl->dev);
- 	chip->dev = pctrl->dev;
- 	chip->owner = THIS_MODULE;
diff --git a/target/linux/ipq806x/patches/0028-pinctrl-msm-Drop-unused-includes.patch b/target/linux/ipq806x/patches/0028-pinctrl-msm-Drop-unused-includes.patch
deleted file mode 100644
index d8cd970..0000000
--- a/target/linux/ipq806x/patches/0028-pinctrl-msm-Drop-unused-includes.patch
+++ /dev/null
@@ -1,51 +0,0 @@
-From d2caa906f865d6919c511a956ae63ab62b240eba Mon Sep 17 00:00:00 2001
-From: Stephen Boyd <sboyd@codeaurora.org>
-Date: Thu, 6 Mar 2014 22:44:42 -0800
-Subject: [PATCH 028/182] pinctrl: msm: Drop unused includes
-
-These includes are unused or can be handled via forward
-declarations. Remove them.
-
-Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
-Acked-by: Bjorn Andersson <bjorn.andersson@sonymobile.com>
-Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
----
- drivers/pinctrl/pinctrl-msm.c     |    1 -
- drivers/pinctrl/pinctrl-msm.h     |    5 +----
- drivers/pinctrl/pinctrl-msm8x74.c |    1 -
- 3 files changed, 1 insertion(+), 6 deletions(-)
-
---- a/drivers/pinctrl/pinctrl-msm.c
-+++ b/drivers/pinctrl/pinctrl-msm.c
-@@ -28,7 +28,6 @@
- #include <linux/interrupt.h>
- #include <linux/irq.h>
- #include <linux/irqchip/chained_irq.h>
--#include <linux/of_irq.h>
- #include <linux/spinlock.h>
- 
- #include "core.h"
---- a/drivers/pinctrl/pinctrl-msm.h
-+++ b/drivers/pinctrl/pinctrl-msm.h
-@@ -13,10 +13,7 @@
- #ifndef __PINCTRL_MSM_H__
- #define __PINCTRL_MSM_H__
- 
--#include <linux/pinctrl/pinctrl.h>
--#include <linux/pinctrl/pinmux.h>
--#include <linux/pinctrl/pinconf.h>
--#include <linux/pinctrl/machine.h>
-+struct pinctrl_pin_desc;
- 
- /**
-  * struct msm_function - a pinmux function
---- a/drivers/pinctrl/pinctrl-msm8x74.c
-+++ b/drivers/pinctrl/pinctrl-msm8x74.c
-@@ -15,7 +15,6 @@
- #include <linux/of.h>
- #include <linux/platform_device.h>
- #include <linux/pinctrl/pinctrl.h>
--#include <linux/pinctrl/pinmux.h>
- 
- #include "pinctrl-msm.h"
- 
diff --git a/target/linux/ipq806x/patches/0029-pinctrl-msm-Drop-OF_IRQ-dependency.patch b/target/linux/ipq806x/patches/0029-pinctrl-msm-Drop-OF_IRQ-dependency.patch
deleted file mode 100644
index 1357f3b..0000000
--- a/target/linux/ipq806x/patches/0029-pinctrl-msm-Drop-OF_IRQ-dependency.patch
+++ /dev/null
@@ -1,26 +0,0 @@
-From 2cfbd01bd994bd16dbee28a99553796f12848c4c Mon Sep 17 00:00:00 2001
-From: Stephen Boyd <sboyd@codeaurora.org>
-Date: Thu, 6 Mar 2014 22:44:43 -0800
-Subject: [PATCH 029/182] pinctrl: msm: Drop OF_IRQ dependency
-
-This driver doesn't rely on any functionality living in
-drivers/of/irq.c to compile. Drop this dependency.
-
-Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
-Acked-by: Bjorn Andersson <bjorn.andersson@sonymobile.com>
-Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
----
- drivers/pinctrl/Kconfig |    2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/drivers/pinctrl/Kconfig
-+++ b/drivers/pinctrl/Kconfig
-@@ -224,7 +224,7 @@ config PINCTRL_MSM
- 
- config PINCTRL_MSM8X74
- 	tristate "Qualcomm 8x74 pin controller driver"
--	depends on GPIOLIB && OF && OF_IRQ
-+	depends on GPIOLIB && OF
- 	select PINCTRL_MSM
- 	help
- 	  This is the pinctrl, pinmux, pinconf and gpiolib driver for the
diff --git a/target/linux/ipq806x/patches/0030-pinctrl-msm-Replace-lookup-tables-with-math.patch b/target/linux/ipq806x/patches/0030-pinctrl-msm-Replace-lookup-tables-with-math.patch
deleted file mode 100644
index 6bc94af..0000000
--- a/target/linux/ipq806x/patches/0030-pinctrl-msm-Replace-lookup-tables-with-math.patch
+++ /dev/null
@@ -1,61 +0,0 @@
-From e34d9fdac8182f6ce8933501fea6e84664060bf0 Mon Sep 17 00:00:00 2001
-From: Stephen Boyd <sboyd@codeaurora.org>
-Date: Thu, 6 Mar 2014 22:44:44 -0800
-Subject: [PATCH 030/182] pinctrl: msm: Replace lookup tables with math
-
-We don't need to waste space with these lookup tables, just do
-the math directly.
-
-Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
-Acked-by: Bjorn Andersson <bjorn.andersson@sonymobile.com>
-Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
----
- drivers/pinctrl/pinctrl-msm.c |   14 ++++++++------
- 1 file changed, 8 insertions(+), 6 deletions(-)
-
---- a/drivers/pinctrl/pinctrl-msm.c
-+++ b/drivers/pinctrl/pinctrl-msm.c
-@@ -258,8 +258,10 @@ static int msm_config_set(struct pinctrl
- #define MSM_PULL_DOWN	1
- #define MSM_PULL_UP	3
- 
--static const unsigned msm_regval_to_drive[] = { 2, 4, 6, 8, 10, 12, 14, 16 };
--static const unsigned msm_drive_to_regval[] = { -1, -1, 0, -1, 1, -1, 2, -1, 3, -1, 4, -1, 5, -1, 6, -1, 7 };
-+static unsigned msm_regval_to_drive(u32 val)
-+{
-+	return (val + 1) * 2;
-+}
- 
- static int msm_config_group_get(struct pinctrl_dev *pctldev,
- 				unsigned int group,
-@@ -296,7 +298,7 @@ static int msm_config_group_get(struct p
- 		arg = arg == MSM_PULL_UP;
- 		break;
- 	case PIN_CONFIG_DRIVE_STRENGTH:
--		arg = msm_regval_to_drive[arg];
-+		arg = msm_regval_to_drive(arg);
- 		break;
- 	default:
- 		dev_err(pctrl->dev, "Unsupported config parameter: %x\n",
-@@ -349,10 +351,10 @@ static int msm_config_group_set(struct p
- 			break;
- 		case PIN_CONFIG_DRIVE_STRENGTH:
- 			/* Check for invalid values */
--			if (arg >= ARRAY_SIZE(msm_drive_to_regval))
-+			if (arg > 16 || arg < 2 || (arg % 2) != 0)
- 				arg = -1;
- 			else
--				arg = msm_drive_to_regval[arg];
-+				arg = (arg / 2) - 1;
- 			break;
- 		default:
- 			dev_err(pctrl->dev, "Unsupported config parameter: %x\n",
-@@ -531,7 +533,7 @@ static void msm_gpio_dbg_show_one(struct
- 	pull = (ctl_reg >> g->pull_bit) & 3;
- 
- 	seq_printf(s, " %-8s: %-3s %d", g->name, is_out ? "out" : "in", func);
--	seq_printf(s, " %dmA", msm_regval_to_drive[drive]);
-+	seq_printf(s, " %dmA", msm_regval_to_drive(drive));
- 	seq_printf(s, " %s", pulls[pull]);
- }
- 
diff --git a/target/linux/ipq806x/patches/0031-pinctrl-msm-Remove-impossible-WARN_ON-s.patch b/target/linux/ipq806x/patches/0031-pinctrl-msm-Remove-impossible-WARN_ON-s.patch
deleted file mode 100644
index 3356efc..0000000
--- a/target/linux/ipq806x/patches/0031-pinctrl-msm-Remove-impossible-WARN_ON-s.patch
+++ /dev/null
@@ -1,90 +0,0 @@
-From 286113578287b9c7619b4104864cffb91820f49d Mon Sep 17 00:00:00 2001
-From: Stephen Boyd <sboyd@codeaurora.org>
-Date: Thu, 6 Mar 2014 22:44:45 -0800
-Subject: [PATCH 031/182] pinctrl: msm: Remove impossible WARN_ON()s
-
-All these functions are limited in what they can pass as the gpio
-or irq number to whatever is setup during probe. Remove the
-checks.
-
-Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
-Acked-by: Bjorn Andersson <bjorn.andersson@sonymobile.com>
-Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
----
- drivers/pinctrl/pinctrl-msm.c |   16 ----------------
- 1 file changed, 16 deletions(-)
-
---- a/drivers/pinctrl/pinctrl-msm.c
-+++ b/drivers/pinctrl/pinctrl-msm.c
-@@ -401,8 +401,6 @@ static int msm_gpio_direction_input(stru
- 	u32 val;
- 
- 	g = &pctrl->soc->groups[offset];
--	if (WARN_ON(g->io_reg < 0))
--		return -EINVAL;
- 
- 	spin_lock_irqsave(&pctrl->lock, flags);
- 
-@@ -423,8 +421,6 @@ static int msm_gpio_direction_output(str
- 	u32 val;
- 
- 	g = &pctrl->soc->groups[offset];
--	if (WARN_ON(g->io_reg < 0))
--		return -EINVAL;
- 
- 	spin_lock_irqsave(&pctrl->lock, flags);
- 
-@@ -451,8 +447,6 @@ static int msm_gpio_get(struct gpio_chip
- 	u32 val;
- 
- 	g = &pctrl->soc->groups[offset];
--	if (WARN_ON(g->io_reg < 0))
--		return -EINVAL;
- 
- 	val = readl(pctrl->regs + g->io_reg);
- 	return !!(val & BIT(g->in_bit));
-@@ -466,8 +460,6 @@ static void msm_gpio_set(struct gpio_chi
- 	u32 val;
- 
- 	g = &pctrl->soc->groups[offset];
--	if (WARN_ON(g->io_reg < 0))
--		return;
- 
- 	spin_lock_irqsave(&pctrl->lock, flags);
- 
-@@ -616,8 +608,6 @@ static void msm_gpio_irq_mask(struct irq
- 
- 	pctrl = irq_data_get_irq_chip_data(d);
- 	g = &pctrl->soc->groups[d->hwirq];
--	if (WARN_ON(g->intr_cfg_reg < 0))
--		return;
- 
- 	spin_lock_irqsave(&pctrl->lock, flags);
- 
-@@ -639,8 +629,6 @@ static void msm_gpio_irq_unmask(struct i
- 
- 	pctrl = irq_data_get_irq_chip_data(d);
- 	g = &pctrl->soc->groups[d->hwirq];
--	if (WARN_ON(g->intr_status_reg < 0))
--		return;
- 
- 	spin_lock_irqsave(&pctrl->lock, flags);
- 
-@@ -666,8 +654,6 @@ static void msm_gpio_irq_ack(struct irq_
- 
- 	pctrl = irq_data_get_irq_chip_data(d);
- 	g = &pctrl->soc->groups[d->hwirq];
--	if (WARN_ON(g->intr_status_reg < 0))
--		return;
- 
- 	spin_lock_irqsave(&pctrl->lock, flags);
- 
-@@ -692,8 +678,6 @@ static int msm_gpio_irq_set_type(struct
- 
- 	pctrl = irq_data_get_irq_chip_data(d);
- 	g = &pctrl->soc->groups[d->hwirq];
--	if (WARN_ON(g->intr_cfg_reg < 0))
--		return -EINVAL;
- 
- 	spin_lock_irqsave(&pctrl->lock, flags);
- 
diff --git a/target/linux/ipq806x/patches/0032-pinctrl-msm-Simplify-msm_config_reg-and-callers.patch b/target/linux/ipq806x/patches/0032-pinctrl-msm-Simplify-msm_config_reg-and-callers.patch
deleted file mode 100644
index f7798ae..0000000
--- a/target/linux/ipq806x/patches/0032-pinctrl-msm-Simplify-msm_config_reg-and-callers.patch
+++ /dev/null
@@ -1,110 +0,0 @@
-From 2d9ffb1a3f87396c3b792124870ef63fc27c568f Mon Sep 17 00:00:00 2001
-From: Stephen Boyd <sboyd@codeaurora.org>
-Date: Thu, 6 Mar 2014 22:44:46 -0800
-Subject: [PATCH 032/182] pinctrl: msm: Simplify msm_config_reg() and callers
-
-We don't need to check for a negative reg here because reg is
-always the same and is always non-negative. Also, collapse the
-switch statement down for the duplicate cases.
-
-Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
-Acked-by: Bjorn Andersson <bjorn.andersson@sonymobile.com>
-Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
----
- drivers/pinctrl/pinctrl-msm.c |   29 +++++------------------------
- 1 file changed, 5 insertions(+), 24 deletions(-)
-
---- a/drivers/pinctrl/pinctrl-msm.c
-+++ b/drivers/pinctrl/pinctrl-msm.c
-@@ -200,28 +200,17 @@ static const struct pinmux_ops msm_pinmu
- static int msm_config_reg(struct msm_pinctrl *pctrl,
- 			  const struct msm_pingroup *g,
- 			  unsigned param,
--			  s16 *reg,
- 			  unsigned *mask,
- 			  unsigned *bit)
- {
- 	switch (param) {
- 	case PIN_CONFIG_BIAS_DISABLE:
--		*reg = g->ctl_reg;
--		*bit = g->pull_bit;
--		*mask = 3;
--		break;
- 	case PIN_CONFIG_BIAS_PULL_DOWN:
--		*reg = g->ctl_reg;
--		*bit = g->pull_bit;
--		*mask = 3;
--		break;
- 	case PIN_CONFIG_BIAS_PULL_UP:
--		*reg = g->ctl_reg;
- 		*bit = g->pull_bit;
- 		*mask = 3;
- 		break;
- 	case PIN_CONFIG_DRIVE_STRENGTH:
--		*reg = g->ctl_reg;
- 		*bit = g->drv_bit;
- 		*mask = 7;
- 		break;
-@@ -230,12 +219,6 @@ static int msm_config_reg(struct msm_pin
- 		return -ENOTSUPP;
- 	}
- 
--	if (*reg < 0) {
--		dev_err(pctrl->dev, "Config param %04x not supported on group %s\n",
--			param, g->name);
--		return -ENOTSUPP;
--	}
--
- 	return 0;
- }
- 
-@@ -273,17 +256,16 @@ static int msm_config_group_get(struct p
- 	unsigned mask;
- 	unsigned arg;
- 	unsigned bit;
--	s16 reg;
- 	int ret;
- 	u32 val;
- 
- 	g = &pctrl->soc->groups[group];
- 
--	ret = msm_config_reg(pctrl, g, param, &reg, &mask, &bit);
-+	ret = msm_config_reg(pctrl, g, param, &mask, &bit);
- 	if (ret < 0)
- 		return ret;
- 
--	val = readl(pctrl->regs + reg);
-+	val = readl(pctrl->regs + g->ctl_reg);
- 	arg = (val >> bit) & mask;
- 
- 	/* Convert register value to pinconf value */
-@@ -323,7 +305,6 @@ static int msm_config_group_set(struct p
- 	unsigned mask;
- 	unsigned arg;
- 	unsigned bit;
--	s16 reg;
- 	int ret;
- 	u32 val;
- 	int i;
-@@ -334,7 +315,7 @@ static int msm_config_group_set(struct p
- 		param = pinconf_to_config_param(configs[i]);
- 		arg = pinconf_to_config_argument(configs[i]);
- 
--		ret = msm_config_reg(pctrl, g, param, &reg, &mask, &bit);
-+		ret = msm_config_reg(pctrl, g, param, &mask, &bit);
- 		if (ret < 0)
- 			return ret;
- 
-@@ -369,10 +350,10 @@ static int msm_config_group_set(struct p
- 		}
- 
- 		spin_lock_irqsave(&pctrl->lock, flags);
--		val = readl(pctrl->regs + reg);
-+		val = readl(pctrl->regs + g->ctl_reg);
- 		val &= ~(mask << bit);
- 		val |= arg << bit;
--		writel(val, pctrl->regs + reg);
-+		writel(val, pctrl->regs + g->ctl_reg);
- 		spin_unlock_irqrestore(&pctrl->lock, flags);
- 	}
- 
diff --git a/target/linux/ipq806x/patches/0033-pinctrl-msm-Support-output-high-low-configuration.patch b/target/linux/ipq806x/patches/0033-pinctrl-msm-Support-output-high-low-configuration.patch
deleted file mode 100644
index f2f7c7d..0000000
--- a/target/linux/ipq806x/patches/0033-pinctrl-msm-Support-output-high-low-configuration.patch
+++ /dev/null
@@ -1,64 +0,0 @@
-From 469f83e0ed374250be5fd6202ac535276a752fa8 Mon Sep 17 00:00:00 2001
-From: Bjorn Andersson <bjorn@kryo.se>
-Date: Tue, 4 Feb 2014 19:55:31 -0800
-Subject: [PATCH 033/182] pinctrl-msm: Support output-{high,low} configuration
-
-Add support for configuring pins as output with value as from the
-pinconf-generic interface.
-
-Signed-off-by: Bjorn Andersson <bjorn.andersson@sonymobile.com>
-Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
----
- drivers/pinctrl/pinctrl-msm.c |   27 +++++++++++++++++++++++++++
- 1 file changed, 27 insertions(+)
-
---- a/drivers/pinctrl/pinctrl-msm.c
-+++ b/drivers/pinctrl/pinctrl-msm.c
-@@ -214,6 +214,11 @@ static int msm_config_reg(struct msm_pin
- 		*bit = g->drv_bit;
- 		*mask = 7;
- 		break;
-+	case PIN_CONFIG_OUTPUT:
-+		*reg = g->ctl_reg;
-+		*bit = g->oe_bit;
-+		*mask = 1;
-+		break;
- 	default:
- 		dev_err(pctrl->dev, "Invalid config param %04x\n", param);
- 		return -ENOTSUPP;
-@@ -282,6 +287,14 @@ static int msm_config_group_get(struct p
- 	case PIN_CONFIG_DRIVE_STRENGTH:
- 		arg = msm_regval_to_drive(arg);
- 		break;
-+	case PIN_CONFIG_OUTPUT:
-+		/* Pin is not output */
-+		if (!arg)
-+			return -EINVAL;
-+
-+		val = readl(pctrl->regs + g->io_reg);
-+		arg = !!(val & BIT(g->in_bit));
-+		break;
- 	default:
- 		dev_err(pctrl->dev, "Unsupported config parameter: %x\n",
- 			param);
-@@ -337,6 +350,20 @@ static int msm_config_group_set(struct p
- 			else
- 				arg = (arg / 2) - 1;
- 			break;
-+		case PIN_CONFIG_OUTPUT:
-+			/* set output value */
-+			spin_lock_irqsave(&pctrl->lock, flags);
-+			val = readl(pctrl->regs + g->io_reg);
-+			if (arg)
-+				val |= BIT(g->out_bit);
-+			else
-+				val &= ~BIT(g->out_bit);
-+			writel(val, pctrl->regs + g->io_reg);
-+			spin_unlock_irqrestore(&pctrl->lock, flags);
-+
-+			/* enable output */
-+			arg = 1;
-+			break;
- 		default:
- 			dev_err(pctrl->dev, "Unsupported config parameter: %x\n",
- 				param);
diff --git a/target/linux/ipq806x/patches/0034-pinctrl-msm-Add-SPI8-pin-definitions.patch b/target/linux/ipq806x/patches/0034-pinctrl-msm-Add-SPI8-pin-definitions.patch
deleted file mode 100644
index a3f6d6a..0000000
--- a/target/linux/ipq806x/patches/0034-pinctrl-msm-Add-SPI8-pin-definitions.patch
+++ /dev/null
@@ -1,58 +0,0 @@
-From 77e4b572fcc4015e235f22fd93b8df35e452baf0 Mon Sep 17 00:00:00 2001
-From: "Ivan T. Ivanov" <iivanov@mm-sol.com>
-Date: Thu, 6 Feb 2014 17:28:48 +0200
-Subject: [PATCH 034/182] pinctrl-msm: Add SPI8 pin definitions
-
-Add pin, group and function definitions for SPI#8
-controller.
-
-Signed-off-by: Ivan T. Ivanov <iivanov@mm-sol.com>
-Acked-by: Bjorn Andersson <bjorn.andersson@sonymobile.com>
-Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
----
- drivers/pinctrl/pinctrl-msm8x74.c |   13 +++++++++----
- 1 file changed, 9 insertions(+), 4 deletions(-)
-
---- a/drivers/pinctrl/pinctrl-msm8x74.c
-+++ b/drivers/pinctrl/pinctrl-msm8x74.c
-@@ -405,6 +405,7 @@ enum msm8x74_functions {
- 	MSM_MUX_blsp_i2c6,
- 	MSM_MUX_blsp_i2c11,
- 	MSM_MUX_blsp_spi1,
-+	MSM_MUX_blsp_spi8,
- 	MSM_MUX_blsp_uart2,
- 	MSM_MUX_blsp_uart8,
- 	MSM_MUX_slimbus,
-@@ -415,6 +416,9 @@ static const char * const blsp_i2c2_grou
- static const char * const blsp_i2c6_groups[] = { "gpio29", "gpio30" };
- static const char * const blsp_i2c11_groups[] = { "gpio83", "gpio84" };
- static const char * const blsp_spi1_groups[] = { "gpio0", "gpio1", "gpio2", "gpio3" };
-+static const char * const blsp_spi8_groups[] = {
-+	"gpio45", "gpio46", "gpio47", "gpio48"
-+};
- static const char * const blsp_uart2_groups[] = { "gpio4", "gpio5" };
- static const char * const blsp_uart8_groups[] = { "gpio45", "gpio46" };
- static const char * const slimbus_groups[] = { "gpio70", "gpio71" };
-@@ -424,6 +428,7 @@ static const struct msm_function msm8x74
- 	FUNCTION(blsp_i2c6),
- 	FUNCTION(blsp_i2c11),
- 	FUNCTION(blsp_spi1),
-+	FUNCTION(blsp_spi8),
- 	FUNCTION(blsp_uart2),
- 	FUNCTION(blsp_uart8),
- 	FUNCTION(slimbus),
-@@ -475,10 +480,10 @@ static const struct msm_pingroup msm8x74
- 	PINGROUP(42,  NA, NA, NA, NA, NA, NA, NA),
- 	PINGROUP(43,  NA, NA, NA, NA, NA, NA, NA),
- 	PINGROUP(44,  NA, NA, NA, NA, NA, NA, NA),
--	PINGROUP(45,  NA, blsp_uart8, NA, NA, NA, NA, NA),
--	PINGROUP(46,  NA, blsp_uart8, NA, NA, NA, NA, NA),
--	PINGROUP(47,  NA, NA, NA, NA, NA, NA, NA),
--	PINGROUP(48,  NA, NA, NA, NA, NA, NA, NA),
-+	PINGROUP(45,  blsp_spi8, blsp_uart8, NA, NA, NA, NA, NA),
-+	PINGROUP(46,  blsp_spi8, blsp_uart8, NA, NA, NA, NA, NA),
-+	PINGROUP(47,  blsp_spi8, NA, NA, NA, NA, NA, NA),
-+	PINGROUP(48,  blsp_spi8, NA, NA, NA, NA, NA, NA),
- 	PINGROUP(49,  NA, NA, NA, NA, NA, NA, NA),
- 	PINGROUP(50,  NA, NA, NA, NA, NA, NA, NA),
- 	PINGROUP(51,  NA, NA, NA, NA, NA, NA, NA),
diff --git a/target/linux/ipq806x/patches/0035-pinctrl-msm-fix-up-out-of-order-merge-conflict.patch b/target/linux/ipq806x/patches/0035-pinctrl-msm-fix-up-out-of-order-merge-conflict.patch
deleted file mode 100644
index f0bd614..0000000
--- a/target/linux/ipq806x/patches/0035-pinctrl-msm-fix-up-out-of-order-merge-conflict.patch
+++ /dev/null
@@ -1,33 +0,0 @@
-From c73a138dd24049d06fe7b22518655ed9e7413cd2 Mon Sep 17 00:00:00 2001
-From: Linus Walleij <linus.walleij@linaro.org>
-Date: Fri, 14 Mar 2014 07:54:20 +0100
-Subject: [PATCH 035/182] pinctrl: msm: fix up out-of-order merge conflict
-
-Commit 051a58b4622f0e1b732acb750097c64bc00ddb93
-"pinctrl: msm: Simplify msm_config_reg() and callers"
-removed the local "reg" variable in the msm_config_reg()
-function, but the earlier
-commit ed118a5fd951bd2def8249ee251842c4f81fe4bd
-"pinctrl-msm: Support output-{high,low} configuration"
-introduced a new switchclause using it.
-
-Fix this up by removing the offending register assignment.
-
-Reported-by: Kbuild test robot <fengguang.wu@intel.com>
-Cc: Stephen Boyd <sboyd@codeaurora.org>
-Acked-by: Bjorn Andersson <bjorn.andersson@sonymobile.com>
-Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
----
- drivers/pinctrl/pinctrl-msm.c |    1 -
- 1 file changed, 1 deletion(-)
-
---- a/drivers/pinctrl/pinctrl-msm.c
-+++ b/drivers/pinctrl/pinctrl-msm.c
-@@ -215,7 +215,6 @@ static int msm_config_reg(struct msm_pin
- 		*mask = 7;
- 		break;
- 	case PIN_CONFIG_OUTPUT:
--		*reg = g->ctl_reg;
- 		*bit = g->oe_bit;
- 		*mask = 1;
- 		break;
diff --git a/target/linux/ipq806x/patches/0036-pinctrl-msm-Correct-interrupt-code-for-TLMM-v2.patch b/target/linux/ipq806x/patches/0036-pinctrl-msm-Correct-interrupt-code-for-TLMM-v2.patch
deleted file mode 100644
index 384e183..0000000
--- a/target/linux/ipq806x/patches/0036-pinctrl-msm-Correct-interrupt-code-for-TLMM-v2.patch
+++ /dev/null
@@ -1,48 +0,0 @@
-From 32787a9bba5a1ebeea891fd7aab954e6d344892a Mon Sep 17 00:00:00 2001
-From: Bjorn Andersson <bjorn.andersson@sonymobile.com>
-Date: Mon, 31 Mar 2014 14:49:54 -0700
-Subject: [PATCH 036/182] pinctrl: msm: Correct interrupt code for TLMM v2
-
-Acking interrupts are done differently between on v2 and v3, so add an extra
-attribute to the pingroup struct to let the platform definitions control this.
-Also make sure to start dual edge detection by detecting the rising edge.
-
-Signed-off-by: Bjorn Andersson <bjorn.andersson@sonymobile.com>
-Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
----
- drivers/pinctrl/pinctrl-msm.c |    6 +++++-
- drivers/pinctrl/pinctrl-msm.h |    1 +
- 2 files changed, 6 insertions(+), 1 deletion(-)
-
---- a/drivers/pinctrl/pinctrl-msm.c
-+++ b/drivers/pinctrl/pinctrl-msm.c
-@@ -665,7 +665,10 @@ static void msm_gpio_irq_ack(struct irq_
- 	spin_lock_irqsave(&pctrl->lock, flags);
- 
- 	val = readl(pctrl->regs + g->intr_status_reg);
--	val &= ~BIT(g->intr_status_bit);
-+	if (g->intr_ack_high)
-+		val |= BIT(g->intr_status_bit);
-+	else
-+		val &= ~BIT(g->intr_status_bit);
- 	writel(val, pctrl->regs + g->intr_status_reg);
- 
- 	if (test_bit(d->hwirq, pctrl->dual_edge_irqs))
-@@ -744,6 +747,7 @@ static int msm_gpio_irq_set_type(struct
- 			break;
- 		case IRQ_TYPE_EDGE_BOTH:
- 			val |= BIT(g->intr_detection_bit);
-+			val |= BIT(g->intr_polarity_bit);
- 			break;
- 		case IRQ_TYPE_LEVEL_LOW:
- 			break;
---- a/drivers/pinctrl/pinctrl-msm.h
-+++ b/drivers/pinctrl/pinctrl-msm.h
-@@ -84,6 +84,7 @@ struct msm_pingroup {
- 
- 	unsigned intr_enable_bit:5;
- 	unsigned intr_status_bit:5;
-+	unsigned intr_ack_high:1;
- 
- 	unsigned intr_target_bit:5;
- 	unsigned intr_raw_status_bit:5;
diff --git a/target/linux/ipq806x/patches/0037-pinctrl-msm-Make-number-of-functions-variable.patch b/target/linux/ipq806x/patches/0037-pinctrl-msm-Make-number-of-functions-variable.patch
deleted file mode 100644
index e36498b..0000000
--- a/target/linux/ipq806x/patches/0037-pinctrl-msm-Make-number-of-functions-variable.patch
+++ /dev/null
@@ -1,65 +0,0 @@
-From 1c11b14dd6d740e997919f0bf789bf921548dc0f Mon Sep 17 00:00:00 2001
-From: Bjorn Andersson <bjorn.andersson@sonymobile.com>
-Date: Mon, 31 Mar 2014 14:49:55 -0700
-Subject: [PATCH 037/182] pinctrl: msm: Make number of functions variable
-
-The various pins may have different number of functions defined, so make this
-number definable per pin instead of just increasing it to the largest one for
-all of the platforms.
-
-Signed-off-by: Bjorn Andersson <bjorn.andersson@sonymobile.com>
-Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
----
- drivers/pinctrl/pinctrl-msm.c     |    4 ++--
- drivers/pinctrl/pinctrl-msm.h     |    3 ++-
- drivers/pinctrl/pinctrl-msm8x74.c |    3 ++-
- 3 files changed, 6 insertions(+), 4 deletions(-)
-
---- a/drivers/pinctrl/pinctrl-msm.c
-+++ b/drivers/pinctrl/pinctrl-msm.c
-@@ -145,12 +145,12 @@ static int msm_pinmux_enable(struct pinc
- 	if (WARN_ON(g->mux_bit < 0))
- 		return -EINVAL;
- 
--	for (i = 0; i < ARRAY_SIZE(g->funcs); i++) {
-+	for (i = 0; i < g->nfuncs; i++) {
- 		if (g->funcs[i] == function)
- 			break;
- 	}
- 
--	if (WARN_ON(i == ARRAY_SIZE(g->funcs)))
-+	if (WARN_ON(i == g->nfuncs))
- 		return -EINVAL;
- 
- 	spin_lock_irqsave(&pctrl->lock, flags);
---- a/drivers/pinctrl/pinctrl-msm.h
-+++ b/drivers/pinctrl/pinctrl-msm.h
-@@ -65,7 +65,8 @@ struct msm_pingroup {
- 	const unsigned *pins;
- 	unsigned npins;
- 
--	unsigned funcs[8];
-+	unsigned *funcs;
-+	unsigned nfuncs;
- 
- 	s16 ctl_reg;
- 	s16 io_reg;
---- a/drivers/pinctrl/pinctrl-msm8x74.c
-+++ b/drivers/pinctrl/pinctrl-msm8x74.c
-@@ -341,7 +341,7 @@ static const unsigned int sdc2_data_pins
- 		.name = "gpio" #id,			\
- 		.pins = gpio##id##_pins,		\
- 		.npins = ARRAY_SIZE(gpio##id##_pins),	\
--		.funcs = {				\
-+		.funcs = (int[]){			\
- 			MSM_MUX_NA, /* gpio mode */	\
- 			MSM_MUX_##f1,			\
- 			MSM_MUX_##f2,			\
-@@ -351,6 +351,7 @@ static const unsigned int sdc2_data_pins
- 			MSM_MUX_##f6,			\
- 			MSM_MUX_##f7			\
- 		},					\
-+		.nfuncs = 8,				\
- 		.ctl_reg = 0x1000 + 0x10 * id,		\
- 		.io_reg = 0x1004 + 0x10 * id,		\
- 		.intr_cfg_reg = 0x1008 + 0x10 * id,	\
diff --git a/target/linux/ipq806x/patches/0038-pinctrl-msm-Add-definitions-for-the-APQ8064-platform.patch b/target/linux/ipq806x/patches/0038-pinctrl-msm-Add-definitions-for-the-APQ8064-platform.patch
deleted file mode 100644
index a177d35..0000000
--- a/target/linux/ipq806x/patches/0038-pinctrl-msm-Add-definitions-for-the-APQ8064-platform.patch
+++ /dev/null
@@ -1,614 +0,0 @@
-From 247288012122ccfe7d5d9af00a45814c6fdd94c5 Mon Sep 17 00:00:00 2001
-From: Bjorn Andersson <bjorn.andersson@sonymobile.com>
-Date: Mon, 31 Mar 2014 14:49:57 -0700
-Subject: [PATCH 038/182] pinctrl: msm: Add definitions for the APQ8064
- platform
-
-This adds pinctrl definitions for the GPIO pins of the TLMM v2 block in the
-Qualcomm APQ8064 platform.
-
-Signed-off-by: Bjorn Andersson <bjorn.andersson@sonymobile.com>
-Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
----
- drivers/pinctrl/Kconfig           |    8 +
- drivers/pinctrl/Makefile          |    1 +
- drivers/pinctrl/pinctrl-apq8064.c |  566 +++++++++++++++++++++++++++++++++++++
- 3 files changed, 575 insertions(+)
- create mode 100644 drivers/pinctrl/pinctrl-apq8064.c
-
---- a/drivers/pinctrl/Kconfig
-+++ b/drivers/pinctrl/Kconfig
-@@ -222,6 +222,14 @@ config PINCTRL_MSM
- 	select PINCONF
- 	select GENERIC_PINCONF
- 
-+config PINCTRL_APQ8064
-+	tristate "Qualcomm APQ8064 pin controller driver"
-+	depends on GPIOLIB && OF
-+	select PINCTRL_MSM
-+	help
-+	  This is the pinctrl, pinmux, pinconf and gpiolib driver for the
-+	  Qualcomm TLMM block found in the Qualcomm APQ8064 platform.
-+
- config PINCTRL_MSM8X74
- 	tristate "Qualcomm 8x74 pin controller driver"
- 	depends on GPIOLIB && OF
---- a/drivers/pinctrl/Makefile
-+++ b/drivers/pinctrl/Makefile
-@@ -38,6 +38,7 @@ obj-$(CONFIG_PINCTRL_IMX23)	+= pinctrl-i
- obj-$(CONFIG_PINCTRL_IMX25)	+= pinctrl-imx25.o
- obj-$(CONFIG_PINCTRL_IMX28)	+= pinctrl-imx28.o
- obj-$(CONFIG_PINCTRL_MSM)	+= pinctrl-msm.o
-+obj-$(CONFIG_PINCTRL_APQ8064)	+= pinctrl-apq8064.o
- obj-$(CONFIG_PINCTRL_MSM8X74)	+= pinctrl-msm8x74.o
- obj-$(CONFIG_PINCTRL_NOMADIK)	+= pinctrl-nomadik.o
- obj-$(CONFIG_PINCTRL_STN8815)	+= pinctrl-nomadik-stn8815.o
---- /dev/null
-+++ b/drivers/pinctrl/pinctrl-apq8064.c
-@@ -0,0 +1,566 @@
-+/*
-+ * Copyright (c) 2014, Sony Mobile Communications AB.
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 and
-+ * only version 2 as published by the Free Software Foundation.
-+ *
-+ * 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/of.h>
-+#include <linux/platform_device.h>
-+#include <linux/pinctrl/pinctrl.h>
-+
-+#include "pinctrl-msm.h"
-+
-+static const struct pinctrl_pin_desc apq8064_pins[] = {
-+	PINCTRL_PIN(0, "GPIO_0"),
-+	PINCTRL_PIN(1, "GPIO_1"),
-+	PINCTRL_PIN(2, "GPIO_2"),
-+	PINCTRL_PIN(3, "GPIO_3"),
-+	PINCTRL_PIN(4, "GPIO_4"),
-+	PINCTRL_PIN(5, "GPIO_5"),
-+	PINCTRL_PIN(6, "GPIO_6"),
-+	PINCTRL_PIN(7, "GPIO_7"),
-+	PINCTRL_PIN(8, "GPIO_8"),
-+	PINCTRL_PIN(9, "GPIO_9"),
-+	PINCTRL_PIN(10, "GPIO_10"),
-+	PINCTRL_PIN(11, "GPIO_11"),
-+	PINCTRL_PIN(12, "GPIO_12"),
-+	PINCTRL_PIN(13, "GPIO_13"),
-+	PINCTRL_PIN(14, "GPIO_14"),
-+	PINCTRL_PIN(15, "GPIO_15"),
-+	PINCTRL_PIN(16, "GPIO_16"),
-+	PINCTRL_PIN(17, "GPIO_17"),
-+	PINCTRL_PIN(18, "GPIO_18"),
-+	PINCTRL_PIN(19, "GPIO_19"),
-+	PINCTRL_PIN(20, "GPIO_20"),
-+	PINCTRL_PIN(21, "GPIO_21"),
-+	PINCTRL_PIN(22, "GPIO_22"),
-+	PINCTRL_PIN(23, "GPIO_23"),
-+	PINCTRL_PIN(24, "GPIO_24"),
-+	PINCTRL_PIN(25, "GPIO_25"),
-+	PINCTRL_PIN(26, "GPIO_26"),
-+	PINCTRL_PIN(27, "GPIO_27"),
-+	PINCTRL_PIN(28, "GPIO_28"),
-+	PINCTRL_PIN(29, "GPIO_29"),
-+	PINCTRL_PIN(30, "GPIO_30"),
-+	PINCTRL_PIN(31, "GPIO_31"),
-+	PINCTRL_PIN(32, "GPIO_32"),
-+	PINCTRL_PIN(33, "GPIO_33"),
-+	PINCTRL_PIN(34, "GPIO_34"),
-+	PINCTRL_PIN(35, "GPIO_35"),
-+	PINCTRL_PIN(36, "GPIO_36"),
-+	PINCTRL_PIN(37, "GPIO_37"),
-+	PINCTRL_PIN(38, "GPIO_38"),
-+	PINCTRL_PIN(39, "GPIO_39"),
-+	PINCTRL_PIN(40, "GPIO_40"),
-+	PINCTRL_PIN(41, "GPIO_41"),
-+	PINCTRL_PIN(42, "GPIO_42"),
-+	PINCTRL_PIN(43, "GPIO_43"),
-+	PINCTRL_PIN(44, "GPIO_44"),
-+	PINCTRL_PIN(45, "GPIO_45"),
-+	PINCTRL_PIN(46, "GPIO_46"),
-+	PINCTRL_PIN(47, "GPIO_47"),
-+	PINCTRL_PIN(48, "GPIO_48"),
-+	PINCTRL_PIN(49, "GPIO_49"),
-+	PINCTRL_PIN(50, "GPIO_50"),
-+	PINCTRL_PIN(51, "GPIO_51"),
-+	PINCTRL_PIN(52, "GPIO_52"),
-+	PINCTRL_PIN(53, "GPIO_53"),
-+	PINCTRL_PIN(54, "GPIO_54"),
-+	PINCTRL_PIN(55, "GPIO_55"),
-+	PINCTRL_PIN(56, "GPIO_56"),
-+	PINCTRL_PIN(57, "GPIO_57"),
-+	PINCTRL_PIN(58, "GPIO_58"),
-+	PINCTRL_PIN(59, "GPIO_59"),
-+	PINCTRL_PIN(60, "GPIO_60"),
-+	PINCTRL_PIN(61, "GPIO_61"),
-+	PINCTRL_PIN(62, "GPIO_62"),
-+	PINCTRL_PIN(63, "GPIO_63"),
-+	PINCTRL_PIN(64, "GPIO_64"),
-+	PINCTRL_PIN(65, "GPIO_65"),
-+	PINCTRL_PIN(66, "GPIO_66"),
-+	PINCTRL_PIN(67, "GPIO_67"),
-+	PINCTRL_PIN(68, "GPIO_68"),
-+	PINCTRL_PIN(69, "GPIO_69"),
-+	PINCTRL_PIN(70, "GPIO_70"),
-+	PINCTRL_PIN(71, "GPIO_71"),
-+	PINCTRL_PIN(72, "GPIO_72"),
-+	PINCTRL_PIN(73, "GPIO_73"),
-+	PINCTRL_PIN(74, "GPIO_74"),
-+	PINCTRL_PIN(75, "GPIO_75"),
-+	PINCTRL_PIN(76, "GPIO_76"),
-+	PINCTRL_PIN(77, "GPIO_77"),
-+	PINCTRL_PIN(78, "GPIO_78"),
-+	PINCTRL_PIN(79, "GPIO_79"),
-+	PINCTRL_PIN(80, "GPIO_80"),
-+	PINCTRL_PIN(81, "GPIO_81"),
-+	PINCTRL_PIN(82, "GPIO_82"),
-+	PINCTRL_PIN(83, "GPIO_83"),
-+	PINCTRL_PIN(84, "GPIO_84"),
-+	PINCTRL_PIN(85, "GPIO_85"),
-+	PINCTRL_PIN(86, "GPIO_86"),
-+	PINCTRL_PIN(87, "GPIO_87"),
-+	PINCTRL_PIN(88, "GPIO_88"),
-+	PINCTRL_PIN(89, "GPIO_89"),
-+};
-+
-+#define DECLARE_APQ_GPIO_PINS(pin) static const unsigned int gpio##pin##_pins[] = { pin }
-+DECLARE_APQ_GPIO_PINS(0);
-+DECLARE_APQ_GPIO_PINS(1);
-+DECLARE_APQ_GPIO_PINS(2);
-+DECLARE_APQ_GPIO_PINS(3);
-+DECLARE_APQ_GPIO_PINS(4);
-+DECLARE_APQ_GPIO_PINS(5);
-+DECLARE_APQ_GPIO_PINS(6);
-+DECLARE_APQ_GPIO_PINS(7);
-+DECLARE_APQ_GPIO_PINS(8);
-+DECLARE_APQ_GPIO_PINS(9);
-+DECLARE_APQ_GPIO_PINS(10);
-+DECLARE_APQ_GPIO_PINS(11);
-+DECLARE_APQ_GPIO_PINS(12);
-+DECLARE_APQ_GPIO_PINS(13);
-+DECLARE_APQ_GPIO_PINS(14);
-+DECLARE_APQ_GPIO_PINS(15);
-+DECLARE_APQ_GPIO_PINS(16);
-+DECLARE_APQ_GPIO_PINS(17);
-+DECLARE_APQ_GPIO_PINS(18);
-+DECLARE_APQ_GPIO_PINS(19);
-+DECLARE_APQ_GPIO_PINS(20);
-+DECLARE_APQ_GPIO_PINS(21);
-+DECLARE_APQ_GPIO_PINS(22);
-+DECLARE_APQ_GPIO_PINS(23);
-+DECLARE_APQ_GPIO_PINS(24);
-+DECLARE_APQ_GPIO_PINS(25);
-+DECLARE_APQ_GPIO_PINS(26);
-+DECLARE_APQ_GPIO_PINS(27);
-+DECLARE_APQ_GPIO_PINS(28);
-+DECLARE_APQ_GPIO_PINS(29);
-+DECLARE_APQ_GPIO_PINS(30);
-+DECLARE_APQ_GPIO_PINS(31);
-+DECLARE_APQ_GPIO_PINS(32);
-+DECLARE_APQ_GPIO_PINS(33);
-+DECLARE_APQ_GPIO_PINS(34);
-+DECLARE_APQ_GPIO_PINS(35);
-+DECLARE_APQ_GPIO_PINS(36);
-+DECLARE_APQ_GPIO_PINS(37);
-+DECLARE_APQ_GPIO_PINS(38);
-+DECLARE_APQ_GPIO_PINS(39);
-+DECLARE_APQ_GPIO_PINS(40);
-+DECLARE_APQ_GPIO_PINS(41);
-+DECLARE_APQ_GPIO_PINS(42);
-+DECLARE_APQ_GPIO_PINS(43);
-+DECLARE_APQ_GPIO_PINS(44);
-+DECLARE_APQ_GPIO_PINS(45);
-+DECLARE_APQ_GPIO_PINS(46);
-+DECLARE_APQ_GPIO_PINS(47);
-+DECLARE_APQ_GPIO_PINS(48);
-+DECLARE_APQ_GPIO_PINS(49);
-+DECLARE_APQ_GPIO_PINS(50);
-+DECLARE_APQ_GPIO_PINS(51);
-+DECLARE_APQ_GPIO_PINS(52);
-+DECLARE_APQ_GPIO_PINS(53);
-+DECLARE_APQ_GPIO_PINS(54);
-+DECLARE_APQ_GPIO_PINS(55);
-+DECLARE_APQ_GPIO_PINS(56);
-+DECLARE_APQ_GPIO_PINS(57);
-+DECLARE_APQ_GPIO_PINS(58);
-+DECLARE_APQ_GPIO_PINS(59);
-+DECLARE_APQ_GPIO_PINS(60);
-+DECLARE_APQ_GPIO_PINS(61);
-+DECLARE_APQ_GPIO_PINS(62);
-+DECLARE_APQ_GPIO_PINS(63);
-+DECLARE_APQ_GPIO_PINS(64);
-+DECLARE_APQ_GPIO_PINS(65);
-+DECLARE_APQ_GPIO_PINS(66);
-+DECLARE_APQ_GPIO_PINS(67);
-+DECLARE_APQ_GPIO_PINS(68);
-+DECLARE_APQ_GPIO_PINS(69);
-+DECLARE_APQ_GPIO_PINS(70);
-+DECLARE_APQ_GPIO_PINS(71);
-+DECLARE_APQ_GPIO_PINS(72);
-+DECLARE_APQ_GPIO_PINS(73);
-+DECLARE_APQ_GPIO_PINS(74);
-+DECLARE_APQ_GPIO_PINS(75);
-+DECLARE_APQ_GPIO_PINS(76);
-+DECLARE_APQ_GPIO_PINS(77);
-+DECLARE_APQ_GPIO_PINS(78);
-+DECLARE_APQ_GPIO_PINS(79);
-+DECLARE_APQ_GPIO_PINS(80);
-+DECLARE_APQ_GPIO_PINS(81);
-+DECLARE_APQ_GPIO_PINS(82);
-+DECLARE_APQ_GPIO_PINS(83);
-+DECLARE_APQ_GPIO_PINS(84);
-+DECLARE_APQ_GPIO_PINS(85);
-+DECLARE_APQ_GPIO_PINS(86);
-+DECLARE_APQ_GPIO_PINS(87);
-+DECLARE_APQ_GPIO_PINS(88);
-+DECLARE_APQ_GPIO_PINS(89);
-+
-+#define FUNCTION(fname)					\
-+	[APQ_MUX_##fname] = {				\
-+		.name = #fname,				\
-+		.groups = fname##_groups,		\
-+		.ngroups = ARRAY_SIZE(fname##_groups),	\
-+	}
-+
-+#define PINGROUP(id, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10) \
-+	{						\
-+		.name = "gpio" #id,			\
-+		.pins = gpio##id##_pins,		\
-+		.npins = ARRAY_SIZE(gpio##id##_pins),	\
-+		.funcs = (int[]){			\
-+			APQ_MUX_NA, /* gpio mode */	\
-+			APQ_MUX_##f1,			\
-+			APQ_MUX_##f2,			\
-+			APQ_MUX_##f3,			\
-+			APQ_MUX_##f4,			\
-+			APQ_MUX_##f5,			\
-+			APQ_MUX_##f6,			\
-+			APQ_MUX_##f7,			\
-+			APQ_MUX_##f8,			\
-+			APQ_MUX_##f9,			\
-+			APQ_MUX_##f10,			\
-+		},					\
-+		.nfuncs = 11,				\
-+		.ctl_reg = 0x1000 + 0x10 * id,		\
-+		.io_reg = 0x1004 + 0x10 * id,		\
-+		.intr_cfg_reg = 0x1008 + 0x10 * id,	\
-+		.intr_status_reg = 0x100c + 0x10 * id,	\
-+		.intr_target_reg = 0x400 + 0x4 * id,	\
-+		.mux_bit = 2,				\
-+		.pull_bit = 0,				\
-+		.drv_bit = 6,				\
-+		.oe_bit = 9,				\
-+		.in_bit = 0,				\
-+		.out_bit = 1,				\
-+		.intr_enable_bit = 0,			\
-+		.intr_status_bit = 0,			\
-+		.intr_ack_high = 1,			\
-+		.intr_target_bit = 0,			\
-+		.intr_raw_status_bit = 3,		\
-+		.intr_polarity_bit = 1,			\
-+		.intr_detection_bit = 2,		\
-+		.intr_detection_width = 1,		\
-+	}
-+
-+enum apq8064_functions {
-+	APQ_MUX_cam_mclk,
-+	APQ_MUX_codec_mic_i2s,
-+	APQ_MUX_codec_spkr_i2s,
-+	APQ_MUX_gsbi1,
-+	APQ_MUX_gsbi2,
-+	APQ_MUX_gsbi3,
-+	APQ_MUX_gsbi4,
-+	APQ_MUX_gsbi4_cam_i2c,
-+	APQ_MUX_gsbi5,
-+	APQ_MUX_gsbi5_spi_cs1,
-+	APQ_MUX_gsbi5_spi_cs2,
-+	APQ_MUX_gsbi5_spi_cs3,
-+	APQ_MUX_gsbi6,
-+	APQ_MUX_gsbi6_spi_cs1,
-+	APQ_MUX_gsbi6_spi_cs2,
-+	APQ_MUX_gsbi6_spi_cs3,
-+	APQ_MUX_gsbi7,
-+	APQ_MUX_gsbi7_spi_cs1,
-+	APQ_MUX_gsbi7_spi_cs2,
-+	APQ_MUX_gsbi7_spi_cs3,
-+	APQ_MUX_gsbi_cam_i2c,
-+	APQ_MUX_hdmi,
-+	APQ_MUX_mi2s,
-+	APQ_MUX_riva_bt,
-+	APQ_MUX_riva_fm,
-+	APQ_MUX_riva_wlan,
-+	APQ_MUX_sdc2,
-+	APQ_MUX_sdc4,
-+	APQ_MUX_slimbus,
-+	APQ_MUX_spkr_i2s,
-+	APQ_MUX_tsif1,
-+	APQ_MUX_tsif2,
-+	APQ_MUX_usb2_hsic,
-+	APQ_MUX_NA,
-+};
-+
-+static const char * const cam_mclk_groups[] = {
-+	"gpio4" "gpio5"
-+};
-+static const char * const codec_mic_i2s_groups[] = {
-+	"gpio34", "gpio35", "gpio36", "gpio37", "gpio38"
-+};
-+static const char * const codec_spkr_i2s_groups[] = {
-+	"gpio39", "gpio40", "gpio41", "gpio42"
-+};
-+static const char * const gsbi1_groups[] = {
-+	"gpio18", "gpio19", "gpio20", "gpio21"
-+};
-+static const char * const gsbi2_groups[] = {
-+	"gpio22", "gpio23", "gpio24", "gpio25"
-+};
-+static const char * const gsbi3_groups[] = {
-+	"gpio6", "gpio7", "gpio8", "gpio9"
-+};
-+static const char * const gsbi4_groups[] = {
-+	"gpio10", "gpio11", "gpio12", "gpio13"
-+};
-+static const char * const gsbi4_cam_i2c_groups[] = {
-+	"gpio10", "gpio11", "gpio12", "gpio13"
-+};
-+static const char * const gsbi5_groups[] = {
-+	"gpio51", "gpio52", "gpio53", "gpio54"
-+};
-+static const char * const gsbi5_spi_cs1_groups[] = {
-+	"gpio47"
-+};
-+static const char * const gsbi5_spi_cs2_groups[] = {
-+	"gpio31"
-+};
-+static const char * const gsbi5_spi_cs3_groups[] = {
-+	"gpio32"
-+};
-+static const char * const gsbi6_groups[] = {
-+	"gpio14", "gpio15", "gpio16", "gpio17"
-+};
-+static const char * const gsbi6_spi_cs1_groups[] = {
-+	"gpio47"
-+};
-+static const char * const gsbi6_spi_cs2_groups[] = {
-+	"gpio31"
-+};
-+static const char * const gsbi6_spi_cs3_groups[] = {
-+	"gpio32"
-+};
-+static const char * const gsbi7_groups[] = {
-+	"gpio82", "gpio83", "gpio84", "gpio85"
-+};
-+static const char * const gsbi7_spi_cs1_groups[] = {
-+	"gpio47"
-+};
-+static const char * const gsbi7_spi_cs2_groups[] = {
-+	"gpio31"
-+};
-+static const char * const gsbi7_spi_cs3_groups[] = {
-+	"gpio32"
-+};
-+static const char * const gsbi_cam_i2c_groups[] = {
-+	"gpio10", "gpio11", "gpio12", "gpio13"
-+};
-+static const char * const hdmi_groups[] = {
-+	"gpio69", "gpio70", "gpio71", "gpio72"
-+};
-+static const char * const mi2s_groups[] = {
-+	"gpio27", "gpio28", "gpio29", "gpio30", "gpio31", "gpio32", "gpio33"
-+};
-+static const char * const riva_bt_groups[] = {
-+	"gpio16", "gpio17"
-+};
-+static const char * const riva_fm_groups[] = {
-+	"gpio14", "gpio15"
-+};
-+static const char * const riva_wlan_groups[] = {
-+	"gpio64", "gpio65", "gpio66", "gpio67", "gpio68"
-+};
-+static const char * const sdc2_groups[] = {
-+	"gpio57", "gpio58", "gpio59", "gpio60", "gpio61", "gpio62"
-+};
-+static const char * const sdc4_groups[] = {
-+	"gpio63", "gpio64", "gpio65", "gpio66", "gpio67", "gpio68"
-+};
-+static const char * const slimbus_groups[] = {
-+	"gpio40", "gpio41"
-+};
-+static const char * const spkr_i2s_groups[] = {
-+	"gpio47", "gpio48", "gpio49", "gpio50"
-+};
-+static const char * const tsif1_groups[] = {
-+	"gpio55", "gpio56", "gpio57"
-+};
-+static const char * const tsif2_groups[] = {
-+	"gpio58", "gpio59", "gpio60"
-+};
-+static const char * const usb2_hsic_groups[] = {
-+	"gpio88", "gpio89"
-+};
-+
-+static const struct msm_function apq8064_functions[] = {
-+	FUNCTION(cam_mclk),
-+	FUNCTION(codec_mic_i2s),
-+	FUNCTION(codec_spkr_i2s),
-+	FUNCTION(gsbi1),
-+	FUNCTION(gsbi2),
-+	FUNCTION(gsbi3),
-+	FUNCTION(gsbi4),
-+	FUNCTION(gsbi4_cam_i2c),
-+	FUNCTION(gsbi5),
-+	FUNCTION(gsbi5_spi_cs1),
-+	FUNCTION(gsbi5_spi_cs2),
-+	FUNCTION(gsbi5_spi_cs3),
-+	FUNCTION(gsbi6),
-+	FUNCTION(gsbi6_spi_cs1),
-+	FUNCTION(gsbi6_spi_cs2),
-+	FUNCTION(gsbi6_spi_cs3),
-+	FUNCTION(gsbi7),
-+	FUNCTION(gsbi7_spi_cs1),
-+	FUNCTION(gsbi7_spi_cs2),
-+	FUNCTION(gsbi7_spi_cs3),
-+	FUNCTION(gsbi_cam_i2c),
-+	FUNCTION(hdmi),
-+	FUNCTION(mi2s),
-+	FUNCTION(riva_bt),
-+	FUNCTION(riva_fm),
-+	FUNCTION(riva_wlan),
-+	FUNCTION(sdc2),
-+	FUNCTION(sdc4),
-+	FUNCTION(slimbus),
-+	FUNCTION(spkr_i2s),
-+	FUNCTION(tsif1),
-+	FUNCTION(tsif2),
-+	FUNCTION(usb2_hsic),
-+};
-+
-+static const struct msm_pingroup apq8064_groups[] = {
-+	PINGROUP(0, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-+	PINGROUP(1, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-+	PINGROUP(2, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-+	PINGROUP(3, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-+	PINGROUP(4, NA, NA, cam_mclk, NA, NA, NA, NA, NA, NA, NA),
-+	PINGROUP(5, NA, cam_mclk, NA, NA, NA, NA, NA, NA, NA, NA),
-+	PINGROUP(6, gsbi3, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-+	PINGROUP(7, gsbi3, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-+	PINGROUP(8, gsbi3, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-+	PINGROUP(9, gsbi3, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-+	PINGROUP(10, gsbi4, NA, NA, NA, NA, NA, NA, NA, gsbi4_cam_i2c, NA),
-+	PINGROUP(11, gsbi4, NA, NA, NA, NA, NA, NA, NA, NA, gsbi4_cam_i2c),
-+	PINGROUP(12, gsbi4, NA, NA, NA, NA, gsbi4_cam_i2c, NA, NA, NA, NA),
-+	PINGROUP(13, gsbi4, NA, NA, NA, NA, gsbi4_cam_i2c, NA, NA, NA, NA),
-+	PINGROUP(14, riva_fm, gsbi6, NA, NA, NA, NA, NA, NA, NA, NA),
-+	PINGROUP(15, riva_fm, gsbi6, NA, NA, NA, NA, NA, NA, NA, NA),
-+	PINGROUP(16, riva_bt, gsbi6, NA, NA, NA, NA, NA, NA, NA, NA),
-+	PINGROUP(17, riva_bt, gsbi6, NA, NA, NA, NA, NA, NA, NA, NA),
-+	PINGROUP(18, gsbi1, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-+	PINGROUP(19, gsbi1, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-+	PINGROUP(20, gsbi1, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-+	PINGROUP(21, gsbi1, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-+	PINGROUP(22, gsbi2, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-+	PINGROUP(23, gsbi2, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-+	PINGROUP(24, gsbi2, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-+	PINGROUP(25, gsbi2, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-+	PINGROUP(26, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-+	PINGROUP(27, mi2s, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-+	PINGROUP(28, mi2s, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-+	PINGROUP(29, mi2s, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-+	PINGROUP(30, mi2s, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-+	PINGROUP(31, mi2s, NA, gsbi5_spi_cs2, gsbi6_spi_cs2, gsbi7_spi_cs2, NA, NA, NA, NA, NA),
-+	PINGROUP(32, mi2s, NA, NA, NA, NA, gsbi5_spi_cs3, gsbi6_spi_cs3, gsbi7_spi_cs3, NA, NA),
-+	PINGROUP(33, mi2s, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-+	PINGROUP(34, codec_mic_i2s, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-+	PINGROUP(35, codec_mic_i2s, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-+	PINGROUP(36, codec_mic_i2s, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-+	PINGROUP(37, codec_mic_i2s, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-+	PINGROUP(38, codec_mic_i2s, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-+	PINGROUP(39, codec_spkr_i2s, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-+	PINGROUP(40, slimbus, codec_spkr_i2s, NA, NA, NA, NA, NA, NA, NA, NA),
-+	PINGROUP(41, slimbus, codec_spkr_i2s, NA, NA, NA, NA, NA, NA, NA, NA),
-+	PINGROUP(42, codec_spkr_i2s, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-+	PINGROUP(43, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-+	PINGROUP(44, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-+	PINGROUP(45, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-+	PINGROUP(46, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-+	PINGROUP(47, spkr_i2s, gsbi5_spi_cs1, gsbi6_spi_cs1, gsbi7_spi_cs1, NA, NA, NA, NA, NA, NA),
-+	PINGROUP(48, spkr_i2s, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-+	PINGROUP(49, spkr_i2s, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-+	PINGROUP(50, spkr_i2s, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-+	PINGROUP(51, NA, gsbi5, NA, NA, NA, NA, NA, NA, NA, NA),
-+	PINGROUP(52, NA, gsbi5, NA, NA, NA, NA, NA, NA, NA, NA),
-+	PINGROUP(53, NA, gsbi5, NA, NA, NA, NA, NA, NA, NA, NA),
-+	PINGROUP(54, NA, gsbi5, NA, NA, NA, NA, NA, NA, NA, NA),
-+	PINGROUP(55, tsif1, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-+	PINGROUP(56, tsif1, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-+	PINGROUP(57, tsif1, sdc2, NA, NA, NA, NA, NA, NA, NA, NA),
-+	PINGROUP(58, tsif2, sdc2, NA, NA, NA, NA, NA, NA, NA, NA),
-+	PINGROUP(59, tsif2, sdc2, NA, NA, NA, NA, NA, NA, NA, NA),
-+	PINGROUP(60, tsif2, sdc2, NA, NA, NA, NA, NA, NA, NA, NA),
-+	PINGROUP(61, NA, sdc2, NA, NA, NA, NA, NA, NA, NA, NA),
-+	PINGROUP(62, NA, sdc2, NA, NA, NA, NA, NA, NA, NA, NA),
-+	PINGROUP(63, NA, sdc4, NA, NA, NA, NA, NA, NA, NA, NA),
-+	PINGROUP(64, riva_wlan, sdc4, NA, NA, NA, NA, NA, NA, NA, NA),
-+	PINGROUP(65, riva_wlan, sdc4, NA, NA, NA, NA, NA, NA, NA, NA),
-+	PINGROUP(66, riva_wlan, sdc4, NA, NA, NA, NA, NA, NA, NA, NA),
-+	PINGROUP(67, riva_wlan, sdc4, NA, NA, NA, NA, NA, NA, NA, NA),
-+	PINGROUP(68, riva_wlan, sdc4, NA, NA, NA, NA, NA, NA, NA, NA),
-+	PINGROUP(69, hdmi, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-+	PINGROUP(70, hdmi, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-+	PINGROUP(71, hdmi, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-+	PINGROUP(72, hdmi, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-+	PINGROUP(73, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-+	PINGROUP(74, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-+	PINGROUP(75, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-+	PINGROUP(76, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-+	PINGROUP(77, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-+	PINGROUP(78, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-+	PINGROUP(79, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-+	PINGROUP(80, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-+	PINGROUP(81, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-+	PINGROUP(82, NA, gsbi7, NA, NA, NA, NA, NA, NA, NA, NA),
-+	PINGROUP(83, gsbi7, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-+	PINGROUP(84, NA, gsbi7, NA, NA, NA, NA, NA, NA, NA, NA),
-+	PINGROUP(85, NA, NA, gsbi7, NA, NA, NA, NA, NA, NA, NA),
-+	PINGROUP(86, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-+	PINGROUP(87, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-+	PINGROUP(88, usb2_hsic, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-+	PINGROUP(89, usb2_hsic, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-+};
-+
-+#define NUM_GPIO_PINGROUPS 90
-+
-+static const struct msm_pinctrl_soc_data apq8064_pinctrl = {
-+	.pins = apq8064_pins,
-+	.npins = ARRAY_SIZE(apq8064_pins),
-+	.functions = apq8064_functions,
-+	.nfunctions = ARRAY_SIZE(apq8064_functions),
-+	.groups = apq8064_groups,
-+	.ngroups = ARRAY_SIZE(apq8064_groups),
-+	.ngpios = NUM_GPIO_PINGROUPS,
-+};
-+
-+static int apq8064_pinctrl_probe(struct platform_device *pdev)
-+{
-+	return msm_pinctrl_probe(pdev, &apq8064_pinctrl);
-+}
-+
-+static const struct of_device_id apq8064_pinctrl_of_match[] = {
-+	{ .compatible = "qcom,apq8064-pinctrl", },
-+	{ },
-+};
-+
-+static struct platform_driver apq8064_pinctrl_driver = {
-+	.driver = {
-+		.name = "apq8064-pinctrl",
-+		.owner = THIS_MODULE,
-+		.of_match_table = apq8064_pinctrl_of_match,
-+	},
-+	.probe = apq8064_pinctrl_probe,
-+	.remove = msm_pinctrl_remove,
-+};
-+
-+static int __init apq8064_pinctrl_init(void)
-+{
-+	return platform_driver_register(&apq8064_pinctrl_driver);
-+}
-+arch_initcall(apq8064_pinctrl_init);
-+
-+static void __exit apq8064_pinctrl_exit(void)
-+{
-+	platform_driver_unregister(&apq8064_pinctrl_driver);
-+}
-+module_exit(apq8064_pinctrl_exit);
-+
-+MODULE_AUTHOR("Bjorn Andersson <bjorn.andersson@sonymobile.com>");
-+MODULE_DESCRIPTION("Qualcomm APQ8064 pinctrl driver");
-+MODULE_LICENSE("GPL v2");
-+MODULE_DEVICE_TABLE(of, apq8064_pinctrl_of_match);
diff --git a/target/linux/ipq806x/patches/0039-pinctrl-msm8x74-make-Kconfig-dependency-more-strict.patch b/target/linux/ipq806x/patches/0039-pinctrl-msm8x74-make-Kconfig-dependency-more-strict.patch
deleted file mode 100644
index 7c56af6..0000000
--- a/target/linux/ipq806x/patches/0039-pinctrl-msm8x74-make-Kconfig-dependency-more-strict.patch
+++ /dev/null
@@ -1,31 +0,0 @@
-From 8605197c200786888415bf2e30d1fbde6ba8ba03 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= <u.kleine-koenig@pengutronix.de>
-Date: Tue, 1 Apr 2014 22:25:59 +0200
-Subject: [PATCH 039/182] pinctrl: msm8x74: make Kconfig dependency more
- strict
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-This driver is only useful on MSM8x74, so let the driver depend on
-ARCH_QCOM but allow compile coverage testing.
-The main benefit is that the driver isn't available to be selected for
-machines that don't have the matching hardware.
-
-Signed-off-by: Uwe Kleine-KÃ¶nig <u.kleine-koenig@pengutronix.de>
-Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
----
- drivers/pinctrl/Kconfig |    2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/drivers/pinctrl/Kconfig
-+++ b/drivers/pinctrl/Kconfig
-@@ -232,7 +232,7 @@ config PINCTRL_APQ8064
- 
- config PINCTRL_MSM8X74
- 	tristate "Qualcomm 8x74 pin controller driver"
--	depends on GPIOLIB && OF
-+	depends on GPIOLIB && OF && (ARCH_QCOM || COMPILE_TEST)
- 	select PINCTRL_MSM
- 	help
- 	  This is the pinctrl, pinmux, pinconf and gpiolib driver for the
diff --git a/target/linux/ipq806x/patches/0040-pinctrl-qcom-Add-definitions-for-IPQ8064.patch b/target/linux/ipq806x/patches/0040-pinctrl-qcom-Add-definitions-for-IPQ8064.patch
deleted file mode 100644
index a54604a..0000000
--- a/target/linux/ipq806x/patches/0040-pinctrl-qcom-Add-definitions-for-IPQ8064.patch
+++ /dev/null
@@ -1,701 +0,0 @@
-From 9bbd9d7e40944ca95e07f363b68700225beb9bef Mon Sep 17 00:00:00 2001
-From: Andy Gross <agross@codeaurora.org>
-Date: Mon, 14 Apr 2014 22:10:35 -0500
-Subject: [PATCH 040/182] pinctrl: qcom: Add definitions for IPQ8064
-
-This adds pinctrl definitions for the GPIO pins of the TLMM v2 block in the
-Qualcomm IPQ8064 platform.
-
-Signed-off-by: Andy Gross <agross@codeaurora.org>
-Reviewed-by: Bjorn Andersson <bjorn.andersson@sonymobile.com>
-Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
----
- drivers/pinctrl/Kconfig           |    8 +
- drivers/pinctrl/Makefile          |    1 +
- drivers/pinctrl/pinctrl-ipq8064.c |  653 +++++++++++++++++++++++++++++++++++++
- 3 files changed, 662 insertions(+)
- create mode 100644 drivers/pinctrl/pinctrl-ipq8064.c
-
---- a/drivers/pinctrl/Kconfig
-+++ b/drivers/pinctrl/Kconfig
-@@ -230,6 +230,14 @@ config PINCTRL_APQ8064
- 	  This is the pinctrl, pinmux, pinconf and gpiolib driver for the
- 	  Qualcomm TLMM block found in the Qualcomm APQ8064 platform.
- 
-+config PINCTRL_IPQ8064
-+	tristate "Qualcomm IPQ8064 pin controller driver"
-+	depends on GPIOLIB && OF
-+	select PINCTRL_MSM
-+	help
-+	  This is the pinctrl, pinmux, pinconf and gpiolib driver for the
-+	  Qualcomm TLMM block found in the Qualcomm IPQ8064 platform.
-+
- config PINCTRL_MSM8X74
- 	tristate "Qualcomm 8x74 pin controller driver"
- 	depends on GPIOLIB && OF && (ARCH_QCOM || COMPILE_TEST)
---- a/drivers/pinctrl/Makefile
-+++ b/drivers/pinctrl/Makefile
-@@ -39,6 +39,7 @@ obj-$(CONFIG_PINCTRL_IMX25)	+= pinctrl-i
- obj-$(CONFIG_PINCTRL_IMX28)	+= pinctrl-imx28.o
- obj-$(CONFIG_PINCTRL_MSM)	+= pinctrl-msm.o
- obj-$(CONFIG_PINCTRL_APQ8064)	+= pinctrl-apq8064.o
-+obj-$(CONFIG_PINCTRL_IPQ8064)	+= pinctrl-ipq8064.o
- obj-$(CONFIG_PINCTRL_MSM8X74)	+= pinctrl-msm8x74.o
- obj-$(CONFIG_PINCTRL_NOMADIK)	+= pinctrl-nomadik.o
- obj-$(CONFIG_PINCTRL_STN8815)	+= pinctrl-nomadik-stn8815.o
---- /dev/null
-+++ b/drivers/pinctrl/pinctrl-ipq8064.c
-@@ -0,0 +1,653 @@
-+/*
-+ * Copyright (c) 2014, The Linux Foundation. All rights reserved.
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 and
-+ * only version 2 as published by the Free Software Foundation.
-+ *
-+ * 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/of.h>
-+#include <linux/platform_device.h>
-+#include <linux/pinctrl/pinctrl.h>
-+
-+#include "pinctrl-msm.h"
-+
-+static const struct pinctrl_pin_desc ipq8064_pins[] = {
-+	PINCTRL_PIN(0, "GPIO_1"),
-+	PINCTRL_PIN(1, "GPIO_1"),
-+	PINCTRL_PIN(2, "GPIO_2"),
-+	PINCTRL_PIN(3, "GPIO_3"),
-+	PINCTRL_PIN(4, "GPIO_4"),
-+	PINCTRL_PIN(5, "GPIO_5"),
-+	PINCTRL_PIN(6, "GPIO_6"),
-+	PINCTRL_PIN(7, "GPIO_7"),
-+	PINCTRL_PIN(8, "GPIO_8"),
-+	PINCTRL_PIN(9, "GPIO_9"),
-+	PINCTRL_PIN(10, "GPIO_10"),
-+	PINCTRL_PIN(11, "GPIO_11"),
-+	PINCTRL_PIN(12, "GPIO_12"),
-+	PINCTRL_PIN(13, "GPIO_13"),
-+	PINCTRL_PIN(14, "GPIO_14"),
-+	PINCTRL_PIN(15, "GPIO_15"),
-+	PINCTRL_PIN(16, "GPIO_16"),
-+	PINCTRL_PIN(17, "GPIO_17"),
-+	PINCTRL_PIN(18, "GPIO_18"),
-+	PINCTRL_PIN(19, "GPIO_19"),
-+	PINCTRL_PIN(20, "GPIO_20"),
-+	PINCTRL_PIN(21, "GPIO_21"),
-+	PINCTRL_PIN(22, "GPIO_22"),
-+	PINCTRL_PIN(23, "GPIO_23"),
-+	PINCTRL_PIN(24, "GPIO_24"),
-+	PINCTRL_PIN(25, "GPIO_25"),
-+	PINCTRL_PIN(26, "GPIO_26"),
-+	PINCTRL_PIN(27, "GPIO_27"),
-+	PINCTRL_PIN(28, "GPIO_28"),
-+	PINCTRL_PIN(29, "GPIO_29"),
-+	PINCTRL_PIN(30, "GPIO_30"),
-+	PINCTRL_PIN(31, "GPIO_31"),
-+	PINCTRL_PIN(32, "GPIO_32"),
-+	PINCTRL_PIN(33, "GPIO_33"),
-+	PINCTRL_PIN(34, "GPIO_34"),
-+	PINCTRL_PIN(35, "GPIO_35"),
-+	PINCTRL_PIN(36, "GPIO_36"),
-+	PINCTRL_PIN(37, "GPIO_37"),
-+	PINCTRL_PIN(38, "GPIO_38"),
-+	PINCTRL_PIN(39, "GPIO_39"),
-+	PINCTRL_PIN(40, "GPIO_40"),
-+	PINCTRL_PIN(41, "GPIO_41"),
-+	PINCTRL_PIN(42, "GPIO_42"),
-+	PINCTRL_PIN(43, "GPIO_43"),
-+	PINCTRL_PIN(44, "GPIO_44"),
-+	PINCTRL_PIN(45, "GPIO_45"),
-+	PINCTRL_PIN(46, "GPIO_46"),
-+	PINCTRL_PIN(47, "GPIO_47"),
-+	PINCTRL_PIN(48, "GPIO_48"),
-+	PINCTRL_PIN(49, "GPIO_49"),
-+	PINCTRL_PIN(50, "GPIO_50"),
-+	PINCTRL_PIN(51, "GPIO_51"),
-+	PINCTRL_PIN(52, "GPIO_52"),
-+	PINCTRL_PIN(53, "GPIO_53"),
-+	PINCTRL_PIN(54, "GPIO_54"),
-+	PINCTRL_PIN(55, "GPIO_55"),
-+	PINCTRL_PIN(56, "GPIO_56"),
-+	PINCTRL_PIN(57, "GPIO_57"),
-+	PINCTRL_PIN(58, "GPIO_58"),
-+	PINCTRL_PIN(59, "GPIO_59"),
-+	PINCTRL_PIN(60, "GPIO_60"),
-+	PINCTRL_PIN(61, "GPIO_61"),
-+	PINCTRL_PIN(62, "GPIO_62"),
-+	PINCTRL_PIN(63, "GPIO_63"),
-+	PINCTRL_PIN(64, "GPIO_64"),
-+	PINCTRL_PIN(65, "GPIO_65"),
-+	PINCTRL_PIN(66, "GPIO_66"),
-+	PINCTRL_PIN(67, "GPIO_67"),
-+	PINCTRL_PIN(68, "GPIO_68"),
-+
-+	PINCTRL_PIN(69, "SDC3_CLK"),
-+	PINCTRL_PIN(70, "SDC3_CMD"),
-+	PINCTRL_PIN(71, "SDC3_DATA"),
-+};
-+
-+#define DECLARE_IPQ_GPIO_PINS(pin) static const unsigned int gpio##pin##_pins[] = { pin }
-+DECLARE_IPQ_GPIO_PINS(0);
-+DECLARE_IPQ_GPIO_PINS(1);
-+DECLARE_IPQ_GPIO_PINS(2);
-+DECLARE_IPQ_GPIO_PINS(3);
-+DECLARE_IPQ_GPIO_PINS(4);
-+DECLARE_IPQ_GPIO_PINS(5);
-+DECLARE_IPQ_GPIO_PINS(6);
-+DECLARE_IPQ_GPIO_PINS(7);
-+DECLARE_IPQ_GPIO_PINS(8);
-+DECLARE_IPQ_GPIO_PINS(9);
-+DECLARE_IPQ_GPIO_PINS(10);
-+DECLARE_IPQ_GPIO_PINS(11);
-+DECLARE_IPQ_GPIO_PINS(12);
-+DECLARE_IPQ_GPIO_PINS(13);
-+DECLARE_IPQ_GPIO_PINS(14);
-+DECLARE_IPQ_GPIO_PINS(15);
-+DECLARE_IPQ_GPIO_PINS(16);
-+DECLARE_IPQ_GPIO_PINS(17);
-+DECLARE_IPQ_GPIO_PINS(18);
-+DECLARE_IPQ_GPIO_PINS(19);
-+DECLARE_IPQ_GPIO_PINS(20);
-+DECLARE_IPQ_GPIO_PINS(21);
-+DECLARE_IPQ_GPIO_PINS(22);
-+DECLARE_IPQ_GPIO_PINS(23);
-+DECLARE_IPQ_GPIO_PINS(24);
-+DECLARE_IPQ_GPIO_PINS(25);
-+DECLARE_IPQ_GPIO_PINS(26);
-+DECLARE_IPQ_GPIO_PINS(27);
-+DECLARE_IPQ_GPIO_PINS(28);
-+DECLARE_IPQ_GPIO_PINS(29);
-+DECLARE_IPQ_GPIO_PINS(30);
-+DECLARE_IPQ_GPIO_PINS(31);
-+DECLARE_IPQ_GPIO_PINS(32);
-+DECLARE_IPQ_GPIO_PINS(33);
-+DECLARE_IPQ_GPIO_PINS(34);
-+DECLARE_IPQ_GPIO_PINS(35);
-+DECLARE_IPQ_GPIO_PINS(36);
-+DECLARE_IPQ_GPIO_PINS(37);
-+DECLARE_IPQ_GPIO_PINS(38);
-+DECLARE_IPQ_GPIO_PINS(39);
-+DECLARE_IPQ_GPIO_PINS(40);
-+DECLARE_IPQ_GPIO_PINS(41);
-+DECLARE_IPQ_GPIO_PINS(42);
-+DECLARE_IPQ_GPIO_PINS(43);
-+DECLARE_IPQ_GPIO_PINS(44);
-+DECLARE_IPQ_GPIO_PINS(45);
-+DECLARE_IPQ_GPIO_PINS(46);
-+DECLARE_IPQ_GPIO_PINS(47);
-+DECLARE_IPQ_GPIO_PINS(48);
-+DECLARE_IPQ_GPIO_PINS(49);
-+DECLARE_IPQ_GPIO_PINS(50);
-+DECLARE_IPQ_GPIO_PINS(51);
-+DECLARE_IPQ_GPIO_PINS(52);
-+DECLARE_IPQ_GPIO_PINS(53);
-+DECLARE_IPQ_GPIO_PINS(54);
-+DECLARE_IPQ_GPIO_PINS(55);
-+DECLARE_IPQ_GPIO_PINS(56);
-+DECLARE_IPQ_GPIO_PINS(57);
-+DECLARE_IPQ_GPIO_PINS(58);
-+DECLARE_IPQ_GPIO_PINS(59);
-+DECLARE_IPQ_GPIO_PINS(60);
-+DECLARE_IPQ_GPIO_PINS(61);
-+DECLARE_IPQ_GPIO_PINS(62);
-+DECLARE_IPQ_GPIO_PINS(63);
-+DECLARE_IPQ_GPIO_PINS(64);
-+DECLARE_IPQ_GPIO_PINS(65);
-+DECLARE_IPQ_GPIO_PINS(66);
-+DECLARE_IPQ_GPIO_PINS(67);
-+DECLARE_IPQ_GPIO_PINS(68);
-+
-+static const unsigned int sdc3_clk_pins[] = { 69 };
-+static const unsigned int sdc3_cmd_pins[] = { 70 };
-+static const unsigned int sdc3_data_pins[] = { 71 };
-+
-+#define FUNCTION(fname)					\
-+	[IPQ_MUX_##fname] = {				\
-+		.name = #fname,				\
-+		.groups = fname##_groups,		\
-+		.ngroups = ARRAY_SIZE(fname##_groups),	\
-+	}
-+
-+#define PINGROUP(id, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10) \
-+	{						\
-+		.name = "gpio" #id,			\
-+		.pins = gpio##id##_pins,		\
-+		.npins = ARRAY_SIZE(gpio##id##_pins),	\
-+		.funcs = (int[]){			\
-+			IPQ_MUX_NA, /* gpio mode */	\
-+			IPQ_MUX_##f1,			\
-+			IPQ_MUX_##f2,			\
-+			IPQ_MUX_##f3,			\
-+			IPQ_MUX_##f4,			\
-+			IPQ_MUX_##f5,			\
-+			IPQ_MUX_##f6,			\
-+			IPQ_MUX_##f7,			\
-+			IPQ_MUX_##f8,			\
-+			IPQ_MUX_##f9,			\
-+			IPQ_MUX_##f10,			\
-+		},					\
-+		.nfuncs = 11,				\
-+		.ctl_reg = 0x1000 + 0x10 * id,		\
-+		.io_reg = 0x1004 + 0x10 * id,		\
-+		.intr_cfg_reg = 0x1008 + 0x10 * id,	\
-+		.intr_status_reg = 0x100c + 0x10 * id,	\
-+		.intr_target_reg = 0x400 + 0x4 * id,	\
-+		.mux_bit = 2,				\
-+		.pull_bit = 0,				\
-+		.drv_bit = 6,				\
-+		.oe_bit = 9,				\
-+		.in_bit = 0,				\
-+		.out_bit = 1,				\
-+		.intr_enable_bit = 0,			\
-+		.intr_status_bit = 0,			\
-+		.intr_ack_high = 1,			\
-+		.intr_target_bit = 0,			\
-+		.intr_raw_status_bit = 3,		\
-+		.intr_polarity_bit = 1,			\
-+		.intr_detection_bit = 2,		\
-+		.intr_detection_width = 1,		\
-+	}
-+
-+#define SDC_PINGROUP(pg_name, ctl, pull, drv)		\
-+	{						\
-+		.name = #pg_name,	                \
-+		.pins = pg_name##_pins,                 \
-+		.npins = ARRAY_SIZE(pg_name##_pins),    \
-+		.ctl_reg = ctl,                         \
-+		.io_reg = 0,                            \
-+		.intr_cfg_reg = 0,                      \
-+		.intr_status_reg = 0,                   \
-+		.intr_target_reg = 0,                   \
-+		.mux_bit = -1,                          \
-+		.pull_bit = pull,                       \
-+		.drv_bit = drv,                         \
-+		.oe_bit = -1,                           \
-+		.in_bit = -1,                           \
-+		.out_bit = -1,                          \
-+		.intr_enable_bit = -1,                  \
-+		.intr_status_bit = -1,                  \
-+		.intr_target_bit = -1,                  \
-+		.intr_raw_status_bit = -1,              \
-+		.intr_polarity_bit = -1,                \
-+		.intr_detection_bit = -1,               \
-+		.intr_detection_width = -1,             \
-+	}
-+
-+enum ipq8064_functions {
-+	IPQ_MUX_mdio,
-+	IPQ_MUX_mi2s,
-+	IPQ_MUX_pdm,
-+	IPQ_MUX_ssbi,
-+	IPQ_MUX_spmi,
-+	IPQ_MUX_audio_pcm,
-+	IPQ_MUX_gsbi1,
-+	IPQ_MUX_gsbi2,
-+	IPQ_MUX_gsbi4,
-+	IPQ_MUX_gsbi5,
-+	IPQ_MUX_gsbi5_spi_cs1,
-+	IPQ_MUX_gsbi5_spi_cs2,
-+	IPQ_MUX_gsbi5_spi_cs3,
-+	IPQ_MUX_gsbi6,
-+	IPQ_MUX_gsbi7,
-+	IPQ_MUX_nss_spi,
-+	IPQ_MUX_sdc1,
-+	IPQ_MUX_spdif,
-+	IPQ_MUX_nand,
-+	IPQ_MUX_tsif1,
-+	IPQ_MUX_tsif2,
-+	IPQ_MUX_usb_fs_n,
-+	IPQ_MUX_usb_fs,
-+	IPQ_MUX_usb2_hsic,
-+	IPQ_MUX_rgmii2,
-+	IPQ_MUX_sata,
-+	IPQ_MUX_pcie1_rst,
-+	IPQ_MUX_pcie1_prsnt,
-+	IPQ_MUX_pcie1_pwrflt,
-+	IPQ_MUX_pcie1_pwren_n,
-+	IPQ_MUX_pcie1_pwren,
-+	IPQ_MUX_pcie1_clk_req,
-+	IPQ_MUX_pcie2_rst,
-+	IPQ_MUX_pcie2_prsnt,
-+	IPQ_MUX_pcie2_pwrflt,
-+	IPQ_MUX_pcie2_pwren_n,
-+	IPQ_MUX_pcie2_pwren,
-+	IPQ_MUX_pcie2_clk_req,
-+	IPQ_MUX_pcie3_rst,
-+	IPQ_MUX_pcie3_prsnt,
-+	IPQ_MUX_pcie3_pwrflt,
-+	IPQ_MUX_pcie3_pwren_n,
-+	IPQ_MUX_pcie3_pwren,
-+	IPQ_MUX_pcie3_clk_req,
-+	IPQ_MUX_ps_hold,
-+	IPQ_MUX_NA,
-+};
-+
-+static const char * const mdio_groups[] = {
-+	"gpio0", "gpio1", "gpio10", "gpio11",
-+};
-+
-+static const char * const mi2s_groups[] = {
-+	"gpio27", "gpio28", "gpio29", "gpio30", "gpio31", "gpio32",
-+	"gpio33", "gpio55", "gpio56", "gpio57", "gpio58",
-+};
-+
-+static const char * const pdm_groups[] = {
-+	"gpio3", "gpio16", "gpio17", "gpio22", "gpio30", "gpio31",
-+	"gpio34", "gpio35", "gpio52", "gpio55", "gpio56", "gpio58",
-+	"gpio59",
-+};
-+
-+static const char * const ssbi_groups[] = {
-+	"gpio10", "gpio11",
-+};
-+
-+static const char * const spmi_groups[] = {
-+	"gpio10", "gpio11",
-+};
-+
-+static const char * const audio_pcm_groups[] = {
-+	"gpio14", "gpio15", "gpio16", "gpio17",
-+};
-+
-+static const char * const gsbi1_groups[] = {
-+	"gpio51", "gpio52", "gpio53", "gpio54",
-+};
-+
-+static const char * const gsbi2_groups[] = {
-+	"gpio22", "gpio23", "gpio24", "gpio25",
-+};
-+
-+static const char * const gsbi4_groups[] = {
-+	"gpio10", "gpio11", "gpio12", "gpio13",
-+};
-+
-+static const char * const gsbi5_groups[] = {
-+	"gpio18", "gpio19", "gpio20", "gpio21",
-+};
-+
-+static const char * const gsbi5_spi_cs1_groups[] = {
-+	"gpio6", "gpio61",
-+};
-+
-+static const char * const gsbi5_spi_cs2_groups[] = {
-+	"gpio7", "gpio62",
-+};
-+
-+static const char * const gsbi5_spi_cs3_groups[] = {
-+	"gpio2",
-+};
-+
-+static const char * const gsbi6_groups[] = {
-+	"gpio27", "gpio28", "gpio29", "gpio30", "gpio55", "gpio56",
-+	"gpio57", "gpio58",
-+};
-+
-+static const char * const gsbi7_groups[] = {
-+	"gpio6", "gpio7", "gpio8", "gpio9",
-+};
-+
-+static const char * const nss_spi_groups[] = {
-+	"gpio14", "gpio15", "gpio16", "gpio17", "gpio55", "gpio56",
-+	"gpio57", "gpio58",
-+};
-+
-+static const char * const sdc1_groups[] = {
-+	"gpio38", "gpio39", "gpio40", "gpio41", "gpio42", "gpio43",
-+	"gpio44", "gpio45", "gpio46", "gpio47",
-+};
-+
-+static const char * const spdif_groups[] = {
-+	"gpio_10", "gpio_48",
-+};
-+
-+static const char * const nand_groups[] = {
-+	"gpio34", "gpio35", "gpio36", "gpio37", "gpio38", "gpio39",
-+	"gpio40", "gpio41", "gpio42", "gpio43", "gpio44", "gpio45",
-+	"gpio46", "gpio47",
-+};
-+
-+static const char * const tsif1_groups[] = {
-+	"gpio55", "gpio56", "gpio57", "gpio58",
-+};
-+
-+static const char * const tsif2_groups[] = {
-+	"gpio59", "gpio60", "gpio61", "gpio62",
-+};
-+
-+static const char * const usb_fs_n_groups[] = {
-+	"gpio6",
-+};
-+
-+static const char * const usb_fs_groups[] = {
-+	"gpio6", "gpio7", "gpio8",
-+};
-+
-+static const char * const usb2_hsic_groups[] = {
-+	"gpio67", "gpio68",
-+};
-+
-+static const char * const rgmii2_groups[] = {
-+	"gpio27", "gpio28", "gpio29", "gpio30", "gpio31", "gpio32",
-+	"gpio51", "gpio52", "gpio59", "gpio60", "gpio61", "gpio62",
-+};
-+
-+static const char * const sata_groups[] = {
-+	"gpio10",
-+};
-+
-+static const char * const pcie1_rst_groups[] = {
-+	"gpio3",
-+};
-+
-+static const char * const pcie1_prsnt_groups[] = {
-+	"gpio3", "gpio11",
-+};
-+
-+static const char * const pcie1_pwren_n_groups[] = {
-+	"gpio4", "gpio12",
-+};
-+
-+static const char * const pcie1_pwren_groups[] = {
-+	"gpio4", "gpio12",
-+};
-+
-+static const char * const pcie1_pwrflt_groups[] = {
-+	"gpio5", "gpio13",
-+};
-+
-+static const char * const pcie1_clk_req_groups[] = {
-+	"gpio5",
-+};
-+
-+static const char * const pcie2_rst_groups[] = {
-+	"gpio48",
-+};
-+
-+static const char * const pcie2_prsnt_groups[] = {
-+	"gpio11", "gpio48",
-+};
-+
-+static const char * const pcie2_pwren_n_groups[] = {
-+	"gpio12", "gpio49",
-+};
-+
-+static const char * const pcie2_pwren_groups[] = {
-+	"gpio12", "gpio49",
-+};
-+
-+static const char * const pcie2_pwrflt_groups[] = {
-+	"gpio13", "gpio50",
-+};
-+
-+static const char * const pcie2_clk_req_groups[] = {
-+	"gpio50",
-+};
-+
-+static const char * const pcie3_rst_groups[] = {
-+	"gpio63",
-+};
-+
-+static const char * const pcie3_prsnt_groups[] = {
-+	"gpio11",
-+};
-+
-+static const char * const pcie3_pwren_n_groups[] = {
-+	"gpio12",
-+};
-+
-+static const char * const pcie3_pwren_groups[] = {
-+	"gpio12",
-+};
-+
-+static const char * const pcie3_pwrflt_groups[] = {
-+	"gpio13",
-+};
-+
-+static const char * const pcie3_clk_req_groups[] = {
-+	"gpio65",
-+};
-+
-+static const char * const ps_hold_groups[] = {
-+	"gpio26",
-+};
-+
-+static const struct msm_function ipq8064_functions[] = {
-+	FUNCTION(mdio),
-+	FUNCTION(ssbi),
-+	FUNCTION(spmi),
-+	FUNCTION(mi2s),
-+	FUNCTION(pdm),
-+	FUNCTION(audio_pcm),
-+	FUNCTION(gsbi1),
-+	FUNCTION(gsbi2),
-+	FUNCTION(gsbi4),
-+	FUNCTION(gsbi5),
-+	FUNCTION(gsbi5_spi_cs1),
-+	FUNCTION(gsbi5_spi_cs2),
-+	FUNCTION(gsbi5_spi_cs3),
-+	FUNCTION(gsbi6),
-+	FUNCTION(gsbi7),
-+	FUNCTION(nss_spi),
-+	FUNCTION(sdc1),
-+	FUNCTION(spdif),
-+	FUNCTION(nand),
-+	FUNCTION(tsif1),
-+	FUNCTION(tsif2),
-+	FUNCTION(usb_fs_n),
-+	FUNCTION(usb_fs),
-+	FUNCTION(usb2_hsic),
-+	FUNCTION(rgmii2),
-+	FUNCTION(sata),
-+	FUNCTION(pcie1_rst),
-+	FUNCTION(pcie1_prsnt),
-+	FUNCTION(pcie1_pwren_n),
-+	FUNCTION(pcie1_pwren),
-+	FUNCTION(pcie1_pwrflt),
-+	FUNCTION(pcie1_clk_req),
-+	FUNCTION(pcie2_rst),
-+	FUNCTION(pcie2_prsnt),
-+	FUNCTION(pcie2_pwren_n),
-+	FUNCTION(pcie2_pwren),
-+	FUNCTION(pcie2_pwrflt),
-+	FUNCTION(pcie2_clk_req),
-+	FUNCTION(pcie3_rst),
-+	FUNCTION(pcie3_prsnt),
-+	FUNCTION(pcie3_pwren_n),
-+	FUNCTION(pcie3_pwren),
-+	FUNCTION(pcie3_pwrflt),
-+	FUNCTION(pcie3_clk_req),
-+	FUNCTION(ps_hold),
-+};
-+
-+static const struct msm_pingroup ipq8064_groups[] = {
-+	PINGROUP(0, mdio, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-+	PINGROUP(1, mdio, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-+	PINGROUP(2, gsbi5_spi_cs3, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-+	PINGROUP(3, pcie1_rst, pcie1_prsnt, pdm, NA, NA, NA, NA, NA, NA, NA),
-+	PINGROUP(4, pcie1_pwren_n, pcie1_pwren, NA, NA, NA, NA, NA, NA, NA, NA),
-+	PINGROUP(5, pcie1_clk_req, pcie1_pwrflt, NA, NA, NA, NA, NA, NA, NA, NA),
-+	PINGROUP(6, gsbi7, usb_fs, gsbi5_spi_cs1, usb_fs_n, NA, NA, NA, NA, NA, NA),
-+	PINGROUP(7, gsbi7, usb_fs, gsbi5_spi_cs2, NA, NA, NA, NA, NA, NA, NA),
-+	PINGROUP(8, gsbi7, usb_fs, NA, NA, NA, NA, NA, NA, NA, NA),
-+	PINGROUP(9, gsbi7, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-+	PINGROUP(10, gsbi4, spdif, sata, ssbi, mdio, spmi, NA, NA, NA, NA),
-+	PINGROUP(11, gsbi4, pcie2_prsnt, pcie1_prsnt, pcie3_prsnt, ssbi, mdio, spmi, NA, NA, NA),
-+	PINGROUP(12, gsbi4, pcie2_pwren_n, pcie1_pwren_n, pcie3_pwren_n, pcie2_pwren, pcie1_pwren, pcie3_pwren, NA, NA, NA),
-+	PINGROUP(13, gsbi4, pcie2_pwrflt, pcie1_pwrflt, pcie3_pwrflt, NA, NA, NA, NA, NA, NA),
-+	PINGROUP(14, audio_pcm, nss_spi, NA, NA, NA, NA, NA, NA, NA, NA),
-+	PINGROUP(15, audio_pcm, nss_spi, NA, NA, NA, NA, NA, NA, NA, NA),
-+	PINGROUP(16, audio_pcm, nss_spi, pdm, NA, NA, NA, NA, NA, NA, NA),
-+	PINGROUP(17, audio_pcm, nss_spi, pdm, NA, NA, NA, NA, NA, NA, NA),
-+	PINGROUP(18, gsbi5, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-+	PINGROUP(19, gsbi5, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-+	PINGROUP(20, gsbi5, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-+	PINGROUP(21, gsbi5, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-+	PINGROUP(22, gsbi2, pdm, NA, NA, NA, NA, NA, NA, NA, NA),
-+	PINGROUP(23, gsbi2, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-+	PINGROUP(24, gsbi2, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-+	PINGROUP(25, gsbi2, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-+	PINGROUP(26, ps_hold, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-+	PINGROUP(27, mi2s, rgmii2, gsbi6, NA, NA, NA, NA, NA, NA, NA),
-+	PINGROUP(28, mi2s, rgmii2, gsbi6, NA, NA, NA, NA, NA, NA, NA),
-+	PINGROUP(29, mi2s, rgmii2, gsbi6, NA, NA, NA, NA, NA, NA, NA),
-+	PINGROUP(30, mi2s, rgmii2, gsbi6, pdm, NA, NA, NA, NA, NA, NA),
-+	PINGROUP(31, mi2s, rgmii2, pdm, NA, NA, NA, NA, NA, NA, NA),
-+	PINGROUP(32, mi2s, rgmii2, NA, NA, NA, NA, NA, NA, NA, NA),
-+	PINGROUP(33, mi2s, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-+	PINGROUP(34, nand, pdm, NA, NA, NA, NA, NA, NA, NA, NA),
-+	PINGROUP(35, nand, pdm, NA, NA, NA, NA, NA, NA, NA, NA),
-+	PINGROUP(36, nand, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-+	PINGROUP(37, nand, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-+	PINGROUP(38, nand, sdc1, NA, NA, NA, NA, NA, NA, NA, NA),
-+	PINGROUP(39, nand, sdc1, NA, NA, NA, NA, NA, NA, NA, NA),
-+	PINGROUP(40, nand, sdc1, NA, NA, NA, NA, NA, NA, NA, NA),
-+	PINGROUP(41, nand, sdc1, NA, NA, NA, NA, NA, NA, NA, NA),
-+	PINGROUP(42, nand, sdc1, NA, NA, NA, NA, NA, NA, NA, NA),
-+	PINGROUP(43, nand, sdc1, NA, NA, NA, NA, NA, NA, NA, NA),
-+	PINGROUP(44, nand, sdc1, NA, NA, NA, NA, NA, NA, NA, NA),
-+	PINGROUP(45, nand, sdc1, NA, NA, NA, NA, NA, NA, NA, NA),
-+	PINGROUP(46, nand, sdc1, NA, NA, NA, NA, NA, NA, NA, NA),
-+	PINGROUP(47, nand, sdc1, NA, NA, NA, NA, NA, NA, NA, NA),
-+	PINGROUP(48, pcie2_rst, spdif, NA, NA, NA, NA, NA, NA, NA, NA),
-+	PINGROUP(49, pcie2_pwren_n, pcie2_pwren, NA, NA, NA, NA, NA, NA, NA, NA),
-+	PINGROUP(50, pcie2_clk_req, pcie2_pwrflt, NA, NA, NA, NA, NA, NA, NA, NA),
-+	PINGROUP(51, gsbi1, rgmii2, NA, NA, NA, NA, NA, NA, NA, NA),
-+	PINGROUP(52, gsbi1, rgmii2, pdm, NA, NA, NA, NA, NA, NA, NA),
-+	PINGROUP(53, gsbi1, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-+	PINGROUP(54, gsbi1, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-+	PINGROUP(55, tsif1, mi2s, gsbi6, pdm, nss_spi, NA, NA, NA, NA, NA),
-+	PINGROUP(56, tsif1, mi2s, gsbi6, pdm, nss_spi, NA, NA, NA, NA, NA),
-+	PINGROUP(57, tsif1, mi2s, gsbi6, nss_spi, NA, NA, NA, NA, NA, NA),
-+	PINGROUP(58, tsif1, mi2s, gsbi6, pdm, nss_spi, NA, NA, NA, NA, NA),
-+	PINGROUP(59, tsif2, rgmii2, pdm, NA, NA, NA, NA, NA, NA, NA),
-+	PINGROUP(60, tsif2, rgmii2, NA, NA, NA, NA, NA, NA, NA, NA),
-+	PINGROUP(61, tsif2, rgmii2, gsbi5_spi_cs1, NA, NA, NA, NA, NA, NA, NA),
-+	PINGROUP(62, tsif2, rgmii2, gsbi5_spi_cs2, NA, NA, NA, NA, NA, NA, NA),
-+	PINGROUP(63, pcie3_rst, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-+	PINGROUP(64, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-+	PINGROUP(65, pcie3_clk_req, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-+	PINGROUP(66, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-+	PINGROUP(67, usb2_hsic, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-+	PINGROUP(68, usb2_hsic, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-+	SDC_PINGROUP(sdc3_clk, 0x204a, 14, 6),
-+	SDC_PINGROUP(sdc3_cmd, 0x204a, 11, 3),
-+	SDC_PINGROUP(sdc3_data, 0x204a, 9, 0),
-+};
-+
-+#define NUM_GPIO_PINGROUPS 69
-+
-+static const struct msm_pinctrl_soc_data ipq8064_pinctrl = {
-+	.pins = ipq8064_pins,
-+	.npins = ARRAY_SIZE(ipq8064_pins),
-+	.functions = ipq8064_functions,
-+	.nfunctions = ARRAY_SIZE(ipq8064_functions),
-+	.groups = ipq8064_groups,
-+	.ngroups = ARRAY_SIZE(ipq8064_groups),
-+	.ngpios = NUM_GPIO_PINGROUPS,
-+};
-+
-+static int ipq8064_pinctrl_probe(struct platform_device *pdev)
-+{
-+	return msm_pinctrl_probe(pdev, &ipq8064_pinctrl);
-+}
-+
-+static const struct of_device_id ipq8064_pinctrl_of_match[] = {
-+	{ .compatible = "qcom,ipq8064-pinctrl", },
-+	{ },
-+};
-+
-+static struct platform_driver ipq8064_pinctrl_driver = {
-+	.driver = {
-+		.name = "ipq8064-pinctrl",
-+		.owner = THIS_MODULE,
-+		.of_match_table = ipq8064_pinctrl_of_match,
-+	},
-+	.probe = ipq8064_pinctrl_probe,
-+	.remove = msm_pinctrl_remove,
-+};
-+
-+static int __init ipq8064_pinctrl_init(void)
-+{
-+	return platform_driver_register(&ipq8064_pinctrl_driver);
-+}
-+arch_initcall(ipq8064_pinctrl_init);
-+
-+static void __exit ipq8064_pinctrl_exit(void)
-+{
-+	platform_driver_unregister(&ipq8064_pinctrl_driver);
-+}
-+module_exit(ipq8064_pinctrl_exit);
-+
-+MODULE_AUTHOR("Andy Gross <agross@codeaurora.org>");
-+MODULE_DESCRIPTION("Qualcomm IPQ8064 pinctrl driver");
-+MODULE_LICENSE("GPL v2");
-+MODULE_DEVICE_TABLE(of, ipq8064_pinctrl_of_match);
diff --git a/target/linux/ipq806x/patches/0041-dt-Document-Qualcomm-IPQ8064-pinctrl-binding.patch b/target/linux/ipq806x/patches/0041-dt-Document-Qualcomm-IPQ8064-pinctrl-binding.patch
deleted file mode 100644
index c1adc99..0000000
--- a/target/linux/ipq806x/patches/0041-dt-Document-Qualcomm-IPQ8064-pinctrl-binding.patch
+++ /dev/null
@@ -1,114 +0,0 @@
-From 425015979d3b1600d14403be7d6d64ba1238e58d Mon Sep 17 00:00:00 2001
-From: Andy Gross <agross@codeaurora.org>
-Date: Mon, 14 Apr 2014 22:10:36 -0500
-Subject: [PATCH 041/182] dt: Document Qualcomm IPQ8064 pinctrl binding
-
-Define a new binding for the Qualcomm TLMMv2 based pin controller inside the
-IPQ8064.
-
-Signed-off-by: Andy Gross <agross@codeaurora.org>
-Reviewed-by: Bjorn Andersson <bjorn.andersson@sonymobile.com>
-Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
----
- .../bindings/pinctrl/qcom,ipq8064-pinctrl.txt      |   95 ++++++++++++++++++++
- 1 file changed, 95 insertions(+)
- create mode 100644 Documentation/devicetree/bindings/pinctrl/qcom,ipq8064-pinctrl.txt
-
---- /dev/null
-+++ b/Documentation/devicetree/bindings/pinctrl/qcom,ipq8064-pinctrl.txt
-@@ -0,0 +1,95 @@
-+Qualcomm IPQ8064 TLMM block
-+
-+Required properties:
-+- compatible: "qcom,ipq8064-pinctrl"
-+- reg: Should be the base address and length of the TLMM block.
-+- interrupts: Should be the parent IRQ of the TLMM block.
-+- interrupt-controller: Marks the device node as an interrupt controller.
-+- #interrupt-cells: Should be two.
-+- gpio-controller: Marks the device node as a GPIO controller.
-+- #gpio-cells : Should be two.
-+                The first cell is the gpio pin number and the
-+                second cell is used for optional parameters.
-+
-+Please refer to ../gpio/gpio.txt and ../interrupt-controller/interrupts.txt for
-+a general description of GPIO and interrupt bindings.
-+
-+Please refer to pinctrl-bindings.txt in this directory for details of the
-+common pinctrl bindings used by client devices, including the meaning of the
-+phrase "pin configuration node".
-+
-+Qualcomm's pin configuration nodes act as a container for an abitrary number of
-+subnodes. Each of these subnodes represents some desired configuration for a
-+pin, a group, or a list of pins or groups. This configuration can include the
-+mux function to select on those pin(s)/group(s), and various pin configuration
-+parameters, such as pull-up, drive strength, etc.
-+
-+The name of each subnode is not important; all subnodes should be enumerated
-+and processed purely based on their content.
-+
-+Each subnode only affects those parameters that are explicitly listed. In
-+other words, a subnode that lists a mux function but no pin configuration
-+parameters implies no information about any pin configuration parameters.
-+Similarly, a pin subnode that describes a pullup parameter implies no
-+information about e.g. the mux function.
-+
-+
-+The following generic properties as defined in pinctrl-bindings.txt are valid
-+to specify in a pin configuration subnode:
-+
-+ pins, function, bias-disable, bias-pull-down, bias-pull,up, drive-strength,
-+ output-low, output-high.
-+
-+Non-empty subnodes must specify the 'pins' property.
-+
-+Valid values for qcom,pins are:
-+  gpio0-gpio68
-+   Supports mux, bias, and drive-strength
-+
-+  sdc3_clk, sdc3_cmd, sdc3_data
-+   Supports bias and drive-strength
-+
-+
-+Valid values for function are:
-+  mdio, mi2s, pdm, ssbi, spmi, audio_pcm, gsbi1, gsbi2, gsbi4, gsbi5,
-+  gsbi5_spi_cs1, gsbi5_spi_cs2, gsbi5_spi_cs3, gsbi6, gsbi7, nss_spi, sdc1,
-+  spdif, nand, tsif1, tsif2, usb_fs_n, usb_fs, usb2_hsic, rgmii2, sata,
-+  pcie1_rst, pcie1_prsnt, pcie1_pwren_n, pcie1_pwren, pcie1_pwrflt,
-+  pcie1_clk_req, pcie2_rst, pcie2_prsnt, pcie2_pwren_n, pcie2_pwren,
-+  pcie2_pwrflt, pcie2_clk_req, pcie3_rst, pcie3_prsnt, pcie3_pwren_n,
-+  pcie3_pwren, pcie3_pwrflt, pcie3_clk_req, ps_hold
-+
-+Example:
-+
-+	pinmux: pinctrl@800000 {
-+		compatible = "qcom,ipq8064-pinctrl";
-+		reg = <0x800000 0x4000>;
-+
-+		gpio-controller;
-+		#gpio-cells = <2>;
-+		interrupt-controller;
-+		#interrupt-cells = <2>;
-+		interrupts = <0 32 0x4>;
-+
-+		pinctrl-names = "default";
-+		pinctrl-0 = <&gsbi5_uart_default>;
-+
-+		gsbi5_uart_default: gsbi5_uart_default {
-+			mux {
-+				pins = "gpio18", "gpio19";
-+				function = "gsbi5";
-+			};
-+
-+			tx {
-+				pins = "gpio18";
-+				drive-strength = <4>;
-+				bias-disable;
-+			};
-+
-+			rx {
-+				pins = "gpio19";
-+				drive-strength = <2>;
-+				bias-pull-up;
-+			};
-+		};
-+	};
diff --git a/target/linux/ipq806x/patches/0042-ARM-qcom-Select-PINCTRL-by-default-for-ARCH_QCOM.patch b/target/linux/ipq806x/patches/0042-ARM-qcom-Select-PINCTRL-by-default-for-ARCH_QCOM.patch
deleted file mode 100644
index cbccbc2..0000000
--- a/target/linux/ipq806x/patches/0042-ARM-qcom-Select-PINCTRL-by-default-for-ARCH_QCOM.patch
+++ /dev/null
@@ -1,24 +0,0 @@
-From add2c1451495ccc4e67ced3dd12d4286500f1672 Mon Sep 17 00:00:00 2001
-From: Andy Gross <agross@codeaurora.org>
-Date: Mon, 14 Apr 2014 22:10:37 -0500
-Subject: [PATCH 042/182] ARM: qcom: Select PINCTRL by default for ARCH_QCOM
-
-Add missing PINCTRL selection.  This enables selection of pinctrollers for
-Qualcomm processors.
-
-Signed-off-by: Andy Gross <agross@codeaurora.org>
-Acked-by: Linus Walleij <linus.walleij@linaro.org>
----
- arch/arm/mach-qcom/Kconfig |    1 +
- 1 file changed, 1 insertion(+)
-
---- a/arch/arm/mach-qcom/Kconfig
-+++ b/arch/arm/mach-qcom/Kconfig
-@@ -5,6 +5,7 @@ config ARCH_QCOM
- 	select CLKSRC_OF
- 	select GENERIC_CLOCKEVENTS
- 	select HAVE_SMP
-+	select PINCTRL
- 	select QCOM_SCM if SMP
- 	help
- 	  Support for Qualcomm's devicetree based systems.
diff --git a/target/linux/ipq806x/patches/0043-pinctrl-qcom-Correct-name-for-pin-0.patch b/target/linux/ipq806x/patches/0043-pinctrl-qcom-Correct-name-for-pin-0.patch
deleted file mode 100644
index 03896ec..0000000
--- a/target/linux/ipq806x/patches/0043-pinctrl-qcom-Correct-name-for-pin-0.patch
+++ /dev/null
@@ -1,23 +0,0 @@
-From 4cf6d61dc3441f50d1d56bfd72280dbcd2b584a6 Mon Sep 17 00:00:00 2001
-From: Andy Gross <agross@codeaurora.org>
-Date: Fri, 25 Apr 2014 15:41:55 -0500
-Subject: [PATCH 043/182] pinctrl: qcom: Correct name for pin 0
-
-Fix copy/paste error in pinctrl_pin_desc for pin 0.
-
-Signed-off-by: Andy Gross <agross@codeaurora.org>
----
- drivers/pinctrl/pinctrl-ipq8064.c |    2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/drivers/pinctrl/pinctrl-ipq8064.c
-+++ b/drivers/pinctrl/pinctrl-ipq8064.c
-@@ -20,7 +20,7 @@
- #include "pinctrl-msm.h"
- 
- static const struct pinctrl_pin_desc ipq8064_pins[] = {
--	PINCTRL_PIN(0, "GPIO_1"),
-+	PINCTRL_PIN(0, "GPIO_0"),
- 	PINCTRL_PIN(1, "GPIO_1"),
- 	PINCTRL_PIN(2, "GPIO_2"),
- 	PINCTRL_PIN(3, "GPIO_3"),
diff --git a/target/linux/ipq806x/patches/0044-dmaengine-qcom_bam_dma-Add-device-tree-binding.patch b/target/linux/ipq806x/patches/0044-dmaengine-qcom_bam_dma-Add-device-tree-binding.patch
deleted file mode 100644
index e77d05f..0000000
--- a/target/linux/ipq806x/patches/0044-dmaengine-qcom_bam_dma-Add-device-tree-binding.patch
+++ /dev/null
@@ -1,59 +0,0 @@
-From b5e19b657e352d565c5ddeae5f6dfd542de9d7e5 Mon Sep 17 00:00:00 2001
-From: Andy Gross <agross@codeaurora.org>
-Date: Mon, 10 Mar 2014 16:40:19 -0500
-Subject: [PATCH 044/182] dmaengine: qcom_bam_dma: Add device tree binding
-
-Add device tree binding support for the QCOM BAM DMA driver.
-
-Acked-by: Kumar Gala <galak@codeaurora.org>
-Signed-off-by: Andy Gross <agross@codeaurora.org>
-Signed-off-by: Vinod Koul <vinod.koul@intel.com>
----
- .../devicetree/bindings/dma/qcom_bam_dma.txt       |   41 ++++++++++++++++++++
- 1 file changed, 41 insertions(+)
- create mode 100644 Documentation/devicetree/bindings/dma/qcom_bam_dma.txt
-
---- /dev/null
-+++ b/Documentation/devicetree/bindings/dma/qcom_bam_dma.txt
-@@ -0,0 +1,41 @@
-+QCOM BAM DMA controller
-+
-+Required properties:
-+- compatible: must contain "qcom,bam-v1.4.0" for MSM8974
-+- reg: Address range for DMA registers
-+- interrupts: Should contain the one interrupt shared by all channels
-+- #dma-cells: must be <1>, the cell in the dmas property of the client device
-+  represents the channel number
-+- clocks: required clock
-+- clock-names: must contain "bam_clk" entry
-+- qcom,ee : indicates the active Execution Environment identifier (0-7) used in
-+  the secure world.
-+
-+Example:
-+
-+	uart-bam: dma@f9984000 = {
-+		compatible = "qcom,bam-v1.4.0";
-+		reg = <0xf9984000 0x15000>;
-+		interrupts = <0 94 0>;
-+		clocks = <&gcc GCC_BAM_DMA_AHB_CLK>;
-+		clock-names = "bam_clk";
-+		#dma-cells = <1>;
-+		qcom,ee = <0>;
-+	};
-+
-+DMA clients must use the format described in the dma.txt file, using a two cell
-+specifier for each channel.
-+
-+Example:
-+	serial@f991e000 {
-+		compatible = "qcom,msm-uart";
-+		reg = <0xf991e000 0x1000>
-+			<0xf9944000 0x19000>;
-+		interrupts = <0 108 0>;
-+		clocks = <&gcc GCC_BLSP1_UART2_APPS_CLK>,
-+			<&gcc GCC_BLSP1_AHB_CLK>;
-+		clock-names = "core", "iface";
-+
-+		dmas = <&uart-bam 0>, <&uart-bam 1>;
-+		dma-names = "rx", "tx";
-+	};
diff --git a/target/linux/ipq806x/patches/0045-dmaengine-add-Qualcomm-BAM-dma-driver.patch b/target/linux/ipq806x/patches/0045-dmaengine-add-Qualcomm-BAM-dma-driver.patch
deleted file mode 100644
index 98c71db..0000000
--- a/target/linux/ipq806x/patches/0045-dmaengine-add-Qualcomm-BAM-dma-driver.patch
+++ /dev/null
@@ -1,1164 +0,0 @@
-From 23dd43da9c885789b3d5aceed3e401345f8e8106 Mon Sep 17 00:00:00 2001
-From: Andy Gross <agross@codeaurora.org>
-Date: Sat, 29 Mar 2014 18:53:16 +0530
-Subject: [PATCH 045/182] dmaengine: add Qualcomm BAM dma driver
-
-Add the DMA engine driver for the QCOM Bus Access Manager (BAM) DMA controller
-found in the MSM 8x74 platforms.
-
-Each BAM DMA device is associated with a specific on-chip peripheral.  Each
-channel provides a uni-directional data transfer engine that is capable of
-transferring data between the peripheral and system memory (System mode), or
-between two peripherals (BAM2BAM).
-
-The initial release of this driver only supports slave transfers between
-peripherals and system memory.
-
-Signed-off-by: Andy Gross <agross@codeaurora.org>
-Tested-by: Stanimir Varbanov <svarbanov@mm-sol.com>
-Signed-off-by: Vinod Koul <vinod.koul@intel.com>
----
- drivers/dma/Kconfig        |    9 +
- drivers/dma/Makefile       |    2 +
- drivers/dma/qcom_bam_dma.c | 1111 ++++++++++++++++++++++++++++++++++++++++++++
- 3 files changed, 1122 insertions(+)
- create mode 100644 drivers/dma/qcom_bam_dma.c
-
---- a/drivers/dma/Kconfig
-+++ b/drivers/dma/Kconfig
-@@ -401,4 +401,13 @@ config DMATEST
- config DMA_ENGINE_RAID
- 	bool
- 
-+config QCOM_BAM_DMA
-+	tristate "QCOM BAM DMA support"
-+	depends on ARCH_QCOM || (COMPILE_TEST && OF && ARM)
-+	select DMA_ENGINE
-+	select DMA_VIRTUAL_CHANNELS
-+	---help---
-+	  Enable support for the QCOM BAM DMA controller.  This controller
-+	  provides DMA capabilities for a variety of on-chip devices.
-+
- endif
---- a/drivers/dma/Makefile
-+++ b/drivers/dma/Makefile
-@@ -44,3 +44,5 @@ obj-$(CONFIG_DMA_JZ4740) += dma-jz4740.o
- obj-$(CONFIG_TI_CPPI41) += cppi41.o
- obj-$(CONFIG_K3_DMA) += k3dma.o
- obj-$(CONFIG_MOXART_DMA) += moxart-dma.o
-+obj-$(CONFIG_FSL_EDMA) += fsl-edma.o
-+obj-$(CONFIG_QCOM_BAM_DMA) += qcom_bam_dma.o
---- /dev/null
-+++ b/drivers/dma/qcom_bam_dma.c
-@@ -0,0 +1,1111 @@
-+/*
-+ * Copyright (c) 2013-2014, The Linux Foundation. All rights reserved.
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 and
-+ * only version 2 as published by the Free Software Foundation.
-+ *
-+ * 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.
-+ *
-+ */
-+/*
-+ * QCOM BAM DMA engine driver
-+ *
-+ * QCOM BAM DMA blocks are distributed amongst a number of the on-chip
-+ * peripherals on the MSM 8x74.  The configuration of the channels are dependent
-+ * on the way they are hard wired to that specific peripheral.  The peripheral
-+ * device tree entries specify the configuration of each channel.
-+ *
-+ * The DMA controller requires the use of external memory for storage of the
-+ * hardware descriptors for each channel.  The descriptor FIFO is accessed as a
-+ * circular buffer and operations are managed according to the offset within the
-+ * FIFO.  After pipe/channel reset, all of the pipe registers and internal state
-+ * are back to defaults.
-+ *
-+ * During DMA operations, we write descriptors to the FIFO, being careful to
-+ * handle wrapping and then write the last FIFO offset to that channel's
-+ * P_EVNT_REG register to kick off the transaction.  The P_SW_OFSTS register
-+ * indicates the current FIFO offset that is being processed, so there is some
-+ * indication of where the hardware is currently working.
-+ */
-+
-+#include <linux/kernel.h>
-+#include <linux/io.h>
-+#include <linux/init.h>
-+#include <linux/slab.h>
-+#include <linux/module.h>
-+#include <linux/interrupt.h>
-+#include <linux/dma-mapping.h>
-+#include <linux/scatterlist.h>
-+#include <linux/device.h>
-+#include <linux/platform_device.h>
-+#include <linux/of.h>
-+#include <linux/of_address.h>
-+#include <linux/of_irq.h>
-+#include <linux/of_dma.h>
-+#include <linux/clk.h>
-+#include <linux/dmaengine.h>
-+
-+#include "dmaengine.h"
-+#include "virt-dma.h"
-+
-+struct bam_desc_hw {
-+	u32 addr;		/* Buffer physical address */
-+	u16 size;		/* Buffer size in bytes */
-+	u16 flags;
-+};
-+
-+#define DESC_FLAG_INT BIT(15)
-+#define DESC_FLAG_EOT BIT(14)
-+#define DESC_FLAG_EOB BIT(13)
-+
-+struct bam_async_desc {
-+	struct virt_dma_desc vd;
-+
-+	u32 num_desc;
-+	u32 xfer_len;
-+	struct bam_desc_hw *curr_desc;
-+
-+	enum dma_transfer_direction dir;
-+	size_t length;
-+	struct bam_desc_hw desc[0];
-+};
-+
-+#define BAM_CTRL			0x0000
-+#define BAM_REVISION			0x0004
-+#define BAM_SW_REVISION			0x0080
-+#define BAM_NUM_PIPES			0x003C
-+#define BAM_TIMER			0x0040
-+#define BAM_TIMER_CTRL			0x0044
-+#define BAM_DESC_CNT_TRSHLD		0x0008
-+#define BAM_IRQ_SRCS			0x000C
-+#define BAM_IRQ_SRCS_MSK		0x0010
-+#define BAM_IRQ_SRCS_UNMASKED		0x0030
-+#define BAM_IRQ_STTS			0x0014
-+#define BAM_IRQ_CLR			0x0018
-+#define BAM_IRQ_EN			0x001C
-+#define BAM_CNFG_BITS			0x007C
-+#define BAM_IRQ_SRCS_EE(ee)		(0x0800 + ((ee) * 0x80))
-+#define BAM_IRQ_SRCS_MSK_EE(ee)		(0x0804 + ((ee) * 0x80))
-+#define BAM_P_CTRL(pipe)		(0x1000 + ((pipe) * 0x1000))
-+#define BAM_P_RST(pipe)			(0x1004 + ((pipe) * 0x1000))
-+#define BAM_P_HALT(pipe)		(0x1008 + ((pipe) * 0x1000))
-+#define BAM_P_IRQ_STTS(pipe)		(0x1010 + ((pipe) * 0x1000))
-+#define BAM_P_IRQ_CLR(pipe)		(0x1014 + ((pipe) * 0x1000))
-+#define BAM_P_IRQ_EN(pipe)		(0x1018 + ((pipe) * 0x1000))
-+#define BAM_P_EVNT_DEST_ADDR(pipe)	(0x182C + ((pipe) * 0x1000))
-+#define BAM_P_EVNT_REG(pipe)		(0x1818 + ((pipe) * 0x1000))
-+#define BAM_P_SW_OFSTS(pipe)		(0x1800 + ((pipe) * 0x1000))
-+#define BAM_P_DATA_FIFO_ADDR(pipe)	(0x1824 + ((pipe) * 0x1000))
-+#define BAM_P_DESC_FIFO_ADDR(pipe)	(0x181C + ((pipe) * 0x1000))
-+#define BAM_P_EVNT_TRSHLD(pipe)		(0x1828 + ((pipe) * 0x1000))
-+#define BAM_P_FIFO_SIZES(pipe)		(0x1820 + ((pipe) * 0x1000))
-+
-+/* BAM CTRL */
-+#define BAM_SW_RST			BIT(0)
-+#define BAM_EN				BIT(1)
-+#define BAM_EN_ACCUM			BIT(4)
-+#define BAM_TESTBUS_SEL_SHIFT		5
-+#define BAM_TESTBUS_SEL_MASK		0x3F
-+#define BAM_DESC_CACHE_SEL_SHIFT	13
-+#define BAM_DESC_CACHE_SEL_MASK		0x3
-+#define BAM_CACHED_DESC_STORE		BIT(15)
-+#define IBC_DISABLE			BIT(16)
-+
-+/* BAM REVISION */
-+#define REVISION_SHIFT		0
-+#define REVISION_MASK		0xFF
-+#define NUM_EES_SHIFT		8
-+#define NUM_EES_MASK		0xF
-+#define CE_BUFFER_SIZE		BIT(13)
-+#define AXI_ACTIVE		BIT(14)
-+#define USE_VMIDMT		BIT(15)
-+#define SECURED			BIT(16)
-+#define BAM_HAS_NO_BYPASS	BIT(17)
-+#define HIGH_FREQUENCY_BAM	BIT(18)
-+#define INACTIV_TMRS_EXST	BIT(19)
-+#define NUM_INACTIV_TMRS	BIT(20)
-+#define DESC_CACHE_DEPTH_SHIFT	21
-+#define DESC_CACHE_DEPTH_1	(0 << DESC_CACHE_DEPTH_SHIFT)
-+#define DESC_CACHE_DEPTH_2	(1 << DESC_CACHE_DEPTH_SHIFT)
-+#define DESC_CACHE_DEPTH_3	(2 << DESC_CACHE_DEPTH_SHIFT)
-+#define DESC_CACHE_DEPTH_4	(3 << DESC_CACHE_DEPTH_SHIFT)
-+#define CMD_DESC_EN		BIT(23)
-+#define INACTIV_TMR_BASE_SHIFT	24
-+#define INACTIV_TMR_BASE_MASK	0xFF
-+
-+/* BAM NUM PIPES */
-+#define BAM_NUM_PIPES_SHIFT		0
-+#define BAM_NUM_PIPES_MASK		0xFF
-+#define PERIPH_NON_PIPE_GRP_SHIFT	16
-+#define PERIPH_NON_PIP_GRP_MASK		0xFF
-+#define BAM_NON_PIPE_GRP_SHIFT		24
-+#define BAM_NON_PIPE_GRP_MASK		0xFF
-+
-+/* BAM CNFG BITS */
-+#define BAM_PIPE_CNFG		BIT(2)
-+#define BAM_FULL_PIPE		BIT(11)
-+#define BAM_NO_EXT_P_RST	BIT(12)
-+#define BAM_IBC_DISABLE		BIT(13)
-+#define BAM_SB_CLK_REQ		BIT(14)
-+#define BAM_PSM_CSW_REQ		BIT(15)
-+#define BAM_PSM_P_RES		BIT(16)
-+#define BAM_AU_P_RES		BIT(17)
-+#define BAM_SI_P_RES		BIT(18)
-+#define BAM_WB_P_RES		BIT(19)
-+#define BAM_WB_BLK_CSW		BIT(20)
-+#define BAM_WB_CSW_ACK_IDL	BIT(21)
-+#define BAM_WB_RETR_SVPNT	BIT(22)
-+#define BAM_WB_DSC_AVL_P_RST	BIT(23)
-+#define BAM_REG_P_EN		BIT(24)
-+#define BAM_PSM_P_HD_DATA	BIT(25)
-+#define BAM_AU_ACCUMED		BIT(26)
-+#define BAM_CMD_ENABLE		BIT(27)
-+
-+#define BAM_CNFG_BITS_DEFAULT	(BAM_PIPE_CNFG |	\
-+				 BAM_NO_EXT_P_RST |	\
-+				 BAM_IBC_DISABLE |	\
-+				 BAM_SB_CLK_REQ |	\
-+				 BAM_PSM_CSW_REQ |	\
-+				 BAM_PSM_P_RES |	\
-+				 BAM_AU_P_RES |		\
-+				 BAM_SI_P_RES |		\
-+				 BAM_WB_P_RES |		\
-+				 BAM_WB_BLK_CSW |	\
-+				 BAM_WB_CSW_ACK_IDL |	\
-+				 BAM_WB_RETR_SVPNT |	\
-+				 BAM_WB_DSC_AVL_P_RST |	\
-+				 BAM_REG_P_EN |		\
-+				 BAM_PSM_P_HD_DATA |	\
-+				 BAM_AU_ACCUMED |	\
-+				 BAM_CMD_ENABLE)
-+
-+/* PIPE CTRL */
-+#define P_EN			BIT(1)
-+#define P_DIRECTION		BIT(3)
-+#define P_SYS_STRM		BIT(4)
-+#define P_SYS_MODE		BIT(5)
-+#define P_AUTO_EOB		BIT(6)
-+#define P_AUTO_EOB_SEL_SHIFT	7
-+#define P_AUTO_EOB_SEL_512	(0 << P_AUTO_EOB_SEL_SHIFT)
-+#define P_AUTO_EOB_SEL_256	(1 << P_AUTO_EOB_SEL_SHIFT)
-+#define P_AUTO_EOB_SEL_128	(2 << P_AUTO_EOB_SEL_SHIFT)
-+#define P_AUTO_EOB_SEL_64	(3 << P_AUTO_EOB_SEL_SHIFT)
-+#define P_PREFETCH_LIMIT_SHIFT	9
-+#define P_PREFETCH_LIMIT_32	(0 << P_PREFETCH_LIMIT_SHIFT)
-+#define P_PREFETCH_LIMIT_16	(1 << P_PREFETCH_LIMIT_SHIFT)
-+#define P_PREFETCH_LIMIT_4	(2 << P_PREFETCH_LIMIT_SHIFT)
-+#define P_WRITE_NWD		BIT(11)
-+#define P_LOCK_GROUP_SHIFT	16
-+#define P_LOCK_GROUP_MASK	0x1F
-+
-+/* BAM_DESC_CNT_TRSHLD */
-+#define CNT_TRSHLD		0xffff
-+#define DEFAULT_CNT_THRSHLD	0x4
-+
-+/* BAM_IRQ_SRCS */
-+#define BAM_IRQ			BIT(31)
-+#define P_IRQ			0x7fffffff
-+
-+/* BAM_IRQ_SRCS_MSK */
-+#define BAM_IRQ_MSK		BAM_IRQ
-+#define P_IRQ_MSK		P_IRQ
-+
-+/* BAM_IRQ_STTS */
-+#define BAM_TIMER_IRQ		BIT(4)
-+#define BAM_EMPTY_IRQ		BIT(3)
-+#define BAM_ERROR_IRQ		BIT(2)
-+#define BAM_HRESP_ERR_IRQ	BIT(1)
-+
-+/* BAM_IRQ_CLR */
-+#define BAM_TIMER_CLR		BIT(4)
-+#define BAM_EMPTY_CLR		BIT(3)
-+#define BAM_ERROR_CLR		BIT(2)
-+#define BAM_HRESP_ERR_CLR	BIT(1)
-+
-+/* BAM_IRQ_EN */
-+#define BAM_TIMER_EN		BIT(4)
-+#define BAM_EMPTY_EN		BIT(3)
-+#define BAM_ERROR_EN		BIT(2)
-+#define BAM_HRESP_ERR_EN	BIT(1)
-+
-+/* BAM_P_IRQ_EN */
-+#define P_PRCSD_DESC_EN		BIT(0)
-+#define P_TIMER_EN		BIT(1)
-+#define P_WAKE_EN		BIT(2)
-+#define P_OUT_OF_DESC_EN	BIT(3)
-+#define P_ERR_EN		BIT(4)
-+#define P_TRNSFR_END_EN		BIT(5)
-+#define P_DEFAULT_IRQS_EN	(P_PRCSD_DESC_EN | P_ERR_EN | P_TRNSFR_END_EN)
-+
-+/* BAM_P_SW_OFSTS */
-+#define P_SW_OFSTS_MASK		0xffff
-+
-+#define BAM_DESC_FIFO_SIZE	SZ_32K
-+#define MAX_DESCRIPTORS (BAM_DESC_FIFO_SIZE / sizeof(struct bam_desc_hw) - 1)
-+#define BAM_MAX_DATA_SIZE	(SZ_32K - 8)
-+
-+struct bam_chan {
-+	struct virt_dma_chan vc;
-+
-+	struct bam_device *bdev;
-+
-+	/* configuration from device tree */
-+	u32 id;
-+
-+	struct bam_async_desc *curr_txd;	/* current running dma */
-+
-+	/* runtime configuration */
-+	struct dma_slave_config slave;
-+
-+	/* fifo storage */
-+	struct bam_desc_hw *fifo_virt;
-+	dma_addr_t fifo_phys;
-+
-+	/* fifo markers */
-+	unsigned short head;		/* start of active descriptor entries */
-+	unsigned short tail;		/* end of active descriptor entries */
-+
-+	unsigned int initialized;	/* is the channel hw initialized? */
-+	unsigned int paused;		/* is the channel paused? */
-+	unsigned int reconfigure;	/* new slave config? */
-+
-+	struct list_head node;
-+};
-+
-+static inline struct bam_chan *to_bam_chan(struct dma_chan *common)
-+{
-+	return container_of(common, struct bam_chan, vc.chan);
-+}
-+
-+struct bam_device {
-+	void __iomem *regs;
-+	struct device *dev;
-+	struct dma_device common;
-+	struct device_dma_parameters dma_parms;
-+	struct bam_chan *channels;
-+	u32 num_channels;
-+
-+	/* execution environment ID, from DT */
-+	u32 ee;
-+
-+	struct clk *bamclk;
-+	int irq;
-+
-+	/* dma start transaction tasklet */
-+	struct tasklet_struct task;
-+};
-+
-+/**
-+ * bam_reset_channel - Reset individual BAM DMA channel
-+ * @bchan: bam channel
-+ *
-+ * This function resets a specific BAM channel
-+ */
-+static void bam_reset_channel(struct bam_chan *bchan)
-+{
-+	struct bam_device *bdev = bchan->bdev;
-+
-+	lockdep_assert_held(&bchan->vc.lock);
-+
-+	/* reset channel */
-+	writel_relaxed(1, bdev->regs + BAM_P_RST(bchan->id));
-+	writel_relaxed(0, bdev->regs + BAM_P_RST(bchan->id));
-+
-+	/* don't allow cpu to reorder BAM register accesses done after this */
-+	wmb();
-+
-+	/* make sure hw is initialized when channel is used the first time  */
-+	bchan->initialized = 0;
-+}
-+
-+/**
-+ * bam_chan_init_hw - Initialize channel hardware
-+ * @bchan: bam channel
-+ *
-+ * This function resets and initializes the BAM channel
-+ */
-+static void bam_chan_init_hw(struct bam_chan *bchan,
-+	enum dma_transfer_direction dir)
-+{
-+	struct bam_device *bdev = bchan->bdev;
-+	u32 val;
-+
-+	/* Reset the channel to clear internal state of the FIFO */
-+	bam_reset_channel(bchan);
-+
-+	/*
-+	 * write out 8 byte aligned address.  We have enough space for this
-+	 * because we allocated 1 more descriptor (8 bytes) than we can use
-+	 */
-+	writel_relaxed(ALIGN(bchan->fifo_phys, sizeof(struct bam_desc_hw)),
-+			bdev->regs + BAM_P_DESC_FIFO_ADDR(bchan->id));
-+	writel_relaxed(BAM_DESC_FIFO_SIZE, bdev->regs +
-+			BAM_P_FIFO_SIZES(bchan->id));
-+
-+	/* enable the per pipe interrupts, enable EOT, ERR, and INT irqs */
-+	writel_relaxed(P_DEFAULT_IRQS_EN, bdev->regs + BAM_P_IRQ_EN(bchan->id));
-+
-+	/* unmask the specific pipe and EE combo */
-+	val = readl_relaxed(bdev->regs + BAM_IRQ_SRCS_MSK_EE(bdev->ee));
-+	val |= BIT(bchan->id);
-+	writel_relaxed(val, bdev->regs + BAM_IRQ_SRCS_MSK_EE(bdev->ee));
-+
-+	/* don't allow cpu to reorder the channel enable done below */
-+	wmb();
-+
-+	/* set fixed direction and mode, then enable channel */
-+	val = P_EN | P_SYS_MODE;
-+	if (dir == DMA_DEV_TO_MEM)
-+		val |= P_DIRECTION;
-+
-+	writel_relaxed(val, bdev->regs + BAM_P_CTRL(bchan->id));
-+
-+	bchan->initialized = 1;
-+
-+	/* init FIFO pointers */
-+	bchan->head = 0;
-+	bchan->tail = 0;
-+}
-+
-+/**
-+ * bam_alloc_chan - Allocate channel resources for DMA channel.
-+ * @chan: specified channel
-+ *
-+ * This function allocates the FIFO descriptor memory
-+ */
-+static int bam_alloc_chan(struct dma_chan *chan)
-+{
-+	struct bam_chan *bchan = to_bam_chan(chan);
-+	struct bam_device *bdev = bchan->bdev;
-+
-+	if (bchan->fifo_virt)
-+		return 0;
-+
-+	/* allocate FIFO descriptor space, but only if necessary */
-+	bchan->fifo_virt = dma_alloc_writecombine(bdev->dev, BAM_DESC_FIFO_SIZE,
-+				&bchan->fifo_phys, GFP_KERNEL);
-+
-+	if (!bchan->fifo_virt) {
-+		dev_err(bdev->dev, "Failed to allocate desc fifo\n");
-+		return -ENOMEM;
-+	}
-+
-+	return 0;
-+}
-+
-+/**
-+ * bam_free_chan - Frees dma resources associated with specific channel
-+ * @chan: specified channel
-+ *
-+ * Free the allocated fifo descriptor memory and channel resources
-+ *
-+ */
-+static void bam_free_chan(struct dma_chan *chan)
-+{
-+	struct bam_chan *bchan = to_bam_chan(chan);
-+	struct bam_device *bdev = bchan->bdev;
-+	u32 val;
-+	unsigned long flags;
-+
-+	vchan_free_chan_resources(to_virt_chan(chan));
-+
-+	if (bchan->curr_txd) {
-+		dev_err(bchan->bdev->dev, "Cannot free busy channel\n");
-+		return;
-+	}
-+
-+	spin_lock_irqsave(&bchan->vc.lock, flags);
-+	bam_reset_channel(bchan);
-+	spin_unlock_irqrestore(&bchan->vc.lock, flags);
-+
-+	dma_free_writecombine(bdev->dev, BAM_DESC_FIFO_SIZE, bchan->fifo_virt,
-+				bchan->fifo_phys);
-+	bchan->fifo_virt = NULL;
-+
-+	/* mask irq for pipe/channel */
-+	val = readl_relaxed(bdev->regs + BAM_IRQ_SRCS_MSK_EE(bdev->ee));
-+	val &= ~BIT(bchan->id);
-+	writel_relaxed(val, bdev->regs + BAM_IRQ_SRCS_MSK_EE(bdev->ee));
-+
-+	/* disable irq */
-+	writel_relaxed(0, bdev->regs + BAM_P_IRQ_EN(bchan->id));
-+}
-+
-+/**
-+ * bam_slave_config - set slave configuration for channel
-+ * @chan: dma channel
-+ * @cfg: slave configuration
-+ *
-+ * Sets slave configuration for channel
-+ *
-+ */
-+static void bam_slave_config(struct bam_chan *bchan,
-+		struct dma_slave_config *cfg)
-+{
-+	memcpy(&bchan->slave, cfg, sizeof(*cfg));
-+	bchan->reconfigure = 1;
-+}
-+
-+/**
-+ * bam_prep_slave_sg - Prep slave sg transaction
-+ *
-+ * @chan: dma channel
-+ * @sgl: scatter gather list
-+ * @sg_len: length of sg
-+ * @direction: DMA transfer direction
-+ * @flags: DMA flags
-+ * @context: transfer context (unused)
-+ */
-+static struct dma_async_tx_descriptor *bam_prep_slave_sg(struct dma_chan *chan,
-+	struct scatterlist *sgl, unsigned int sg_len,
-+	enum dma_transfer_direction direction, unsigned long flags,
-+	void *context)
-+{
-+	struct bam_chan *bchan = to_bam_chan(chan);
-+	struct bam_device *bdev = bchan->bdev;
-+	struct bam_async_desc *async_desc;
-+	struct scatterlist *sg;
-+	u32 i;
-+	struct bam_desc_hw *desc;
-+	unsigned int num_alloc = 0;
-+
-+
-+	if (!is_slave_direction(direction)) {
-+		dev_err(bdev->dev, "invalid dma direction\n");
-+		return NULL;
-+	}
-+
-+	/* calculate number of required entries */
-+	for_each_sg(sgl, sg, sg_len, i)
-+		num_alloc += DIV_ROUND_UP(sg_dma_len(sg), BAM_MAX_DATA_SIZE);
-+
-+	/* allocate enough room to accomodate the number of entries */
-+	async_desc = kzalloc(sizeof(*async_desc) +
-+			(num_alloc * sizeof(struct bam_desc_hw)), GFP_NOWAIT);
-+
-+	if (!async_desc)
-+		goto err_out;
-+
-+	async_desc->num_desc = num_alloc;
-+	async_desc->curr_desc = async_desc->desc;
-+	async_desc->dir = direction;
-+
-+	/* fill in temporary descriptors */
-+	desc = async_desc->desc;
-+	for_each_sg(sgl, sg, sg_len, i) {
-+		unsigned int remainder = sg_dma_len(sg);
-+		unsigned int curr_offset = 0;
-+
-+		do {
-+			desc->addr = sg_dma_address(sg) + curr_offset;
-+
-+			if (remainder > BAM_MAX_DATA_SIZE) {
-+				desc->size = BAM_MAX_DATA_SIZE;
-+				remainder -= BAM_MAX_DATA_SIZE;
-+				curr_offset += BAM_MAX_DATA_SIZE;
-+			} else {
-+				desc->size = remainder;
-+				remainder = 0;
-+			}
-+
-+			async_desc->length += desc->size;
-+			desc++;
-+		} while (remainder > 0);
-+	}
-+
-+	return vchan_tx_prep(&bchan->vc, &async_desc->vd, flags);
-+
-+err_out:
-+	kfree(async_desc);
-+	return NULL;
-+}
-+
-+/**
-+ * bam_dma_terminate_all - terminate all transactions on a channel
-+ * @bchan: bam dma channel
-+ *
-+ * Dequeues and frees all transactions
-+ * No callbacks are done
-+ *
-+ */
-+static void bam_dma_terminate_all(struct bam_chan *bchan)
-+{
-+	unsigned long flag;
-+	LIST_HEAD(head);
-+
-+	/* remove all transactions, including active transaction */
-+	spin_lock_irqsave(&bchan->vc.lock, flag);
-+	if (bchan->curr_txd) {
-+		list_add(&bchan->curr_txd->vd.node, &bchan->vc.desc_issued);
-+		bchan->curr_txd = NULL;
-+	}
-+
-+	vchan_get_all_descriptors(&bchan->vc, &head);
-+	spin_unlock_irqrestore(&bchan->vc.lock, flag);
-+
-+	vchan_dma_desc_free_list(&bchan->vc, &head);
-+}
-+
-+/**
-+ * bam_control - DMA device control
-+ * @chan: dma channel
-+ * @cmd: control cmd
-+ * @arg: cmd argument
-+ *
-+ * Perform DMA control command
-+ *
-+ */
-+static int bam_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd,
-+	unsigned long arg)
-+{
-+	struct bam_chan *bchan = to_bam_chan(chan);
-+	struct bam_device *bdev = bchan->bdev;
-+	int ret = 0;
-+	unsigned long flag;
-+
-+	switch (cmd) {
-+	case DMA_PAUSE:
-+		spin_lock_irqsave(&bchan->vc.lock, flag);
-+		writel_relaxed(1, bdev->regs + BAM_P_HALT(bchan->id));
-+		bchan->paused = 1;
-+		spin_unlock_irqrestore(&bchan->vc.lock, flag);
-+		break;
-+
-+	case DMA_RESUME:
-+		spin_lock_irqsave(&bchan->vc.lock, flag);
-+		writel_relaxed(0, bdev->regs + BAM_P_HALT(bchan->id));
-+		bchan->paused = 0;
-+		spin_unlock_irqrestore(&bchan->vc.lock, flag);
-+		break;
-+
-+	case DMA_TERMINATE_ALL:
-+		bam_dma_terminate_all(bchan);
-+		break;
-+
-+	case DMA_SLAVE_CONFIG:
-+		spin_lock_irqsave(&bchan->vc.lock, flag);
-+		bam_slave_config(bchan, (struct dma_slave_config *)arg);
-+		spin_unlock_irqrestore(&bchan->vc.lock, flag);
-+		break;
-+
-+	default:
-+		ret = -ENXIO;
-+		break;
-+	}
-+
-+	return ret;
-+}
-+
-+/**
-+ * process_channel_irqs - processes the channel interrupts
-+ * @bdev: bam controller
-+ *
-+ * This function processes the channel interrupts
-+ *
-+ */
-+static u32 process_channel_irqs(struct bam_device *bdev)
-+{
-+	u32 i, srcs, pipe_stts;
-+	unsigned long flags;
-+	struct bam_async_desc *async_desc;
-+
-+	srcs = readl_relaxed(bdev->regs + BAM_IRQ_SRCS_EE(bdev->ee));
-+
-+	/* return early if no pipe/channel interrupts are present */
-+	if (!(srcs & P_IRQ))
-+		return srcs;
-+
-+	for (i = 0; i < bdev->num_channels; i++) {
-+		struct bam_chan *bchan = &bdev->channels[i];
-+
-+		if (!(srcs & BIT(i)))
-+			continue;
-+
-+		/* clear pipe irq */
-+		pipe_stts = readl_relaxed(bdev->regs +
-+			BAM_P_IRQ_STTS(i));
-+
-+		writel_relaxed(pipe_stts, bdev->regs +
-+				BAM_P_IRQ_CLR(i));
-+
-+		spin_lock_irqsave(&bchan->vc.lock, flags);
-+		async_desc = bchan->curr_txd;
-+
-+		if (async_desc) {
-+			async_desc->num_desc -= async_desc->xfer_len;
-+			async_desc->curr_desc += async_desc->xfer_len;
-+			bchan->curr_txd = NULL;
-+
-+			/* manage FIFO */
-+			bchan->head += async_desc->xfer_len;
-+			bchan->head %= MAX_DESCRIPTORS;
-+
-+			/*
-+			 * if complete, process cookie.  Otherwise
-+			 * push back to front of desc_issued so that
-+			 * it gets restarted by the tasklet
-+			 */
-+			if (!async_desc->num_desc)
-+				vchan_cookie_complete(&async_desc->vd);
-+			else
-+				list_add(&async_desc->vd.node,
-+					&bchan->vc.desc_issued);
-+		}
-+
-+		spin_unlock_irqrestore(&bchan->vc.lock, flags);
-+	}
-+
-+	return srcs;
-+}
-+
-+/**
-+ * bam_dma_irq - irq handler for bam controller
-+ * @irq: IRQ of interrupt
-+ * @data: callback data
-+ *
-+ * IRQ handler for the bam controller
-+ */
-+static irqreturn_t bam_dma_irq(int irq, void *data)
-+{
-+	struct bam_device *bdev = data;
-+	u32 clr_mask = 0, srcs = 0;
-+
-+	srcs |= process_channel_irqs(bdev);
-+
-+	/* kick off tasklet to start next dma transfer */
-+	if (srcs & P_IRQ)
-+		tasklet_schedule(&bdev->task);
-+
-+	if (srcs & BAM_IRQ)
-+		clr_mask = readl_relaxed(bdev->regs + BAM_IRQ_STTS);
-+
-+	/* don't allow reorder of the various accesses to the BAM registers */
-+	mb();
-+
-+	writel_relaxed(clr_mask, bdev->regs + BAM_IRQ_CLR);
-+
-+	return IRQ_HANDLED;
-+}
-+
-+/**
-+ * bam_tx_status - returns status of transaction
-+ * @chan: dma channel
-+ * @cookie: transaction cookie
-+ * @txstate: DMA transaction state
-+ *
-+ * Return status of dma transaction
-+ */
-+static enum dma_status bam_tx_status(struct dma_chan *chan, dma_cookie_t cookie,
-+		struct dma_tx_state *txstate)
-+{
-+	struct bam_chan *bchan = to_bam_chan(chan);
-+	struct virt_dma_desc *vd;
-+	int ret;
-+	size_t residue = 0;
-+	unsigned int i;
-+	unsigned long flags;
-+
-+	ret = dma_cookie_status(chan, cookie, txstate);
-+	if (ret == DMA_COMPLETE)
-+		return ret;
-+
-+	if (!txstate)
-+		return bchan->paused ? DMA_PAUSED : ret;
-+
-+	spin_lock_irqsave(&bchan->vc.lock, flags);
-+	vd = vchan_find_desc(&bchan->vc, cookie);
-+	if (vd)
-+		residue = container_of(vd, struct bam_async_desc, vd)->length;
-+	else if (bchan->curr_txd && bchan->curr_txd->vd.tx.cookie == cookie)
-+		for (i = 0; i < bchan->curr_txd->num_desc; i++)
-+			residue += bchan->curr_txd->curr_desc[i].size;
-+
-+	spin_unlock_irqrestore(&bchan->vc.lock, flags);
-+
-+	dma_set_residue(txstate, residue);
-+
-+	if (ret == DMA_IN_PROGRESS && bchan->paused)
-+		ret = DMA_PAUSED;
-+
-+	return ret;
-+}
-+
-+/**
-+ * bam_apply_new_config
-+ * @bchan: bam dma channel
-+ * @dir: DMA direction
-+ */
-+static void bam_apply_new_config(struct bam_chan *bchan,
-+	enum dma_transfer_direction dir)
-+{
-+	struct bam_device *bdev = bchan->bdev;
-+	u32 maxburst;
-+
-+	if (dir == DMA_DEV_TO_MEM)
-+		maxburst = bchan->slave.src_maxburst;
-+	else
-+		maxburst = bchan->slave.dst_maxburst;
-+
-+	writel_relaxed(maxburst, bdev->regs + BAM_DESC_CNT_TRSHLD);
-+
-+	bchan->reconfigure = 0;
-+}
-+
-+/**
-+ * bam_start_dma - start next transaction
-+ * @bchan - bam dma channel
-+ */
-+static void bam_start_dma(struct bam_chan *bchan)
-+{
-+	struct virt_dma_desc *vd = vchan_next_desc(&bchan->vc);
-+	struct bam_device *bdev = bchan->bdev;
-+	struct bam_async_desc *async_desc;
-+	struct bam_desc_hw *desc;
-+	struct bam_desc_hw *fifo = PTR_ALIGN(bchan->fifo_virt,
-+					sizeof(struct bam_desc_hw));
-+
-+	lockdep_assert_held(&bchan->vc.lock);
-+
-+	if (!vd)
-+		return;
-+
-+	list_del(&vd->node);
-+
-+	async_desc = container_of(vd, struct bam_async_desc, vd);
-+	bchan->curr_txd = async_desc;
-+
-+	/* on first use, initialize the channel hardware */
-+	if (!bchan->initialized)
-+		bam_chan_init_hw(bchan, async_desc->dir);
-+
-+	/* apply new slave config changes, if necessary */
-+	if (bchan->reconfigure)
-+		bam_apply_new_config(bchan, async_desc->dir);
-+
-+	desc = bchan->curr_txd->curr_desc;
-+
-+	if (async_desc->num_desc > MAX_DESCRIPTORS)
-+		async_desc->xfer_len = MAX_DESCRIPTORS;
-+	else
-+		async_desc->xfer_len = async_desc->num_desc;
-+
-+	/* set INT on last descriptor */
-+	desc[async_desc->xfer_len - 1].flags |= DESC_FLAG_INT;
-+
-+	if (bchan->tail + async_desc->xfer_len > MAX_DESCRIPTORS) {
-+		u32 partial = MAX_DESCRIPTORS - bchan->tail;
-+
-+		memcpy(&fifo[bchan->tail], desc,
-+				partial * sizeof(struct bam_desc_hw));
-+		memcpy(fifo, &desc[partial], (async_desc->xfer_len - partial) *
-+				sizeof(struct bam_desc_hw));
-+	} else {
-+		memcpy(&fifo[bchan->tail], desc,
-+			async_desc->xfer_len * sizeof(struct bam_desc_hw));
-+	}
-+
-+	bchan->tail += async_desc->xfer_len;
-+	bchan->tail %= MAX_DESCRIPTORS;
-+
-+	/* ensure descriptor writes and dma start not reordered */
-+	wmb();
-+	writel_relaxed(bchan->tail * sizeof(struct bam_desc_hw),
-+			bdev->regs + BAM_P_EVNT_REG(bchan->id));
-+}
-+
-+/**
-+ * dma_tasklet - DMA IRQ tasklet
-+ * @data: tasklet argument (bam controller structure)
-+ *
-+ * Sets up next DMA operation and then processes all completed transactions
-+ */
-+static void dma_tasklet(unsigned long data)
-+{
-+	struct bam_device *bdev = (struct bam_device *)data;
-+	struct bam_chan *bchan;
-+	unsigned long flags;
-+	unsigned int i;
-+
-+	/* go through the channels and kick off transactions */
-+	for (i = 0; i < bdev->num_channels; i++) {
-+		bchan = &bdev->channels[i];
-+		spin_lock_irqsave(&bchan->vc.lock, flags);
-+
-+		if (!list_empty(&bchan->vc.desc_issued) && !bchan->curr_txd)
-+			bam_start_dma(bchan);
-+		spin_unlock_irqrestore(&bchan->vc.lock, flags);
-+	}
-+}
-+
-+/**
-+ * bam_issue_pending - starts pending transactions
-+ * @chan: dma channel
-+ *
-+ * Calls tasklet directly which in turn starts any pending transactions
-+ */
-+static void bam_issue_pending(struct dma_chan *chan)
-+{
-+	struct bam_chan *bchan = to_bam_chan(chan);
-+	unsigned long flags;
-+
-+	spin_lock_irqsave(&bchan->vc.lock, flags);
-+
-+	/* if work pending and idle, start a transaction */
-+	if (vchan_issue_pending(&bchan->vc) && !bchan->curr_txd)
-+		bam_start_dma(bchan);
-+
-+	spin_unlock_irqrestore(&bchan->vc.lock, flags);
-+}
-+
-+/**
-+ * bam_dma_free_desc - free descriptor memory
-+ * @vd: virtual descriptor
-+ *
-+ */
-+static void bam_dma_free_desc(struct virt_dma_desc *vd)
-+{
-+	struct bam_async_desc *async_desc = container_of(vd,
-+			struct bam_async_desc, vd);
-+
-+	kfree(async_desc);
-+}
-+
-+static struct dma_chan *bam_dma_xlate(struct of_phandle_args *dma_spec,
-+		struct of_dma *of)
-+{
-+	struct bam_device *bdev = container_of(of->of_dma_data,
-+					struct bam_device, common);
-+	unsigned int request;
-+
-+	if (dma_spec->args_count != 1)
-+		return NULL;
-+
-+	request = dma_spec->args[0];
-+	if (request >= bdev->num_channels)
-+		return NULL;
-+
-+	return dma_get_slave_channel(&(bdev->channels[request].vc.chan));
-+}
-+
-+/**
-+ * bam_init
-+ * @bdev: bam device
-+ *
-+ * Initialization helper for global bam registers
-+ */
-+static int bam_init(struct bam_device *bdev)
-+{
-+	u32 val;
-+
-+	/* read revision and configuration information */
-+	val = readl_relaxed(bdev->regs + BAM_REVISION) >> NUM_EES_SHIFT;
-+	val &= NUM_EES_MASK;
-+
-+	/* check that configured EE is within range */
-+	if (bdev->ee >= val)
-+		return -EINVAL;
-+
-+	val = readl_relaxed(bdev->regs + BAM_NUM_PIPES);
-+	bdev->num_channels = val & BAM_NUM_PIPES_MASK;
-+
-+	/* s/w reset bam */
-+	/* after reset all pipes are disabled and idle */
-+	val = readl_relaxed(bdev->regs + BAM_CTRL);
-+	val |= BAM_SW_RST;
-+	writel_relaxed(val, bdev->regs + BAM_CTRL);
-+	val &= ~BAM_SW_RST;
-+	writel_relaxed(val, bdev->regs + BAM_CTRL);
-+
-+	/* make sure previous stores are visible before enabling BAM */
-+	wmb();
-+
-+	/* enable bam */
-+	val |= BAM_EN;
-+	writel_relaxed(val, bdev->regs + BAM_CTRL);
-+
-+	/* set descriptor threshhold, start with 4 bytes */
-+	writel_relaxed(DEFAULT_CNT_THRSHLD, bdev->regs + BAM_DESC_CNT_TRSHLD);
-+
-+	/* Enable default set of h/w workarounds, ie all except BAM_FULL_PIPE */
-+	writel_relaxed(BAM_CNFG_BITS_DEFAULT, bdev->regs + BAM_CNFG_BITS);
-+
-+	/* enable irqs for errors */
-+	writel_relaxed(BAM_ERROR_EN | BAM_HRESP_ERR_EN,
-+				bdev->regs + BAM_IRQ_EN);
-+
-+	/* unmask global bam interrupt */
-+	writel_relaxed(BAM_IRQ_MSK, bdev->regs + BAM_IRQ_SRCS_MSK_EE(bdev->ee));
-+
-+	return 0;
-+}
-+
-+static void bam_channel_init(struct bam_device *bdev, struct bam_chan *bchan,
-+	u32 index)
-+{
-+	bchan->id = index;
-+	bchan->bdev = bdev;
-+
-+	vchan_init(&bchan->vc, &bdev->common);
-+	bchan->vc.desc_free = bam_dma_free_desc;
-+}
-+
-+static int bam_dma_probe(struct platform_device *pdev)
-+{
-+	struct bam_device *bdev;
-+	struct resource *iores;
-+	int ret, i;
-+
-+	bdev = devm_kzalloc(&pdev->dev, sizeof(*bdev), GFP_KERNEL);
-+	if (!bdev)
-+		return -ENOMEM;
-+
-+	bdev->dev = &pdev->dev;
-+
-+	iores = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-+	bdev->regs = devm_ioremap_resource(&pdev->dev, iores);
-+	if (IS_ERR(bdev->regs))
-+		return PTR_ERR(bdev->regs);
-+
-+	bdev->irq = platform_get_irq(pdev, 0);
-+	if (bdev->irq < 0)
-+		return bdev->irq;
-+
-+	ret = of_property_read_u32(pdev->dev.of_node, "qcom,ee", &bdev->ee);
-+	if (ret) {
-+		dev_err(bdev->dev, "Execution environment unspecified\n");
-+		return ret;
-+	}
-+
-+	bdev->bamclk = devm_clk_get(bdev->dev, "bam_clk");
-+	if (IS_ERR(bdev->bamclk))
-+		return PTR_ERR(bdev->bamclk);
-+
-+	ret = clk_prepare_enable(bdev->bamclk);
-+	if (ret) {
-+		dev_err(bdev->dev, "failed to prepare/enable clock\n");
-+		return ret;
-+	}
-+
-+	ret = bam_init(bdev);
-+	if (ret)
-+		goto err_disable_clk;
-+
-+	tasklet_init(&bdev->task, dma_tasklet, (unsigned long)bdev);
-+
-+	bdev->channels = devm_kcalloc(bdev->dev, bdev->num_channels,
-+				sizeof(*bdev->channels), GFP_KERNEL);
-+
-+	if (!bdev->channels) {
-+		ret = -ENOMEM;
-+		goto err_disable_clk;
-+	}
-+
-+	/* allocate and initialize channels */
-+	INIT_LIST_HEAD(&bdev->common.channels);
-+
-+	for (i = 0; i < bdev->num_channels; i++)
-+		bam_channel_init(bdev, &bdev->channels[i], i);
-+
-+	ret = devm_request_irq(bdev->dev, bdev->irq, bam_dma_irq,
-+			IRQF_TRIGGER_HIGH, "bam_dma", bdev);
-+	if (ret)
-+		goto err_disable_clk;
-+
-+	/* set max dma segment size */
-+	bdev->common.dev = bdev->dev;
-+	bdev->common.dev->dma_parms = &bdev->dma_parms;
-+	ret = dma_set_max_seg_size(bdev->common.dev, BAM_MAX_DATA_SIZE);
-+	if (ret) {
-+		dev_err(bdev->dev, "cannot set maximum segment size\n");
-+		goto err_disable_clk;
-+	}
-+
-+	platform_set_drvdata(pdev, bdev);
-+
-+	/* set capabilities */
-+	dma_cap_zero(bdev->common.cap_mask);
-+	dma_cap_set(DMA_SLAVE, bdev->common.cap_mask);
-+
-+	/* initialize dmaengine apis */
-+	bdev->common.device_alloc_chan_resources = bam_alloc_chan;
-+	bdev->common.device_free_chan_resources = bam_free_chan;
-+	bdev->common.device_prep_slave_sg = bam_prep_slave_sg;
-+	bdev->common.device_control = bam_control;
-+	bdev->common.device_issue_pending = bam_issue_pending;
-+	bdev->common.device_tx_status = bam_tx_status;
-+	bdev->common.dev = bdev->dev;
-+
-+	ret = dma_async_device_register(&bdev->common);
-+	if (ret) {
-+		dev_err(bdev->dev, "failed to register dma async device\n");
-+		goto err_disable_clk;
-+	}
-+
-+	ret = of_dma_controller_register(pdev->dev.of_node, bam_dma_xlate,
-+					&bdev->common);
-+	if (ret)
-+		goto err_unregister_dma;
-+
-+	return 0;
-+
-+err_unregister_dma:
-+	dma_async_device_unregister(&bdev->common);
-+err_disable_clk:
-+	clk_disable_unprepare(bdev->bamclk);
-+	return ret;
-+}
-+
-+static int bam_dma_remove(struct platform_device *pdev)
-+{
-+	struct bam_device *bdev = platform_get_drvdata(pdev);
-+	u32 i;
-+
-+	of_dma_controller_free(pdev->dev.of_node);
-+	dma_async_device_unregister(&bdev->common);
-+
-+	/* mask all interrupts for this execution environment */
-+	writel_relaxed(0, bdev->regs + BAM_IRQ_SRCS_MSK_EE(bdev->ee));
-+
-+	devm_free_irq(bdev->dev, bdev->irq, bdev);
-+
-+	for (i = 0; i < bdev->num_channels; i++) {
-+		bam_dma_terminate_all(&bdev->channels[i]);
-+		tasklet_kill(&bdev->channels[i].vc.task);
-+
-+		dma_free_writecombine(bdev->dev, BAM_DESC_FIFO_SIZE,
-+			bdev->channels[i].fifo_virt,
-+			bdev->channels[i].fifo_phys);
-+	}
-+
-+	tasklet_kill(&bdev->task);
-+
-+	clk_disable_unprepare(bdev->bamclk);
-+
-+	return 0;
-+}
-+
-+static const struct of_device_id bam_of_match[] = {
-+	{ .compatible = "qcom,bam-v1.4.0", },
-+	{}
-+};
-+MODULE_DEVICE_TABLE(of, bam_of_match);
-+
-+static struct platform_driver bam_dma_driver = {
-+	.probe = bam_dma_probe,
-+	.remove = bam_dma_remove,
-+	.driver = {
-+		.name = "bam-dma-engine",
-+		.owner = THIS_MODULE,
-+		.of_match_table = bam_of_match,
-+	},
-+};
-+
-+module_platform_driver(bam_dma_driver);
-+
-+MODULE_AUTHOR("Andy Gross <agross@codeaurora.org>");
-+MODULE_DESCRIPTION("QCOM BAM DMA engine driver");
-+MODULE_LICENSE("GPL v2");
diff --git a/target/linux/ipq806x/patches/0046-mmc-sdhci-msm-Qualcomm-SDHCI-binding-documentation.patch b/target/linux/ipq806x/patches/0046-mmc-sdhci-msm-Qualcomm-SDHCI-binding-documentation.patch
deleted file mode 100644
index 65c5347..0000000
--- a/target/linux/ipq806x/patches/0046-mmc-sdhci-msm-Qualcomm-SDHCI-binding-documentation.patch
+++ /dev/null
@@ -1,75 +0,0 @@
-From 8a70c89b2fbb635a8d4fec302165343827aeed9f Mon Sep 17 00:00:00 2001
-From: Georgi Djakov <gdjakov@mm-sol.com>
-Date: Mon, 10 Mar 2014 17:37:11 +0200
-Subject: [PATCH 046/182] mmc: sdhci-msm: Qualcomm SDHCI binding documentation
-
-This patch adds the device-tree binding documentation for Qualcomm
-SDHCI driver. It contains the differences between the core properties
-in mmc.txt and the properties used by the sdhci-msm driver.
-
-Signed-off-by: Georgi Djakov <gdjakov@mm-sol.com>
-Acked-by: Ulf Hansson <ulf.hansson@linaro.org>
-Signed-off-by: Chris Ball <chris@printf.net>
----
- .../devicetree/bindings/mmc/sdhci-msm.txt          |   55 ++++++++++++++++++++
- 1 file changed, 55 insertions(+)
- create mode 100644 Documentation/devicetree/bindings/mmc/sdhci-msm.txt
-
---- /dev/null
-+++ b/Documentation/devicetree/bindings/mmc/sdhci-msm.txt
-@@ -0,0 +1,55 @@
-+* Qualcomm SDHCI controller (sdhci-msm)
-+
-+This file documents differences between the core properties in mmc.txt
-+and the properties used by the sdhci-msm driver.
-+
-+Required properties:
-+- compatible: Should contain "qcom,sdhci-msm-v4".
-+- reg: Base address and length of the register in the following order:
-+	- Host controller register map (required)
-+	- SD Core register map (required)
-+- interrupts: Should contain an interrupt-specifiers for the interrupts:
-+	- Host controller interrupt (required)
-+- pinctrl-names: Should contain only one value - "default".
-+- pinctrl-0: Should specify pin control groups used for this controller.
-+- clocks: A list of phandle + clock-specifier pairs for the clocks listed in clock-names.
-+- clock-names: Should contain the following:
-+	"iface" - Main peripheral bus clock (PCLK/HCLK - AHB Bus clock) (required)
-+	"core"	- SDC MMC clock (MCLK) (required)
-+	"bus"	- SDCC bus voter clock (optional)
-+
-+Example:
-+
-+	sdhc_1: sdhci@f9824900 {
-+		compatible = "qcom,sdhci-msm-v4";
-+		reg = <0xf9824900 0x11c>, <0xf9824000 0x800>;
-+		interrupts = <0 123 0>;
-+		bus-width = <8>;
-+		non-removable;
-+
-+		vmmc = <&pm8941_l20>;
-+		vqmmc = <&pm8941_s3>;
-+
-+		pinctrl-names = "default";
-+		pinctrl-0 = <&sdc1_clk &sdc1_cmd &sdc1_data>;
-+
-+		clocks = <&gcc GCC_SDCC1_APPS_CLK>, <&gcc GCC_SDCC1_AHB_CLK>;
-+		clock-names = "core", "iface";
-+	};
-+
-+	sdhc_2: sdhci@f98a4900 {
-+		compatible = "qcom,sdhci-msm-v4";
-+		reg = <0xf98a4900 0x11c>, <0xf98a4000 0x800>;
-+		interrupts = <0 125 0>;
-+		bus-width = <4>;
-+		cd-gpios = <&msmgpio 62 0x1>;
-+
-+		vmmc = <&pm8941_l21>;
-+		vqmmc = <&pm8941_l13>;
-+
-+		pinctrl-names = "default";
-+		pinctrl-0 = <&sdc2_clk &sdc2_cmd &sdc2_data>;
-+
-+		clocks = <&gcc GCC_SDCC2_APPS_CLK>, <&gcc GCC_SDCC2_AHB_CLK>;
-+		clock-names = "core", "iface";
-+	};
diff --git a/target/linux/ipq806x/patches/0047-mmc-sdhci-msm-Initial-support-for-Qualcomm-chipsets.patch b/target/linux/ipq806x/patches/0047-mmc-sdhci-msm-Initial-support-for-Qualcomm-chipsets.patch
deleted file mode 100644
index 9417e1d..0000000
--- a/target/linux/ipq806x/patches/0047-mmc-sdhci-msm-Initial-support-for-Qualcomm-chipsets.patch
+++ /dev/null
@@ -1,265 +0,0 @@
-From 5a8f026acb4a7a6c6d0c868cc1790363640b9b8f Mon Sep 17 00:00:00 2001
-From: Georgi Djakov <gdjakov@mm-sol.com>
-Date: Mon, 10 Mar 2014 17:37:12 +0200
-Subject: [PATCH 047/182] mmc: sdhci-msm: Initial support for Qualcomm
- chipsets
-
-This platform driver adds the initial support of Secure Digital Host
-Controller Interface compliant controller found in Qualcomm chipsets.
-
-Signed-off-by: Asutosh Das <asutoshd@codeaurora.org>
-Signed-off-by: Venkat Gopalakrishnan <venkatg@codeaurora.org>
-Tested-by: Ivan T. Ivanov <iivanov@mm-sol.com>
-Signed-off-by: Georgi Djakov <gdjakov@mm-sol.com>
-Acked-by: Ulf Hansson <ulf.hansson@linaro.org>
-Signed-off-by: Chris Ball <chris@printf.net>
----
- drivers/mmc/host/Kconfig     |   13 +++
- drivers/mmc/host/Makefile    |    1 +
- drivers/mmc/host/sdhci-msm.c |  208 ++++++++++++++++++++++++++++++++++++++++++
- 3 files changed, 222 insertions(+)
- create mode 100644 drivers/mmc/host/sdhci-msm.c
-
---- a/drivers/mmc/host/Kconfig
-+++ b/drivers/mmc/host/Kconfig
-@@ -334,6 +334,19 @@ config MMC_ATMELMCI
- 
- 	  If unsure, say N.
- 
-+config MMC_SDHCI_MSM
-+	tristate "Qualcomm SDHCI Controller Support"
-+	depends on ARCH_QCOM
-+	depends on MMC_SDHCI_PLTFM
-+	help
-+	  This selects the Secure Digital Host Controller Interface (SDHCI)
-+	  support present in Qualcomm SOCs. The controller supports
-+	  SD/MMC/SDIO devices.
-+
-+	  If you have a controller with this interface, say Y or M here.
-+
-+	  If unsure, say N.
-+
- config MMC_MSM
- 	tristate "Qualcomm SDCC Controller Support"
- 	depends on MMC && (ARCH_MSM7X00A || ARCH_MSM7X30 || ARCH_QSD8X50)
---- a/drivers/mmc/host/Makefile
-+++ b/drivers/mmc/host/Makefile
-@@ -65,6 +65,7 @@ obj-$(CONFIG_MMC_SDHCI_OF_ESDHC)	+= sdhc
- obj-$(CONFIG_MMC_SDHCI_OF_HLWD)		+= sdhci-of-hlwd.o
- obj-$(CONFIG_MMC_SDHCI_BCM_KONA)	+= sdhci-bcm-kona.o
- obj-$(CONFIG_MMC_SDHCI_BCM2835)		+= sdhci-bcm2835.o
-+obj-$(CONFIG_MMC_SDHCI_MSM)		+= sdhci-msm.o
- 
- ifeq ($(CONFIG_CB710_DEBUG),y)
- 	CFLAGS-cb710-mmc	+= -DDEBUG
---- /dev/null
-+++ b/drivers/mmc/host/sdhci-msm.c
-@@ -0,0 +1,208 @@
-+/*
-+ * drivers/mmc/host/sdhci-msm.c - Qualcomm SDHCI Platform driver
-+ *
-+ * Copyright (c) 2013-2014, The Linux Foundation. All rights reserved.
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 and
-+ * only version 2 as published by the Free Software Foundation.
-+ *
-+ * 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/of_device.h>
-+#include <linux/regulator/consumer.h>
-+#include <linux/delay.h>
-+
-+#include "sdhci-pltfm.h"
-+
-+#define CORE_HC_MODE		0x78
-+#define HC_MODE_EN		0x1
-+#define CORE_POWER		0x0
-+#define CORE_SW_RST		BIT(7)
-+
-+
-+struct sdhci_msm_host {
-+	struct platform_device *pdev;
-+	void __iomem *core_mem;	/* MSM SDCC mapped address */
-+	struct clk *clk;	/* main SD/MMC bus clock */
-+	struct clk *pclk;	/* SDHC peripheral bus clock */
-+	struct clk *bus_clk;	/* SDHC bus voter clock */
-+	struct mmc_host *mmc;
-+	struct sdhci_pltfm_data sdhci_msm_pdata;
-+};
-+
-+/* Platform specific tuning */
-+static int sdhci_msm_execute_tuning(struct sdhci_host *host, u32 opcode)
-+{
-+	/*
-+	 * Tuning is required for SDR104, HS200 and HS400 cards and if the clock
-+	 * frequency greater than 100MHz in those modes. The standard tuning
-+	 * procedure should not be executed, but a custom implementation will be
-+	 * added here instead.
-+	 */
-+	return 0;
-+}
-+
-+static const struct of_device_id sdhci_msm_dt_match[] = {
-+	{ .compatible = "qcom,sdhci-msm-v4" },
-+	{},
-+};
-+
-+MODULE_DEVICE_TABLE(of, sdhci_msm_dt_match);
-+
-+static struct sdhci_ops sdhci_msm_ops = {
-+	.platform_execute_tuning = sdhci_msm_execute_tuning,
-+};
-+
-+static int sdhci_msm_probe(struct platform_device *pdev)
-+{
-+	struct sdhci_host *host;
-+	struct sdhci_pltfm_host *pltfm_host;
-+	struct sdhci_msm_host *msm_host;
-+	struct resource *core_memres;
-+	int ret;
-+	u16 host_version;
-+
-+	msm_host = devm_kzalloc(&pdev->dev, sizeof(*msm_host), GFP_KERNEL);
-+	if (!msm_host)
-+		return -ENOMEM;
-+
-+	msm_host->sdhci_msm_pdata.ops = &sdhci_msm_ops;
-+	host = sdhci_pltfm_init(pdev, &msm_host->sdhci_msm_pdata, 0);
-+	if (IS_ERR(host))
-+		return PTR_ERR(host);
-+
-+	pltfm_host = sdhci_priv(host);
-+	pltfm_host->priv = msm_host;
-+	msm_host->mmc = host->mmc;
-+	msm_host->pdev = pdev;
-+
-+	ret = mmc_of_parse(host->mmc);
-+	if (ret)
-+		goto pltfm_free;
-+
-+	sdhci_get_of_property(pdev);
-+
-+	/* Setup SDCC bus voter clock. */
-+	msm_host->bus_clk = devm_clk_get(&pdev->dev, "bus");
-+	if (!IS_ERR(msm_host->bus_clk)) {
-+		/* Vote for max. clk rate for max. performance */
-+		ret = clk_set_rate(msm_host->bus_clk, INT_MAX);
-+		if (ret)
-+			goto pltfm_free;
-+		ret = clk_prepare_enable(msm_host->bus_clk);
-+		if (ret)
-+			goto pltfm_free;
-+	}
-+
-+	/* Setup main peripheral bus clock */
-+	msm_host->pclk = devm_clk_get(&pdev->dev, "iface");
-+	if (IS_ERR(msm_host->pclk)) {
-+		ret = PTR_ERR(msm_host->pclk);
-+		dev_err(&pdev->dev, "Perpheral clk setup failed (%d)\n", ret);
-+		goto bus_clk_disable;
-+	}
-+
-+	ret = clk_prepare_enable(msm_host->pclk);
-+	if (ret)
-+		goto bus_clk_disable;
-+
-+	/* Setup SDC MMC clock */
-+	msm_host->clk = devm_clk_get(&pdev->dev, "core");
-+	if (IS_ERR(msm_host->clk)) {
-+		ret = PTR_ERR(msm_host->clk);
-+		dev_err(&pdev->dev, "SDC MMC clk setup failed (%d)\n", ret);
-+		goto pclk_disable;
-+	}
-+
-+	ret = clk_prepare_enable(msm_host->clk);
-+	if (ret)
-+		goto pclk_disable;
-+
-+	core_memres = platform_get_resource(pdev, IORESOURCE_MEM, 1);
-+	msm_host->core_mem = devm_ioremap_resource(&pdev->dev, core_memres);
-+
-+	if (IS_ERR(msm_host->core_mem)) {
-+		dev_err(&pdev->dev, "Failed to remap registers\n");
-+		ret = PTR_ERR(msm_host->core_mem);
-+		goto clk_disable;
-+	}
-+
-+	/* Reset the core and Enable SDHC mode */
-+	writel_relaxed(readl_relaxed(msm_host->core_mem + CORE_POWER) |
-+		       CORE_SW_RST, msm_host->core_mem + CORE_POWER);
-+
-+	/* SW reset can take upto 10HCLK + 15MCLK cycles. (min 40us) */
-+	usleep_range(1000, 5000);
-+	if (readl(msm_host->core_mem + CORE_POWER) & CORE_SW_RST) {
-+		dev_err(&pdev->dev, "Stuck in reset\n");
-+		ret = -ETIMEDOUT;
-+		goto clk_disable;
-+	}
-+
-+	/* Set HC_MODE_EN bit in HC_MODE register */
-+	writel_relaxed(HC_MODE_EN, (msm_host->core_mem + CORE_HC_MODE));
-+
-+	host->quirks |= SDHCI_QUIRK_BROKEN_CARD_DETECTION;
-+	host->quirks |= SDHCI_QUIRK_SINGLE_POWER_WRITE;
-+
-+	host_version = readw_relaxed((host->ioaddr + SDHCI_HOST_VERSION));
-+	dev_dbg(&pdev->dev, "Host Version: 0x%x Vendor Version 0x%x\n",
-+		host_version, ((host_version & SDHCI_VENDOR_VER_MASK) >>
-+			       SDHCI_VENDOR_VER_SHIFT));
-+
-+	ret = sdhci_add_host(host);
-+	if (ret)
-+		goto clk_disable;
-+
-+	return 0;
-+
-+clk_disable:
-+	clk_disable_unprepare(msm_host->clk);
-+pclk_disable:
-+	clk_disable_unprepare(msm_host->pclk);
-+bus_clk_disable:
-+	if (!IS_ERR(msm_host->bus_clk))
-+		clk_disable_unprepare(msm_host->bus_clk);
-+pltfm_free:
-+	sdhci_pltfm_free(pdev);
-+	return ret;
-+}
-+
-+static int sdhci_msm_remove(struct platform_device *pdev)
-+{
-+	struct sdhci_host *host = platform_get_drvdata(pdev);
-+	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
-+	struct sdhci_msm_host *msm_host = pltfm_host->priv;
-+	int dead = (readl_relaxed(host->ioaddr + SDHCI_INT_STATUS) ==
-+		    0xffffffff);
-+
-+	sdhci_remove_host(host, dead);
-+	sdhci_pltfm_free(pdev);
-+	clk_disable_unprepare(msm_host->clk);
-+	clk_disable_unprepare(msm_host->pclk);
-+	if (!IS_ERR(msm_host->bus_clk))
-+		clk_disable_unprepare(msm_host->bus_clk);
-+	return 0;
-+}
-+
-+static struct platform_driver sdhci_msm_driver = {
-+	.probe = sdhci_msm_probe,
-+	.remove = sdhci_msm_remove,
-+	.driver = {
-+		   .name = "sdhci_msm",
-+		   .owner = THIS_MODULE,
-+		   .of_match_table = sdhci_msm_dt_match,
-+	},
-+};
-+
-+module_platform_driver(sdhci_msm_driver);
-+
-+MODULE_DESCRIPTION("Qualcomm Secure Digital Host Controller Interface driver");
-+MODULE_LICENSE("GPL v2");
diff --git a/target/linux/ipq806x/patches/0048-mmc-sdhci-msm-Add-platform_execute_tuning-implementa.patch b/target/linux/ipq806x/patches/0048-mmc-sdhci-msm-Add-platform_execute_tuning-implementa.patch
deleted file mode 100644
index e2c34bf..0000000
--- a/target/linux/ipq806x/patches/0048-mmc-sdhci-msm-Add-platform_execute_tuning-implementa.patch
+++ /dev/null
@@ -1,467 +0,0 @@
-From c2a237b3e467c8bb349c4624b71ec400abaf8ad1 Mon Sep 17 00:00:00 2001
-From: Georgi Djakov <gdjakov@mm-sol.com>
-Date: Mon, 10 Mar 2014 17:37:13 +0200
-Subject: [PATCH 048/182] mmc: sdhci-msm: Add platform_execute_tuning
- implementation
-
-This patch adds implementation for platform specific tuning in order
-to support HS200 bus speed mode on Qualcomm SDHCI controller.
-
-Signed-off-by: Asutosh Das <asutoshd@codeaurora.org>
-Signed-off-by: Venkat Gopalakrishnan <venkatg@codeaurora.org>
-Signed-off-by: Georgi Djakov <gdjakov@mm-sol.com>
-Acked-by: Ulf Hansson <ulf.hansson@linaro.org>
-Signed-off-by: Chris Ball <chris@printf.net>
----
- drivers/mmc/host/sdhci-msm.c |  420 +++++++++++++++++++++++++++++++++++++++++-
- 1 file changed, 415 insertions(+), 5 deletions(-)
-
---- a/drivers/mmc/host/sdhci-msm.c
-+++ b/drivers/mmc/host/sdhci-msm.c
-@@ -18,6 +18,8 @@
- #include <linux/of_device.h>
- #include <linux/regulator/consumer.h>
- #include <linux/delay.h>
-+#include <linux/mmc/mmc.h>
-+#include <linux/slab.h>
- 
- #include "sdhci-pltfm.h"
- 
-@@ -26,6 +28,42 @@
- #define CORE_POWER		0x0
- #define CORE_SW_RST		BIT(7)
- 
-+#define MAX_PHASES		16
-+#define CORE_DLL_LOCK		BIT(7)
-+#define CORE_DLL_EN		BIT(16)
-+#define CORE_CDR_EN		BIT(17)
-+#define CORE_CK_OUT_EN		BIT(18)
-+#define CORE_CDR_EXT_EN		BIT(19)
-+#define CORE_DLL_PDN		BIT(29)
-+#define CORE_DLL_RST		BIT(30)
-+#define CORE_DLL_CONFIG		0x100
-+#define CORE_DLL_STATUS		0x108
-+
-+#define CORE_VENDOR_SPEC	0x10c
-+#define CORE_CLK_PWRSAVE	BIT(1)
-+
-+#define CDR_SELEXT_SHIFT	20
-+#define CDR_SELEXT_MASK		(0xf << CDR_SELEXT_SHIFT)
-+#define CMUX_SHIFT_PHASE_SHIFT	24
-+#define CMUX_SHIFT_PHASE_MASK	(7 << CMUX_SHIFT_PHASE_SHIFT)
-+
-+static const u32 tuning_block_64[] = {
-+	0x00ff0fff, 0xccc3ccff, 0xffcc3cc3, 0xeffefffe,
-+	0xddffdfff, 0xfbfffbff, 0xff7fffbf, 0xefbdf777,
-+	0xf0fff0ff, 0x3cccfc0f, 0xcfcc33cc, 0xeeffefff,
-+	0xfdfffdff, 0xffbfffdf, 0xfff7ffbb, 0xde7b7ff7
-+};
-+
-+static const u32 tuning_block_128[] = {
-+	0xff00ffff, 0x0000ffff, 0xccccffff, 0xcccc33cc,
-+	0xcc3333cc, 0xffffcccc, 0xffffeeff, 0xffeeeeff,
-+	0xffddffff, 0xddddffff, 0xbbffffff, 0xbbffffff,
-+	0xffffffbb, 0xffffff77, 0x77ff7777, 0xffeeddbb,
-+	0x00ffffff, 0x00ffffff, 0xccffff00, 0xcc33cccc,
-+	0x3333cccc, 0xffcccccc, 0xffeeffff, 0xeeeeffff,
-+	0xddffffff, 0xddffffff, 0xffffffdd, 0xffffffbb,
-+	0xffffbbbb, 0xffff77ff, 0xff7777ff, 0xeeddbb77
-+};
- 
- struct sdhci_msm_host {
- 	struct platform_device *pdev;
-@@ -38,17 +76,389 @@ struct sdhci_msm_host {
- };
- 
- /* Platform specific tuning */
--static int sdhci_msm_execute_tuning(struct sdhci_host *host, u32 opcode)
-+static inline int msm_dll_poll_ck_out_en(struct sdhci_host *host, u8 poll)
-+{
-+	u32 wait_cnt = 50;
-+	u8 ck_out_en;
-+	struct mmc_host *mmc = host->mmc;
-+
-+	/* Poll for CK_OUT_EN bit.  max. poll time = 50us */
-+	ck_out_en = !!(readl_relaxed(host->ioaddr + CORE_DLL_CONFIG) &
-+			CORE_CK_OUT_EN);
-+
-+	while (ck_out_en != poll) {
-+		if (--wait_cnt == 0) {
-+			dev_err(mmc_dev(mmc), "%s: CK_OUT_EN bit is not %d\n",
-+			       mmc_hostname(mmc), poll);
-+			return -ETIMEDOUT;
-+		}
-+		udelay(1);
-+
-+		ck_out_en = !!(readl_relaxed(host->ioaddr + CORE_DLL_CONFIG) &
-+				CORE_CK_OUT_EN);
-+	}
-+
-+	return 0;
-+}
-+
-+static int msm_config_cm_dll_phase(struct sdhci_host *host, u8 phase)
-+{
-+	int rc;
-+	static const u8 grey_coded_phase_table[] = {
-+		0x0, 0x1, 0x3, 0x2, 0x6, 0x7, 0x5, 0x4,
-+		0xc, 0xd, 0xf, 0xe, 0xa, 0xb, 0x9, 0x8
-+	};
-+	unsigned long flags;
-+	u32 config;
-+	struct mmc_host *mmc = host->mmc;
-+
-+	spin_lock_irqsave(&host->lock, flags);
-+
-+	config = readl_relaxed(host->ioaddr + CORE_DLL_CONFIG);
-+	config &= ~(CORE_CDR_EN | CORE_CK_OUT_EN);
-+	config |= (CORE_CDR_EXT_EN | CORE_DLL_EN);
-+	writel_relaxed(config, host->ioaddr + CORE_DLL_CONFIG);
-+
-+	/* Wait until CK_OUT_EN bit of DLL_CONFIG register becomes '0' */
-+	rc = msm_dll_poll_ck_out_en(host, 0);
-+	if (rc)
-+		goto err_out;
-+
-+	/*
-+	 * Write the selected DLL clock output phase (0 ... 15)
-+	 * to CDR_SELEXT bit field of DLL_CONFIG register.
-+	 */
-+	config = readl_relaxed(host->ioaddr + CORE_DLL_CONFIG);
-+	config &= ~CDR_SELEXT_MASK;
-+	config |= grey_coded_phase_table[phase] << CDR_SELEXT_SHIFT;
-+	writel_relaxed(config, host->ioaddr + CORE_DLL_CONFIG);
-+
-+	/* Set CK_OUT_EN bit of DLL_CONFIG register to 1. */
-+	writel_relaxed((readl_relaxed(host->ioaddr + CORE_DLL_CONFIG)
-+			| CORE_CK_OUT_EN), host->ioaddr + CORE_DLL_CONFIG);
-+
-+	/* Wait until CK_OUT_EN bit of DLL_CONFIG register becomes '1' */
-+	rc = msm_dll_poll_ck_out_en(host, 1);
-+	if (rc)
-+		goto err_out;
-+
-+	config = readl_relaxed(host->ioaddr + CORE_DLL_CONFIG);
-+	config |= CORE_CDR_EN;
-+	config &= ~CORE_CDR_EXT_EN;
-+	writel_relaxed(config, host->ioaddr + CORE_DLL_CONFIG);
-+	goto out;
-+
-+err_out:
-+	dev_err(mmc_dev(mmc), "%s: Failed to set DLL phase: %d\n",
-+	       mmc_hostname(mmc), phase);
-+out:
-+	spin_unlock_irqrestore(&host->lock, flags);
-+	return rc;
-+}
-+
-+/*
-+ * Find out the greatest range of consecuitive selected
-+ * DLL clock output phases that can be used as sampling
-+ * setting for SD3.0 UHS-I card read operation (in SDR104
-+ * timing mode) or for eMMC4.5 card read operation (in HS200
-+ * timing mode).
-+ * Select the 3/4 of the range and configure the DLL with the
-+ * selected DLL clock output phase.
-+ */
-+
-+static int msm_find_most_appropriate_phase(struct sdhci_host *host,
-+					   u8 *phase_table, u8 total_phases)
-+{
-+	int ret;
-+	u8 ranges[MAX_PHASES][MAX_PHASES] = { {0}, {0} };
-+	u8 phases_per_row[MAX_PHASES] = { 0 };
-+	int row_index = 0, col_index = 0, selected_row_index = 0, curr_max = 0;
-+	int i, cnt, phase_0_raw_index = 0, phase_15_raw_index = 0;
-+	bool phase_0_found = false, phase_15_found = false;
-+	struct mmc_host *mmc = host->mmc;
-+
-+	if (!total_phases || (total_phases > MAX_PHASES)) {
-+		dev_err(mmc_dev(mmc), "%s: Invalid argument: total_phases=%d\n",
-+		       mmc_hostname(mmc), total_phases);
-+		return -EINVAL;
-+	}
-+
-+	for (cnt = 0; cnt < total_phases; cnt++) {
-+		ranges[row_index][col_index] = phase_table[cnt];
-+		phases_per_row[row_index] += 1;
-+		col_index++;
-+
-+		if ((cnt + 1) == total_phases) {
-+			continue;
-+		/* check if next phase in phase_table is consecutive or not */
-+		} else if ((phase_table[cnt] + 1) != phase_table[cnt + 1]) {
-+			row_index++;
-+			col_index = 0;
-+		}
-+	}
-+
-+	if (row_index >= MAX_PHASES)
-+		return -EINVAL;
-+
-+	/* Check if phase-0 is present in first valid window? */
-+	if (!ranges[0][0]) {
-+		phase_0_found = true;
-+		phase_0_raw_index = 0;
-+		/* Check if cycle exist between 2 valid windows */
-+		for (cnt = 1; cnt <= row_index; cnt++) {
-+			if (phases_per_row[cnt]) {
-+				for (i = 0; i < phases_per_row[cnt]; i++) {
-+					if (ranges[cnt][i] == 15) {
-+						phase_15_found = true;
-+						phase_15_raw_index = cnt;
-+						break;
-+					}
-+				}
-+			}
-+		}
-+	}
-+
-+	/* If 2 valid windows form cycle then merge them as single window */
-+	if (phase_0_found && phase_15_found) {
-+		/* number of phases in raw where phase 0 is present */
-+		u8 phases_0 = phases_per_row[phase_0_raw_index];
-+		/* number of phases in raw where phase 15 is present */
-+		u8 phases_15 = phases_per_row[phase_15_raw_index];
-+
-+		if (phases_0 + phases_15 >= MAX_PHASES)
-+			/*
-+			 * If there are more than 1 phase windows then total
-+			 * number of phases in both the windows should not be
-+			 * more than or equal to MAX_PHASES.
-+			 */
-+			return -EINVAL;
-+
-+		/* Merge 2 cyclic windows */
-+		i = phases_15;
-+		for (cnt = 0; cnt < phases_0; cnt++) {
-+			ranges[phase_15_raw_index][i] =
-+			    ranges[phase_0_raw_index][cnt];
-+			if (++i >= MAX_PHASES)
-+				break;
-+		}
-+
-+		phases_per_row[phase_0_raw_index] = 0;
-+		phases_per_row[phase_15_raw_index] = phases_15 + phases_0;
-+	}
-+
-+	for (cnt = 0; cnt <= row_index; cnt++) {
-+		if (phases_per_row[cnt] > curr_max) {
-+			curr_max = phases_per_row[cnt];
-+			selected_row_index = cnt;
-+		}
-+	}
-+
-+	i = (curr_max * 3) / 4;
-+	if (i)
-+		i--;
-+
-+	ret = ranges[selected_row_index][i];
-+
-+	if (ret >= MAX_PHASES) {
-+		ret = -EINVAL;
-+		dev_err(mmc_dev(mmc), "%s: Invalid phase selected=%d\n",
-+		       mmc_hostname(mmc), ret);
-+	}
-+
-+	return ret;
-+}
-+
-+static inline void msm_cm_dll_set_freq(struct sdhci_host *host)
-+{
-+	u32 mclk_freq = 0, config;
-+
-+	/* Program the MCLK value to MCLK_FREQ bit field */
-+	if (host->clock <= 112000000)
-+		mclk_freq = 0;
-+	else if (host->clock <= 125000000)
-+		mclk_freq = 1;
-+	else if (host->clock <= 137000000)
-+		mclk_freq = 2;
-+	else if (host->clock <= 150000000)
-+		mclk_freq = 3;
-+	else if (host->clock <= 162000000)
-+		mclk_freq = 4;
-+	else if (host->clock <= 175000000)
-+		mclk_freq = 5;
-+	else if (host->clock <= 187000000)
-+		mclk_freq = 6;
-+	else if (host->clock <= 200000000)
-+		mclk_freq = 7;
-+
-+	config = readl_relaxed(host->ioaddr + CORE_DLL_CONFIG);
-+	config &= ~CMUX_SHIFT_PHASE_MASK;
-+	config |= mclk_freq << CMUX_SHIFT_PHASE_SHIFT;
-+	writel_relaxed(config, host->ioaddr + CORE_DLL_CONFIG);
-+}
-+
-+/* Initialize the DLL (Programmable Delay Line) */
-+static int msm_init_cm_dll(struct sdhci_host *host)
- {
-+	struct mmc_host *mmc = host->mmc;
-+	int wait_cnt = 50;
-+	unsigned long flags;
-+
-+	spin_lock_irqsave(&host->lock, flags);
-+
- 	/*
--	 * Tuning is required for SDR104, HS200 and HS400 cards and if the clock
--	 * frequency greater than 100MHz in those modes. The standard tuning
--	 * procedure should not be executed, but a custom implementation will be
--	 * added here instead.
-+	 * Make sure that clock is always enabled when DLL
-+	 * tuning is in progress. Keeping PWRSAVE ON may
-+	 * turn off the clock.
- 	 */
-+	writel_relaxed((readl_relaxed(host->ioaddr + CORE_VENDOR_SPEC)
-+			& ~CORE_CLK_PWRSAVE), host->ioaddr + CORE_VENDOR_SPEC);
-+
-+	/* Write 1 to DLL_RST bit of DLL_CONFIG register */
-+	writel_relaxed((readl_relaxed(host->ioaddr + CORE_DLL_CONFIG)
-+			| CORE_DLL_RST), host->ioaddr + CORE_DLL_CONFIG);
-+
-+	/* Write 1 to DLL_PDN bit of DLL_CONFIG register */
-+	writel_relaxed((readl_relaxed(host->ioaddr + CORE_DLL_CONFIG)
-+			| CORE_DLL_PDN), host->ioaddr + CORE_DLL_CONFIG);
-+	msm_cm_dll_set_freq(host);
-+
-+	/* Write 0 to DLL_RST bit of DLL_CONFIG register */
-+	writel_relaxed((readl_relaxed(host->ioaddr + CORE_DLL_CONFIG)
-+			& ~CORE_DLL_RST), host->ioaddr + CORE_DLL_CONFIG);
-+
-+	/* Write 0 to DLL_PDN bit of DLL_CONFIG register */
-+	writel_relaxed((readl_relaxed(host->ioaddr + CORE_DLL_CONFIG)
-+			& ~CORE_DLL_PDN), host->ioaddr + CORE_DLL_CONFIG);
-+
-+	/* Set DLL_EN bit to 1. */
-+	writel_relaxed((readl_relaxed(host->ioaddr + CORE_DLL_CONFIG)
-+			| CORE_DLL_EN), host->ioaddr + CORE_DLL_CONFIG);
-+
-+	/* Set CK_OUT_EN bit to 1. */
-+	writel_relaxed((readl_relaxed(host->ioaddr + CORE_DLL_CONFIG)
-+			| CORE_CK_OUT_EN), host->ioaddr + CORE_DLL_CONFIG);
-+
-+	/* Wait until DLL_LOCK bit of DLL_STATUS register becomes '1' */
-+	while (!(readl_relaxed(host->ioaddr + CORE_DLL_STATUS) &
-+		 CORE_DLL_LOCK)) {
-+		/* max. wait for 50us sec for LOCK bit to be set */
-+		if (--wait_cnt == 0) {
-+			dev_err(mmc_dev(mmc), "%s: DLL failed to LOCK\n",
-+			       mmc_hostname(mmc));
-+			spin_unlock_irqrestore(&host->lock, flags);
-+			return -ETIMEDOUT;
-+		}
-+		udelay(1);
-+	}
-+
-+	spin_unlock_irqrestore(&host->lock, flags);
- 	return 0;
- }
- 
-+static int sdhci_msm_execute_tuning(struct sdhci_host *host, u32 opcode)
-+{
-+	int tuning_seq_cnt = 3;
-+	u8 phase, *data_buf, tuned_phases[16], tuned_phase_cnt = 0;
-+	const u32 *tuning_block_pattern = tuning_block_64;
-+	int size = sizeof(tuning_block_64);	/* Pattern size in bytes */
-+	int rc;
-+	struct mmc_host *mmc = host->mmc;
-+	struct mmc_ios ios = host->mmc->ios;
-+
-+	/*
-+	 * Tuning is required for SDR104, HS200 and HS400 cards and
-+	 * if clock frequency is greater than 100MHz in these modes.
-+	 */
-+	if (host->clock <= 100 * 1000 * 1000 ||
-+	    !((ios.timing == MMC_TIMING_MMC_HS200) ||
-+	      (ios.timing == MMC_TIMING_UHS_SDR104)))
-+		return 0;
-+
-+	if ((opcode == MMC_SEND_TUNING_BLOCK_HS200) &&
-+	    (mmc->ios.bus_width == MMC_BUS_WIDTH_8)) {
-+		tuning_block_pattern = tuning_block_128;
-+		size = sizeof(tuning_block_128);
-+	}
-+
-+	data_buf = kmalloc(size, GFP_KERNEL);
-+	if (!data_buf)
-+		return -ENOMEM;
-+
-+retry:
-+	/* First of all reset the tuning block */
-+	rc = msm_init_cm_dll(host);
-+	if (rc)
-+		goto out;
-+
-+	phase = 0;
-+	do {
-+		struct mmc_command cmd = { 0 };
-+		struct mmc_data data = { 0 };
-+		struct mmc_request mrq = {
-+			.cmd = &cmd,
-+			.data = &data
-+		};
-+		struct scatterlist sg;
-+
-+		/* Set the phase in delay line hw block */
-+		rc = msm_config_cm_dll_phase(host, phase);
-+		if (rc)
-+			goto out;
-+
-+		cmd.opcode = opcode;
-+		cmd.flags = MMC_RSP_R1 | MMC_CMD_ADTC;
-+
-+		data.blksz = size;
-+		data.blocks = 1;
-+		data.flags = MMC_DATA_READ;
-+		data.timeout_ns = NSEC_PER_SEC;	/* 1 second */
-+
-+		data.sg = &sg;
-+		data.sg_len = 1;
-+		sg_init_one(&sg, data_buf, size);
-+		memset(data_buf, 0, size);
-+		mmc_wait_for_req(mmc, &mrq);
-+
-+		if (!cmd.error && !data.error &&
-+		    !memcmp(data_buf, tuning_block_pattern, size)) {
-+			/* Tuning is successful at this tuning point */
-+			tuned_phases[tuned_phase_cnt++] = phase;
-+			dev_dbg(mmc_dev(mmc), "%s: Found good phase = %d\n",
-+				 mmc_hostname(mmc), phase);
-+		}
-+	} while (++phase < ARRAY_SIZE(tuned_phases));
-+
-+	if (tuned_phase_cnt) {
-+		rc = msm_find_most_appropriate_phase(host, tuned_phases,
-+						     tuned_phase_cnt);
-+		if (rc < 0)
-+			goto out;
-+		else
-+			phase = rc;
-+
-+		/*
-+		 * Finally set the selected phase in delay
-+		 * line hw block.
-+		 */
-+		rc = msm_config_cm_dll_phase(host, phase);
-+		if (rc)
-+			goto out;
-+		dev_dbg(mmc_dev(mmc), "%s: Setting the tuning phase to %d\n",
-+			 mmc_hostname(mmc), phase);
-+	} else {
-+		if (--tuning_seq_cnt)
-+			goto retry;
-+		/* Tuning failed */
-+		dev_dbg(mmc_dev(mmc), "%s: No tuning point found\n",
-+		       mmc_hostname(mmc));
-+		rc = -EIO;
-+	}
-+
-+out:
-+	kfree(data_buf);
-+	return rc;
-+}
-+
- static const struct of_device_id sdhci_msm_dt_match[] = {
- 	{ .compatible = "qcom,sdhci-msm-v4" },
- 	{},
diff --git a/target/linux/ipq806x/patches/0049-drivers-of-add-initialization-code-for-static-reserv.patch b/target/linux/ipq806x/patches/0049-drivers-of-add-initialization-code-for-static-reserv.patch
deleted file mode 100644
index 1e304dd..0000000
--- a/target/linux/ipq806x/patches/0049-drivers-of-add-initialization-code-for-static-reserv.patch
+++ /dev/null
@@ -1,209 +0,0 @@
-From 60ee5b21ce14a7d5c269115b0751b904d0e005ed Mon Sep 17 00:00:00 2001
-From: Marek Szyprowski <m.szyprowski@samsung.com>
-Date: Fri, 28 Feb 2014 14:42:47 +0100
-Subject: [PATCH 049/182] drivers: of: add initialization code for static
- reserved memory
-
-This patch adds support for static (defined by 'reg' property) reserved
-memory regions declared in device tree.
-
-Memory blocks can be reliably reserved only during early boot. This must
-happen before the whole memory management subsystem is initialized,
-because we need to ensure that the given contiguous blocks are not yet
-allocated by kernel. Also it must happen before kernel mappings for the
-whole low memory are created, to ensure that there will be no mappings
-(for reserved blocks). Typically, all this happens before device tree
-structures are unflattened, so we need to get reserved memory layout
-directly from fdt.
-
-Based on previous code provided by Josh Cartwright <joshc@codeaurora.org>
-
-Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
-Signed-off-by: Grant Likely <grant.likely@linaro.org>
----
- drivers/of/fdt.c       |  131 ++++++++++++++++++++++++++++++++++++++++++++++++
- include/linux/of_fdt.h |    4 ++
- 2 files changed, 135 insertions(+)
-
---- a/drivers/of/fdt.c
-+++ b/drivers/of/fdt.c
-@@ -15,6 +15,7 @@
- #include <linux/module.h>
- #include <linux/of.h>
- #include <linux/of_fdt.h>
-+#include <linux/sizes.h>
- #include <linux/string.h>
- #include <linux/errno.h>
- #include <linux/slab.h>
-@@ -440,6 +441,118 @@ struct boot_param_header *initial_boot_p
- #ifdef CONFIG_OF_EARLY_FLATTREE
- 
- /**
-+ * res_mem_reserve_reg() - reserve all memory described in 'reg' property
-+ */
-+static int __init __reserved_mem_reserve_reg(unsigned long node,
-+					     const char *uname)
-+{
-+	int t_len = (dt_root_addr_cells + dt_root_size_cells) * sizeof(__be32);
-+	phys_addr_t base, size;
-+	unsigned long len;
-+	__be32 *prop;
-+	int nomap;
-+
-+	prop = of_get_flat_dt_prop(node, "reg", &len);
-+	if (!prop)
-+		return -ENOENT;
-+
-+	if (len && len % t_len != 0) {
-+		pr_err("Reserved memory: invalid reg property in '%s', skipping node.\n",
-+		       uname);
-+		return -EINVAL;
-+	}
-+
-+	nomap = of_get_flat_dt_prop(node, "no-map", NULL) != NULL;
-+
-+	while (len >= t_len) {
-+		base = dt_mem_next_cell(dt_root_addr_cells, &prop);
-+		size = dt_mem_next_cell(dt_root_size_cells, &prop);
-+
-+		if (base && size &&
-+		    early_init_dt_reserve_memory_arch(base, size, nomap) == 0)
-+			pr_debug("Reserved memory: reserved region for node '%s': base %pa, size %ld MiB\n",
-+				uname, &base, (unsigned long)size / SZ_1M);
-+		else
-+			pr_info("Reserved memory: failed to reserve memory for node '%s': base %pa, size %ld MiB\n",
-+				uname, &base, (unsigned long)size / SZ_1M);
-+
-+		len -= t_len;
-+	}
-+	return 0;
-+}
-+
-+/**
-+ * __reserved_mem_check_root() - check if #size-cells, #address-cells provided
-+ * in /reserved-memory matches the values supported by the current implementation,
-+ * also check if ranges property has been provided
-+ */
-+static int __reserved_mem_check_root(unsigned long node)
-+{
-+	__be32 *prop;
-+
-+	prop = of_get_flat_dt_prop(node, "#size-cells", NULL);
-+	if (!prop || be32_to_cpup(prop) != dt_root_size_cells)
-+		return -EINVAL;
-+
-+	prop = of_get_flat_dt_prop(node, "#address-cells", NULL);
-+	if (!prop || be32_to_cpup(prop) != dt_root_addr_cells)
-+		return -EINVAL;
-+
-+	prop = of_get_flat_dt_prop(node, "ranges", NULL);
-+	if (!prop)
-+		return -EINVAL;
-+	return 0;
-+}
-+
-+/**
-+ * fdt_scan_reserved_mem() - scan a single FDT node for reserved memory
-+ */
-+static int __init __fdt_scan_reserved_mem(unsigned long node, const char *uname,
-+					  int depth, void *data)
-+{
-+	static int found;
-+	const char *status;
-+
-+	if (!found && depth == 1 && strcmp(uname, "reserved-memory") == 0) {
-+		if (__reserved_mem_check_root(node) != 0) {
-+			pr_err("Reserved memory: unsupported node format, ignoring\n");
-+			/* break scan */
-+			return 1;
-+		}
-+		found = 1;
-+		/* scan next node */
-+		return 0;
-+	} else if (!found) {
-+		/* scan next node */
-+		return 0;
-+	} else if (found && depth < 2) {
-+		/* scanning of /reserved-memory has been finished */
-+		return 1;
-+	}
-+
-+	status = of_get_flat_dt_prop(node, "status", NULL);
-+	if (status && strcmp(status, "okay") != 0 && strcmp(status, "ok") != 0)
-+		return 0;
-+
-+	__reserved_mem_reserve_reg(node, uname);
-+
-+	/* scan next node */
-+	return 0;
-+}
-+
-+/**
-+ * early_init_fdt_scan_reserved_mem() - create reserved memory regions
-+ *
-+ * This function grabs memory from early allocator for device exclusive use
-+ * defined in device tree structures. It should be called by arch specific code
-+ * once the early allocator (i.e. memblock) has been fully activated.
-+ */
-+void __init early_init_fdt_scan_reserved_mem(void)
-+{
-+	of_scan_flat_dt(__fdt_scan_reserved_mem, NULL);
-+}
-+
-+/**
-  * of_scan_flat_dt - scan flattened tree blob and call callback on each.
-  * @it: callback function
-  * @data: context data pointer
-@@ -859,6 +972,16 @@ void __init __weak early_init_dt_add_mem
- 	memblock_add(base, size);
- }
- 
-+int __init __weak early_init_dt_reserve_memory_arch(phys_addr_t base,
-+					phys_addr_t size, bool nomap)
-+{
-+	if (memblock_is_region_reserved(base, size))
-+		return -EBUSY;
-+	if (nomap)
-+		return memblock_remove(base, size);
-+	return memblock_reserve(base, size);
-+}
-+
- /*
-  * called from unflatten_device_tree() to bootstrap devicetree itself
-  * Architectures can override this definition if memblock isn't used
-@@ -867,6 +990,14 @@ void * __init __weak early_init_dt_alloc
- {
- 	return __va(memblock_alloc(size, align));
- }
-+#else
-+int __init __weak early_init_dt_reserve_memory_arch(phys_addr_t base,
-+					phys_addr_t size, bool nomap)
-+{
-+	pr_err("Reserved memory not supported, ignoring range 0x%llx - 0x%llx%s\n",
-+		  base, size, nomap ? " (nomap)" : "");
-+	return -ENOSYS;
-+}
- #endif
- 
- bool __init early_init_dt_scan(void *params)
---- a/include/linux/of_fdt.h
-+++ b/include/linux/of_fdt.h
-@@ -98,7 +98,10 @@ extern int early_init_dt_scan_chosen(uns
- 				     int depth, void *data);
- extern int early_init_dt_scan_memory(unsigned long node, const char *uname,
- 				     int depth, void *data);
-+extern void early_init_fdt_scan_reserved_mem(void);
- extern void early_init_dt_add_memory_arch(u64 base, u64 size);
-+extern int early_init_dt_reserve_memory_arch(phys_addr_t base, phys_addr_t size,
-+					     bool no_map);
- extern void * early_init_dt_alloc_memory_arch(u64 size, u64 align);
- extern u64 dt_mem_next_cell(int s, __be32 **cellp);
- 
-@@ -118,6 +121,7 @@ extern void unflatten_and_copy_device_tr
- extern void early_init_devtree(void *);
- extern void early_get_first_memblock_info(void *, phys_addr_t *);
- #else /* CONFIG_OF_FLATTREE */
-+static inline void early_init_fdt_scan_reserved_mem(void) {}
- static inline const char *of_flat_dt_get_machine_name(void) { return NULL; }
- static inline void unflatten_device_tree(void) {}
- static inline void unflatten_and_copy_device_tree(void) {}
diff --git a/target/linux/ipq806x/patches/0050-drivers-of-add-initialization-code-for-dynamic-reser.patch b/target/linux/ipq806x/patches/0050-drivers-of-add-initialization-code-for-dynamic-reser.patch
deleted file mode 100644
index 4b633b5..0000000
--- a/target/linux/ipq806x/patches/0050-drivers-of-add-initialization-code-for-dynamic-reser.patch
+++ /dev/null
@@ -1,316 +0,0 @@
-From 968b497e1027ec78e986370976c76e1652aa0459 Mon Sep 17 00:00:00 2001
-From: Marek Szyprowski <m.szyprowski@samsung.com>
-Date: Fri, 28 Feb 2014 14:42:48 +0100
-Subject: [PATCH 050/182] drivers: of: add initialization code for dynamic
- reserved memory
-
-This patch adds support for dynamically allocated reserved memory regions
-declared in device tree. Such regions are defined by 'size', 'alignment'
-and 'alloc-ranges' properties.
-
-Based on previous code provided by Josh Cartwright <joshc@codeaurora.org>
-
-Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
-Signed-off-by: Grant Likely <grant.likely@linaro.org>
----
- drivers/of/Kconfig              |    6 ++
- drivers/of/Makefile             |    1 +
- drivers/of/fdt.c                |   13 ++-
- drivers/of/of_reserved_mem.c    |  188 +++++++++++++++++++++++++++++++++++++++
- include/linux/of_reserved_mem.h |   21 +++++
- 5 files changed, 227 insertions(+), 2 deletions(-)
- create mode 100644 drivers/of/of_reserved_mem.c
- create mode 100644 include/linux/of_reserved_mem.h
-
---- a/drivers/of/Kconfig
-+++ b/drivers/of/Kconfig
-@@ -75,4 +75,10 @@ config OF_MTD
- 	depends on MTD
- 	def_bool y
- 
-+config OF_RESERVED_MEM
-+	depends on OF_EARLY_FLATTREE
-+	bool
-+	help
-+	  Helpers to allow for reservation of memory regions
-+
- endmenu # OF
---- a/drivers/of/Makefile
-+++ b/drivers/of/Makefile
-@@ -9,3 +9,4 @@ obj-$(CONFIG_OF_MDIO)	+= of_mdio.o
- obj-$(CONFIG_OF_PCI)	+= of_pci.o
- obj-$(CONFIG_OF_PCI_IRQ)  += of_pci_irq.o
- obj-$(CONFIG_OF_MTD)	+= of_mtd.o
-+obj-$(CONFIG_OF_RESERVED_MEM) += of_reserved_mem.o
---- a/drivers/of/fdt.c
-+++ b/drivers/of/fdt.c
-@@ -15,6 +15,7 @@
- #include <linux/module.h>
- #include <linux/of.h>
- #include <linux/of_fdt.h>
-+#include <linux/of_reserved_mem.h>
- #include <linux/sizes.h>
- #include <linux/string.h>
- #include <linux/errno.h>
-@@ -450,7 +451,7 @@ static int __init __reserved_mem_reserve
- 	phys_addr_t base, size;
- 	unsigned long len;
- 	__be32 *prop;
--	int nomap;
-+	int nomap, first = 1;
- 
- 	prop = of_get_flat_dt_prop(node, "reg", &len);
- 	if (!prop)
-@@ -477,6 +478,10 @@ static int __init __reserved_mem_reserve
- 				uname, &base, (unsigned long)size / SZ_1M);
- 
- 		len -= t_len;
-+		if (first) {
-+			fdt_reserved_mem_save_node(node, uname, base, size);
-+			first = 0;
-+		}
- 	}
- 	return 0;
- }
-@@ -512,6 +517,7 @@ static int __init __fdt_scan_reserved_me
- {
- 	static int found;
- 	const char *status;
-+	int err;
- 
- 	if (!found && depth == 1 && strcmp(uname, "reserved-memory") == 0) {
- 		if (__reserved_mem_check_root(node) != 0) {
-@@ -534,7 +540,9 @@ static int __init __fdt_scan_reserved_me
- 	if (status && strcmp(status, "okay") != 0 && strcmp(status, "ok") != 0)
- 		return 0;
- 
--	__reserved_mem_reserve_reg(node, uname);
-+	err = __reserved_mem_reserve_reg(node, uname);
-+	if (err == -ENOENT && of_get_flat_dt_prop(node, "size", NULL))
-+		fdt_reserved_mem_save_node(node, uname, 0, 0);
- 
- 	/* scan next node */
- 	return 0;
-@@ -550,6 +558,7 @@ static int __init __fdt_scan_reserved_me
- void __init early_init_fdt_scan_reserved_mem(void)
- {
- 	of_scan_flat_dt(__fdt_scan_reserved_mem, NULL);
-+	fdt_init_reserved_mem();
- }
- 
- /**
---- /dev/null
-+++ b/drivers/of/of_reserved_mem.c
-@@ -0,0 +1,188 @@
-+/*
-+ * Device tree based initialization code for reserved memory.
-+ *
-+ * Copyright (c) 2013, The Linux Foundation. All Rights Reserved.
-+ * Copyright (c) 2013,2014 Samsung Electronics Co., Ltd.
-+ *		http://www.samsung.com
-+ * Author: Marek Szyprowski <m.szyprowski@samsung.com>
-+ * Author: Josh Cartwright <joshc@codeaurora.org>
-+ *
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU General Public License as
-+ * published by the Free Software Foundation; either version 2 of the
-+ * License or (at your optional) any later version of the license.
-+ */
-+
-+#include <linux/err.h>
-+#include <linux/of.h>
-+#include <linux/of_fdt.h>
-+#include <linux/of_platform.h>
-+#include <linux/mm.h>
-+#include <linux/sizes.h>
-+#include <linux/of_reserved_mem.h>
-+
-+#define MAX_RESERVED_REGIONS	16
-+static struct reserved_mem reserved_mem[MAX_RESERVED_REGIONS];
-+static int reserved_mem_count;
-+
-+#if defined(CONFIG_HAVE_MEMBLOCK)
-+#include <linux/memblock.h>
-+int __init __weak early_init_dt_alloc_reserved_memory_arch(phys_addr_t size,
-+	phys_addr_t align, phys_addr_t start, phys_addr_t end, bool nomap,
-+	phys_addr_t *res_base)
-+{
-+	/*
-+	 * We use __memblock_alloc_base() because memblock_alloc_base()
-+	 * panic()s on allocation failure.
-+	 */
-+	phys_addr_t base = __memblock_alloc_base(size, align, end);
-+	if (!base)
-+		return -ENOMEM;
-+
-+	/*
-+	 * Check if the allocated region fits in to start..end window
-+	 */
-+	if (base < start) {
-+		memblock_free(base, size);
-+		return -ENOMEM;
-+	}
-+
-+	*res_base = base;
-+	if (nomap)
-+		return memblock_remove(base, size);
-+	return 0;
-+}
-+#else
-+int __init __weak early_init_dt_alloc_reserved_memory_arch(phys_addr_t size,
-+	phys_addr_t align, phys_addr_t start, phys_addr_t end, bool nomap,
-+	phys_addr_t *res_base)
-+{
-+	pr_err("Reserved memory not supported, ignoring region 0x%llx%s\n",
-+		  size, nomap ? " (nomap)" : "");
-+	return -ENOSYS;
-+}
-+#endif
-+
-+/**
-+ * res_mem_save_node() - save fdt node for second pass initialization
-+ */
-+void __init fdt_reserved_mem_save_node(unsigned long node, const char *uname,
-+				      phys_addr_t base, phys_addr_t size)
-+{
-+	struct reserved_mem *rmem = &reserved_mem[reserved_mem_count];
-+
-+	if (reserved_mem_count == ARRAY_SIZE(reserved_mem)) {
-+		pr_err("Reserved memory: not enough space all defined regions.\n");
-+		return;
-+	}
-+
-+	rmem->fdt_node = node;
-+	rmem->name = uname;
-+	rmem->base = base;
-+	rmem->size = size;
-+
-+	reserved_mem_count++;
-+	return;
-+}
-+
-+/**
-+ * res_mem_alloc_size() - allocate reserved memory described by 'size', 'align'
-+ *			  and 'alloc-ranges' properties
-+ */
-+static int __init __reserved_mem_alloc_size(unsigned long node,
-+	const char *uname, phys_addr_t *res_base, phys_addr_t *res_size)
-+{
-+	int t_len = (dt_root_addr_cells + dt_root_size_cells) * sizeof(__be32);
-+	phys_addr_t start = 0, end = 0;
-+	phys_addr_t base = 0, align = 0, size;
-+	unsigned long len;
-+	__be32 *prop;
-+	int nomap;
-+	int ret;
-+
-+	prop = of_get_flat_dt_prop(node, "size", &len);
-+	if (!prop)
-+		return -EINVAL;
-+
-+	if (len != dt_root_size_cells * sizeof(__be32)) {
-+		pr_err("Reserved memory: invalid size property in '%s' node.\n",
-+				uname);
-+		return -EINVAL;
-+	}
-+	size = dt_mem_next_cell(dt_root_size_cells, &prop);
-+
-+	nomap = of_get_flat_dt_prop(node, "no-map", NULL) != NULL;
-+
-+	prop = of_get_flat_dt_prop(node, "alignment", &len);
-+	if (prop) {
-+		if (len != dt_root_addr_cells * sizeof(__be32)) {
-+			pr_err("Reserved memory: invalid alignment property in '%s' node.\n",
-+				uname);
-+			return -EINVAL;
-+		}
-+		align = dt_mem_next_cell(dt_root_addr_cells, &prop);
-+	}
-+
-+	prop = of_get_flat_dt_prop(node, "alloc-ranges", &len);
-+	if (prop) {
-+
-+		if (len % t_len != 0) {
-+			pr_err("Reserved memory: invalid alloc-ranges property in '%s', skipping node.\n",
-+			       uname);
-+			return -EINVAL;
-+		}
-+
-+		base = 0;
-+
-+		while (len > 0) {
-+			start = dt_mem_next_cell(dt_root_addr_cells, &prop);
-+			end = start + dt_mem_next_cell(dt_root_size_cells,
-+						       &prop);
-+
-+			ret = early_init_dt_alloc_reserved_memory_arch(size,
-+					align, start, end, nomap, &base);
-+			if (ret == 0) {
-+				pr_debug("Reserved memory: allocated memory for '%s' node: base %pa, size %ld MiB\n",
-+					uname, &base,
-+					(unsigned long)size / SZ_1M);
-+				break;
-+			}
-+			len -= t_len;
-+		}
-+
-+	} else {
-+		ret = early_init_dt_alloc_reserved_memory_arch(size, align,
-+							0, 0, nomap, &base);
-+		if (ret == 0)
-+			pr_debug("Reserved memory: allocated memory for '%s' node: base %pa, size %ld MiB\n",
-+				uname, &base, (unsigned long)size / SZ_1M);
-+	}
-+
-+	if (base == 0) {
-+		pr_info("Reserved memory: failed to allocate memory for node '%s'\n",
-+			uname);
-+		return -ENOMEM;
-+	}
-+
-+	*res_base = base;
-+	*res_size = size;
-+
-+	return 0;
-+}
-+
-+/**
-+ * fdt_init_reserved_mem - allocate and init all saved reserved memory regions
-+ */
-+void __init fdt_init_reserved_mem(void)
-+{
-+	int i;
-+	for (i = 0; i < reserved_mem_count; i++) {
-+		struct reserved_mem *rmem = &reserved_mem[i];
-+		unsigned long node = rmem->fdt_node;
-+		int err = 0;
-+
-+		if (rmem->size == 0)
-+			err = __reserved_mem_alloc_size(node, rmem->name,
-+						 &rmem->base, &rmem->size);
-+	}
-+}
---- /dev/null
-+++ b/include/linux/of_reserved_mem.h
-@@ -0,0 +1,21 @@
-+#ifndef __OF_RESERVED_MEM_H
-+#define __OF_RESERVED_MEM_H
-+
-+struct reserved_mem {
-+	const char			*name;
-+	unsigned long			fdt_node;
-+	phys_addr_t			base;
-+	phys_addr_t			size;
-+};
-+
-+#ifdef CONFIG_OF_RESERVED_MEM
-+void fdt_init_reserved_mem(void);
-+void fdt_reserved_mem_save_node(unsigned long node, const char *uname,
-+			       phys_addr_t base, phys_addr_t size);
-+#else
-+static inline void fdt_init_reserved_mem(void) { }
-+static inline void fdt_reserved_mem_save_node(unsigned long node,
-+		const char *uname, phys_addr_t base, phys_addr_t size) { }
-+#endif
-+
-+#endif /* __OF_RESERVED_MEM_H */
diff --git a/target/linux/ipq806x/patches/0051-drivers-of-add-support-for-custom-reserved-memory-dr.patch b/target/linux/ipq806x/patches/0051-drivers-of-add-support-for-custom-reserved-memory-dr.patch
deleted file mode 100644
index 48ad8ac..0000000
--- a/target/linux/ipq806x/patches/0051-drivers-of-add-support-for-custom-reserved-memory-dr.patch
+++ /dev/null
@@ -1,147 +0,0 @@
-From fc9e25ed9db2fcfbf16a9cbbf5a1f449da78f1d9 Mon Sep 17 00:00:00 2001
-From: Marek Szyprowski <m.szyprowski@samsung.com>
-Date: Fri, 28 Feb 2014 14:42:49 +0100
-Subject: [PATCH 051/182] drivers: of: add support for custom reserved memory
- drivers
-
-Add support for custom reserved memory drivers. Call their init() function
-for each reserved region and prepare for using operations provided by them
-with by the reserved_mem->ops array.
-
-Based on previous code provided by Josh Cartwright <joshc@codeaurora.org>
-
-Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
-Signed-off-by: Grant Likely <grant.likely@linaro.org>
----
- drivers/of/of_reserved_mem.c      |   29 +++++++++++++++++++++++++++++
- include/asm-generic/vmlinux.lds.h |   11 +++++++++++
- include/linux/of_reserved_mem.h   |   32 ++++++++++++++++++++++++++++++++
- 3 files changed, 72 insertions(+)
-
---- a/drivers/of/of_reserved_mem.c
-+++ b/drivers/of/of_reserved_mem.c
-@@ -170,6 +170,33 @@ static int __init __reserved_mem_alloc_s
- 	return 0;
- }
- 
-+static const struct of_device_id __rmem_of_table_sentinel
-+	__used __section(__reservedmem_of_table_end);
-+
-+/**
-+ * res_mem_init_node() - call region specific reserved memory init code
-+ */
-+static int __init __reserved_mem_init_node(struct reserved_mem *rmem)
-+{
-+	extern const struct of_device_id __reservedmem_of_table[];
-+	const struct of_device_id *i;
-+
-+	for (i = __reservedmem_of_table; i < &__rmem_of_table_sentinel; i++) {
-+		reservedmem_of_init_fn initfn = i->data;
-+		const char *compat = i->compatible;
-+
-+		if (!of_flat_dt_is_compatible(rmem->fdt_node, compat))
-+			continue;
-+
-+		if (initfn(rmem, rmem->fdt_node, rmem->name) == 0) {
-+			pr_info("Reserved memory: initialized node %s, compatible id %s\n",
-+				rmem->name, compat);
-+			return 0;
-+		}
-+	}
-+	return -ENOENT;
-+}
-+
- /**
-  * fdt_init_reserved_mem - allocate and init all saved reserved memory regions
-  */
-@@ -184,5 +211,7 @@ void __init fdt_init_reserved_mem(void)
- 		if (rmem->size == 0)
- 			err = __reserved_mem_alloc_size(node, rmem->name,
- 						 &rmem->base, &rmem->size);
-+		if (err == 0)
-+			__reserved_mem_init_node(rmem);
- 	}
- }
---- a/include/asm-generic/vmlinux.lds.h
-+++ b/include/asm-generic/vmlinux.lds.h
-@@ -177,6 +177,16 @@
- #define CLK_OF_TABLES()
- #endif
- 
-+#ifdef CONFIG_OF_RESERVED_MEM
-+#define RESERVEDMEM_OF_TABLES()				\
-+	. = ALIGN(8);					\
-+	VMLINUX_SYMBOL(__reservedmem_of_table) = .;	\
-+	*(__reservedmem_of_table)			\
-+	*(__reservedmem_of_table_end)
-+#else
-+#define RESERVEDMEM_OF_TABLES()
-+#endif
-+
- #ifdef CONFIG_SMP
- #define CPU_METHOD_OF_TABLES() . = ALIGN(8);				    \
- 			   VMLINUX_SYMBOL(__cpu_method_of_table_begin) = .; \
-@@ -510,6 +520,7 @@
- 	TRACE_SYSCALLS()						\
- 	MEM_DISCARD(init.rodata)					\
- 	CLK_OF_TABLES()							\
-+	RESERVEDMEM_OF_TABLES()						\
- 	CLKSRC_OF_TABLES()						\
- 	CPU_METHOD_OF_TABLES()						\
- 	KERNEL_DTB()							\
---- a/include/linux/of_reserved_mem.h
-+++ b/include/linux/of_reserved_mem.h
-@@ -1,21 +1,53 @@
- #ifndef __OF_RESERVED_MEM_H
- #define __OF_RESERVED_MEM_H
- 
-+struct device;
-+struct of_phandle_args;
-+struct reserved_mem_ops;
-+
- struct reserved_mem {
- 	const char			*name;
- 	unsigned long			fdt_node;
-+	const struct reserved_mem_ops	*ops;
- 	phys_addr_t			base;
- 	phys_addr_t			size;
-+	void				*priv;
-+};
-+
-+struct reserved_mem_ops {
-+	void	(*device_init)(struct reserved_mem *rmem,
-+			       struct device *dev);
-+	void	(*device_release)(struct reserved_mem *rmem,
-+				  struct device *dev);
- };
- 
-+typedef int (*reservedmem_of_init_fn)(struct reserved_mem *rmem,
-+				      unsigned long node, const char *uname);
-+
- #ifdef CONFIG_OF_RESERVED_MEM
- void fdt_init_reserved_mem(void);
- void fdt_reserved_mem_save_node(unsigned long node, const char *uname,
- 			       phys_addr_t base, phys_addr_t size);
-+
-+#define RESERVEDMEM_OF_DECLARE(name, compat, init)			\
-+	static const struct of_device_id __reservedmem_of_table_##name	\
-+		__used __section(__reservedmem_of_table)		\
-+		 = { .compatible = compat,				\
-+		     .data = (init == (reservedmem_of_init_fn)NULL) ?	\
-+				init : init }
-+
- #else
- static inline void fdt_init_reserved_mem(void) { }
- static inline void fdt_reserved_mem_save_node(unsigned long node,
- 		const char *uname, phys_addr_t base, phys_addr_t size) { }
-+
-+#define RESERVEDMEM_OF_DECLARE(name, compat, init)			\
-+	static const struct of_device_id __reservedmem_of_table_##name	\
-+		__attribute__((unused))					\
-+		 = { .compatible = compat,				\
-+		     .data = (init == (reservedmem_of_init_fn)NULL) ?	\
-+				init : init }
-+
- #endif
- 
- #endif /* __OF_RESERVED_MEM_H */
diff --git a/target/linux/ipq806x/patches/0052-arm-add-support-for-reserved-memory-defined-by-devic.patch b/target/linux/ipq806x/patches/0052-arm-add-support-for-reserved-memory-defined-by-devic.patch
deleted file mode 100644
index 7e90e2d..0000000
--- a/target/linux/ipq806x/patches/0052-arm-add-support-for-reserved-memory-defined-by-devic.patch
+++ /dev/null
@@ -1,36 +0,0 @@
-From 95c831bca9181df62230171fd66286d08ea886a8 Mon Sep 17 00:00:00 2001
-From: Marek Szyprowski <m.szyprowski@samsung.com>
-Date: Fri, 28 Feb 2014 14:42:54 +0100
-Subject: [PATCH 052/182] arm: add support for reserved memory defined by
- device tree
-
-Enable reserved memory initialization from device tree.
-
-Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
-Signed-off-by: Grant Likely <grant.likely@linaro.org>
----
- arch/arm/Kconfig   |    1 +
- arch/arm/mm/init.c |    2 ++
- 2 files changed, 3 insertions(+)
-
---- a/arch/arm/Kconfig
-+++ b/arch/arm/Kconfig
-@@ -1923,6 +1923,7 @@ config USE_OF
- 	select IRQ_DOMAIN
- 	select OF
- 	select OF_EARLY_FLATTREE
-+	select OF_RESERVED_MEM
- 	help
- 	  Include support for flattened device tree machine descriptions.
- 
---- a/arch/arm/mm/init.c
-+++ b/arch/arm/mm/init.c
-@@ -323,6 +323,8 @@ void __init arm_memblock_init(struct mem
- 	if (mdesc->reserve)
- 		mdesc->reserve();
- 
-+	early_init_fdt_scan_reserved_mem();
-+
- 	/*
- 	 * reserve memory for DMA contigouos allocations,
- 	 * must come from DMA area inside low memory
diff --git a/target/linux/ipq806x/patches/0053-of-document-bindings-for-reserved-memory-nodes.patch b/target/linux/ipq806x/patches/0053-of-document-bindings-for-reserved-memory-nodes.patch
deleted file mode 100644
index 5363b70..0000000
--- a/target/linux/ipq806x/patches/0053-of-document-bindings-for-reserved-memory-nodes.patch
+++ /dev/null
@@ -1,158 +0,0 @@
-From 060a8e3db75ef98fb296b03b8fb0cdfcbcc76c6e Mon Sep 17 00:00:00 2001
-From: Grant Likely <grant.likely@linaro.org>
-Date: Fri, 28 Feb 2014 14:42:46 +0100
-Subject: [PATCH 053/182] of: document bindings for reserved-memory nodes
-
-Reserved memory nodes allow for the reservation of static (fixed
-address) regions, or dynamically allocated regions for a specific
-purpose.
-
-[joshc: Based on binding document proposed (in non-patch form) here:
- http://lkml.kernel.org/g/20131030134702.19B57C402A0@trevor.secretlab.ca
- adapted to support #memory-region-cells]
-Signed-off-by: Josh Cartwright <joshc@codeaurora.org>
-[mszyprow: removed #memory-region-cells property]
-Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
-[grant.likely: removed residual #memory-region-cells example]
-Signed-off-by: Grant Likely <grant.likely@linaro.org>
----
- .../bindings/reserved-memory/reserved-memory.txt   |  133 ++++++++++++++++++++
- 1 file changed, 133 insertions(+)
- create mode 100644 Documentation/devicetree/bindings/reserved-memory/reserved-memory.txt
-
---- /dev/null
-+++ b/Documentation/devicetree/bindings/reserved-memory/reserved-memory.txt
-@@ -0,0 +1,133 @@
-+*** Reserved memory regions ***
-+
-+Reserved memory is specified as a node under the /reserved-memory node.
-+The operating system shall exclude reserved memory from normal usage
-+one can create child nodes describing particular reserved (excluded from
-+normal use) memory regions. Such memory regions are usually designed for
-+the special usage by various device drivers.
-+
-+Parameters for each memory region can be encoded into the device tree
-+with the following nodes:
-+
-+/reserved-memory node
-+---------------------
-+#address-cells, #size-cells (required) - standard definition
-+    - Should use the same values as the root node
-+ranges (required) - standard definition
-+    - Should be empty
-+
-+/reserved-memory/ child nodes
-+-----------------------------
-+Each child of the reserved-memory node specifies one or more regions of
-+reserved memory. Each child node may either use a 'reg' property to
-+specify a specific range of reserved memory, or a 'size' property with
-+optional constraints to request a dynamically allocated block of memory.
-+
-+Following the generic-names recommended practice, node names should
-+reflect the purpose of the node (ie. "framebuffer" or "dma-pool"). Unit
-+address (@<address>) should be appended to the name if the node is a
-+static allocation.
-+
-+Properties:
-+Requires either a) or b) below.
-+a) static allocation
-+   reg (required) - standard definition
-+b) dynamic allocation
-+   size (required) - length based on parent's #size-cells
-+                   - Size in bytes of memory to reserve.
-+   alignment (optional) - length based on parent's #size-cells
-+                        - Address boundary for alignment of allocation.
-+   alloc-ranges (optional) - prop-encoded-array (address, length pairs).
-+                           - Specifies regions of memory that are
-+                             acceptable to allocate from.
-+
-+If both reg and size are present, then the reg property takes precedence
-+and size is ignored.
-+
-+Additional properties:
-+compatible (optional) - standard definition
-+    - may contain the following strings:
-+        - shared-dma-pool: This indicates a region of memory meant to be
-+          used as a shared pool of DMA buffers for a set of devices. It can
-+          be used by an operating system to instanciate the necessary pool
-+          management subsystem if necessary.
-+        - vendor specific string in the form <vendor>,[<device>-]<usage>
-+no-map (optional) - empty property
-+    - Indicates the operating system must not create a virtual mapping
-+      of the region as part of its standard mapping of system memory,
-+      nor permit speculative access to it under any circumstances other
-+      than under the control of the device driver using the region.
-+reusable (optional) - empty property
-+    - The operating system can use the memory in this region with the
-+      limitation that the device driver(s) owning the region need to be
-+      able to reclaim it back. Typically that means that the operating
-+      system can use that region to store volatile or cached data that
-+      can be otherwise regenerated or migrated elsewhere.
-+
-+Linux implementation note:
-+- If a "linux,cma-default" property is present, then Linux will use the
-+  region for the default pool of the contiguous memory allocator.
-+
-+Device node references to reserved memory
-+-----------------------------------------
-+Regions in the /reserved-memory node may be referenced by other device
-+nodes by adding a memory-region property to the device node.
-+
-+memory-region (optional) - phandle, specifier pairs to children of /reserved-memory
-+
-+Example
-+-------
-+This example defines 3 contiguous regions are defined for Linux kernel:
-+one default of all device drivers (named linux,cma@72000000 and 64MiB in size),
-+one dedicated to the framebuffer device (named framebuffer@78000000, 8MiB), and
-+one for multimedia processing (named multimedia-memory@77000000, 64MiB).
-+
-+/ {
-+	#address-cells = <1>;
-+	#size-cells = <1>;
-+
-+	memory {
-+		reg = <0x40000000 0x40000000>;
-+	};
-+
-+	reserved-memory {
-+		#address-cells = <1>;
-+		#size-cells = <1>;
-+		ranges;
-+
-+		/* global autoconfigured region for contiguous allocations */
-+		linux,cma {
-+			compatible = "shared-dma-pool";
-+			reusable;
-+			size = <0x4000000>;
-+			alignment = <0x2000>;
-+			linux,cma-default;
-+		};
-+
-+		display_reserved: framebuffer@78000000 {
-+			reg = <0x78000000 0x800000>;
-+		};
-+
-+		multimedia_reserved: multimedia@77000000 {
-+			compatible = "acme,multimedia-memory";
-+			reg = <0x77000000 0x4000000>;
-+		};
-+	};
-+
-+	/* ... */
-+
-+	fb0: video@12300000 {
-+		memory-region = <&display_reserved>;
-+		/* ... */
-+	};
-+
-+	scaler: scaler@12500000 {
-+		memory-region = <&multimedia_reserved>;
-+		/* ... */
-+	};
-+
-+	codec: codec@12600000 {
-+		memory-region = <&multimedia_reserved>;
-+		/* ... */
-+	};
-+};
diff --git a/target/linux/ipq806x/patches/0054-of-only-scan-for-reserved-mem-when-fdt-present.patch b/target/linux/ipq806x/patches/0054-of-only-scan-for-reserved-mem-when-fdt-present.patch
deleted file mode 100644
index 6efcf38..0000000
--- a/target/linux/ipq806x/patches/0054-of-only-scan-for-reserved-mem-when-fdt-present.patch
+++ /dev/null
@@ -1,30 +0,0 @@
-From 884ab569aec3a0847702dff0dad133bfb67e234c Mon Sep 17 00:00:00 2001
-From: Josh Cartwright <joshc@codeaurora.org>
-Date: Thu, 13 Mar 2014 16:36:36 -0500
-Subject: [PATCH 054/182] of: only scan for reserved mem when fdt present
-
-When the reserved memory patches hit -next, several legacy (non-DT) boot
-failures were detected and bisected down to that commit. There needs to
-be some sanity checking whether a DT is even present before parsing the
-reserved ranges.
-
-Reported-by: Kevin Hilman <khilman@linaro.org>
-Signed-off-by: Josh Cartwright <joshc@codeaurora.org>
-Tested-by: Kevin Hilman <khilman@linaro.org>
-Signed-off-by: Grant Likely <grant.likely@linaro.org>
----
- drivers/of/fdt.c |    3 +++
- 1 file changed, 3 insertions(+)
-
---- a/drivers/of/fdt.c
-+++ b/drivers/of/fdt.c
-@@ -557,6 +557,9 @@ static int __init __fdt_scan_reserved_me
-  */
- void __init early_init_fdt_scan_reserved_mem(void)
- {
-+	if (!initial_boot_params)
-+		return;
-+
- 	of_scan_flat_dt(__fdt_scan_reserved_mem, NULL);
- 	fdt_init_reserved_mem();
- }
diff --git a/target/linux/ipq806x/patches/0055-spmi-Linux-driver-framework-for-SPMI.patch b/target/linux/ipq806x/patches/0055-spmi-Linux-driver-framework-for-SPMI.patch
deleted file mode 100644
index 80d3b6c..0000000
--- a/target/linux/ipq806x/patches/0055-spmi-Linux-driver-framework-for-SPMI.patch
+++ /dev/null
@@ -1,919 +0,0 @@
-From 1b0018dfd6295cbcc87738601b84bf49f3004419 Mon Sep 17 00:00:00 2001
-From: Kenneth Heitke <kheitke@codeaurora.org>
-Date: Wed, 12 Feb 2014 13:44:22 -0600
-Subject: [PATCH 055/182] spmi: Linux driver framework for SPMI
-
-System Power Management Interface (SPMI) is a specification
-developed by the MIPI (Mobile Industry Process Interface) Alliance
-optimized for the real time control of Power Management ICs (PMIC).
-
-SPMI is a two-wire serial interface that supports up to 4 master
-devices and up to 16 logical slaves.
-
-The framework supports message APIs, multiple busses (1 controller
-per bus) and multiple clients/slave devices per controller.
-
-Signed-off-by: Kenneth Heitke <kheitke@codeaurora.org>
-Signed-off-by: Michael Bohan <mbohan@codeaurora.org>
-Signed-off-by: Josh Cartwright <joshc@codeaurora.org>
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/Kconfig                 |    2 +
- drivers/Makefile                |    1 +
- drivers/spmi/Kconfig            |    9 +
- drivers/spmi/Makefile           |    4 +
- drivers/spmi/spmi.c             |  609 +++++++++++++++++++++++++++++++++++++++
- include/dt-bindings/spmi/spmi.h |   18 ++
- include/linux/mod_devicetable.h |    8 +
- include/linux/spmi.h            |  191 ++++++++++++
- 8 files changed, 842 insertions(+)
- create mode 100644 drivers/spmi/Kconfig
- create mode 100644 drivers/spmi/Makefile
- create mode 100644 drivers/spmi/spmi.c
- create mode 100644 include/dt-bindings/spmi/spmi.h
- create mode 100644 include/linux/spmi.h
-
---- a/drivers/Kconfig
-+++ b/drivers/Kconfig
-@@ -52,6 +52,8 @@ source "drivers/i2c/Kconfig"
- 
- source "drivers/spi/Kconfig"
- 
-+source "drivers/spmi/Kconfig"
-+
- source "drivers/hsi/Kconfig"
- 
- source "drivers/pps/Kconfig"
---- a/drivers/Makefile
-+++ b/drivers/Makefile
-@@ -66,6 +66,7 @@ obj-$(CONFIG_ATA)		+= ata/
- obj-$(CONFIG_TARGET_CORE)	+= target/
- obj-$(CONFIG_MTD)		+= mtd/
- obj-$(CONFIG_SPI)		+= spi/
-+obj-$(CONFIG_SPMI)		+= spmi/
- obj-y				+= hsi/
- obj-y				+= net/
- obj-$(CONFIG_ATM)		+= atm/
---- /dev/null
-+++ b/drivers/spmi/Kconfig
-@@ -0,0 +1,9 @@
-+#
-+# SPMI driver configuration
-+#
-+menuconfig SPMI
-+	tristate "SPMI support"
-+	help
-+	  SPMI (System Power Management Interface) is a two-wire
-+	  serial interface between baseband and application processors
-+	  and Power Management Integrated Circuits (PMIC).
---- /dev/null
-+++ b/drivers/spmi/Makefile
-@@ -0,0 +1,4 @@
-+#
-+# Makefile for kernel SPMI framework.
-+#
-+obj-$(CONFIG_SPMI)	+= spmi.o
---- /dev/null
-+++ b/drivers/spmi/spmi.c
-@@ -0,0 +1,609 @@
-+/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 and
-+ * only version 2 as published by the Free Software Foundation.
-+ *
-+ * 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/kernel.h>
-+#include <linux/errno.h>
-+#include <linux/idr.h>
-+#include <linux/slab.h>
-+#include <linux/module.h>
-+#include <linux/of.h>
-+#include <linux/of_device.h>
-+#include <linux/platform_device.h>
-+#include <linux/spmi.h>
-+#include <linux/module.h>
-+#include <linux/pm_runtime.h>
-+
-+#include <dt-bindings/spmi/spmi.h>
-+
-+static DEFINE_IDA(ctrl_ida);
-+
-+static void spmi_dev_release(struct device *dev)
-+{
-+	struct spmi_device *sdev = to_spmi_device(dev);
-+	kfree(sdev);
-+}
-+
-+static const struct device_type spmi_dev_type = {
-+	.release	= spmi_dev_release,
-+};
-+
-+static void spmi_ctrl_release(struct device *dev)
-+{
-+	struct spmi_controller *ctrl = to_spmi_controller(dev);
-+	ida_simple_remove(&ctrl_ida, ctrl->nr);
-+	kfree(ctrl);
-+}
-+
-+static const struct device_type spmi_ctrl_type = {
-+	.release	= spmi_ctrl_release,
-+};
-+
-+#ifdef CONFIG_PM_RUNTIME
-+static int spmi_runtime_suspend(struct device *dev)
-+{
-+	struct spmi_device *sdev = to_spmi_device(dev);
-+	int err;
-+
-+	err = pm_generic_runtime_suspend(dev);
-+	if (err)
-+		return err;
-+
-+	return spmi_command_sleep(sdev);
-+}
-+
-+static int spmi_runtime_resume(struct device *dev)
-+{
-+	struct spmi_device *sdev = to_spmi_device(dev);
-+	int err;
-+
-+	err = spmi_command_wakeup(sdev);
-+	if (err)
-+		return err;
-+
-+	return pm_generic_runtime_resume(dev);
-+}
-+#endif
-+
-+static const struct dev_pm_ops spmi_pm_ops = {
-+	SET_RUNTIME_PM_OPS(
-+		spmi_runtime_suspend,
-+		spmi_runtime_resume,
-+		NULL
-+	)
-+};
-+
-+static int spmi_device_match(struct device *dev, struct device_driver *drv)
-+{
-+	if (of_driver_match_device(dev, drv))
-+		return 1;
-+
-+	if (drv->name)
-+		return strncmp(dev_name(dev), drv->name,
-+			       SPMI_NAME_SIZE) == 0;
-+
-+	return 0;
-+}
-+
-+/**
-+ * spmi_device_add() - add a device previously constructed via spmi_device_alloc()
-+ * @sdev:	spmi_device to be added
-+ */
-+int spmi_device_add(struct spmi_device *sdev)
-+{
-+	struct spmi_controller *ctrl = sdev->ctrl;
-+	int err;
-+
-+	dev_set_name(&sdev->dev, "%d-%02x", ctrl->nr, sdev->usid);
-+
-+	err = device_add(&sdev->dev);
-+	if (err < 0) {
-+		dev_err(&sdev->dev, "Can't add %s, status %d\n",
-+			dev_name(&sdev->dev), err);
-+		goto err_device_add;
-+	}
-+
-+	dev_dbg(&sdev->dev, "device %s registered\n", dev_name(&sdev->dev));
-+
-+err_device_add:
-+	return err;
-+}
-+EXPORT_SYMBOL_GPL(spmi_device_add);
-+
-+/**
-+ * spmi_device_remove(): remove an SPMI device
-+ * @sdev:	spmi_device to be removed
-+ */
-+void spmi_device_remove(struct spmi_device *sdev)
-+{
-+	device_unregister(&sdev->dev);
-+}
-+EXPORT_SYMBOL_GPL(spmi_device_remove);
-+
-+static inline int
-+spmi_cmd(struct spmi_controller *ctrl, u8 opcode, u8 sid)
-+{
-+	if (!ctrl || !ctrl->cmd || ctrl->dev.type != &spmi_ctrl_type)
-+		return -EINVAL;
-+
-+	return ctrl->cmd(ctrl, opcode, sid);
-+}
-+
-+static inline int spmi_read_cmd(struct spmi_controller *ctrl, u8 opcode,
-+				u8 sid, u16 addr, u8 *buf, size_t len)
-+{
-+	if (!ctrl || !ctrl->read_cmd || ctrl->dev.type != &spmi_ctrl_type)
-+		return -EINVAL;
-+
-+	return ctrl->read_cmd(ctrl, opcode, sid, addr, buf, len);
-+}
-+
-+static inline int spmi_write_cmd(struct spmi_controller *ctrl, u8 opcode,
-+				 u8 sid, u16 addr, const u8 *buf, size_t len)
-+{
-+	if (!ctrl || !ctrl->write_cmd || ctrl->dev.type != &spmi_ctrl_type)
-+		return -EINVAL;
-+
-+	return ctrl->write_cmd(ctrl, opcode, sid, addr, buf, len);
-+}
-+
-+/**
-+ * spmi_register_read() - register read
-+ * @sdev:	SPMI device.
-+ * @addr:	slave register address (5-bit address).
-+ * @buf:	buffer to be populated with data from the Slave.
-+ *
-+ * Reads 1 byte of data from a Slave device register.
-+ */
-+int spmi_register_read(struct spmi_device *sdev, u8 addr, u8 *buf)
-+{
-+	/* 5-bit register address */
-+	if (addr > 0x1F)
-+		return -EINVAL;
-+
-+	return spmi_read_cmd(sdev->ctrl, SPMI_CMD_READ, sdev->usid, addr,
-+			     buf, 1);
-+}
-+EXPORT_SYMBOL_GPL(spmi_register_read);
-+
-+/**
-+ * spmi_ext_register_read() - extended register read
-+ * @sdev:	SPMI device.
-+ * @addr:	slave register address (8-bit address).
-+ * @buf:	buffer to be populated with data from the Slave.
-+ * @len:	the request number of bytes to read (up to 16 bytes).
-+ *
-+ * Reads up to 16 bytes of data from the extended register space on a
-+ * Slave device.
-+ */
-+int spmi_ext_register_read(struct spmi_device *sdev, u8 addr, u8 *buf,
-+			   size_t len)
-+{
-+	/* 8-bit register address, up to 16 bytes */
-+	if (len == 0 || len > 16)
-+		return -EINVAL;
-+
-+	return spmi_read_cmd(sdev->ctrl, SPMI_CMD_EXT_READ, sdev->usid, addr,
-+			     buf, len);
-+}
-+EXPORT_SYMBOL_GPL(spmi_ext_register_read);
-+
-+/**
-+ * spmi_ext_register_readl() - extended register read long
-+ * @sdev:	SPMI device.
-+ * @addr:	slave register address (16-bit address).
-+ * @buf:	buffer to be populated with data from the Slave.
-+ * @len:	the request number of bytes to read (up to 8 bytes).
-+ *
-+ * Reads up to 8 bytes of data from the extended register space on a
-+ * Slave device using 16-bit address.
-+ */
-+int spmi_ext_register_readl(struct spmi_device *sdev, u16 addr, u8 *buf,
-+			    size_t len)
-+{
-+	/* 16-bit register address, up to 8 bytes */
-+	if (len == 0 || len > 8)
-+		return -EINVAL;
-+
-+	return spmi_read_cmd(sdev->ctrl, SPMI_CMD_EXT_READL, sdev->usid, addr,
-+			     buf, len);
-+}
-+EXPORT_SYMBOL_GPL(spmi_ext_register_readl);
-+
-+/**
-+ * spmi_register_write() - register write
-+ * @sdev:	SPMI device
-+ * @addr:	slave register address (5-bit address).
-+ * @data:	buffer containing the data to be transferred to the Slave.
-+ *
-+ * Writes 1 byte of data to a Slave device register.
-+ */
-+int spmi_register_write(struct spmi_device *sdev, u8 addr, u8 data)
-+{
-+	/* 5-bit register address */
-+	if (addr > 0x1F)
-+		return -EINVAL;
-+
-+	return spmi_write_cmd(sdev->ctrl, SPMI_CMD_WRITE, sdev->usid, addr,
-+			      &data, 1);
-+}
-+EXPORT_SYMBOL_GPL(spmi_register_write);
-+
-+/**
-+ * spmi_register_zero_write() - register zero write
-+ * @sdev:	SPMI device.
-+ * @data:	the data to be written to register 0 (7-bits).
-+ *
-+ * Writes data to register 0 of the Slave device.
-+ */
-+int spmi_register_zero_write(struct spmi_device *sdev, u8 data)
-+{
-+	return spmi_write_cmd(sdev->ctrl, SPMI_CMD_ZERO_WRITE, sdev->usid, 0,
-+			      &data, 1);
-+}
-+EXPORT_SYMBOL_GPL(spmi_register_zero_write);
-+
-+/**
-+ * spmi_ext_register_write() - extended register write
-+ * @sdev:	SPMI device.
-+ * @addr:	slave register address (8-bit address).
-+ * @buf:	buffer containing the data to be transferred to the Slave.
-+ * @len:	the request number of bytes to read (up to 16 bytes).
-+ *
-+ * Writes up to 16 bytes of data to the extended register space of a
-+ * Slave device.
-+ */
-+int spmi_ext_register_write(struct spmi_device *sdev, u8 addr, const u8 *buf,
-+			    size_t len)
-+{
-+	/* 8-bit register address, up to 16 bytes */
-+	if (len == 0 || len > 16)
-+		return -EINVAL;
-+
-+	return spmi_write_cmd(sdev->ctrl, SPMI_CMD_EXT_WRITE, sdev->usid, addr,
-+			      buf, len);
-+}
-+EXPORT_SYMBOL_GPL(spmi_ext_register_write);
-+
-+/**
-+ * spmi_ext_register_writel() - extended register write long
-+ * @sdev:	SPMI device.
-+ * @addr:	slave register address (16-bit address).
-+ * @buf:	buffer containing the data to be transferred to the Slave.
-+ * @len:	the request number of bytes to read (up to 8 bytes).
-+ *
-+ * Writes up to 8 bytes of data to the extended register space of a
-+ * Slave device using 16-bit address.
-+ */
-+int spmi_ext_register_writel(struct spmi_device *sdev, u16 addr, const u8 *buf,
-+			     size_t len)
-+{
-+	/* 4-bit Slave Identifier, 16-bit register address, up to 8 bytes */
-+	if (len == 0 || len > 8)
-+		return -EINVAL;
-+
-+	return spmi_write_cmd(sdev->ctrl, SPMI_CMD_EXT_WRITEL, sdev->usid,
-+			      addr, buf, len);
-+}
-+EXPORT_SYMBOL_GPL(spmi_ext_register_writel);
-+
-+/**
-+ * spmi_command_reset() - sends RESET command to the specified slave
-+ * @sdev:	SPMI device.
-+ *
-+ * The Reset command initializes the Slave and forces all registers to
-+ * their reset values. The Slave shall enter the STARTUP state after
-+ * receiving a Reset command.
-+ */
-+int spmi_command_reset(struct spmi_device *sdev)
-+{
-+	return spmi_cmd(sdev->ctrl, SPMI_CMD_RESET, sdev->usid);
-+}
-+EXPORT_SYMBOL_GPL(spmi_command_reset);
-+
-+/**
-+ * spmi_command_sleep() - sends SLEEP command to the specified SPMI device
-+ * @sdev:	SPMI device.
-+ *
-+ * The Sleep command causes the Slave to enter the user defined SLEEP state.
-+ */
-+int spmi_command_sleep(struct spmi_device *sdev)
-+{
-+	return spmi_cmd(sdev->ctrl, SPMI_CMD_SLEEP, sdev->usid);
-+}
-+EXPORT_SYMBOL_GPL(spmi_command_sleep);
-+
-+/**
-+ * spmi_command_wakeup() - sends WAKEUP command to the specified SPMI device
-+ * @sdev:	SPMI device.
-+ *
-+ * The Wakeup command causes the Slave to move from the SLEEP state to
-+ * the ACTIVE state.
-+ */
-+int spmi_command_wakeup(struct spmi_device *sdev)
-+{
-+	return spmi_cmd(sdev->ctrl, SPMI_CMD_WAKEUP, sdev->usid);
-+}
-+EXPORT_SYMBOL_GPL(spmi_command_wakeup);
-+
-+/**
-+ * spmi_command_shutdown() - sends SHUTDOWN command to the specified SPMI device
-+ * @sdev:	SPMI device.
-+ *
-+ * The Shutdown command causes the Slave to enter the SHUTDOWN state.
-+ */
-+int spmi_command_shutdown(struct spmi_device *sdev)
-+{
-+	return spmi_cmd(sdev->ctrl, SPMI_CMD_SHUTDOWN, sdev->usid);
-+}
-+EXPORT_SYMBOL_GPL(spmi_command_shutdown);
-+
-+static int spmi_drv_probe(struct device *dev)
-+{
-+	const struct spmi_driver *sdrv = to_spmi_driver(dev->driver);
-+	struct spmi_device *sdev = to_spmi_device(dev);
-+	int err;
-+
-+	/* Ensure the slave is in ACTIVE state */
-+	err = spmi_command_wakeup(sdev);
-+	if (err)
-+		goto fail_wakeup;
-+
-+	pm_runtime_get_noresume(dev);
-+	pm_runtime_set_active(dev);
-+	pm_runtime_enable(dev);
-+
-+	err = sdrv->probe(sdev);
-+	if (err)
-+		goto fail_probe;
-+
-+	return 0;
-+
-+fail_probe:
-+	pm_runtime_disable(dev);
-+	pm_runtime_set_suspended(dev);
-+	pm_runtime_put_noidle(dev);
-+fail_wakeup:
-+	return err;
-+}
-+
-+static int spmi_drv_remove(struct device *dev)
-+{
-+	const struct spmi_driver *sdrv = to_spmi_driver(dev->driver);
-+
-+	pm_runtime_get_sync(dev);
-+	sdrv->remove(to_spmi_device(dev));
-+	pm_runtime_put_noidle(dev);
-+
-+	pm_runtime_disable(dev);
-+	pm_runtime_set_suspended(dev);
-+	pm_runtime_put_noidle(dev);
-+	return 0;
-+}
-+
-+static struct bus_type spmi_bus_type = {
-+	.name		= "spmi",
-+	.match		= spmi_device_match,
-+	.pm		= &spmi_pm_ops,
-+	.probe		= spmi_drv_probe,
-+	.remove		= spmi_drv_remove,
-+};
-+
-+/**
-+ * spmi_controller_alloc() - Allocate a new SPMI device
-+ * @ctrl:	associated controller
-+ *
-+ * Caller is responsible for either calling spmi_device_add() to add the
-+ * newly allocated controller, or calling spmi_device_put() to discard it.
-+ */
-+struct spmi_device *spmi_device_alloc(struct spmi_controller *ctrl)
-+{
-+	struct spmi_device *sdev;
-+
-+	sdev = kzalloc(sizeof(*sdev), GFP_KERNEL);
-+	if (!sdev)
-+		return NULL;
-+
-+	sdev->ctrl = ctrl;
-+	device_initialize(&sdev->dev);
-+	sdev->dev.parent = &ctrl->dev;
-+	sdev->dev.bus = &spmi_bus_type;
-+	sdev->dev.type = &spmi_dev_type;
-+	return sdev;
-+}
-+EXPORT_SYMBOL_GPL(spmi_device_alloc);
-+
-+/**
-+ * spmi_controller_alloc() - Allocate a new SPMI controller
-+ * @parent:	parent device
-+ * @size:	size of private data
-+ *
-+ * Caller is responsible for either calling spmi_controller_add() to add the
-+ * newly allocated controller, or calling spmi_controller_put() to discard it.
-+ * The allocated private data region may be accessed via
-+ * spmi_controller_get_drvdata()
-+ */
-+struct spmi_controller *spmi_controller_alloc(struct device *parent,
-+					      size_t size)
-+{
-+	struct spmi_controller *ctrl;
-+	int id;
-+
-+	if (WARN_ON(!parent))
-+		return NULL;
-+
-+	ctrl = kzalloc(sizeof(*ctrl) + size, GFP_KERNEL);
-+	if (!ctrl)
-+		return NULL;
-+
-+	device_initialize(&ctrl->dev);
-+	ctrl->dev.type = &spmi_ctrl_type;
-+	ctrl->dev.bus = &spmi_bus_type;
-+	ctrl->dev.parent = parent;
-+	ctrl->dev.of_node = parent->of_node;
-+	spmi_controller_set_drvdata(ctrl, &ctrl[1]);
-+
-+	id = ida_simple_get(&ctrl_ida, 0, 0, GFP_KERNEL);
-+	if (id < 0) {
-+		dev_err(parent,
-+			"unable to allocate SPMI controller identifier.\n");
-+		spmi_controller_put(ctrl);
-+		return NULL;
-+	}
-+
-+	ctrl->nr = id;
-+	dev_set_name(&ctrl->dev, "spmi-%d", id);
-+
-+	dev_dbg(&ctrl->dev, "allocated controller 0x%p id %d\n", ctrl, id);
-+	return ctrl;
-+}
-+EXPORT_SYMBOL_GPL(spmi_controller_alloc);
-+
-+static void of_spmi_register_devices(struct spmi_controller *ctrl)
-+{
-+	struct device_node *node;
-+	int err;
-+
-+	if (!ctrl->dev.of_node)
-+		return;
-+
-+	for_each_available_child_of_node(ctrl->dev.of_node, node) {
-+		struct spmi_device *sdev;
-+		u32 reg[2];
-+
-+		dev_dbg(&ctrl->dev, "adding child %s\n", node->full_name);
-+
-+		err = of_property_read_u32_array(node, "reg", reg, 2);
-+		if (err) {
-+			dev_err(&ctrl->dev,
-+				"node %s err (%d) does not have 'reg' property\n",
-+				node->full_name, err);
-+			continue;
-+		}
-+
-+		if (reg[1] != SPMI_USID) {
-+			dev_err(&ctrl->dev,
-+				"node %s contains unsupported 'reg' entry\n",
-+				node->full_name);
-+			continue;
-+		}
-+
-+		if (reg[0] >= SPMI_MAX_SLAVE_ID) {
-+			dev_err(&ctrl->dev,
-+				"invalid usid on node %s\n",
-+				node->full_name);
-+			continue;
-+		}
-+
-+		dev_dbg(&ctrl->dev, "read usid %02x\n", reg[0]);
-+
-+		sdev = spmi_device_alloc(ctrl);
-+		if (!sdev)
-+			continue;
-+
-+		sdev->dev.of_node = node;
-+		sdev->usid = (u8) reg[0];
-+
-+		err = spmi_device_add(sdev);
-+		if (err) {
-+			dev_err(&sdev->dev,
-+				"failure adding device. status %d\n", err);
-+			spmi_device_put(sdev);
-+		}
-+	}
-+}
-+
-+/**
-+ * spmi_controller_add() - Add an SPMI controller
-+ * @ctrl:	controller to be registered.
-+ *
-+ * Register a controller previously allocated via spmi_controller_alloc() with
-+ * the SPMI core.
-+ */
-+int spmi_controller_add(struct spmi_controller *ctrl)
-+{
-+	int ret;
-+
-+	/* Can't register until after driver model init */
-+	if (WARN_ON(!spmi_bus_type.p))
-+		return -EAGAIN;
-+
-+	ret = device_add(&ctrl->dev);
-+	if (ret)
-+		return ret;
-+
-+	if (IS_ENABLED(CONFIG_OF))
-+		of_spmi_register_devices(ctrl);
-+
-+	dev_dbg(&ctrl->dev, "spmi-%d registered: dev:%p\n",
-+		ctrl->nr, &ctrl->dev);
-+
-+	return 0;
-+};
-+EXPORT_SYMBOL_GPL(spmi_controller_add);
-+
-+/* Remove a device associated with a controller */
-+static int spmi_ctrl_remove_device(struct device *dev, void *data)
-+{
-+	struct spmi_device *spmidev = to_spmi_device(dev);
-+	if (dev->type == &spmi_dev_type)
-+		spmi_device_remove(spmidev);
-+	return 0;
-+}
-+
-+/**
-+ * spmi_controller_remove(): remove an SPMI controller
-+ * @ctrl:	controller to remove
-+ *
-+ * Remove a SPMI controller.  Caller is responsible for calling
-+ * spmi_controller_put() to discard the allocated controller.
-+ */
-+void spmi_controller_remove(struct spmi_controller *ctrl)
-+{
-+	int dummy;
-+
-+	if (!ctrl)
-+		return;
-+
-+	dummy = device_for_each_child(&ctrl->dev, NULL,
-+				      spmi_ctrl_remove_device);
-+	device_del(&ctrl->dev);
-+}
-+EXPORT_SYMBOL_GPL(spmi_controller_remove);
-+
-+/**
-+ * spmi_driver_register() - Register client driver with SPMI core
-+ * @sdrv:	client driver to be associated with client-device.
-+ *
-+ * This API will register the client driver with the SPMI framework.
-+ * It is typically called from the driver's module-init function.
-+ */
-+int spmi_driver_register(struct spmi_driver *sdrv)
-+{
-+	sdrv->driver.bus = &spmi_bus_type;
-+	return driver_register(&sdrv->driver);
-+}
-+EXPORT_SYMBOL_GPL(spmi_driver_register);
-+
-+static void __exit spmi_exit(void)
-+{
-+	bus_unregister(&spmi_bus_type);
-+}
-+module_exit(spmi_exit);
-+
-+static int __init spmi_init(void)
-+{
-+	return bus_register(&spmi_bus_type);
-+}
-+postcore_initcall(spmi_init);
-+
-+MODULE_LICENSE("GPL v2");
-+MODULE_DESCRIPTION("SPMI module");
-+MODULE_ALIAS("platform:spmi");
---- /dev/null
-+++ b/include/dt-bindings/spmi/spmi.h
-@@ -0,0 +1,18 @@
-+/* Copyright (c) 2013, The Linux Foundation. All rights reserved.
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 and
-+ * only version 2 as published by the Free Software Foundation.
-+ *
-+ * 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 __DT_BINDINGS_SPMI_H
-+#define __DT_BINDINGS_SPMI_H
-+
-+#define SPMI_USID	0
-+#define SPMI_GSID	1
-+
-+#endif
---- a/include/linux/mod_devicetable.h
-+++ b/include/linux/mod_devicetable.h
-@@ -432,6 +432,14 @@ struct spi_device_id {
- 	kernel_ulong_t driver_data;	/* Data private to the driver */
- };
- 
-+#define SPMI_NAME_SIZE	32
-+#define SPMI_MODULE_PREFIX "spmi:"
-+
-+struct spmi_device_id {
-+	char name[SPMI_NAME_SIZE];
-+	kernel_ulong_t driver_data;	/* Data private to the driver */
-+};
-+
- /* dmi */
- enum dmi_field {
- 	DMI_NONE,
---- /dev/null
-+++ b/include/linux/spmi.h
-@@ -0,0 +1,191 @@
-+/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 and
-+ * only version 2 as published by the Free Software Foundation.
-+ *
-+ * 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_SPMI_H
-+#define _LINUX_SPMI_H
-+
-+#include <linux/types.h>
-+#include <linux/device.h>
-+#include <linux/mod_devicetable.h>
-+
-+/* Maximum slave identifier */
-+#define SPMI_MAX_SLAVE_ID		16
-+
-+/* SPMI Commands */
-+#define SPMI_CMD_EXT_WRITE		0x00
-+#define SPMI_CMD_RESET			0x10
-+#define SPMI_CMD_SLEEP			0x11
-+#define SPMI_CMD_SHUTDOWN		0x12
-+#define SPMI_CMD_WAKEUP			0x13
-+#define SPMI_CMD_AUTHENTICATE		0x14
-+#define SPMI_CMD_MSTR_READ		0x15
-+#define SPMI_CMD_MSTR_WRITE		0x16
-+#define SPMI_CMD_TRANSFER_BUS_OWNERSHIP	0x1A
-+#define SPMI_CMD_DDB_MASTER_READ	0x1B
-+#define SPMI_CMD_DDB_SLAVE_READ		0x1C
-+#define SPMI_CMD_EXT_READ		0x20
-+#define SPMI_CMD_EXT_WRITEL		0x30
-+#define SPMI_CMD_EXT_READL		0x38
-+#define SPMI_CMD_WRITE			0x40
-+#define SPMI_CMD_READ			0x60
-+#define SPMI_CMD_ZERO_WRITE		0x80
-+
-+/**
-+ * struct spmi_device - Basic representation of an SPMI device
-+ * @dev:	Driver model representation of the device.
-+ * @ctrl:	SPMI controller managing the bus hosting this device.
-+ * @usid:	This devices' Unique Slave IDentifier.
-+ */
-+struct spmi_device {
-+	struct device		dev;
-+	struct spmi_controller	*ctrl;
-+	u8			usid;
-+};
-+
-+static inline struct spmi_device *to_spmi_device(struct device *d)
-+{
-+	return container_of(d, struct spmi_device, dev);
-+}
-+
-+static inline void *spmi_device_get_drvdata(const struct spmi_device *sdev)
-+{
-+	return dev_get_drvdata(&sdev->dev);
-+}
-+
-+static inline void spmi_device_set_drvdata(struct spmi_device *sdev, void *data)
-+{
-+	dev_set_drvdata(&sdev->dev, data);
-+}
-+
-+struct spmi_device *spmi_device_alloc(struct spmi_controller *ctrl);
-+
-+static inline void spmi_device_put(struct spmi_device *sdev)
-+{
-+	if (sdev)
-+		put_device(&sdev->dev);
-+}
-+
-+int spmi_device_add(struct spmi_device *sdev);
-+
-+void spmi_device_remove(struct spmi_device *sdev);
-+
-+/**
-+ * struct spmi_controller - interface to the SPMI master controller
-+ * @dev:	Driver model representation of the device.
-+ * @nr:		board-specific number identifier for this controller/bus
-+ * @cmd:	sends a non-data command sequence on the SPMI bus.
-+ * @read_cmd:	sends a register read command sequence on the SPMI bus.
-+ * @write_cmd:	sends a register write command sequence on the SPMI bus.
-+ */
-+struct spmi_controller {
-+	struct device		dev;
-+	unsigned int		nr;
-+	int	(*cmd)(struct spmi_controller *ctrl, u8 opcode, u8 sid);
-+	int	(*read_cmd)(struct spmi_controller *ctrl, u8 opcode,
-+			    u8 sid, u16 addr, u8 *buf, size_t len);
-+	int	(*write_cmd)(struct spmi_controller *ctrl, u8 opcode,
-+			     u8 sid, u16 addr, const u8 *buf, size_t len);
-+};
-+
-+static inline struct spmi_controller *to_spmi_controller(struct device *d)
-+{
-+	return container_of(d, struct spmi_controller, dev);
-+}
-+
-+static inline
-+void *spmi_controller_get_drvdata(const struct spmi_controller *ctrl)
-+{
-+	return dev_get_drvdata(&ctrl->dev);
-+}
-+
-+static inline void spmi_controller_set_drvdata(struct spmi_controller *ctrl,
-+					       void *data)
-+{
-+	dev_set_drvdata(&ctrl->dev, data);
-+}
-+
-+struct spmi_controller *spmi_controller_alloc(struct device *parent,
-+					      size_t size);
-+
-+/**
-+ * spmi_controller_put() - decrement controller refcount
-+ * @ctrl	SPMI controller.
-+ */
-+static inline void spmi_controller_put(struct spmi_controller *ctrl)
-+{
-+	if (ctrl)
-+		put_device(&ctrl->dev);
-+}
-+
-+int spmi_controller_add(struct spmi_controller *ctrl);
-+void spmi_controller_remove(struct spmi_controller *ctrl);
-+
-+/**
-+ * struct spmi_driver - SPMI slave device driver
-+ * @driver:	SPMI device drivers should initialize name and owner field of
-+ *		this structure.
-+ * @probe:	binds this driver to a SPMI device.
-+ * @remove:	unbinds this driver from the SPMI device.
-+ * @shutdown:	standard shutdown callback used during powerdown/halt.
-+ * @suspend:	standard suspend callback used during system suspend.
-+ * @resume:	standard resume callback used during system resume.
-+ *
-+ * If PM runtime support is desired for a slave, a device driver can call
-+ * pm_runtime_put() from their probe() routine (and a balancing
-+ * pm_runtime_get() in remove()).  PM runtime support for a slave is
-+ * implemented by issuing a SLEEP command to the slave on runtime_suspend(),
-+ * transitioning the slave into the SLEEP state.  On runtime_resume(), a WAKEUP
-+ * command is sent to the slave to bring it back to ACTIVE.
-+ */
-+struct spmi_driver {
-+	struct device_driver driver;
-+	int	(*probe)(struct spmi_device *sdev);
-+	void	(*remove)(struct spmi_device *sdev);
-+};
-+
-+static inline struct spmi_driver *to_spmi_driver(struct device_driver *d)
-+{
-+	return container_of(d, struct spmi_driver, driver);
-+}
-+
-+int spmi_driver_register(struct spmi_driver *sdrv);
-+
-+/**
-+ * spmi_driver_unregister() - unregister an SPMI client driver
-+ * @sdrv:	the driver to unregister
-+ */
-+static inline void spmi_driver_unregister(struct spmi_driver *sdrv)
-+{
-+	if (sdrv)
-+		driver_unregister(&sdrv->driver);
-+}
-+
-+#define module_spmi_driver(__spmi_driver) \
-+	module_driver(__spmi_driver, spmi_driver_register, \
-+			spmi_driver_unregister)
-+
-+int spmi_register_read(struct spmi_device *sdev, u8 addr, u8 *buf);
-+int spmi_ext_register_read(struct spmi_device *sdev, u8 addr, u8 *buf,
-+			   size_t len);
-+int spmi_ext_register_readl(struct spmi_device *sdev, u16 addr, u8 *buf,
-+			    size_t len);
-+int spmi_register_write(struct spmi_device *sdev, u8 addr, u8 data);
-+int spmi_register_zero_write(struct spmi_device *sdev, u8 data);
-+int spmi_ext_register_write(struct spmi_device *sdev, u8 addr,
-+			    const u8 *buf, size_t len);
-+int spmi_ext_register_writel(struct spmi_device *sdev, u16 addr,
-+			     const u8 *buf, size_t len);
-+int spmi_command_reset(struct spmi_device *sdev);
-+int spmi_command_sleep(struct spmi_device *sdev);
-+int spmi_command_wakeup(struct spmi_device *sdev);
-+int spmi_command_shutdown(struct spmi_device *sdev);
-+
-+#endif
diff --git a/target/linux/ipq806x/patches/0056-spmi-Add-MSM-PMIC-Arbiter-SPMI-controller.patch b/target/linux/ipq806x/patches/0056-spmi-Add-MSM-PMIC-Arbiter-SPMI-controller.patch
deleted file mode 100644
index e2fde2d..0000000
--- a/target/linux/ipq806x/patches/0056-spmi-Add-MSM-PMIC-Arbiter-SPMI-controller.patch
+++ /dev/null
@@ -1,467 +0,0 @@
-From 1e1f53fbc2848b23af572c16d19e8004f6a7c9c1 Mon Sep 17 00:00:00 2001
-From: Kenneth Heitke <kheitke@codeaurora.org>
-Date: Wed, 12 Feb 2014 13:44:24 -0600
-Subject: [PATCH 056/182] spmi: Add MSM PMIC Arbiter SPMI controller
-
-Qualcomm's PMIC Arbiter SPMI controller functions as a bus master and
-is used to communication with one or more PMIC (slave) devices on the
-SPMI bus.  The PMIC Arbiter is actually a hardware wrapper around the
-SPMI controller that provides concurrent and autonomous PMIC access
-to various entities that need to communicate with the PMIC.
-
-The SPMI controller hardware handles all of the SPMI bus activity (bus
-arbitration, sequence start condition, transmission of frames, etc).
-This software driver uses the PMIC Arbiter register interface to
-initiate command sequences on the SPMI bus.  The status register is
-read to determine when the command sequence has completed and whether
-or not it completed successfully.
-
-Signed-off-by: Kenneth Heitke <kheitke@codeaurora.org>
-Signed-off-by: Josh Cartwright <joshc@codeaurora.org>
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/spmi/Kconfig         |   17 ++
- drivers/spmi/Makefile        |    2 +
- drivers/spmi/spmi-pmic-arb.c |  405 ++++++++++++++++++++++++++++++++++++++++++
- 3 files changed, 424 insertions(+)
- create mode 100644 drivers/spmi/spmi-pmic-arb.c
-
---- a/drivers/spmi/Kconfig
-+++ b/drivers/spmi/Kconfig
-@@ -7,3 +7,20 @@ menuconfig SPMI
- 	  SPMI (System Power Management Interface) is a two-wire
- 	  serial interface between baseband and application processors
- 	  and Power Management Integrated Circuits (PMIC).
-+
-+if SPMI
-+
-+config SPMI_MSM_PMIC_ARB
-+	tristate "Qualcomm MSM SPMI Controller (PMIC Arbiter)"
-+	depends on ARM
-+	depends on ARCH_MSM || COMPILE_TEST
-+	default ARCH_MSM
-+	help
-+	  If you say yes to this option, support will be included for the
-+	  built-in SPMI PMIC Arbiter interface on Qualcomm MSM family
-+	  processors.
-+
-+	  This is required for communicating with Qualcomm PMICs and
-+	  other devices that have the SPMI interface.
-+
-+endif
---- a/drivers/spmi/Makefile
-+++ b/drivers/spmi/Makefile
-@@ -2,3 +2,5 @@
- # Makefile for kernel SPMI framework.
- #
- obj-$(CONFIG_SPMI)	+= spmi.o
-+
-+obj-$(CONFIG_SPMI_MSM_PMIC_ARB)	+= spmi-pmic-arb.o
---- /dev/null
-+++ b/drivers/spmi/spmi-pmic-arb.c
-@@ -0,0 +1,405 @@
-+/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 and
-+ * only version 2 as published by the Free Software Foundation.
-+ *
-+ * 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/delay.h>
-+#include <linux/err.h>
-+#include <linux/interrupt.h>
-+#include <linux/io.h>
-+#include <linux/kernel.h>
-+#include <linux/module.h>
-+#include <linux/of.h>
-+#include <linux/platform_device.h>
-+#include <linux/slab.h>
-+#include <linux/spmi.h>
-+
-+/* PMIC Arbiter configuration registers */
-+#define PMIC_ARB_VERSION		0x0000
-+#define PMIC_ARB_INT_EN			0x0004
-+
-+/* PMIC Arbiter channel registers */
-+#define PMIC_ARB_CMD(N)			(0x0800 + (0x80 * (N)))
-+#define PMIC_ARB_CONFIG(N)		(0x0804 + (0x80 * (N)))
-+#define PMIC_ARB_STATUS(N)		(0x0808 + (0x80 * (N)))
-+#define PMIC_ARB_WDATA0(N)		(0x0810 + (0x80 * (N)))
-+#define PMIC_ARB_WDATA1(N)		(0x0814 + (0x80 * (N)))
-+#define PMIC_ARB_RDATA0(N)		(0x0818 + (0x80 * (N)))
-+#define PMIC_ARB_RDATA1(N)		(0x081C + (0x80 * (N)))
-+
-+/* Interrupt Controller */
-+#define SPMI_PIC_OWNER_ACC_STATUS(M, N)	(0x0000 + ((32 * (M)) + (4 * (N))))
-+#define SPMI_PIC_ACC_ENABLE(N)		(0x0200 + (4 * (N)))
-+#define SPMI_PIC_IRQ_STATUS(N)		(0x0600 + (4 * (N)))
-+#define SPMI_PIC_IRQ_CLEAR(N)		(0x0A00 + (4 * (N)))
-+
-+/* Mapping Table */
-+#define SPMI_MAPPING_TABLE_REG(N)	(0x0B00 + (4 * (N)))
-+#define SPMI_MAPPING_BIT_INDEX(X)	(((X) >> 18) & 0xF)
-+#define SPMI_MAPPING_BIT_IS_0_FLAG(X)	(((X) >> 17) & 0x1)
-+#define SPMI_MAPPING_BIT_IS_0_RESULT(X)	(((X) >> 9) & 0xFF)
-+#define SPMI_MAPPING_BIT_IS_1_FLAG(X)	(((X) >> 8) & 0x1)
-+#define SPMI_MAPPING_BIT_IS_1_RESULT(X)	(((X) >> 0) & 0xFF)
-+
-+#define SPMI_MAPPING_TABLE_LEN		255
-+#define SPMI_MAPPING_TABLE_TREE_DEPTH	16	/* Maximum of 16-bits */
-+
-+/* Ownership Table */
-+#define SPMI_OWNERSHIP_TABLE_REG(N)	(0x0700 + (4 * (N)))
-+#define SPMI_OWNERSHIP_PERIPH2OWNER(X)	((X) & 0x7)
-+
-+/* Channel Status fields */
-+enum pmic_arb_chnl_status {
-+	PMIC_ARB_STATUS_DONE	= (1 << 0),
-+	PMIC_ARB_STATUS_FAILURE	= (1 << 1),
-+	PMIC_ARB_STATUS_DENIED	= (1 << 2),
-+	PMIC_ARB_STATUS_DROPPED	= (1 << 3),
-+};
-+
-+/* Command register fields */
-+#define PMIC_ARB_CMD_MAX_BYTE_COUNT	8
-+
-+/* Command Opcodes */
-+enum pmic_arb_cmd_op_code {
-+	PMIC_ARB_OP_EXT_WRITEL = 0,
-+	PMIC_ARB_OP_EXT_READL = 1,
-+	PMIC_ARB_OP_EXT_WRITE = 2,
-+	PMIC_ARB_OP_RESET = 3,
-+	PMIC_ARB_OP_SLEEP = 4,
-+	PMIC_ARB_OP_SHUTDOWN = 5,
-+	PMIC_ARB_OP_WAKEUP = 6,
-+	PMIC_ARB_OP_AUTHENTICATE = 7,
-+	PMIC_ARB_OP_MSTR_READ = 8,
-+	PMIC_ARB_OP_MSTR_WRITE = 9,
-+	PMIC_ARB_OP_EXT_READ = 13,
-+	PMIC_ARB_OP_WRITE = 14,
-+	PMIC_ARB_OP_READ = 15,
-+	PMIC_ARB_OP_ZERO_WRITE = 16,
-+};
-+
-+/* Maximum number of support PMIC peripherals */
-+#define PMIC_ARB_MAX_PERIPHS		256
-+#define PMIC_ARB_PERIPH_ID_VALID	(1 << 15)
-+#define PMIC_ARB_TIMEOUT_US		100
-+#define PMIC_ARB_MAX_TRANS_BYTES	(8)
-+
-+#define PMIC_ARB_APID_MASK		0xFF
-+#define PMIC_ARB_PPID_MASK		0xFFF
-+
-+/* interrupt enable bit */
-+#define SPMI_PIC_ACC_ENABLE_BIT		BIT(0)
-+
-+/**
-+ * spmi_pmic_arb_dev - SPMI PMIC Arbiter object
-+ *
-+ * @base:		address of the PMIC Arbiter core registers.
-+ * @intr:		address of the SPMI interrupt control registers.
-+ * @cnfg:		address of the PMIC Arbiter configuration registers.
-+ * @lock:		lock to synchronize accesses.
-+ * @channel:		which channel to use for accesses.
-+ */
-+struct spmi_pmic_arb_dev {
-+	void __iomem		*base;
-+	void __iomem		*intr;
-+	void __iomem		*cnfg;
-+	raw_spinlock_t		lock;
-+	u8			channel;
-+};
-+
-+static inline u32 pmic_arb_base_read(struct spmi_pmic_arb_dev *dev, u32 offset)
-+{
-+	return readl_relaxed(dev->base + offset);
-+}
-+
-+static inline void pmic_arb_base_write(struct spmi_pmic_arb_dev *dev,
-+				       u32 offset, u32 val)
-+{
-+	writel_relaxed(val, dev->base + offset);
-+}
-+
-+/**
-+ * pa_read_data: reads pmic-arb's register and copy 1..4 bytes to buf
-+ * @bc:		byte count -1. range: 0..3
-+ * @reg:	register's address
-+ * @buf:	output parameter, length must be bc + 1
-+ */
-+static void pa_read_data(struct spmi_pmic_arb_dev *dev, u8 *buf, u32 reg, u8 bc)
-+{
-+	u32 data = pmic_arb_base_read(dev, reg);
-+	memcpy(buf, &data, (bc & 3) + 1);
-+}
-+
-+/**
-+ * pa_write_data: write 1..4 bytes from buf to pmic-arb's register
-+ * @bc:		byte-count -1. range: 0..3.
-+ * @reg:	register's address.
-+ * @buf:	buffer to write. length must be bc + 1.
-+ */
-+static void
-+pa_write_data(struct spmi_pmic_arb_dev *dev, const u8 *buf, u32 reg, u8 bc)
-+{
-+	u32 data = 0;
-+	memcpy(&data, buf, (bc & 3) + 1);
-+	pmic_arb_base_write(dev, reg, data);
-+}
-+
-+static int pmic_arb_wait_for_done(struct spmi_controller *ctrl)
-+{
-+	struct spmi_pmic_arb_dev *dev = spmi_controller_get_drvdata(ctrl);
-+	u32 status = 0;
-+	u32 timeout = PMIC_ARB_TIMEOUT_US;
-+	u32 offset = PMIC_ARB_STATUS(dev->channel);
-+
-+	while (timeout--) {
-+		status = pmic_arb_base_read(dev, offset);
-+
-+		if (status & PMIC_ARB_STATUS_DONE) {
-+			if (status & PMIC_ARB_STATUS_DENIED) {
-+				dev_err(&ctrl->dev,
-+					"%s: transaction denied (0x%x)\n",
-+					__func__, status);
-+				return -EPERM;
-+			}
-+
-+			if (status & PMIC_ARB_STATUS_FAILURE) {
-+				dev_err(&ctrl->dev,
-+					"%s: transaction failed (0x%x)\n",
-+					__func__, status);
-+				return -EIO;
-+			}
-+
-+			if (status & PMIC_ARB_STATUS_DROPPED) {
-+				dev_err(&ctrl->dev,
-+					"%s: transaction dropped (0x%x)\n",
-+					__func__, status);
-+				return -EIO;
-+			}
-+
-+			return 0;
-+		}
-+		udelay(1);
-+	}
-+
-+	dev_err(&ctrl->dev,
-+		"%s: timeout, status 0x%x\n",
-+		__func__, status);
-+	return -ETIMEDOUT;
-+}
-+
-+/* Non-data command */
-+static int pmic_arb_cmd(struct spmi_controller *ctrl, u8 opc, u8 sid)
-+{
-+	struct spmi_pmic_arb_dev *pmic_arb = spmi_controller_get_drvdata(ctrl);
-+	unsigned long flags;
-+	u32 cmd;
-+	int rc;
-+
-+	/* Check for valid non-data command */
-+	if (opc < SPMI_CMD_RESET || opc > SPMI_CMD_WAKEUP)
-+		return -EINVAL;
-+
-+	cmd = ((opc | 0x40) << 27) | ((sid & 0xf) << 20);
-+
-+	raw_spin_lock_irqsave(&pmic_arb->lock, flags);
-+	pmic_arb_base_write(pmic_arb, PMIC_ARB_CMD(pmic_arb->channel), cmd);
-+	rc = pmic_arb_wait_for_done(ctrl);
-+	raw_spin_unlock_irqrestore(&pmic_arb->lock, flags);
-+
-+	return rc;
-+}
-+
-+static int pmic_arb_read_cmd(struct spmi_controller *ctrl, u8 opc, u8 sid,
-+			     u16 addr, u8 *buf, size_t len)
-+{
-+	struct spmi_pmic_arb_dev *pmic_arb = spmi_controller_get_drvdata(ctrl);
-+	unsigned long flags;
-+	u8 bc = len - 1;
-+	u32 cmd;
-+	int rc;
-+
-+	if (bc >= PMIC_ARB_MAX_TRANS_BYTES) {
-+		dev_err(&ctrl->dev,
-+			"pmic-arb supports 1..%d bytes per trans, but %d requested",
-+			PMIC_ARB_MAX_TRANS_BYTES, len);
-+		return  -EINVAL;
-+	}
-+
-+	/* Check the opcode */
-+	if (opc >= 0x60 && opc <= 0x7F)
-+		opc = PMIC_ARB_OP_READ;
-+	else if (opc >= 0x20 && opc <= 0x2F)
-+		opc = PMIC_ARB_OP_EXT_READ;
-+	else if (opc >= 0x38 && opc <= 0x3F)
-+		opc = PMIC_ARB_OP_EXT_READL;
-+	else
-+		return -EINVAL;
-+
-+	cmd = (opc << 27) | ((sid & 0xf) << 20) | (addr << 4) | (bc & 0x7);
-+
-+	raw_spin_lock_irqsave(&pmic_arb->lock, flags);
-+	pmic_arb_base_write(pmic_arb, PMIC_ARB_CMD(pmic_arb->channel), cmd);
-+	rc = pmic_arb_wait_for_done(ctrl);
-+	if (rc)
-+		goto done;
-+
-+	pa_read_data(pmic_arb, buf, PMIC_ARB_RDATA0(pmic_arb->channel),
-+		     min_t(u8, bc, 3));
-+
-+	if (bc > 3)
-+		pa_read_data(pmic_arb, buf + 4,
-+				PMIC_ARB_RDATA1(pmic_arb->channel), bc - 4);
-+
-+done:
-+	raw_spin_unlock_irqrestore(&pmic_arb->lock, flags);
-+	return rc;
-+}
-+
-+static int pmic_arb_write_cmd(struct spmi_controller *ctrl, u8 opc, u8 sid,
-+			      u16 addr, const u8 *buf, size_t len)
-+{
-+	struct spmi_pmic_arb_dev *pmic_arb = spmi_controller_get_drvdata(ctrl);
-+	unsigned long flags;
-+	u8 bc = len - 1;
-+	u32 cmd;
-+	int rc;
-+
-+	if (bc >= PMIC_ARB_MAX_TRANS_BYTES) {
-+		dev_err(&ctrl->dev,
-+			"pmic-arb supports 1..%d bytes per trans, but:%d requested",
-+			PMIC_ARB_MAX_TRANS_BYTES, len);
-+		return  -EINVAL;
-+	}
-+
-+	/* Check the opcode */
-+	if (opc >= 0x40 && opc <= 0x5F)
-+		opc = PMIC_ARB_OP_WRITE;
-+	else if (opc >= 0x00 && opc <= 0x0F)
-+		opc = PMIC_ARB_OP_EXT_WRITE;
-+	else if (opc >= 0x30 && opc <= 0x37)
-+		opc = PMIC_ARB_OP_EXT_WRITEL;
-+	else if (opc >= 0x80 && opc <= 0xFF)
-+		opc = PMIC_ARB_OP_ZERO_WRITE;
-+	else
-+		return -EINVAL;
-+
-+	cmd = (opc << 27) | ((sid & 0xf) << 20) | (addr << 4) | (bc & 0x7);
-+
-+	/* Write data to FIFOs */
-+	raw_spin_lock_irqsave(&pmic_arb->lock, flags);
-+	pa_write_data(pmic_arb, buf, PMIC_ARB_WDATA0(pmic_arb->channel)
-+							, min_t(u8, bc, 3));
-+	if (bc > 3)
-+		pa_write_data(pmic_arb, buf + 4,
-+				PMIC_ARB_WDATA1(pmic_arb->channel), bc - 4);
-+
-+	/* Start the transaction */
-+	pmic_arb_base_write(pmic_arb, PMIC_ARB_CMD(pmic_arb->channel), cmd);
-+	rc = pmic_arb_wait_for_done(ctrl);
-+	raw_spin_unlock_irqrestore(&pmic_arb->lock, flags);
-+
-+	return rc;
-+}
-+
-+static int spmi_pmic_arb_probe(struct platform_device *pdev)
-+{
-+	struct spmi_pmic_arb_dev *pa;
-+	struct spmi_controller *ctrl;
-+	struct resource *res;
-+	u32 channel;
-+	int err, i;
-+
-+	ctrl = spmi_controller_alloc(&pdev->dev, sizeof(*pa));
-+	if (!ctrl)
-+		return -ENOMEM;
-+
-+	pa = spmi_controller_get_drvdata(ctrl);
-+
-+	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "core");
-+	pa->base = devm_ioremap_resource(&ctrl->dev, res);
-+	if (IS_ERR(pa->base)) {
-+		err = PTR_ERR(pa->base);
-+		goto err_put_ctrl;
-+	}
-+
-+	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "intr");
-+	pa->intr = devm_ioremap_resource(&ctrl->dev, res);
-+	if (IS_ERR(pa->intr)) {
-+		err = PTR_ERR(pa->intr);
-+		goto err_put_ctrl;
-+	}
-+
-+	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "cnfg");
-+	pa->cnfg = devm_ioremap_resource(&ctrl->dev, res);
-+	if (IS_ERR(pa->cnfg)) {
-+		err = PTR_ERR(pa->cnfg);
-+		goto err_put_ctrl;
-+	}
-+
-+	err = of_property_read_u32(pdev->dev.of_node, "qcom,channel", &channel);
-+	if (err) {
-+		dev_err(&pdev->dev, "channel unspecified.\n");
-+		goto err_put_ctrl;
-+	}
-+
-+	if (channel > 5) {
-+		dev_err(&pdev->dev, "invalid channel (%u) specified.\n",
-+			channel);
-+		goto err_put_ctrl;
-+	}
-+
-+	pa->channel = channel;
-+
-+	platform_set_drvdata(pdev, ctrl);
-+	raw_spin_lock_init(&pa->lock);
-+
-+	ctrl->cmd = pmic_arb_cmd;
-+	ctrl->read_cmd = pmic_arb_read_cmd;
-+	ctrl->write_cmd = pmic_arb_write_cmd;
-+
-+	err = spmi_controller_add(ctrl);
-+	if (err)
-+		goto err_put_ctrl;
-+
-+	dev_dbg(&ctrl->dev, "PMIC Arb Version 0x%x\n",
-+		pmic_arb_base_read(pa, PMIC_ARB_VERSION));
-+
-+	return 0;
-+
-+err_put_ctrl:
-+	spmi_controller_put(ctrl);
-+	return err;
-+}
-+
-+static int spmi_pmic_arb_remove(struct platform_device *pdev)
-+{
-+	struct spmi_controller *ctrl = platform_get_drvdata(pdev);
-+	spmi_controller_remove(ctrl);
-+	spmi_controller_put(ctrl);
-+	return 0;
-+}
-+
-+static const struct of_device_id spmi_pmic_arb_match_table[] = {
-+	{ .compatible = "qcom,spmi-pmic-arb", },
-+	{},
-+};
-+MODULE_DEVICE_TABLE(of, spmi_pmic_arb_match_table);
-+
-+static struct platform_driver spmi_pmic_arb_driver = {
-+	.probe		= spmi_pmic_arb_probe,
-+	.remove		= spmi_pmic_arb_remove,
-+	.driver		= {
-+		.name	= "spmi_pmic_arb",
-+		.owner	= THIS_MODULE,
-+		.of_match_table = spmi_pmic_arb_match_table,
-+	},
-+};
-+module_platform_driver(spmi_pmic_arb_driver);
-+
-+MODULE_LICENSE("GPL v2");
-+MODULE_ALIAS("platform:spmi_pmic_arb");
diff --git a/target/linux/ipq806x/patches/0057-spmi-pmic_arb-add-support-for-interrupt-handling.patch b/target/linux/ipq806x/patches/0057-spmi-pmic_arb-add-support-for-interrupt-handling.patch
deleted file mode 100644
index b1420b4..0000000
--- a/target/linux/ipq806x/patches/0057-spmi-pmic_arb-add-support-for-interrupt-handling.patch
+++ /dev/null
@@ -1,487 +0,0 @@
-From b5bc51d44485c7ce0ca180a8c5de11a206f686e8 Mon Sep 17 00:00:00 2001
-From: Josh Cartwright <joshc@codeaurora.org>
-Date: Wed, 12 Feb 2014 13:44:25 -0600
-Subject: [PATCH 057/182] spmi: pmic_arb: add support for interrupt handling
-
-The Qualcomm PMIC Arbiter, in addition to being a basic SPMI controller,
-also implements interrupt handling for slave devices.  Note, this is
-outside the scope of SPMI, as SPMI leaves interrupt handling completely
-unspecified.
-
-Extend the driver to provide a irq_chip implementation and chained irq
-handling which allows for these interrupts to be used.
-
-Cc: Thomas Gleixner <tglx@linutronix.de>
-Signed-off-by: Josh Cartwright <joshc@codeaurora.org>
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/spmi/Kconfig         |    1 +
- drivers/spmi/spmi-pmic-arb.c |  377 +++++++++++++++++++++++++++++++++++++++++-
- 2 files changed, 376 insertions(+), 2 deletions(-)
-
---- a/drivers/spmi/Kconfig
-+++ b/drivers/spmi/Kconfig
-@@ -13,6 +13,7 @@ if SPMI
- config SPMI_MSM_PMIC_ARB
- 	tristate "Qualcomm MSM SPMI Controller (PMIC Arbiter)"
- 	depends on ARM
-+	depends on IRQ_DOMAIN
- 	depends on ARCH_MSM || COMPILE_TEST
- 	default ARCH_MSM
- 	help
---- a/drivers/spmi/spmi-pmic-arb.c
-+++ b/drivers/spmi/spmi-pmic-arb.c
-@@ -13,6 +13,9 @@
- #include <linux/err.h>
- #include <linux/interrupt.h>
- #include <linux/io.h>
-+#include <linux/irqchip/chained_irq.h>
-+#include <linux/irqdomain.h>
-+#include <linux/irq.h>
- #include <linux/kernel.h>
- #include <linux/module.h>
- #include <linux/of.h>
-@@ -103,6 +106,14 @@ enum pmic_arb_cmd_op_code {
-  * @cnfg:		address of the PMIC Arbiter configuration registers.
-  * @lock:		lock to synchronize accesses.
-  * @channel:		which channel to use for accesses.
-+ * @irq:		PMIC ARB interrupt.
-+ * @ee:			the current Execution Environment
-+ * @min_apid:		minimum APID (used for bounding IRQ search)
-+ * @max_apid:		maximum APID
-+ * @mapping_table:	in-memory copy of PPID -> APID mapping table.
-+ * @domain:		irq domain object for PMIC IRQ domain
-+ * @spmic:		SPMI controller object
-+ * @apid_to_ppid:	cached mapping from APID to PPID
-  */
- struct spmi_pmic_arb_dev {
- 	void __iomem		*base;
-@@ -110,6 +121,14 @@ struct spmi_pmic_arb_dev {
- 	void __iomem		*cnfg;
- 	raw_spinlock_t		lock;
- 	u8			channel;
-+	int			irq;
-+	u8			ee;
-+	u8			min_apid;
-+	u8			max_apid;
-+	u32			mapping_table[SPMI_MAPPING_TABLE_LEN];
-+	struct irq_domain	*domain;
-+	struct spmi_controller	*spmic;
-+	u16			apid_to_ppid[256];
- };
- 
- static inline u32 pmic_arb_base_read(struct spmi_pmic_arb_dev *dev, u32 offset)
-@@ -306,12 +325,316 @@ static int pmic_arb_write_cmd(struct spm
- 	return rc;
- }
- 
-+enum qpnpint_regs {
-+	QPNPINT_REG_RT_STS		= 0x10,
-+	QPNPINT_REG_SET_TYPE		= 0x11,
-+	QPNPINT_REG_POLARITY_HIGH	= 0x12,
-+	QPNPINT_REG_POLARITY_LOW	= 0x13,
-+	QPNPINT_REG_LATCHED_CLR		= 0x14,
-+	QPNPINT_REG_EN_SET		= 0x15,
-+	QPNPINT_REG_EN_CLR		= 0x16,
-+	QPNPINT_REG_LATCHED_STS		= 0x18,
-+};
-+
-+struct spmi_pmic_arb_qpnpint_type {
-+	u8 type; /* 1 -> edge */
-+	u8 polarity_high;
-+	u8 polarity_low;
-+} __packed;
-+
-+/* Simplified accessor functions for irqchip callbacks */
-+static void qpnpint_spmi_write(struct irq_data *d, u8 reg, void *buf,
-+			       size_t len)
-+{
-+	struct spmi_pmic_arb_dev *pa = irq_data_get_irq_chip_data(d);
-+	u8 sid = d->hwirq >> 24;
-+	u8 per = d->hwirq >> 16;
-+
-+	if (pmic_arb_write_cmd(pa->spmic, SPMI_CMD_EXT_WRITEL, sid,
-+			       (per << 8) + reg, buf, len))
-+		dev_err_ratelimited(&pa->spmic->dev,
-+				"failed irqchip transaction on %x\n",
-+				    d->irq);
-+}
-+
-+static void qpnpint_spmi_read(struct irq_data *d, u8 reg, void *buf, size_t len)
-+{
-+	struct spmi_pmic_arb_dev *pa = irq_data_get_irq_chip_data(d);
-+	u8 sid = d->hwirq >> 24;
-+	u8 per = d->hwirq >> 16;
-+
-+	if (pmic_arb_read_cmd(pa->spmic, SPMI_CMD_EXT_READL, sid,
-+			      (per << 8) + reg, buf, len))
-+		dev_err_ratelimited(&pa->spmic->dev,
-+				"failed irqchip transaction on %x\n",
-+				    d->irq);
-+}
-+
-+static void periph_interrupt(struct spmi_pmic_arb_dev *pa, u8 apid)
-+{
-+	unsigned int irq;
-+	u32 status;
-+	int id;
-+
-+	status = readl_relaxed(pa->intr + SPMI_PIC_IRQ_STATUS(apid));
-+	while (status) {
-+		id = ffs(status) - 1;
-+		status &= ~(1 << id);
-+		irq = irq_find_mapping(pa->domain,
-+				       pa->apid_to_ppid[apid] << 16
-+				     | id << 8
-+				     | apid);
-+		generic_handle_irq(irq);
-+	}
-+}
-+
-+static void pmic_arb_chained_irq(unsigned int irq, struct irq_desc *desc)
-+{
-+	struct spmi_pmic_arb_dev *pa = irq_get_handler_data(irq);
-+	struct irq_chip *chip = irq_get_chip(irq);
-+	void __iomem *intr = pa->intr;
-+	int first = pa->min_apid >> 5;
-+	int last = pa->max_apid >> 5;
-+	u32 status;
-+	int i, id;
-+
-+	chained_irq_enter(chip, desc);
-+
-+	for (i = first; i <= last; ++i) {
-+		status = readl_relaxed(intr +
-+				       SPMI_PIC_OWNER_ACC_STATUS(pa->ee, i));
-+		while (status) {
-+			id = ffs(status) - 1;
-+			status &= ~(1 << id);
-+			periph_interrupt(pa, id + i * 32);
-+		}
-+	}
-+
-+	chained_irq_exit(chip, desc);
-+}
-+
-+static void qpnpint_irq_ack(struct irq_data *d)
-+{
-+	struct spmi_pmic_arb_dev *pa = irq_data_get_irq_chip_data(d);
-+	u8 irq  = d->hwirq >> 8;
-+	u8 apid = d->hwirq;
-+	unsigned long flags;
-+	u8 data;
-+
-+	raw_spin_lock_irqsave(&pa->lock, flags);
-+	writel_relaxed(1 << irq, pa->intr + SPMI_PIC_IRQ_CLEAR(apid));
-+	raw_spin_unlock_irqrestore(&pa->lock, flags);
-+
-+	data = 1 << irq;
-+	qpnpint_spmi_write(d, QPNPINT_REG_LATCHED_CLR, &data, 1);
-+}
-+
-+static void qpnpint_irq_mask(struct irq_data *d)
-+{
-+	struct spmi_pmic_arb_dev *pa = irq_data_get_irq_chip_data(d);
-+	u8 irq  = d->hwirq >> 8;
-+	u8 apid = d->hwirq;
-+	unsigned long flags;
-+	u32 status;
-+	u8 data;
-+
-+	raw_spin_lock_irqsave(&pa->lock, flags);
-+	status = readl_relaxed(pa->intr + SPMI_PIC_ACC_ENABLE(apid));
-+	if (status & SPMI_PIC_ACC_ENABLE_BIT) {
-+		status = status & ~SPMI_PIC_ACC_ENABLE_BIT;
-+		writel_relaxed(status, pa->intr + SPMI_PIC_ACC_ENABLE(apid));
-+	}
-+	raw_spin_unlock_irqrestore(&pa->lock, flags);
-+
-+	data = 1 << irq;
-+	qpnpint_spmi_write(d, QPNPINT_REG_EN_CLR, &data, 1);
-+}
-+
-+static void qpnpint_irq_unmask(struct irq_data *d)
-+{
-+	struct spmi_pmic_arb_dev *pa = irq_data_get_irq_chip_data(d);
-+	u8 irq  = d->hwirq >> 8;
-+	u8 apid = d->hwirq;
-+	unsigned long flags;
-+	u32 status;
-+	u8 data;
-+
-+	raw_spin_lock_irqsave(&pa->lock, flags);
-+	status = readl_relaxed(pa->intr + SPMI_PIC_ACC_ENABLE(apid));
-+	if (!(status & SPMI_PIC_ACC_ENABLE_BIT)) {
-+		writel_relaxed(status | SPMI_PIC_ACC_ENABLE_BIT,
-+				pa->intr + SPMI_PIC_ACC_ENABLE(apid));
-+	}
-+	raw_spin_unlock_irqrestore(&pa->lock, flags);
-+
-+	data = 1 << irq;
-+	qpnpint_spmi_write(d, QPNPINT_REG_EN_SET, &data, 1);
-+}
-+
-+static void qpnpint_irq_enable(struct irq_data *d)
-+{
-+	u8 irq  = d->hwirq >> 8;
-+	u8 data;
-+
-+	qpnpint_irq_unmask(d);
-+
-+	data = 1 << irq;
-+	qpnpint_spmi_write(d, QPNPINT_REG_LATCHED_CLR, &data, 1);
-+}
-+
-+static int qpnpint_irq_set_type(struct irq_data *d, unsigned int flow_type)
-+{
-+	struct spmi_pmic_arb_qpnpint_type type;
-+	u8 irq = d->hwirq >> 8;
-+
-+	qpnpint_spmi_read(d, QPNPINT_REG_SET_TYPE, &type, sizeof(type));
-+
-+	if (flow_type & (IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING)) {
-+		type.type |= 1 << irq;
-+		if (flow_type & IRQF_TRIGGER_RISING)
-+			type.polarity_high |= 1 << irq;
-+		if (flow_type & IRQF_TRIGGER_FALLING)
-+			type.polarity_low  |= 1 << irq;
-+	} else {
-+		if ((flow_type & (IRQF_TRIGGER_HIGH)) &&
-+		    (flow_type & (IRQF_TRIGGER_LOW)))
-+			return -EINVAL;
-+
-+		type.type &= ~(1 << irq); /* level trig */
-+		if (flow_type & IRQF_TRIGGER_HIGH)
-+			type.polarity_high |= 1 << irq;
-+		else
-+			type.polarity_low  |= 1 << irq;
-+	}
-+
-+	qpnpint_spmi_write(d, QPNPINT_REG_SET_TYPE, &type, sizeof(type));
-+	return 0;
-+}
-+
-+static struct irq_chip pmic_arb_irqchip = {
-+	.name		= "pmic_arb",
-+	.irq_enable	= qpnpint_irq_enable,
-+	.irq_ack	= qpnpint_irq_ack,
-+	.irq_mask	= qpnpint_irq_mask,
-+	.irq_unmask	= qpnpint_irq_unmask,
-+	.irq_set_type	= qpnpint_irq_set_type,
-+	.flags		= IRQCHIP_MASK_ON_SUSPEND
-+			| IRQCHIP_SKIP_SET_WAKE,
-+};
-+
-+struct spmi_pmic_arb_irq_spec {
-+	unsigned slave:4;
-+	unsigned per:8;
-+	unsigned irq:3;
-+};
-+
-+static int search_mapping_table(struct spmi_pmic_arb_dev *pa,
-+				struct spmi_pmic_arb_irq_spec *spec,
-+				u8 *apid)
-+{
-+	u16 ppid = spec->slave << 8 | spec->per;
-+	u32 *mapping_table = pa->mapping_table;
-+	int index = 0, i;
-+	u32 data;
-+
-+	for (i = 0; i < SPMI_MAPPING_TABLE_TREE_DEPTH; ++i) {
-+		data = mapping_table[index];
-+
-+		if (ppid & (1 << SPMI_MAPPING_BIT_INDEX(data))) {
-+			if (SPMI_MAPPING_BIT_IS_1_FLAG(data)) {
-+				index = SPMI_MAPPING_BIT_IS_1_RESULT(data);
-+			} else {
-+				*apid = SPMI_MAPPING_BIT_IS_1_RESULT(data);
-+				return 0;
-+			}
-+		} else {
-+			if (SPMI_MAPPING_BIT_IS_0_FLAG(data)) {
-+				index = SPMI_MAPPING_BIT_IS_0_RESULT(data);
-+			} else {
-+				*apid = SPMI_MAPPING_BIT_IS_0_RESULT(data);
-+				return 0;
-+			}
-+		}
-+	}
-+
-+	return -ENODEV;
-+}
-+
-+static int qpnpint_irq_domain_dt_translate(struct irq_domain *d,
-+					   struct device_node *controller,
-+					   const u32 *intspec,
-+					   unsigned int intsize,
-+					   unsigned long *out_hwirq,
-+					   unsigned int *out_type)
-+{
-+	struct spmi_pmic_arb_dev *pa = d->host_data;
-+	struct spmi_pmic_arb_irq_spec spec;
-+	int err;
-+	u8 apid;
-+
-+	dev_dbg(&pa->spmic->dev,
-+		"intspec[0] 0x%1x intspec[1] 0x%02x intspec[2] 0x%02x\n",
-+		intspec[0], intspec[1], intspec[2]);
-+
-+	if (d->of_node != controller)
-+		return -EINVAL;
-+	if (intsize != 4)
-+		return -EINVAL;
-+	if (intspec[0] > 0xF || intspec[1] > 0xFF || intspec[2] > 0x7)
-+		return -EINVAL;
-+
-+	spec.slave = intspec[0];
-+	spec.per   = intspec[1];
-+	spec.irq   = intspec[2];
-+
-+	err = search_mapping_table(pa, &spec, &apid);
-+	if (err)
-+		return err;
-+
-+	pa->apid_to_ppid[apid] = spec.slave << 8 | spec.per;
-+
-+	/* Keep track of {max,min}_apid for bounding search during interrupt */
-+	if (apid > pa->max_apid)
-+		pa->max_apid = apid;
-+	if (apid < pa->min_apid)
-+		pa->min_apid = apid;
-+
-+	*out_hwirq = spec.slave << 24
-+		   | spec.per   << 16
-+		   | spec.irq   << 8
-+		   | apid;
-+	*out_type  = intspec[3] & IRQ_TYPE_SENSE_MASK;
-+
-+	dev_dbg(&pa->spmic->dev, "out_hwirq = %lu\n", *out_hwirq);
-+
-+	return 0;
-+}
-+
-+static int qpnpint_irq_domain_map(struct irq_domain *d,
-+				  unsigned int virq,
-+				  irq_hw_number_t hwirq)
-+{
-+	struct spmi_pmic_arb_dev *pa = d->host_data;
-+
-+	dev_dbg(&pa->spmic->dev, "virq = %u, hwirq = %lu\n", virq, hwirq);
-+
-+	irq_set_chip_and_handler(virq, &pmic_arb_irqchip, handle_level_irq);
-+	irq_set_chip_data(virq, d->host_data);
-+	irq_set_noprobe(virq);
-+	return 0;
-+}
-+
-+static const struct irq_domain_ops pmic_arb_irq_domain_ops = {
-+	.map	= qpnpint_irq_domain_map,
-+	.xlate	= qpnpint_irq_domain_dt_translate,
-+};
-+
- static int spmi_pmic_arb_probe(struct platform_device *pdev)
- {
- 	struct spmi_pmic_arb_dev *pa;
- 	struct spmi_controller *ctrl;
- 	struct resource *res;
--	u32 channel;
-+	u32 channel, ee;
- 	int err, i;
- 
- 	ctrl = spmi_controller_alloc(&pdev->dev, sizeof(*pa));
-@@ -319,6 +642,7 @@ static int spmi_pmic_arb_probe(struct pl
- 		return -ENOMEM;
- 
- 	pa = spmi_controller_get_drvdata(ctrl);
-+	pa->spmic = ctrl;
- 
- 	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "core");
- 	pa->base = devm_ioremap_resource(&ctrl->dev, res);
-@@ -341,6 +665,12 @@ static int spmi_pmic_arb_probe(struct pl
- 		goto err_put_ctrl;
- 	}
- 
-+	pa->irq = platform_get_irq_byname(pdev, "periph_irq");
-+	if (pa->irq < 0) {
-+		err = pa->irq;
-+		goto err_put_ctrl;
-+	}
-+
- 	err = of_property_read_u32(pdev->dev.of_node, "qcom,channel", &channel);
- 	if (err) {
- 		dev_err(&pdev->dev, "channel unspecified.\n");
-@@ -355,6 +685,29 @@ static int spmi_pmic_arb_probe(struct pl
- 
- 	pa->channel = channel;
- 
-+	err = of_property_read_u32(pdev->dev.of_node, "qcom,ee", &ee);
-+	if (err) {
-+		dev_err(&pdev->dev, "EE unspecified.\n");
-+		goto err_put_ctrl;
-+	}
-+
-+	if (ee > 5) {
-+		dev_err(&pdev->dev, "invalid EE (%u) specified\n", ee);
-+		err = -EINVAL;
-+		goto err_put_ctrl;
-+	}
-+
-+	pa->ee = ee;
-+
-+	for (i = 0; i < ARRAY_SIZE(pa->mapping_table); ++i)
-+		pa->mapping_table[i] = readl_relaxed(
-+				pa->cnfg + SPMI_MAPPING_TABLE_REG(i));
-+
-+	/* Initialize max_apid/min_apid to the opposite bounds, during
-+	 * the irq domain translation, we are sure to update these */
-+	pa->max_apid = 0;
-+	pa->min_apid = PMIC_ARB_MAX_PERIPHS - 1;
-+
- 	platform_set_drvdata(pdev, ctrl);
- 	raw_spin_lock_init(&pa->lock);
- 
-@@ -362,15 +715,31 @@ static int spmi_pmic_arb_probe(struct pl
- 	ctrl->read_cmd = pmic_arb_read_cmd;
- 	ctrl->write_cmd = pmic_arb_write_cmd;
- 
-+	dev_dbg(&pdev->dev, "adding irq domain\n");
-+	pa->domain = irq_domain_add_tree(pdev->dev.of_node,
-+					 &pmic_arb_irq_domain_ops, pa);
-+	if (!pa->domain) {
-+		dev_err(&pdev->dev, "unable to create irq_domain\n");
-+		err = -ENOMEM;
-+		goto err_put_ctrl;
-+	}
-+
-+	irq_set_handler_data(pa->irq, pa);
-+	irq_set_chained_handler(pa->irq, pmic_arb_chained_irq);
-+
- 	err = spmi_controller_add(ctrl);
- 	if (err)
--		goto err_put_ctrl;
-+		goto err_domain_remove;
- 
- 	dev_dbg(&ctrl->dev, "PMIC Arb Version 0x%x\n",
- 		pmic_arb_base_read(pa, PMIC_ARB_VERSION));
- 
- 	return 0;
- 
-+err_domain_remove:
-+	irq_set_chained_handler(pa->irq, NULL);
-+	irq_set_handler_data(pa->irq, NULL);
-+	irq_domain_remove(pa->domain);
- err_put_ctrl:
- 	spmi_controller_put(ctrl);
- 	return err;
-@@ -379,7 +748,11 @@ err_put_ctrl:
- static int spmi_pmic_arb_remove(struct platform_device *pdev)
- {
- 	struct spmi_controller *ctrl = platform_get_drvdata(pdev);
-+	struct spmi_pmic_arb_dev *pa = spmi_controller_get_drvdata(ctrl);
- 	spmi_controller_remove(ctrl);
-+	irq_set_chained_handler(pa->irq, NULL);
-+	irq_set_handler_data(pa->irq, NULL);
-+	irq_domain_remove(pa->domain);
- 	spmi_controller_put(ctrl);
- 	return 0;
- }
diff --git a/target/linux/ipq806x/patches/0058-spmi-pmic_arb-make-selectable-on-ARCH_QCOM.patch b/target/linux/ipq806x/patches/0058-spmi-pmic_arb-make-selectable-on-ARCH_QCOM.patch
deleted file mode 100644
index 0df3780..0000000
--- a/target/linux/ipq806x/patches/0058-spmi-pmic_arb-make-selectable-on-ARCH_QCOM.patch
+++ /dev/null
@@ -1,29 +0,0 @@
-From 840fe915072597b5ba9599c4579f014f47b9638e Mon Sep 17 00:00:00 2001
-From: Josh Cartwright <joshc@codeaurora.org>
-Date: Mon, 3 Mar 2014 10:49:43 -0600
-Subject: [PATCH 058/182] spmi: pmic_arb: make selectable on ARCH_QCOM
-
-With the split of Qualcomm MSM support into legacy and multiplatform,
-the SPMI PMIC arb driver is only relevant on the multiplatform supported
-SoCs. Switch the Kconfig depends to ARCH_QCOM.
-
-Acked-by: Kumar Gala <galak@codeaurora.org>
-Signed-off-by: Josh Cartwright <joshc@codeaurora.org>
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/spmi/Kconfig |    4 ++--
- 1 file changed, 2 insertions(+), 2 deletions(-)
-
---- a/drivers/spmi/Kconfig
-+++ b/drivers/spmi/Kconfig
-@@ -14,8 +14,8 @@ config SPMI_MSM_PMIC_ARB
- 	tristate "Qualcomm MSM SPMI Controller (PMIC Arbiter)"
- 	depends on ARM
- 	depends on IRQ_DOMAIN
--	depends on ARCH_MSM || COMPILE_TEST
--	default ARCH_MSM
-+	depends on ARCH_QCOM || COMPILE_TEST
-+	default ARCH_QCOM
- 	help
- 	  If you say yes to this option, support will be included for the
- 	  built-in SPMI PMIC Arbiter interface on Qualcomm MSM family
diff --git a/target/linux/ipq806x/patches/0059-spmi-pm-drop-bus-level-PM-suspend-resume-routines.patch b/target/linux/ipq806x/patches/0059-spmi-pm-drop-bus-level-PM-suspend-resume-routines.patch
deleted file mode 100644
index b8bb48c..0000000
--- a/target/linux/ipq806x/patches/0059-spmi-pm-drop-bus-level-PM-suspend-resume-routines.patch
+++ /dev/null
@@ -1,69 +0,0 @@
-From 9d13f01e2ec45253adaae1a330cdc4eb881c7377 Mon Sep 17 00:00:00 2001
-From: Josh Cartwright <joshc@codeaurora.org>
-Date: Mon, 3 Mar 2014 10:49:44 -0600
-Subject: [PATCH 059/182] spmi: pm: drop bus-level PM suspend/resume routines
-
-SPMI defines the behavior of a device in the "SLEEP" state as being
-"user-defined or specified by the device manufacturer".  Without
-clearly-defined bus-level semantics for low-power states, push the
-responsibility of transitioning a device into/out of "SLEEP" into SPMI
-device drivers.
-
-Cc: Felipe Balbi <balbi@ti.com>
-Signed-off-by: Josh Cartwright <joshc@codeaurora.org>
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/spmi/spmi.c |   35 -----------------------------------
- 1 file changed, 35 deletions(-)
-
---- a/drivers/spmi/spmi.c
-+++ b/drivers/spmi/spmi.c
-@@ -46,40 +46,6 @@ static const struct device_type spmi_ctr
- 	.release	= spmi_ctrl_release,
- };
- 
--#ifdef CONFIG_PM_RUNTIME
--static int spmi_runtime_suspend(struct device *dev)
--{
--	struct spmi_device *sdev = to_spmi_device(dev);
--	int err;
--
--	err = pm_generic_runtime_suspend(dev);
--	if (err)
--		return err;
--
--	return spmi_command_sleep(sdev);
--}
--
--static int spmi_runtime_resume(struct device *dev)
--{
--	struct spmi_device *sdev = to_spmi_device(dev);
--	int err;
--
--	err = spmi_command_wakeup(sdev);
--	if (err)
--		return err;
--
--	return pm_generic_runtime_resume(dev);
--}
--#endif
--
--static const struct dev_pm_ops spmi_pm_ops = {
--	SET_RUNTIME_PM_OPS(
--		spmi_runtime_suspend,
--		spmi_runtime_resume,
--		NULL
--	)
--};
--
- static int spmi_device_match(struct device *dev, struct device_driver *drv)
- {
- 	if (of_driver_match_device(dev, drv))
-@@ -391,7 +357,6 @@ static int spmi_drv_remove(struct device
- static struct bus_type spmi_bus_type = {
- 	.name		= "spmi",
- 	.match		= spmi_device_match,
--	.pm		= &spmi_pm_ops,
- 	.probe		= spmi_drv_probe,
- 	.remove		= spmi_drv_remove,
- };
diff --git a/target/linux/ipq806x/patches/0060-i2c-qup-New-bus-driver-for-the-Qualcomm-QUP-I2C-cont.patch b/target/linux/ipq806x/patches/0060-i2c-qup-New-bus-driver-for-the-Qualcomm-QUP-I2C-cont.patch
deleted file mode 100644
index c96fc15..0000000
--- a/target/linux/ipq806x/patches/0060-i2c-qup-New-bus-driver-for-the-Qualcomm-QUP-I2C-cont.patch
+++ /dev/null
@@ -1,825 +0,0 @@
-From 226eff10dc11af5d6b1bc31e5cedc079aa564fb3 Mon Sep 17 00:00:00 2001
-From: Bjorn Andersson <bjorn.andersson@sonymobile.com>
-Date: Thu, 13 Mar 2014 19:07:43 -0700
-Subject: [PATCH 060/182] i2c: qup: New bus driver for the Qualcomm QUP I2C
- controller
-
-This bus driver supports the QUP i2c hardware controller in the Qualcomm SOCs.
-The Qualcomm Universal Peripheral Engine (QUP) is a general purpose data path
-engine with input/output FIFOs and an embedded i2c mini-core. The driver
-supports FIFO mode (for low bandwidth applications) and block mode (interrupt
-generated for each block-size data transfer).
-
-Signed-off-by: Ivan T. Ivanov <iivanov@mm-sol.com>
-Signed-off-by: Bjorn Andersson <bjorn.andersson@sonymobile.com>
-Reviewed-by: Andy Gross <agross@codeaurora.org>
-Tested-by: Philip Elcan <pelcan@codeaurora.org>
-[wsa: removed needless IS_ERR_VALUE]
-Signed-off-by: Wolfram Sang <wsa@the-dreams.de>
----
- drivers/i2c/busses/Kconfig   |   10 +
- drivers/i2c/busses/Makefile  |    1 +
- drivers/i2c/busses/i2c-qup.c |  768 ++++++++++++++++++++++++++++++++++++++++++
- 3 files changed, 779 insertions(+)
- create mode 100644 drivers/i2c/busses/i2c-qup.c
-
---- a/drivers/i2c/busses/Kconfig
-+++ b/drivers/i2c/busses/Kconfig
-@@ -649,6 +649,16 @@ config I2C_PXA_SLAVE
- 	  is necessary for systems where the PXA may be a target on the
- 	  I2C bus.
- 
-+config I2C_QUP
-+	tristate "Qualcomm QUP based I2C controller"
-+	depends on ARCH_QCOM
-+	help
-+	  If you say yes to this option, support will be included for the
-+	  built-in I2C interface on the Qualcomm SoCs.
-+
-+	  This driver can also be built as a module.  If so, the module
-+	  will be called i2c-qup.
-+
- config I2C_RIIC
- 	tristate "Renesas RIIC adapter"
- 	depends on ARCH_SHMOBILE || COMPILE_TEST
---- a/drivers/i2c/busses/Makefile
-+++ b/drivers/i2c/busses/Makefile
-@@ -63,6 +63,7 @@ obj-$(CONFIG_I2C_PNX)		+= i2c-pnx.o
- obj-$(CONFIG_I2C_PUV3)		+= i2c-puv3.o
- obj-$(CONFIG_I2C_PXA)		+= i2c-pxa.o
- obj-$(CONFIG_I2C_PXA_PCI)	+= i2c-pxa-pci.o
-+obj-$(CONFIG_I2C_QUP)		+= i2c-qup.o
- obj-$(CONFIG_I2C_RIIC)		+= i2c-riic.o
- obj-$(CONFIG_I2C_S3C2410)	+= i2c-s3c2410.o
- obj-$(CONFIG_I2C_S6000)		+= i2c-s6000.o
---- /dev/null
-+++ b/drivers/i2c/busses/i2c-qup.c
-@@ -0,0 +1,768 @@
-+/*
-+ * Copyright (c) 2009-2013, The Linux Foundation. All rights reserved.
-+ * Copyright (c) 2014, Sony Mobile Communications AB.
-+ *
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 and
-+ * only version 2 as published by the Free Software Foundation.
-+ *
-+ * 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/delay.h>
-+#include <linux/err.h>
-+#include <linux/i2c.h>
-+#include <linux/interrupt.h>
-+#include <linux/io.h>
-+#include <linux/module.h>
-+#include <linux/of.h>
-+#include <linux/platform_device.h>
-+#include <linux/pm_runtime.h>
-+
-+/* QUP Registers */
-+#define QUP_CONFIG		0x000
-+#define QUP_STATE		0x004
-+#define QUP_IO_MODE		0x008
-+#define QUP_SW_RESET		0x00c
-+#define QUP_OPERATIONAL		0x018
-+#define QUP_ERROR_FLAGS		0x01c
-+#define QUP_ERROR_FLAGS_EN	0x020
-+#define QUP_HW_VERSION		0x030
-+#define QUP_MX_OUTPUT_CNT	0x100
-+#define QUP_OUT_FIFO_BASE	0x110
-+#define QUP_MX_WRITE_CNT	0x150
-+#define QUP_MX_INPUT_CNT	0x200
-+#define QUP_MX_READ_CNT		0x208
-+#define QUP_IN_FIFO_BASE	0x218
-+#define QUP_I2C_CLK_CTL		0x400
-+#define QUP_I2C_STATUS		0x404
-+
-+/* QUP States and reset values */
-+#define QUP_RESET_STATE		0
-+#define QUP_RUN_STATE		1
-+#define QUP_PAUSE_STATE		3
-+#define QUP_STATE_MASK		3
-+
-+#define QUP_STATE_VALID		BIT(2)
-+#define QUP_I2C_MAST_GEN	BIT(4)
-+
-+#define QUP_OPERATIONAL_RESET	0x000ff0
-+#define QUP_I2C_STATUS_RESET	0xfffffc
-+
-+/* QUP OPERATIONAL FLAGS */
-+#define QUP_I2C_NACK_FLAG	BIT(3)
-+#define QUP_OUT_NOT_EMPTY	BIT(4)
-+#define QUP_IN_NOT_EMPTY	BIT(5)
-+#define QUP_OUT_FULL		BIT(6)
-+#define QUP_OUT_SVC_FLAG	BIT(8)
-+#define QUP_IN_SVC_FLAG		BIT(9)
-+#define QUP_MX_OUTPUT_DONE	BIT(10)
-+#define QUP_MX_INPUT_DONE	BIT(11)
-+
-+/* I2C mini core related values */
-+#define QUP_CLOCK_AUTO_GATE	BIT(13)
-+#define I2C_MINI_CORE		(2 << 8)
-+#define I2C_N_VAL		15
-+/* Most significant word offset in FIFO port */
-+#define QUP_MSW_SHIFT		(I2C_N_VAL + 1)
-+
-+/* Packing/Unpacking words in FIFOs, and IO modes */
-+#define QUP_OUTPUT_BLK_MODE	(1 << 10)
-+#define QUP_INPUT_BLK_MODE	(1 << 12)
-+#define QUP_UNPACK_EN		BIT(14)
-+#define QUP_PACK_EN		BIT(15)
-+
-+#define QUP_REPACK_EN		(QUP_UNPACK_EN | QUP_PACK_EN)
-+
-+#define QUP_OUTPUT_BLOCK_SIZE(x)(((x) >> 0) & 0x03)
-+#define QUP_OUTPUT_FIFO_SIZE(x)	(((x) >> 2) & 0x07)
-+#define QUP_INPUT_BLOCK_SIZE(x)	(((x) >> 5) & 0x03)
-+#define QUP_INPUT_FIFO_SIZE(x)	(((x) >> 7) & 0x07)
-+
-+/* QUP tags */
-+#define QUP_TAG_START		(1 << 8)
-+#define QUP_TAG_DATA		(2 << 8)
-+#define QUP_TAG_STOP		(3 << 8)
-+#define QUP_TAG_REC		(4 << 8)
-+
-+/* Status, Error flags */
-+#define I2C_STATUS_WR_BUFFER_FULL	BIT(0)
-+#define I2C_STATUS_BUS_ACTIVE		BIT(8)
-+#define I2C_STATUS_ERROR_MASK		0x38000fc
-+#define QUP_STATUS_ERROR_FLAGS		0x7c
-+
-+#define QUP_READ_LIMIT			256
-+
-+struct qup_i2c_dev {
-+	struct device		*dev;
-+	void __iomem		*base;
-+	int			irq;
-+	struct clk		*clk;
-+	struct clk		*pclk;
-+	struct i2c_adapter	adap;
-+
-+	int			clk_ctl;
-+	int			out_fifo_sz;
-+	int			in_fifo_sz;
-+	int			out_blk_sz;
-+	int			in_blk_sz;
-+
-+	unsigned long		one_byte_t;
-+
-+	struct i2c_msg		*msg;
-+	/* Current posion in user message buffer */
-+	int			pos;
-+	/* I2C protocol errors */
-+	u32			bus_err;
-+	/* QUP core errors */
-+	u32			qup_err;
-+
-+	struct completion	xfer;
-+};
-+
-+static irqreturn_t qup_i2c_interrupt(int irq, void *dev)
-+{
-+	struct qup_i2c_dev *qup = dev;
-+	u32 bus_err;
-+	u32 qup_err;
-+	u32 opflags;
-+
-+	bus_err = readl(qup->base + QUP_I2C_STATUS);
-+	qup_err = readl(qup->base + QUP_ERROR_FLAGS);
-+	opflags = readl(qup->base + QUP_OPERATIONAL);
-+
-+	if (!qup->msg) {
-+		/* Clear Error interrupt */
-+		writel(QUP_RESET_STATE, qup->base + QUP_STATE);
-+		return IRQ_HANDLED;
-+	}
-+
-+	bus_err &= I2C_STATUS_ERROR_MASK;
-+	qup_err &= QUP_STATUS_ERROR_FLAGS;
-+
-+	if (qup_err) {
-+		/* Clear Error interrupt */
-+		writel(qup_err, qup->base + QUP_ERROR_FLAGS);
-+		goto done;
-+	}
-+
-+	if (bus_err) {
-+		/* Clear Error interrupt */
-+		writel(QUP_RESET_STATE, qup->base + QUP_STATE);
-+		goto done;
-+	}
-+
-+	if (opflags & QUP_IN_SVC_FLAG)
-+		writel(QUP_IN_SVC_FLAG, qup->base + QUP_OPERATIONAL);
-+
-+	if (opflags & QUP_OUT_SVC_FLAG)
-+		writel(QUP_OUT_SVC_FLAG, qup->base + QUP_OPERATIONAL);
-+
-+done:
-+	qup->qup_err = qup_err;
-+	qup->bus_err = bus_err;
-+	complete(&qup->xfer);
-+	return IRQ_HANDLED;
-+}
-+
-+static int qup_i2c_poll_state_mask(struct qup_i2c_dev *qup,
-+				   u32 req_state, u32 req_mask)
-+{
-+	int retries = 1;
-+	u32 state;
-+
-+	/*
-+	 * State transition takes 3 AHB clocks cycles + 3 I2C master clock
-+	 * cycles. So retry once after a 1uS delay.
-+	 */
-+	do {
-+		state = readl(qup->base + QUP_STATE);
-+
-+		if (state & QUP_STATE_VALID &&
-+		    (state & req_mask) == req_state)
-+			return 0;
-+
-+		udelay(1);
-+	} while (retries--);
-+
-+	return -ETIMEDOUT;
-+}
-+
-+static int qup_i2c_poll_state(struct qup_i2c_dev *qup, u32 req_state)
-+{
-+	return qup_i2c_poll_state_mask(qup, req_state, QUP_STATE_MASK);
-+}
-+
-+static int qup_i2c_poll_state_valid(struct qup_i2c_dev *qup)
-+{
-+	return qup_i2c_poll_state_mask(qup, 0, 0);
-+}
-+
-+static int qup_i2c_poll_state_i2c_master(struct qup_i2c_dev *qup)
-+{
-+	return qup_i2c_poll_state_mask(qup, QUP_I2C_MAST_GEN, QUP_I2C_MAST_GEN);
-+}
-+
-+static int qup_i2c_change_state(struct qup_i2c_dev *qup, u32 state)
-+{
-+	if (qup_i2c_poll_state_valid(qup) != 0)
-+		return -EIO;
-+
-+	writel(state, qup->base + QUP_STATE);
-+
-+	if (qup_i2c_poll_state(qup, state) != 0)
-+		return -EIO;
-+	return 0;
-+}
-+
-+static int qup_i2c_wait_writeready(struct qup_i2c_dev *qup)
-+{
-+	unsigned long timeout;
-+	u32 opflags;
-+	u32 status;
-+
-+	timeout = jiffies + HZ;
-+
-+	for (;;) {
-+		opflags = readl(qup->base + QUP_OPERATIONAL);
-+		status = readl(qup->base + QUP_I2C_STATUS);
-+
-+		if (!(opflags & QUP_OUT_NOT_EMPTY) &&
-+		    !(status & I2C_STATUS_BUS_ACTIVE))
-+			return 0;
-+
-+		if (time_after(jiffies, timeout))
-+			return -ETIMEDOUT;
-+
-+		usleep_range(qup->one_byte_t, qup->one_byte_t * 2);
-+	}
-+}
-+
-+static void qup_i2c_set_write_mode(struct qup_i2c_dev *qup, struct i2c_msg *msg)
-+{
-+	/* Number of entries to shift out, including the start */
-+	int total = msg->len + 1;
-+
-+	if (total < qup->out_fifo_sz) {
-+		/* FIFO mode */
-+		writel(QUP_REPACK_EN, qup->base + QUP_IO_MODE);
-+		writel(total, qup->base + QUP_MX_WRITE_CNT);
-+	} else {
-+		/* BLOCK mode (transfer data on chunks) */
-+		writel(QUP_OUTPUT_BLK_MODE | QUP_REPACK_EN,
-+		       qup->base + QUP_IO_MODE);
-+		writel(total, qup->base + QUP_MX_OUTPUT_CNT);
-+	}
-+}
-+
-+static void qup_i2c_issue_write(struct qup_i2c_dev *qup, struct i2c_msg *msg)
-+{
-+	u32 addr = msg->addr << 1;
-+	u32 qup_tag;
-+	u32 opflags;
-+	int idx;
-+	u32 val;
-+
-+	if (qup->pos == 0) {
-+		val = QUP_TAG_START | addr;
-+		idx = 1;
-+	} else {
-+		val = 0;
-+		idx = 0;
-+	}
-+
-+	while (qup->pos < msg->len) {
-+		/* Check that there's space in the FIFO for our pair */
-+		opflags = readl(qup->base + QUP_OPERATIONAL);
-+		if (opflags & QUP_OUT_FULL)
-+			break;
-+
-+		if (qup->pos == msg->len - 1)
-+			qup_tag = QUP_TAG_STOP;
-+		else
-+			qup_tag = QUP_TAG_DATA;
-+
-+		if (idx & 1)
-+			val |= (qup_tag | msg->buf[qup->pos]) << QUP_MSW_SHIFT;
-+		else
-+			val = qup_tag | msg->buf[qup->pos];
-+
-+		/* Write out the pair and the last odd value */
-+		if (idx & 1 || qup->pos == msg->len - 1)
-+			writel(val, qup->base + QUP_OUT_FIFO_BASE);
-+
-+		qup->pos++;
-+		idx++;
-+	}
-+}
-+
-+static int qup_i2c_write_one(struct qup_i2c_dev *qup, struct i2c_msg *msg)
-+{
-+	unsigned long left;
-+	int ret;
-+
-+	qup->msg = msg;
-+	qup->pos = 0;
-+
-+	enable_irq(qup->irq);
-+
-+	qup_i2c_set_write_mode(qup, msg);
-+
-+	ret = qup_i2c_change_state(qup, QUP_RUN_STATE);
-+	if (ret)
-+		goto err;
-+
-+	writel(qup->clk_ctl, qup->base + QUP_I2C_CLK_CTL);
-+
-+	do {
-+		ret = qup_i2c_change_state(qup, QUP_PAUSE_STATE);
-+		if (ret)
-+			goto err;
-+
-+		qup_i2c_issue_write(qup, msg);
-+
-+		ret = qup_i2c_change_state(qup, QUP_RUN_STATE);
-+		if (ret)
-+			goto err;
-+
-+		left = wait_for_completion_timeout(&qup->xfer, HZ);
-+		if (!left) {
-+			writel(1, qup->base + QUP_SW_RESET);
-+			ret = -ETIMEDOUT;
-+			goto err;
-+		}
-+
-+		if (qup->bus_err || qup->qup_err) {
-+			if (qup->bus_err & QUP_I2C_NACK_FLAG)
-+				dev_err(qup->dev, "NACK from %x\n", msg->addr);
-+			ret = -EIO;
-+			goto err;
-+		}
-+	} while (qup->pos < msg->len);
-+
-+	/* Wait for the outstanding data in the fifo to drain */
-+	ret = qup_i2c_wait_writeready(qup);
-+
-+err:
-+	disable_irq(qup->irq);
-+	qup->msg = NULL;
-+
-+	return ret;
-+}
-+
-+static void qup_i2c_set_read_mode(struct qup_i2c_dev *qup, int len)
-+{
-+	if (len < qup->in_fifo_sz) {
-+		/* FIFO mode */
-+		writel(QUP_REPACK_EN, qup->base + QUP_IO_MODE);
-+		writel(len, qup->base + QUP_MX_READ_CNT);
-+	} else {
-+		/* BLOCK mode (transfer data on chunks) */
-+		writel(QUP_INPUT_BLK_MODE | QUP_REPACK_EN,
-+		       qup->base + QUP_IO_MODE);
-+		writel(len, qup->base + QUP_MX_INPUT_CNT);
-+	}
-+}
-+
-+static void qup_i2c_issue_read(struct qup_i2c_dev *qup, struct i2c_msg *msg)
-+{
-+	u32 addr, len, val;
-+
-+	addr = (msg->addr << 1) | 1;
-+
-+	/* 0 is used to specify a length 256 (QUP_READ_LIMIT) */
-+	len = (msg->len == QUP_READ_LIMIT) ? 0 : msg->len;
-+
-+	val = ((QUP_TAG_REC | len) << QUP_MSW_SHIFT) | QUP_TAG_START | addr;
-+	writel(val, qup->base + QUP_OUT_FIFO_BASE);
-+}
-+
-+
-+static void qup_i2c_read_fifo(struct qup_i2c_dev *qup, struct i2c_msg *msg)
-+{
-+	u32 opflags;
-+	u32 val = 0;
-+	int idx;
-+
-+	for (idx = 0; qup->pos < msg->len; idx++) {
-+		if ((idx & 1) == 0) {
-+			/* Check that FIFO have data */
-+			opflags = readl(qup->base + QUP_OPERATIONAL);
-+			if (!(opflags & QUP_IN_NOT_EMPTY))
-+				break;
-+
-+			/* Reading 2 words at time */
-+			val = readl(qup->base + QUP_IN_FIFO_BASE);
-+
-+			msg->buf[qup->pos++] = val & 0xFF;
-+		} else {
-+			msg->buf[qup->pos++] = val >> QUP_MSW_SHIFT;
-+		}
-+	}
-+}
-+
-+static int qup_i2c_read_one(struct qup_i2c_dev *qup, struct i2c_msg *msg)
-+{
-+	unsigned long left;
-+	int ret;
-+
-+	/*
-+	 * The QUP block will issue a NACK and STOP on the bus when reaching
-+	 * the end of the read, the length of the read is specified as one byte
-+	 * which limits the possible read to 256 (QUP_READ_LIMIT) bytes.
-+	 */
-+	if (msg->len > QUP_READ_LIMIT) {
-+		dev_err(qup->dev, "HW not capable of reads over %d bytes\n",
-+			QUP_READ_LIMIT);
-+		return -EINVAL;
-+	}
-+
-+	qup->msg = msg;
-+	qup->pos  = 0;
-+
-+	enable_irq(qup->irq);
-+
-+	qup_i2c_set_read_mode(qup, msg->len);
-+
-+	ret = qup_i2c_change_state(qup, QUP_RUN_STATE);
-+	if (ret)
-+		goto err;
-+
-+	writel(qup->clk_ctl, qup->base + QUP_I2C_CLK_CTL);
-+
-+	ret = qup_i2c_change_state(qup, QUP_PAUSE_STATE);
-+	if (ret)
-+		goto err;
-+
-+	qup_i2c_issue_read(qup, msg);
-+
-+	ret = qup_i2c_change_state(qup, QUP_RUN_STATE);
-+	if (ret)
-+		goto err;
-+
-+	do {
-+		left = wait_for_completion_timeout(&qup->xfer, HZ);
-+		if (!left) {
-+			writel(1, qup->base + QUP_SW_RESET);
-+			ret = -ETIMEDOUT;
-+			goto err;
-+		}
-+
-+		if (qup->bus_err || qup->qup_err) {
-+			if (qup->bus_err & QUP_I2C_NACK_FLAG)
-+				dev_err(qup->dev, "NACK from %x\n", msg->addr);
-+			ret = -EIO;
-+			goto err;
-+		}
-+
-+		qup_i2c_read_fifo(qup, msg);
-+	} while (qup->pos < msg->len);
-+
-+err:
-+	disable_irq(qup->irq);
-+	qup->msg = NULL;
-+
-+	return ret;
-+}
-+
-+static int qup_i2c_xfer(struct i2c_adapter *adap,
-+			struct i2c_msg msgs[],
-+			int num)
-+{
-+	struct qup_i2c_dev *qup = i2c_get_adapdata(adap);
-+	int ret, idx;
-+
-+	ret = pm_runtime_get_sync(qup->dev);
-+	if (ret)
-+		goto out;
-+
-+	writel(1, qup->base + QUP_SW_RESET);
-+	ret = qup_i2c_poll_state(qup, QUP_RESET_STATE);
-+	if (ret)
-+		goto out;
-+
-+	/* Configure QUP as I2C mini core */
-+	writel(I2C_MINI_CORE | I2C_N_VAL, qup->base + QUP_CONFIG);
-+
-+	for (idx = 0; idx < num; idx++) {
-+		if (msgs[idx].len == 0) {
-+			ret = -EINVAL;
-+			goto out;
-+		}
-+
-+		if (qup_i2c_poll_state_i2c_master(qup)) {
-+			ret = -EIO;
-+			goto out;
-+		}
-+
-+		if (msgs[idx].flags & I2C_M_RD)
-+			ret = qup_i2c_read_one(qup, &msgs[idx]);
-+		else
-+			ret = qup_i2c_write_one(qup, &msgs[idx]);
-+
-+		if (ret)
-+			break;
-+
-+		ret = qup_i2c_change_state(qup, QUP_RESET_STATE);
-+		if (ret)
-+			break;
-+	}
-+
-+	if (ret == 0)
-+		ret = num;
-+out:
-+
-+	pm_runtime_mark_last_busy(qup->dev);
-+	pm_runtime_put_autosuspend(qup->dev);
-+
-+	return ret;
-+}
-+
-+static u32 qup_i2c_func(struct i2c_adapter *adap)
-+{
-+	return I2C_FUNC_I2C | (I2C_FUNC_SMBUS_EMUL & ~I2C_FUNC_SMBUS_QUICK);
-+}
-+
-+static const struct i2c_algorithm qup_i2c_algo = {
-+	.master_xfer	= qup_i2c_xfer,
-+	.functionality	= qup_i2c_func,
-+};
-+
-+static void qup_i2c_enable_clocks(struct qup_i2c_dev *qup)
-+{
-+	clk_prepare_enable(qup->clk);
-+	clk_prepare_enable(qup->pclk);
-+}
-+
-+static void qup_i2c_disable_clocks(struct qup_i2c_dev *qup)
-+{
-+	u32 config;
-+
-+	qup_i2c_change_state(qup, QUP_RESET_STATE);
-+	clk_disable_unprepare(qup->clk);
-+	config = readl(qup->base + QUP_CONFIG);
-+	config |= QUP_CLOCK_AUTO_GATE;
-+	writel(config, qup->base + QUP_CONFIG);
-+	clk_disable_unprepare(qup->pclk);
-+}
-+
-+static int qup_i2c_probe(struct platform_device *pdev)
-+{
-+	static const int blk_sizes[] = {4, 16, 32};
-+	struct device_node *node = pdev->dev.of_node;
-+	struct qup_i2c_dev *qup;
-+	unsigned long one_bit_t;
-+	struct resource *res;
-+	u32 io_mode, hw_ver, size;
-+	int ret, fs_div, hs_div;
-+	int src_clk_freq;
-+	int clk_freq = 100000;
-+
-+	qup = devm_kzalloc(&pdev->dev, sizeof(*qup), GFP_KERNEL);
-+	if (!qup)
-+		return -ENOMEM;
-+
-+	qup->dev = &pdev->dev;
-+	init_completion(&qup->xfer);
-+	platform_set_drvdata(pdev, qup);
-+
-+	of_property_read_u32(node, "clock-frequency", &clk_freq);
-+
-+	/* We support frequencies up to FAST Mode (400KHz) */
-+	if (!clk_freq || clk_freq > 400000) {
-+		dev_err(qup->dev, "clock frequency not supported %d\n",
-+			clk_freq);
-+		return -EINVAL;
-+	}
-+
-+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-+	qup->base = devm_ioremap_resource(qup->dev, res);
-+	if (IS_ERR(qup->base))
-+		return PTR_ERR(qup->base);
-+
-+	qup->irq = platform_get_irq(pdev, 0);
-+	if (qup->irq < 0) {
-+		dev_err(qup->dev, "No IRQ defined\n");
-+		return qup->irq;
-+	}
-+
-+	qup->clk = devm_clk_get(qup->dev, "core");
-+	if (IS_ERR(qup->clk)) {
-+		dev_err(qup->dev, "Could not get core clock\n");
-+		return PTR_ERR(qup->clk);
-+	}
-+
-+	qup->pclk = devm_clk_get(qup->dev, "iface");
-+	if (IS_ERR(qup->pclk)) {
-+		dev_err(qup->dev, "Could not get iface clock\n");
-+		return PTR_ERR(qup->pclk);
-+	}
-+
-+	qup_i2c_enable_clocks(qup);
-+
-+	/*
-+	 * Bootloaders might leave a pending interrupt on certain QUP's,
-+	 * so we reset the core before registering for interrupts.
-+	 */
-+	writel(1, qup->base + QUP_SW_RESET);
-+	ret = qup_i2c_poll_state_valid(qup);
-+	if (ret)
-+		goto fail;
-+
-+	ret = devm_request_irq(qup->dev, qup->irq, qup_i2c_interrupt,
-+			       IRQF_TRIGGER_HIGH, "i2c_qup", qup);
-+	if (ret) {
-+		dev_err(qup->dev, "Request %d IRQ failed\n", qup->irq);
-+		goto fail;
-+	}
-+	disable_irq(qup->irq);
-+
-+	hw_ver = readl(qup->base + QUP_HW_VERSION);
-+	dev_dbg(qup->dev, "Revision %x\n", hw_ver);
-+
-+	io_mode = readl(qup->base + QUP_IO_MODE);
-+
-+	/*
-+	 * The block/fifo size w.r.t. 'actual data' is 1/2 due to 'tag'
-+	 * associated with each byte written/received
-+	 */
-+	size = QUP_OUTPUT_BLOCK_SIZE(io_mode);
-+	if (size > ARRAY_SIZE(blk_sizes))
-+		return -EIO;
-+	qup->out_blk_sz = blk_sizes[size] / 2;
-+
-+	size = QUP_INPUT_BLOCK_SIZE(io_mode);
-+	if (size > ARRAY_SIZE(blk_sizes))
-+		return -EIO;
-+	qup->in_blk_sz = blk_sizes[size] / 2;
-+
-+	size = QUP_OUTPUT_FIFO_SIZE(io_mode);
-+	qup->out_fifo_sz = qup->out_blk_sz * (2 << size);
-+
-+	size = QUP_INPUT_FIFO_SIZE(io_mode);
-+	qup->in_fifo_sz = qup->in_blk_sz * (2 << size);
-+
-+	src_clk_freq = clk_get_rate(qup->clk);
-+	fs_div = ((src_clk_freq / clk_freq) / 2) - 3;
-+	hs_div = 3;
-+	qup->clk_ctl = (hs_div << 8) | (fs_div & 0xff);
-+
-+	/*
-+	 * Time it takes for a byte to be clocked out on the bus.
-+	 * Each byte takes 9 clock cycles (8 bits + 1 ack).
-+	 */
-+	one_bit_t = (USEC_PER_SEC / clk_freq) + 1;
-+	qup->one_byte_t = one_bit_t * 9;
-+
-+	dev_dbg(qup->dev, "IN:block:%d, fifo:%d, OUT:block:%d, fifo:%d\n",
-+		qup->in_blk_sz, qup->in_fifo_sz,
-+		qup->out_blk_sz, qup->out_fifo_sz);
-+
-+	i2c_set_adapdata(&qup->adap, qup);
-+	qup->adap.algo = &qup_i2c_algo;
-+	qup->adap.dev.parent = qup->dev;
-+	qup->adap.dev.of_node = pdev->dev.of_node;
-+	strlcpy(qup->adap.name, "QUP I2C adapter", sizeof(qup->adap.name));
-+
-+	ret = i2c_add_adapter(&qup->adap);
-+	if (ret)
-+		goto fail;
-+
-+	pm_runtime_set_autosuspend_delay(qup->dev, MSEC_PER_SEC);
-+	pm_runtime_use_autosuspend(qup->dev);
-+	pm_runtime_set_active(qup->dev);
-+	pm_runtime_enable(qup->dev);
-+	return 0;
-+
-+fail:
-+	qup_i2c_disable_clocks(qup);
-+	return ret;
-+}
-+
-+static int qup_i2c_remove(struct platform_device *pdev)
-+{
-+	struct qup_i2c_dev *qup = platform_get_drvdata(pdev);
-+
-+	disable_irq(qup->irq);
-+	qup_i2c_disable_clocks(qup);
-+	i2c_del_adapter(&qup->adap);
-+	pm_runtime_disable(qup->dev);
-+	pm_runtime_set_suspended(qup->dev);
-+	return 0;
-+}
-+
-+#ifdef CONFIG_PM
-+static int qup_i2c_pm_suspend_runtime(struct device *device)
-+{
-+	struct qup_i2c_dev *qup = dev_get_drvdata(device);
-+
-+	dev_dbg(device, "pm_runtime: suspending...\n");
-+	qup_i2c_disable_clocks(qup);
-+	return 0;
-+}
-+
-+static int qup_i2c_pm_resume_runtime(struct device *device)
-+{
-+	struct qup_i2c_dev *qup = dev_get_drvdata(device);
-+
-+	dev_dbg(device, "pm_runtime: resuming...\n");
-+	qup_i2c_enable_clocks(qup);
-+	return 0;
-+}
-+#endif
-+
-+#ifdef CONFIG_PM_SLEEP
-+static int qup_i2c_suspend(struct device *device)
-+{
-+	qup_i2c_pm_suspend_runtime(device);
-+	return 0;
-+}
-+
-+static int qup_i2c_resume(struct device *device)
-+{
-+	qup_i2c_pm_resume_runtime(device);
-+	pm_runtime_mark_last_busy(device);
-+	pm_request_autosuspend(device);
-+	return 0;
-+}
-+#endif
-+
-+static const struct dev_pm_ops qup_i2c_qup_pm_ops = {
-+	SET_SYSTEM_SLEEP_PM_OPS(
-+		qup_i2c_suspend,
-+		qup_i2c_resume)
-+	SET_RUNTIME_PM_OPS(
-+		qup_i2c_pm_suspend_runtime,
-+		qup_i2c_pm_resume_runtime,
-+		NULL)
-+};
-+
-+static const struct of_device_id qup_i2c_dt_match[] = {
-+	{ .compatible = "qcom,i2c-qup-v1.1.1" },
-+	{ .compatible = "qcom,i2c-qup-v2.1.1" },
-+	{ .compatible = "qcom,i2c-qup-v2.2.1" },
-+	{}
-+};
-+MODULE_DEVICE_TABLE(of, qup_i2c_dt_match);
-+
-+static struct platform_driver qup_i2c_driver = {
-+	.probe  = qup_i2c_probe,
-+	.remove = qup_i2c_remove,
-+	.driver = {
-+		.name = "i2c_qup",
-+		.owner = THIS_MODULE,
-+		.pm = &qup_i2c_qup_pm_ops,
-+		.of_match_table = qup_i2c_dt_match,
-+	},
-+};
-+
-+module_platform_driver(qup_i2c_driver);
-+
-+MODULE_LICENSE("GPL v2");
-+MODULE_ALIAS("platform:i2c_qup");
diff --git a/target/linux/ipq806x/patches/0061-i2c-qup-Add-device-tree-bindings-information.patch b/target/linux/ipq806x/patches/0061-i2c-qup-Add-device-tree-bindings-information.patch
deleted file mode 100644
index 2f9ee58..0000000
--- a/target/linux/ipq806x/patches/0061-i2c-qup-Add-device-tree-bindings-information.patch
+++ /dev/null
@@ -1,65 +0,0 @@
-From 81480a89c72d811376e9e040729721705b2a984d Mon Sep 17 00:00:00 2001
-From: "Ivan T. Ivanov" <iivanov@mm-sol.com>
-Date: Thu, 13 Mar 2014 19:07:42 -0700
-Subject: [PATCH 061/182] i2c: qup: Add device tree bindings information
-
-The Qualcomm Universal Peripherial (QUP) wraps I2C mini-core and
-provide input and output FIFO's for it. I2C controller can operate
-as master with supported bus speeds of 100Kbps and 400Kbps.
-
-Signed-off-by: Ivan T. Ivanov <iivanov@mm-sol.com>
-[bjorn: reformulated part of binding description
-        added version to compatible
-        cleaned up example]
-Signed-off-by: Bjorn Andersson <bjorn.andersson@sonymobile.com>
-Acked-by: Rob Herring <robh@kernel.org>
-[wsa: removed the dummy child node which was a confusing example]
-Signed-off-by: Wolfram Sang <wsa@the-dreams.de>
----
- .../devicetree/bindings/i2c/qcom,i2c-qup.txt       |   40 ++++++++++++++++++++
- 1 file changed, 40 insertions(+)
- create mode 100644 Documentation/devicetree/bindings/i2c/qcom,i2c-qup.txt
-
---- /dev/null
-+++ b/Documentation/devicetree/bindings/i2c/qcom,i2c-qup.txt
-@@ -0,0 +1,40 @@
-+Qualcomm Universal Peripheral (QUP) I2C controller
-+
-+Required properties:
-+ - compatible: Should be:
-+   * "qcom,i2c-qup-v1.1.1" for 8660, 8960 and 8064.
-+   * "qcom,i2c-qup-v2.1.1" for 8974 v1.
-+   * "qcom,i2c-qup-v2.2.1" for 8974 v2 and later.
-+ - reg: Should contain QUP register address and length.
-+ - interrupts: Should contain I2C interrupt.
-+
-+ - clocks: A list of phandles + clock-specifiers, one for each entry in
-+   clock-names.
-+ - clock-names: Should contain:
-+   * "core" for the core clock
-+   * "iface" for the AHB clock
-+
-+ - #address-cells: Should be <1> Address cells for i2c device address
-+ - #size-cells: Should be <0> as i2c addresses have no size component
-+
-+Optional properties:
-+ - clock-frequency: Should specify the desired i2c bus clock frequency in Hz,
-+                    defaults to 100kHz if omitted.
-+
-+Child nodes should conform to i2c bus binding.
-+
-+Example:
-+
-+ i2c@f9924000 {
-+ 	compatible = "qcom,i2c-qup-v2.2.1";
-+ 	reg = <0xf9924000 0x1000>;
-+ 	interrupts = <0 96 0>;
-+
-+ 	clocks = <&gcc GCC_BLSP1_QUP2_I2C_APPS_CLK>, <&gcc GCC_BLSP1_AHB_CLK>;
-+ 	clock-names = "core", "iface";
-+
-+ 	clock-frequency = <355000>;
-+
-+ 	#address-cells = <1>;
-+ 	#size-cells = <0>;
-+ };
diff --git a/target/linux/ipq806x/patches/0062-i2c-qup-off-by-ones-in-qup_i2c_probe.patch b/target/linux/ipq806x/patches/0062-i2c-qup-off-by-ones-in-qup_i2c_probe.patch
deleted file mode 100644
index 3feef66..0000000
--- a/target/linux/ipq806x/patches/0062-i2c-qup-off-by-ones-in-qup_i2c_probe.patch
+++ /dev/null
@@ -1,31 +0,0 @@
-From aa50d1b0d81e4a9509f15894ec64013aa5190b59 Mon Sep 17 00:00:00 2001
-From: Dan Carpenter <dan.carpenter@oracle.com>
-Date: Thu, 3 Apr 2014 10:22:54 +0300
-Subject: [PATCH 062/182] i2c: qup: off by ones in qup_i2c_probe()
-
-These should ">= ARRAY_SIZE()" instead of "> ARRAY_SIZE()".
-
-Fixes: 10c5a8425968 ('i2c: qup: New bus driver for the Qualcomm QUP I2C controller')
-Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
-Signed-off-by: Wolfram Sang <wsa@the-dreams.de>
----
- drivers/i2c/busses/i2c-qup.c |    4 ++--
- 1 file changed, 2 insertions(+), 2 deletions(-)
-
---- a/drivers/i2c/busses/i2c-qup.c
-+++ b/drivers/i2c/busses/i2c-qup.c
-@@ -633,12 +633,12 @@ static int qup_i2c_probe(struct platform
- 	 * associated with each byte written/received
- 	 */
- 	size = QUP_OUTPUT_BLOCK_SIZE(io_mode);
--	if (size > ARRAY_SIZE(blk_sizes))
-+	if (size >= ARRAY_SIZE(blk_sizes))
- 		return -EIO;
- 	qup->out_blk_sz = blk_sizes[size] / 2;
- 
- 	size = QUP_INPUT_BLOCK_SIZE(io_mode);
--	if (size > ARRAY_SIZE(blk_sizes))
-+	if (size >= ARRAY_SIZE(blk_sizes))
- 		return -EIO;
- 	qup->in_blk_sz = blk_sizes[size] / 2;
- 
diff --git a/target/linux/ipq806x/patches/0063-i2c-qup-use-proper-type-fro-clk_freq.patch b/target/linux/ipq806x/patches/0063-i2c-qup-use-proper-type-fro-clk_freq.patch
deleted file mode 100644
index 13ffab4..0000000
--- a/target/linux/ipq806x/patches/0063-i2c-qup-use-proper-type-fro-clk_freq.patch
+++ /dev/null
@@ -1,25 +0,0 @@
-From 62bdf6c11c9120543ba4831f0226bf51db1d1fc0 Mon Sep 17 00:00:00 2001
-From: Wolfram Sang <wsa@the-dreams.de>
-Date: Thu, 3 Apr 2014 11:30:33 +0200
-Subject: [PATCH 063/182] i2c: qup: use proper type fro clk_freq
-
-It is used with of_property_read_u32(), so it should be u32.
-
-Signed-off-by: Wolfram Sang <wsa@the-dreams.de>
-Acked-by: Bjorn Andersson <bjorn.andersson@sonymobile.com>
-Fixes: 10c5a8425968 ('i2c: qup: New bus driver for the Qualcomm QUP I2C controller')
----
- drivers/i2c/busses/i2c-qup.c |    2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/drivers/i2c/busses/i2c-qup.c
-+++ b/drivers/i2c/busses/i2c-qup.c
-@@ -562,7 +562,7 @@ static int qup_i2c_probe(struct platform
- 	u32 io_mode, hw_ver, size;
- 	int ret, fs_div, hs_div;
- 	int src_clk_freq;
--	int clk_freq = 100000;
-+	u32 clk_freq = 100000;
- 
- 	qup = devm_kzalloc(&pdev->dev, sizeof(*qup), GFP_KERNEL);
- 	if (!qup)
diff --git a/target/linux/ipq806x/patches/0064-i2c-qup-Fix-pm_runtime_get_sync-usage.patch b/target/linux/ipq806x/patches/0064-i2c-qup-Fix-pm_runtime_get_sync-usage.patch
deleted file mode 100644
index 497b57e..0000000
--- a/target/linux/ipq806x/patches/0064-i2c-qup-Fix-pm_runtime_get_sync-usage.patch
+++ /dev/null
@@ -1,26 +0,0 @@
-From 82f2e53f207019c0d364d92515410be8dffd7524 Mon Sep 17 00:00:00 2001
-From: Andy Gross <agross@codeaurora.org>
-Date: Fri, 2 May 2014 20:54:29 -0500
-Subject: [PATCH 064/182] i2c: qup: Fix pm_runtime_get_sync usage
-
-This patch corrects the error check on the call to pm_runtime_get_sync.
-
-Signed-off-by: Andy Gross <agross@codeaurora.org>
-Reviewed-by: Ivan T. Ivanov <iivanov@mm-sol.com>
-Acked-by: Bjorn Andersson <bjorn.andersson@sonymobile.com>
-Signed-off-by: Wolfram Sang <wsa@the-dreams.de>
----
- drivers/i2c/busses/i2c-qup.c |    2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/drivers/i2c/busses/i2c-qup.c
-+++ b/drivers/i2c/busses/i2c-qup.c
-@@ -479,7 +479,7 @@ static int qup_i2c_xfer(struct i2c_adapt
- 	int ret, idx;
- 
- 	ret = pm_runtime_get_sync(qup->dev);
--	if (ret)
-+	if (ret < 0)
- 		goto out;
- 
- 	writel(1, qup->base + QUP_SW_RESET);
diff --git a/target/linux/ipq806x/patches/0065-spi-Add-Qualcomm-QUP-SPI-controller-support.patch b/target/linux/ipq806x/patches/0065-spi-Add-Qualcomm-QUP-SPI-controller-support.patch
deleted file mode 100644
index 3c52f24..0000000
--- a/target/linux/ipq806x/patches/0065-spi-Add-Qualcomm-QUP-SPI-controller-support.patch
+++ /dev/null
@@ -1,897 +0,0 @@
-From 24884115a6029995dba2561b1ee810f28a34271a Mon Sep 17 00:00:00 2001
-From: "Ivan T. Ivanov" <iivanov@mm-sol.com>
-Date: Thu, 13 Feb 2014 18:21:38 +0200
-Subject: [PATCH 065/182] spi: Add Qualcomm QUP SPI controller support
-
-Qualcomm Universal Peripheral (QUP) core is an AHB slave that
-provides a common data path (an output FIFO and an input FIFO)
-for serial peripheral interface (SPI) mini-core. SPI in master
-mode supports up to 50MHz, up to four chip selects, programmable
-data path from 4 bits to 32 bits and numerous protocol variants.
-
-Cc: Alok Chauhan <alokc@codeaurora.org>
-Cc: Gilad Avidov <gavidov@codeaurora.org>
-Cc: Kiran Gunda <kgunda@codeaurora.org>
-Cc: Sagar Dharia <sdharia@codeaurora.org>
-Cc: dsneddon@codeaurora.org
-Signed-off-by: Ivan T. Ivanov <iivanov@mm-sol.com>
-Signed-off-by: Mark Brown <broonie@linaro.org>
----
- drivers/spi/Kconfig   |   13 +
- drivers/spi/Makefile  |    1 +
- drivers/spi/spi-qup.c |  837 +++++++++++++++++++++++++++++++++++++++++++++++++
- 3 files changed, 851 insertions(+)
- create mode 100644 drivers/spi/spi-qup.c
-
---- a/drivers/spi/Kconfig
-+++ b/drivers/spi/Kconfig
-@@ -390,6 +390,19 @@ config SPI_RSPI
- 	help
- 	  SPI driver for Renesas RSPI and QSPI blocks.
- 
-+config SPI_QUP
-+	tristate "Qualcomm SPI controller with QUP interface"
-+	depends on ARCH_MSM_DT
-+	help
-+	  Qualcomm Universal Peripheral (QUP) core is an AHB slave that
-+	  provides a common data path (an output FIFO and an input FIFO)
-+	  for serial peripheral interface (SPI) mini-core. SPI in master
-+	  mode supports up to 50MHz, up to four chip selects, programmable
-+	  data path from 4 bits to 32 bits and numerous protocol variants.
-+
-+	  This driver can also be built as a module.  If so, the module
-+	  will be called spi_qup.
-+
- config SPI_S3C24XX
- 	tristate "Samsung S3C24XX series SPI"
- 	depends on ARCH_S3C24XX
---- a/drivers/spi/Makefile
-+++ b/drivers/spi/Makefile
-@@ -60,6 +60,7 @@ spi-pxa2xx-platform-$(CONFIG_SPI_PXA2XX_
- spi-pxa2xx-platform-$(CONFIG_SPI_PXA2XX_DMA)	+= spi-pxa2xx-dma.o
- obj-$(CONFIG_SPI_PXA2XX)		+= spi-pxa2xx-platform.o
- obj-$(CONFIG_SPI_PXA2XX_PCI)		+= spi-pxa2xx-pci.o
-+obj-$(CONFIG_SPI_QUP)			+= spi-qup.o
- obj-$(CONFIG_SPI_RSPI)			+= spi-rspi.o
- obj-$(CONFIG_SPI_S3C24XX)		+= spi-s3c24xx-hw.o
- spi-s3c24xx-hw-y			:= spi-s3c24xx.o
---- /dev/null
-+++ b/drivers/spi/spi-qup.c
-@@ -0,0 +1,837 @@
-+/*
-+ * Copyright (c) 2008-2014, The Linux foundation. All rights reserved.
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License rev 2 and
-+ * only rev 2 as published by the free Software foundation.
-+ *
-+ * 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/delay.h>
-+#include <linux/err.h>
-+#include <linux/interrupt.h>
-+#include <linux/io.h>
-+#include <linux/list.h>
-+#include <linux/module.h>
-+#include <linux/of.h>
-+#include <linux/platform_device.h>
-+#include <linux/pm_runtime.h>
-+#include <linux/spi/spi.h>
-+
-+#define QUP_CONFIG			0x0000
-+#define QUP_STATE			0x0004
-+#define QUP_IO_M_MODES			0x0008
-+#define QUP_SW_RESET			0x000c
-+#define QUP_OPERATIONAL			0x0018
-+#define QUP_ERROR_FLAGS			0x001c
-+#define QUP_ERROR_FLAGS_EN		0x0020
-+#define QUP_OPERATIONAL_MASK		0x0028
-+#define QUP_HW_VERSION			0x0030
-+#define QUP_MX_OUTPUT_CNT		0x0100
-+#define QUP_OUTPUT_FIFO			0x0110
-+#define QUP_MX_WRITE_CNT		0x0150
-+#define QUP_MX_INPUT_CNT		0x0200
-+#define QUP_MX_READ_CNT			0x0208
-+#define QUP_INPUT_FIFO			0x0218
-+
-+#define SPI_CONFIG			0x0300
-+#define SPI_IO_CONTROL			0x0304
-+#define SPI_ERROR_FLAGS			0x0308
-+#define SPI_ERROR_FLAGS_EN		0x030c
-+
-+/* QUP_CONFIG fields */
-+#define QUP_CONFIG_SPI_MODE		(1 << 8)
-+#define QUP_CONFIG_CLOCK_AUTO_GATE	BIT(13)
-+#define QUP_CONFIG_NO_INPUT		BIT(7)
-+#define QUP_CONFIG_NO_OUTPUT		BIT(6)
-+#define QUP_CONFIG_N			0x001f
-+
-+/* QUP_STATE fields */
-+#define QUP_STATE_VALID			BIT(2)
-+#define QUP_STATE_RESET			0
-+#define QUP_STATE_RUN			1
-+#define QUP_STATE_PAUSE			3
-+#define QUP_STATE_MASK			3
-+#define QUP_STATE_CLEAR			2
-+
-+#define QUP_HW_VERSION_2_1_1		0x20010001
-+
-+/* QUP_IO_M_MODES fields */
-+#define QUP_IO_M_PACK_EN		BIT(15)
-+#define QUP_IO_M_UNPACK_EN		BIT(14)
-+#define QUP_IO_M_INPUT_MODE_MASK_SHIFT	12
-+#define QUP_IO_M_OUTPUT_MODE_MASK_SHIFT	10
-+#define QUP_IO_M_INPUT_MODE_MASK	(3 << QUP_IO_M_INPUT_MODE_MASK_SHIFT)
-+#define QUP_IO_M_OUTPUT_MODE_MASK	(3 << QUP_IO_M_OUTPUT_MODE_MASK_SHIFT)
-+
-+#define QUP_IO_M_OUTPUT_BLOCK_SIZE(x)	(((x) & (0x03 << 0)) >> 0)
-+#define QUP_IO_M_OUTPUT_FIFO_SIZE(x)	(((x) & (0x07 << 2)) >> 2)
-+#define QUP_IO_M_INPUT_BLOCK_SIZE(x)	(((x) & (0x03 << 5)) >> 5)
-+#define QUP_IO_M_INPUT_FIFO_SIZE(x)	(((x) & (0x07 << 7)) >> 7)
-+
-+#define QUP_IO_M_MODE_FIFO		0
-+#define QUP_IO_M_MODE_BLOCK		1
-+#define QUP_IO_M_MODE_DMOV		2
-+#define QUP_IO_M_MODE_BAM		3
-+
-+/* QUP_OPERATIONAL fields */
-+#define QUP_OP_MAX_INPUT_DONE_FLAG	BIT(11)
-+#define QUP_OP_MAX_OUTPUT_DONE_FLAG	BIT(10)
-+#define QUP_OP_IN_SERVICE_FLAG		BIT(9)
-+#define QUP_OP_OUT_SERVICE_FLAG		BIT(8)
-+#define QUP_OP_IN_FIFO_FULL		BIT(7)
-+#define QUP_OP_OUT_FIFO_FULL		BIT(6)
-+#define QUP_OP_IN_FIFO_NOT_EMPTY	BIT(5)
-+#define QUP_OP_OUT_FIFO_NOT_EMPTY	BIT(4)
-+
-+/* QUP_ERROR_FLAGS and QUP_ERROR_FLAGS_EN fields */
-+#define QUP_ERROR_OUTPUT_OVER_RUN	BIT(5)
-+#define QUP_ERROR_INPUT_UNDER_RUN	BIT(4)
-+#define QUP_ERROR_OUTPUT_UNDER_RUN	BIT(3)
-+#define QUP_ERROR_INPUT_OVER_RUN	BIT(2)
-+
-+/* SPI_CONFIG fields */
-+#define SPI_CONFIG_HS_MODE		BIT(10)
-+#define SPI_CONFIG_INPUT_FIRST		BIT(9)
-+#define SPI_CONFIG_LOOPBACK		BIT(8)
-+
-+/* SPI_IO_CONTROL fields */
-+#define SPI_IO_C_FORCE_CS		BIT(11)
-+#define SPI_IO_C_CLK_IDLE_HIGH		BIT(10)
-+#define SPI_IO_C_MX_CS_MODE		BIT(8)
-+#define SPI_IO_C_CS_N_POLARITY_0	BIT(4)
-+#define SPI_IO_C_CS_SELECT(x)		(((x) & 3) << 2)
-+#define SPI_IO_C_CS_SELECT_MASK		0x000c
-+#define SPI_IO_C_TRISTATE_CS		BIT(1)
-+#define SPI_IO_C_NO_TRI_STATE		BIT(0)
-+
-+/* SPI_ERROR_FLAGS and SPI_ERROR_FLAGS_EN fields */
-+#define SPI_ERROR_CLK_OVER_RUN		BIT(1)
-+#define SPI_ERROR_CLK_UNDER_RUN		BIT(0)
-+
-+#define SPI_NUM_CHIPSELECTS		4
-+
-+/* high speed mode is when bus rate is greater then 26MHz */
-+#define SPI_HS_MIN_RATE			26000000
-+#define SPI_MAX_RATE			50000000
-+
-+#define SPI_DELAY_THRESHOLD		1
-+#define SPI_DELAY_RETRY			10
-+
-+struct spi_qup_device {
-+	int select;
-+	u16 mode;
-+};
-+
-+struct spi_qup {
-+	void __iomem		*base;
-+	struct device		*dev;
-+	struct clk		*cclk;	/* core clock */
-+	struct clk		*iclk;	/* interface clock */
-+	int			irq;
-+	u32			max_speed_hz;
-+	spinlock_t		lock;
-+
-+	int			in_fifo_sz;
-+	int			out_fifo_sz;
-+	int			in_blk_sz;
-+	int			out_blk_sz;
-+
-+	struct spi_transfer	*xfer;
-+	struct completion	done;
-+	int			error;
-+	int			w_size;	/* bytes per SPI word */
-+	int			tx_bytes;
-+	int			rx_bytes;
-+};
-+
-+
-+static inline bool spi_qup_is_valid_state(struct spi_qup *controller)
-+{
-+	u32 opstate = readl_relaxed(controller->base + QUP_STATE);
-+
-+	return opstate & QUP_STATE_VALID;
-+}
-+
-+static int spi_qup_set_state(struct spi_qup *controller, u32 state)
-+{
-+	unsigned long loop;
-+	u32 cur_state;
-+
-+	loop = 0;
-+	while (!spi_qup_is_valid_state(controller)) {
-+
-+		usleep_range(SPI_DELAY_THRESHOLD, SPI_DELAY_THRESHOLD * 2);
-+
-+		if (++loop > SPI_DELAY_RETRY)
-+			return -EIO;
-+	}
-+
-+	if (loop)
-+		dev_dbg(controller->dev, "invalid state for %ld,us %d\n",
-+			loop, state);
-+
-+	cur_state = readl_relaxed(controller->base + QUP_STATE);
-+	/*
-+	 * Per spec: for PAUSE_STATE to RESET_STATE, two writes
-+	 * of (b10) are required
-+	 */
-+	if (((cur_state & QUP_STATE_MASK) == QUP_STATE_PAUSE) &&
-+	    (state == QUP_STATE_RESET)) {
-+		writel_relaxed(QUP_STATE_CLEAR, controller->base + QUP_STATE);
-+		writel_relaxed(QUP_STATE_CLEAR, controller->base + QUP_STATE);
-+	} else {
-+		cur_state &= ~QUP_STATE_MASK;
-+		cur_state |= state;
-+		writel_relaxed(cur_state, controller->base + QUP_STATE);
-+	}
-+
-+	loop = 0;
-+	while (!spi_qup_is_valid_state(controller)) {
-+
-+		usleep_range(SPI_DELAY_THRESHOLD, SPI_DELAY_THRESHOLD * 2);
-+
-+		if (++loop > SPI_DELAY_RETRY)
-+			return -EIO;
-+	}
-+
-+	return 0;
-+}
-+
-+
-+static void spi_qup_fifo_read(struct spi_qup *controller,
-+			    struct spi_transfer *xfer)
-+{
-+	u8 *rx_buf = xfer->rx_buf;
-+	u32 word, state;
-+	int idx, shift, w_size;
-+
-+	w_size = controller->w_size;
-+
-+	while (controller->rx_bytes < xfer->len) {
-+
-+		state = readl_relaxed(controller->base + QUP_OPERATIONAL);
-+		if (0 == (state & QUP_OP_IN_FIFO_NOT_EMPTY))
-+			break;
-+
-+		word = readl_relaxed(controller->base + QUP_INPUT_FIFO);
-+
-+		if (!rx_buf) {
-+			controller->rx_bytes += w_size;
-+			continue;
-+		}
-+
-+		for (idx = 0; idx < w_size; idx++, controller->rx_bytes++) {
-+			/*
-+			 * The data format depends on bytes per SPI word:
-+			 *  4 bytes: 0x12345678
-+			 *  2 bytes: 0x00001234
-+			 *  1 byte : 0x00000012
-+			 */
-+			shift = BITS_PER_BYTE;
-+			shift *= (w_size - idx - 1);
-+			rx_buf[controller->rx_bytes] = word >> shift;
-+		}
-+	}
-+}
-+
-+static void spi_qup_fifo_write(struct spi_qup *controller,
-+			    struct spi_transfer *xfer)
-+{
-+	const u8 *tx_buf = xfer->tx_buf;
-+	u32 word, state, data;
-+	int idx, w_size;
-+
-+	w_size = controller->w_size;
-+
-+	while (controller->tx_bytes < xfer->len) {
-+
-+		state = readl_relaxed(controller->base + QUP_OPERATIONAL);
-+		if (state & QUP_OP_OUT_FIFO_FULL)
-+			break;
-+
-+		word = 0;
-+		for (idx = 0; idx < w_size; idx++, controller->tx_bytes++) {
-+
-+			if (!tx_buf) {
-+				controller->tx_bytes += w_size;
-+				break;
-+			}
-+
-+			data = tx_buf[controller->tx_bytes];
-+			word |= data << (BITS_PER_BYTE * (3 - idx));
-+		}
-+
-+		writel_relaxed(word, controller->base + QUP_OUTPUT_FIFO);
-+	}
-+}
-+
-+static irqreturn_t spi_qup_qup_irq(int irq, void *dev_id)
-+{
-+	struct spi_qup *controller = dev_id;
-+	struct spi_transfer *xfer;
-+	u32 opflags, qup_err, spi_err;
-+	unsigned long flags;
-+	int error = 0;
-+
-+	spin_lock_irqsave(&controller->lock, flags);
-+	xfer = controller->xfer;
-+	controller->xfer = NULL;
-+	spin_unlock_irqrestore(&controller->lock, flags);
-+
-+	qup_err = readl_relaxed(controller->base + QUP_ERROR_FLAGS);
-+	spi_err = readl_relaxed(controller->base + SPI_ERROR_FLAGS);
-+	opflags = readl_relaxed(controller->base + QUP_OPERATIONAL);
-+
-+	writel_relaxed(qup_err, controller->base + QUP_ERROR_FLAGS);
-+	writel_relaxed(spi_err, controller->base + SPI_ERROR_FLAGS);
-+	writel_relaxed(opflags, controller->base + QUP_OPERATIONAL);
-+
-+	if (!xfer) {
-+		dev_err_ratelimited(controller->dev, "unexpected irq %x08 %x08 %x08\n",
-+				    qup_err, spi_err, opflags);
-+		return IRQ_HANDLED;
-+	}
-+
-+	if (qup_err) {
-+		if (qup_err & QUP_ERROR_OUTPUT_OVER_RUN)
-+			dev_warn(controller->dev, "OUTPUT_OVER_RUN\n");
-+		if (qup_err & QUP_ERROR_INPUT_UNDER_RUN)
-+			dev_warn(controller->dev, "INPUT_UNDER_RUN\n");
-+		if (qup_err & QUP_ERROR_OUTPUT_UNDER_RUN)
-+			dev_warn(controller->dev, "OUTPUT_UNDER_RUN\n");
-+		if (qup_err & QUP_ERROR_INPUT_OVER_RUN)
-+			dev_warn(controller->dev, "INPUT_OVER_RUN\n");
-+
-+		error = -EIO;
-+	}
-+
-+	if (spi_err) {
-+		if (spi_err & SPI_ERROR_CLK_OVER_RUN)
-+			dev_warn(controller->dev, "CLK_OVER_RUN\n");
-+		if (spi_err & SPI_ERROR_CLK_UNDER_RUN)
-+			dev_warn(controller->dev, "CLK_UNDER_RUN\n");
-+
-+		error = -EIO;
-+	}
-+
-+	if (opflags & QUP_OP_IN_SERVICE_FLAG)
-+		spi_qup_fifo_read(controller, xfer);
-+
-+	if (opflags & QUP_OP_OUT_SERVICE_FLAG)
-+		spi_qup_fifo_write(controller, xfer);
-+
-+	spin_lock_irqsave(&controller->lock, flags);
-+	controller->error = error;
-+	controller->xfer = xfer;
-+	spin_unlock_irqrestore(&controller->lock, flags);
-+
-+	if (controller->rx_bytes == xfer->len || error)
-+		complete(&controller->done);
-+
-+	return IRQ_HANDLED;
-+}
-+
-+
-+/* set clock freq ... bits per word */
-+static int spi_qup_io_config(struct spi_qup *controller,
-+			   struct spi_qup_device *chip,
-+			   struct spi_transfer *xfer)
-+{
-+	u32 config, iomode, mode;
-+	int ret, n_words, w_size;
-+
-+	if (chip->mode & SPI_LOOP && xfer->len > controller->in_fifo_sz) {
-+		dev_err(controller->dev, "too big size for loopback %d > %d\n",
-+			xfer->len, controller->in_fifo_sz);
-+		return -EIO;
-+	}
-+
-+	ret = clk_set_rate(controller->cclk, xfer->speed_hz);
-+	if (ret) {
-+		dev_err(controller->dev, "fail to set frequency %d",
-+			xfer->speed_hz);
-+		return -EIO;
-+	}
-+
-+	if (spi_qup_set_state(controller, QUP_STATE_RESET)) {
-+		dev_err(controller->dev, "cannot set RESET state\n");
-+		return -EIO;
-+	}
-+
-+	w_size = 4;
-+	if (xfer->bits_per_word <= 8)
-+		w_size = 1;
-+	else if (xfer->bits_per_word <= 16)
-+		w_size = 2;
-+
-+	n_words = xfer->len / w_size;
-+	controller->w_size = w_size;
-+
-+	if (n_words <= controller->in_fifo_sz) {
-+		mode = QUP_IO_M_MODE_FIFO;
-+		writel_relaxed(n_words, controller->base + QUP_MX_READ_CNT);
-+		writel_relaxed(n_words, controller->base + QUP_MX_WRITE_CNT);
-+		/* must be zero for FIFO */
-+		writel_relaxed(0, controller->base + QUP_MX_INPUT_CNT);
-+		writel_relaxed(0, controller->base + QUP_MX_OUTPUT_CNT);
-+	} else {
-+		mode = QUP_IO_M_MODE_BLOCK;
-+		writel_relaxed(n_words, controller->base + QUP_MX_INPUT_CNT);
-+		writel_relaxed(n_words, controller->base + QUP_MX_OUTPUT_CNT);
-+		/* must be zero for BLOCK and BAM */
-+		writel_relaxed(0, controller->base + QUP_MX_READ_CNT);
-+		writel_relaxed(0, controller->base + QUP_MX_WRITE_CNT);
-+	}
-+
-+	iomode = readl_relaxed(controller->base + QUP_IO_M_MODES);
-+	/* Set input and output transfer mode */
-+	iomode &= ~(QUP_IO_M_INPUT_MODE_MASK | QUP_IO_M_OUTPUT_MODE_MASK);
-+	iomode &= ~(QUP_IO_M_PACK_EN | QUP_IO_M_UNPACK_EN);
-+	iomode |= (mode << QUP_IO_M_OUTPUT_MODE_MASK_SHIFT);
-+	iomode |= (mode << QUP_IO_M_INPUT_MODE_MASK_SHIFT);
-+
-+	writel_relaxed(iomode, controller->base + QUP_IO_M_MODES);
-+
-+	config = readl_relaxed(controller->base + SPI_CONFIG);
-+
-+	if (chip->mode & SPI_LOOP)
-+		config |= SPI_CONFIG_LOOPBACK;
-+	else
-+		config &= ~SPI_CONFIG_LOOPBACK;
-+
-+	if (chip->mode & SPI_CPHA)
-+		config &= ~SPI_CONFIG_INPUT_FIRST;
-+	else
-+		config |= SPI_CONFIG_INPUT_FIRST;
-+
-+	/*
-+	 * HS_MODE improves signal stability for spi-clk high rates,
-+	 * but is invalid in loop back mode.
-+	 */
-+	if ((xfer->speed_hz >= SPI_HS_MIN_RATE) && !(chip->mode & SPI_LOOP))
-+		config |= SPI_CONFIG_HS_MODE;
-+	else
-+		config &= ~SPI_CONFIG_HS_MODE;
-+
-+	writel_relaxed(config, controller->base + SPI_CONFIG);
-+
-+	config = readl_relaxed(controller->base + QUP_CONFIG);
-+	config &= ~(QUP_CONFIG_NO_INPUT | QUP_CONFIG_NO_OUTPUT | QUP_CONFIG_N);
-+	config |= xfer->bits_per_word - 1;
-+	config |= QUP_CONFIG_SPI_MODE;
-+	writel_relaxed(config, controller->base + QUP_CONFIG);
-+
-+	writel_relaxed(0, controller->base + QUP_OPERATIONAL_MASK);
-+	return 0;
-+}
-+
-+static void spi_qup_set_cs(struct spi_device *spi, bool enable)
-+{
-+	struct spi_qup *controller = spi_master_get_devdata(spi->master);
-+	struct spi_qup_device *chip = spi_get_ctldata(spi);
-+
-+	u32 iocontol, mask;
-+
-+	iocontol = readl_relaxed(controller->base + SPI_IO_CONTROL);
-+
-+	/* Disable auto CS toggle and use manual */
-+	iocontol &= ~SPI_IO_C_MX_CS_MODE;
-+	iocontol |= SPI_IO_C_FORCE_CS;
-+
-+	iocontol &= ~SPI_IO_C_CS_SELECT_MASK;
-+	iocontol |= SPI_IO_C_CS_SELECT(chip->select);
-+
-+	mask = SPI_IO_C_CS_N_POLARITY_0 << chip->select;
-+
-+	if (enable)
-+		iocontol |= mask;
-+	else
-+		iocontol &= ~mask;
-+
-+	writel_relaxed(iocontol, controller->base + SPI_IO_CONTROL);
-+}
-+
-+static int spi_qup_transfer_one(struct spi_master *master,
-+			      struct spi_device *spi,
-+			      struct spi_transfer *xfer)
-+{
-+	struct spi_qup *controller = spi_master_get_devdata(master);
-+	struct spi_qup_device *chip = spi_get_ctldata(spi);
-+	unsigned long timeout, flags;
-+	int ret = -EIO;
-+
-+	ret = spi_qup_io_config(controller, chip, xfer);
-+	if (ret)
-+		return ret;
-+
-+	timeout = DIV_ROUND_UP(xfer->speed_hz, MSEC_PER_SEC);
-+	timeout = DIV_ROUND_UP(xfer->len * 8, timeout);
-+	timeout = 100 * msecs_to_jiffies(timeout);
-+
-+	reinit_completion(&controller->done);
-+
-+	spin_lock_irqsave(&controller->lock, flags);
-+	controller->xfer     = xfer;
-+	controller->error    = 0;
-+	controller->rx_bytes = 0;
-+	controller->tx_bytes = 0;
-+	spin_unlock_irqrestore(&controller->lock, flags);
-+
-+	if (spi_qup_set_state(controller, QUP_STATE_RUN)) {
-+		dev_warn(controller->dev, "cannot set RUN state\n");
-+		goto exit;
-+	}
-+
-+	if (spi_qup_set_state(controller, QUP_STATE_PAUSE)) {
-+		dev_warn(controller->dev, "cannot set PAUSE state\n");
-+		goto exit;
-+	}
-+
-+	spi_qup_fifo_write(controller, xfer);
-+
-+	if (spi_qup_set_state(controller, QUP_STATE_RUN)) {
-+		dev_warn(controller->dev, "cannot set EXECUTE state\n");
-+		goto exit;
-+	}
-+
-+	if (!wait_for_completion_timeout(&controller->done, timeout))
-+		ret = -ETIMEDOUT;
-+exit:
-+	spi_qup_set_state(controller, QUP_STATE_RESET);
-+	spin_lock_irqsave(&controller->lock, flags);
-+	controller->xfer = NULL;
-+	if (!ret)
-+		ret = controller->error;
-+	spin_unlock_irqrestore(&controller->lock, flags);
-+	return ret;
-+}
-+
-+static int spi_qup_setup(struct spi_device *spi)
-+{
-+	struct spi_qup *controller = spi_master_get_devdata(spi->master);
-+	struct spi_qup_device *chip = spi_get_ctldata(spi);
-+
-+	if (spi->chip_select >= spi->master->num_chipselect) {
-+		dev_err(controller->dev, "invalid chip_select %d\n",
-+			spi->chip_select);
-+		return -EINVAL;
-+	}
-+
-+	if (spi->max_speed_hz > controller->max_speed_hz) {
-+		dev_err(controller->dev, "invalid max_speed_hz %d\n",
-+			spi->max_speed_hz);
-+		return -EINVAL;
-+	}
-+
-+	if (!chip) {
-+		/* First setup */
-+		chip = kzalloc(sizeof(*chip), GFP_KERNEL);
-+		if (!chip) {
-+			dev_err(controller->dev, "no memory for chip data\n");
-+			return -ENOMEM;
-+		}
-+
-+		chip->mode = spi->mode;
-+		chip->select = spi->chip_select;
-+		spi_set_ctldata(spi, chip);
-+	}
-+
-+	return 0;
-+}
-+
-+static void spi_qup_cleanup(struct spi_device *spi)
-+{
-+	struct spi_qup_device *chip = spi_get_ctldata(spi);
-+
-+	if (!chip)
-+		return;
-+
-+	spi_set_ctldata(spi, NULL);
-+	kfree(chip);
-+}
-+
-+static int spi_qup_probe(struct platform_device *pdev)
-+{
-+	struct spi_master *master;
-+	struct clk *iclk, *cclk;
-+	struct spi_qup *controller;
-+	struct resource *res;
-+	struct device *dev;
-+	void __iomem *base;
-+	u32 data, max_freq, iomode;
-+	int ret, irq, size;
-+
-+	dev = &pdev->dev;
-+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-+	base = devm_ioremap_resource(dev, res);
-+	if (IS_ERR(base))
-+		return PTR_ERR(base);
-+
-+	irq = platform_get_irq(pdev, 0);
-+
-+	if (irq < 0)
-+		return irq;
-+
-+	cclk = devm_clk_get(dev, "core");
-+	if (IS_ERR(cclk))
-+		return PTR_ERR(cclk);
-+
-+	iclk = devm_clk_get(dev, "iface");
-+	if (IS_ERR(iclk))
-+		return PTR_ERR(iclk);
-+
-+	/* This is optional parameter */
-+	if (of_property_read_u32(dev->of_node, "spi-max-frequency", &max_freq))
-+		max_freq = SPI_MAX_RATE;
-+
-+	if (!max_freq || max_freq > SPI_MAX_RATE) {
-+		dev_err(dev, "invalid clock frequency %d\n", max_freq);
-+		return -ENXIO;
-+	}
-+
-+	ret = clk_prepare_enable(cclk);
-+	if (ret) {
-+		dev_err(dev, "cannot enable core clock\n");
-+		return ret;
-+	}
-+
-+	ret = clk_prepare_enable(iclk);
-+	if (ret) {
-+		clk_disable_unprepare(cclk);
-+		dev_err(dev, "cannot enable iface clock\n");
-+		return ret;
-+	}
-+
-+	data = readl_relaxed(base + QUP_HW_VERSION);
-+
-+	if (data < QUP_HW_VERSION_2_1_1) {
-+		clk_disable_unprepare(cclk);
-+		clk_disable_unprepare(iclk);
-+		dev_err(dev, "v.%08x is not supported\n", data);
-+		return -ENXIO;
-+	}
-+
-+	master = spi_alloc_master(dev, sizeof(struct spi_qup));
-+	if (!master) {
-+		clk_disable_unprepare(cclk);
-+		clk_disable_unprepare(iclk);
-+		dev_err(dev, "cannot allocate master\n");
-+		return -ENOMEM;
-+	}
-+
-+	master->bus_num = pdev->id;
-+	master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH | SPI_LOOP;
-+	master->num_chipselect = SPI_NUM_CHIPSELECTS;
-+	master->bits_per_word_mask = SPI_BPW_RANGE_MASK(4, 32);
-+	master->setup = spi_qup_setup;
-+	master->cleanup = spi_qup_cleanup;
-+	master->set_cs = spi_qup_set_cs;
-+	master->transfer_one = spi_qup_transfer_one;
-+	master->dev.of_node = pdev->dev.of_node;
-+	master->auto_runtime_pm = true;
-+
-+	platform_set_drvdata(pdev, master);
-+
-+	controller = spi_master_get_devdata(master);
-+
-+	controller->dev = dev;
-+	controller->base = base;
-+	controller->iclk = iclk;
-+	controller->cclk = cclk;
-+	controller->irq = irq;
-+	controller->max_speed_hz = max_freq;
-+
-+	spin_lock_init(&controller->lock);
-+	init_completion(&controller->done);
-+
-+	iomode = readl_relaxed(base + QUP_IO_M_MODES);
-+
-+	size = QUP_IO_M_OUTPUT_BLOCK_SIZE(iomode);
-+	if (size)
-+		controller->out_blk_sz = size * 16;
-+	else
-+		controller->out_blk_sz = 4;
-+
-+	size = QUP_IO_M_INPUT_BLOCK_SIZE(iomode);
-+	if (size)
-+		controller->in_blk_sz = size * 16;
-+	else
-+		controller->in_blk_sz = 4;
-+
-+	size = QUP_IO_M_OUTPUT_FIFO_SIZE(iomode);
-+	controller->out_fifo_sz = controller->out_blk_sz * (2 << size);
-+
-+	size = QUP_IO_M_INPUT_FIFO_SIZE(iomode);
-+	controller->in_fifo_sz = controller->in_blk_sz * (2 << size);
-+
-+	dev_info(dev, "v.%08x IN:block:%d, fifo:%d, OUT:block:%d, fifo:%d\n",
-+		 data, controller->in_blk_sz, controller->in_fifo_sz,
-+		 controller->out_blk_sz, controller->out_fifo_sz);
-+
-+	writel_relaxed(1, base + QUP_SW_RESET);
-+
-+	ret = spi_qup_set_state(controller, QUP_STATE_RESET);
-+	if (ret) {
-+		dev_err(dev, "cannot set RESET state\n");
-+		goto error;
-+	}
-+
-+	writel_relaxed(0, base + QUP_OPERATIONAL);
-+	writel_relaxed(0, base + QUP_IO_M_MODES);
-+	writel_relaxed(0, base + QUP_OPERATIONAL_MASK);
-+	writel_relaxed(SPI_ERROR_CLK_UNDER_RUN | SPI_ERROR_CLK_OVER_RUN,
-+		       base + SPI_ERROR_FLAGS_EN);
-+
-+	writel_relaxed(0, base + SPI_CONFIG);
-+	writel_relaxed(SPI_IO_C_NO_TRI_STATE, base + SPI_IO_CONTROL);
-+
-+	ret = devm_request_irq(dev, irq, spi_qup_qup_irq,
-+			       IRQF_TRIGGER_HIGH, pdev->name, controller);
-+	if (ret)
-+		goto error;
-+
-+	ret = devm_spi_register_master(dev, master);
-+	if (ret)
-+		goto error;
-+
-+	pm_runtime_set_autosuspend_delay(dev, MSEC_PER_SEC);
-+	pm_runtime_use_autosuspend(dev);
-+	pm_runtime_set_active(dev);
-+	pm_runtime_enable(dev);
-+	return 0;
-+
-+error:
-+	clk_disable_unprepare(cclk);
-+	clk_disable_unprepare(iclk);
-+	spi_master_put(master);
-+	return ret;
-+}
-+
-+#ifdef CONFIG_PM_RUNTIME
-+static int spi_qup_pm_suspend_runtime(struct device *device)
-+{
-+	struct spi_master *master = dev_get_drvdata(device);
-+	struct spi_qup *controller = spi_master_get_devdata(master);
-+	u32 config;
-+
-+	/* Enable clocks auto gaiting */
-+	config = readl(controller->base + QUP_CONFIG);
-+	config |= QUP_CLOCK_AUTO_GATE;
-+	writel_relaxed(config, controller->base + QUP_CONFIG);
-+	return 0;
-+}
-+
-+static int spi_qup_pm_resume_runtime(struct device *device)
-+{
-+	struct spi_master *master = dev_get_drvdata(device);
-+	struct spi_qup *controller = spi_master_get_devdata(master);
-+	u32 config;
-+
-+	/* Disable clocks auto gaiting */
-+	config = readl_relaxed(controller->base + QUP_CONFIG);
-+	config &= ~QUP_CLOCK_AUTO_GATE;
-+	writel_relaxed(config, controller->base + QUP_CONFIG);
-+	return 0;
-+}
-+#endif /* CONFIG_PM_RUNTIME */
-+
-+#ifdef CONFIG_PM_SLEEP
-+static int spi_qup_suspend(struct device *device)
-+{
-+	struct spi_master *master = dev_get_drvdata(device);
-+	struct spi_qup *controller = spi_master_get_devdata(master);
-+	int ret;
-+
-+	ret = spi_master_suspend(master);
-+	if (ret)
-+		return ret;
-+
-+	ret = spi_qup_set_state(controller, QUP_STATE_RESET);
-+	if (ret)
-+		return ret;
-+
-+	clk_disable_unprepare(controller->cclk);
-+	clk_disable_unprepare(controller->iclk);
-+	return 0;
-+}
-+
-+static int spi_qup_resume(struct device *device)
-+{
-+	struct spi_master *master = dev_get_drvdata(device);
-+	struct spi_qup *controller = spi_master_get_devdata(master);
-+	int ret;
-+
-+	ret = clk_prepare_enable(controller->iclk);
-+	if (ret)
-+		return ret;
-+
-+	ret = clk_prepare_enable(controller->cclk);
-+	if (ret)
-+		return ret;
-+
-+	ret = spi_qup_set_state(controller, QUP_STATE_RESET);
-+	if (ret)
-+		return ret;
-+
-+	return spi_master_resume(master);
-+}
-+#endif /* CONFIG_PM_SLEEP */
-+
-+static int spi_qup_remove(struct platform_device *pdev)
-+{
-+	struct spi_master *master = dev_get_drvdata(&pdev->dev);
-+	struct spi_qup *controller = spi_master_get_devdata(master);
-+	int ret;
-+
-+	ret = pm_runtime_get_sync(&pdev->dev);
-+	if (ret)
-+		return ret;
-+
-+	ret = spi_qup_set_state(controller, QUP_STATE_RESET);
-+	if (ret)
-+		return ret;
-+
-+	clk_disable_unprepare(controller->cclk);
-+	clk_disable_unprepare(controller->iclk);
-+
-+	pm_runtime_put_noidle(&pdev->dev);
-+	pm_runtime_disable(&pdev->dev);
-+	spi_master_put(master);
-+	return 0;
-+}
-+
-+static struct of_device_id spi_qup_dt_match[] = {
-+	{ .compatible = "qcom,spi-qup-v2.1.1", },
-+	{ .compatible = "qcom,spi-qup-v2.2.1", },
-+	{ }
-+};
-+MODULE_DEVICE_TABLE(of, spi_qup_dt_match);
-+
-+static const struct dev_pm_ops spi_qup_dev_pm_ops = {
-+	SET_SYSTEM_SLEEP_PM_OPS(spi_qup_suspend, spi_qup_resume)
-+	SET_RUNTIME_PM_OPS(spi_qup_pm_suspend_runtime,
-+			   spi_qup_pm_resume_runtime,
-+			   NULL)
-+};
-+
-+static struct platform_driver spi_qup_driver = {
-+	.driver = {
-+		.name		= "spi_qup",
-+		.owner		= THIS_MODULE,
-+		.pm		= &spi_qup_dev_pm_ops,
-+		.of_match_table = spi_qup_dt_match,
-+	},
-+	.probe = spi_qup_probe,
-+	.remove = spi_qup_remove,
-+};
-+module_platform_driver(spi_qup_driver);
-+
-+MODULE_LICENSE("GPL v2");
-+MODULE_VERSION("0.4");
-+MODULE_ALIAS("platform:spi_qup");
diff --git a/target/linux/ipq806x/patches/0066-spi-qup-Add-device-tree-bindings-information.patch b/target/linux/ipq806x/patches/0066-spi-qup-Add-device-tree-bindings-information.patch
deleted file mode 100644
index 079d59f..0000000
--- a/target/linux/ipq806x/patches/0066-spi-qup-Add-device-tree-bindings-information.patch
+++ /dev/null
@@ -1,105 +0,0 @@
-From a8e8c90a3cc81c6a7a44ff7fb18ceb71978c9155 Mon Sep 17 00:00:00 2001
-From: "Ivan T. Ivanov" <iivanov@mm-sol.com>
-Date: Thu, 13 Feb 2014 18:21:23 +0200
-Subject: [PATCH 066/182] spi: qup: Add device tree bindings information
-
-The Qualcomm Universal Peripheral (QUP) core is an
-AHB slave that provides a common data path (an output
-FIFO and an input FIFO) for serial peripheral interface
-(SPI) mini-core.
-
-Signed-off-by: Ivan T. Ivanov <iivanov@mm-sol.com>
-Signed-off-by: Mark Brown <broonie@linaro.org>
----
- .../devicetree/bindings/spi/qcom,spi-qup.txt       |   85 ++++++++++++++++++++
- 1 file changed, 85 insertions(+)
- create mode 100644 Documentation/devicetree/bindings/spi/qcom,spi-qup.txt
-
---- /dev/null
-+++ b/Documentation/devicetree/bindings/spi/qcom,spi-qup.txt
-@@ -0,0 +1,85 @@
-+Qualcomm Universal Peripheral (QUP) Serial Peripheral Interface (SPI)
-+
-+The QUP core is an AHB slave that provides a common data path (an output FIFO
-+and an input FIFO) for serial peripheral interface (SPI) mini-core.
-+
-+SPI in master mode supports up to 50MHz, up to four chip selects, programmable
-+data path from 4 bits to 32 bits and numerous protocol variants.
-+
-+Required properties:
-+- compatible:     Should contain "qcom,spi-qup-v2.1.1" or "qcom,spi-qup-v2.2.1"
-+- reg:            Should contain base register location and length
-+- interrupts:     Interrupt number used by this controller
-+
-+- clocks:         Should contain the core clock and the AHB clock.
-+- clock-names:    Should be "core" for the core clock and "iface" for the
-+                  AHB clock.
-+
-+- #address-cells: Number of cells required to define a chip select
-+                  address on the SPI bus. Should be set to 1.
-+- #size-cells:    Should be zero.
-+
-+Optional properties:
-+- spi-max-frequency: Specifies maximum SPI clock frequency,
-+                     Units - Hz. Definition as per
-+                     Documentation/devicetree/bindings/spi/spi-bus.txt
-+
-+SPI slave nodes must be children of the SPI master node and can contain
-+properties described in Documentation/devicetree/bindings/spi/spi-bus.txt
-+
-+Example:
-+
-+	spi_8: spi@f9964000 { /* BLSP2 QUP2 */
-+
-+		compatible = "qcom,spi-qup-v2";
-+		#address-cells = <1>;
-+		#size-cells = <0>;
-+		reg = <0xf9964000 0x1000>;
-+		interrupts = <0 102 0>;
-+		spi-max-frequency = <19200000>;
-+
-+		clocks = <&gcc GCC_BLSP2_QUP2_SPI_APPS_CLK>, <&gcc GCC_BLSP2_AHB_CLK>;
-+		clock-names = "core", "iface";
-+
-+		pinctrl-names = "default";
-+		pinctrl-0 = <&spi8_default>;
-+
-+		device@0 {
-+			compatible = "arm,pl022-dummy";
-+			#address-cells = <1>;
-+			#size-cells = <1>;
-+			reg = <0>; /* Chip select 0 */
-+			spi-max-frequency = <19200000>;
-+			spi-cpol;
-+		};
-+
-+		device@1 {
-+			compatible = "arm,pl022-dummy";
-+			#address-cells = <1>;
-+			#size-cells = <1>;
-+			reg = <1>; /* Chip select 1 */
-+			spi-max-frequency = <9600000>;
-+			spi-cpha;
-+		};
-+
-+		device@2 {
-+			compatible = "arm,pl022-dummy";
-+			#address-cells = <1>;
-+			#size-cells = <1>;
-+			reg = <2>; /* Chip select 2 */
-+			spi-max-frequency = <19200000>;
-+			spi-cpol;
-+			spi-cpha;
-+		};
-+
-+		device@3 {
-+			compatible = "arm,pl022-dummy";
-+			#address-cells = <1>;
-+			#size-cells = <1>;
-+			reg = <3>; /* Chip select 3 */
-+			spi-max-frequency = <19200000>;
-+			spi-cpol;
-+			spi-cpha;
-+			spi-cs-high;
-+		};
-+	};
diff --git a/target/linux/ipq806x/patches/0067-spi-qup-Remove-spi_master_put-in-spi_qup_remove.patch b/target/linux/ipq806x/patches/0067-spi-qup-Remove-spi_master_put-in-spi_qup_remove.patch
deleted file mode 100644
index 128eb23..0000000
--- a/target/linux/ipq806x/patches/0067-spi-qup-Remove-spi_master_put-in-spi_qup_remove.patch
+++ /dev/null
@@ -1,25 +0,0 @@
-From c6a3f7bda60cfd78c2b05e8b2ec0fbf0d39da9ea Mon Sep 17 00:00:00 2001
-From: Axel Lin <axel.lin@ingics.com>
-Date: Fri, 21 Feb 2014 09:33:16 +0800
-Subject: [PATCH 067/182] spi: qup: Remove spi_master_put in spi_qup_remove
-
-This driver uses devm_spi_register_master() so don't explicitly call
-spi_master_put() in spi_qup_remove().
-
-Signed-off-by: Axel Lin <axel.lin@ingics.com>
-Acked-by: Ivan T. Ivanov <iivanov@mm-sol.com>
-Signed-off-by: Mark Brown <broonie@linaro.org>
----
- drivers/spi/spi-qup.c |    1 -
- 1 file changed, 1 deletion(-)
-
---- a/drivers/spi/spi-qup.c
-+++ b/drivers/spi/spi-qup.c
-@@ -802,7 +802,6 @@ static int spi_qup_remove(struct platfor
- 
- 	pm_runtime_put_noidle(&pdev->dev);
- 	pm_runtime_disable(&pdev->dev);
--	spi_master_put(master);
- 	return 0;
- }
- 
diff --git a/target/linux/ipq806x/patches/0068-spi-qup-Convert-ot-let-spi-core-handle-checking-tran.patch b/target/linux/ipq806x/patches/0068-spi-qup-Convert-ot-let-spi-core-handle-checking-tran.patch
deleted file mode 100644
index 4b025b5..0000000
--- a/target/linux/ipq806x/patches/0068-spi-qup-Convert-ot-let-spi-core-handle-checking-tran.patch
+++ /dev/null
@@ -1,64 +0,0 @@
-From a4b122f945c564e47a42a9665b484785e86648de Mon Sep 17 00:00:00 2001
-From: Axel Lin <axel.lin@ingics.com>
-Date: Fri, 21 Feb 2014 09:34:16 +0800
-Subject: [PATCH 068/182] spi: qup: Convert ot let spi core handle checking
- transfer speed
-
-Set master->max_speed_hz then spi core will handle checking transfer speed.
-So we can remove the same checking in this driver.
-
-Also remove checking spi->chip_select in spi_qup_setup(), the checking is done
-by spi core.
-
-Signed-off-by: Axel Lin <axel.lin@ingics.com>
-Acked-by: Ivan T. Ivanov <iivanov@mm-sol.com>
-Signed-off-by: Mark Brown <broonie@linaro.org>
----
- drivers/spi/spi-qup.c |   15 +--------------
- 1 file changed, 1 insertion(+), 14 deletions(-)
-
---- a/drivers/spi/spi-qup.c
-+++ b/drivers/spi/spi-qup.c
-@@ -134,7 +134,6 @@ struct spi_qup {
- 	struct clk		*cclk;	/* core clock */
- 	struct clk		*iclk;	/* interface clock */
- 	int			irq;
--	u32			max_speed_hz;
- 	spinlock_t		lock;
- 
- 	int			in_fifo_sz;
-@@ -517,18 +516,6 @@ static int spi_qup_setup(struct spi_devi
- 	struct spi_qup *controller = spi_master_get_devdata(spi->master);
- 	struct spi_qup_device *chip = spi_get_ctldata(spi);
- 
--	if (spi->chip_select >= spi->master->num_chipselect) {
--		dev_err(controller->dev, "invalid chip_select %d\n",
--			spi->chip_select);
--		return -EINVAL;
--	}
--
--	if (spi->max_speed_hz > controller->max_speed_hz) {
--		dev_err(controller->dev, "invalid max_speed_hz %d\n",
--			spi->max_speed_hz);
--		return -EINVAL;
--	}
--
- 	if (!chip) {
- 		/* First setup */
- 		chip = kzalloc(sizeof(*chip), GFP_KERNEL);
-@@ -629,6 +616,7 @@ static int spi_qup_probe(struct platform
- 	master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH | SPI_LOOP;
- 	master->num_chipselect = SPI_NUM_CHIPSELECTS;
- 	master->bits_per_word_mask = SPI_BPW_RANGE_MASK(4, 32);
-+	master->max_speed_hz = max_freq;
- 	master->setup = spi_qup_setup;
- 	master->cleanup = spi_qup_cleanup;
- 	master->set_cs = spi_qup_set_cs;
-@@ -645,7 +633,6 @@ static int spi_qup_probe(struct platform
- 	controller->iclk = iclk;
- 	controller->cclk = cclk;
- 	controller->irq = irq;
--	controller->max_speed_hz = max_freq;
- 
- 	spin_lock_init(&controller->lock);
- 	init_completion(&controller->done);
diff --git a/target/linux/ipq806x/patches/0069-spi-qup-Fix-build-error-due-to-a-typo.patch b/target/linux/ipq806x/patches/0069-spi-qup-Fix-build-error-due-to-a-typo.patch
deleted file mode 100644
index 4209485..0000000
--- a/target/linux/ipq806x/patches/0069-spi-qup-Fix-build-error-due-to-a-typo.patch
+++ /dev/null
@@ -1,43 +0,0 @@
-From df7444fdd808111f7df507b00d357b44d3259376 Mon Sep 17 00:00:00 2001
-From: Axel Lin <axel.lin@ingics.com>
-Date: Sun, 23 Feb 2014 13:27:16 +0800
-Subject: [PATCH 069/182] spi: qup: Fix build error due to a typo
-
-Fix below build error when CONFIG_PM_RUNTIME=y:
-
-C [M]  drivers/spi/spi-qup.o
-drivers/spi/spi-qup.c: In function 'spi_qup_pm_suspend_runtime':
-drivers/spi/spi-qup.c:712:12: error: 'QUP_CLOCK_AUTO_GATE' undeclared (first use in this function)
-drivers/spi/spi-qup.c:712:12: note: each undeclared identifier is reported only once for each function it appears in
-drivers/spi/spi-qup.c: In function 'spi_qup_pm_resume_runtime':
-drivers/spi/spi-qup.c:725:13: error: 'QUP_CLOCK_AUTO_GATE' undeclared (first use in this function)
-make[2]: *** [drivers/spi/spi-qup.o] Error 1
-make[1]: *** [drivers/spi] Error 2
-make: *** [drivers] Error 2
-
-Signed-off-by: Axel Lin <axel.lin@ingics.com>
-Signed-off-by: Mark Brown <broonie@linaro.org>
----
- drivers/spi/spi-qup.c |    4 ++--
- 1 file changed, 2 insertions(+), 2 deletions(-)
-
---- a/drivers/spi/spi-qup.c
-+++ b/drivers/spi/spi-qup.c
-@@ -709,7 +709,7 @@ static int spi_qup_pm_suspend_runtime(st
- 
- 	/* Enable clocks auto gaiting */
- 	config = readl(controller->base + QUP_CONFIG);
--	config |= QUP_CLOCK_AUTO_GATE;
-+	config |= QUP_CONFIG_CLOCK_AUTO_GATE;
- 	writel_relaxed(config, controller->base + QUP_CONFIG);
- 	return 0;
- }
-@@ -722,7 +722,7 @@ static int spi_qup_pm_resume_runtime(str
- 
- 	/* Disable clocks auto gaiting */
- 	config = readl_relaxed(controller->base + QUP_CONFIG);
--	config &= ~QUP_CLOCK_AUTO_GATE;
-+	config &= ~QUP_CONFIG_CLOCK_AUTO_GATE;
- 	writel_relaxed(config, controller->base + QUP_CONFIG);
- 	return 0;
- }
diff --git a/target/linux/ipq806x/patches/0070-spi-qup-Enable-driver-compilation-with-COMPILE_TEST.patch b/target/linux/ipq806x/patches/0070-spi-qup-Enable-driver-compilation-with-COMPILE_TEST.patch
deleted file mode 100644
index 0058992..0000000
--- a/target/linux/ipq806x/patches/0070-spi-qup-Enable-driver-compilation-with-COMPILE_TEST.patch
+++ /dev/null
@@ -1,25 +0,0 @@
-From 4706cb5844e0f1a08ab25e103f6415fde5328ddc Mon Sep 17 00:00:00 2001
-From: Axel Lin <axel.lin@ingics.com>
-Date: Sun, 23 Feb 2014 13:28:33 +0800
-Subject: [PATCH 070/182] spi: qup: Enable driver compilation with
- COMPILE_TEST
-
-This helps increasing build testing coverage.
-
-Signed-off-by: Axel Lin <axel.lin@ingics.com>
-Signed-off-by: Mark Brown <broonie@linaro.org>
----
- drivers/spi/Kconfig |    2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/drivers/spi/Kconfig
-+++ b/drivers/spi/Kconfig
-@@ -392,7 +392,7 @@ config SPI_RSPI
- 
- config SPI_QUP
- 	tristate "Qualcomm SPI controller with QUP interface"
--	depends on ARCH_MSM_DT
-+	depends on ARCH_MSM_DT || COMPILE_TEST
- 	help
- 	  Qualcomm Universal Peripheral (QUP) core is an AHB slave that
- 	  provides a common data path (an output FIFO and an input FIFO)
diff --git a/target/linux/ipq806x/patches/0071-spi-qup-Depend-on-ARM-COMPILE_TEST-to-avoid-build-er.patch b/target/linux/ipq806x/patches/0071-spi-qup-Depend-on-ARM-COMPILE_TEST-to-avoid-build-er.patch
deleted file mode 100644
index 2711a2a..0000000
--- a/target/linux/ipq806x/patches/0071-spi-qup-Depend-on-ARM-COMPILE_TEST-to-avoid-build-er.patch
+++ /dev/null
@@ -1,35 +0,0 @@
-From 7137376bc6415ab9b2f0c5983245a1273812e8b9 Mon Sep 17 00:00:00 2001
-From: Axel Lin <axel.lin@ingics.com>
-Date: Mon, 24 Feb 2014 12:07:51 +0800
-Subject: [PATCH 071/182] spi: qup: Depend on ARM && COMPILE_TEST to avoid
- build error
-
-This driver uses writel_relaxed() which does not exist in x86, ppc, etc.
-Make it depend on ARM && COMPILE_TEST to avoid below build error:
-
-  CC [M]  drivers/spi/spi-qup.o
-drivers/spi/spi-qup.c: In function 'spi_qup_set_state':
-drivers/spi/spi-qup.c:180:3: error: implicit declaration of function 'writel_relaxed' [-Werror=implicit-function-declaration]
-cc1: some warnings being treated as errors
-make[2]: *** [drivers/spi/spi-qup.o] Error 1
-make[1]: *** [drivers/spi] Error 2
-make: *** [drivers] Error 2
-
-Reported-by: Stephen Rothwell <sfr@canb.auug.org.au>
-Signed-off-by: Axel Lin <axel.lin@ingics.com>
-Signed-off-by: Mark Brown <broonie@linaro.org>
----
- drivers/spi/Kconfig |    2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/drivers/spi/Kconfig
-+++ b/drivers/spi/Kconfig
-@@ -392,7 +392,7 @@ config SPI_RSPI
- 
- config SPI_QUP
- 	tristate "Qualcomm SPI controller with QUP interface"
--	depends on ARCH_MSM_DT || COMPILE_TEST
-+	depends on ARCH_MSM_DT || (ARM && COMPILE_TEST)
- 	help
- 	  Qualcomm Universal Peripheral (QUP) core is an AHB slave that
- 	  provides a common data path (an output FIFO and an input FIFO)
diff --git a/target/linux/ipq806x/patches/0072-spi-qup-Remove-module-version.patch b/target/linux/ipq806x/patches/0072-spi-qup-Remove-module-version.patch
deleted file mode 100644
index 6708238..0000000
--- a/target/linux/ipq806x/patches/0072-spi-qup-Remove-module-version.patch
+++ /dev/null
@@ -1,23 +0,0 @@
-From 7b8e00404cfc652abbd538df1365a8046ed0d782 Mon Sep 17 00:00:00 2001
-From: Axel Lin <axel.lin@ingics.com>
-Date: Mon, 24 Feb 2014 13:48:12 +0800
-Subject: [PATCH 072/182] spi: qup: Remove module version
-
-The module version is unlikely to be updated, use kernel version should be
-enough.
-
-Signed-off-by: Axel Lin <axel.lin@ingics.com>
-Acked-by: Ivan T. Ivanov <iivanov@mm-sol.com>
-Signed-off-by: Mark Brown <broonie@linaro.org>
----
- drivers/spi/spi-qup.c |    1 -
- 1 file changed, 1 deletion(-)
-
---- a/drivers/spi/spi-qup.c
-+++ b/drivers/spi/spi-qup.c
-@@ -819,5 +819,4 @@ static struct platform_driver spi_qup_dr
- module_platform_driver(spi_qup_driver);
- 
- MODULE_LICENSE("GPL v2");
--MODULE_VERSION("0.4");
- MODULE_ALIAS("platform:spi_qup");
diff --git a/target/linux/ipq806x/patches/0073-spi-qup-Get-rid-of-using-struct-spi_qup_device.patch b/target/linux/ipq806x/patches/0073-spi-qup-Get-rid-of-using-struct-spi_qup_device.patch
deleted file mode 100644
index b527af9..0000000
--- a/target/linux/ipq806x/patches/0073-spi-qup-Get-rid-of-using-struct-spi_qup_device.patch
+++ /dev/null
@@ -1,162 +0,0 @@
-From 3027505ab8c8cb17291e53bca1d7bd770539d468 Mon Sep 17 00:00:00 2001
-From: Axel Lin <axel.lin@ingics.com>
-Date: Mon, 24 Feb 2014 23:07:36 +0800
-Subject: [PATCH 073/182] spi: qup: Get rid of using struct spi_qup_device
-
-Current code uses struct spi_qup_device to store spi->mode and spi->chip_select
-settings. We can get these settings in spi_qup_transfer_one and spi_qup_set_cs
-without using struct spi_qup_device. Refactor the code a bit to remove
-spi_qup_setup(), spi_qup_cleanup(), and struct spi_qup_device.
-
-Signed-off-by: Axel Lin <axel.lin@ingics.com>
-Tested-by: Ivan T. Ivanov <iivanov@mm-sol.com>
-Signed-off-by: Mark Brown <broonie@linaro.org>
----
- drivers/spi/spi-qup.c |   61 ++++++++-----------------------------------------
- 1 file changed, 9 insertions(+), 52 deletions(-)
-
---- a/drivers/spi/spi-qup.c
-+++ b/drivers/spi/spi-qup.c
-@@ -123,11 +123,6 @@
- #define SPI_DELAY_THRESHOLD		1
- #define SPI_DELAY_RETRY			10
- 
--struct spi_qup_device {
--	int select;
--	u16 mode;
--};
--
- struct spi_qup {
- 	void __iomem		*base;
- 	struct device		*dev;
-@@ -338,14 +333,13 @@ static irqreturn_t spi_qup_qup_irq(int i
- 
- 
- /* set clock freq ... bits per word */
--static int spi_qup_io_config(struct spi_qup *controller,
--			   struct spi_qup_device *chip,
--			   struct spi_transfer *xfer)
-+static int spi_qup_io_config(struct spi_device *spi, struct spi_transfer *xfer)
- {
-+	struct spi_qup *controller = spi_master_get_devdata(spi->master);
- 	u32 config, iomode, mode;
- 	int ret, n_words, w_size;
- 
--	if (chip->mode & SPI_LOOP && xfer->len > controller->in_fifo_sz) {
-+	if (spi->mode & SPI_LOOP && xfer->len > controller->in_fifo_sz) {
- 		dev_err(controller->dev, "too big size for loopback %d > %d\n",
- 			xfer->len, controller->in_fifo_sz);
- 		return -EIO;
-@@ -399,12 +393,12 @@ static int spi_qup_io_config(struct spi_
- 
- 	config = readl_relaxed(controller->base + SPI_CONFIG);
- 
--	if (chip->mode & SPI_LOOP)
-+	if (spi->mode & SPI_LOOP)
- 		config |= SPI_CONFIG_LOOPBACK;
- 	else
- 		config &= ~SPI_CONFIG_LOOPBACK;
- 
--	if (chip->mode & SPI_CPHA)
-+	if (spi->mode & SPI_CPHA)
- 		config &= ~SPI_CONFIG_INPUT_FIRST;
- 	else
- 		config |= SPI_CONFIG_INPUT_FIRST;
-@@ -413,7 +407,7 @@ static int spi_qup_io_config(struct spi_
- 	 * HS_MODE improves signal stability for spi-clk high rates,
- 	 * but is invalid in loop back mode.
- 	 */
--	if ((xfer->speed_hz >= SPI_HS_MIN_RATE) && !(chip->mode & SPI_LOOP))
-+	if ((xfer->speed_hz >= SPI_HS_MIN_RATE) && !(spi->mode & SPI_LOOP))
- 		config |= SPI_CONFIG_HS_MODE;
- 	else
- 		config &= ~SPI_CONFIG_HS_MODE;
-@@ -433,7 +427,6 @@ static int spi_qup_io_config(struct spi_
- static void spi_qup_set_cs(struct spi_device *spi, bool enable)
- {
- 	struct spi_qup *controller = spi_master_get_devdata(spi->master);
--	struct spi_qup_device *chip = spi_get_ctldata(spi);
- 
- 	u32 iocontol, mask;
- 
-@@ -444,9 +437,9 @@ static void spi_qup_set_cs(struct spi_de
- 	iocontol |= SPI_IO_C_FORCE_CS;
- 
- 	iocontol &= ~SPI_IO_C_CS_SELECT_MASK;
--	iocontol |= SPI_IO_C_CS_SELECT(chip->select);
-+	iocontol |= SPI_IO_C_CS_SELECT(spi->chip_select);
- 
--	mask = SPI_IO_C_CS_N_POLARITY_0 << chip->select;
-+	mask = SPI_IO_C_CS_N_POLARITY_0 << spi->chip_select;
- 
- 	if (enable)
- 		iocontol |= mask;
-@@ -461,11 +454,10 @@ static int spi_qup_transfer_one(struct s
- 			      struct spi_transfer *xfer)
- {
- 	struct spi_qup *controller = spi_master_get_devdata(master);
--	struct spi_qup_device *chip = spi_get_ctldata(spi);
- 	unsigned long timeout, flags;
- 	int ret = -EIO;
- 
--	ret = spi_qup_io_config(controller, chip, xfer);
-+	ret = spi_qup_io_config(spi, xfer);
- 	if (ret)
- 		return ret;
- 
-@@ -511,38 +503,6 @@ exit:
- 	return ret;
- }
- 
--static int spi_qup_setup(struct spi_device *spi)
--{
--	struct spi_qup *controller = spi_master_get_devdata(spi->master);
--	struct spi_qup_device *chip = spi_get_ctldata(spi);
--
--	if (!chip) {
--		/* First setup */
--		chip = kzalloc(sizeof(*chip), GFP_KERNEL);
--		if (!chip) {
--			dev_err(controller->dev, "no memory for chip data\n");
--			return -ENOMEM;
--		}
--
--		chip->mode = spi->mode;
--		chip->select = spi->chip_select;
--		spi_set_ctldata(spi, chip);
--	}
--
--	return 0;
--}
--
--static void spi_qup_cleanup(struct spi_device *spi)
--{
--	struct spi_qup_device *chip = spi_get_ctldata(spi);
--
--	if (!chip)
--		return;
--
--	spi_set_ctldata(spi, NULL);
--	kfree(chip);
--}
--
- static int spi_qup_probe(struct platform_device *pdev)
- {
- 	struct spi_master *master;
-@@ -561,7 +521,6 @@ static int spi_qup_probe(struct platform
- 		return PTR_ERR(base);
- 
- 	irq = platform_get_irq(pdev, 0);
--
- 	if (irq < 0)
- 		return irq;
- 
-@@ -617,8 +576,6 @@ static int spi_qup_probe(struct platform
- 	master->num_chipselect = SPI_NUM_CHIPSELECTS;
- 	master->bits_per_word_mask = SPI_BPW_RANGE_MASK(4, 32);
- 	master->max_speed_hz = max_freq;
--	master->setup = spi_qup_setup;
--	master->cleanup = spi_qup_cleanup;
- 	master->set_cs = spi_qup_set_cs;
- 	master->transfer_one = spi_qup_transfer_one;
- 	master->dev.of_node = pdev->dev.of_node;
diff --git a/target/linux/ipq806x/patches/0074-spi-qup-Depend-on-ARCH_QCOM.patch b/target/linux/ipq806x/patches/0074-spi-qup-Depend-on-ARCH_QCOM.patch
deleted file mode 100644
index 7b924f1..0000000
--- a/target/linux/ipq806x/patches/0074-spi-qup-Depend-on-ARCH_QCOM.patch
+++ /dev/null
@@ -1,31 +0,0 @@
-From 5148138d2b879c7b024fa3865fb3980c6dc84fcc Mon Sep 17 00:00:00 2001
-From: Paul Bolle <pebolle@tiscali.nl>
-Date: Mon, 7 Apr 2014 16:15:45 +0200
-Subject: [PATCH 074/182] spi: qup: Depend on ARCH_QCOM
-
-Commit 8fc1b0f87d9f ("ARM: qcom: Split Qualcomm support into legacy and
-multiplatform") removed Kconfig symbol ARCH_MSM_DT. But that commit
-left one (optional) dependency on ARCH_MSM_DT untouched.
-
-Three Kconfig symbols used to depend on ARCH_MSM_DT: ARCH_MSM8X60,
-ARCH_MSM8960, and ARCH_MSM8974. These three symbols now depend on
-ARCH_QCOM. So it appears this driver needs to depend on ARCH_QCOM too.
-
-Signed-off-by: Paul Bolle <pebolle@tiscali.nl>
-Reviewed-by: Stephen Boyd <sboyd@codeaurora.org>
-Signed-off-by: Mark Brown <broonie@linaro.org>
----
- drivers/spi/Kconfig |    2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/drivers/spi/Kconfig
-+++ b/drivers/spi/Kconfig
-@@ -392,7 +392,7 @@ config SPI_RSPI
- 
- config SPI_QUP
- 	tristate "Qualcomm SPI controller with QUP interface"
--	depends on ARCH_MSM_DT || (ARM && COMPILE_TEST)
-+	depends on ARCH_QCOM || (ARM && COMPILE_TEST)
- 	help
- 	  Qualcomm Universal Peripheral (QUP) core is an AHB slave that
- 	  provides a common data path (an output FIFO and an input FIFO)
diff --git a/target/linux/ipq806x/patches/0075-spi-qup-Correct-selection-of-FIFO-Block-mode.patch b/target/linux/ipq806x/patches/0075-spi-qup-Correct-selection-of-FIFO-Block-mode.patch
deleted file mode 100644
index 0fd095a..0000000
--- a/target/linux/ipq806x/patches/0075-spi-qup-Correct-selection-of-FIFO-Block-mode.patch
+++ /dev/null
@@ -1,34 +0,0 @@
-From e8e77359524e6629bac68db4183694fccffaed8e Mon Sep 17 00:00:00 2001
-From: Andy Gross <agross@codeaurora.org>
-Date: Tue, 13 May 2014 16:34:42 -0500
-Subject: [PATCH 075/182] spi: qup: Correct selection of FIFO/Block mode
-
-This patch fixes the calculation for determining whether to use FIFO or BLOCK
-mode.
-
-Signed-off-by: Andy Gross <agross@codeaurora.org>
-Signed-off-by: Mark Brown <broonie@linaro.org>
----
- drivers/spi/spi-qup.c |    4 ++--
- 1 file changed, 2 insertions(+), 2 deletions(-)
-
---- a/drivers/spi/spi-qup.c
-+++ b/drivers/spi/spi-qup.c
-@@ -287,7 +287,7 @@ static irqreturn_t spi_qup_qup_irq(int i
- 	writel_relaxed(opflags, controller->base + QUP_OPERATIONAL);
- 
- 	if (!xfer) {
--		dev_err_ratelimited(controller->dev, "unexpected irq %x08 %x08 %x08\n",
-+		dev_err_ratelimited(controller->dev, "unexpected irq %08x %08x %08x\n",
- 				    qup_err, spi_err, opflags);
- 		return IRQ_HANDLED;
- 	}
-@@ -366,7 +366,7 @@ static int spi_qup_io_config(struct spi_
- 	n_words = xfer->len / w_size;
- 	controller->w_size = w_size;
- 
--	if (n_words <= controller->in_fifo_sz) {
-+	if (n_words <= (controller->in_fifo_sz / sizeof(u32))) {
- 		mode = QUP_IO_M_MODE_FIFO;
- 		writel_relaxed(n_words, controller->base + QUP_MX_READ_CNT);
- 		writel_relaxed(n_words, controller->base + QUP_MX_WRITE_CNT);
diff --git a/target/linux/ipq806x/patches/0078-clk-qcom-Consolidate-common-probe-code.patch b/target/linux/ipq806x/patches/0078-clk-qcom-Consolidate-common-probe-code.patch
deleted file mode 100644
index 25b6ac2..0000000
--- a/target/linux/ipq806x/patches/0078-clk-qcom-Consolidate-common-probe-code.patch
+++ /dev/null
@@ -1,734 +0,0 @@
-From d79cb0c583772f38a9367af106d61bcf8bfa08e4 Mon Sep 17 00:00:00 2001
-From: Stephen Boyd <sboyd@codeaurora.org>
-Date: Fri, 21 Mar 2014 17:59:37 -0700
-Subject: [PATCH 078/182] clk: qcom: Consolidate common probe code
-
-Most of the probe code is the same between all the different
-clock controllers. Consolidate the code into a common.c file.
-This makes changes to the common probe parts easier and reduces
-chances for bugs.
-
-Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
-Signed-off-by: Kumar Gala <galak@codeaurora.org>
----
- drivers/clk/qcom/Makefile       |    1 +
- drivers/clk/qcom/common.c       |   99 +++++++++++++++++++++++++++++++++++++++
- drivers/clk/qcom/common.h       |   34 ++++++++++++++
- drivers/clk/qcom/gcc-msm8660.c  |   87 +++++-----------------------------
- drivers/clk/qcom/gcc-msm8960.c  |   77 +++++-------------------------
- drivers/clk/qcom/gcc-msm8974.c  |   77 +++++-------------------------
- drivers/clk/qcom/mmcc-msm8960.c |   78 +++++-------------------------
- drivers/clk/qcom/mmcc-msm8974.c |   80 +++++++------------------------
- 8 files changed, 196 insertions(+), 337 deletions(-)
- create mode 100644 drivers/clk/qcom/common.c
- create mode 100644 drivers/clk/qcom/common.h
-
---- a/drivers/clk/qcom/Makefile
-+++ b/drivers/clk/qcom/Makefile
-@@ -1,5 +1,6 @@
- obj-$(CONFIG_COMMON_CLK_QCOM) += clk-qcom.o
- 
-+clk-qcom-y += common.o
- clk-qcom-y += clk-regmap.o
- clk-qcom-y += clk-pll.o
- clk-qcom-y += clk-rcg.o
---- /dev/null
-+++ b/drivers/clk/qcom/common.c
-@@ -0,0 +1,99 @@
-+/*
-+ * Copyright (c) 2013-2014, The Linux Foundation. All rights reserved.
-+ *
-+ * This software is licensed under the terms of the GNU General Public
-+ * License version 2, as published by the Free Software Foundation, and
-+ * may be copied, distributed, and modified under those terms.
-+ *
-+ * 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/export.h>
-+#include <linux/regmap.h>
-+#include <linux/platform_device.h>
-+#include <linux/clk-provider.h>
-+#include <linux/reset-controller.h>
-+
-+#include "common.h"
-+#include "clk-regmap.h"
-+#include "reset.h"
-+
-+struct qcom_cc {
-+	struct qcom_reset_controller reset;
-+	struct clk_onecell_data data;
-+	struct clk *clks[];
-+};
-+
-+int qcom_cc_probe(struct platform_device *pdev, const struct qcom_cc_desc *desc)
-+{
-+	void __iomem *base;
-+	struct resource *res;
-+	int i, ret;
-+	struct device *dev = &pdev->dev;
-+	struct clk *clk;
-+	struct clk_onecell_data *data;
-+	struct clk **clks;
-+	struct regmap *regmap;
-+	struct qcom_reset_controller *reset;
-+	struct qcom_cc *cc;
-+	size_t num_clks = desc->num_clks;
-+	struct clk_regmap **rclks = desc->clks;
-+
-+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-+	base = devm_ioremap_resource(dev, res);
-+	if (IS_ERR(base))
-+		return PTR_ERR(base);
-+
-+	regmap = devm_regmap_init_mmio(dev, base, desc->config);
-+	if (IS_ERR(regmap))
-+		return PTR_ERR(regmap);
-+
-+	cc = devm_kzalloc(dev, sizeof(*cc) + sizeof(*clks) * num_clks,
-+			  GFP_KERNEL);
-+	if (!cc)
-+		return -ENOMEM;
-+
-+	clks = cc->clks;
-+	data = &cc->data;
-+	data->clks = clks;
-+	data->clk_num = num_clks;
-+
-+	for (i = 0; i < num_clks; i++) {
-+		if (!rclks[i])
-+			continue;
-+		clk = devm_clk_register_regmap(dev, rclks[i]);
-+		if (IS_ERR(clk))
-+			return PTR_ERR(clk);
-+		clks[i] = clk;
-+	}
-+
-+	ret = of_clk_add_provider(dev->of_node, of_clk_src_onecell_get, data);
-+	if (ret)
-+		return ret;
-+
-+	reset = &cc->reset;
-+	reset->rcdev.of_node = dev->of_node;
-+	reset->rcdev.ops = &qcom_reset_ops;
-+	reset->rcdev.owner = dev->driver->owner;
-+	reset->rcdev.nr_resets = desc->num_resets;
-+	reset->regmap = regmap;
-+	reset->reset_map = desc->resets;
-+	platform_set_drvdata(pdev, &reset->rcdev);
-+
-+	ret = reset_controller_register(&reset->rcdev);
-+	if (ret)
-+		of_clk_del_provider(dev->of_node);
-+
-+	return ret;
-+}
-+EXPORT_SYMBOL_GPL(qcom_cc_probe);
-+
-+void qcom_cc_remove(struct platform_device *pdev)
-+{
-+	of_clk_del_provider(pdev->dev.of_node);
-+	reset_controller_unregister(platform_get_drvdata(pdev));
-+}
-+EXPORT_SYMBOL_GPL(qcom_cc_remove);
---- /dev/null
-+++ b/drivers/clk/qcom/common.h
-@@ -0,0 +1,34 @@
-+/*
-+ * Copyright (c) 2014, The Linux Foundation. All rights reserved.
-+ *
-+ * This software is licensed under the terms of the GNU General Public
-+ * License version 2, as published by the Free Software Foundation, and
-+ * may be copied, distributed, and modified under those terms.
-+ *
-+ * 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 __QCOM_CLK_COMMON_H__
-+#define __QCOM_CLK_COMMON_H__
-+
-+struct platform_device;
-+struct regmap_config;
-+struct clk_regmap;
-+struct qcom_reset_map;
-+
-+struct qcom_cc_desc {
-+	const struct regmap_config *config;
-+	struct clk_regmap **clks;
-+	size_t num_clks;
-+	const struct qcom_reset_map *resets;
-+	size_t num_resets;
-+};
-+
-+extern int qcom_cc_probe(struct platform_device *pdev,
-+			 const struct qcom_cc_desc *desc);
-+
-+extern void qcom_cc_remove(struct platform_device *pdev);
-+
-+#endif
---- a/drivers/clk/qcom/gcc-msm8660.c
-+++ b/drivers/clk/qcom/gcc-msm8660.c
-@@ -25,6 +25,7 @@
- #include <dt-bindings/clock/qcom,gcc-msm8660.h>
- #include <dt-bindings/reset/qcom,gcc-msm8660.h>
- 
-+#include "common.h"
- #include "clk-regmap.h"
- #include "clk-pll.h"
- #include "clk-rcg.h"
-@@ -2701,94 +2702,28 @@ static const struct regmap_config gcc_ms
- 	.fast_io	= true,
- };
- 
-+static const struct qcom_cc_desc gcc_msm8660_desc = {
-+	.config = &gcc_msm8660_regmap_config,
-+	.clks = gcc_msm8660_clks,
-+	.num_clks = ARRAY_SIZE(gcc_msm8660_clks),
-+	.resets = gcc_msm8660_resets,
-+	.num_resets = ARRAY_SIZE(gcc_msm8660_resets),
-+};
-+
- static const struct of_device_id gcc_msm8660_match_table[] = {
- 	{ .compatible = "qcom,gcc-msm8660" },
- 	{ }
- };
- MODULE_DEVICE_TABLE(of, gcc_msm8660_match_table);
- 
--struct qcom_cc {
--	struct qcom_reset_controller reset;
--	struct clk_onecell_data data;
--	struct clk *clks[];
--};
--
- static int gcc_msm8660_probe(struct platform_device *pdev)
- {
--	void __iomem *base;
--	struct resource *res;
--	int i, ret;
--	struct device *dev = &pdev->dev;
--	struct clk *clk;
--	struct clk_onecell_data *data;
--	struct clk **clks;
--	struct regmap *regmap;
--	size_t num_clks;
--	struct qcom_reset_controller *reset;
--	struct qcom_cc *cc;
--
--	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
--	base = devm_ioremap_resource(dev, res);
--	if (IS_ERR(base))
--		return PTR_ERR(base);
--
--	regmap = devm_regmap_init_mmio(dev, base, &gcc_msm8660_regmap_config);
--	if (IS_ERR(regmap))
--		return PTR_ERR(regmap);
--
--	num_clks = ARRAY_SIZE(gcc_msm8660_clks);
--	cc = devm_kzalloc(dev, sizeof(*cc) + sizeof(*clks) * num_clks,
--			  GFP_KERNEL);
--	if (!cc)
--		return -ENOMEM;
--
--	clks = cc->clks;
--	data = &cc->data;
--	data->clks = clks;
--	data->clk_num = num_clks;
--
--	/* Temporary until RPM clocks supported */
--	clk = clk_register_fixed_rate(dev, "cxo", NULL, CLK_IS_ROOT, 19200000);
--	if (IS_ERR(clk))
--		return PTR_ERR(clk);
--
--	clk = clk_register_fixed_rate(dev, "pxo", NULL, CLK_IS_ROOT, 27000000);
--	if (IS_ERR(clk))
--		return PTR_ERR(clk);
--
--	for (i = 0; i < num_clks; i++) {
--		if (!gcc_msm8660_clks[i])
--			continue;
--		clk = devm_clk_register_regmap(dev, gcc_msm8660_clks[i]);
--		if (IS_ERR(clk))
--			return PTR_ERR(clk);
--		clks[i] = clk;
--	}
--
--	ret = of_clk_add_provider(dev->of_node, of_clk_src_onecell_get, data);
--	if (ret)
--		return ret;
--
--	reset = &cc->reset;
--	reset->rcdev.of_node = dev->of_node;
--	reset->rcdev.ops = &qcom_reset_ops,
--	reset->rcdev.owner = THIS_MODULE,
--	reset->rcdev.nr_resets = ARRAY_SIZE(gcc_msm8660_resets),
--	reset->regmap = regmap;
--	reset->reset_map = gcc_msm8660_resets,
--	platform_set_drvdata(pdev, &reset->rcdev);
--
--	ret = reset_controller_register(&reset->rcdev);
--	if (ret)
--		of_clk_del_provider(dev->of_node);
--
--	return ret;
-+	return qcom_cc_probe(pdev, &gcc_msm8660_desc);
- }
- 
- static int gcc_msm8660_remove(struct platform_device *pdev)
- {
--	of_clk_del_provider(pdev->dev.of_node);
--	reset_controller_unregister(platform_get_drvdata(pdev));
-+	qcom_cc_remove(pdev);
- 	return 0;
- }
- 
---- a/drivers/clk/qcom/gcc-msm8960.c
-+++ b/drivers/clk/qcom/gcc-msm8960.c
-@@ -25,6 +25,7 @@
- #include <dt-bindings/clock/qcom,gcc-msm8960.h>
- #include <dt-bindings/reset/qcom,gcc-msm8960.h>
- 
-+#include "common.h"
- #include "clk-regmap.h"
- #include "clk-pll.h"
- #include "clk-rcg.h"
-@@ -2875,51 +2876,24 @@ static const struct regmap_config gcc_ms
- 	.fast_io	= true,
- };
- 
-+static const struct qcom_cc_desc gcc_msm8960_desc = {
-+	.config = &gcc_msm8960_regmap_config,
-+	.clks = gcc_msm8960_clks,
-+	.num_clks = ARRAY_SIZE(gcc_msm8960_clks),
-+	.resets = gcc_msm8960_resets,
-+	.num_resets = ARRAY_SIZE(gcc_msm8960_resets),
-+};
-+
- static const struct of_device_id gcc_msm8960_match_table[] = {
- 	{ .compatible = "qcom,gcc-msm8960" },
- 	{ }
- };
- MODULE_DEVICE_TABLE(of, gcc_msm8960_match_table);
- 
--struct qcom_cc {
--	struct qcom_reset_controller reset;
--	struct clk_onecell_data data;
--	struct clk *clks[];
--};
--
- static int gcc_msm8960_probe(struct platform_device *pdev)
- {
--	void __iomem *base;
--	struct resource *res;
--	int i, ret;
--	struct device *dev = &pdev->dev;
- 	struct clk *clk;
--	struct clk_onecell_data *data;
--	struct clk **clks;
--	struct regmap *regmap;
--	size_t num_clks;
--	struct qcom_reset_controller *reset;
--	struct qcom_cc *cc;
--
--	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
--	base = devm_ioremap_resource(dev, res);
--	if (IS_ERR(base))
--		return PTR_ERR(base);
--
--	regmap = devm_regmap_init_mmio(dev, base, &gcc_msm8960_regmap_config);
--	if (IS_ERR(regmap))
--		return PTR_ERR(regmap);
--
--	num_clks = ARRAY_SIZE(gcc_msm8960_clks);
--	cc = devm_kzalloc(dev, sizeof(*cc) + sizeof(*clks) * num_clks,
--			  GFP_KERNEL);
--	if (!cc)
--		return -ENOMEM;
--
--	clks = cc->clks;
--	data = &cc->data;
--	data->clks = clks;
--	data->clk_num = num_clks;
-+	struct device *dev = &pdev->dev;
- 
- 	/* Temporary until RPM clocks supported */
- 	clk = clk_register_fixed_rate(dev, "cxo", NULL, CLK_IS_ROOT, 19200000);
-@@ -2930,39 +2904,12 @@ static int gcc_msm8960_probe(struct plat
- 	if (IS_ERR(clk))
- 		return PTR_ERR(clk);
- 
--	for (i = 0; i < num_clks; i++) {
--		if (!gcc_msm8960_clks[i])
--			continue;
--		clk = devm_clk_register_regmap(dev, gcc_msm8960_clks[i]);
--		if (IS_ERR(clk))
--			return PTR_ERR(clk);
--		clks[i] = clk;
--	}
--
--	ret = of_clk_add_provider(dev->of_node, of_clk_src_onecell_get, data);
--	if (ret)
--		return ret;
--
--	reset = &cc->reset;
--	reset->rcdev.of_node = dev->of_node;
--	reset->rcdev.ops = &qcom_reset_ops,
--	reset->rcdev.owner = THIS_MODULE,
--	reset->rcdev.nr_resets = ARRAY_SIZE(gcc_msm8960_resets),
--	reset->regmap = regmap;
--	reset->reset_map = gcc_msm8960_resets,
--	platform_set_drvdata(pdev, &reset->rcdev);
--
--	ret = reset_controller_register(&reset->rcdev);
--	if (ret)
--		of_clk_del_provider(dev->of_node);
--
--	return ret;
-+	return qcom_cc_probe(pdev, &gcc_msm8960_desc);
- }
- 
- static int gcc_msm8960_remove(struct platform_device *pdev)
- {
--	of_clk_del_provider(pdev->dev.of_node);
--	reset_controller_unregister(platform_get_drvdata(pdev));
-+	qcom_cc_remove(pdev);
- 	return 0;
- }
- 
---- a/drivers/clk/qcom/gcc-msm8974.c
-+++ b/drivers/clk/qcom/gcc-msm8974.c
-@@ -25,6 +25,7 @@
- #include <dt-bindings/clock/qcom,gcc-msm8974.h>
- #include <dt-bindings/reset/qcom,gcc-msm8974.h>
- 
-+#include "common.h"
- #include "clk-regmap.h"
- #include "clk-pll.h"
- #include "clk-rcg.h"
-@@ -2574,51 +2575,24 @@ static const struct regmap_config gcc_ms
- 	.fast_io	= true,
- };
- 
-+static const struct qcom_cc_desc gcc_msm8974_desc = {
-+	.config = &gcc_msm8974_regmap_config,
-+	.clks = gcc_msm8974_clocks,
-+	.num_clks = ARRAY_SIZE(gcc_msm8974_clocks),
-+	.resets = gcc_msm8974_resets,
-+	.num_resets = ARRAY_SIZE(gcc_msm8974_resets),
-+};
-+
- static const struct of_device_id gcc_msm8974_match_table[] = {
- 	{ .compatible = "qcom,gcc-msm8974" },
- 	{ }
- };
- MODULE_DEVICE_TABLE(of, gcc_msm8974_match_table);
- 
--struct qcom_cc {
--	struct qcom_reset_controller reset;
--	struct clk_onecell_data data;
--	struct clk *clks[];
--};
--
- static int gcc_msm8974_probe(struct platform_device *pdev)
- {
--	void __iomem *base;
--	struct resource *res;
--	int i, ret;
--	struct device *dev = &pdev->dev;
- 	struct clk *clk;
--	struct clk_onecell_data *data;
--	struct clk **clks;
--	struct regmap *regmap;
--	size_t num_clks;
--	struct qcom_reset_controller *reset;
--	struct qcom_cc *cc;
--
--	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
--	base = devm_ioremap_resource(dev, res);
--	if (IS_ERR(base))
--		return PTR_ERR(base);
--
--	regmap = devm_regmap_init_mmio(dev, base, &gcc_msm8974_regmap_config);
--	if (IS_ERR(regmap))
--		return PTR_ERR(regmap);
--
--	num_clks = ARRAY_SIZE(gcc_msm8974_clocks);
--	cc = devm_kzalloc(dev, sizeof(*cc) + sizeof(*clks) * num_clks,
--			  GFP_KERNEL);
--	if (!cc)
--		return -ENOMEM;
--
--	clks = cc->clks;
--	data = &cc->data;
--	data->clks = clks;
--	data->clk_num = num_clks;
-+	struct device *dev = &pdev->dev;
- 
- 	/* Temporary until RPM clocks supported */
- 	clk = clk_register_fixed_rate(dev, "xo", NULL, CLK_IS_ROOT, 19200000);
-@@ -2631,39 +2605,12 @@ static int gcc_msm8974_probe(struct plat
- 	if (IS_ERR(clk))
- 		return PTR_ERR(clk);
- 
--	for (i = 0; i < num_clks; i++) {
--		if (!gcc_msm8974_clocks[i])
--			continue;
--		clk = devm_clk_register_regmap(dev, gcc_msm8974_clocks[i]);
--		if (IS_ERR(clk))
--			return PTR_ERR(clk);
--		clks[i] = clk;
--	}
--
--	ret = of_clk_add_provider(dev->of_node, of_clk_src_onecell_get, data);
--	if (ret)
--		return ret;
--
--	reset = &cc->reset;
--	reset->rcdev.of_node = dev->of_node;
--	reset->rcdev.ops = &qcom_reset_ops,
--	reset->rcdev.owner = THIS_MODULE,
--	reset->rcdev.nr_resets = ARRAY_SIZE(gcc_msm8974_resets),
--	reset->regmap = regmap;
--	reset->reset_map = gcc_msm8974_resets,
--	platform_set_drvdata(pdev, &reset->rcdev);
--
--	ret = reset_controller_register(&reset->rcdev);
--	if (ret)
--		of_clk_del_provider(dev->of_node);
--
--	return ret;
-+	return qcom_cc_probe(pdev, &gcc_msm8974_desc);
- }
- 
- static int gcc_msm8974_remove(struct platform_device *pdev)
- {
--	of_clk_del_provider(pdev->dev.of_node);
--	reset_controller_unregister(platform_get_drvdata(pdev));
-+	qcom_cc_remove(pdev);
- 	return 0;
- }
- 
---- a/drivers/clk/qcom/mmcc-msm8960.c
-+++ b/drivers/clk/qcom/mmcc-msm8960.c
-@@ -26,6 +26,7 @@
- #include <dt-bindings/clock/qcom,mmcc-msm8960.h>
- #include <dt-bindings/reset/qcom,mmcc-msm8960.h>
- 
-+#include "common.h"
- #include "clk-regmap.h"
- #include "clk-pll.h"
- #include "clk-rcg.h"
-@@ -2224,85 +2225,28 @@ static const struct regmap_config mmcc_m
- 	.fast_io	= true,
- };
- 
-+static const struct qcom_cc_desc mmcc_msm8960_desc = {
-+	.config = &mmcc_msm8960_regmap_config,
-+	.clks = mmcc_msm8960_clks,
-+	.num_clks = ARRAY_SIZE(mmcc_msm8960_clks),
-+	.resets = mmcc_msm8960_resets,
-+	.num_resets = ARRAY_SIZE(mmcc_msm8960_resets),
-+};
-+
- static const struct of_device_id mmcc_msm8960_match_table[] = {
- 	{ .compatible = "qcom,mmcc-msm8960" },
- 	{ }
- };
- MODULE_DEVICE_TABLE(of, mmcc_msm8960_match_table);
- 
--struct qcom_cc {
--	struct qcom_reset_controller reset;
--	struct clk_onecell_data data;
--	struct clk *clks[];
--};
--
- static int mmcc_msm8960_probe(struct platform_device *pdev)
- {
--	void __iomem *base;
--	struct resource *res;
--	int i, ret;
--	struct device *dev = &pdev->dev;
--	struct clk *clk;
--	struct clk_onecell_data *data;
--	struct clk **clks;
--	struct regmap *regmap;
--	size_t num_clks;
--	struct qcom_reset_controller *reset;
--	struct qcom_cc *cc;
--
--	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
--	base = devm_ioremap_resource(dev, res);
--	if (IS_ERR(base))
--		return PTR_ERR(base);
--
--	regmap = devm_regmap_init_mmio(dev, base, &mmcc_msm8960_regmap_config);
--	if (IS_ERR(regmap))
--		return PTR_ERR(regmap);
--
--	num_clks = ARRAY_SIZE(mmcc_msm8960_clks);
--	cc = devm_kzalloc(dev, sizeof(*cc) + sizeof(*clks) * num_clks,
--			  GFP_KERNEL);
--	if (!cc)
--		return -ENOMEM;
--
--	clks = cc->clks;
--	data = &cc->data;
--	data->clks = clks;
--	data->clk_num = num_clks;
--
--	for (i = 0; i < num_clks; i++) {
--		if (!mmcc_msm8960_clks[i])
--			continue;
--		clk = devm_clk_register_regmap(dev, mmcc_msm8960_clks[i]);
--		if (IS_ERR(clk))
--			return PTR_ERR(clk);
--		clks[i] = clk;
--	}
--
--	ret = of_clk_add_provider(dev->of_node, of_clk_src_onecell_get, data);
--	if (ret)
--		return ret;
--
--	reset = &cc->reset;
--	reset->rcdev.of_node = dev->of_node;
--	reset->rcdev.ops = &qcom_reset_ops,
--	reset->rcdev.owner = THIS_MODULE,
--	reset->rcdev.nr_resets = ARRAY_SIZE(mmcc_msm8960_resets),
--	reset->regmap = regmap;
--	reset->reset_map = mmcc_msm8960_resets,
--	platform_set_drvdata(pdev, &reset->rcdev);
--
--	ret = reset_controller_register(&reset->rcdev);
--	if (ret)
--		of_clk_del_provider(dev->of_node);
--
--	return ret;
-+	return qcom_cc_probe(pdev, &mmcc_msm8960_desc);
- }
- 
- static int mmcc_msm8960_remove(struct platform_device *pdev)
- {
--	of_clk_del_provider(pdev->dev.of_node);
--	reset_controller_unregister(platform_get_drvdata(pdev));
-+	qcom_cc_remove(pdev);
- 	return 0;
- }
- 
---- a/drivers/clk/qcom/mmcc-msm8974.c
-+++ b/drivers/clk/qcom/mmcc-msm8974.c
-@@ -25,6 +25,7 @@
- #include <dt-bindings/clock/qcom,mmcc-msm8974.h>
- #include <dt-bindings/reset/qcom,mmcc-msm8974.h>
- 
-+#include "common.h"
- #include "clk-regmap.h"
- #include "clk-pll.h"
- #include "clk-rcg.h"
-@@ -2527,88 +2528,39 @@ static const struct regmap_config mmcc_m
- 	.fast_io	= true,
- };
- 
-+static const struct qcom_cc_desc mmcc_msm8974_desc = {
-+	.config = &mmcc_msm8974_regmap_config,
-+	.clks = mmcc_msm8974_clocks,
-+	.num_clks = ARRAY_SIZE(mmcc_msm8974_clocks),
-+	.resets = mmcc_msm8974_resets,
-+	.num_resets = ARRAY_SIZE(mmcc_msm8974_resets),
-+};
-+
- static const struct of_device_id mmcc_msm8974_match_table[] = {
- 	{ .compatible = "qcom,mmcc-msm8974" },
- 	{ }
- };
- MODULE_DEVICE_TABLE(of, mmcc_msm8974_match_table);
- 
--struct qcom_cc {
--	struct qcom_reset_controller reset;
--	struct clk_onecell_data data;
--	struct clk *clks[];
--};
--
- static int mmcc_msm8974_probe(struct platform_device *pdev)
- {
--	void __iomem *base;
--	struct resource *res;
--	int i, ret;
--	struct device *dev = &pdev->dev;
--	struct clk *clk;
--	struct clk_onecell_data *data;
--	struct clk **clks;
-+	int ret;
- 	struct regmap *regmap;
--	size_t num_clks;
--	struct qcom_reset_controller *reset;
--	struct qcom_cc *cc;
--
--	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
--	base = devm_ioremap_resource(dev, res);
--	if (IS_ERR(base))
--		return PTR_ERR(base);
--
--	regmap = devm_regmap_init_mmio(dev, base, &mmcc_msm8974_regmap_config);
--	if (IS_ERR(regmap))
--		return PTR_ERR(regmap);
--
--	num_clks = ARRAY_SIZE(mmcc_msm8974_clocks);
--	cc = devm_kzalloc(dev, sizeof(*cc) + sizeof(*clks) * num_clks,
--			  GFP_KERNEL);
--	if (!cc)
--		return -ENOMEM;
--
--	clks = cc->clks;
--	data = &cc->data;
--	data->clks = clks;
--	data->clk_num = num_clks;
--
--	clk_pll_configure_sr_hpm_lp(&mmpll1, regmap, &mmpll1_config, true);
--	clk_pll_configure_sr_hpm_lp(&mmpll3, regmap, &mmpll3_config, false);
- 
--	for (i = 0; i < num_clks; i++) {
--		if (!mmcc_msm8974_clocks[i])
--			continue;
--		clk = devm_clk_register_regmap(dev, mmcc_msm8974_clocks[i]);
--		if (IS_ERR(clk))
--			return PTR_ERR(clk);
--		clks[i] = clk;
--	}
--
--	ret = of_clk_add_provider(dev->of_node, of_clk_src_onecell_get, data);
-+	ret = qcom_cc_probe(pdev, &mmcc_msm8974_desc);
- 	if (ret)
- 		return ret;
- 
--	reset = &cc->reset;
--	reset->rcdev.of_node = dev->of_node;
--	reset->rcdev.ops = &qcom_reset_ops,
--	reset->rcdev.owner = THIS_MODULE,
--	reset->rcdev.nr_resets = ARRAY_SIZE(mmcc_msm8974_resets),
--	reset->regmap = regmap;
--	reset->reset_map = mmcc_msm8974_resets,
--	platform_set_drvdata(pdev, &reset->rcdev);
--
--	ret = reset_controller_register(&reset->rcdev);
--	if (ret)
--		of_clk_del_provider(dev->of_node);
-+	regmap = dev_get_regmap(&pdev->dev, NULL);
-+	clk_pll_configure_sr_hpm_lp(&mmpll1, regmap, &mmpll1_config, true);
-+	clk_pll_configure_sr_hpm_lp(&mmpll3, regmap, &mmpll3_config, false);
- 
--	return ret;
-+	return 0;
- }
- 
- static int mmcc_msm8974_remove(struct platform_device *pdev)
- {
--	of_clk_del_provider(pdev->dev.of_node);
--	reset_controller_unregister(platform_get_drvdata(pdev));
-+	qcom_cc_remove(pdev);
- 	return 0;
- }
- 
diff --git a/target/linux/ipq806x/patches/0079-clk-qcom-Add-basic-support-for-APQ8064-global-clock-.patch b/target/linux/ipq806x/patches/0079-clk-qcom-Add-basic-support-for-APQ8064-global-clock-.patch
deleted file mode 100644
index 307e797..0000000
--- a/target/linux/ipq806x/patches/0079-clk-qcom-Add-basic-support-for-APQ8064-global-clock-.patch
+++ /dev/null
@@ -1,114 +0,0 @@
-From 0f171b8a6e1723f0ce6f98f8b3fba7d2583088c1 Mon Sep 17 00:00:00 2001
-From: Kumar Gala <galak@codeaurora.org>
-Date: Fri, 4 Apr 2014 11:31:29 -0500
-Subject: [PATCH 079/182] clk: qcom: Add basic support for APQ8064 global
- clock controller clocks
-
-The APQ8064 and MSM8960 share a significant amount of clock data and
-code between the two SoCs.  Rather than duplicating the data we just add
-support for a unqiue APQ8064 clock table into the MSM8960 code.
-
-For now add just enough clocks to get a basic serial port going on an
-APQ8064 device.
-
-Signed-off-by: Kumar Gala <galak@codeaurora.org>
-Reviewed-by: Stephen Boyd <sboyd@codeaurora.org>
-Signed-off-by: Mike Turquette <mturquette@linaro.org>
-[mturquette@linaro.org: trivial conflict due to missing ipq8064 support]
----
- .../devicetree/bindings/clock/qcom,gcc.txt         |    1 +
- drivers/clk/qcom/Kconfig                           |    4 +--
- drivers/clk/qcom/gcc-msm8960.c                     |   30 ++++++++++++++++++--
- 3 files changed, 30 insertions(+), 5 deletions(-)
-
---- a/Documentation/devicetree/bindings/clock/qcom,gcc.txt
-+++ b/Documentation/devicetree/bindings/clock/qcom,gcc.txt
-@@ -4,6 +4,7 @@ Qualcomm Global Clock & Reset Controller
- Required properties :
- - compatible : shall contain only one of the following:
- 
-+			"qcom,gcc-apq8064"
- 			"qcom,gcc-msm8660"
- 			"qcom,gcc-msm8960"
- 			"qcom,gcc-msm8974"
---- a/drivers/clk/qcom/Kconfig
-+++ b/drivers/clk/qcom/Kconfig
-@@ -13,10 +13,10 @@ config MSM_GCC_8660
- 	  i2c, USB, SD/eMMC, etc.
- 
- config MSM_GCC_8960
--	tristate "MSM8960 Global Clock Controller"
-+	tristate "APQ8064/MSM8960 Global Clock Controller"
- 	depends on COMMON_CLK_QCOM
- 	help
--	  Support for the global clock controller on msm8960 devices.
-+	  Support for the global clock controller on apq8064/msm8960 devices.
- 	  Say Y if you want to use peripheral devices such as UART, SPI,
- 	  i2c, USB, SD/eMMC, SATA, PCIe, etc.
- 
---- a/drivers/clk/qcom/gcc-msm8960.c
-+++ b/drivers/clk/qcom/gcc-msm8960.c
-@@ -1,5 +1,5 @@
- /*
-- * Copyright (c) 2013, The Linux Foundation. All rights reserved.
-+ * Copyright (c) 2013-2014, The Linux Foundation. All rights reserved.
-  *
-  * This software is licensed under the terms of the GNU General Public
-  * License version 2, as published by the Free Software Foundation, and
-@@ -2868,6 +2868,16 @@ static const struct qcom_reset_map gcc_m
- 	[RIVA_RESET] = { 0x35e0 },
- };
- 
-+static struct clk_regmap *gcc_apq8064_clks[] = {
-+	[PLL8] = &pll8.clkr,
-+	[PLL8_VOTE] = &pll8_vote,
-+	[GSBI7_UART_SRC] = &gsbi7_uart_src.clkr,
-+	[GSBI7_UART_CLK] = &gsbi7_uart_clk.clkr,
-+	[GSBI7_QUP_SRC] = &gsbi7_qup_src.clkr,
-+	[GSBI7_QUP_CLK] = &gsbi7_qup_clk.clkr,
-+	[GSBI7_H_CLK] = &gsbi7_h_clk.clkr,
-+};
-+
- static const struct regmap_config gcc_msm8960_regmap_config = {
- 	.reg_bits	= 32,
- 	.reg_stride	= 4,
-@@ -2884,8 +2894,17 @@ static const struct qcom_cc_desc gcc_msm
- 	.num_resets = ARRAY_SIZE(gcc_msm8960_resets),
- };
- 
-+static const struct qcom_cc_desc gcc_apq8064_desc = {
-+	.config = &gcc_msm8960_regmap_config,
-+	.clks = gcc_apq8064_clks,
-+	.num_clks = ARRAY_SIZE(gcc_apq8064_clks),
-+	.resets = gcc_msm8960_resets,
-+	.num_resets = ARRAY_SIZE(gcc_msm8960_resets),
-+};
-+
- static const struct of_device_id gcc_msm8960_match_table[] = {
--	{ .compatible = "qcom,gcc-msm8960" },
-+	{ .compatible = "qcom,gcc-msm8960", .data = &gcc_msm8960_desc },
-+	{ .compatible = "qcom,gcc-apq8064", .data = &gcc_apq8064_desc },
- 	{ }
- };
- MODULE_DEVICE_TABLE(of, gcc_msm8960_match_table);
-@@ -2894,6 +2913,11 @@ static int gcc_msm8960_probe(struct plat
- {
- 	struct clk *clk;
- 	struct device *dev = &pdev->dev;
-+	const struct of_device_id *match;
-+
-+	match = of_match_device(gcc_msm8960_match_table, &pdev->dev);
-+	if (!match)
-+		return -EINVAL;
- 
- 	/* Temporary until RPM clocks supported */
- 	clk = clk_register_fixed_rate(dev, "cxo", NULL, CLK_IS_ROOT, 19200000);
-@@ -2904,7 +2928,7 @@ static int gcc_msm8960_probe(struct plat
- 	if (IS_ERR(clk))
- 		return PTR_ERR(clk);
- 
--	return qcom_cc_probe(pdev, &gcc_msm8960_desc);
-+	return qcom_cc_probe(pdev, match->data);
- }
- 
- static int gcc_msm8960_remove(struct platform_device *pdev)
diff --git a/target/linux/ipq806x/patches/0080-clk-qcom-Various-fixes-for-MSM8960-s-global-clock-co.patch b/target/linux/ipq806x/patches/0080-clk-qcom-Various-fixes-for-MSM8960-s-global-clock-co.patch
deleted file mode 100644
index 9731771..0000000
--- a/target/linux/ipq806x/patches/0080-clk-qcom-Various-fixes-for-MSM8960-s-global-clock-co.patch
+++ /dev/null
@@ -1,92 +0,0 @@
-From 7456451e9df88d4c33479e3d4ea124d8a91ceb57 Mon Sep 17 00:00:00 2001
-From: Kumar Gala <galak@codeaurora.org>
-Date: Fri, 4 Apr 2014 11:32:56 -0500
-Subject: [PATCH 080/182] clk: qcom: Various fixes for MSM8960's global clock
- controller
-
-* Remove CE2_SLEEP_CLK, doesn't exist on 8960 family SoCs
-* Fix incorrect offset for PMIC_SSBI2_RESET
-* Fix typo:
-	SIC_TIC -> SPS_TIC_H
-	SFAB_ADM0_M2_A_CLK -> SFAB_ADM0_M2_H_CLK
-* Fix naming convention:
-	SFAB_CFPB_S_HCLK -> SFAB_CFPB_S_H_CLK
-	SATA_SRC_CLK -> SATA_CLK_SRC
-
-Signed-off-by: Kumar Gala <galak@codeaurora.org>
-Reviewed-by: Stephen Boyd <sboyd@codeaurora.org>
-Signed-off-by: Mike Turquette <mturquette@linaro.org>
----
- drivers/clk/qcom/gcc-msm8960.c               |    4 ++--
- include/dt-bindings/clock/qcom,gcc-msm8960.h |    7 +++----
- include/dt-bindings/reset/qcom,gcc-msm8960.h |    2 +-
- 3 files changed, 6 insertions(+), 7 deletions(-)
-
---- a/drivers/clk/qcom/gcc-msm8960.c
-+++ b/drivers/clk/qcom/gcc-msm8960.c
-@@ -2810,7 +2810,7 @@ static const struct qcom_reset_map gcc_m
- 	[PPSS_PROC_RESET] = { 0x2594, 1 },
- 	[PPSS_RESET] = { 0x2594},
- 	[DMA_BAM_RESET] = { 0x25c0, 7 },
--	[SIC_TIC_RESET] = { 0x2600, 7 },
-+	[SPS_TIC_H_RESET] = { 0x2600, 7 },
- 	[SLIMBUS_H_RESET] = { 0x2620, 7 },
- 	[SFAB_CFPB_M_RESET] = { 0x2680, 7 },
- 	[SFAB_CFPB_S_RESET] = { 0x26c0, 7 },
-@@ -2823,7 +2823,7 @@ static const struct qcom_reset_map gcc_m
- 	[SFAB_SFPB_M_RESET] = { 0x2780, 7 },
- 	[SFAB_SFPB_S_RESET] = { 0x27a0, 7 },
- 	[RPM_PROC_RESET] = { 0x27c0, 7 },
--	[PMIC_SSBI2_RESET] = { 0x270c, 12 },
-+	[PMIC_SSBI2_RESET] = { 0x280c, 12 },
- 	[SDC1_RESET] = { 0x2830 },
- 	[SDC2_RESET] = { 0x2850 },
- 	[SDC3_RESET] = { 0x2870 },
---- a/include/dt-bindings/clock/qcom,gcc-msm8960.h
-+++ b/include/dt-bindings/clock/qcom,gcc-msm8960.h
-@@ -51,7 +51,7 @@
- #define QDSS_TSCTR_CLK				34
- #define SFAB_ADM0_M0_A_CLK			35
- #define SFAB_ADM0_M1_A_CLK			36
--#define SFAB_ADM0_M2_A_CLK			37
-+#define SFAB_ADM0_M2_H_CLK			37
- #define ADM0_CLK				38
- #define ADM0_PBUS_CLK				39
- #define MSS_XPU_CLK				40
-@@ -99,7 +99,7 @@
- #define CFPB2_H_CLK				82
- #define SFAB_CFPB_M_H_CLK			83
- #define CFPB_MASTER_H_CLK			84
--#define SFAB_CFPB_S_HCLK			85
-+#define SFAB_CFPB_S_H_CLK			85
- #define CFPB_SPLITTER_H_CLK			86
- #define TSIF_H_CLK				87
- #define TSIF_INACTIVITY_TIMERS_CLK		88
-@@ -110,7 +110,6 @@
- #define CE1_SLEEP_CLK				93
- #define CE2_H_CLK				94
- #define CE2_CORE_CLK				95
--#define CE2_SLEEP_CLK				96
- #define SFPB_H_CLK_SRC				97
- #define SFPB_H_CLK				98
- #define SFAB_SFPB_M_H_CLK			99
-@@ -252,7 +251,7 @@
- #define MSS_S_H_CLK				235
- #define MSS_CXO_SRC_CLK				236
- #define SATA_H_CLK				237
--#define SATA_SRC_CLK				238
-+#define SATA_CLK_SRC				238
- #define SATA_RXOOB_CLK				239
- #define SATA_PMALIVE_CLK			240
- #define SATA_PHY_REF_CLK			241
---- a/include/dt-bindings/reset/qcom,gcc-msm8960.h
-+++ b/include/dt-bindings/reset/qcom,gcc-msm8960.h
-@@ -58,7 +58,7 @@
- #define PPSS_PROC_RESET					41
- #define PPSS_RESET					42
- #define DMA_BAM_RESET					43
--#define SIC_TIC_RESET					44
-+#define SPS_TIC_H_RESET					44
- #define SLIMBUS_H_RESET					45
- #define SFAB_CFPB_M_RESET				46
- #define SFAB_CFPB_S_RESET				47
diff --git a/target/linux/ipq806x/patches/0081-ARM-config-Add-qcom_defconfig.patch b/target/linux/ipq806x/patches/0081-ARM-config-Add-qcom_defconfig.patch
deleted file mode 100644
index dd87c1f..0000000
--- a/target/linux/ipq806x/patches/0081-ARM-config-Add-qcom_defconfig.patch
+++ /dev/null
@@ -1,184 +0,0 @@
-From e1f51c2d41c8936b8383cf4ac53c1ff05b0e2e2f Mon Sep 17 00:00:00 2001
-From: Stephen Boyd <sboyd@codeaurora.org>
-Date: Thu, 27 Feb 2014 12:54:24 -0800
-Subject: [PATCH 081/182] ARM: config: Add qcom_defconfig
-
-Add a defconfig for mach-qcom platforms (copied from msm_defconfig).
-Although these platforms are part of the multi-platform kernel, it's
-useful to have a stripped down version of the defconfig that just
-selects the DT based Qualcomm platforms and drivers.
-
-Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
-Signed-off-by: Kumar Gala <galak@codeaurora.org>
----
- arch/arm/configs/qcom_defconfig |  164 +++++++++++++++++++++++++++++++++++++++
- 1 file changed, 164 insertions(+)
- create mode 100644 arch/arm/configs/qcom_defconfig
-
---- /dev/null
-+++ b/arch/arm/configs/qcom_defconfig
-@@ -0,0 +1,164 @@
-+CONFIG_SYSVIPC=y
-+CONFIG_NO_HZ=y
-+CONFIG_HIGH_RES_TIMERS=y
-+CONFIG_IKCONFIG=y
-+CONFIG_IKCONFIG_PROC=y
-+CONFIG_BLK_DEV_INITRD=y
-+CONFIG_SYSCTL_SYSCALL=y
-+CONFIG_KALLSYMS_ALL=y
-+CONFIG_EMBEDDED=y
-+# CONFIG_SLUB_DEBUG is not set
-+# CONFIG_COMPAT_BRK is not set
-+CONFIG_PROFILING=y
-+CONFIG_OPROFILE=y
-+CONFIG_KPROBES=y
-+CONFIG_MODULES=y
-+CONFIG_MODULE_UNLOAD=y
-+CONFIG_MODULE_FORCE_UNLOAD=y
-+CONFIG_MODVERSIONS=y
-+CONFIG_PARTITION_ADVANCED=y
-+CONFIG_ARCH_QCOM=y
-+CONFIG_ARCH_MSM8X60=y
-+CONFIG_ARCH_MSM8960=y
-+CONFIG_ARCH_MSM8974=y
-+CONFIG_SMP=y
-+CONFIG_PREEMPT=y
-+CONFIG_AEABI=y
-+CONFIG_HIGHMEM=y
-+CONFIG_HIGHPTE=y
-+CONFIG_CLEANCACHE=y
-+CONFIG_ARM_APPENDED_DTB=y
-+CONFIG_ARM_ATAG_DTB_COMPAT=y
-+CONFIG_VFP=y
-+CONFIG_NEON=y
-+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
-+CONFIG_NET=y
-+CONFIG_PACKET=y
-+CONFIG_UNIX=y
-+CONFIG_INET=y
-+CONFIG_IP_ADVANCED_ROUTER=y
-+CONFIG_IP_MULTIPLE_TABLES=y
-+CONFIG_IP_ROUTE_VERBOSE=y
-+CONFIG_IP_PNP=y
-+CONFIG_IP_PNP_DHCP=y
-+# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
-+# CONFIG_INET_XFRM_MODE_TUNNEL is not set
-+# CONFIG_INET_XFRM_MODE_BEET is not set
-+# CONFIG_INET_LRO is not set
-+# CONFIG_IPV6 is not set
-+CONFIG_CFG80211=y
-+CONFIG_RFKILL=y
-+CONFIG_DEVTMPFS=y
-+CONFIG_DEVTMPFS_MOUNT=y
-+CONFIG_MTD=y
-+CONFIG_MTD_BLOCK=y
-+CONFIG_MTD_M25P80=y
-+CONFIG_BLK_DEV_LOOP=y
-+CONFIG_BLK_DEV_RAM=y
-+CONFIG_SCSI=y
-+CONFIG_SCSI_TGT=y
-+CONFIG_BLK_DEV_SD=y
-+CONFIG_CHR_DEV_SG=y
-+CONFIG_CHR_DEV_SCH=y
-+CONFIG_SCSI_MULTI_LUN=y
-+CONFIG_SCSI_CONSTANTS=y
-+CONFIG_SCSI_LOGGING=y
-+CONFIG_SCSI_SCAN_ASYNC=y
-+CONFIG_NETDEVICES=y
-+CONFIG_DUMMY=y
-+CONFIG_MDIO_BITBANG=y
-+CONFIG_MDIO_GPIO=y
-+CONFIG_SLIP=y
-+CONFIG_SLIP_COMPRESSED=y
-+CONFIG_SLIP_MODE_SLIP6=y
-+CONFIG_USB_USBNET=y
-+# CONFIG_USB_NET_AX8817X is not set
-+# CONFIG_USB_NET_ZAURUS is not set
-+CONFIG_INPUT_EVDEV=y
-+# CONFIG_KEYBOARD_ATKBD is not set
-+# CONFIG_MOUSE_PS2 is not set
-+CONFIG_INPUT_JOYSTICK=y
-+CONFIG_INPUT_TOUCHSCREEN=y
-+CONFIG_INPUT_MISC=y
-+CONFIG_INPUT_UINPUT=y
-+CONFIG_SERIO_LIBPS2=y
-+# CONFIG_LEGACY_PTYS is not set
-+CONFIG_SERIAL_MSM=y
-+CONFIG_SERIAL_MSM_CONSOLE=y
-+CONFIG_HW_RANDOM=y
-+CONFIG_HW_RANDOM_MSM=y
-+CONFIG_I2C=y
-+CONFIG_I2C_CHARDEV=y
-+CONFIG_I2C_QUP=y
-+CONFIG_SPI=y
-+CONFIG_SPI_QUP=y
-+CONFIG_SPMI=y
-+CONFIG_PINCTRL_APQ8064=y
-+CONFIG_PINCTRL_IPQ8064=y
-+CONFIG_PINCTRL_MSM8X74=y
-+CONFIG_DEBUG_GPIO=y
-+CONFIG_GPIO_SYSFS=y
-+CONFIG_POWER_SUPPLY=y
-+CONFIG_POWER_RESET=y
-+CONFIG_POWER_RESET_MSM=y
-+CONFIG_THERMAL=y
-+CONFIG_REGULATOR=y
-+CONFIG_MEDIA_SUPPORT=y
-+CONFIG_FB=y
-+CONFIG_SOUND=y
-+CONFIG_SND=y
-+CONFIG_SND_DYNAMIC_MINORS=y
-+# CONFIG_SND_ARM is not set
-+# CONFIG_SND_SPI is not set
-+# CONFIG_SND_USB is not set
-+CONFIG_SND_SOC=y
-+CONFIG_HID_BATTERY_STRENGTH=y
-+CONFIG_USB=y
-+CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
-+CONFIG_USB_MON=y
-+CONFIG_USB_EHCI_HCD=y
-+CONFIG_USB_ACM=y
-+CONFIG_USB_SERIAL=y
-+CONFIG_USB_GADGET=y
-+CONFIG_USB_GADGET_DEBUG_FILES=y
-+CONFIG_USB_GADGET_VBUS_DRAW=500
-+CONFIG_MMC=y
-+CONFIG_MMC_BLOCK_MINORS=16
-+CONFIG_MMC_SDHCI=y
-+CONFIG_MMC_SDHCI_PLTFM=y
-+CONFIG_MMC_SDHCI_MSM=y
-+CONFIG_RTC_CLASS=y
-+CONFIG_DMADEVICES=y
-+CONFIG_QCOM_BAM_DMA=y
-+CONFIG_STAGING=y
-+CONFIG_COMMON_CLK_QCOM=y
-+CONFIG_MSM_GCC_8660=y
-+CONFIG_MSM_MMCC_8960=y
-+CONFIG_MSM_MMCC_8974=y
-+CONFIG_MSM_IOMMU=y
-+CONFIG_GENERIC_PHY=y
-+CONFIG_EXT2_FS=y
-+CONFIG_EXT2_FS_XATTR=y
-+CONFIG_EXT3_FS=y
-+# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
-+CONFIG_EXT4_FS=y
-+CONFIG_FUSE_FS=y
-+CONFIG_VFAT_FS=y
-+CONFIG_TMPFS=y
-+CONFIG_JFFS2_FS=y
-+CONFIG_NFS_FS=y
-+CONFIG_NFS_V3_ACL=y
-+CONFIG_NFS_V4=y
-+CONFIG_CIFS=y
-+CONFIG_NLS_CODEPAGE_437=y
-+CONFIG_NLS_ASCII=y
-+CONFIG_NLS_ISO8859_1=y
-+CONFIG_NLS_UTF8=y
-+CONFIG_PRINTK_TIME=y
-+CONFIG_DYNAMIC_DEBUG=y
-+CONFIG_DEBUG_INFO=y
-+CONFIG_MAGIC_SYSRQ=y
-+CONFIG_LOCKUP_DETECTOR=y
-+# CONFIG_DETECT_HUNG_TASK is not set
-+# CONFIG_SCHED_DEBUG is not set
-+CONFIG_TIMER_STATS=y
diff --git a/target/linux/ipq806x/patches/0082-ARM-qcom-Enable-GSBI-driver-in-defconfig.patch b/target/linux/ipq806x/patches/0082-ARM-qcom-Enable-GSBI-driver-in-defconfig.patch
deleted file mode 100644
index 180f102..0000000
--- a/target/linux/ipq806x/patches/0082-ARM-qcom-Enable-GSBI-driver-in-defconfig.patch
+++ /dev/null
@@ -1,20 +0,0 @@
-From d247fb8a019e4cc5a607c7fff9922e8e98c2c660 Mon Sep 17 00:00:00 2001
-From: Kumar Gala <galak@codeaurora.org>
-Date: Thu, 29 May 2014 11:25:24 -0500
-Subject: [PATCH 082/182] ARM: qcom: Enable GSBI driver in defconfig
-
-Signed-off-by: Kumar Gala <galak@codeaurora.org>
----
- arch/arm/configs/qcom_defconfig |    1 +
- 1 file changed, 1 insertion(+)
-
---- a/arch/arm/configs/qcom_defconfig
-+++ b/arch/arm/configs/qcom_defconfig
-@@ -131,6 +131,7 @@ CONFIG_RTC_CLASS=y
- CONFIG_DMADEVICES=y
- CONFIG_QCOM_BAM_DMA=y
- CONFIG_STAGING=y
-+CONFIG_QCOM_GSBI=y
- CONFIG_COMMON_CLK_QCOM=y
- CONFIG_MSM_GCC_8660=y
- CONFIG_MSM_MMCC_8960=y
diff --git a/target/linux/ipq806x/patches/0083-soc-Introduce-drivers-soc-place-holder-for-SOC-speci.patch b/target/linux/ipq806x/patches/0083-soc-Introduce-drivers-soc-place-holder-for-SOC-speci.patch
deleted file mode 100644
index 5f173fb..0000000
--- a/target/linux/ipq806x/patches/0083-soc-Introduce-drivers-soc-place-holder-for-SOC-speci.patch
+++ /dev/null
@@ -1,58 +0,0 @@
-From 2dac9498966c79a6abb09764419ffd42a44c78cf Mon Sep 17 00:00:00 2001
-From: Santosh Shilimkar <santosh.shilimkar@ti.com>
-Date: Wed, 23 Apr 2014 19:46:17 -0400
-Subject: [PATCH 083/182] soc: Introduce drivers/soc place-holder for SOC
- specific drivers
-
-Based on earlier thread "https://lkml.org/lkml/2013/10/7/662" and
-discussion at Kernel Summit'2013, it was agreed to create
-'driver/soc' for drivers which are quite SOC specific.
-
-Further discussion on the subject is in response to
-the earlier version of the patch is here:
-	http://lwn.net/Articles/588942/
-
-Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-Cc: Kumar Gala <galak@codeaurora.org>
-Cc: Paul Walmsley <paul@pwsan.com>
-Cc: Olof Johansson <olof@lixom.net>
-Cc: Arnd Bergmann <arnd@arndb.de>
-Signed-off-by: Sandeep Nair <sandeep_n@ti.com>
-Signed-off-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
-Signed-off-by: Kumar Gala <galak@codeaurora.org>
----
- drivers/Kconfig     |    2 ++
- drivers/Makefile    |    3 +++
- drivers/soc/Kconfig |    3 +++
- 3 files changed, 8 insertions(+)
- create mode 100644 drivers/soc/Kconfig
-
---- a/drivers/Kconfig
-+++ b/drivers/Kconfig
-@@ -132,6 +132,8 @@ source "drivers/staging/Kconfig"
- 
- source "drivers/platform/Kconfig"
- 
-+source "drivers/soc/Kconfig"
-+
- source "drivers/clk/Kconfig"
- 
- source "drivers/hwspinlock/Kconfig"
---- a/drivers/Makefile
-+++ b/drivers/Makefile
-@@ -33,6 +33,9 @@ obj-y				+= amba/
- # really early.
- obj-$(CONFIG_DMADEVICES)	+= dma/
- 
-+# SOC specific infrastructure drivers.
-+obj-y				+= soc/
-+
- obj-$(CONFIG_VIRTIO)		+= virtio/
- obj-$(CONFIG_XEN)		+= xen/
- 
---- /dev/null
-+++ b/drivers/soc/Kconfig
-@@ -0,0 +1,3 @@
-+menu "SOC (System On Chip) specific Drivers"
-+
-+endmenu
diff --git a/target/linux/ipq806x/patches/0084-soc-qcom-Add-GSBI-driver.patch b/target/linux/ipq806x/patches/0084-soc-qcom-Add-GSBI-driver.patch
deleted file mode 100644
index 545c4be..0000000
--- a/target/linux/ipq806x/patches/0084-soc-qcom-Add-GSBI-driver.patch
+++ /dev/null
@@ -1,145 +0,0 @@
-From a2f0fc20ea49e5dbbdbb21444683ea760fbdd38f Mon Sep 17 00:00:00 2001
-From: Andy Gross <agross@codeaurora.org>
-Date: Thu, 24 Apr 2014 11:31:21 -0500
-Subject: [PATCH 084/182] soc: qcom: Add GSBI driver
-
-The GSBI (General Serial Bus Interface) driver controls the overarching
-configuration of the shared serial bus infrastructure on APQ8064, IPQ8064, and
-earlier QCOM processors.  The GSBI supports UART, I2C, SPI, and UIM
-functionality in various combinations.
-
-Signed-off-by: Andy Gross <agross@codeaurora.org>
-Signed-off-by: Kumar Gala <galak@codeaurora.org>
----
- drivers/soc/Kconfig          |    2 +
- drivers/soc/Makefile         |    5 +++
- drivers/soc/qcom/Kconfig     |   11 ++++++
- drivers/soc/qcom/Makefile    |    1 +
- drivers/soc/qcom/qcom_gsbi.c |   84 ++++++++++++++++++++++++++++++++++++++++++
- 5 files changed, 103 insertions(+)
- create mode 100644 drivers/soc/Makefile
- create mode 100644 drivers/soc/qcom/Kconfig
- create mode 100644 drivers/soc/qcom/Makefile
- create mode 100644 drivers/soc/qcom/qcom_gsbi.c
-
---- a/drivers/soc/Kconfig
-+++ b/drivers/soc/Kconfig
-@@ -1,3 +1,5 @@
- menu "SOC (System On Chip) specific Drivers"
- 
-+source "drivers/soc/qcom/Kconfig"
-+
- endmenu
---- /dev/null
-+++ b/drivers/soc/Makefile
-@@ -0,0 +1,5 @@
-+#
-+# Makefile for the Linux Kernel SOC specific device drivers.
-+#
-+
-+obj-$(CONFIG_ARCH_QCOM)		+= qcom/
---- /dev/null
-+++ b/drivers/soc/qcom/Kconfig
-@@ -0,0 +1,11 @@
-+#
-+# QCOM Soc drivers
-+#
-+config QCOM_GSBI
-+        tristate "QCOM General Serial Bus Interface"
-+        depends on ARCH_QCOM
-+        help
-+          Say y here to enable GSBI support.  The GSBI provides control
-+          functions for connecting the underlying serial UART, SPI, and I2C
-+          devices to the output pins.
-+
---- /dev/null
-+++ b/drivers/soc/qcom/Makefile
-@@ -0,0 +1 @@
-+obj-$(CONFIG_QCOM_GSBI)	+=	qcom_gsbi.o
---- /dev/null
-+++ b/drivers/soc/qcom/qcom_gsbi.c
-@@ -0,0 +1,84 @@
-+/*
-+ * Copyright (c) 2014, The Linux foundation. All rights reserved.
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License rev 2 and
-+ * only rev 2 as published by the free Software foundation.
-+ *
-+ * 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/err.h>
-+#include <linux/io.h>
-+#include <linux/module.h>
-+#include <linux/of.h>
-+#include <linux/of_platform.h>
-+#include <linux/platform_device.h>
-+
-+#define GSBI_CTRL_REG		0x0000
-+#define GSBI_PROTOCOL_SHIFT	4
-+
-+static int gsbi_probe(struct platform_device *pdev)
-+{
-+	struct device_node *node = pdev->dev.of_node;
-+	struct resource *res;
-+	void __iomem *base;
-+	struct clk *hclk;
-+	u32 mode, crci = 0;
-+
-+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-+	base = devm_ioremap_resource(&pdev->dev, res);
-+	if (IS_ERR(base))
-+		return PTR_ERR(base);
-+
-+	if (of_property_read_u32(node, "qcom,mode", &mode)) {
-+		dev_err(&pdev->dev, "missing mode configuration\n");
-+		return -EINVAL;
-+	}
-+
-+	/* not required, so default to 0 if not present */
-+	of_property_read_u32(node, "qcom,crci", &crci);
-+
-+	dev_info(&pdev->dev, "GSBI port protocol: %d crci: %d\n", mode, crci);
-+
-+	hclk = devm_clk_get(&pdev->dev, "iface");
-+	if (IS_ERR(hclk))
-+		return PTR_ERR(hclk);
-+
-+	clk_prepare_enable(hclk);
-+
-+	writel_relaxed((mode << GSBI_PROTOCOL_SHIFT) | crci,
-+				base + GSBI_CTRL_REG);
-+
-+	/* make sure the gsbi control write is not reordered */
-+	wmb();
-+
-+	clk_disable_unprepare(hclk);
-+
-+	return of_platform_populate(pdev->dev.of_node, NULL, NULL, &pdev->dev);
-+}
-+
-+static const struct of_device_id gsbi_dt_match[] = {
-+	{ .compatible = "qcom,gsbi-v1.0.0", },
-+};
-+
-+MODULE_DEVICE_TABLE(of, gsbi_dt_match);
-+
-+static struct platform_driver gsbi_driver = {
-+	.driver = {
-+		.name		= "gsbi",
-+		.owner		= THIS_MODULE,
-+		.of_match_table	= gsbi_dt_match,
-+	},
-+	.probe = gsbi_probe,
-+};
-+
-+module_platform_driver(gsbi_driver);
-+
-+MODULE_AUTHOR("Andy Gross <agross@codeaurora.org>");
-+MODULE_DESCRIPTION("QCOM GSBI driver");
-+MODULE_LICENSE("GPL v2");
diff --git a/target/linux/ipq806x/patches/0085-soc-qcom-fix-of_device_id-table.patch b/target/linux/ipq806x/patches/0085-soc-qcom-fix-of_device_id-table.patch
deleted file mode 100644
index 3c58107..0000000
--- a/target/linux/ipq806x/patches/0085-soc-qcom-fix-of_device_id-table.patch
+++ /dev/null
@@ -1,23 +0,0 @@
-From 8efaabc573e58f4b891340f4aedb34f9d0656067 Mon Sep 17 00:00:00 2001
-From: Arnd Bergmann <arnd@arndb.de>
-Date: Mon, 26 May 2014 18:07:05 +0200
-Subject: [PATCH 085/182] soc: qcom: fix of_device_id table
-
-The match tables must be zero-terminated, and Kbuild now helpfully
-fails to link the kernel if that isn't the case.
-
-Signed-off-by: Arnd Bergmann <arnd@arndb.de>
----
- drivers/soc/qcom/qcom_gsbi.c |    1 +
- 1 file changed, 1 insertion(+)
-
---- a/drivers/soc/qcom/qcom_gsbi.c
-+++ b/drivers/soc/qcom/qcom_gsbi.c
-@@ -64,6 +64,7 @@ static int gsbi_probe(struct platform_de
- 
- static const struct of_device_id gsbi_dt_match[] = {
- 	{ .compatible = "qcom,gsbi-v1.0.0", },
-+	{ },
- };
- 
- MODULE_DEVICE_TABLE(of, gsbi_dt_match);
diff --git a/target/linux/ipq806x/patches/0086-msm_serial-Add-support-for-poll_-get-put-_char.patch b/target/linux/ipq806x/patches/0086-msm_serial-Add-support-for-poll_-get-put-_char.patch
deleted file mode 100644
index 68204c5..0000000
--- a/target/linux/ipq806x/patches/0086-msm_serial-Add-support-for-poll_-get-put-_char.patch
+++ /dev/null
@@ -1,239 +0,0 @@
-From 48ab619dd6e308c57dac3e5d022a3099806bf79e Mon Sep 17 00:00:00 2001
-From: Stephen Boyd <sboyd@codeaurora.org>
-Date: Tue, 14 Jan 2014 12:34:55 -0800
-Subject: [PATCH 086/182] msm_serial: Add support for poll_{get,put}_char()
-
-Implement the polling functionality for the MSM serial driver.
-This allows us to use KGDB on this hardware.
-
-Cc: David Brown <davidb@codeaurora.org>
-Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/tty/serial/msm_serial.c |  140 ++++++++++++++++++++++++++++++++++++++-
- drivers/tty/serial/msm_serial.h |    9 +++
- 2 files changed, 146 insertions(+), 3 deletions(-)
-
---- a/drivers/tty/serial/msm_serial.c
-+++ b/drivers/tty/serial/msm_serial.c
-@@ -39,6 +39,13 @@
- 
- #include "msm_serial.h"
- 
-+enum {
-+	UARTDM_1P1 = 1,
-+	UARTDM_1P2,
-+	UARTDM_1P3,
-+	UARTDM_1P4,
-+};
-+
- struct msm_port {
- 	struct uart_port	uart;
- 	char			name[16];
-@@ -309,6 +316,8 @@ static unsigned int msm_get_mctrl(struct
- 
- static void msm_reset(struct uart_port *port)
- {
-+	struct msm_port *msm_port = UART_TO_MSM(port);
-+
- 	/* reset everything */
- 	msm_write(port, UART_CR_CMD_RESET_RX, UART_CR);
- 	msm_write(port, UART_CR_CMD_RESET_TX, UART_CR);
-@@ -316,6 +325,10 @@ static void msm_reset(struct uart_port *
- 	msm_write(port, UART_CR_CMD_RESET_BREAK_INT, UART_CR);
- 	msm_write(port, UART_CR_CMD_RESET_CTS, UART_CR);
- 	msm_write(port, UART_CR_CMD_SET_RFR, UART_CR);
-+
-+	/* Disable DM modes */
-+	if (msm_port->is_uartdm)
-+		msm_write(port, 0, UARTDM_DMEN);
- }
- 
- static void msm_set_mctrl(struct uart_port *port, unsigned int mctrl)
-@@ -711,6 +724,117 @@ static void msm_power(struct uart_port *
- 	}
- }
- 
-+#ifdef CONFIG_CONSOLE_POLL
-+static int msm_poll_init(struct uart_port *port)
-+{
-+	struct msm_port *msm_port = UART_TO_MSM(port);
-+
-+	/* Enable single character mode on RX FIFO */
-+	if (msm_port->is_uartdm >= UARTDM_1P4)
-+		msm_write(port, UARTDM_DMEN_RX_SC_ENABLE, UARTDM_DMEN);
-+
-+	return 0;
-+}
-+
-+static int msm_poll_get_char_single(struct uart_port *port)
-+{
-+	struct msm_port *msm_port = UART_TO_MSM(port);
-+	unsigned int rf_reg = msm_port->is_uartdm ? UARTDM_RF : UART_RF;
-+
-+	if (!(msm_read(port, UART_SR) & UART_SR_RX_READY))
-+		return NO_POLL_CHAR;
-+	else
-+		return msm_read(port, rf_reg) & 0xff;
-+}
-+
-+static int msm_poll_get_char_dm_1p3(struct uart_port *port)
-+{
-+	int c;
-+	static u32 slop;
-+	static int count;
-+	unsigned char *sp = (unsigned char *)&slop;
-+
-+	/* Check if a previous read had more than one char */
-+	if (count) {
-+		c = sp[sizeof(slop) - count];
-+		count--;
-+	/* Or if FIFO is empty */
-+	} else if (!(msm_read(port, UART_SR) & UART_SR_RX_READY)) {
-+		/*
-+		 * If RX packing buffer has less than a word, force stale to
-+		 * push contents into RX FIFO
-+		 */
-+		count = msm_read(port, UARTDM_RXFS);
-+		count = (count >> UARTDM_RXFS_BUF_SHIFT) & UARTDM_RXFS_BUF_MASK;
-+		if (count) {
-+			msm_write(port, UART_CR_CMD_FORCE_STALE, UART_CR);
-+			slop = msm_read(port, UARTDM_RF);
-+			c = sp[0];
-+			count--;
-+		} else {
-+			c = NO_POLL_CHAR;
-+		}
-+	/* FIFO has a word */
-+	} else {
-+		slop = msm_read(port, UARTDM_RF);
-+		c = sp[0];
-+		count = sizeof(slop) - 1;
-+	}
-+
-+	return c;
-+}
-+
-+static int msm_poll_get_char(struct uart_port *port)
-+{
-+	u32 imr;
-+	int c;
-+	struct msm_port *msm_port = UART_TO_MSM(port);
-+
-+	/* Disable all interrupts */
-+	imr = msm_read(port, UART_IMR);
-+	msm_write(port, 0, UART_IMR);
-+
-+	if (msm_port->is_uartdm == UARTDM_1P3)
-+		c = msm_poll_get_char_dm_1p3(port);
-+	else
-+		c = msm_poll_get_char_single(port);
-+
-+	/* Enable interrupts */
-+	msm_write(port, imr, UART_IMR);
-+
-+	return c;
-+}
-+
-+static void msm_poll_put_char(struct uart_port *port, unsigned char c)
-+{
-+	u32 imr;
-+	struct msm_port *msm_port = UART_TO_MSM(port);
-+
-+	/* Disable all interrupts */
-+	imr = msm_read(port, UART_IMR);
-+	msm_write(port, 0, UART_IMR);
-+
-+	if (msm_port->is_uartdm)
-+		reset_dm_count(port, 1);
-+
-+	/* Wait until FIFO is empty */
-+	while (!(msm_read(port, UART_SR) & UART_SR_TX_READY))
-+		cpu_relax();
-+
-+	/* Write a character */
-+	msm_write(port, c, msm_port->is_uartdm ? UARTDM_TF : UART_TF);
-+
-+	/* Wait until FIFO is empty */
-+	while (!(msm_read(port, UART_SR) & UART_SR_TX_READY))
-+		cpu_relax();
-+
-+	/* Enable interrupts */
-+	msm_write(port, imr, UART_IMR);
-+
-+	return;
-+}
-+#endif
-+
- static struct uart_ops msm_uart_pops = {
- 	.tx_empty = msm_tx_empty,
- 	.set_mctrl = msm_set_mctrl,
-@@ -729,6 +853,11 @@ static struct uart_ops msm_uart_pops = {
- 	.config_port = msm_config_port,
- 	.verify_port = msm_verify_port,
- 	.pm = msm_power,
-+#ifdef CONFIG_CONSOLE_POLL
-+	.poll_init = msm_poll_init,
-+	.poll_get_char	= msm_poll_get_char,
-+	.poll_put_char	= msm_poll_put_char,
-+#endif
- };
- 
- static struct msm_port msm_uart_ports[] = {
-@@ -900,7 +1029,10 @@ static struct uart_driver msm_uart_drive
- static atomic_t msm_uart_next_id = ATOMIC_INIT(0);
- 
- static const struct of_device_id msm_uartdm_table[] = {
--	{ .compatible = "qcom,msm-uartdm" },
-+	{ .compatible = "qcom,msm-uartdm-v1.1", .data = (void *)UARTDM_1P1 },
-+	{ .compatible = "qcom,msm-uartdm-v1.2", .data = (void *)UARTDM_1P2 },
-+	{ .compatible = "qcom,msm-uartdm-v1.3", .data = (void *)UARTDM_1P3 },
-+	{ .compatible = "qcom,msm-uartdm-v1.4", .data = (void *)UARTDM_1P4 },
- 	{ }
- };
- 
-@@ -909,6 +1041,7 @@ static int __init msm_serial_probe(struc
- 	struct msm_port *msm_port;
- 	struct resource *resource;
- 	struct uart_port *port;
-+	const struct of_device_id *id;
- 	int irq;
- 
- 	if (pdev->id == -1)
-@@ -923,8 +1056,9 @@ static int __init msm_serial_probe(struc
- 	port->dev = &pdev->dev;
- 	msm_port = UART_TO_MSM(port);
- 
--	if (of_match_device(msm_uartdm_table, &pdev->dev))
--		msm_port->is_uartdm = 1;
-+	id = of_match_device(msm_uartdm_table, &pdev->dev);
-+	if (id)
-+		msm_port->is_uartdm = (unsigned long)id->data;
- 	else
- 		msm_port->is_uartdm = 0;
- 
---- a/drivers/tty/serial/msm_serial.h
-+++ b/drivers/tty/serial/msm_serial.h
-@@ -59,6 +59,7 @@
- #define UART_CR_CMD_RESET_RFR		(14 << 4)
- #define UART_CR_CMD_PROTECTION_EN	(16 << 4)
- #define UART_CR_CMD_STALE_EVENT_ENABLE	(80 << 4)
-+#define UART_CR_CMD_FORCE_STALE		(4 << 8)
- #define UART_CR_CMD_RESET_TX_READY	(3 << 8)
- #define UART_CR_TX_DISABLE		(1 << 3)
- #define UART_CR_TX_ENABLE		(1 << 2)
-@@ -113,6 +114,14 @@
- #define GSBI_PROTOCOL_UART	0x40
- #define GSBI_PROTOCOL_IDLE	0x0
- 
-+#define UARTDM_RXFS		0x50
-+#define UARTDM_RXFS_BUF_SHIFT	0x7
-+#define UARTDM_RXFS_BUF_MASK	0x7
-+
-+#define UARTDM_DMEN		0x3C
-+#define UARTDM_DMEN_RX_SC_ENABLE BIT(5)
-+#define UARTDM_DMEN_TX_SC_ENABLE BIT(4)
-+
- #define UARTDM_DMRX		0x34
- #define UARTDM_NCF_TX		0x40
- #define UARTDM_RX_TOTAL_SNAP	0x38
diff --git a/target/linux/ipq806x/patches/0087-tty-serial-msm-Remove-direct-access-to-GSBI.patch b/target/linux/ipq806x/patches/0087-tty-serial-msm-Remove-direct-access-to-GSBI.patch
deleted file mode 100644
index 9eb7138..0000000
--- a/target/linux/ipq806x/patches/0087-tty-serial-msm-Remove-direct-access-to-GSBI.patch
+++ /dev/null
@@ -1,144 +0,0 @@
-From 025909cbf933cc20c2ff5ea9f87de8e17a739a08 Mon Sep 17 00:00:00 2001
-From: Andy Gross <agross@codeaurora.org>
-Date: Thu, 24 Apr 2014 11:31:22 -0500
-Subject: [PATCH 087/182] tty: serial: msm: Remove direct access to GSBI
-
-This patch removes direct access of the GSBI registers.  GSBI configuration
-should be done through the GSBI driver directly.
-
-Signed-off-by: Andy Gross <agross@codeaurora.org>
-Signed-off-by: Kumar Gala <galak@codeaurora.org>
----
- drivers/tty/serial/msm_serial.c |   48 ++-------------------------------------
- drivers/tty/serial/msm_serial.h |    5 ----
- 2 files changed, 2 insertions(+), 51 deletions(-)
-
---- a/drivers/tty/serial/msm_serial.c
-+++ b/drivers/tty/serial/msm_serial.c
-@@ -52,7 +52,6 @@ struct msm_port {
- 	struct clk		*clk;
- 	struct clk		*pclk;
- 	unsigned int		imr;
--	void __iomem		*gsbi_base;
- 	int			is_uartdm;
- 	unsigned int		old_snap_state;
- };
-@@ -599,9 +598,7 @@ static const char *msm_type(struct uart_
- static void msm_release_port(struct uart_port *port)
- {
- 	struct platform_device *pdev = to_platform_device(port->dev);
--	struct msm_port *msm_port = UART_TO_MSM(port);
- 	struct resource *uart_resource;
--	struct resource *gsbi_resource;
- 	resource_size_t size;
- 
- 	uart_resource = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-@@ -612,28 +609,12 @@ static void msm_release_port(struct uart
- 	release_mem_region(port->mapbase, size);
- 	iounmap(port->membase);
- 	port->membase = NULL;
--
--	if (msm_port->gsbi_base) {
--		writel_relaxed(GSBI_PROTOCOL_IDLE,
--				msm_port->gsbi_base + GSBI_CONTROL);
--
--		gsbi_resource = platform_get_resource(pdev, IORESOURCE_MEM, 1);
--		if (unlikely(!gsbi_resource))
--			return;
--
--		size = resource_size(gsbi_resource);
--		release_mem_region(gsbi_resource->start, size);
--		iounmap(msm_port->gsbi_base);
--		msm_port->gsbi_base = NULL;
--	}
- }
- 
- static int msm_request_port(struct uart_port *port)
- {
--	struct msm_port *msm_port = UART_TO_MSM(port);
- 	struct platform_device *pdev = to_platform_device(port->dev);
- 	struct resource *uart_resource;
--	struct resource *gsbi_resource;
- 	resource_size_t size;
- 	int ret;
- 
-@@ -652,30 +633,8 @@ static int msm_request_port(struct uart_
- 		goto fail_release_port;
- 	}
- 
--	gsbi_resource = platform_get_resource(pdev, IORESOURCE_MEM, 1);
--	/* Is this a GSBI-based port? */
--	if (gsbi_resource) {
--		size = resource_size(gsbi_resource);
--
--		if (!request_mem_region(gsbi_resource->start, size,
--						 "msm_serial")) {
--			ret = -EBUSY;
--			goto fail_release_port_membase;
--		}
--
--		msm_port->gsbi_base = ioremap(gsbi_resource->start, size);
--		if (!msm_port->gsbi_base) {
--			ret = -EBUSY;
--			goto fail_release_gsbi;
--		}
--	}
--
- 	return 0;
- 
--fail_release_gsbi:
--	release_mem_region(gsbi_resource->start, size);
--fail_release_port_membase:
--	iounmap(port->membase);
- fail_release_port:
- 	release_mem_region(port->mapbase, size);
- 	return ret;
-@@ -683,7 +642,6 @@ fail_release_port:
- 
- static void msm_config_port(struct uart_port *port, int flags)
- {
--	struct msm_port *msm_port = UART_TO_MSM(port);
- 	int ret;
- 	if (flags & UART_CONFIG_TYPE) {
- 		port->type = PORT_MSM;
-@@ -691,9 +649,6 @@ static void msm_config_port(struct uart_
- 		if (ret)
- 			return;
- 	}
--	if (msm_port->gsbi_base)
--		writel_relaxed(GSBI_PROTOCOL_UART,
--				msm_port->gsbi_base + GSBI_CONTROL);
- }
- 
- static int msm_verify_port(struct uart_port *port, struct serial_struct *ser)
-@@ -1110,6 +1065,7 @@ static struct of_device_id msm_match_tab
- 
- static struct platform_driver msm_platform_driver = {
- 	.remove = msm_serial_remove,
-+	.probe = msm_serial_probe,
- 	.driver = {
- 		.name = "msm_serial",
- 		.owner = THIS_MODULE,
-@@ -1125,7 +1081,7 @@ static int __init msm_serial_init(void)
- 	if (unlikely(ret))
- 		return ret;
- 
--	ret = platform_driver_probe(&msm_platform_driver, msm_serial_probe);
-+	ret = platform_driver_register(&msm_platform_driver);
- 	if (unlikely(ret))
- 		uart_unregister_driver(&msm_uart_driver);
- 
---- a/drivers/tty/serial/msm_serial.h
-+++ b/drivers/tty/serial/msm_serial.h
-@@ -109,11 +109,6 @@
- #define UART_ISR		0x0014
- #define UART_ISR_TX_READY	(1 << 7)
- 
--#define GSBI_CONTROL		0x0
--#define GSBI_PROTOCOL_CODE	0x30
--#define GSBI_PROTOCOL_UART	0x40
--#define GSBI_PROTOCOL_IDLE	0x0
--
- #define UARTDM_RXFS		0x50
- #define UARTDM_RXFS_BUF_SHIFT	0x7
- #define UARTDM_RXFS_BUF_MASK	0x7
diff --git a/target/linux/ipq806x/patches/0088-soc-qcom-Add-device-tree-binding-for-GSBI.patch b/target/linux/ipq806x/patches/0088-soc-qcom-Add-device-tree-binding-for-GSBI.patch
deleted file mode 100644
index 523d5cb..0000000
--- a/target/linux/ipq806x/patches/0088-soc-qcom-Add-device-tree-binding-for-GSBI.patch
+++ /dev/null
@@ -1,126 +0,0 @@
-From 5a58dbf4d82c29f7e6d89abc3520bed1aa2af05c Mon Sep 17 00:00:00 2001
-From: Andy Gross <agross@codeaurora.org>
-Date: Thu, 24 Apr 2014 11:31:20 -0500
-Subject: [PATCH 088/182] soc: qcom: Add device tree binding for GSBI
-
-Add device tree binding support for the QCOM GSBI driver.
-
-Signed-off-by: Andy Gross <agross@codeaurora.org>
-Signed-off-by: Kumar Gala <galak@codeaurora.org>
----
- .../devicetree/bindings/soc/qcom/qcom,gsbi.txt     |   78 ++++++++++++++++++++
- include/dt-bindings/soc/qcom,gsbi.h                |   26 +++++++
- 2 files changed, 104 insertions(+)
- create mode 100644 Documentation/devicetree/bindings/soc/qcom/qcom,gsbi.txt
- create mode 100644 include/dt-bindings/soc/qcom,gsbi.h
-
---- /dev/null
-+++ b/Documentation/devicetree/bindings/soc/qcom/qcom,gsbi.txt
-@@ -0,0 +1,78 @@
-+QCOM GSBI (General Serial Bus Interface) Driver
-+
-+The GSBI controller is modeled as a node with zero or more child nodes, each
-+representing a serial sub-node device that is mux'd as part of the GSBI
-+configuration settings.  The mode setting will govern the input/output mode of
-+the 4 GSBI IOs.
-+
-+Required properties:
-+- compatible: must contain "qcom,gsbi-v1.0.0" for APQ8064/IPQ8064
-+- reg: Address range for GSBI registers
-+- clocks: required clock
-+- clock-names: must contain "iface" entry
-+- qcom,mode : indicates MUX value for configuration of the serial interface.
-+  Please reference dt-bindings/soc/qcom,gsbi.h for valid mux values.
-+
-+Optional properties:
-+- qcom,crci : indicates CRCI MUX value for QUP CRCI ports.  Please reference
-+  dt-bindings/soc/qcom,gsbi.h for valid CRCI mux values.
-+
-+Required properties if child node exists:
-+- #address-cells: Must be 1
-+- #size-cells: Must be 1
-+- ranges: Must be present
-+
-+Properties for children:
-+
-+A GSBI controller node can contain 0 or more child nodes representing serial
-+devices.  These serial devices can be a QCOM UART, I2C controller, spi
-+controller, or some combination of aforementioned devices.
-+
-+See the following for child node definitions:
-+Documentation/devicetree/bindings/i2c/qcom,i2c-qup.txt
-+Documentation/devicetree/bindings/spi/qcom,spi-qup.txt
-+Documentation/devicetree/bindings/serial/qcom,msm-uartdm.txt
-+
-+Example for APQ8064:
-+
-+#include <dt-bindings/soc/qcom,gsbi.h>
-+
-+	gsbi4@16300000 {
-+		compatible = "qcom,gsbi-v1.0.0";
-+		reg = <0x16300000 0x100>;
-+		clocks = <&gcc GSBI4_H_CLK>;
-+		clock-names = "iface";
-+		#address-cells = <1>;
-+		#size-cells = <1>;
-+		ranges;
-+		qcom,mode = <GSBI_PROT_I2C_UART>;
-+		qcom,crci = <GSBI_CRCI_QUP>;
-+
-+		/* child nodes go under here */
-+
-+		i2c_qup4: i2c@16380000 {
-+		        compatible = "qcom,i2c-qup-v1.1.1";
-+		        reg = <0x16380000 0x1000>;
-+		        interrupts = <0 153 0>;
-+
-+		        clocks = <&gcc GSBI4_QUP_CLK>, <&gcc GSBI4_H_CLK>;
-+		        clock-names = "core", "iface";
-+
-+		        clock-frequency = <200000>;
-+
-+		        #address-cells = <1>;
-+		        #size-cells = <0>;
-+
-+		 };
-+
-+		uart4:	serial@16340000 {
-+			compatible = "qcom,msm-uartdm-v1.3", "qcom,msm-uartdm";
-+			reg = <0x16340000 0x1000>,
-+				<0x16300000 0x1000>;
-+			interrupts = <0 152 0x0>;
-+			clocks = <&gcc GSBI4_UART_CLK>, <&gcc GSBI4_H_CLK>;
-+			clock-names = "core", "iface";
-+			status = "ok";
-+		};
-+	};
-+
---- /dev/null
-+++ b/include/dt-bindings/soc/qcom,gsbi.h
-@@ -0,0 +1,26 @@
-+/* Copyright (c) 2013, The Linux Foundation. All rights reserved.
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 and
-+ * only version 2 as published by the Free Software Foundation.
-+ *
-+ * 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 __DT_BINDINGS_QCOM_GSBI_H
-+#define __DT_BINDINGS_QCOM_GSBI_H
-+
-+#define GSBI_PROT_IDLE		0
-+#define GSBI_PROT_I2C_UIM	1
-+#define GSBI_PROT_I2C		2
-+#define GSBI_PROT_SPI		3
-+#define GSBI_PROT_UART_W_FC	4
-+#define GSBI_PROT_UIM		5
-+#define GSBI_PROT_I2C_UART	6
-+
-+#define GSBI_CRCI_QUP		0
-+#define GSBI_CRCI_UART		1
-+
-+#endif
diff --git a/target/linux/ipq806x/patches/0089-ARM-dts-MSM8974-Add-pinctrl-node.patch b/target/linux/ipq806x/patches/0089-ARM-dts-MSM8974-Add-pinctrl-node.patch
deleted file mode 100644
index ca06428..0000000
--- a/target/linux/ipq806x/patches/0089-ARM-dts-MSM8974-Add-pinctrl-node.patch
+++ /dev/null
@@ -1,52 +0,0 @@
-From b3a77c7cab10272988231482e2c654c5f10a910c Mon Sep 17 00:00:00 2001
-From: "Ivan T. Ivanov" <iivanov@mm-sol.com>
-Date: Thu, 6 Feb 2014 17:28:49 +0200
-Subject: [PATCH 089/182] ARM: dts: MSM8974: Add pinctrl node
-
-Add the pin control node and pin definitions of SPI8.
-
-Signed-off-by: Ivan T. Ivanov <iivanov@mm-sol.com>
-Reviewed-by: Bjorn Andersson <bjorn.andersson@sonymobile.com>
-Acked-by: Linus Walleij <linus.walleij@linaro.org>
-Signed-off-by: Kumar Gala <galak@codeaurora.org>
----
- arch/arm/boot/dts/qcom-msm8974.dtsi |   29 +++++++++++++++++++++++++++++
- 1 file changed, 29 insertions(+)
-
---- a/arch/arm/boot/dts/qcom-msm8974.dtsi
-+++ b/arch/arm/boot/dts/qcom-msm8974.dtsi
-@@ -198,5 +198,34 @@
- 			clocks = <&gcc GCC_PRNG_AHB_CLK>;
- 			clock-names = "core";
- 		};
-+
-+		msmgpio: pinctrl@fd510000 {
-+			compatible = "qcom,msm8974-pinctrl";
-+			reg = <0xfd510000 0x4000>;
-+			gpio-controller;
-+			#gpio-cells = <2>;
-+			interrupt-controller;
-+			#interrupt-cells = <2>;
-+			interrupts = <0 208 0>;
-+
-+			spi8_default: spi8_default {
-+				mosi {
-+					pins = "gpio45";
-+					function = "blsp_spi8";
-+				};
-+				miso {
-+					pins = "gpio46";
-+					function = "blsp_spi8";
-+				};
-+				cs {
-+					pins = "gpio47";
-+					function = "blsp_spi8";
-+				};
-+				clk {
-+					pins = "gpio48";
-+					function = "blsp_spi8";
-+				};
-+			};
-+		};
- 	};
- };
diff --git a/target/linux/ipq806x/patches/0090-ARM-dts-msm-Add-SDHC-controller-nodes-for-MSM8974-an.patch b/target/linux/ipq806x/patches/0090-ARM-dts-msm-Add-SDHC-controller-nodes-for-MSM8974-an.patch
deleted file mode 100644
index 7788f8a..0000000
--- a/target/linux/ipq806x/patches/0090-ARM-dts-msm-Add-SDHC-controller-nodes-for-MSM8974-an.patch
+++ /dev/null
@@ -1,68 +0,0 @@
-From 6632619d49f0f90c4d74caad67749864f154cae4 Mon Sep 17 00:00:00 2001
-From: Georgi Djakov <gdjakov@mm-sol.com>
-Date: Fri, 31 Jan 2014 16:21:56 +0200
-Subject: [PATCH 090/182] ARM: dts: msm: Add SDHC controller nodes for MSM8974
- and DB8074 board
-
-Add support for the 2 SDHC controllers on the DB8074 board.  The first
-controller (at 0xf9824900) is connected to an on board soldered eMMC.
-The second controller (at 0xf98a4900) is connected to a uSD card slot.
-
-Signed-off-by: Georgi Djakov <gdjakov@mm-sol.com>
-Signed-off-by: Kumar Gala <galak@codeaurora.org>
----
- arch/arm/boot/dts/qcom-apq8074-dragonboard.dts |   13 +++++++++++++
- arch/arm/boot/dts/qcom-msm8974.dtsi            |   22 ++++++++++++++++++++++
- 2 files changed, 35 insertions(+)
-
---- a/arch/arm/boot/dts/qcom-apq8074-dragonboard.dts
-+++ b/arch/arm/boot/dts/qcom-apq8074-dragonboard.dts
-@@ -3,4 +3,17 @@
- / {
- 	model = "Qualcomm APQ8074 Dragonboard";
- 	compatible = "qcom,apq8074-dragonboard", "qcom,apq8074";
-+
-+	soc: soc {
-+		sdhci@f9824900 {
-+			bus-width = <8>;
-+			non-removable;
-+			status = "ok";
-+		};
-+
-+		sdhci@f98a4900 {
-+			cd-gpios = <&msmgpio 62 0x1>;
-+			bus-width = <4>;
-+		};
-+	};
- };
---- a/arch/arm/boot/dts/qcom-msm8974.dtsi
-+++ b/arch/arm/boot/dts/qcom-msm8974.dtsi
-@@ -192,6 +192,28 @@
- 			clock-names = "core", "iface";
- 		};
- 
-+		sdhci@f9824900 {
-+			compatible = "qcom,sdhci-msm-v4";
-+			reg = <0xf9824900 0x11c>, <0xf9824000 0x800>;
-+			reg-names = "hc_mem", "core_mem";
-+			interrupts = <0 123 0>, <0 138 0>;
-+			interrupt-names = "hc_irq", "pwr_irq";
-+			clocks = <&gcc GCC_SDCC1_APPS_CLK>, <&gcc GCC_SDCC1_AHB_CLK>;
-+			clock-names = "core", "iface";
-+			status = "disabled";
-+		};
-+
-+		sdhci@f98a4900 {
-+			compatible = "qcom,sdhci-msm-v4";
-+			reg = <0xf98a4900 0x11c>, <0xf98a4000 0x800>;
-+			reg-names = "hc_mem", "core_mem";
-+			interrupts = <0 125 0>, <0 221 0>;
-+			interrupt-names = "hc_irq", "pwr_irq";
-+			clocks = <&gcc GCC_SDCC2_APPS_CLK>, <&gcc GCC_SDCC2_AHB_CLK>;
-+			clock-names = "core", "iface";
-+			status = "disabled";
-+		};
-+
- 		rng@f9bff000 {
- 			compatible = "qcom,prng";
- 			reg = <0xf9bff000 0x200>;
diff --git a/target/linux/ipq806x/patches/0091-ARM-dts-qcom-Update-msm8974-apq8074-device-trees.patch b/target/linux/ipq806x/patches/0091-ARM-dts-qcom-Update-msm8974-apq8074-device-trees.patch
deleted file mode 100644
index 0f6764d..0000000
--- a/target/linux/ipq806x/patches/0091-ARM-dts-qcom-Update-msm8974-apq8074-device-trees.patch
+++ /dev/null
@@ -1,179 +0,0 @@
-From 63495b04141e60ceb40d4632a41b7cd4a3d23dd2 Mon Sep 17 00:00:00 2001
-From: Kumar Gala <galak@codeaurora.org>
-Date: Wed, 28 May 2014 12:01:29 -0500
-Subject: [PATCH 091/182] ARM: dts: qcom: Update msm8974/apq8074 device trees
-
-* Move SoC peripherals into an SoC container node
-* Move serial enabling into board file (qcom-apq8074-dragonboard.dts)
-* Move spi pinctrl into board file
-* Cleanup cpu node to match binding spec, enable-method and compatible
-  should be per cpu, not part of the container
-* Drop interrupts property from l2-cache node as its not part of the
-  binding spec
-* Move timer node out of SoC container
-
-Signed-off-by: Kumar Gala <galak@codeaurora.org>
----
- arch/arm/boot/dts/qcom-apq8074-dragonboard.dts |   28 +++++++++++++-
- arch/arm/boot/dts/qcom-msm8974.dtsi            |   49 +++++++++---------------
- 2 files changed, 45 insertions(+), 32 deletions(-)
-
---- a/arch/arm/boot/dts/qcom-apq8074-dragonboard.dts
-+++ b/arch/arm/boot/dts/qcom-apq8074-dragonboard.dts
-@@ -4,7 +4,11 @@
- 	model = "Qualcomm APQ8074 Dragonboard";
- 	compatible = "qcom,apq8074-dragonboard", "qcom,apq8074";
- 
--	soc: soc {
-+	soc {
-+		serial@f991e000 {
-+			status = "ok";
-+		};
-+
- 		sdhci@f9824900 {
- 			bus-width = <8>;
- 			non-removable;
-@@ -15,5 +19,27 @@
- 			cd-gpios = <&msmgpio 62 0x1>;
- 			bus-width = <4>;
- 		};
-+
-+
-+		pinctrl@fd510000 {
-+			spi8_default: spi8_default {
-+				mosi {
-+					pins = "gpio45";
-+					function = "blsp_spi8";
-+				};
-+				miso {
-+					pins = "gpio46";
-+					function = "blsp_spi8";
-+				};
-+				cs {
-+					pins = "gpio47";
-+					function = "blsp_spi8";
-+				};
-+				clk {
-+					pins = "gpio48";
-+					function = "blsp_spi8";
-+				};
-+			};
-+		};
- 	};
- };
---- a/arch/arm/boot/dts/qcom-msm8974.dtsi
-+++ b/arch/arm/boot/dts/qcom-msm8974.dtsi
-@@ -13,10 +13,10 @@
- 		#address-cells = <1>;
- 		#size-cells = <0>;
- 		interrupts = <1 9 0xf04>;
--		compatible = "qcom,krait";
--		enable-method = "qcom,kpss-acc-v2";
- 
- 		cpu@0 {
-+			compatible = "qcom,krait";
-+			enable-method = "qcom,kpss-acc-v2";
- 			device_type = "cpu";
- 			reg = <0>;
- 			next-level-cache = <&L2>;
-@@ -24,6 +24,8 @@
- 		};
- 
- 		cpu@1 {
-+			compatible = "qcom,krait";
-+			enable-method = "qcom,kpss-acc-v2";
- 			device_type = "cpu";
- 			reg = <1>;
- 			next-level-cache = <&L2>;
-@@ -31,6 +33,8 @@
- 		};
- 
- 		cpu@2 {
-+			compatible = "qcom,krait";
-+			enable-method = "qcom,kpss-acc-v2";
- 			device_type = "cpu";
- 			reg = <2>;
- 			next-level-cache = <&L2>;
-@@ -38,6 +42,8 @@
- 		};
- 
- 		cpu@3 {
-+			compatible = "qcom,krait";
-+			enable-method = "qcom,kpss-acc-v2";
- 			device_type = "cpu";
- 			reg = <3>;
- 			next-level-cache = <&L2>;
-@@ -47,7 +53,6 @@
- 		L2: l2-cache {
- 			compatible = "cache";
- 			cache-level = <2>;
--			interrupts = <0 2 0x4>;
- 			qcom,saw = <&saw_l2>;
- 		};
- 	};
-@@ -57,6 +62,15 @@
- 		interrupts = <1 7 0xf04>;
- 	};
- 
-+	timer {
-+		compatible = "arm,armv7-timer";
-+		interrupts = <1 2 0xf08>,
-+			     <1 3 0xf08>,
-+			     <1 4 0xf08>,
-+			     <1 1 0xf08>;
-+		clock-frequency = <19200000>;
-+	};
-+
- 	soc: soc {
- 		#address-cells = <1>;
- 		#size-cells = <1>;
-@@ -71,15 +85,6 @@
- 			      <0xf9002000 0x1000>;
- 		};
- 
--		timer {
--			compatible = "arm,armv7-timer";
--			interrupts = <1 2 0xf08>,
--				     <1 3 0xf08>,
--				     <1 4 0xf08>,
--				     <1 1 0xf08>;
--			clock-frequency = <19200000>;
--		};
--
- 		timer@f9020000 {
- 			#address-cells = <1>;
- 			#size-cells = <1>;
-@@ -190,6 +195,7 @@
- 			interrupts = <0 108 0x0>;
- 			clocks = <&gcc GCC_BLSP1_UART2_APPS_CLK>, <&gcc GCC_BLSP1_AHB_CLK>;
- 			clock-names = "core", "iface";
-+			status = "disabled";
- 		};
- 
- 		sdhci@f9824900 {
-@@ -229,25 +235,6 @@
- 			interrupt-controller;
- 			#interrupt-cells = <2>;
- 			interrupts = <0 208 0>;
--
--			spi8_default: spi8_default {
--				mosi {
--					pins = "gpio45";
--					function = "blsp_spi8";
--				};
--				miso {
--					pins = "gpio46";
--					function = "blsp_spi8";
--				};
--				cs {
--					pins = "gpio47";
--					function = "blsp_spi8";
--				};
--				clk {
--					pins = "gpio48";
--					function = "blsp_spi8";
--				};
--			};
- 		};
- 	};
- };
diff --git a/target/linux/ipq806x/patches/0092-ARM-dts-qcom-Update-msm8960-device-trees.patch b/target/linux/ipq806x/patches/0092-ARM-dts-qcom-Update-msm8960-device-trees.patch
deleted file mode 100644
index 5b24b4a..0000000
--- a/target/linux/ipq806x/patches/0092-ARM-dts-qcom-Update-msm8960-device-trees.patch
+++ /dev/null
@@ -1,261 +0,0 @@
-From 881200420e6ece87d9abbb13c0653d26455cdbdd Mon Sep 17 00:00:00 2001
-From: Kumar Gala <galak@codeaurora.org>
-Date: Wed, 28 May 2014 12:09:53 -0500
-Subject: [PATCH 092/182] ARM: dts: qcom: Update msm8960 device trees
-
-* Move SoC peripherals into an SoC container node
-* Move serial enabling into board file (qcom-msm8960-cdp.dts)
-* Cleanup cpu node to match binding spec, enable-method and compatible
-  should be per cpu, not part of the container
-* Drop interrupts property from l2-cache node as its not part of the
-  binding spec
-* Add GSBI node and configuration of GSBI controller
-
-Signed-off-by: Kumar Gala <galak@codeaurora.org>
----
- arch/arm/boot/dts/qcom-msm8960-cdp.dts |   10 ++
- arch/arm/boot/dts/qcom-msm8960.dtsi    |  176 ++++++++++++++++++--------------
- 2 files changed, 108 insertions(+), 78 deletions(-)
-
---- a/arch/arm/boot/dts/qcom-msm8960-cdp.dts
-+++ b/arch/arm/boot/dts/qcom-msm8960-cdp.dts
-@@ -3,4 +3,14 @@
- / {
- 	model = "Qualcomm MSM8960 CDP";
- 	compatible = "qcom,msm8960-cdp", "qcom,msm8960";
-+
-+	soc {
-+		gsbi@16400000 {
-+			status = "ok";
-+			qcom,mode = <GSBI_PROT_I2C_UART>;
-+			serial@16440000 {
-+				status = "ok";
-+			};
-+		};
-+	};
- };
---- a/arch/arm/boot/dts/qcom-msm8960.dtsi
-+++ b/arch/arm/boot/dts/qcom-msm8960.dtsi
-@@ -3,6 +3,7 @@
- /include/ "skeleton.dtsi"
- 
- #include <dt-bindings/clock/qcom,gcc-msm8960.h>
-+#include <dt-bindings/soc/qcom,gsbi.h>
- 
- / {
- 	model = "Qualcomm MSM8960";
-@@ -13,10 +14,10 @@
- 		#address-cells = <1>;
- 		#size-cells = <0>;
- 		interrupts = <1 14 0x304>;
--		compatible = "qcom,krait";
--		enable-method = "qcom,kpss-acc-v1";
- 
- 		cpu@0 {
-+			compatible = "qcom,krait";
-+			enable-method = "qcom,kpss-acc-v1";
- 			device_type = "cpu";
- 			reg = <0>;
- 			next-level-cache = <&L2>;
-@@ -25,6 +26,8 @@
- 		};
- 
- 		cpu@1 {
-+			compatible = "qcom,krait";
-+			enable-method = "qcom,kpss-acc-v1";
- 			device_type = "cpu";
- 			reg = <1>;
- 			next-level-cache = <&L2>;
-@@ -35,7 +38,6 @@
- 		L2: l2-cache {
- 			compatible = "cache";
- 			cache-level = <2>;
--			interrupts = <0 2 0x4>;
- 		};
- 	};
- 
-@@ -45,91 +47,109 @@
- 		qcom,no-pc-write;
- 	};
- 
--	intc: interrupt-controller@2000000 {
--		compatible = "qcom,msm-qgic2";
--		interrupt-controller;
--		#interrupt-cells = <3>;
--		reg = < 0x02000000 0x1000 >,
--		      < 0x02002000 0x1000 >;
--	};
-+	soc: soc {
-+		#address-cells = <1>;
-+		#size-cells = <1>;
-+		ranges;
-+		compatible = "simple-bus";
-+
-+		intc: interrupt-controller@2000000 {
-+			compatible = "qcom,msm-qgic2";
-+			interrupt-controller;
-+			#interrupt-cells = <3>;
-+			reg = <0x02000000 0x1000>,
-+			      <0x02002000 0x1000>;
-+		};
- 
--	timer@200a000 {
--		compatible = "qcom,kpss-timer", "qcom,msm-timer";
--		interrupts = <1 1 0x301>,
--			     <1 2 0x301>,
--			     <1 3 0x301>;
--		reg = <0x0200a000 0x100>;
--		clock-frequency = <27000000>,
--				  <32768>;
--		cpu-offset = <0x80000>;
--	};
-+		timer@200a000 {
-+			compatible = "qcom,kpss-timer", "qcom,msm-timer";
-+			interrupts = <1 1 0x301>,
-+				     <1 2 0x301>,
-+				     <1 3 0x301>;
-+			reg = <0x0200a000 0x100>;
-+			clock-frequency = <27000000>,
-+					  <32768>;
-+			cpu-offset = <0x80000>;
-+		};
- 
--	msmgpio: gpio@800000 {
--		compatible = "qcom,msm-gpio";
--		gpio-controller;
--		#gpio-cells = <2>;
--		ngpio = <150>;
--		interrupts = <0 16 0x4>;
--		interrupt-controller;
--		#interrupt-cells = <2>;
--		reg = <0x800000 0x4000>;
--	};
-+		msmgpio: gpio@800000 {
-+			compatible = "qcom,msm-gpio";
-+			gpio-controller;
-+			#gpio-cells = <2>;
-+			ngpio = <150>;
-+			interrupts = <0 16 0x4>;
-+			interrupt-controller;
-+			#interrupt-cells = <2>;
-+			reg = <0x800000 0x4000>;
-+		};
- 
--	gcc: clock-controller@900000 {
--		compatible = "qcom,gcc-msm8960";
--		#clock-cells = <1>;
--		#reset-cells = <1>;
--		reg = <0x900000 0x4000>;
--	};
-+		gcc: clock-controller@900000 {
-+			compatible = "qcom,gcc-msm8960";
-+			#clock-cells = <1>;
-+			#reset-cells = <1>;
-+			reg = <0x900000 0x4000>;
-+		};
- 
--	clock-controller@4000000 {
--		compatible = "qcom,mmcc-msm8960";
--		reg = <0x4000000 0x1000>;
--		#clock-cells = <1>;
--		#reset-cells = <1>;
--	};
-+		clock-controller@4000000 {
-+			compatible = "qcom,mmcc-msm8960";
-+			reg = <0x4000000 0x1000>;
-+			#clock-cells = <1>;
-+			#reset-cells = <1>;
-+		};
- 
--	acc0: clock-controller@2088000 {
--		compatible = "qcom,kpss-acc-v1";
--		reg = <0x02088000 0x1000>, <0x02008000 0x1000>;
--	};
-+		acc0: clock-controller@2088000 {
-+			compatible = "qcom,kpss-acc-v1";
-+			reg = <0x02088000 0x1000>, <0x02008000 0x1000>;
-+		};
- 
--	acc1: clock-controller@2098000 {
--		compatible = "qcom,kpss-acc-v1";
--		reg = <0x02098000 0x1000>, <0x02008000 0x1000>;
--	};
-+		acc1: clock-controller@2098000 {
-+			compatible = "qcom,kpss-acc-v1";
-+			reg = <0x02098000 0x1000>, <0x02008000 0x1000>;
-+		};
- 
--	saw0: regulator@2089000 {
--		compatible = "qcom,saw2";
--		reg = <0x02089000 0x1000>, <0x02009000 0x1000>;
--		regulator;
--	};
-+		saw0: regulator@2089000 {
-+			compatible = "qcom,saw2";
-+			reg = <0x02089000 0x1000>, <0x02009000 0x1000>;
-+			regulator;
-+		};
- 
--	saw1: regulator@2099000 {
--		compatible = "qcom,saw2";
--		reg = <0x02099000 0x1000>, <0x02009000 0x1000>;
--		regulator;
--	};
-+		saw1: regulator@2099000 {
-+			compatible = "qcom,saw2";
-+			reg = <0x02099000 0x1000>, <0x02009000 0x1000>;
-+			regulator;
-+		};
- 
--	serial@16440000 {
--		compatible = "qcom,msm-uartdm-v1.3", "qcom,msm-uartdm";
--		reg = <0x16440000 0x1000>,
--		      <0x16400000 0x1000>;
--		interrupts = <0 154 0x0>;
--		clocks = <&gcc GSBI5_UART_CLK>, <&gcc GSBI5_H_CLK>;
--		clock-names = "core", "iface";
--	};
-+		gsbi5: gsbi@16400000 {
-+			compatible = "qcom,gsbi-v1.0.0";
-+			reg = <0x16400000 0x100>;
-+			clocks = <&gcc GSBI5_H_CLK>;
-+			clock-names = "iface";
-+			#address-cells = <1>;
-+			#size-cells = <1>;
-+			ranges;
-+
-+			serial@16440000 {
-+				compatible = "qcom,msm-uartdm-v1.3", "qcom,msm-uartdm";
-+				reg = <0x16440000 0x1000>,
-+				      <0x16400000 0x1000>;
-+				interrupts = <0 154 0x0>;
-+				clocks = <&gcc GSBI5_UART_CLK>, <&gcc GSBI5_H_CLK>;
-+				clock-names = "core", "iface";
-+				status = "disabled";
-+			};
-+		};
- 
--	qcom,ssbi@500000 {
--		compatible = "qcom,ssbi";
--		reg = <0x500000 0x1000>;
--		qcom,controller-type = "pmic-arbiter";
--	};
-+		qcom,ssbi@500000 {
-+			compatible = "qcom,ssbi";
-+			reg = <0x500000 0x1000>;
-+			qcom,controller-type = "pmic-arbiter";
-+		};
- 
--	rng@1a500000 {
--		compatible = "qcom,prng";
--		reg = <0x1a500000 0x200>;
--		clocks = <&gcc PRNG_CLK>;
--		clock-names = "core";
-+		rng@1a500000 {
-+			compatible = "qcom,prng";
-+			reg = <0x1a500000 0x200>;
-+			clocks = <&gcc PRNG_CLK>;
-+			clock-names = "core";
-+		};
- 	};
- };
diff --git a/target/linux/ipq806x/patches/0093-ARM-dts-qcom-Update-msm8660-device-trees.patch b/target/linux/ipq806x/patches/0093-ARM-dts-qcom-Update-msm8660-device-trees.patch
deleted file mode 100644
index 8359faf..0000000
--- a/target/linux/ipq806x/patches/0093-ARM-dts-qcom-Update-msm8660-device-trees.patch
+++ /dev/null
@@ -1,184 +0,0 @@
-From 355bf7c6410f5b6e37b5c2b28ebe59bb701c42d6 Mon Sep 17 00:00:00 2001
-From: Kumar Gala <galak@codeaurora.org>
-Date: Wed, 28 May 2014 12:12:40 -0500
-Subject: [PATCH 093/182] ARM: dts: qcom: Update msm8660 device trees
-
-* Move SoC peripherals into an SoC container node
-* Move serial enabling into board file (qcom-msm8660-surf.dts)
-* Cleanup cpu node to match binding spec, enable-method and compatible
-  should be per cpu, not part of the container
-* Add GSBI node and configuration of GSBI controller
-
-Signed-off-by: Kumar Gala <galak@codeaurora.org>
----
- arch/arm/boot/dts/qcom-msm8660-surf.dts |   10 +++
- arch/arm/boot/dts/qcom-msm8660.dtsi     |  115 ++++++++++++++++++-------------
- 2 files changed, 78 insertions(+), 47 deletions(-)
-
---- a/arch/arm/boot/dts/qcom-msm8660-surf.dts
-+++ b/arch/arm/boot/dts/qcom-msm8660-surf.dts
-@@ -3,4 +3,14 @@
- / {
- 	model = "Qualcomm MSM8660 SURF";
- 	compatible = "qcom,msm8660-surf", "qcom,msm8660";
-+
-+	soc {
-+		gsbi@19c00000 {
-+			status = "ok";
-+			qcom,mode = <GSBI_PROT_I2C_UART>;
-+			serial@19c40000 {
-+				status = "ok";
-+			};
-+		};
-+	};
- };
---- a/arch/arm/boot/dts/qcom-msm8660.dtsi
-+++ b/arch/arm/boot/dts/qcom-msm8660.dtsi
-@@ -3,6 +3,7 @@
- /include/ "skeleton.dtsi"
- 
- #include <dt-bindings/clock/qcom,gcc-msm8660.h>
-+#include <dt-bindings/soc/qcom,gsbi.h>
- 
- / {
- 	model = "Qualcomm MSM8660";
-@@ -12,16 +13,18 @@
- 	cpus {
- 		#address-cells = <1>;
- 		#size-cells = <0>;
--		compatible = "qcom,scorpion";
--		enable-method = "qcom,gcc-msm8660";
- 
- 		cpu@0 {
-+			compatible = "qcom,scorpion";
-+			enable-method = "qcom,gcc-msm8660";
- 			device_type = "cpu";
- 			reg = <0>;
- 			next-level-cache = <&L2>;
- 		};
- 
- 		cpu@1 {
-+			compatible = "qcom,scorpion";
-+			enable-method = "qcom,gcc-msm8660";
- 			device_type = "cpu";
- 			reg = <1>;
- 			next-level-cache = <&L2>;
-@@ -33,55 +36,73 @@
- 		};
- 	};
- 
--	intc: interrupt-controller@2080000 {
--		compatible = "qcom,msm-8660-qgic";
--		interrupt-controller;
--		#interrupt-cells = <3>;
--		reg = < 0x02080000 0x1000 >,
--		      < 0x02081000 0x1000 >;
--	};
-+	soc: soc {
-+		#address-cells = <1>;
-+		#size-cells = <1>;
-+		ranges;
-+		compatible = "simple-bus";
-+
-+		intc: interrupt-controller@2080000 {
-+			compatible = "qcom,msm-8660-qgic";
-+			interrupt-controller;
-+			#interrupt-cells = <3>;
-+			reg = < 0x02080000 0x1000 >,
-+			      < 0x02081000 0x1000 >;
-+		};
- 
--	timer@2000000 {
--		compatible = "qcom,scss-timer", "qcom,msm-timer";
--		interrupts = <1 0 0x301>,
--			     <1 1 0x301>,
--			     <1 2 0x301>;
--		reg = <0x02000000 0x100>;
--		clock-frequency = <27000000>,
--				  <32768>;
--		cpu-offset = <0x40000>;
--	};
-+		timer@2000000 {
-+			compatible = "qcom,scss-timer", "qcom,msm-timer";
-+			interrupts = <1 0 0x301>,
-+				     <1 1 0x301>,
-+				     <1 2 0x301>;
-+			reg = <0x02000000 0x100>;
-+			clock-frequency = <27000000>,
-+					  <32768>;
-+			cpu-offset = <0x40000>;
-+		};
- 
--	msmgpio: gpio@800000 {
--		compatible = "qcom,msm-gpio";
--		reg = <0x00800000 0x4000>;
--		gpio-controller;
--		#gpio-cells = <2>;
--		ngpio = <173>;
--		interrupts = <0 16 0x4>;
--		interrupt-controller;
--		#interrupt-cells = <2>;
--	};
-+		msmgpio: gpio@800000 {
-+			compatible = "qcom,msm-gpio";
-+			reg = <0x00800000 0x4000>;
-+			gpio-controller;
-+			#gpio-cells = <2>;
-+			ngpio = <173>;
-+			interrupts = <0 16 0x4>;
-+			interrupt-controller;
-+			#interrupt-cells = <2>;
-+		};
- 
--	gcc: clock-controller@900000 {
--		compatible = "qcom,gcc-msm8660";
--		#clock-cells = <1>;
--		#reset-cells = <1>;
--		reg = <0x900000 0x4000>;
--	};
-+		gcc: clock-controller@900000 {
-+			compatible = "qcom,gcc-msm8660";
-+			#clock-cells = <1>;
-+			#reset-cells = <1>;
-+			reg = <0x900000 0x4000>;
-+		};
- 
--	serial@19c40000 {
--		compatible = "qcom,msm-uartdm-v1.3", "qcom,msm-uartdm";
--		reg = <0x19c40000 0x1000>,
--		      <0x19c00000 0x1000>;
--		interrupts = <0 195 0x0>;
--		clocks = <&gcc GSBI12_UART_CLK>, <&gcc GSBI12_H_CLK>;
--		clock-names = "core", "iface";
--	};
-+		gsbi12: gsbi@19c00000 {
-+			compatible = "qcom,gsbi-v1.0.0";
-+			reg = <0x19c00000 0x100>;
-+			clocks = <&gcc GSBI12_H_CLK>;
-+			clock-names = "iface";
-+			#address-cells = <1>;
-+			#size-cells = <1>;
-+			ranges;
-+
-+			serial@19c40000 {
-+				compatible = "qcom,msm-uartdm-v1.3", "qcom,msm-uartdm";
-+				reg = <0x19c40000 0x1000>,
-+				      <0x19c00000 0x1000>;
-+				interrupts = <0 195 0x0>;
-+				clocks = <&gcc GSBI12_UART_CLK>, <&gcc GSBI12_H_CLK>;
-+				clock-names = "core", "iface";
-+				status = "disabled";
-+			};
-+		};
- 
--	qcom,ssbi@500000 {
--		compatible = "qcom,ssbi";
--		reg = <0x500000 0x1000>;
--		qcom,controller-type = "pmic-arbiter";
-+		qcom,ssbi@500000 {
-+			compatible = "qcom,ssbi";
-+			reg = <0x500000 0x1000>;
-+			qcom,controller-type = "pmic-arbiter";
-+		};
- 	};
- };
diff --git a/target/linux/ipq806x/patches/0094-ARM-dts-qcom-Add-initial-APQ8064-SoC-and-IFC6410-boa.patch b/target/linux/ipq806x/patches/0094-ARM-dts-qcom-Add-initial-APQ8064-SoC-and-IFC6410-boa.patch
deleted file mode 100644
index fb2910b..0000000
--- a/target/linux/ipq806x/patches/0094-ARM-dts-qcom-Add-initial-APQ8064-SoC-and-IFC6410-boa.patch
+++ /dev/null
@@ -1,249 +0,0 @@
-From 07d7d95706c1bf373bd6b30c42f95c7b8dc8b9ce Mon Sep 17 00:00:00 2001
-From: Kumar Gala <galak@codeaurora.org>
-Date: Thu, 3 Apr 2014 14:48:22 -0500
-Subject: [PATCH 094/182] ARM: dts: qcom: Add initial APQ8064 SoC and IFC6410
- board device trees
-
-Add basic APQ8064 SoC include device tree and support for basic booting on
-the IFC6410 board.  Also, keep dtb build list and qcom_dt_match in sorted
-order.
-
-Signed-off-by: Kumar Gala <galak@codeaurora.org>
----
- arch/arm/boot/dts/Makefile                 |    8 +-
- arch/arm/boot/dts/qcom-apq8064-ifc6410.dts |   16 +++
- arch/arm/boot/dts/qcom-apq8064-v2.0.dtsi   |    1 +
- arch/arm/boot/dts/qcom-apq8064.dtsi        |  170 ++++++++++++++++++++++++++++
- arch/arm/mach-qcom/board.c                 |    3 +-
- 5 files changed, 194 insertions(+), 4 deletions(-)
- create mode 100644 arch/arm/boot/dts/qcom-apq8064-ifc6410.dts
- create mode 100644 arch/arm/boot/dts/qcom-apq8064-v2.0.dtsi
- create mode 100644 arch/arm/boot/dts/qcom-apq8064.dtsi
-
---- a/arch/arm/boot/dts/Makefile
-+++ b/arch/arm/boot/dts/Makefile
-@@ -231,9 +231,11 @@ dtb-$(CONFIG_ARCH_OMAP2PLUS) += omap2420
- 	dra7-evm.dtb
- dtb-$(CONFIG_ARCH_ORION5X) += orion5x-lacie-ethernet-disk-mini-v2.dtb
- dtb-$(CONFIG_ARCH_PRIMA2) += prima2-evb.dtb
--dtb-$(CONFIG_ARCH_QCOM) += qcom-msm8660-surf.dtb \
--	qcom-msm8960-cdp.dtb \
--	qcom-apq8074-dragonboard.dtb
-+dtb-$(CONFIG_ARCH_QCOM) += \
-+	qcom-apq8064-ifc6410.dtb \
-+	qcom-apq8074-dragonboard.dtb \
-+	qcom-msm8660-surf.dtb \
-+	qcom-msm8960-cdp.dtb
- dtb-$(CONFIG_ARCH_U8500) += ste-snowball.dtb \
- 	ste-hrefprev60-stuib.dtb \
- 	ste-hrefprev60-tvk.dtb \
---- /dev/null
-+++ b/arch/arm/boot/dts/qcom-apq8064-ifc6410.dts
-@@ -0,0 +1,16 @@
-+#include "qcom-apq8064-v2.0.dtsi"
-+
-+/ {
-+	model = "Qualcomm APQ8064/IFC6410";
-+	compatible = "qcom,apq8064-ifc6410", "qcom,apq8064";
-+
-+	soc {
-+		gsbi@16600000 {
-+			status = "ok";
-+			qcom,mode = <GSBI_PROT_I2C_UART>;
-+			serial@16640000 {
-+				status = "ok";
-+			};
-+		};
-+	};
-+};
---- /dev/null
-+++ b/arch/arm/boot/dts/qcom-apq8064-v2.0.dtsi
-@@ -0,0 +1 @@
-+#include "qcom-apq8064.dtsi"
---- /dev/null
-+++ b/arch/arm/boot/dts/qcom-apq8064.dtsi
-@@ -0,0 +1,170 @@
-+/dts-v1/;
-+
-+#include "skeleton.dtsi"
-+#include <dt-bindings/clock/qcom,gcc-msm8960.h>
-+#include <dt-bindings/soc/qcom,gsbi.h>
-+
-+/ {
-+	model = "Qualcomm APQ8064";
-+	compatible = "qcom,apq8064";
-+	interrupt-parent = <&intc>;
-+
-+	cpus {
-+		#address-cells = <1>;
-+		#size-cells = <0>;
-+
-+		cpu@0 {
-+			compatible = "qcom,krait";
-+			enable-method = "qcom,kpss-acc-v1";
-+			device_type = "cpu";
-+			reg = <0>;
-+			next-level-cache = <&L2>;
-+			qcom,acc = <&acc0>;
-+			qcom,saw = <&saw0>;
-+		};
-+
-+		cpu@1 {
-+			compatible = "qcom,krait";
-+			enable-method = "qcom,kpss-acc-v1";
-+			device_type = "cpu";
-+			reg = <1>;
-+			next-level-cache = <&L2>;
-+			qcom,acc = <&acc1>;
-+			qcom,saw = <&saw1>;
-+		};
-+
-+		cpu@2 {
-+			compatible = "qcom,krait";
-+			enable-method = "qcom,kpss-acc-v1";
-+			device_type = "cpu";
-+			reg = <2>;
-+			next-level-cache = <&L2>;
-+			qcom,acc = <&acc2>;
-+			qcom,saw = <&saw2>;
-+		};
-+
-+		cpu@3 {
-+			compatible = "qcom,krait";
-+			enable-method = "qcom,kpss-acc-v1";
-+			device_type = "cpu";
-+			reg = <3>;
-+			next-level-cache = <&L2>;
-+			qcom,acc = <&acc3>;
-+			qcom,saw = <&saw3>;
-+		};
-+
-+		L2: l2-cache {
-+			compatible = "cache";
-+			cache-level = <2>;
-+		};
-+	};
-+
-+	cpu-pmu {
-+		compatible = "qcom,krait-pmu";
-+		interrupts = <1 10 0x304>;
-+	};
-+
-+	soc: soc {
-+		#address-cells = <1>;
-+		#size-cells = <1>;
-+		ranges;
-+		compatible = "simple-bus";
-+
-+		intc: interrupt-controller@2000000 {
-+			compatible = "qcom,msm-qgic2";
-+			interrupt-controller;
-+			#interrupt-cells = <3>;
-+			reg = <0x02000000 0x1000>,
-+			      <0x02002000 0x1000>;
-+		};
-+
-+		timer@200a000 {
-+			compatible = "qcom,kpss-timer", "qcom,msm-timer";
-+			interrupts = <1 1 0x301>,
-+				     <1 2 0x301>,
-+				     <1 3 0x301>;
-+			reg = <0x0200a000 0x100>;
-+			clock-frequency = <27000000>,
-+					  <32768>;
-+			cpu-offset = <0x80000>;
-+		};
-+
-+		acc0: clock-controller@2088000 {
-+			compatible = "qcom,kpss-acc-v1";
-+			reg = <0x02088000 0x1000>, <0x02008000 0x1000>;
-+		};
-+
-+		acc1: clock-controller@2098000 {
-+			compatible = "qcom,kpss-acc-v1";
-+			reg = <0x02098000 0x1000>, <0x02008000 0x1000>;
-+		};
-+
-+		acc2: clock-controller@20a8000 {
-+			compatible = "qcom,kpss-acc-v1";
-+			reg = <0x020a8000 0x1000>, <0x02008000 0x1000>;
-+		};
-+
-+		acc3: clock-controller@20b8000 {
-+			compatible = "qcom,kpss-acc-v1";
-+			reg = <0x020b8000 0x1000>, <0x02008000 0x1000>;
-+		};
-+
-+		saw0: regulator@2089000 {
-+			compatible = "qcom,saw2";
-+			reg = <0x02089000 0x1000>, <0x02009000 0x1000>;
-+			regulator;
-+		};
-+
-+		saw1: regulator@2099000 {
-+			compatible = "qcom,saw2";
-+			reg = <0x02099000 0x1000>, <0x02009000 0x1000>;
-+			regulator;
-+		};
-+
-+		saw2: regulator@20a9000 {
-+			compatible = "qcom,saw2";
-+			reg = <0x020a9000 0x1000>, <0x02009000 0x1000>;
-+			regulator;
-+		};
-+
-+		saw3: regulator@20b9000 {
-+			compatible = "qcom,saw2";
-+			reg = <0x020b9000 0x1000>, <0x02009000 0x1000>;
-+			regulator;
-+		};
-+
-+		gsbi7: gsbi@16600000 {
-+			status = "disabled";
-+			compatible = "qcom,gsbi-v1.0.0";
-+			reg = <0x16600000 0x100>;
-+			clocks = <&gcc GSBI7_H_CLK>;
-+			clock-names = "iface";
-+			#address-cells = <1>;
-+			#size-cells = <1>;
-+			ranges;
-+
-+			serial@16640000 {
-+				compatible = "qcom,msm-uartdm-v1.3", "qcom,msm-uartdm";
-+				reg = <0x16640000 0x1000>,
-+				      <0x16600000 0x1000>;
-+				interrupts = <0 158 0x0>;
-+				clocks = <&gcc GSBI7_UART_CLK>, <&gcc GSBI7_H_CLK>;
-+				clock-names = "core", "iface";
-+				status = "disabled";
-+			};
-+		};
-+
-+		qcom,ssbi@500000 {
-+			compatible = "qcom,ssbi";
-+			reg = <0x00500000 0x1000>;
-+			qcom,controller-type = "pmic-arbiter";
-+		};
-+
-+		gcc: clock-controller@900000 {
-+			compatible = "qcom,gcc-apq8064";
-+			reg = <0x00900000 0x4000>;
-+			#clock-cells = <1>;
-+			#reset-cells = <1>;
-+		};
-+	};
-+};
---- a/arch/arm/mach-qcom/board.c
-+++ b/arch/arm/mach-qcom/board.c
-@@ -15,9 +15,10 @@
- #include <asm/mach/arch.h>
- 
- static const char * const qcom_dt_match[] __initconst = {
-+	"qcom,apq8064",
-+	"qcom,apq8074-dragonboard",
- 	"qcom,msm8660-surf",
- 	"qcom,msm8960-cdp",
--	"qcom,apq8074-dragonboard",
- 	NULL
- };
- 
diff --git a/target/linux/ipq806x/patches/0095-ARM-dts-qcom-Add-APQ8084-MTP-board-support.patch b/target/linux/ipq806x/patches/0095-ARM-dts-qcom-Add-APQ8084-MTP-board-support.patch
deleted file mode 100644
index 3c4f221..0000000
--- a/target/linux/ipq806x/patches/0095-ARM-dts-qcom-Add-APQ8084-MTP-board-support.patch
+++ /dev/null
@@ -1,35 +0,0 @@
-From 9b06bc14f21463cf687ac6fdd07ca04b99c15466 Mon Sep 17 00:00:00 2001
-From: Georgi Djakov <gdjakov@mm-sol.com>
-Date: Fri, 23 May 2014 18:12:30 +0300
-Subject: [PATCH 095/182] ARM: dts: qcom: Add APQ8084-MTP board support
-
-Add device-tree file for APQ8084-MTP board, which belongs
-to the Snapdragon 805 family.
-
-Signed-off-by: Georgi Djakov <gdjakov@mm-sol.com>
-Signed-off-by: Kumar Gala <galak@codeaurora.org>
----
- arch/arm/boot/dts/Makefile             |    1 +
- arch/arm/boot/dts/qcom-apq8084-mtp.dts |    6 ++++++
- 2 files changed, 7 insertions(+)
- create mode 100644 arch/arm/boot/dts/qcom-apq8084-mtp.dts
-
---- a/arch/arm/boot/dts/Makefile
-+++ b/arch/arm/boot/dts/Makefile
-@@ -234,6 +234,7 @@ dtb-$(CONFIG_ARCH_PRIMA2) += prima2-evb.
- dtb-$(CONFIG_ARCH_QCOM) += \
- 	qcom-apq8064-ifc6410.dtb \
- 	qcom-apq8074-dragonboard.dtb \
-+	qcom-apq8084-mtp.dtb \
- 	qcom-msm8660-surf.dtb \
- 	qcom-msm8960-cdp.dtb
- dtb-$(CONFIG_ARCH_U8500) += ste-snowball.dtb \
---- /dev/null
-+++ b/arch/arm/boot/dts/qcom-apq8084-mtp.dts
-@@ -0,0 +1,6 @@
-+#include "qcom-apq8084.dtsi"
-+
-+/ {
-+	model = "Qualcomm APQ 8084-MTP";
-+	compatible = "qcom,apq8084-mtp", "qcom,apq8084";
-+};
diff --git a/target/linux/ipq806x/patches/0096-ARM-dts-qcom-Add-APQ8084-SoC-support.patch b/target/linux/ipq806x/patches/0096-ARM-dts-qcom-Add-APQ8084-SoC-support.patch
deleted file mode 100644
index 1863059..0000000
--- a/target/linux/ipq806x/patches/0096-ARM-dts-qcom-Add-APQ8084-SoC-support.patch
+++ /dev/null
@@ -1,208 +0,0 @@
-From 8c52931421759b70fc37771be3390813a2a2f9f5 Mon Sep 17 00:00:00 2001
-From: Georgi Djakov <gdjakov@mm-sol.com>
-Date: Fri, 23 May 2014 18:12:29 +0300
-Subject: [PATCH 096/182] ARM: dts: qcom: Add APQ8084 SoC support
-
-Add support for the Qualcomm Snapdragon 805 APQ8084 SoC. It is
-used on APQ8084-MTP and other boards.
-
-Signed-off-by: Georgi Djakov <gdjakov@mm-sol.com>
-Signed-off-by: Kumar Gala <galak@codeaurora.org>
----
- arch/arm/boot/dts/qcom-apq8084.dtsi |  179 +++++++++++++++++++++++++++++++++++
- arch/arm/mach-qcom/board.c          |    1 +
- 2 files changed, 180 insertions(+)
- create mode 100644 arch/arm/boot/dts/qcom-apq8084.dtsi
-
---- /dev/null
-+++ b/arch/arm/boot/dts/qcom-apq8084.dtsi
-@@ -0,0 +1,179 @@
-+/dts-v1/;
-+
-+#include "skeleton.dtsi"
-+
-+/ {
-+	model = "Qualcomm APQ 8084";
-+	compatible = "qcom,apq8084";
-+	interrupt-parent = <&intc>;
-+
-+	cpus {
-+		#address-cells = <1>;
-+		#size-cells = <0>;
-+
-+		cpu@0 {
-+			device_type = "cpu";
-+			compatible = "qcom,krait";
-+			reg = <0>;
-+			enable-method = "qcom,kpss-acc-v2";
-+			next-level-cache = <&L2>;
-+			qcom,acc = <&acc0>;
-+		};
-+
-+		cpu@1 {
-+			device_type = "cpu";
-+			compatible = "qcom,krait";
-+			reg = <1>;
-+			enable-method = "qcom,kpss-acc-v2";
-+			next-level-cache = <&L2>;
-+			qcom,acc = <&acc1>;
-+		};
-+
-+		cpu@2 {
-+			device_type = "cpu";
-+			compatible = "qcom,krait";
-+			reg = <2>;
-+			enable-method = "qcom,kpss-acc-v2";
-+			next-level-cache = <&L2>;
-+			qcom,acc = <&acc2>;
-+		};
-+
-+		cpu@3 {
-+			device_type = "cpu";
-+			compatible = "qcom,krait";
-+			reg = <3>;
-+			enable-method = "qcom,kpss-acc-v2";
-+			next-level-cache = <&L2>;
-+			qcom,acc = <&acc3>;
-+		};
-+
-+		L2: l2-cache {
-+			compatible = "qcom,arch-cache";
-+			cache-level = <2>;
-+			qcom,saw = <&saw_l2>;
-+		};
-+	};
-+
-+	cpu-pmu {
-+		compatible = "qcom,krait-pmu";
-+		interrupts = <1 7 0xf04>;
-+	};
-+
-+	timer {
-+		compatible = "arm,armv7-timer";
-+		interrupts = <1 2 0xf08>,
-+			     <1 3 0xf08>,
-+			     <1 4 0xf08>,
-+			     <1 1 0xf08>;
-+		clock-frequency = <19200000>;
-+	};
-+
-+	soc: soc {
-+		#address-cells = <1>;
-+		#size-cells = <1>;
-+		ranges;
-+		compatible = "simple-bus";
-+
-+		intc: interrupt-controller@f9000000 {
-+			compatible = "qcom,msm-qgic2";
-+			interrupt-controller;
-+			#interrupt-cells = <3>;
-+			reg = <0xf9000000 0x1000>,
-+			      <0xf9002000 0x1000>;
-+		};
-+
-+		timer@f9020000 {
-+			#address-cells = <1>;
-+			#size-cells = <1>;
-+			ranges;
-+			compatible = "arm,armv7-timer-mem";
-+			reg = <0xf9020000 0x1000>;
-+			clock-frequency = <19200000>;
-+
-+			frame@f9021000 {
-+				frame-number = <0>;
-+				interrupts = <0 8 0x4>,
-+					     <0 7 0x4>;
-+				reg = <0xf9021000 0x1000>,
-+				      <0xf9022000 0x1000>;
-+			};
-+
-+			frame@f9023000 {
-+				frame-number = <1>;
-+				interrupts = <0 9 0x4>;
-+				reg = <0xf9023000 0x1000>;
-+				status = "disabled";
-+			};
-+
-+			frame@f9024000 {
-+				frame-number = <2>;
-+				interrupts = <0 10 0x4>;
-+				reg = <0xf9024000 0x1000>;
-+				status = "disabled";
-+			};
-+
-+			frame@f9025000 {
-+				frame-number = <3>;
-+				interrupts = <0 11 0x4>;
-+				reg = <0xf9025000 0x1000>;
-+				status = "disabled";
-+			};
-+
-+			frame@f9026000 {
-+				frame-number = <4>;
-+				interrupts = <0 12 0x4>;
-+				reg = <0xf9026000 0x1000>;
-+				status = "disabled";
-+			};
-+
-+			frame@f9027000 {
-+				frame-number = <5>;
-+				interrupts = <0 13 0x4>;
-+				reg = <0xf9027000 0x1000>;
-+				status = "disabled";
-+			};
-+
-+			frame@f9028000 {
-+				frame-number = <6>;
-+				interrupts = <0 14 0x4>;
-+				reg = <0xf9028000 0x1000>;
-+				status = "disabled";
-+			};
-+		};
-+
-+		saw_l2: regulator@f9012000 {
-+			compatible = "qcom,saw2";
-+			reg = <0xf9012000 0x1000>;
-+			regulator;
-+		};
-+
-+		acc0: clock-controller@f9088000 {
-+			compatible = "qcom,kpss-acc-v2";
-+			reg = <0xf9088000 0x1000>,
-+			      <0xf9008000 0x1000>;
-+		};
-+
-+		acc1: clock-controller@f9098000 {
-+			compatible = "qcom,kpss-acc-v2";
-+			reg = <0xf9098000 0x1000>,
-+			      <0xf9008000 0x1000>;
-+		};
-+
-+		acc2: clock-controller@f90a8000 {
-+			compatible = "qcom,kpss-acc-v2";
-+			reg = <0xf90a8000 0x1000>,
-+			      <0xf9008000 0x1000>;
-+		};
-+
-+		acc3: clock-controller@f90b8000 {
-+			compatible = "qcom,kpss-acc-v2";
-+			reg = <0xf90b8000 0x1000>,
-+			      <0xf9008000 0x1000>;
-+		};
-+
-+		restart@fc4ab000 {
-+			compatible = "qcom,pshold";
-+			reg = <0xfc4ab000 0x4>;
-+		};
-+	};
-+};
---- a/arch/arm/mach-qcom/board.c
-+++ b/arch/arm/mach-qcom/board.c
-@@ -17,6 +17,7 @@
- static const char * const qcom_dt_match[] __initconst = {
- 	"qcom,apq8064",
- 	"qcom,apq8074-dragonboard",
-+	"qcom,apq8084",
- 	"qcom,msm8660-surf",
- 	"qcom,msm8960-cdp",
- 	NULL
diff --git a/target/linux/ipq806x/patches/0097-ARM-debug-qcom-make-UART-address-selection-configura.patch b/target/linux/ipq806x/patches/0097-ARM-debug-qcom-make-UART-address-selection-configura.patch
deleted file mode 100644
index 1c67fb7..0000000
--- a/target/linux/ipq806x/patches/0097-ARM-debug-qcom-make-UART-address-selection-configura.patch
+++ /dev/null
@@ -1,258 +0,0 @@
-From 48167d4a55890a783cc8b1590bc8071253ae4b83 Mon Sep 17 00:00:00 2001
-From: "Ivan T. Ivanov" <iivanov@mm-sol.com>
-Date: Mon, 14 Apr 2014 16:47:34 +0300
-Subject: [PATCH 097/182] ARM: debug: qcom: make UART address selection
- configuration option
-
-Separate Qualcomm low-level debugging UART to two options.
-
-DEBUG_MSM_UART is used in earlier non-multi platform arches,
-like MSM7X00A, QSD8X50 and MSM7X30.
-
-DEBUG_QCOM_UARTDM is used in multi-plafrom arches and have
-embedded data mover.
-
-Make DEBUG_UART_PHYS and DEBUG_UART_BASE user adjustable by
-Kconfig menu.
-
-Signed-off-by: Ivan T. Ivanov <iivanov@mm-sol.com>
-Reviewed-by: Stephen Boyd <sboyd@codeaurora.org>
-Tested-by: Stephen Boyd <sboyd@codeaurora.org>
-Signed-off-by: Kumar Gala <galak@codeaurora.org>
----
- arch/arm/Kconfig.debug       |   81 +++++++++++++++++-------------------------
- arch/arm/include/debug/msm.S |   46 +++---------------------
- arch/arm/mach-msm/Kconfig    |    3 --
- 3 files changed, 38 insertions(+), 92 deletions(-)
-
---- a/arch/arm/Kconfig.debug
-+++ b/arch/arm/Kconfig.debug
-@@ -353,56 +353,39 @@ choice
- 		  Say Y here if you want kernel low-level debugging support
- 		  on MMP UART3.
- 
--	config DEBUG_MSM_UART1
--		bool "Kernel low-level debugging messages via MSM UART1"
--		depends on ARCH_MSM7X00A || ARCH_MSM7X30 || ARCH_QSD8X50
--		select DEBUG_MSM_UART
-+	config DEBUG_MSM_UART
-+		bool "Kernel low-level debugging messages via MSM UART"
-+		depends on ARCH_MSM
- 		help
- 		  Say Y here if you want the debug print routines to direct
--		  their output to the first serial port on MSM devices.
-+		  their output to the serial port on MSM devices.
- 
--	config DEBUG_MSM_UART2
--		bool "Kernel low-level debugging messages via MSM UART2"
--		depends on ARCH_MSM7X00A || ARCH_MSM7X30 || ARCH_QSD8X50
--		select DEBUG_MSM_UART
--		help
--		  Say Y here if you want the debug print routines to direct
--		  their output to the second serial port on MSM devices.
-+		  ARCH                DEBUG_UART_PHYS   DEBUG_UART_BASE   #
-+		  MSM7X00A, QSD8X50   0xa9a00000        0xe1000000        UART1
-+		  MSM7X00A, QSD8X50   0xa9b00000        0xe1000000        UART2
-+		  MSM7X00A, QSD8X50   0xa9c00000        0xe1000000        UART3
- 
--	config DEBUG_MSM_UART3
--		bool "Kernel low-level debugging messages via MSM UART3"
--		depends on ARCH_MSM7X00A || ARCH_MSM7X30 || ARCH_QSD8X50
--		select DEBUG_MSM_UART
--		help
--		  Say Y here if you want the debug print routines to direct
--		  their output to the third serial port on MSM devices.
-+		  MSM7X30             0xaca00000        0xe1000000        UART1
-+		  MSM7X30             0xacb00000        0xe1000000        UART2
-+		  MSM7X30             0xacc00000        0xe1000000        UART3
- 
--	config DEBUG_MSM8660_UART
--		bool "Kernel low-level debugging messages via MSM 8660 UART"
--		depends on ARCH_MSM8X60
--		select MSM_HAS_DEBUG_UART_HS
--		select DEBUG_MSM_UART
--		help
--		  Say Y here if you want the debug print routines to direct
--		  their output to the serial port on MSM 8660 devices.
-+		  Please adjust DEBUG_UART_PHYS and DEBUG_UART_BASE configuration
-+		  options based on your needs.
- 
--	config DEBUG_MSM8960_UART
--		bool "Kernel low-level debugging messages via MSM 8960 UART"
--		depends on ARCH_MSM8960
--		select MSM_HAS_DEBUG_UART_HS
--		select DEBUG_MSM_UART
-+	config DEBUG_QCOM_UARTDM
-+		bool "Kernel low-level debugging messages via QCOM UARTDM"
-+		depends on ARCH_QCOM
- 		help
- 		  Say Y here if you want the debug print routines to direct
--		  their output to the serial port on MSM 8960 devices.
-+		  their output to the serial port on Qualcomm devices.
- 
--	config DEBUG_MSM8974_UART
--		bool "Kernel low-level debugging messages via MSM 8974 UART"
--		depends on ARCH_MSM8974
--		select MSM_HAS_DEBUG_UART_HS
--		select DEBUG_MSM_UART
--		help
--		  Say Y here if you want the debug print routines to direct
--		  their output to the serial port on MSM 8974 devices.
-+		  ARCH      DEBUG_UART_PHYS   DEBUG_UART_BASE
-+		  MSM8X60   0x19c40000        0xf0040000
-+		  MSM8960   0x16440000        0xf0040000
-+		  MSM8974   0xf991e000        0xfa71e000
-+
-+		  Please adjust DEBUG_UART_PHYS and DEBUG_UART_BASE configuration
-+		  options based on your needs.
- 
- 	config DEBUG_MVEBU_UART
- 		bool "Kernel low-level debugging messages via MVEBU UART (old bootloaders)"
-@@ -954,10 +937,6 @@ config DEBUG_STI_UART
- 	bool
- 	depends on ARCH_STI
- 
--config DEBUG_MSM_UART
--	bool
--	depends on ARCH_MSM || ARCH_QCOM
--
- config DEBUG_LL_INCLUDE
- 	string
- 	default "debug/8250.S" if DEBUG_LL_UART_8250 || DEBUG_UART_8250
-@@ -975,7 +954,7 @@ config DEBUG_LL_INCLUDE
- 				 DEBUG_IMX53_UART ||\
- 				 DEBUG_IMX6Q_UART || \
- 				 DEBUG_IMX6SL_UART
--	default "debug/msm.S" if DEBUG_MSM_UART
-+	default "debug/msm.S" if DEBUG_MSM_UART || DEBUG_QCOM_UARTDM
- 	default "debug/omap2plus.S" if DEBUG_OMAP2PLUS_UART
- 	default "debug/sirf.S" if DEBUG_SIRFPRIMA2_UART1 || DEBUG_SIRFMARCO_UART1
- 	default "debug/sti.S" if DEBUG_STI_UART
-@@ -1039,6 +1018,7 @@ config DEBUG_UART_PHYS
- 	default 0x80074000 if DEBUG_IMX28_UART
- 	default 0x808c0000 if ARCH_EP93XX
- 	default 0x90020000 if DEBUG_NSPIRE_CLASSIC_UART || DEBUG_NSPIRE_CX_UART
-+	default 0xa9a00000 if DEBUG_MSM_UART
- 	default 0xb0090000 if DEBUG_VEXPRESS_UART0_CRX
- 	default 0xc0013000 if DEBUG_U300_UART
- 	default 0xc8000000 if ARCH_IXP4XX && !CPU_BIG_ENDIAN
-@@ -1054,6 +1034,7 @@ config DEBUG_UART_PHYS
- 				ARCH_ORION5X
- 	default 0xf7fc9000 if DEBUG_BERLIN_UART
- 	default 0xf8b00000 if DEBUG_HI3716_UART
-+	default 0xf991e000 if DEBUG_QCOM_UARTDM
- 	default 0xfcb00000 if DEBUG_HI3620_UART
- 	default 0xfe800000 if ARCH_IOP32X
- 	default 0xffc02000 if DEBUG_SOCFPGA_UART
-@@ -1062,11 +1043,13 @@ config DEBUG_UART_PHYS
- 	default 0xfffff700 if ARCH_IOP33X
- 	depends on DEBUG_LL_UART_8250 || DEBUG_LL_UART_PL01X || \
- 		DEBUG_LL_UART_EFM32 || \
--		DEBUG_UART_8250 || DEBUG_UART_PL01X
-+		DEBUG_UART_8250 || DEBUG_UART_PL01X || \
-+		DEBUG_MSM_UART || DEBUG_QCOM_UARTDM
- 
- config DEBUG_UART_VIRT
- 	hex "Virtual base address of debug UART"
- 	default 0xe0010fe0 if ARCH_RPC
-+	default 0xe1000000 if DEBUG_MSM_UART
- 	default 0xf0000be0 if ARCH_EBSA110
- 	default 0xf0009000 if DEBUG_CNS3XXX
- 	default 0xf01fb000 if DEBUG_NOMADIK_UART
-@@ -1081,6 +1064,7 @@ config DEBUG_UART_VIRT
- 	default 0xf7fc9000 if DEBUG_BERLIN_UART
- 	default 0xf8009000 if DEBUG_VEXPRESS_UART0_CA9
- 	default 0xf8090000 if DEBUG_VEXPRESS_UART0_RS1
-+	default 0xfa71e000 if DEBUG_QCOM_UARTDM
- 	default 0xfb009000 if DEBUG_REALVIEW_STD_PORT
- 	default 0xfb10c000 if DEBUG_REALVIEW_PB1176_PORT
- 	default 0xfd000000 if ARCH_SPEAR3XX || ARCH_SPEAR6XX
-@@ -1120,7 +1104,8 @@ config DEBUG_UART_VIRT
- 	default 0xff003000 if DEBUG_U300_UART
- 	default DEBUG_UART_PHYS if !MMU
- 	depends on DEBUG_LL_UART_8250 || DEBUG_LL_UART_PL01X || \
--		DEBUG_UART_8250 || DEBUG_UART_PL01X
-+		DEBUG_UART_8250 || DEBUG_UART_PL01X || \
-+		DEBUG_MSM_UART || DEBUG_QCOM_UARTDM
- 
- config DEBUG_UART_8250_SHIFT
- 	int "Register offset shift for the 8250 debug UART"
---- a/arch/arm/include/debug/msm.S
-+++ b/arch/arm/include/debug/msm.S
-@@ -15,51 +15,15 @@
-  *
-  */
- 
--#if defined(CONFIG_ARCH_MSM7X00A) || defined(CONFIG_ARCH_QSD8X50)
--#define MSM_UART1_PHYS        0xA9A00000
--#define MSM_UART2_PHYS        0xA9B00000
--#define MSM_UART3_PHYS        0xA9C00000
--#elif defined(CONFIG_ARCH_MSM7X30)
--#define MSM_UART1_PHYS        0xACA00000
--#define MSM_UART2_PHYS        0xACB00000
--#define MSM_UART3_PHYS        0xACC00000
--#endif
--
--#if defined(CONFIG_DEBUG_MSM_UART1)
--#define MSM_DEBUG_UART_BASE	0xE1000000
--#define MSM_DEBUG_UART_PHYS	MSM_UART1_PHYS
--#elif defined(CONFIG_DEBUG_MSM_UART2)
--#define MSM_DEBUG_UART_BASE	0xE1000000
--#define MSM_DEBUG_UART_PHYS	MSM_UART2_PHYS
--#elif defined(CONFIG_DEBUG_MSM_UART3)
--#define MSM_DEBUG_UART_BASE	0xE1000000
--#define MSM_DEBUG_UART_PHYS	MSM_UART3_PHYS
--#endif
--
--#ifdef CONFIG_DEBUG_MSM8660_UART
--#define MSM_DEBUG_UART_BASE	0xF0040000
--#define MSM_DEBUG_UART_PHYS	0x19C40000
--#endif
--
--#ifdef CONFIG_DEBUG_MSM8960_UART
--#define MSM_DEBUG_UART_BASE	0xF0040000
--#define MSM_DEBUG_UART_PHYS	0x16440000
--#endif
--
--#ifdef CONFIG_DEBUG_MSM8974_UART
--#define MSM_DEBUG_UART_BASE	0xFA71E000
--#define MSM_DEBUG_UART_PHYS	0xF991E000
--#endif
--
- 	.macro	addruart, rp, rv, tmp
--#ifdef MSM_DEBUG_UART_PHYS
--	ldr	\rp, =MSM_DEBUG_UART_PHYS
--	ldr	\rv, =MSM_DEBUG_UART_BASE
-+#ifdef CONFIG_DEBUG_UART_PHYS
-+	ldr	\rp, =CONFIG_DEBUG_UART_PHYS
-+	ldr	\rv, =CONFIG_DEBUG_UART_VIRT
- #endif
- 	.endm
- 
- 	.macro	senduart, rd, rx
--#ifdef CONFIG_MSM_HAS_DEBUG_UART_HS
-+#ifdef CONFIG_DEBUG_QCOM_UARTDM
- 	@ Write the 1 character to UARTDM_TF
- 	str	\rd, [\rx, #0x70]
- #else
-@@ -68,7 +32,7 @@
- 	.endm
- 
- 	.macro	waituart, rd, rx
--#ifdef CONFIG_MSM_HAS_DEBUG_UART_HS
-+#ifdef CONFIG_DEBUG_QCOM_UARTDM
- 	@ check for TX_EMT in UARTDM_SR
- 	ldr	\rd, [\rx, #0x08]
- 	tst	\rd, #0x08
---- a/arch/arm/mach-msm/Kconfig
-+++ b/arch/arm/mach-msm/Kconfig
-@@ -42,9 +42,6 @@ config ARCH_QSD8X50
- 
- endchoice
- 
--config MSM_HAS_DEBUG_UART_HS
--	bool
--
- config MSM_SOC_REV_A
- 	bool
- 
diff --git a/target/linux/ipq806x/patches/0098-ARM-debug-qcom-add-UART-addresses-to-Kconfig-help-fo.patch b/target/linux/ipq806x/patches/0098-ARM-debug-qcom-add-UART-addresses-to-Kconfig-help-fo.patch
deleted file mode 100644
index a94a7c9..0000000
--- a/target/linux/ipq806x/patches/0098-ARM-debug-qcom-add-UART-addresses-to-Kconfig-help-fo.patch
+++ /dev/null
@@ -1,25 +0,0 @@
-From 0a551e04e9a36ca1f8332071787b0e26bc5f8ecc Mon Sep 17 00:00:00 2001
-From: Georgi Djakov <gdjakov@mm-sol.com>
-Date: Fri, 23 May 2014 18:12:32 +0300
-Subject: [PATCH 098/182] ARM: debug: qcom: add UART addresses to Kconfig help
- for APQ8084
-
-Add information about the APQ8084 debug UART physical and virtual
-addresses in the DEBUG_QCOM_UARTDM Kconfig help section.
-
-Signed-off-by: Georgi Djakov <gdjakov@mm-sol.com>
-Signed-off-by: Kumar Gala <galak@codeaurora.org>
----
- arch/arm/Kconfig.debug |    1 +
- 1 file changed, 1 insertion(+)
-
---- a/arch/arm/Kconfig.debug
-+++ b/arch/arm/Kconfig.debug
-@@ -380,6 +380,7 @@ choice
- 		  their output to the serial port on Qualcomm devices.
- 
- 		  ARCH      DEBUG_UART_PHYS   DEBUG_UART_BASE
-+		  APQ8084   0xf995e000        0xfa75e000
- 		  MSM8X60   0x19c40000        0xf0040000
- 		  MSM8960   0x16440000        0xf0040000
- 		  MSM8974   0xf991e000        0xfa71e000
diff --git a/target/linux/ipq806x/patches/0099-ARM-qcom-Enable-ARM_AMBA-option-for-Qualcomm-SOCs.patch b/target/linux/ipq806x/patches/0099-ARM-qcom-Enable-ARM_AMBA-option-for-Qualcomm-SOCs.patch
deleted file mode 100644
index 1212da2..0000000
--- a/target/linux/ipq806x/patches/0099-ARM-qcom-Enable-ARM_AMBA-option-for-Qualcomm-SOCs.patch
+++ /dev/null
@@ -1,26 +0,0 @@
-From b6ee2071ec3af3ec90d93b8b70aa17d741590148 Mon Sep 17 00:00:00 2001
-From: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
-Date: Thu, 15 May 2014 11:08:55 +0100
-Subject: [PATCH 099/182] ARM: qcom: Enable ARM_AMBA option for Qualcomm SOCs.
-
-As some of the IPs on Qualcomm SOCs are based on ARM PrimeCell IPs.
-For example SDCC controller is PrimeCell MCI pl180. Adding this option will
-give flexibility to reuse the existing drivers as it is without major
-modifications.
-
-Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
-Signed-off-by: Kumar Gala <galak@codeaurora.org>
----
- arch/arm/mach-qcom/Kconfig |    1 +
- 1 file changed, 1 insertion(+)
-
---- a/arch/arm/mach-qcom/Kconfig
-+++ b/arch/arm/mach-qcom/Kconfig
-@@ -2,6 +2,7 @@ config ARCH_QCOM
- 	bool "Qualcomm Support" if ARCH_MULTI_V7
- 	select ARCH_REQUIRE_GPIOLIB
- 	select ARM_GIC
-+	select ARM_AMBA
- 	select CLKSRC_OF
- 	select GENERIC_CLOCKEVENTS
- 	select HAVE_SMP
diff --git a/target/linux/ipq806x/patches/0100-clk-qcom-Fix-msm8660-GCC-probe.patch b/target/linux/ipq806x/patches/0100-clk-qcom-Fix-msm8660-GCC-probe.patch
deleted file mode 100644
index f1f1445..0000000
--- a/target/linux/ipq806x/patches/0100-clk-qcom-Fix-msm8660-GCC-probe.patch
+++ /dev/null
@@ -1,37 +0,0 @@
-From d54996ddc69b69fe21f776e1de1eace04bca01c3 Mon Sep 17 00:00:00 2001
-From: Stephen Boyd <sboyd@codeaurora.org>
-Date: Fri, 16 May 2014 10:05:14 -0700
-Subject: [PATCH 100/182] clk: qcom: Fix msm8660 GCC probe
-
-When consolidating the msm8660 GCC probe code I forgot to keep
-around these temporary clock registrations. Put them back so the
-clock tree is not entirely orphaned.
-
-Fixes: 49fc825f0cc2 (clk: qcom: Consolidate common probe code)
-Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
-Signed-off-by: Mike Turquette <mturquette@linaro.org>
----
- drivers/clk/qcom/gcc-msm8660.c |   12 ++++++++++++
- 1 file changed, 12 insertions(+)
-
---- a/drivers/clk/qcom/gcc-msm8660.c
-+++ b/drivers/clk/qcom/gcc-msm8660.c
-@@ -2718,6 +2718,18 @@ MODULE_DEVICE_TABLE(of, gcc_msm8660_matc
- 
- static int gcc_msm8660_probe(struct platform_device *pdev)
- {
-+	struct clk *clk;
-+	struct device *dev = &pdev->dev;
-+
-+	/* Temporary until RPM clocks supported */
-+	clk = clk_register_fixed_rate(dev, "cxo", NULL, CLK_IS_ROOT, 19200000);
-+	if (IS_ERR(clk))
-+		return PTR_ERR(clk);
-+
-+	clk = clk_register_fixed_rate(dev, "pxo", NULL, CLK_IS_ROOT, 27000000);
-+	if (IS_ERR(clk))
-+		return PTR_ERR(clk);
-+
- 	return qcom_cc_probe(pdev, &gcc_msm8660_desc);
- }
- 
diff --git a/target/linux/ipq806x/patches/0101-clk-qcom-Fix-blsp2_ahb_clk-register-offset.patch b/target/linux/ipq806x/patches/0101-clk-qcom-Fix-blsp2_ahb_clk-register-offset.patch
deleted file mode 100644
index 705582f..0000000
--- a/target/linux/ipq806x/patches/0101-clk-qcom-Fix-blsp2_ahb_clk-register-offset.patch
+++ /dev/null
@@ -1,25 +0,0 @@
-From b11c02becb4dadf5c375fef4b98f92af67106f18 Mon Sep 17 00:00:00 2001
-From: Georgi Djakov <gdjakov@mm-sol.com>
-Date: Tue, 20 May 2014 19:50:54 +0300
-Subject: [PATCH 101/182] clk: qcom: Fix blsp2_ahb_clk register offset
-
-The address of the blsp2_ahb_clk register is incorrect. Fix it.
-
-Signed-off-by: Georgi Djakov <gdjakov@mm-sol.com>
-Reviewed-by: Stephen Boyd <sboyd@codeaurora.org>
-Signed-off-by: Mike Turquette <mturquette@linaro.org>
----
- drivers/clk/qcom/gcc-msm8974.c |    2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/drivers/clk/qcom/gcc-msm8974.c
-+++ b/drivers/clk/qcom/gcc-msm8974.c
-@@ -1341,7 +1341,7 @@ static struct clk_branch gcc_blsp1_uart6
- };
- 
- static struct clk_branch gcc_blsp2_ahb_clk = {
--	.halt_reg = 0x05c4,
-+	.halt_reg = 0x0944,
- 	.halt_check = BRANCH_HALT_VOTED,
- 	.clkr = {
- 		.enable_reg = 0x1484,
diff --git a/target/linux/ipq806x/patches/0104-clk-qcom-Return-highest-rate-when-round_rate-exceeds.patch b/target/linux/ipq806x/patches/0104-clk-qcom-Return-highest-rate-when-round_rate-exceeds.patch
deleted file mode 100644
index 3312f2f..0000000
--- a/target/linux/ipq806x/patches/0104-clk-qcom-Return-highest-rate-when-round_rate-exceeds.patch
+++ /dev/null
@@ -1,31 +0,0 @@
-From 6417bb8469eb495d7f4e4b6b0ac08cbc1b8606cb Mon Sep 17 00:00:00 2001
-From: Stephen Boyd <sboyd@codeaurora.org>
-Date: Fri, 16 May 2014 16:07:10 -0700
-Subject: [PATCH 104/182] clk: qcom: Return highest rate when round_rate()
- exceeds plan
-
-Some drivers may want to call clk_set_rate() with a very large
-number to force the clock to go as fast as it possibly can
-without having to know the range between the highest rate and
-second highest rate. Add support for this by defaulting to the
-highest rate in the frequency table if we can't find a frequency
-greater than what is requested.
-
-Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
-Signed-off-by: Mike Turquette <mturquette@linaro.org>
----
- drivers/clk/qcom/clk-rcg2.c |    3 ++-
- 1 file changed, 2 insertions(+), 1 deletion(-)
-
---- a/drivers/clk/qcom/clk-rcg2.c
-+++ b/drivers/clk/qcom/clk-rcg2.c
-@@ -181,7 +181,8 @@ struct freq_tbl *find_freq(const struct
- 		if (rate <= f->freq)
- 			return f;
- 
--	return NULL;
-+	/* Default to our fastest rate */
-+	return f - 1;
- }
- 
- static long _freq_tbl_determine_rate(struct clk_hw *hw,
diff --git a/target/linux/ipq806x/patches/0105-clk-qcom-Support-display-RCG-clocks.patch b/target/linux/ipq806x/patches/0105-clk-qcom-Support-display-RCG-clocks.patch
deleted file mode 100644
index befdfeb..0000000
--- a/target/linux/ipq806x/patches/0105-clk-qcom-Support-display-RCG-clocks.patch
+++ /dev/null
@@ -1,371 +0,0 @@
-From 3123079878e29eb8c541111e30de4d1bb42ac6f9 Mon Sep 17 00:00:00 2001
-From: Stephen Boyd <sboyd@codeaurora.org>
-Date: Fri, 16 May 2014 16:07:11 -0700
-Subject: [PATCH 105/182] clk: qcom: Support display RCG clocks
-
-Add support for the DSI/EDP/HDMI RCG clocks. With the proper
-display driver in place this should allow us to support display
-clocks on msm8974 based devices.
-
-Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
-Signed-off-by: Mike Turquette <mturquette@linaro.org>
----
- drivers/clk/qcom/clk-rcg.h  |    3 +
- drivers/clk/qcom/clk-rcg2.c |  299 ++++++++++++++++++++++++++++++++++++++++---
- 2 files changed, 287 insertions(+), 15 deletions(-)
-
---- a/drivers/clk/qcom/clk-rcg.h
-+++ b/drivers/clk/qcom/clk-rcg.h
-@@ -155,5 +155,8 @@ struct clk_rcg2 {
- #define to_clk_rcg2(_hw) container_of(to_clk_regmap(_hw), struct clk_rcg2, clkr)
- 
- extern const struct clk_ops clk_rcg2_ops;
-+extern const struct clk_ops clk_edp_pixel_ops;
-+extern const struct clk_ops clk_byte_ops;
-+extern const struct clk_ops clk_pixel_ops;
- 
- #endif
---- a/drivers/clk/qcom/clk-rcg2.c
-+++ b/drivers/clk/qcom/clk-rcg2.c
-@@ -19,6 +19,7 @@
- #include <linux/clk-provider.h>
- #include <linux/delay.h>
- #include <linux/regmap.h>
-+#include <linux/math64.h>
- 
- #include <asm/div64.h>
- 
-@@ -225,31 +226,25 @@ static long clk_rcg2_determine_rate(stru
- 	return _freq_tbl_determine_rate(hw, rcg->freq_tbl, rate, p_rate, p);
- }
- 
--static int __clk_rcg2_set_rate(struct clk_hw *hw, unsigned long rate)
-+static int clk_rcg2_configure(struct clk_rcg2 *rcg, const struct freq_tbl *f)
- {
--	struct clk_rcg2 *rcg = to_clk_rcg2(hw);
--	const struct freq_tbl *f;
- 	u32 cfg, mask;
- 	int ret;
- 
--	f = find_freq(rcg->freq_tbl, rate);
--	if (!f)
--		return -EINVAL;
--
- 	if (rcg->mnd_width && f->n) {
- 		mask = BIT(rcg->mnd_width) - 1;
--		ret = regmap_update_bits(rcg->clkr.regmap, rcg->cmd_rcgr + M_REG,
--					 mask, f->m);
-+		ret = regmap_update_bits(rcg->clkr.regmap,
-+				rcg->cmd_rcgr + M_REG, mask, f->m);
- 		if (ret)
- 			return ret;
- 
--		ret = regmap_update_bits(rcg->clkr.regmap, rcg->cmd_rcgr + N_REG,
--					 mask, ~(f->n - f->m));
-+		ret = regmap_update_bits(rcg->clkr.regmap,
-+				rcg->cmd_rcgr + N_REG, mask, ~(f->n - f->m));
- 		if (ret)
- 			return ret;
- 
--		ret = regmap_update_bits(rcg->clkr.regmap, rcg->cmd_rcgr + D_REG,
--					 mask, ~f->n);
-+		ret = regmap_update_bits(rcg->clkr.regmap,
-+				rcg->cmd_rcgr + D_REG, mask, ~f->n);
- 		if (ret)
- 			return ret;
- 	}
-@@ -260,14 +255,26 @@ static int __clk_rcg2_set_rate(struct cl
- 	cfg |= rcg->parent_map[f->src] << CFG_SRC_SEL_SHIFT;
- 	if (rcg->mnd_width && f->n)
- 		cfg |= CFG_MODE_DUAL_EDGE;
--	ret = regmap_update_bits(rcg->clkr.regmap, rcg->cmd_rcgr + CFG_REG, mask,
--			cfg);
-+	ret = regmap_update_bits(rcg->clkr.regmap,
-+			rcg->cmd_rcgr + CFG_REG, mask, cfg);
- 	if (ret)
- 		return ret;
- 
- 	return update_config(rcg);
- }
- 
-+static int __clk_rcg2_set_rate(struct clk_hw *hw, unsigned long rate)
-+{
-+	struct clk_rcg2 *rcg = to_clk_rcg2(hw);
-+	const struct freq_tbl *f;
-+
-+	f = find_freq(rcg->freq_tbl, rate);
-+	if (!f)
-+		return -EINVAL;
-+
-+	return clk_rcg2_configure(rcg, f);
-+}
-+
- static int clk_rcg2_set_rate(struct clk_hw *hw, unsigned long rate,
- 			    unsigned long parent_rate)
- {
-@@ -290,3 +297,265 @@ const struct clk_ops clk_rcg2_ops = {
- 	.set_rate_and_parent = clk_rcg2_set_rate_and_parent,
- };
- EXPORT_SYMBOL_GPL(clk_rcg2_ops);
-+
-+struct frac_entry {
-+	int num;
-+	int den;
-+};
-+
-+static const struct frac_entry frac_table_675m[] = {	/* link rate of 270M */
-+	{ 52, 295 },	/* 119 M */
-+	{ 11, 57 },	/* 130.25 M */
-+	{ 63, 307 },	/* 138.50 M */
-+	{ 11, 50 },	/* 148.50 M */
-+	{ 47, 206 },	/* 154 M */
-+	{ 31, 100 },	/* 205.25 M */
-+	{ 107, 269 },	/* 268.50 M */
-+	{ },
-+};
-+
-+static struct frac_entry frac_table_810m[] = { /* Link rate of 162M */
-+	{ 31, 211 },	/* 119 M */
-+	{ 32, 199 },	/* 130.25 M */
-+	{ 63, 307 },	/* 138.50 M */
-+	{ 11, 60 },	/* 148.50 M */
-+	{ 50, 263 },	/* 154 M */
-+	{ 31, 120 },	/* 205.25 M */
-+	{ 119, 359 },	/* 268.50 M */
-+	{ },
-+};
-+
-+static int clk_edp_pixel_set_rate(struct clk_hw *hw, unsigned long rate,
-+			      unsigned long parent_rate)
-+{
-+	struct clk_rcg2 *rcg = to_clk_rcg2(hw);
-+	struct freq_tbl f = *rcg->freq_tbl;
-+	const struct frac_entry *frac;
-+	int delta = 100000;
-+	s64 src_rate = parent_rate;
-+	s64 request;
-+	u32 mask = BIT(rcg->hid_width) - 1;
-+	u32 hid_div;
-+
-+	if (src_rate == 810000000)
-+		frac = frac_table_810m;
-+	else
-+		frac = frac_table_675m;
-+
-+	for (; frac->num; frac++) {
-+		request = rate;
-+		request *= frac->den;
-+		request = div_s64(request, frac->num);
-+		if ((src_rate < (request - delta)) ||
-+		    (src_rate > (request + delta)))
-+			continue;
-+
-+		regmap_read(rcg->clkr.regmap, rcg->cmd_rcgr + CFG_REG,
-+				&hid_div);
-+		f.pre_div = hid_div;
-+		f.pre_div >>= CFG_SRC_DIV_SHIFT;
-+		f.pre_div &= mask;
-+		f.m = frac->num;
-+		f.n = frac->den;
-+
-+		return clk_rcg2_configure(rcg, &f);
-+	}
-+
-+	return -EINVAL;
-+}
-+
-+static int clk_edp_pixel_set_rate_and_parent(struct clk_hw *hw,
-+		unsigned long rate, unsigned long parent_rate, u8 index)
-+{
-+	/* Parent index is set statically in frequency table */
-+	return clk_edp_pixel_set_rate(hw, rate, parent_rate);
-+}
-+
-+static long clk_edp_pixel_determine_rate(struct clk_hw *hw, unsigned long rate,
-+				 unsigned long *p_rate, struct clk **p)
-+{
-+	struct clk_rcg2 *rcg = to_clk_rcg2(hw);
-+	const struct freq_tbl *f = rcg->freq_tbl;
-+	const struct frac_entry *frac;
-+	int delta = 100000;
-+	s64 src_rate = *p_rate;
-+	s64 request;
-+	u32 mask = BIT(rcg->hid_width) - 1;
-+	u32 hid_div;
-+
-+	/* Force the correct parent */
-+	*p = clk_get_parent_by_index(hw->clk, f->src);
-+
-+	if (src_rate == 810000000)
-+		frac = frac_table_810m;
-+	else
-+		frac = frac_table_675m;
-+
-+	for (; frac->num; frac++) {
-+		request = rate;
-+		request *= frac->den;
-+		request = div_s64(request, frac->num);
-+		if ((src_rate < (request - delta)) ||
-+		    (src_rate > (request + delta)))
-+			continue;
-+
-+		regmap_read(rcg->clkr.regmap, rcg->cmd_rcgr + CFG_REG,
-+				&hid_div);
-+		hid_div >>= CFG_SRC_DIV_SHIFT;
-+		hid_div &= mask;
-+
-+		return calc_rate(src_rate, frac->num, frac->den, !!frac->den,
-+				 hid_div);
-+	}
-+
-+	return -EINVAL;
-+}
-+
-+const struct clk_ops clk_edp_pixel_ops = {
-+	.is_enabled = clk_rcg2_is_enabled,
-+	.get_parent = clk_rcg2_get_parent,
-+	.set_parent = clk_rcg2_set_parent,
-+	.recalc_rate = clk_rcg2_recalc_rate,
-+	.set_rate = clk_edp_pixel_set_rate,
-+	.set_rate_and_parent = clk_edp_pixel_set_rate_and_parent,
-+	.determine_rate = clk_edp_pixel_determine_rate,
-+};
-+EXPORT_SYMBOL_GPL(clk_edp_pixel_ops);
-+
-+static long clk_byte_determine_rate(struct clk_hw *hw, unsigned long rate,
-+			 unsigned long *p_rate, struct clk **p)
-+{
-+	struct clk_rcg2 *rcg = to_clk_rcg2(hw);
-+	const struct freq_tbl *f = rcg->freq_tbl;
-+	unsigned long parent_rate, div;
-+	u32 mask = BIT(rcg->hid_width) - 1;
-+
-+	if (rate == 0)
-+		return -EINVAL;
-+
-+	*p = clk_get_parent_by_index(hw->clk, f->src);
-+	*p_rate = parent_rate = __clk_round_rate(*p, rate);
-+
-+	div = DIV_ROUND_UP((2 * parent_rate), rate) - 1;
-+	div = min_t(u32, div, mask);
-+
-+	return calc_rate(parent_rate, 0, 0, 0, div);
-+}
-+
-+static int clk_byte_set_rate(struct clk_hw *hw, unsigned long rate,
-+			 unsigned long parent_rate)
-+{
-+	struct clk_rcg2 *rcg = to_clk_rcg2(hw);
-+	struct freq_tbl f = *rcg->freq_tbl;
-+	unsigned long div;
-+	u32 mask = BIT(rcg->hid_width) - 1;
-+
-+	div = DIV_ROUND_UP((2 * parent_rate), rate) - 1;
-+	div = min_t(u32, div, mask);
-+
-+	f.pre_div = div;
-+
-+	return clk_rcg2_configure(rcg, &f);
-+}
-+
-+static int clk_byte_set_rate_and_parent(struct clk_hw *hw,
-+		unsigned long rate, unsigned long parent_rate, u8 index)
-+{
-+	/* Parent index is set statically in frequency table */
-+	return clk_byte_set_rate(hw, rate, parent_rate);
-+}
-+
-+const struct clk_ops clk_byte_ops = {
-+	.is_enabled = clk_rcg2_is_enabled,
-+	.get_parent = clk_rcg2_get_parent,
-+	.set_parent = clk_rcg2_set_parent,
-+	.recalc_rate = clk_rcg2_recalc_rate,
-+	.set_rate = clk_byte_set_rate,
-+	.set_rate_and_parent = clk_byte_set_rate_and_parent,
-+	.determine_rate = clk_byte_determine_rate,
-+};
-+EXPORT_SYMBOL_GPL(clk_byte_ops);
-+
-+static const struct frac_entry frac_table_pixel[] = {
-+	{ 3, 8 },
-+	{ 2, 9 },
-+	{ 4, 9 },
-+	{ 1, 1 },
-+	{ }
-+};
-+
-+static long clk_pixel_determine_rate(struct clk_hw *hw, unsigned long rate,
-+				 unsigned long *p_rate, struct clk **p)
-+{
-+	struct clk_rcg2 *rcg = to_clk_rcg2(hw);
-+	unsigned long request, src_rate;
-+	int delta = 100000;
-+	const struct freq_tbl *f = rcg->freq_tbl;
-+	const struct frac_entry *frac = frac_table_pixel;
-+	struct clk *parent = *p = clk_get_parent_by_index(hw->clk, f->src);
-+
-+	for (; frac->num; frac++) {
-+		request = (rate * frac->den) / frac->num;
-+
-+		src_rate = __clk_round_rate(parent, request);
-+		if ((src_rate < (request - delta)) ||
-+			(src_rate > (request + delta)))
-+			continue;
-+
-+		*p_rate = src_rate;
-+		return (src_rate * frac->num) / frac->den;
-+	}
-+
-+	return -EINVAL;
-+}
-+
-+static int clk_pixel_set_rate(struct clk_hw *hw, unsigned long rate,
-+		unsigned long parent_rate)
-+{
-+	struct clk_rcg2 *rcg = to_clk_rcg2(hw);
-+	struct freq_tbl f = *rcg->freq_tbl;
-+	const struct frac_entry *frac = frac_table_pixel;
-+	unsigned long request, src_rate;
-+	int delta = 100000;
-+	u32 mask = BIT(rcg->hid_width) - 1;
-+	u32 hid_div;
-+	struct clk *parent = clk_get_parent_by_index(hw->clk, f.src);
-+
-+	for (; frac->num; frac++) {
-+		request = (rate * frac->den) / frac->num;
-+
-+		src_rate = __clk_round_rate(parent, request);
-+		if ((src_rate < (request - delta)) ||
-+			(src_rate > (request + delta)))
-+			continue;
-+
-+		regmap_read(rcg->clkr.regmap, rcg->cmd_rcgr + CFG_REG,
-+				&hid_div);
-+		f.pre_div = hid_div;
-+		f.pre_div >>= CFG_SRC_DIV_SHIFT;
-+		f.pre_div &= mask;
-+		f.m = frac->num;
-+		f.n = frac->den;
-+
-+		return clk_rcg2_configure(rcg, &f);
-+	}
-+	return -EINVAL;
-+}
-+
-+static int clk_pixel_set_rate_and_parent(struct clk_hw *hw, unsigned long rate,
-+		unsigned long parent_rate, u8 index)
-+{
-+	/* Parent index is set statically in frequency table */
-+	return clk_pixel_set_rate(hw, rate, parent_rate);
-+}
-+
-+const struct clk_ops clk_pixel_ops = {
-+	.is_enabled = clk_rcg2_is_enabled,
-+	.get_parent = clk_rcg2_get_parent,
-+	.set_parent = clk_rcg2_set_parent,
-+	.recalc_rate = clk_rcg2_recalc_rate,
-+	.set_rate = clk_pixel_set_rate,
-+	.set_rate_and_parent = clk_pixel_set_rate_and_parent,
-+	.determine_rate = clk_pixel_determine_rate,
-+};
-+EXPORT_SYMBOL_GPL(clk_pixel_ops);
diff --git a/target/linux/ipq806x/patches/0106-clk-qcom-Properly-support-display-clocks-on-msm8974.patch b/target/linux/ipq806x/patches/0106-clk-qcom-Properly-support-display-clocks-on-msm8974.patch
deleted file mode 100644
index c798917..0000000
--- a/target/linux/ipq806x/patches/0106-clk-qcom-Properly-support-display-clocks-on-msm8974.patch
+++ /dev/null
@@ -1,254 +0,0 @@
-From 4ccbe584ecb970f86bab58c0ca93998cccc9e810 Mon Sep 17 00:00:00 2001
-From: Stephen Boyd <sboyd@codeaurora.org>
-Date: Fri, 16 May 2014 16:07:12 -0700
-Subject: [PATCH 106/182] clk: qcom: Properly support display clocks on
- msm8974
-
-The display clocks all source from dedicated phy PLLs within their
-respective multimedia hardware block. Hook up these PLLs to the
-display clocks with the appropriate parent mappings, clock flags,
-and the appropriate clock ops. This should allow the display
-clocks to work once the appropriate phy PLL driver registers their
-PLL clocks.
-
-Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
-Signed-off-by: Mike Turquette <mturquette@linaro.org>
----
- drivers/clk/qcom/mmcc-msm8974.c |  105 ++++++++++++++++++++-------------------
- 1 file changed, 54 insertions(+), 51 deletions(-)
-
---- a/drivers/clk/qcom/mmcc-msm8974.c
-+++ b/drivers/clk/qcom/mmcc-msm8974.c
-@@ -41,9 +41,11 @@
- #define P_EDPVCO	3
- #define P_GPLL1		4
- #define P_DSI0PLL	4
-+#define P_DSI0PLL_BYTE	4
- #define P_MMPLL2	4
- #define P_MMPLL3	4
- #define P_DSI1PLL	5
-+#define P_DSI1PLL_BYTE	5
- 
- static const u8 mmcc_xo_mmpll0_mmpll1_gpll0_map[] = {
- 	[P_XO]		= 0,
-@@ -161,6 +163,24 @@ static const char *mmcc_xo_dsi_hdmi_edp_
- 	"dsi1pll",
- };
- 
-+static const u8 mmcc_xo_dsibyte_hdmi_edp_gpll0_map[] = {
-+	[P_XO]			= 0,
-+	[P_EDPLINK]		= 4,
-+	[P_HDMIPLL]		= 3,
-+	[P_GPLL0]		= 5,
-+	[P_DSI0PLL_BYTE]	= 1,
-+	[P_DSI1PLL_BYTE]	= 2,
-+};
-+
-+static const char *mmcc_xo_dsibyte_hdmi_edp_gpll0[] = {
-+	"xo",
-+	"edp_link_clk",
-+	"hdmipll",
-+	"gpll0_vote",
-+	"dsi0pllbyte",
-+	"dsi1pllbyte",
-+};
-+
- #define F(f, s, h, m, n) { (f), (s), (2 * (h) - 1), (m), (n) }
- 
- static struct clk_pll mmpll0 = {
-@@ -500,15 +520,8 @@ static struct clk_rcg2 jpeg2_clk_src = {
- 	},
- };
- 
--static struct freq_tbl ftbl_mdss_pclk0_clk[] = {
--	F(125000000, P_DSI0PLL, 2, 0, 0),
--	F(250000000, P_DSI0PLL, 1, 0, 0),
--	{ }
--};
--
--static struct freq_tbl ftbl_mdss_pclk1_clk[] = {
--	F(125000000, P_DSI1PLL, 2, 0, 0),
--	F(250000000, P_DSI1PLL, 1, 0, 0),
-+static struct freq_tbl pixel_freq_tbl[] = {
-+	{ .src = P_DSI0PLL },
- 	{ }
- };
- 
-@@ -517,12 +530,13 @@ static struct clk_rcg2 pclk0_clk_src = {
- 	.mnd_width = 8,
- 	.hid_width = 5,
- 	.parent_map = mmcc_xo_dsi_hdmi_edp_gpll0_map,
--	.freq_tbl = ftbl_mdss_pclk0_clk,
-+	.freq_tbl = pixel_freq_tbl,
- 	.clkr.hw.init = &(struct clk_init_data){
- 		.name = "pclk0_clk_src",
- 		.parent_names = mmcc_xo_dsi_hdmi_edp_gpll0,
- 		.num_parents = 6,
--		.ops = &clk_rcg2_ops,
-+		.ops = &clk_pixel_ops,
-+		.flags = CLK_SET_RATE_PARENT,
- 	},
- };
- 
-@@ -531,12 +545,13 @@ static struct clk_rcg2 pclk1_clk_src = {
- 	.mnd_width = 8,
- 	.hid_width = 5,
- 	.parent_map = mmcc_xo_dsi_hdmi_edp_gpll0_map,
--	.freq_tbl = ftbl_mdss_pclk1_clk,
-+	.freq_tbl = pixel_freq_tbl,
- 	.clkr.hw.init = &(struct clk_init_data){
- 		.name = "pclk1_clk_src",
- 		.parent_names = mmcc_xo_dsi_hdmi_edp_gpll0,
- 		.num_parents = 6,
--		.ops = &clk_rcg2_ops,
-+		.ops = &clk_pixel_ops,
-+		.flags = CLK_SET_RATE_PARENT,
- 	},
- };
- 
-@@ -754,41 +769,36 @@ static struct clk_rcg2 cpp_clk_src = {
- 	},
- };
- 
--static struct freq_tbl ftbl_mdss_byte0_clk[] = {
--	F(93750000, P_DSI0PLL, 8, 0, 0),
--	F(187500000, P_DSI0PLL, 4, 0, 0),
--	{ }
--};
--
--static struct freq_tbl ftbl_mdss_byte1_clk[] = {
--	F(93750000, P_DSI1PLL, 8, 0, 0),
--	F(187500000, P_DSI1PLL, 4, 0, 0),
-+static struct freq_tbl byte_freq_tbl[] = {
-+	{ .src = P_DSI0PLL_BYTE },
- 	{ }
- };
- 
- static struct clk_rcg2 byte0_clk_src = {
- 	.cmd_rcgr = 0x2120,
- 	.hid_width = 5,
--	.parent_map = mmcc_xo_dsi_hdmi_edp_gpll0_map,
--	.freq_tbl = ftbl_mdss_byte0_clk,
-+	.parent_map = mmcc_xo_dsibyte_hdmi_edp_gpll0_map,
-+	.freq_tbl = byte_freq_tbl,
- 	.clkr.hw.init = &(struct clk_init_data){
- 		.name = "byte0_clk_src",
--		.parent_names = mmcc_xo_dsi_hdmi_edp_gpll0,
-+		.parent_names = mmcc_xo_dsibyte_hdmi_edp_gpll0,
- 		.num_parents = 6,
--		.ops = &clk_rcg2_ops,
-+		.ops = &clk_byte_ops,
-+		.flags = CLK_SET_RATE_PARENT,
- 	},
- };
- 
- static struct clk_rcg2 byte1_clk_src = {
- 	.cmd_rcgr = 0x2140,
- 	.hid_width = 5,
--	.parent_map = mmcc_xo_dsi_hdmi_edp_gpll0_map,
--	.freq_tbl = ftbl_mdss_byte1_clk,
-+	.parent_map = mmcc_xo_dsibyte_hdmi_edp_gpll0_map,
-+	.freq_tbl = byte_freq_tbl,
- 	.clkr.hw.init = &(struct clk_init_data){
- 		.name = "byte1_clk_src",
--		.parent_names = mmcc_xo_dsi_hdmi_edp_gpll0,
-+		.parent_names = mmcc_xo_dsibyte_hdmi_edp_gpll0,
- 		.num_parents = 6,
--		.ops = &clk_rcg2_ops,
-+		.ops = &clk_byte_ops,
-+		.flags = CLK_SET_RATE_PARENT,
- 	},
- };
- 
-@@ -826,12 +836,12 @@ static struct clk_rcg2 edplink_clk_src =
- 		.parent_names = mmcc_xo_dsi_hdmi_edp_gpll0,
- 		.num_parents = 6,
- 		.ops = &clk_rcg2_ops,
-+		.flags = CLK_SET_RATE_PARENT,
- 	},
- };
- 
--static struct freq_tbl ftbl_mdss_edppixel_clk[] = {
--	F(175000000, P_EDPVCO, 2, 0, 0),
--	F(350000000, P_EDPVCO, 11, 0, 0),
-+static struct freq_tbl edp_pixel_freq_tbl[] = {
-+	{ .src = P_EDPVCO },
- 	{ }
- };
- 
-@@ -840,12 +850,12 @@ static struct clk_rcg2 edppixel_clk_src
- 	.mnd_width = 8,
- 	.hid_width = 5,
- 	.parent_map = mmcc_xo_dsi_hdmi_edp_map,
--	.freq_tbl = ftbl_mdss_edppixel_clk,
-+	.freq_tbl = edp_pixel_freq_tbl,
- 	.clkr.hw.init = &(struct clk_init_data){
- 		.name = "edppixel_clk_src",
- 		.parent_names = mmcc_xo_dsi_hdmi_edp,
- 		.num_parents = 6,
--		.ops = &clk_rcg2_ops,
-+		.ops = &clk_edp_pixel_ops,
- 	},
- };
- 
-@@ -857,11 +867,11 @@ static struct freq_tbl ftbl_mdss_esc0_1_
- static struct clk_rcg2 esc0_clk_src = {
- 	.cmd_rcgr = 0x2160,
- 	.hid_width = 5,
--	.parent_map = mmcc_xo_dsi_hdmi_edp_gpll0_map,
-+	.parent_map = mmcc_xo_dsibyte_hdmi_edp_gpll0_map,
- 	.freq_tbl = ftbl_mdss_esc0_1_clk,
- 	.clkr.hw.init = &(struct clk_init_data){
- 		.name = "esc0_clk_src",
--		.parent_names = mmcc_xo_dsi_hdmi_edp_gpll0,
-+		.parent_names = mmcc_xo_dsibyte_hdmi_edp_gpll0,
- 		.num_parents = 6,
- 		.ops = &clk_rcg2_ops,
- 	},
-@@ -870,26 +880,18 @@ static struct clk_rcg2 esc0_clk_src = {
- static struct clk_rcg2 esc1_clk_src = {
- 	.cmd_rcgr = 0x2180,
- 	.hid_width = 5,
--	.parent_map = mmcc_xo_dsi_hdmi_edp_gpll0_map,
-+	.parent_map = mmcc_xo_dsibyte_hdmi_edp_gpll0_map,
- 	.freq_tbl = ftbl_mdss_esc0_1_clk,
- 	.clkr.hw.init = &(struct clk_init_data){
- 		.name = "esc1_clk_src",
--		.parent_names = mmcc_xo_dsi_hdmi_edp_gpll0,
-+		.parent_names = mmcc_xo_dsibyte_hdmi_edp_gpll0,
- 		.num_parents = 6,
- 		.ops = &clk_rcg2_ops,
- 	},
- };
- 
--static struct freq_tbl ftbl_mdss_extpclk_clk[] = {
--	F(25200000, P_HDMIPLL, 1, 0, 0),
--	F(27000000, P_HDMIPLL, 1, 0, 0),
--	F(27030000, P_HDMIPLL, 1, 0, 0),
--	F(65000000, P_HDMIPLL, 1, 0, 0),
--	F(74250000, P_HDMIPLL, 1, 0, 0),
--	F(108000000, P_HDMIPLL, 1, 0, 0),
--	F(148500000, P_HDMIPLL, 1, 0, 0),
--	F(268500000, P_HDMIPLL, 1, 0, 0),
--	F(297000000, P_HDMIPLL, 1, 0, 0),
-+static struct freq_tbl extpclk_freq_tbl[] = {
-+	{ .src = P_HDMIPLL },
- 	{ }
- };
- 
-@@ -897,12 +899,13 @@ static struct clk_rcg2 extpclk_clk_src =
- 	.cmd_rcgr = 0x2060,
- 	.hid_width = 5,
- 	.parent_map = mmcc_xo_dsi_hdmi_edp_gpll0_map,
--	.freq_tbl = ftbl_mdss_extpclk_clk,
-+	.freq_tbl = extpclk_freq_tbl,
- 	.clkr.hw.init = &(struct clk_init_data){
- 		.name = "extpclk_clk_src",
- 		.parent_names = mmcc_xo_dsi_hdmi_edp_gpll0,
- 		.num_parents = 6,
--		.ops = &clk_rcg2_ops,
-+		.ops = &clk_byte_ops,
-+		.flags = CLK_SET_RATE_PARENT,
- 	},
- };
- 
diff --git a/target/linux/ipq806x/patches/0107-clk-qcom-Support-msm8974pro-global-clock-control-har.patch b/target/linux/ipq806x/patches/0107-clk-qcom-Support-msm8974pro-global-clock-control-har.patch
deleted file mode 100644
index 670acad..0000000
--- a/target/linux/ipq806x/patches/0107-clk-qcom-Support-msm8974pro-global-clock-control-har.patch
+++ /dev/null
@@ -1,236 +0,0 @@
-From a740d2b024c5b71c6f9989976049f03b634bb13d Mon Sep 17 00:00:00 2001
-From: Stephen Boyd <sboyd@codeaurora.org>
-Date: Fri, 16 May 2014 16:07:13 -0700
-Subject: [PATCH 107/182] clk: qcom: Support msm8974pro global clock control
- hardware
-
-A new PLL (gpll4) is added on msm8974 PRO devices to support a
-faster sdc1 clock rate. Add support for this and the two new sdcc
-cal clocks.
-
-Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
-Signed-off-by: Mike Turquette <mturquette@linaro.org>
----
- .../devicetree/bindings/clock/qcom,gcc.txt         |    2 +
- drivers/clk/qcom/gcc-msm8974.c                     |  130 +++++++++++++++++++-
- include/dt-bindings/clock/qcom,gcc-msm8974.h       |    4 +
- 3 files changed, 130 insertions(+), 6 deletions(-)
-
---- a/Documentation/devicetree/bindings/clock/qcom,gcc.txt
-+++ b/Documentation/devicetree/bindings/clock/qcom,gcc.txt
-@@ -8,6 +8,8 @@ Required properties :
- 			"qcom,gcc-msm8660"
- 			"qcom,gcc-msm8960"
- 			"qcom,gcc-msm8974"
-+			"qcom,gcc-msm8974pro"
-+			"qcom,gcc-msm8974pro-ac"
- 
- - reg : shall contain base register location and length
- - #clock-cells : shall contain 1
---- a/drivers/clk/qcom/gcc-msm8974.c
-+++ b/drivers/clk/qcom/gcc-msm8974.c
-@@ -35,6 +35,7 @@
- #define P_XO	0
- #define P_GPLL0	1
- #define P_GPLL1	1
-+#define P_GPLL4	2
- 
- static const u8 gcc_xo_gpll0_map[] = {
- 	[P_XO]		= 0,
-@@ -46,6 +47,18 @@ static const char *gcc_xo_gpll0[] = {
- 	"gpll0_vote",
- };
- 
-+static const u8 gcc_xo_gpll0_gpll4_map[] = {
-+	[P_XO]		= 0,
-+	[P_GPLL0]	= 1,
-+	[P_GPLL4]	= 5,
-+};
-+
-+static const char *gcc_xo_gpll0_gpll4[] = {
-+	"xo",
-+	"gpll0_vote",
-+	"gpll4_vote",
-+};
-+
- #define F(f, s, h, m, n) { (f), (s), (2 * (h) - 1), (m), (n) }
- 
- static struct clk_pll gpll0 = {
-@@ -138,6 +151,33 @@ static struct clk_regmap gpll1_vote = {
- 	},
- };
- 
-+static struct clk_pll gpll4 = {
-+	.l_reg = 0x1dc4,
-+	.m_reg = 0x1dc8,
-+	.n_reg = 0x1dcc,
-+	.config_reg = 0x1dd4,
-+	.mode_reg = 0x1dc0,
-+	.status_reg = 0x1ddc,
-+	.status_bit = 17,
-+	.clkr.hw.init = &(struct clk_init_data){
-+		.name = "gpll4",
-+		.parent_names = (const char *[]){ "xo" },
-+		.num_parents = 1,
-+		.ops = &clk_pll_ops,
-+	},
-+};
-+
-+static struct clk_regmap gpll4_vote = {
-+	.enable_reg = 0x1480,
-+	.enable_mask = BIT(4),
-+	.hw.init = &(struct clk_init_data){
-+		.name = "gpll4_vote",
-+		.parent_names = (const char *[]){ "gpll4" },
-+		.num_parents = 1,
-+		.ops = &clk_pll_vote_ops,
-+	},
-+};
-+
- static const struct freq_tbl ftbl_gcc_usb30_master_clk[] = {
- 	F(125000000, P_GPLL0, 1, 5, 24),
- 	{ }
-@@ -812,18 +852,33 @@ static const struct freq_tbl ftbl_gcc_sd
- 	{ }
- };
- 
-+static const struct freq_tbl ftbl_gcc_sdcc1_apps_clk_pro[] = {
-+	F(144000, P_XO, 16, 3, 25),
-+	F(400000, P_XO, 12, 1, 4),
-+	F(20000000, P_GPLL0, 15, 1, 2),
-+	F(25000000, P_GPLL0, 12, 1, 2),
-+	F(50000000, P_GPLL0, 12, 0, 0),
-+	F(100000000, P_GPLL0, 6, 0, 0),
-+	F(192000000, P_GPLL4, 4, 0, 0),
-+	F(200000000, P_GPLL0, 3, 0, 0),
-+	F(384000000, P_GPLL4, 2, 0, 0),
-+	{ }
-+};
-+
-+static struct clk_init_data sdcc1_apps_clk_src_init = {
-+	.name = "sdcc1_apps_clk_src",
-+	.parent_names = gcc_xo_gpll0,
-+	.num_parents = 2,
-+	.ops = &clk_rcg2_ops,
-+};
-+
- static struct clk_rcg2 sdcc1_apps_clk_src = {
- 	.cmd_rcgr = 0x04d0,
- 	.mnd_width = 8,
- 	.hid_width = 5,
- 	.parent_map = gcc_xo_gpll0_map,
- 	.freq_tbl = ftbl_gcc_sdcc1_4_apps_clk,
--	.clkr.hw.init = &(struct clk_init_data){
--		.name = "sdcc1_apps_clk_src",
--		.parent_names = gcc_xo_gpll0,
--		.num_parents = 2,
--		.ops = &clk_rcg2_ops,
--	},
-+	.clkr.hw.init = &sdcc1_apps_clk_src_init,
- };
- 
- static struct clk_rcg2 sdcc2_apps_clk_src = {
-@@ -1995,6 +2050,38 @@ static struct clk_branch gcc_sdcc1_apps_
- 	},
- };
- 
-+static struct clk_branch gcc_sdcc1_cdccal_ff_clk = {
-+	.halt_reg = 0x04e8,
-+	.clkr = {
-+		.enable_reg = 0x04e8,
-+		.enable_mask = BIT(0),
-+		.hw.init = &(struct clk_init_data){
-+			.name = "gcc_sdcc1_cdccal_ff_clk",
-+			.parent_names = (const char *[]){
-+				"xo"
-+			},
-+			.num_parents = 1,
-+			.ops = &clk_branch2_ops,
-+		},
-+	},
-+};
-+
-+static struct clk_branch gcc_sdcc1_cdccal_sleep_clk = {
-+	.halt_reg = 0x04e4,
-+	.clkr = {
-+		.enable_reg = 0x04e4,
-+		.enable_mask = BIT(0),
-+		.hw.init = &(struct clk_init_data){
-+			.name = "gcc_sdcc1_cdccal_sleep_clk",
-+			.parent_names = (const char *[]){
-+				"sleep_clk_src"
-+			},
-+			.num_parents = 1,
-+			.ops = &clk_branch2_ops,
-+		},
-+	},
-+};
-+
- static struct clk_branch gcc_sdcc2_ahb_clk = {
- 	.halt_reg = 0x0508,
- 	.clkr = {
-@@ -2484,6 +2571,10 @@ static struct clk_regmap *gcc_msm8974_cl
- 	[GCC_USB_HSIC_IO_CAL_SLEEP_CLK] = &gcc_usb_hsic_io_cal_sleep_clk.clkr,
- 	[GCC_USB_HSIC_SYSTEM_CLK] = &gcc_usb_hsic_system_clk.clkr,
- 	[GCC_MMSS_GPLL0_CLK_SRC] = &gcc_mmss_gpll0_clk_src,
-+	[GPLL4] = NULL,
-+	[GPLL4_VOTE] = NULL,
-+	[GCC_SDCC1_CDCCAL_SLEEP_CLK] = NULL,
-+	[GCC_SDCC1_CDCCAL_FF_CLK] = NULL,
- };
- 
- static const struct qcom_reset_map gcc_msm8974_resets[] = {
-@@ -2585,14 +2676,41 @@ static const struct qcom_cc_desc gcc_msm
- 
- static const struct of_device_id gcc_msm8974_match_table[] = {
- 	{ .compatible = "qcom,gcc-msm8974" },
-+	{ .compatible = "qcom,gcc-msm8974pro" , .data = (void *)1UL },
-+	{ .compatible = "qcom,gcc-msm8974pro-ac", .data = (void *)1UL },
- 	{ }
- };
- MODULE_DEVICE_TABLE(of, gcc_msm8974_match_table);
- 
-+static void msm8974_pro_clock_override(void)
-+{
-+	sdcc1_apps_clk_src_init.parent_names = gcc_xo_gpll0_gpll4;
-+	sdcc1_apps_clk_src_init.num_parents = 3;
-+	sdcc1_apps_clk_src.freq_tbl = ftbl_gcc_sdcc1_apps_clk_pro;
-+	sdcc1_apps_clk_src.parent_map = gcc_xo_gpll0_gpll4_map;
-+
-+	gcc_msm8974_clocks[GPLL4] = &gpll4.clkr;
-+	gcc_msm8974_clocks[GPLL4_VOTE] = &gpll4_vote;
-+	gcc_msm8974_clocks[GCC_SDCC1_CDCCAL_SLEEP_CLK] =
-+		&gcc_sdcc1_cdccal_sleep_clk.clkr;
-+	gcc_msm8974_clocks[GCC_SDCC1_CDCCAL_FF_CLK] =
-+		&gcc_sdcc1_cdccal_ff_clk.clkr;
-+}
-+
- static int gcc_msm8974_probe(struct platform_device *pdev)
- {
- 	struct clk *clk;
- 	struct device *dev = &pdev->dev;
-+	bool pro;
-+	const struct of_device_id *id;
-+
-+	id = of_match_device(gcc_msm8974_match_table, dev);
-+	if (!id)
-+		return -ENODEV;
-+	pro = !!(id->data);
-+
-+	if (pro)
-+		msm8974_pro_clock_override();
- 
- 	/* Temporary until RPM clocks supported */
- 	clk = clk_register_fixed_rate(dev, "xo", NULL, CLK_IS_ROOT, 19200000);
---- a/include/dt-bindings/clock/qcom,gcc-msm8974.h
-+++ b/include/dt-bindings/clock/qcom,gcc-msm8974.h
-@@ -316,5 +316,9 @@
- #define GCC_CE2_CLK_SLEEP_ENA					299
- #define GCC_CE2_AXI_CLK_SLEEP_ENA				300
- #define GCC_CE2_AHB_CLK_SLEEP_ENA				301
-+#define GPLL4							302
-+#define GPLL4_VOTE						303
-+#define GCC_SDCC1_CDCCAL_SLEEP_CLK				304
-+#define GCC_SDCC1_CDCCAL_FF_CLK					305
- 
- #endif
diff --git a/target/linux/ipq806x/patches/0108-clk-qcom-Return-error-pointers-for-unimplemented-clo.patch b/target/linux/ipq806x/patches/0108-clk-qcom-Return-error-pointers-for-unimplemented-clo.patch
deleted file mode 100644
index 52d497f..0000000
--- a/target/linux/ipq806x/patches/0108-clk-qcom-Return-error-pointers-for-unimplemented-clo.patch
+++ /dev/null
@@ -1,32 +0,0 @@
-From 77b7f864b03d6b49c143a9c8c19432feef3032b5 Mon Sep 17 00:00:00 2001
-From: Stephen Boyd <sboyd@codeaurora.org>
-Date: Fri, 16 May 2014 16:07:14 -0700
-Subject: [PATCH 108/182] clk: qcom: Return error pointers for unimplemented
- clocks
-
-Not all clocks are implemented but client drivers can still
-request them. Currently we will return a NULL pointer to them if
-the clock isn't implemented in software but NULL pointers are
-valid clock pointers. Return an error pointer so that driver's
-don't proceed without a clock they may actually need.
-
-Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
-Signed-off-by: Mike Turquette <mturquette@linaro.org>
----
- drivers/clk/qcom/common.c |    4 +++-
- 1 file changed, 3 insertions(+), 1 deletion(-)
-
---- a/drivers/clk/qcom/common.c
-+++ b/drivers/clk/qcom/common.c
-@@ -62,8 +62,10 @@ int qcom_cc_probe(struct platform_device
- 	data->clk_num = num_clks;
- 
- 	for (i = 0; i < num_clks; i++) {
--		if (!rclks[i])
-+		if (!rclks[i]) {
-+			clks[i] = ERR_PTR(-ENOENT);
- 			continue;
-+		}
- 		clk = devm_clk_register_regmap(dev, rclks[i]);
- 		if (IS_ERR(clk))
- 			return PTR_ERR(clk);
diff --git a/target/linux/ipq806x/patches/0109-libahci-Allow-drivers-to-override-start_engine.patch b/target/linux/ipq806x/patches/0109-libahci-Allow-drivers-to-override-start_engine.patch
deleted file mode 100644
index aa2fee6..0000000
--- a/target/linux/ipq806x/patches/0109-libahci-Allow-drivers-to-override-start_engine.patch
+++ /dev/null
@@ -1,212 +0,0 @@
-From 10f3c772363e549c3dbd3cc3755d270c5656d5b8 Mon Sep 17 00:00:00 2001
-From: Hans de Goede <hdegoede@redhat.com>
-Date: Sat, 22 Feb 2014 16:53:30 +0100
-Subject: [PATCH 109/182] 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>
-Signed-off-by: Tejun Heo <tj@kernel.org>
----
- 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
-@@ -324,6 +324,12 @@ struct ahci_host_priv {
- 	u32			em_msg_type;	/* EM message type */
- 	struct clk		*clk;		/* Only for platforms supporting clk */
- 	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);
diff --git a/target/linux/ipq806x/patches/0110-ahci-platform-Add-support-for-devices-with-more-then.patch b/target/linux/ipq806x/patches/0110-ahci-platform-Add-support-for-devices-with-more-then.patch
deleted file mode 100644
index 54f84ee..0000000
--- a/target/linux/ipq806x/patches/0110-ahci-platform-Add-support-for-devices-with-more-then.patch
+++ /dev/null
@@ -1,242 +0,0 @@
-From b7ad421c184b827806c7f65be3a980cfc855b589 Mon Sep 17 00:00:00 2001
-From: Hans de Goede <hdegoede@redhat.com>
-Date: Sat, 22 Feb 2014 16:53:31 +0100
-Subject: [PATCH 110/182] ahci-platform: Add support for devices with more
- then 1 clock
-
-The allwinner-sun4i AHCI controller needs 2 clocks to be enabled and the
-imx AHCI controller needs 3 clocks to be enabled.
-
-tj: Minor comment formatting updates.
-
-Signed-off-by: Hans de Goede <hdegoede@redhat.com>
-Signed-off-by: Tejun Heo <tj@kernel.org>
----
- .../devicetree/bindings/ata/ahci-platform.txt      |    1 +
- drivers/ata/ahci.h                                 |    3 +-
- drivers/ata/ahci_platform.c                        |  113 +++++++++++++++-----
- include/linux/ahci_platform.h                      |    4 +
- 4 files changed, 93 insertions(+), 28 deletions(-)
-
---- a/Documentation/devicetree/bindings/ata/ahci-platform.txt
-+++ b/Documentation/devicetree/bindings/ata/ahci-platform.txt
-@@ -10,6 +10,7 @@ Required properties:
- 
- Optional properties:
- - dma-coherent      : Present if dma operations are coherent
-+- clocks            : a list of phandle + clock specifier pairs
- 
- Example:
-         sata@ffe08000 {
---- a/drivers/ata/ahci.h
-+++ b/drivers/ata/ahci.h
-@@ -51,6 +51,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,7 +323,7 @@ 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 */
- 	void			*plat_data;	/* Other platform data */
- 	/*
- 	 * Optional ahci_start_engine override, if not set this gets set to the
---- a/drivers/ata/ahci_platform.c
-+++ b/drivers/ata/ahci_platform.c
-@@ -87,6 +87,60 @@ static struct scsi_host_template ahci_pl
- 	AHCI_SHT("ahci_platform"),
- };
- 
-+/**
-+ * 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.
-+ *
-+ * RETURNS:
-+ * 0 on success otherwise a negative error code
-+ */
-+int ahci_platform_enable_clks(struct ahci_host_priv *hpriv)
-+{
-+	int c, rc;
-+
-+	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;
-+
-+disable_unprepare_clk:
-+	while (--c >= 0)
-+		clk_disable_unprepare(hpriv->clks[c]);
-+	return rc;
-+}
-+EXPORT_SYMBOL_GPL(ahci_platform_enable_clks);
-+
-+/**
-+ * 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).
-+ */
-+void ahci_platform_disable_clks(struct ahci_host_priv *hpriv)
-+{
-+	int c;
-+
-+	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);
-+
-+static void ahci_put_clks(struct ahci_host_priv *hpriv)
-+{
-+	int c;
-+
-+	for (c = 0; c < AHCI_MAX_CLKS && hpriv->clks[c]; c++)
-+		clk_put(hpriv->clks[c]);
-+}
-+
- static int ahci_probe(struct platform_device *pdev)
- {
- 	struct device *dev = &pdev->dev;
-@@ -97,6 +151,7 @@ static int ahci_probe(struct platform_de
- 	struct ahci_host_priv *hpriv;
- 	struct ata_host *host;
- 	struct resource *mem;
-+	struct clk *clk;
- 	int irq;
- 	int n_ports;
- 	int i;
-@@ -131,17 +186,31 @@ static int ahci_probe(struct platform_de
- 		return -ENOMEM;
- 	}
- 
--	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;
-+	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 free_clk;
-+			break;
- 		}
-+		hpriv->clks[i] = clk;
- 	}
- 
-+	rc = ahci_enable_clks(dev, hpriv);
-+	if (rc)
-+		goto free_clk;
-+
- 	/*
- 	 * Some platforms might need to prepare for mmio region access,
- 	 * which could be done in the following init call. So, the mmio
-@@ -222,11 +291,9 @@ pdata_exit:
- 	if (pdata && pdata->exit)
- 		pdata->exit(dev);
- disable_unprepare_clk:
--	if (!IS_ERR(hpriv->clk))
--		clk_disable_unprepare(hpriv->clk);
-+	ahci_disable_clks(hpriv);
- free_clk:
--	if (!IS_ERR(hpriv->clk))
--		clk_put(hpriv->clk);
-+	ahci_put_clks(hpriv);
- 	return rc;
- }
- 
-@@ -239,10 +306,8 @@ 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_disable_clks(hpriv);
-+	ahci_put_clks(hpriv);
- }
- 
- #ifdef CONFIG_PM_SLEEP
-@@ -277,8 +342,7 @@ static int ahci_suspend(struct device *d
- 	if (pdata && pdata->suspend)
- 		return pdata->suspend(dev);
- 
--	if (!IS_ERR(hpriv->clk))
--		clk_disable_unprepare(hpriv->clk);
-+	ahci_disable_clks(hpriv);
- 
- 	return 0;
- }
-@@ -290,13 +354,9 @@ static int ahci_resume(struct device *de
- 	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_enable_clks(dev, hpriv);
-+	if (rc)
-+		return rc;
- 
- 	if (pdata && pdata->resume) {
- 		rc = pdata->resume(dev);
-@@ -317,8 +377,7 @@ static int ahci_resume(struct device *de
- 	return 0;
- 
- disable_unprepare_clk:
--	if (!IS_ERR(hpriv->clk))
--		clk_disable_unprepare(hpriv->clk);
-+	ahci_disable_clks(hpriv);
- 
- 	return rc;
- }
---- a/include/linux/ahci_platform.h
-+++ b/include/linux/ahci_platform.h
-@@ -19,6 +19,7 @@
- 
- struct device;
- struct ata_port_info;
-+struct ahci_host_priv;
- 
- struct ahci_platform_data {
- 	int (*init)(struct device *dev, void __iomem *addr);
-@@ -30,4 +31,7 @@ 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);
-+
- #endif /* _AHCI_PLATFORM_H */
diff --git a/target/linux/ipq806x/patches/0111-ahci-platform-Add-support-for-an-optional-regulator-.patch b/target/linux/ipq806x/patches/0111-ahci-platform-Add-support-for-an-optional-regulator-.patch
deleted file mode 100644
index a8b1c6f..0000000
--- a/target/linux/ipq806x/patches/0111-ahci-platform-Add-support-for-an-optional-regulator-.patch
+++ /dev/null
@@ -1,133 +0,0 @@
-From 967f4a7821a3356d9d3c8b641537cd6d5eb15439 Mon Sep 17 00:00:00 2001
-From: Hans de Goede <hdegoede@redhat.com>
-Date: Sat, 22 Feb 2014 16:53:32 +0100
-Subject: [PATCH 111/182] ahci-platform: Add support for an optional regulator
- for sata-target power
-
-Signed-off-by: Hans de Goede <hdegoede@redhat.com>
-Signed-off-by: Tejun Heo <tj@kernel.org>
----
- .../devicetree/bindings/ata/ahci-platform.txt      |    1 +
- drivers/ata/ahci.h                                 |    2 ++
- drivers/ata/ahci_platform.c                        |   36 ++++++++++++++++++--
- 3 files changed, 37 insertions(+), 2 deletions(-)
-
---- a/Documentation/devicetree/bindings/ata/ahci-platform.txt
-+++ b/Documentation/devicetree/bindings/ata/ahci-platform.txt
-@@ -11,6 +11,7 @@ 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.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
-@@ -324,6 +325,7 @@ struct ahci_host_priv {
- 	u32			em_buf_sz;	/* EM buffer size in byte */
- 	u32			em_msg_type;	/* EM message type */
- 	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
---- a/drivers/ata/ahci_platform.c
-+++ b/drivers/ata/ahci_platform.c
-@@ -186,6 +186,14 @@ static int ahci_probe(struct platform_de
- 		return -ENOMEM;
- 	}
- 
-+	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)
-+			return -EPROBE_DEFER;
-+		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,
-@@ -207,9 +215,15 @@ static int ahci_probe(struct platform_de
- 		hpriv->clks[i] = clk;
- 	}
- 
-+	if (hpriv->target_pwr) {
-+		rc = regulator_enable(hpriv->target_pwr);
-+		if (rc)
-+			goto free_clk;
-+	}
-+
- 	rc = ahci_enable_clks(dev, hpriv);
- 	if (rc)
--		goto free_clk;
-+		goto disable_regulator;
- 
- 	/*
- 	 * Some platforms might need to prepare for mmio region access,
-@@ -292,6 +306,9 @@ pdata_exit:
- 		pdata->exit(dev);
- disable_unprepare_clk:
- 	ahci_disable_clks(hpriv);
-+disable_regulator:
-+	if (hpriv->target_pwr)
-+		regulator_disable(hpriv->target_pwr);
- free_clk:
- 	ahci_put_clks(hpriv);
- 	return rc;
-@@ -308,6 +325,9 @@ static void ahci_host_stop(struct ata_ho
- 
- 	ahci_disable_clks(hpriv);
- 	ahci_put_clks(hpriv);
-+
-+	if (hpriv->target_pwr)
-+		regulator_disable(hpriv->target_pwr);
- }
- 
- #ifdef CONFIG_PM_SLEEP
-@@ -344,6 +364,9 @@ static int ahci_suspend(struct device *d
- 
- 	ahci_disable_clks(hpriv);
- 
-+	if (hpriv->target_pwr)
-+		regulator_disable(hpriv->target_pwr);
-+
- 	return 0;
- }
- 
-@@ -354,9 +377,15 @@ static int ahci_resume(struct device *de
- 	struct ahci_host_priv *hpriv = host->private_data;
- 	int rc;
- 
-+	if (hpriv->target_pwr) {
-+		rc = regulator_enable(hpriv->target_pwr);
-+		if (rc)
-+			return rc;
-+	}
-+
- 	rc = ahci_enable_clks(dev, hpriv);
- 	if (rc)
--		return rc;
-+		goto disable_regulator;
- 
- 	if (pdata && pdata->resume) {
- 		rc = pdata->resume(dev);
-@@ -378,6 +407,9 @@ static int ahci_resume(struct device *de
- 
- disable_unprepare_clk:
- 	ahci_disable_clks(hpriv);
-+disable_regulator:
-+	if (hpriv->target_pwr)
-+		regulator_disable(hpriv->target_pwr);
- 
- 	return rc;
- }
diff --git a/target/linux/ipq806x/patches/0112-ahci-platform-Add-enable_-disable_resources-helper-f.patch b/target/linux/ipq806x/patches/0112-ahci-platform-Add-enable_-disable_resources-helper-f.patch
deleted file mode 100644
index 888ee32..0000000
--- a/target/linux/ipq806x/patches/0112-ahci-platform-Add-enable_-disable_resources-helper-f.patch
+++ /dev/null
@@ -1,201 +0,0 @@
-From 3b2df84624b38362cb84c2d4c6d1d3540c5069d3 Mon Sep 17 00:00:00 2001
-From: Hans de Goede <hdegoede@redhat.com>
-Date: Sat, 22 Feb 2014 16:53:33 +0100
-Subject: [PATCH 112/182] ahci-platform: Add enable_ / disable_resources
- helper functions
-
-tj: Minor comment formatting updates.
-
-Signed-off-by: Hans de Goede <hdegoede@redhat.com>
-Signed-off-by: Tejun Heo <tj@kernel.org>
----
- drivers/ata/ahci_platform.c   |  106 +++++++++++++++++++++++++++--------------
- include/linux/ahci_platform.h |    2 +
- 2 files changed, 71 insertions(+), 37 deletions(-)
-
---- a/drivers/ata/ahci_platform.c
-+++ b/drivers/ata/ahci_platform.c
-@@ -133,6 +133,62 @@ void ahci_platform_disable_clks(struct a
- }
- 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.
-+ *
-+ * 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;
-+	}
-+
-+	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
-+ */
-+void ahci_platform_disable_resources(struct ahci_host_priv *hpriv)
-+{
-+	ahci_platform_disable_clks(hpriv);
-+
-+	if (hpriv->target_pwr)
-+		regulator_disable(hpriv->target_pwr);
-+}
-+EXPORT_SYMBOL_GPL(ahci_platform_disable_resources);
-+
- static void ahci_put_clks(struct ahci_host_priv *hpriv)
- {
- 	int c;
-@@ -215,15 +271,9 @@ static int ahci_probe(struct platform_de
- 		hpriv->clks[i] = clk;
- 	}
- 
--	if (hpriv->target_pwr) {
--		rc = regulator_enable(hpriv->target_pwr);
--		if (rc)
--			goto free_clk;
--	}
--
--	rc = ahci_enable_clks(dev, hpriv);
-+	rc = ahci_platform_enable_resources(hpriv);
- 	if (rc)
--		goto disable_regulator;
-+		goto free_clk;
- 
- 	/*
- 	 * Some platforms might need to prepare for mmio region access,
-@@ -234,7 +284,7 @@ static int ahci_probe(struct platform_de
- 	if (pdata && pdata->init) {
- 		rc = pdata->init(dev, hpriv->mmio);
- 		if (rc)
--			goto disable_unprepare_clk;
-+			goto disable_resources;
- 	}
- 
- 	ahci_save_initial_config(dev, hpriv,
-@@ -304,11 +354,8 @@ static int ahci_probe(struct platform_de
- pdata_exit:
- 	if (pdata && pdata->exit)
- 		pdata->exit(dev);
--disable_unprepare_clk:
--	ahci_disable_clks(hpriv);
--disable_regulator:
--	if (hpriv->target_pwr)
--		regulator_disable(hpriv->target_pwr);
-+disable_resources:
-+	ahci_platform_disable_resources(hpriv);
- free_clk:
- 	ahci_put_clks(hpriv);
- 	return rc;
-@@ -323,11 +370,8 @@ static void ahci_host_stop(struct ata_ho
- 	if (pdata && pdata->exit)
- 		pdata->exit(dev);
- 
--	ahci_disable_clks(hpriv);
-+	ahci_platform_disable_resources(hpriv);
- 	ahci_put_clks(hpriv);
--
--	if (hpriv->target_pwr)
--		regulator_disable(hpriv->target_pwr);
- }
- 
- #ifdef CONFIG_PM_SLEEP
-@@ -362,10 +406,7 @@ static int ahci_suspend(struct device *d
- 	if (pdata && pdata->suspend)
- 		return pdata->suspend(dev);
- 
--	ahci_disable_clks(hpriv);
--
--	if (hpriv->target_pwr)
--		regulator_disable(hpriv->target_pwr);
-+	ahci_platform_disable_resources(hpriv);
- 
- 	return 0;
- }
-@@ -377,26 +418,20 @@ static int ahci_resume(struct device *de
- 	struct ahci_host_priv *hpriv = host->private_data;
- 	int rc;
- 
--	if (hpriv->target_pwr) {
--		rc = regulator_enable(hpriv->target_pwr);
--		if (rc)
--			return rc;
--	}
--
--	rc = ahci_enable_clks(dev, hpriv);
-+	rc = ahci_platform_enable_resources(hpriv);
- 	if (rc)
--		goto disable_regulator;
-+		return rc;
- 
- 	if (pdata && pdata->resume) {
- 		rc = pdata->resume(dev);
- 		if (rc)
--			goto disable_unprepare_clk;
-+			goto disable_resources;
- 	}
- 
- 	if (dev->power.power_state.event == PM_EVENT_SUSPEND) {
- 		rc = ahci_reset_controller(host);
- 		if (rc)
--			goto disable_unprepare_clk;
-+			goto disable_resources;
- 
- 		ahci_init_controller(host);
- 	}
-@@ -405,11 +440,8 @@ static int ahci_resume(struct device *de
- 
- 	return 0;
- 
--disable_unprepare_clk:
--	ahci_disable_clks(hpriv);
--disable_regulator:
--	if (hpriv->target_pwr)
--		regulator_disable(hpriv->target_pwr);
-+disable_resources:
-+	ahci_platform_disable_resources(hpriv);
- 
- 	return rc;
- }
---- a/include/linux/ahci_platform.h
-+++ b/include/linux/ahci_platform.h
-@@ -33,5 +33,7 @@ struct ahci_platform_data {
- 
- 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);
- 
- #endif /* _AHCI_PLATFORM_H */
diff --git a/target/linux/ipq806x/patches/0113-ata-delete-non-required-instances-of-include-linux-i.patch b/target/linux/ipq806x/patches/0113-ata-delete-non-required-instances-of-include-linux-i.patch
deleted file mode 100644
index 18e034e..0000000
--- a/target/linux/ipq806x/patches/0113-ata-delete-non-required-instances-of-include-linux-i.patch
+++ /dev/null
@@ -1,765 +0,0 @@
-From 01b380db3c35bbd87cb3765573fd049bce3d7640 Mon Sep 17 00:00:00 2001
-From: Paul Gortmaker <paul.gortmaker@windriver.com>
-Date: Tue, 21 Jan 2014 16:22:51 -0500
-Subject: [PATCH 113/182] ata: delete non-required instances of include
- <linux/init.h>
-
-None of these files are actually using any __init type directives
-and hence don't need to include <linux/init.h>.  Most are just a
-left over from __devinit and __cpuinit removal, or simply due to
-code getting copied from one driver to the next.
-
-Cc: linux-ide@vger.kernel.org
-Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com>
-Signed-off-by: Tejun Heo <tj@kernel.org>
----
- drivers/ata/acard-ahci.c        |    1 -
- drivers/ata/ahci.c              |    1 -
- drivers/ata/ahci_platform.c     |    1 -
- drivers/ata/ata_generic.c       |    1 -
- drivers/ata/libahci.c           |    1 -
- drivers/ata/pata_acpi.c         |    1 -
- drivers/ata/pata_amd.c          |    1 -
- drivers/ata/pata_artop.c        |    1 -
- drivers/ata/pata_at91.c         |    1 -
- drivers/ata/pata_atiixp.c       |    1 -
- drivers/ata/pata_atp867x.c      |    1 -
- drivers/ata/pata_cmd640.c       |    1 -
- drivers/ata/pata_cmd64x.c       |    1 -
- drivers/ata/pata_cs5520.c       |    1 -
- drivers/ata/pata_cs5530.c       |    1 -
- drivers/ata/pata_cs5535.c       |    1 -
- drivers/ata/pata_cs5536.c       |    1 -
- drivers/ata/pata_cypress.c      |    1 -
- drivers/ata/pata_efar.c         |    1 -
- drivers/ata/pata_ep93xx.c       |    1 -
- drivers/ata/pata_hpt366.c       |    1 -
- drivers/ata/pata_hpt37x.c       |    1 -
- drivers/ata/pata_hpt3x2n.c      |    1 -
- drivers/ata/pata_hpt3x3.c       |    1 -
- drivers/ata/pata_imx.c          |    1 -
- drivers/ata/pata_it8213.c       |    1 -
- drivers/ata/pata_it821x.c       |    1 -
- drivers/ata/pata_jmicron.c      |    1 -
- drivers/ata/pata_marvell.c      |    1 -
- drivers/ata/pata_mpiix.c        |    1 -
- drivers/ata/pata_netcell.c      |    1 -
- drivers/ata/pata_ninja32.c      |    1 -
- drivers/ata/pata_ns87410.c      |    1 -
- drivers/ata/pata_ns87415.c      |    1 -
- drivers/ata/pata_oldpiix.c      |    1 -
- drivers/ata/pata_opti.c         |    1 -
- drivers/ata/pata_optidma.c      |    1 -
- drivers/ata/pata_pcmcia.c       |    1 -
- drivers/ata/pata_pdc2027x.c     |    1 -
- drivers/ata/pata_pdc202xx_old.c |    1 -
- drivers/ata/pata_piccolo.c      |    1 -
- drivers/ata/pata_platform.c     |    1 -
- drivers/ata/pata_pxa.c          |    1 -
- drivers/ata/pata_radisys.c      |    1 -
- drivers/ata/pata_rdc.c          |    1 -
- drivers/ata/pata_rz1000.c       |    1 -
- drivers/ata/pata_sc1200.c       |    1 -
- drivers/ata/pata_scc.c          |    1 -
- drivers/ata/pata_sch.c          |    1 -
- drivers/ata/pata_serverworks.c  |    1 -
- drivers/ata/pata_sil680.c       |    1 -
- drivers/ata/pata_sis.c          |    1 -
- drivers/ata/pata_sl82c105.c     |    1 -
- drivers/ata/pata_triflex.c      |    1 -
- drivers/ata/pata_via.c          |    1 -
- drivers/ata/pdc_adma.c          |    1 -
- drivers/ata/sata_dwc_460ex.c    |    1 -
- drivers/ata/sata_highbank.c     |    1 -
- drivers/ata/sata_nv.c           |    1 -
- drivers/ata/sata_promise.c      |    1 -
- drivers/ata/sata_qstor.c        |    1 -
- drivers/ata/sata_sil.c          |    1 -
- drivers/ata/sata_sis.c          |    1 -
- drivers/ata/sata_svw.c          |    1 -
- drivers/ata/sata_sx4.c          |    1 -
- drivers/ata/sata_uli.c          |    1 -
- drivers/ata/sata_via.c          |    1 -
- drivers/ata/sata_vsc.c          |    1 -
- 68 files changed, 68 deletions(-)
-
---- a/drivers/ata/acard-ahci.c
-+++ b/drivers/ata/acard-ahci.c
-@@ -36,7 +36,6 @@
- #include <linux/kernel.h>
- #include <linux/module.h>
- #include <linux/pci.h>
--#include <linux/init.h>
- #include <linux/blkdev.h>
- #include <linux/delay.h>
- #include <linux/interrupt.h>
---- a/drivers/ata/ahci.c
-+++ b/drivers/ata/ahci.c
-@@ -35,7 +35,6 @@
- #include <linux/kernel.h>
- #include <linux/module.h>
- #include <linux/pci.h>
--#include <linux/init.h>
- #include <linux/blkdev.h>
- #include <linux/delay.h>
- #include <linux/interrupt.h>
---- a/drivers/ata/ahci_platform.c
-+++ b/drivers/ata/ahci_platform.c
-@@ -17,7 +17,6 @@
- #include <linux/gfp.h>
- #include <linux/module.h>
- #include <linux/pm.h>
--#include <linux/init.h>
- #include <linux/interrupt.h>
- #include <linux/device.h>
- #include <linux/platform_device.h>
---- a/drivers/ata/ata_generic.c
-+++ b/drivers/ata/ata_generic.c
-@@ -19,7 +19,6 @@
- #include <linux/kernel.h>
- #include <linux/module.h>
- #include <linux/pci.h>
--#include <linux/init.h>
- #include <linux/blkdev.h>
- #include <linux/delay.h>
- #include <scsi/scsi_host.h>
---- a/drivers/ata/libahci.c
-+++ b/drivers/ata/libahci.c
-@@ -35,7 +35,6 @@
- #include <linux/kernel.h>
- #include <linux/gfp.h>
- #include <linux/module.h>
--#include <linux/init.h>
- #include <linux/blkdev.h>
- #include <linux/delay.h>
- #include <linux/interrupt.h>
---- a/drivers/ata/pata_acpi.c
-+++ b/drivers/ata/pata_acpi.c
-@@ -7,7 +7,6 @@
- #include <linux/kernel.h>
- #include <linux/module.h>
- #include <linux/pci.h>
--#include <linux/init.h>
- #include <linux/blkdev.h>
- #include <linux/delay.h>
- #include <linux/device.h>
---- a/drivers/ata/pata_amd.c
-+++ b/drivers/ata/pata_amd.c
-@@ -17,7 +17,6 @@
- #include <linux/kernel.h>
- #include <linux/module.h>
- #include <linux/pci.h>
--#include <linux/init.h>
- #include <linux/blkdev.h>
- #include <linux/delay.h>
- #include <scsi/scsi_host.h>
---- a/drivers/ata/pata_artop.c
-+++ b/drivers/ata/pata_artop.c
-@@ -19,7 +19,6 @@
- #include <linux/kernel.h>
- #include <linux/module.h>
- #include <linux/pci.h>
--#include <linux/init.h>
- #include <linux/blkdev.h>
- #include <linux/delay.h>
- #include <linux/device.h>
---- a/drivers/ata/pata_at91.c
-+++ b/drivers/ata/pata_at91.c
-@@ -18,7 +18,6 @@
- 
- #include <linux/kernel.h>
- #include <linux/module.h>
--#include <linux/init.h>
- #include <linux/blkdev.h>
- #include <linux/gfp.h>
- #include <scsi/scsi_host.h>
---- a/drivers/ata/pata_atiixp.c
-+++ b/drivers/ata/pata_atiixp.c
-@@ -15,7 +15,6 @@
- #include <linux/kernel.h>
- #include <linux/module.h>
- #include <linux/pci.h>
--#include <linux/init.h>
- #include <linux/blkdev.h>
- #include <linux/delay.h>
- #include <scsi/scsi_host.h>
---- a/drivers/ata/pata_atp867x.c
-+++ b/drivers/ata/pata_atp867x.c
-@@ -29,7 +29,6 @@
- #include <linux/kernel.h>
- #include <linux/module.h>
- #include <linux/pci.h>
--#include <linux/init.h>
- #include <linux/blkdev.h>
- #include <linux/delay.h>
- #include <linux/device.h>
---- a/drivers/ata/pata_cmd640.c
-+++ b/drivers/ata/pata_cmd640.c
-@@ -15,7 +15,6 @@
- #include <linux/kernel.h>
- #include <linux/module.h>
- #include <linux/pci.h>
--#include <linux/init.h>
- #include <linux/blkdev.h>
- #include <linux/delay.h>
- #include <linux/gfp.h>
---- a/drivers/ata/pata_cmd64x.c
-+++ b/drivers/ata/pata_cmd64x.c
-@@ -26,7 +26,6 @@
- #include <linux/kernel.h>
- #include <linux/module.h>
- #include <linux/pci.h>
--#include <linux/init.h>
- #include <linux/blkdev.h>
- #include <linux/delay.h>
- #include <scsi/scsi_host.h>
---- a/drivers/ata/pata_cs5520.c
-+++ b/drivers/ata/pata_cs5520.c
-@@ -34,7 +34,6 @@
- #include <linux/kernel.h>
- #include <linux/module.h>
- #include <linux/pci.h>
--#include <linux/init.h>
- #include <linux/blkdev.h>
- #include <linux/delay.h>
- #include <scsi/scsi_host.h>
---- a/drivers/ata/pata_cs5530.c
-+++ b/drivers/ata/pata_cs5530.c
-@@ -26,7 +26,6 @@
- #include <linux/kernel.h>
- #include <linux/module.h>
- #include <linux/pci.h>
--#include <linux/init.h>
- #include <linux/blkdev.h>
- #include <linux/delay.h>
- #include <scsi/scsi_host.h>
---- a/drivers/ata/pata_cs5535.c
-+++ b/drivers/ata/pata_cs5535.c
-@@ -31,7 +31,6 @@
- #include <linux/kernel.h>
- #include <linux/module.h>
- #include <linux/pci.h>
--#include <linux/init.h>
- #include <linux/blkdev.h>
- #include <linux/delay.h>
- #include <scsi/scsi_host.h>
---- a/drivers/ata/pata_cs5536.c
-+++ b/drivers/ata/pata_cs5536.c
-@@ -33,7 +33,6 @@
- #include <linux/kernel.h>
- #include <linux/module.h>
- #include <linux/pci.h>
--#include <linux/init.h>
- #include <linux/blkdev.h>
- #include <linux/delay.h>
- #include <linux/libata.h>
---- a/drivers/ata/pata_cypress.c
-+++ b/drivers/ata/pata_cypress.c
-@@ -11,7 +11,6 @@
- #include <linux/kernel.h>
- #include <linux/module.h>
- #include <linux/pci.h>
--#include <linux/init.h>
- #include <linux/blkdev.h>
- #include <linux/delay.h>
- #include <scsi/scsi_host.h>
---- a/drivers/ata/pata_efar.c
-+++ b/drivers/ata/pata_efar.c
-@@ -14,7 +14,6 @@
- #include <linux/kernel.h>
- #include <linux/module.h>
- #include <linux/pci.h>
--#include <linux/init.h>
- #include <linux/blkdev.h>
- #include <linux/delay.h>
- #include <linux/device.h>
---- a/drivers/ata/pata_ep93xx.c
-+++ b/drivers/ata/pata_ep93xx.c
-@@ -34,7 +34,6 @@
- #include <linux/err.h>
- #include <linux/kernel.h>
- #include <linux/module.h>
--#include <linux/init.h>
- #include <linux/blkdev.h>
- #include <scsi/scsi_host.h>
- #include <linux/ata.h>
---- a/drivers/ata/pata_hpt366.c
-+++ b/drivers/ata/pata_hpt366.c
-@@ -19,7 +19,6 @@
- #include <linux/kernel.h>
- #include <linux/module.h>
- #include <linux/pci.h>
--#include <linux/init.h>
- #include <linux/blkdev.h>
- #include <linux/delay.h>
- #include <scsi/scsi_host.h>
---- a/drivers/ata/pata_hpt37x.c
-+++ b/drivers/ata/pata_hpt37x.c
-@@ -19,7 +19,6 @@
- #include <linux/kernel.h>
- #include <linux/module.h>
- #include <linux/pci.h>
--#include <linux/init.h>
- #include <linux/blkdev.h>
- #include <linux/delay.h>
- #include <scsi/scsi_host.h>
---- a/drivers/ata/pata_hpt3x2n.c
-+++ b/drivers/ata/pata_hpt3x2n.c
-@@ -20,7 +20,6 @@
- #include <linux/kernel.h>
- #include <linux/module.h>
- #include <linux/pci.h>
--#include <linux/init.h>
- #include <linux/blkdev.h>
- #include <linux/delay.h>
- #include <scsi/scsi_host.h>
---- a/drivers/ata/pata_hpt3x3.c
-+++ b/drivers/ata/pata_hpt3x3.c
-@@ -16,7 +16,6 @@
- #include <linux/kernel.h>
- #include <linux/module.h>
- #include <linux/pci.h>
--#include <linux/init.h>
- #include <linux/blkdev.h>
- #include <linux/delay.h>
- #include <scsi/scsi_host.h>
---- a/drivers/ata/pata_imx.c
-+++ b/drivers/ata/pata_imx.c
-@@ -15,7 +15,6 @@
-  */
- #include <linux/kernel.h>
- #include <linux/module.h>
--#include <linux/init.h>
- #include <linux/blkdev.h>
- #include <scsi/scsi_host.h>
- #include <linux/ata.h>
---- a/drivers/ata/pata_it8213.c
-+++ b/drivers/ata/pata_it8213.c
-@@ -10,7 +10,6 @@
- #include <linux/kernel.h>
- #include <linux/module.h>
- #include <linux/pci.h>
--#include <linux/init.h>
- #include <linux/blkdev.h>
- #include <linux/delay.h>
- #include <linux/device.h>
---- a/drivers/ata/pata_it821x.c
-+++ b/drivers/ata/pata_it821x.c
-@@ -72,7 +72,6 @@
- #include <linux/kernel.h>
- #include <linux/module.h>
- #include <linux/pci.h>
--#include <linux/init.h>
- #include <linux/blkdev.h>
- #include <linux/delay.h>
- #include <linux/slab.h>
---- a/drivers/ata/pata_jmicron.c
-+++ b/drivers/ata/pata_jmicron.c
-@@ -10,7 +10,6 @@
- #include <linux/kernel.h>
- #include <linux/module.h>
- #include <linux/pci.h>
--#include <linux/init.h>
- #include <linux/blkdev.h>
- #include <linux/delay.h>
- #include <linux/device.h>
---- a/drivers/ata/pata_marvell.c
-+++ b/drivers/ata/pata_marvell.c
-@@ -11,7 +11,6 @@
- #include <linux/kernel.h>
- #include <linux/module.h>
- #include <linux/pci.h>
--#include <linux/init.h>
- #include <linux/blkdev.h>
- #include <linux/delay.h>
- #include <linux/device.h>
---- a/drivers/ata/pata_mpiix.c
-+++ b/drivers/ata/pata_mpiix.c
-@@ -28,7 +28,6 @@
- #include <linux/kernel.h>
- #include <linux/module.h>
- #include <linux/pci.h>
--#include <linux/init.h>
- #include <linux/blkdev.h>
- #include <linux/delay.h>
- #include <scsi/scsi_host.h>
---- a/drivers/ata/pata_netcell.c
-+++ b/drivers/ata/pata_netcell.c
-@@ -7,7 +7,6 @@
- #include <linux/kernel.h>
- #include <linux/module.h>
- #include <linux/pci.h>
--#include <linux/init.h>
- #include <linux/blkdev.h>
- #include <linux/delay.h>
- #include <linux/device.h>
---- a/drivers/ata/pata_ninja32.c
-+++ b/drivers/ata/pata_ninja32.c
-@@ -37,7 +37,6 @@
- #include <linux/kernel.h>
- #include <linux/module.h>
- #include <linux/pci.h>
--#include <linux/init.h>
- #include <linux/blkdev.h>
- #include <linux/delay.h>
- #include <scsi/scsi_host.h>
---- a/drivers/ata/pata_ns87410.c
-+++ b/drivers/ata/pata_ns87410.c
-@@ -20,7 +20,6 @@
- #include <linux/kernel.h>
- #include <linux/module.h>
- #include <linux/pci.h>
--#include <linux/init.h>
- #include <linux/blkdev.h>
- #include <linux/delay.h>
- #include <scsi/scsi_host.h>
---- a/drivers/ata/pata_ns87415.c
-+++ b/drivers/ata/pata_ns87415.c
-@@ -25,7 +25,6 @@
- #include <linux/kernel.h>
- #include <linux/module.h>
- #include <linux/pci.h>
--#include <linux/init.h>
- #include <linux/blkdev.h>
- #include <linux/delay.h>
- #include <linux/device.h>
---- a/drivers/ata/pata_oldpiix.c
-+++ b/drivers/ata/pata_oldpiix.c
-@@ -16,7 +16,6 @@
- #include <linux/kernel.h>
- #include <linux/module.h>
- #include <linux/pci.h>
--#include <linux/init.h>
- #include <linux/blkdev.h>
- #include <linux/delay.h>
- #include <linux/device.h>
---- a/drivers/ata/pata_opti.c
-+++ b/drivers/ata/pata_opti.c
-@@ -26,7 +26,6 @@
- #include <linux/kernel.h>
- #include <linux/module.h>
- #include <linux/pci.h>
--#include <linux/init.h>
- #include <linux/blkdev.h>
- #include <linux/delay.h>
- #include <scsi/scsi_host.h>
---- a/drivers/ata/pata_optidma.c
-+++ b/drivers/ata/pata_optidma.c
-@@ -25,7 +25,6 @@
- #include <linux/kernel.h>
- #include <linux/module.h>
- #include <linux/pci.h>
--#include <linux/init.h>
- #include <linux/blkdev.h>
- #include <linux/delay.h>
- #include <scsi/scsi_host.h>
---- a/drivers/ata/pata_pcmcia.c
-+++ b/drivers/ata/pata_pcmcia.c
-@@ -26,7 +26,6 @@
- 
- #include <linux/kernel.h>
- #include <linux/module.h>
--#include <linux/init.h>
- #include <linux/blkdev.h>
- #include <linux/delay.h>
- #include <linux/slab.h>
---- a/drivers/ata/pata_pdc2027x.c
-+++ b/drivers/ata/pata_pdc2027x.c
-@@ -25,7 +25,6 @@
- #include <linux/kernel.h>
- #include <linux/module.h>
- #include <linux/pci.h>
--#include <linux/init.h>
- #include <linux/blkdev.h>
- #include <linux/delay.h>
- #include <linux/device.h>
---- a/drivers/ata/pata_pdc202xx_old.c
-+++ b/drivers/ata/pata_pdc202xx_old.c
-@@ -15,7 +15,6 @@
- #include <linux/kernel.h>
- #include <linux/module.h>
- #include <linux/pci.h>
--#include <linux/init.h>
- #include <linux/blkdev.h>
- #include <linux/delay.h>
- #include <scsi/scsi_host.h>
---- a/drivers/ata/pata_piccolo.c
-+++ b/drivers/ata/pata_piccolo.c
-@@ -18,7 +18,6 @@
- #include <linux/kernel.h>
- #include <linux/module.h>
- #include <linux/pci.h>
--#include <linux/init.h>
- #include <linux/blkdev.h>
- #include <linux/delay.h>
- #include <scsi/scsi_host.h>
---- a/drivers/ata/pata_platform.c
-+++ b/drivers/ata/pata_platform.c
-@@ -13,7 +13,6 @@
-  */
- #include <linux/kernel.h>
- #include <linux/module.h>
--#include <linux/init.h>
- #include <linux/blkdev.h>
- #include <scsi/scsi_host.h>
- #include <linux/ata.h>
---- a/drivers/ata/pata_pxa.c
-+++ b/drivers/ata/pata_pxa.c
-@@ -20,7 +20,6 @@
- 
- #include <linux/kernel.h>
- #include <linux/module.h>
--#include <linux/init.h>
- #include <linux/blkdev.h>
- #include <linux/ata.h>
- #include <linux/libata.h>
---- a/drivers/ata/pata_radisys.c
-+++ b/drivers/ata/pata_radisys.c
-@@ -15,7 +15,6 @@
- #include <linux/kernel.h>
- #include <linux/module.h>
- #include <linux/pci.h>
--#include <linux/init.h>
- #include <linux/blkdev.h>
- #include <linux/delay.h>
- #include <linux/device.h>
---- a/drivers/ata/pata_rdc.c
-+++ b/drivers/ata/pata_rdc.c
-@@ -24,7 +24,6 @@
- #include <linux/kernel.h>
- #include <linux/module.h>
- #include <linux/pci.h>
--#include <linux/init.h>
- #include <linux/blkdev.h>
- #include <linux/delay.h>
- #include <linux/device.h>
---- a/drivers/ata/pata_rz1000.c
-+++ b/drivers/ata/pata_rz1000.c
-@@ -14,7 +14,6 @@
- #include <linux/kernel.h>
- #include <linux/module.h>
- #include <linux/pci.h>
--#include <linux/init.h>
- #include <linux/blkdev.h>
- #include <linux/delay.h>
- #include <scsi/scsi_host.h>
---- a/drivers/ata/pata_sc1200.c
-+++ b/drivers/ata/pata_sc1200.c
-@@ -32,7 +32,6 @@
- #include <linux/kernel.h>
- #include <linux/module.h>
- #include <linux/pci.h>
--#include <linux/init.h>
- #include <linux/blkdev.h>
- #include <linux/delay.h>
- #include <scsi/scsi_host.h>
---- a/drivers/ata/pata_scc.c
-+++ b/drivers/ata/pata_scc.c
-@@ -35,7 +35,6 @@
- #include <linux/kernel.h>
- #include <linux/module.h>
- #include <linux/pci.h>
--#include <linux/init.h>
- #include <linux/blkdev.h>
- #include <linux/delay.h>
- #include <linux/device.h>
---- a/drivers/ata/pata_sch.c
-+++ b/drivers/ata/pata_sch.c
-@@ -27,7 +27,6 @@
- #include <linux/kernel.h>
- #include <linux/module.h>
- #include <linux/pci.h>
--#include <linux/init.h>
- #include <linux/blkdev.h>
- #include <linux/delay.h>
- #include <linux/device.h>
---- a/drivers/ata/pata_serverworks.c
-+++ b/drivers/ata/pata_serverworks.c
-@@ -34,7 +34,6 @@
- #include <linux/kernel.h>
- #include <linux/module.h>
- #include <linux/pci.h>
--#include <linux/init.h>
- #include <linux/blkdev.h>
- #include <linux/delay.h>
- #include <scsi/scsi_host.h>
---- a/drivers/ata/pata_sil680.c
-+++ b/drivers/ata/pata_sil680.c
-@@ -25,7 +25,6 @@
- #include <linux/kernel.h>
- #include <linux/module.h>
- #include <linux/pci.h>
--#include <linux/init.h>
- #include <linux/blkdev.h>
- #include <linux/delay.h>
- #include <scsi/scsi_host.h>
---- a/drivers/ata/pata_sis.c
-+++ b/drivers/ata/pata_sis.c
-@@ -26,7 +26,6 @@
- #include <linux/kernel.h>
- #include <linux/module.h>
- #include <linux/pci.h>
--#include <linux/init.h>
- #include <linux/blkdev.h>
- #include <linux/delay.h>
- #include <linux/device.h>
---- a/drivers/ata/pata_sl82c105.c
-+++ b/drivers/ata/pata_sl82c105.c
-@@ -19,7 +19,6 @@
- #include <linux/kernel.h>
- #include <linux/module.h>
- #include <linux/pci.h>
--#include <linux/init.h>
- #include <linux/blkdev.h>
- #include <linux/delay.h>
- #include <scsi/scsi_host.h>
---- a/drivers/ata/pata_triflex.c
-+++ b/drivers/ata/pata_triflex.c
-@@ -36,7 +36,6 @@
- #include <linux/kernel.h>
- #include <linux/module.h>
- #include <linux/pci.h>
--#include <linux/init.h>
- #include <linux/blkdev.h>
- #include <linux/delay.h>
- #include <scsi/scsi_host.h>
---- a/drivers/ata/pata_via.c
-+++ b/drivers/ata/pata_via.c
-@@ -55,7 +55,6 @@
- #include <linux/kernel.h>
- #include <linux/module.h>
- #include <linux/pci.h>
--#include <linux/init.h>
- #include <linux/blkdev.h>
- #include <linux/delay.h>
- #include <linux/gfp.h>
---- a/drivers/ata/pdc_adma.c
-+++ b/drivers/ata/pdc_adma.c
-@@ -36,7 +36,6 @@
- #include <linux/module.h>
- #include <linux/gfp.h>
- #include <linux/pci.h>
--#include <linux/init.h>
- #include <linux/blkdev.h>
- #include <linux/delay.h>
- #include <linux/interrupt.h>
---- a/drivers/ata/sata_dwc_460ex.c
-+++ b/drivers/ata/sata_dwc_460ex.c
-@@ -29,7 +29,6 @@
- 
- #include <linux/kernel.h>
- #include <linux/module.h>
--#include <linux/init.h>
- #include <linux/device.h>
- #include <linux/of_address.h>
- #include <linux/of_irq.h>
---- a/drivers/ata/sata_highbank.c
-+++ b/drivers/ata/sata_highbank.c
-@@ -19,7 +19,6 @@
- #include <linux/kernel.h>
- #include <linux/gfp.h>
- #include <linux/module.h>
--#include <linux/init.h>
- #include <linux/types.h>
- #include <linux/err.h>
- #include <linux/io.h>
---- a/drivers/ata/sata_nv.c
-+++ b/drivers/ata/sata_nv.c
-@@ -40,7 +40,6 @@
- #include <linux/module.h>
- #include <linux/gfp.h>
- #include <linux/pci.h>
--#include <linux/init.h>
- #include <linux/blkdev.h>
- #include <linux/delay.h>
- #include <linux/interrupt.h>
---- a/drivers/ata/sata_promise.c
-+++ b/drivers/ata/sata_promise.c
-@@ -35,7 +35,6 @@
- #include <linux/module.h>
- #include <linux/gfp.h>
- #include <linux/pci.h>
--#include <linux/init.h>
- #include <linux/blkdev.h>
- #include <linux/delay.h>
- #include <linux/interrupt.h>
---- a/drivers/ata/sata_qstor.c
-+++ b/drivers/ata/sata_qstor.c
-@@ -31,7 +31,6 @@
- #include <linux/module.h>
- #include <linux/gfp.h>
- #include <linux/pci.h>
--#include <linux/init.h>
- #include <linux/blkdev.h>
- #include <linux/delay.h>
- #include <linux/interrupt.h>
---- a/drivers/ata/sata_sil.c
-+++ b/drivers/ata/sata_sil.c
-@@ -37,7 +37,6 @@
- #include <linux/kernel.h>
- #include <linux/module.h>
- #include <linux/pci.h>
--#include <linux/init.h>
- #include <linux/blkdev.h>
- #include <linux/delay.h>
- #include <linux/interrupt.h>
---- a/drivers/ata/sata_sis.c
-+++ b/drivers/ata/sata_sis.c
-@@ -33,7 +33,6 @@
- #include <linux/kernel.h>
- #include <linux/module.h>
- #include <linux/pci.h>
--#include <linux/init.h>
- #include <linux/blkdev.h>
- #include <linux/delay.h>
- #include <linux/interrupt.h>
---- a/drivers/ata/sata_svw.c
-+++ b/drivers/ata/sata_svw.c
-@@ -39,7 +39,6 @@
- #include <linux/kernel.h>
- #include <linux/module.h>
- #include <linux/pci.h>
--#include <linux/init.h>
- #include <linux/blkdev.h>
- #include <linux/delay.h>
- #include <linux/interrupt.h>
---- a/drivers/ata/sata_sx4.c
-+++ b/drivers/ata/sata_sx4.c
-@@ -82,7 +82,6 @@
- #include <linux/module.h>
- #include <linux/pci.h>
- #include <linux/slab.h>
--#include <linux/init.h>
- #include <linux/blkdev.h>
- #include <linux/delay.h>
- #include <linux/interrupt.h>
---- a/drivers/ata/sata_uli.c
-+++ b/drivers/ata/sata_uli.c
-@@ -28,7 +28,6 @@
- #include <linux/module.h>
- #include <linux/gfp.h>
- #include <linux/pci.h>
--#include <linux/init.h>
- #include <linux/blkdev.h>
- #include <linux/delay.h>
- #include <linux/interrupt.h>
---- a/drivers/ata/sata_via.c
-+++ b/drivers/ata/sata_via.c
-@@ -36,7 +36,6 @@
- #include <linux/kernel.h>
- #include <linux/module.h>
- #include <linux/pci.h>
--#include <linux/init.h>
- #include <linux/blkdev.h>
- #include <linux/delay.h>
- #include <linux/device.h>
---- a/drivers/ata/sata_vsc.c
-+++ b/drivers/ata/sata_vsc.c
-@@ -37,7 +37,6 @@
- #include <linux/kernel.h>
- #include <linux/module.h>
- #include <linux/pci.h>
--#include <linux/init.h>
- #include <linux/blkdev.h>
- #include <linux/delay.h>
- #include <linux/interrupt.h>
diff --git a/target/linux/ipq806x/patches/0114-ahci-platform-Library-ise-ahci_probe-functionality.patch b/target/linux/ipq806x/patches/0114-ahci-platform-Library-ise-ahci_probe-functionality.patch
deleted file mode 100644
index 3b638d4..0000000
--- a/target/linux/ipq806x/patches/0114-ahci-platform-Library-ise-ahci_probe-functionality.patch
+++ /dev/null
@@ -1,334 +0,0 @@
-From 8be4987340a101253fb871556894a002f1afb51f Mon Sep 17 00:00:00 2001
-From: Hans de Goede <hdegoede@redhat.com>
-Date: Sat, 22 Feb 2014 16:53:34 +0100
-Subject: [PATCH 114/182] ahci-platform: "Library-ise" ahci_probe
- functionality
-
-ahci_probe consists of 3 steps:
-1) Get resources (get mmio, clks, regulator)
-2) Enable resources, handled by ahci_platform_enable_resouces
-3) The more or less standard ahci-host controller init sequence
-
-This commit refactors step 1 and 3 into separate functions, so the platform
-drivers for AHCI implementations which need a specific order in step 2,
-and / or need to do some custom register poking at some time, can re-use
-ahci-platform.c code without needing to copy and paste it.
-
-Note that ahci_platform_init_host's prototype takes the 3 non function
-members of ahci_platform_data as arguments, the idea is that drivers using
-the new exported utility functions will not use ahci_platform_data at all,
-and hopefully in the future ahci_platform_data can go away entirely.
-
-tj: Minor comment formatting updates.
-
-Signed-off-by: Hans de Goede <hdegoede@redhat.com>
-Signed-off-by: Tejun Heo <tj@kernel.org>
----
- drivers/ata/ahci_platform.c   |  188 +++++++++++++++++++++++++++--------------
- include/linux/ahci_platform.h |   14 +++
- 2 files changed, 137 insertions(+), 65 deletions(-)
-
---- a/drivers/ata/ahci_platform.c
-+++ b/drivers/ata/ahci_platform.c
-@@ -188,64 +188,60 @@ void ahci_platform_disable_resources(str
- }
- EXPORT_SYMBOL_GPL(ahci_platform_disable_resources);
- 
--static void ahci_put_clks(struct ahci_host_priv *hpriv)
-+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]);
- }
- 
--static int ahci_probe(struct platform_device *pdev)
-+/**
-+ * 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
-+ *
-+ * 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_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;
- 	struct clk *clk;
--	int irq;
--	int n_ports;
--	int i;
--	int rc;
-+	int i, rc = -ENOMEM;
- 
--	mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
--	if (!mem) {
--		dev_err(dev, "no mmio space\n");
--		return -EINVAL;
--	}
-+	if (!devres_open_group(dev, NULL, GFP_KERNEL))
-+		return ERR_PTR(-ENOMEM);
- 
--	irq = platform_get_irq(pdev, 0);
--	if (irq <= 0) {
--		dev_err(dev, "no irq\n");
--		return -EINVAL;
--	}
--
--	if (pdata && pdata->ata_port_info)
--		pi = *pdata->ata_port_info;
-+	hpriv = devres_alloc(ahci_platform_put_resources, sizeof(*hpriv),
-+			     GFP_KERNEL);
-+	if (!hpriv)
-+		goto err_out;
- 
--	hpriv = devm_kzalloc(dev, sizeof(*hpriv), GFP_KERNEL);
--	if (!hpriv) {
--		dev_err(dev, "can't alloc ahci_host_priv\n");
--		return -ENOMEM;
--	}
-+	devres_add(dev, hpriv);
- 
--	hpriv->flags |= (unsigned long)pi.private_data;
--
--	hpriv->mmio = devm_ioremap(dev, mem->start, resource_size(mem));
-+	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->target_pwr = devm_regulator_get_optional(dev, "target");
- 	if (IS_ERR(hpriv->target_pwr)) {
- 		rc = PTR_ERR(hpriv->target_pwr);
- 		if (rc == -EPROBE_DEFER)
--			return -EPROBE_DEFER;
-+			goto err_out;
- 		hpriv->target_pwr = NULL;
- 	}
- 
-@@ -264,33 +260,59 @@ static int ahci_probe(struct platform_de
- 		if (IS_ERR(clk)) {
- 			rc = PTR_ERR(clk);
- 			if (rc == -EPROBE_DEFER)
--				goto free_clk;
-+				goto err_out;
- 			break;
- 		}
- 		hpriv->clks[i] = clk;
- 	}
- 
--	rc = ahci_platform_enable_resources(hpriv);
--	if (rc)
--		goto free_clk;
-+	devres_remove_group(dev, NULL);
-+	return hpriv;
- 
--	/*
--	 * 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;
--	}
-+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.
-+ *
-+ * 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;
- 
-@@ -307,10 +329,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;
- 
-@@ -325,7 +345,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 */
-@@ -339,13 +360,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;
- 
-@@ -355,8 +416,6 @@ pdata_exit:
- 		pdata->exit(dev);
- disable_resources:
- 	ahci_platform_disable_resources(hpriv);
--free_clk:
--	ahci_put_clks(hpriv);
- 	return rc;
- }
- 
-@@ -370,7 +429,6 @@ static void ahci_host_stop(struct ata_ho
- 		pdata->exit(dev);
- 
- 	ahci_platform_disable_resources(hpriv);
--	ahci_put_clks(hpriv);
- }
- 
- #ifdef CONFIG_PM_SLEEP
---- a/include/linux/ahci_platform.h
-+++ b/include/linux/ahci_platform.h
-@@ -20,7 +20,14 @@
- 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);
-@@ -35,5 +42,12 @@ int ahci_platform_enable_clks(struct ahc
- 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);
- 
- #endif /* _AHCI_PLATFORM_H */
diff --git a/target/linux/ipq806x/patches/0115-ahci-platform-Library-ise-suspend-resume-functionali.patch b/target/linux/ipq806x/patches/0115-ahci-platform-Library-ise-suspend-resume-functionali.patch
deleted file mode 100644
index 8cc7d7a..0000000
--- a/target/linux/ipq806x/patches/0115-ahci-platform-Library-ise-suspend-resume-functionali.patch
+++ /dev/null
@@ -1,173 +0,0 @@
-From 8121ed9c7ea2d56f5e0a98c2db396214f85d7485 Mon Sep 17 00:00:00 2001
-From: Hans de Goede <hdegoede@redhat.com>
-Date: Sat, 22 Feb 2014 16:53:35 +0100
-Subject: [PATCH 115/182] ahci-platform: "Library-ise" suspend / resume
- functionality
-
-Split suspend / resume code into host suspend / resume functionality and
-resource enable / disabling phases, and export the new suspend_ / resume_host
-functions.
-
-tj: Minor comment formatting updates.
-
-Signed-off-by: Hans de Goede <hdegoede@redhat.com>
-Signed-off-by: Tejun Heo <tj@kernel.org>
----
- drivers/ata/ahci_platform.c   |   97 ++++++++++++++++++++++++++++++++++-------
- include/linux/ahci_platform.h |    5 +++
- 2 files changed, 87 insertions(+), 15 deletions(-)
-
---- a/drivers/ata/ahci_platform.c
-+++ b/drivers/ata/ahci_platform.c
-@@ -432,14 +432,23 @@ static void ahci_host_stop(struct ata_ho
- }
- 
- #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.
-+ *
-+ * 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");
-@@ -456,7 +465,58 @@ 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.
-+ *
-+ * 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.
-+ *
-+ * 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;
- 
-@@ -467,8 +527,19 @@ static int ahci_suspend(struct device *d
- 
- 	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.
-+ *
-+ * 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);
-@@ -485,15 +556,9 @@ static int ahci_resume(struct device *de
- 			goto disable_resources;
- 	}
- 
--	if (dev->power.power_state.event == PM_EVENT_SUSPEND) {
--		rc = ahci_reset_controller(host);
--		if (rc)
--			goto disable_resources;
--
--		ahci_init_controller(host);
--	}
--
--	ata_host_resume(host);
-+	rc = ahci_platform_resume_host(dev);
-+	if (rc)
-+		goto disable_resources;
- 
- 	return 0;
- 
-@@ -502,9 +567,11 @@ disable_resources:
- 
- 	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
-@@ -50,4 +50,9 @@ int ahci_platform_init_host(struct platf
- 			    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/ipq806x/patches/0116-ata-ahci_platform-Add-DT-compatible-for-Synopsis-DWC.patch b/target/linux/ipq806x/patches/0116-ata-ahci_platform-Add-DT-compatible-for-Synopsis-DWC.patch
deleted file mode 100644
index e64e5c9..0000000
--- a/target/linux/ipq806x/patches/0116-ata-ahci_platform-Add-DT-compatible-for-Synopsis-DWC.patch
+++ /dev/null
@@ -1,27 +0,0 @@
-From bab3492791ade083c172a898b6f7a3692ffb89d5 Mon Sep 17 00:00:00 2001
-From: Roger Quadros <rogerq@ti.com>
-Date: Sat, 22 Feb 2014 16:53:38 +0100
-Subject: [PATCH 116/182] 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>
-Signed-off-by: Tejun Heo <tj@kernel.org>
----
- drivers/ata/ahci_platform.c |    1 +
- 1 file changed, 1 insertion(+)
-
---- a/drivers/ata/ahci_platform.c
-+++ b/drivers/ata/ahci_platform.c
-@@ -577,6 +577,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);
diff --git a/target/linux/ipq806x/patches/0117-ata-ahci_platform-Manage-SATA-PHY.patch b/target/linux/ipq806x/patches/0117-ata-ahci_platform-Manage-SATA-PHY.patch
deleted file mode 100644
index 20211dc..0000000
--- a/target/linux/ipq806x/patches/0117-ata-ahci_platform-Manage-SATA-PHY.patch
+++ /dev/null
@@ -1,134 +0,0 @@
-From 05b9b8d1035944af25694d2ebe53077cf1ccb067 Mon Sep 17 00:00:00 2001
-From: Roger Quadros <rogerq@ti.com>
-Date: Sat, 22 Feb 2014 16:53:40 +0100
-Subject: [PATCH 117/182] ata: ahci_platform: Manage SATA PHY
-
-Some platforms have a PHY hooked up to the SATA controller. The PHY
-needs to be initialized and powered up for SATA to work. We do that
-using the PHY framework.
-
-tj: Minor comment formatting updates.
-
-CC: Balaji T K <balajitk@ti.com>
-Signed-off-by: Roger Quadros <rogerq@ti.com>
-Signed-off-by: Hans de Goede <hdegoede@redhat.com>
-Signed-off-by: Tejun Heo<tj@kernel.org>
----
- drivers/ata/ahci.h          |    2 ++
- drivers/ata/ahci_platform.c |   47 +++++++++++++++++++++++++++++++++++++++++--
- 2 files changed, 47 insertions(+), 2 deletions(-)
-
---- 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 */
-@@ -326,6 +327,7 @@ struct ahci_host_priv {
- 	u32			em_msg_type;	/* EM message type */
- 	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_platform.c
-+++ b/drivers/ata/ahci_platform.c
-@@ -22,6 +22,7 @@
- #include <linux/platform_device.h>
- #include <linux/libata.h>
- #include <linux/ahci_platform.h>
-+#include <linux/phy/phy.h>
- #include "ahci.h"
- 
- static void ahci_host_stop(struct ata_host *host);
-@@ -140,6 +141,7 @@ EXPORT_SYMBOL_GPL(ahci_platform_disable_
-  * 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.
-@@ -161,8 +163,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);
-@@ -176,11 +193,17 @@ 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
-  */
- 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)
-@@ -208,6 +231,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)
-  *
-  * RETURNS:
-  * The allocated ahci_host_priv on success, otherwise an ERR_PTR value
-@@ -266,6 +290,25 @@ 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;
-+		}
-+	}
-+
- 	devres_remove_group(dev, NULL);
- 	return hpriv;
- 
diff --git a/target/linux/ipq806x/patches/0118-ata-ahci_platform-runtime-resume-the-device-before-u.patch b/target/linux/ipq806x/patches/0118-ata-ahci_platform-runtime-resume-the-device-before-u.patch
deleted file mode 100644
index 6603bb9..0000000
--- a/target/linux/ipq806x/patches/0118-ata-ahci_platform-runtime-resume-the-device-before-u.patch
+++ /dev/null
@@ -1,79 +0,0 @@
-From abe309ab531f22b9b89329bd825606f6b68a95a1 Mon Sep 17 00:00:00 2001
-From: Roger Quadros <rogerq@ti.com>
-Date: Sat, 22 Feb 2014 16:53:41 +0100
-Subject: [PATCH 118/182] ata: ahci_platform: runtime resume the device before
- use
-
-On OMAP platforms the device needs to be runtime resumed before it can
-be accessed. The OMAP HWMOD framework takes care of enabling the
-module and its resources based on the device's runtime PM state.
-
-In this patch we runtime resume during .probe() and runtime suspend
-after .remove().
-
-We also update the runtime PM state during .resume().
-
-CC: Balaji T K <balajitk@ti.com>
-Signed-off-by: Roger Quadros <rogerq@ti.com>
-Signed-off-by: Hans de Goede <hdegoede@redhat.com>
-Signed-off-by: Tejun Heo <tj@kernel.org>
----
- drivers/ata/ahci.h          |    1 +
- drivers/ata/ahci_platform.c |   15 +++++++++++++++
- 2 files changed, 16 insertions(+)
-
---- a/drivers/ata/ahci.h
-+++ b/drivers/ata/ahci.h
-@@ -325,6 +325,7 @@ 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 */
---- a/drivers/ata/ahci_platform.c
-+++ b/drivers/ata/ahci_platform.c
-@@ -23,6 +23,7 @@
- #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);
-@@ -216,6 +217,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]);
- }
-@@ -309,6 +315,10 @@ struct ahci_host_priv *ahci_platform_get
- 		}
- 	}
- 
-+	pm_runtime_enable(dev);
-+	pm_runtime_get_sync(dev);
-+	hpriv->got_runtime_pm = true;
-+
- 	devres_remove_group(dev, NULL);
- 	return hpriv;
- 
-@@ -603,6 +613,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:
diff --git a/target/linux/ipq806x/patches/0119-ahci_platform-Drop-support-for-ahci-strict-platform-.patch b/target/linux/ipq806x/patches/0119-ahci_platform-Drop-support-for-ahci-strict-platform-.patch
deleted file mode 100644
index 2e833ce..0000000
--- a/target/linux/ipq806x/patches/0119-ahci_platform-Drop-support-for-ahci-strict-platform-.patch
+++ /dev/null
@@ -1,49 +0,0 @@
-From 474c436aebe260b0e6e7042ce5291137b7c87b57 Mon Sep 17 00:00:00 2001
-From: Hans de Goede <hdegoede@redhat.com>
-Date: Sat, 22 Feb 2014 17:22:53 +0100
-Subject: [PATCH 119/182] ahci_platform: Drop support for ahci-strict platform
- device type
-
-I've done a grep over the entire kernel tree and nothing is using this
-(anymore?).
-
-Signed-off-by: Hans de Goede <hdegoede@redhat.com>
-Signed-off-by: Tejun Heo <tj@kernel.org>
----
- drivers/ata/ahci_platform.c |   11 -----------
- 1 file changed, 11 deletions(-)
-
---- a/drivers/ata/ahci_platform.c
-+++ b/drivers/ata/ahci_platform.c
-@@ -31,7 +31,6 @@ static void ahci_host_stop(struct ata_ho
- enum ahci_type {
- 	AHCI,		/* standard platform ahci */
- 	IMX53_AHCI,	/* ahci on i.mx53 */
--	STRICT_AHCI,	/* delayed DMA engine start */
- };
- 
- static struct platform_device_id ahci_devtype[] = {
-@@ -42,9 +41,6 @@ static struct platform_device_id ahci_de
- 		.name = "imx53-ahci",
- 		.driver_data = IMX53_AHCI,
- 	}, {
--		.name = "strict-ahci",
--		.driver_data = STRICT_AHCI,
--	}, {
- 		/* sentinel */
- 	}
- };
-@@ -75,13 +71,6 @@ static const struct ata_port_info ahci_p
- 		.udma_mask	= ATA_UDMA6,
- 		.port_ops	= &ahci_platform_retry_srst_ops,
- 	},
--	[STRICT_AHCI] = {
--		AHCI_HFLAGS	(AHCI_HFLAG_DELAY_ENGINE),
--		.flags		= AHCI_FLAG_COMMON,
--		.pio_mask	= ATA_PIO4,
--		.udma_mask	= ATA_UDMA6,
--		.port_ops	= &ahci_platform_ops,
--	},
- };
- 
- static struct scsi_host_template ahci_platform_sht = {
diff --git a/target/linux/ipq806x/patches/0120-ahci_platform-Drop-support-for-imx53-ahci-platform-d.patch b/target/linux/ipq806x/patches/0120-ahci_platform-Drop-support-for-imx53-ahci-platform-d.patch
deleted file mode 100644
index b18c04f..0000000
--- a/target/linux/ipq806x/patches/0120-ahci_platform-Drop-support-for-imx53-ahci-platform-d.patch
+++ /dev/null
@@ -1,105 +0,0 @@
-From 0d153bacb749d9291324ef0282ea9d235baca499 Mon Sep 17 00:00:00 2001
-From: Hans de Goede <hdegoede@redhat.com>
-Date: Sat, 22 Feb 2014 17:22:54 +0100
-Subject: [PATCH 120/182] ahci_platform: Drop support for imx53-ahci platform
- device type
-
-Since the 3.13 release the ahci_imx driver has proper devicetree enabled
-support for ahci on imx53 and that is used instead of the old board file
-created imx53-ahci platform device.
-
-Note this patch also complete drops the id-table, an id-table is not needed
-for a single id platform driver, the name field in the driver struct suffices.
-
-And the code already has an explicit "MODULE_ALIAS("platform:ahci");" so the
-id-table is not needed for that either.
-
-Cc: Marek Vasut <marex@denx.de>
-Signed-off-by: Hans de Goede <hdegoede@redhat.com>
-Signed-off-by: Tejun Heo <tj@kernel.org>
----
- drivers/ata/ahci_platform.c |   46 ++++++-------------------------------------
- 1 file changed, 6 insertions(+), 40 deletions(-)
-
---- a/drivers/ata/ahci_platform.c
-+++ b/drivers/ata/ahci_platform.c
-@@ -28,49 +28,17 @@
- 
- static void ahci_host_stop(struct ata_host *host);
- 
--enum ahci_type {
--	AHCI,		/* standard platform ahci */
--	IMX53_AHCI,	/* ahci on i.mx53 */
--};
--
--static struct platform_device_id ahci_devtype[] = {
--	{
--		.name = "ahci",
--		.driver_data = AHCI,
--	}, {
--		.name = "imx53-ahci",
--		.driver_data = IMX53_AHCI,
--	}, {
--		/* sentinel */
--	}
--};
--MODULE_DEVICE_TABLE(platform, ahci_devtype);
--
- struct ata_port_operations ahci_platform_ops = {
- 	.inherits	= &ahci_ops,
- 	.host_stop	= ahci_host_stop,
- };
- EXPORT_SYMBOL_GPL(ahci_platform_ops);
- 
--static struct ata_port_operations ahci_platform_retry_srst_ops = {
--	.inherits	= &ahci_pmp_retry_srst_ops,
--	.host_stop	= ahci_host_stop,
--};
--
--static const struct ata_port_info ahci_port_info[] = {
--	/* by features */
--	[AHCI] = {
--		.flags		= AHCI_FLAG_COMMON,
--		.pio_mask	= ATA_PIO4,
--		.udma_mask	= ATA_UDMA6,
--		.port_ops	= &ahci_platform_ops,
--	},
--	[IMX53_AHCI] = {
--		.flags		= AHCI_FLAG_COMMON,
--		.pio_mask	= ATA_PIO4,
--		.udma_mask	= ATA_UDMA6,
--		.port_ops	= &ahci_platform_retry_srst_ops,
--	},
-+static const struct ata_port_info ahci_port_info = {
-+	.flags		= AHCI_FLAG_COMMON,
-+	.pio_mask	= ATA_PIO4,
-+	.udma_mask	= ATA_UDMA6,
-+	.port_ops	= &ahci_platform_ops,
- };
- 
- static struct scsi_host_template ahci_platform_sht = {
-@@ -416,7 +384,6 @@ static int ahci_probe(struct platform_de
- {
- 	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;
-@@ -444,7 +411,7 @@ static int ahci_probe(struct platform_de
- 	if (pdata && pdata->ata_port_info)
- 		pi_template = pdata->ata_port_info;
- 	else
--		pi_template = &ahci_port_info[id ? id->driver_data : 0];
-+		pi_template = &ahci_port_info;
- 
- 	rc = ahci_platform_init_host(pdev, hpriv, pi_template,
- 				     pdata ? pdata->force_port_map : 0,
-@@ -638,7 +605,6 @@ static struct platform_driver ahci_drive
- 		.of_match_table = ahci_of_match,
- 		.pm = &ahci_pm_ops,
- 	},
--	.id_table	= ahci_devtype,
- };
- module_platform_driver(ahci_driver);
- 
diff --git a/target/linux/ipq806x/patches/0121-ahci_platform-Drop-unused-ahci_platform_data-members.patch b/target/linux/ipq806x/patches/0121-ahci_platform-Drop-unused-ahci_platform_data-members.patch
deleted file mode 100644
index 2895a2b..0000000
--- a/target/linux/ipq806x/patches/0121-ahci_platform-Drop-unused-ahci_platform_data-members.patch
+++ /dev/null
@@ -1,55 +0,0 @@
-From 438df60c6bff1b12a407fefcfb8a2e5d9b29ac6a Mon Sep 17 00:00:00 2001
-From: Hans de Goede <hdegoede@redhat.com>
-Date: Sat, 22 Feb 2014 17:22:55 +0100
-Subject: [PATCH 121/182] ahci_platform: Drop unused ahci_platform_data
- members
-
-These members are not used anywhere, and in the future we want
-ahci_platform_data to go away entirely so there is no reason to keep these
-around.
-
-Signed-off-by: Hans de Goede <hdegoede@redhat.com>
-Signed-off-by: Tejun Heo <tj@kernel.org>
----
- drivers/ata/ahci_platform.c   |   10 +---------
- include/linux/ahci_platform.h |    3 ---
- 2 files changed, 1 insertion(+), 12 deletions(-)
-
---- a/drivers/ata/ahci_platform.c
-+++ b/drivers/ata/ahci_platform.c
-@@ -384,7 +384,6 @@ static int ahci_probe(struct platform_de
- {
- 	struct device *dev = &pdev->dev;
- 	struct ahci_platform_data *pdata = dev_get_platdata(dev);
--	const struct ata_port_info *pi_template;
- 	struct ahci_host_priv *hpriv;
- 	int rc;
- 
-@@ -408,14 +407,7 @@ static int ahci_probe(struct platform_de
- 			goto disable_resources;
- 	}
- 
--	if (pdata && pdata->ata_port_info)
--		pi_template = pdata->ata_port_info;
--	else
--		pi_template = &ahci_port_info;
--
--	rc = ahci_platform_init_host(pdev, hpriv, pi_template,
--				     pdata ? pdata->force_port_map : 0,
--				     pdata ? pdata->mask_port_map  : 0);
-+	rc = ahci_platform_init_host(pdev, hpriv, &ahci_port_info, 0, 0);
- 	if (rc)
- 		goto pdata_exit;
- 
---- a/include/linux/ahci_platform.h
-+++ b/include/linux/ahci_platform.h
-@@ -33,9 +33,6 @@ struct ahci_platform_data {
- 	void (*exit)(struct device *dev);
- 	int (*suspend)(struct device *dev);
- 	int (*resume)(struct device *dev);
--	const struct ata_port_info *ata_port_info;
--	unsigned int force_port_map;
--	unsigned int mask_port_map;
- };
- 
- int ahci_platform_enable_clks(struct ahci_host_priv *hpriv);
diff --git a/target/linux/ipq806x/patches/0122-ata-ahci_platform-fix-devm_ioremap_resource-return-v.patch b/target/linux/ipq806x/patches/0122-ata-ahci_platform-fix-devm_ioremap_resource-return-v.patch
deleted file mode 100644
index 322a039..0000000
--- a/target/linux/ipq806x/patches/0122-ata-ahci_platform-fix-devm_ioremap_resource-return-v.patch
+++ /dev/null
@@ -1,41 +0,0 @@
-From 0db91c83bcb5f7307aaa16c093b8c6bb3f44be52 Mon Sep 17 00:00:00 2001
-From: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com>
-Date: Fri, 14 Mar 2014 18:22:09 +0100
-Subject: [PATCH 122/182] ata: ahci_platform: fix devm_ioremap_resource()
- return value checking
-
-devm_ioremap_resource() returns a pointer to the remapped memory or
-an ERR_PTR() encoded error code on failure.  Fix the check inside
-ahci_platform_get_resources() accordingly.
-
-Also while at it remove a needless line break.
-
-Signed-off-by: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com>
-Signed-off-by: Tejun Heo <tj@kernel.org>
----
- drivers/ata/ahci_platform.c |    6 +++---
- 1 file changed, 3 insertions(+), 3 deletions(-)
-
---- a/drivers/ata/ahci_platform.c
-+++ b/drivers/ata/ahci_platform.c
-@@ -199,8 +199,7 @@ static void ahci_platform_put_resources(
-  * 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 ahci_host_priv *ahci_platform_get_resources(struct platform_device *pdev)
- {
- 	struct device *dev = &pdev->dev;
- 	struct ahci_host_priv *hpriv;
-@@ -219,8 +218,9 @@ struct ahci_host_priv *ahci_platform_get
- 
- 	hpriv->mmio = devm_ioremap_resource(dev,
- 			      platform_get_resource(pdev, IORESOURCE_MEM, 0));
--	if (!hpriv->mmio) {
-+	if (IS_ERR(hpriv->mmio)) {
- 		dev_err(dev, "no mmio space\n");
-+		rc = PTR_ERR(hpriv->mmio);
- 		goto err_out;
- 	}
- 
diff --git a/target/linux/ipq806x/patches/0123-ata-ahci_platform-fix-ahci_platform_data-suspend-met.patch b/target/linux/ipq806x/patches/0123-ata-ahci_platform-fix-ahci_platform_data-suspend-met.patch
deleted file mode 100644
index 1a9e6d1..0000000
--- a/target/linux/ipq806x/patches/0123-ata-ahci_platform-fix-ahci_platform_data-suspend-met.patch
+++ /dev/null
@@ -1,45 +0,0 @@
-From bc26554ffa0223015edb474a4877ec544167dfba Mon Sep 17 00:00:00 2001
-From: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com>
-Date: Tue, 25 Mar 2014 19:51:38 +0100
-Subject: [PATCH 123/182] ata: ahci_platform: fix ahci_platform_data->suspend
- method handling
-
-Looking at ST SPEAr1340 AHCI code (the only user of the deprecated
-pdata->suspend and pdata->resume) it is obvious the we should return
-after calling pdata->suspend() only if the function have returned
-non-zero return value.  The code has been broken since commit 1e70c2
-("ata/ahci_platform: Add clock framework support").  Fix it.
-
-Cc: Viresh Kumar <viresh.linux@gmail.com>
-Cc: Shiraz Hashim <shiraz.hashim@st.com>
-Acked-by: Hans de Goede <hdegoede@redhat.com>
-Signed-off-by: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com>
-Signed-off-by: Tejun Heo <tj@kernel.org>
----
- drivers/ata/ahci_platform.c |   11 +++++++++--
- 1 file changed, 9 insertions(+), 2 deletions(-)
-
---- a/drivers/ata/ahci_platform.c
-+++ b/drivers/ata/ahci_platform.c
-@@ -521,12 +521,19 @@ int ahci_platform_suspend(struct device
- 	if (rc)
- 		return rc;
- 
--	if (pdata && pdata->suspend)
--		return pdata->suspend(dev);
-+	if (pdata && pdata->suspend) {
-+		rc = pdata->suspend(dev);
-+		if (rc)
-+			goto resume_host;
-+	}
- 
- 	ahci_platform_disable_resources(hpriv);
- 
- 	return 0;
-+
-+resume_host:
-+	ahci_platform_resume_host(dev);
-+	return rc;
- }
- EXPORT_SYMBOL_GPL(ahci_platform_suspend);
- 
diff --git a/target/linux/ipq806x/patches/0124-ata-move-library-code-from-ahci_platform.c-to-libahc.patch b/target/linux/ipq806x/patches/0124-ata-move-library-code-from-ahci_platform.c-to-libahc.patch
deleted file mode 100644
index eca606b..0000000
--- a/target/linux/ipq806x/patches/0124-ata-move-library-code-from-ahci_platform.c-to-libahc.patch
+++ /dev/null
@@ -1,1145 +0,0 @@
-From 04800db1047afbf6701379435bff1a6fa64215f7 Mon Sep 17 00:00:00 2001
-From: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com>
-Date: Tue, 25 Mar 2014 19:51:39 +0100
-Subject: [PATCH 124/182] ata: move library code from ahci_platform.c to
- libahci_platform.c
-
-Move AHCI platform library code from ahci_platform.c to
-libahci_platform.c and fix dependencies for ahci_st,
-ahci_imx and ahci_sunxi drivers.
-
-Acked-by: Hans de Goede <hdegoede@redhat.com>
-Signed-off-by: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com>
-Signed-off-by: Tejun Heo <tj@kernel.org>
-
-Conflicts:
-	drivers/ata/Kconfig
-	drivers/ata/Makefile
----
- drivers/ata/Kconfig            |    2 +-
- drivers/ata/Makefile           |    4 +-
- drivers/ata/ahci_platform.c    |  515 --------------------------------------
- drivers/ata/libahci_platform.c |  541 ++++++++++++++++++++++++++++++++++++++++
- 4 files changed, 544 insertions(+), 518 deletions(-)
- create mode 100644 drivers/ata/libahci_platform.c
-
---- a/drivers/ata/Kconfig
-+++ b/drivers/ata/Kconfig
-@@ -115,7 +115,7 @@ config SATA_AHCI_PLATFORM
- 
- config AHCI_IMX
- 	tristate "Freescale i.MX AHCI SATA support"
--	depends on SATA_AHCI_PLATFORM && MFD_SYSCON
-+	depends on MFD_SYSCON
- 	help
- 	  This option enables support for the Freescale i.MX SoC's
- 	  onboard AHCI SATA.
---- a/drivers/ata/Makefile
-+++ b/drivers/ata/Makefile
-@@ -4,13 +4,13 @@ obj-$(CONFIG_ATA)		+= libata.o
- # non-SFF interface
- obj-$(CONFIG_SATA_AHCI)		+= ahci.o libahci.o
- obj-$(CONFIG_SATA_ACARD_AHCI)	+= acard-ahci.o libahci.o
--obj-$(CONFIG_SATA_AHCI_PLATFORM) += ahci_platform.o libahci.o
-+obj-$(CONFIG_SATA_AHCI_PLATFORM) += ahci_platform.o libahci.o libahci_platform.o
- obj-$(CONFIG_SATA_FSL)		+= sata_fsl.o
- obj-$(CONFIG_SATA_INIC162X)	+= sata_inic162x.o
- 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_IMX)		+= ahci_imx.o libahci.o libahci_platform.o
- 
- # SFF w/ custom DMA
- obj-$(CONFIG_PDC_ADMA)		+= pdc_adma.o
---- a/drivers/ata/ahci_platform.c
-+++ b/drivers/ata/ahci_platform.c
-@@ -12,28 +12,15 @@
-  * any later version.
-  */
- 
--#include <linux/clk.h>
- #include <linux/kernel.h>
--#include <linux/gfp.h>
- #include <linux/module.h>
- #include <linux/pm.h>
--#include <linux/interrupt.h>
- #include <linux/device.h>
- #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);
--
--struct ata_port_operations ahci_platform_ops = {
--	.inherits	= &ahci_ops,
--	.host_stop	= ahci_host_stop,
--};
--EXPORT_SYMBOL_GPL(ahci_platform_ops);
--
- static const struct ata_port_info ahci_port_info = {
- 	.flags		= AHCI_FLAG_COMMON,
- 	.pio_mask	= ATA_PIO4,
-@@ -41,345 +28,6 @@ static const struct ata_port_info ahci_p
- 	.port_ops	= &ahci_platform_ops,
- };
- 
--static struct scsi_host_template ahci_platform_sht = {
--	AHCI_SHT("ahci_platform"),
--};
--
--/**
-- * 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.
-- *
-- * RETURNS:
-- * 0 on success otherwise a negative error code
-- */
--int ahci_platform_enable_clks(struct ahci_host_priv *hpriv)
--{
--	int c, rc;
--
--	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;
--
--disable_unprepare_clk:
--	while (--c >= 0)
--		clk_disable_unprepare(hpriv->clks[c]);
--	return rc;
--}
--EXPORT_SYMBOL_GPL(ahci_platform_enable_clks);
--
--/**
-- * 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).
-- */
--void ahci_platform_disable_clks(struct ahci_host_priv *hpriv)
--{
--	int c;
--
--	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)
-- * 3) Phy
-- *
-- * If resource enabling fails at any point the previous enabled resources
-- * are disabled in reverse order.
-- *
-- * 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;
--	}
--
--	rc = ahci_platform_enable_clks(hpriv);
--	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);
--	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) Phy
-- * 2) Clocks (through ahci_platform_disable_clks)
-- * 3) Regulator
-- */
--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)
--		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;
--
--	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]);
--}
--
--/**
-- * 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
-- *	4) phy (optional)
-- *
-- * 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 (IS_ERR(hpriv->mmio)) {
--		dev_err(dev, "no mmio space\n");
--		rc = PTR_ERR(hpriv->mmio);
--		goto err_out;
--	}
--
--	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;
--	}
--
--	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;
--
--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.
-- *
-- * 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;
--
--	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;
--
--	if (hpriv->cap & HOST_CAP_PMP)
--		pi.flags |= ATA_FLAG_PMP;
--
--	ahci_set_em_messages(hpriv, &pi);
--
--	/* CAP.NP sometimes indicate the index of the last enabled
--	 * port, at other times, that of the last possible port, so
--	 * determining the maximum port number requires looking at
--	 * both CAP.NP and port_map.
--	 */
--	n_ports = max(ahci_nr_ports(hpriv->cap), fls(hpriv->port_map));
--
--	host = ata_host_alloc_pinfo(dev, ppi, n_ports);
--	if (!host)
--		return -ENOMEM;
--
--	host->private_data = hpriv;
--
--	if (!(hpriv->cap & HOST_CAP_SSS) || ahci_ignore_sss)
--		host->flags |= ATA_HOST_PARALLEL_SCAN;
--	else
--		dev_info(dev, "SSS flag set, parallel bus scan disabled\n");
--
--	if (pi.flags & ATA_FLAG_EM)
--		ahci_reset_em(host);
--
--	for (i = 0; i < host->n_ports; i++) {
--		struct ata_port *ap = host->ports[i];
--
--		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 */
--		if (ap->flags & ATA_FLAG_EM)
--			ap->em_message_type = hpriv->em_msg_type;
--
--		/* disabled/not-implemented port */
--		if (!(hpriv->port_map & (1 << i)))
--			ap->ops = &ata_dummy_port_ops;
--	}
--
--	rc = ahci_reset_controller(host);
--	if (rc)
--		return rc;
--
--	ahci_init_controller(host);
--	ahci_print_info(host, "platform");
--
--	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;
-@@ -420,169 +68,6 @@ disable_resources:
- 	return rc;
- }
- 
--static void ahci_host_stop(struct ata_host *host)
--{
--	struct device *dev = host->dev;
--	struct ahci_platform_data *pdata = dev_get_platdata(dev);
--	struct ahci_host_priv *hpriv = host->private_data;
--
--	if (pdata && pdata->exit)
--		pdata->exit(dev);
--
--	ahci_platform_disable_resources(hpriv);
--}
--
--#ifdef CONFIG_PM_SLEEP
--/**
-- * 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.
-- *
-- * RETURNS:
-- * 0 on success otherwise a negative error code
-- */
--int ahci_platform_suspend_host(struct device *dev)
--{
--	struct ata_host *host = dev_get_drvdata(dev);
--	struct ahci_host_priv *hpriv = host->private_data;
--	void __iomem *mmio = hpriv->mmio;
--	u32 ctl;
--
--	if (hpriv->flags & AHCI_HFLAG_NO_SUSPEND) {
--		dev_err(dev, "firmware update required for suspend/resume\n");
--		return -EIO;
--	}
--
--	/*
--	 * AHCI spec rev1.1 section 8.3.3:
--	 * Software must disable interrupts prior to requesting a
--	 * transition of the HBA to D3 state.
--	 */
--	ctl = readl(mmio + HOST_CTL);
--	ctl &= ~HOST_IRQ_EN;
--	writel(ctl, mmio + HOST_CTL);
--	readl(mmio + HOST_CTL); /* flush */
--
--	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.
-- *
-- * 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.
-- *
-- * 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) {
--		rc = pdata->suspend(dev);
--		if (rc)
--			goto resume_host;
--	}
--
--	ahci_platform_disable_resources(hpriv);
--
--	return 0;
--
--resume_host:
--	ahci_platform_resume_host(dev);
--	return rc;
--}
--EXPORT_SYMBOL_GPL(ahci_platform_suspend);
--
--/**
-- * 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.
-- *
-- * 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;
--
--	rc = ahci_platform_enable_resources(hpriv);
--	if (rc)
--		return rc;
--
--	if (pdata && pdata->resume) {
--		rc = pdata->resume(dev);
--		if (rc)
--			goto disable_resources;
--	}
--
--	rc = ahci_platform_resume_host(dev);
--	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:
--	ahci_platform_disable_resources(hpriv);
--
--	return rc;
--}
--EXPORT_SYMBOL_GPL(ahci_platform_resume);
--#endif
--
- static SIMPLE_DEV_PM_OPS(ahci_pm_ops, ahci_platform_suspend,
- 			 ahci_platform_resume);
- 
---- /dev/null
-+++ b/drivers/ata/libahci_platform.c
-@@ -0,0 +1,541 @@
-+/*
-+ * AHCI SATA platform library
-+ *
-+ * Copyright 2004-2005  Red Hat, Inc.
-+ *   Jeff Garzik <jgarzik@pobox.com>
-+ * Copyright 2010  MontaVista Software, LLC.
-+ *   Anton Vorontsov <avorontsov@ru.mvista.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, or (at your option)
-+ * any later version.
-+ */
-+
-+#include <linux/clk.h>
-+#include <linux/kernel.h>
-+#include <linux/gfp.h>
-+#include <linux/module.h>
-+#include <linux/pm.h>
-+#include <linux/interrupt.h>
-+#include <linux/device.h>
-+#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);
-+
-+struct ata_port_operations ahci_platform_ops = {
-+	.inherits	= &ahci_ops,
-+	.host_stop	= ahci_host_stop,
-+};
-+EXPORT_SYMBOL_GPL(ahci_platform_ops);
-+
-+static struct scsi_host_template ahci_platform_sht = {
-+	AHCI_SHT("ahci_platform"),
-+};
-+
-+/**
-+ * 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.
-+ *
-+ * RETURNS:
-+ * 0 on success otherwise a negative error code
-+ */
-+int ahci_platform_enable_clks(struct ahci_host_priv *hpriv)
-+{
-+	int c, rc;
-+
-+	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;
-+
-+disable_unprepare_clk:
-+	while (--c >= 0)
-+		clk_disable_unprepare(hpriv->clks[c]);
-+	return rc;
-+}
-+EXPORT_SYMBOL_GPL(ahci_platform_enable_clks);
-+
-+/**
-+ * 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).
-+ */
-+void ahci_platform_disable_clks(struct ahci_host_priv *hpriv)
-+{
-+	int c;
-+
-+	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)
-+ * 3) Phy
-+ *
-+ * If resource enabling fails at any point the previous enabled resources
-+ * are disabled in reverse order.
-+ *
-+ * 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;
-+	}
-+
-+	rc = ahci_platform_enable_clks(hpriv);
-+	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);
-+	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) Phy
-+ * 2) Clocks (through ahci_platform_disable_clks)
-+ * 3) Regulator
-+ */
-+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)
-+		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;
-+
-+	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]);
-+}
-+
-+/**
-+ * 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
-+ *	4) phy (optional)
-+ *
-+ * 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 (IS_ERR(hpriv->mmio)) {
-+		dev_err(dev, "no mmio space\n");
-+		rc = PTR_ERR(hpriv->mmio);
-+		goto err_out;
-+	}
-+
-+	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;
-+	}
-+
-+	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;
-+
-+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.
-+ *
-+ * 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;
-+
-+	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;
-+
-+	if (hpriv->cap & HOST_CAP_PMP)
-+		pi.flags |= ATA_FLAG_PMP;
-+
-+	ahci_set_em_messages(hpriv, &pi);
-+
-+	/* CAP.NP sometimes indicate the index of the last enabled
-+	 * port, at other times, that of the last possible port, so
-+	 * determining the maximum port number requires looking at
-+	 * both CAP.NP and port_map.
-+	 */
-+	n_ports = max(ahci_nr_ports(hpriv->cap), fls(hpriv->port_map));
-+
-+	host = ata_host_alloc_pinfo(dev, ppi, n_ports);
-+	if (!host)
-+		return -ENOMEM;
-+
-+	host->private_data = hpriv;
-+
-+	if (!(hpriv->cap & HOST_CAP_SSS) || ahci_ignore_sss)
-+		host->flags |= ATA_HOST_PARALLEL_SCAN;
-+	else
-+		dev_info(dev, "SSS flag set, parallel bus scan disabled\n");
-+
-+	if (pi.flags & ATA_FLAG_EM)
-+		ahci_reset_em(host);
-+
-+	for (i = 0; i < host->n_ports; i++) {
-+		struct ata_port *ap = host->ports[i];
-+
-+		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 */
-+		if (ap->flags & ATA_FLAG_EM)
-+			ap->em_message_type = hpriv->em_msg_type;
-+
-+		/* disabled/not-implemented port */
-+		if (!(hpriv->port_map & (1 << i)))
-+			ap->ops = &ata_dummy_port_ops;
-+	}
-+
-+	rc = ahci_reset_controller(host);
-+	if (rc)
-+		return rc;
-+
-+	ahci_init_controller(host);
-+	ahci_print_info(host, "platform");
-+
-+	return ata_host_activate(host, irq, ahci_interrupt, IRQF_SHARED,
-+				 &ahci_platform_sht);
-+}
-+EXPORT_SYMBOL_GPL(ahci_platform_init_host);
-+
-+static void ahci_host_stop(struct ata_host *host)
-+{
-+	struct device *dev = host->dev;
-+	struct ahci_platform_data *pdata = dev_get_platdata(dev);
-+	struct ahci_host_priv *hpriv = host->private_data;
-+
-+	if (pdata && pdata->exit)
-+		pdata->exit(dev);
-+
-+	ahci_platform_disable_resources(hpriv);
-+}
-+
-+#ifdef CONFIG_PM_SLEEP
-+/**
-+ * 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.
-+ *
-+ * RETURNS:
-+ * 0 on success otherwise a negative error code
-+ */
-+int ahci_platform_suspend_host(struct device *dev)
-+{
-+	struct ata_host *host = dev_get_drvdata(dev);
-+	struct ahci_host_priv *hpriv = host->private_data;
-+	void __iomem *mmio = hpriv->mmio;
-+	u32 ctl;
-+
-+	if (hpriv->flags & AHCI_HFLAG_NO_SUSPEND) {
-+		dev_err(dev, "firmware update required for suspend/resume\n");
-+		return -EIO;
-+	}
-+
-+	/*
-+	 * AHCI spec rev1.1 section 8.3.3:
-+	 * Software must disable interrupts prior to requesting a
-+	 * transition of the HBA to D3 state.
-+	 */
-+	ctl = readl(mmio + HOST_CTL);
-+	ctl &= ~HOST_IRQ_EN;
-+	writel(ctl, mmio + HOST_CTL);
-+	readl(mmio + HOST_CTL); /* flush */
-+
-+	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.
-+ *
-+ * 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.
-+ *
-+ * 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) {
-+		rc = pdata->suspend(dev);
-+		if (rc)
-+			goto resume_host;
-+	}
-+
-+	ahci_platform_disable_resources(hpriv);
-+
-+	return 0;
-+
-+resume_host:
-+	ahci_platform_resume_host(dev);
-+	return rc;
-+}
-+EXPORT_SYMBOL_GPL(ahci_platform_suspend);
-+
-+/**
-+ * 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.
-+ *
-+ * 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;
-+
-+	rc = ahci_platform_enable_resources(hpriv);
-+	if (rc)
-+		return rc;
-+
-+	if (pdata && pdata->resume) {
-+		rc = pdata->resume(dev);
-+		if (rc)
-+			goto disable_resources;
-+	}
-+
-+	rc = ahci_platform_resume_host(dev);
-+	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:
-+	ahci_platform_disable_resources(hpriv);
-+
-+	return rc;
-+}
-+EXPORT_SYMBOL_GPL(ahci_platform_resume);
-+#endif
-+
-+MODULE_DESCRIPTION("AHCI SATA platform library");
-+MODULE_AUTHOR("Anton Vorontsov <avorontsov@ru.mvista.com>");
-+MODULE_LICENSE("GPL");
diff --git a/target/linux/ipq806x/patches/0125-clk-qcom-Add-support-for-IPQ8064-s-global-clock-cont.patch b/target/linux/ipq806x/patches/0125-clk-qcom-Add-support-for-IPQ8064-s-global-clock-cont.patch
deleted file mode 100644
index 4c4e263..0000000
--- a/target/linux/ipq806x/patches/0125-clk-qcom-Add-support-for-IPQ8064-s-global-clock-cont.patch
+++ /dev/null
@@ -1,2921 +0,0 @@
-From 2e6dfaa714ba4bd70fa5dda07c525b6c15e44552 Mon Sep 17 00:00:00 2001
-From: Kumar Gala <galak@codeaurora.org>
-Date: Thu, 3 Apr 2014 13:47:07 -0500
-Subject: [PATCH 125/182] clk: qcom: Add support for IPQ8064's global clock
- controller (GCC)
-
-Add a driver for the global clock controller found on IPQ8064 based
-platforms. This should allow most non-multimedia device drivers to probe
-and control their clocks.
-
-This is currently missing clocks for USB HSIC and networking devices.
-
-Signed-off-by: Kumar Gala <galak@codeaurora.org>
-Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
----
- .../devicetree/bindings/clock/qcom,gcc.txt         |    1 +
- drivers/clk/qcom/Kconfig                           |    8 +
- drivers/clk/qcom/Makefile                          |    1 +
- drivers/clk/qcom/gcc-ipq806x.c                     | 2424 ++++++++++++++++++++
- include/dt-bindings/clock/qcom,gcc-ipq806x.h       |  293 +++
- include/dt-bindings/reset/qcom,gcc-ipq806x.h       |  132 ++
- 6 files changed, 2859 insertions(+)
- create mode 100644 drivers/clk/qcom/gcc-ipq806x.c
- create mode 100644 include/dt-bindings/clock/qcom,gcc-ipq806x.h
- create mode 100644 include/dt-bindings/reset/qcom,gcc-ipq806x.h
-
---- a/Documentation/devicetree/bindings/clock/qcom,gcc.txt
-+++ b/Documentation/devicetree/bindings/clock/qcom,gcc.txt
-@@ -5,6 +5,7 @@ Required properties :
- - compatible : shall contain only one of the following:
- 
- 			"qcom,gcc-apq8064"
-+			"qcom,gcc-ipq8064"
- 			"qcom,gcc-msm8660"
- 			"qcom,gcc-msm8960"
- 			"qcom,gcc-msm8974"
---- a/drivers/clk/qcom/Kconfig
-+++ b/drivers/clk/qcom/Kconfig
-@@ -4,6 +4,14 @@ config COMMON_CLK_QCOM
- 	select REGMAP_MMIO
- 	select RESET_CONTROLLER
- 
-+config IPQ_GCC_806X
-+	tristate "IPQ806x Global Clock Controller"
-+	depends on COMMON_CLK_QCOM
-+	help
-+	  Support for the global clock controller on ipq806x devices.
-+	  Say Y if you want to use peripheral devices such as UART, SPI,
-+	  i2c, USB, SD/eMMC, etc.
-+
- config MSM_GCC_8660
- 	tristate "MSM8660 Global Clock Controller"
- 	depends on COMMON_CLK_QCOM
---- a/drivers/clk/qcom/Makefile
-+++ b/drivers/clk/qcom/Makefile
-@@ -8,6 +8,7 @@ clk-qcom-y += clk-rcg2.o
- clk-qcom-y += clk-branch.o
- clk-qcom-y += reset.o
- 
-+obj-$(CONFIG_IPQ_GCC_806X) += gcc-ipq806x.o
- obj-$(CONFIG_MSM_GCC_8660) += gcc-msm8660.o
- obj-$(CONFIG_MSM_GCC_8960) += gcc-msm8960.o
- obj-$(CONFIG_MSM_GCC_8974) += gcc-msm8974.o
---- /dev/null
-+++ b/drivers/clk/qcom/gcc-ipq806x.c
-@@ -0,0 +1,2424 @@
-+/*
-+ * Copyright (c) 2014, The Linux Foundation. All rights reserved.
-+ *
-+ * This software is licensed under the terms of the GNU General Public
-+ * License version 2, as published by the Free Software Foundation, and
-+ * may be copied, distributed, and modified under those terms.
-+ *
-+ * 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/kernel.h>
-+#include <linux/bitops.h>
-+#include <linux/err.h>
-+#include <linux/platform_device.h>
-+#include <linux/module.h>
-+#include <linux/of.h>
-+#include <linux/of_device.h>
-+#include <linux/clk-provider.h>
-+#include <linux/regmap.h>
-+#include <linux/reset-controller.h>
-+
-+#include <dt-bindings/clock/qcom,gcc-ipq806x.h>
-+#include <dt-bindings/reset/qcom,gcc-ipq806x.h>
-+
-+#include "common.h"
-+#include "clk-regmap.h"
-+#include "clk-pll.h"
-+#include "clk-rcg.h"
-+#include "clk-branch.h"
-+#include "reset.h"
-+
-+static struct clk_pll pll3 = {
-+	.l_reg = 0x3164,
-+	.m_reg = 0x3168,
-+	.n_reg = 0x316c,
-+	.config_reg = 0x3174,
-+	.mode_reg = 0x3160,
-+	.status_reg = 0x3178,
-+	.status_bit = 16,
-+	.clkr.hw.init = &(struct clk_init_data){
-+		.name = "pll3",
-+		.parent_names = (const char *[]){ "pxo" },
-+		.num_parents = 1,
-+		.ops = &clk_pll_ops,
-+	},
-+};
-+
-+static struct clk_pll pll8 = {
-+	.l_reg = 0x3144,
-+	.m_reg = 0x3148,
-+	.n_reg = 0x314c,
-+	.config_reg = 0x3154,
-+	.mode_reg = 0x3140,
-+	.status_reg = 0x3158,
-+	.status_bit = 16,
-+	.clkr.hw.init = &(struct clk_init_data){
-+		.name = "pll8",
-+		.parent_names = (const char *[]){ "pxo" },
-+		.num_parents = 1,
-+		.ops = &clk_pll_ops,
-+	},
-+};
-+
-+static struct clk_regmap pll8_vote = {
-+	.enable_reg = 0x34c0,
-+	.enable_mask = BIT(8),
-+	.hw.init = &(struct clk_init_data){
-+		.name = "pll8_vote",
-+		.parent_names = (const char *[]){ "pll8" },
-+		.num_parents = 1,
-+		.ops = &clk_pll_vote_ops,
-+	},
-+};
-+
-+static struct clk_pll pll14 = {
-+	.l_reg = 0x31c4,
-+	.m_reg = 0x31c8,
-+	.n_reg = 0x31cc,
-+	.config_reg = 0x31d4,
-+	.mode_reg = 0x31c0,
-+	.status_reg = 0x31d8,
-+	.status_bit = 16,
-+	.clkr.hw.init = &(struct clk_init_data){
-+		.name = "pll14",
-+		.parent_names = (const char *[]){ "pxo" },
-+		.num_parents = 1,
-+		.ops = &clk_pll_ops,
-+	},
-+};
-+
-+static struct clk_regmap pll14_vote = {
-+	.enable_reg = 0x34c0,
-+	.enable_mask = BIT(14),
-+	.hw.init = &(struct clk_init_data){
-+		.name = "pll14_vote",
-+		.parent_names = (const char *[]){ "pll14" },
-+		.num_parents = 1,
-+		.ops = &clk_pll_vote_ops,
-+	},
-+};
-+
-+#define P_PXO	0
-+#define P_PLL8	1
-+#define P_PLL3	1
-+#define P_PLL0	2
-+#define P_CXO	2
-+
-+static const u8 gcc_pxo_pll8_map[] = {
-+	[P_PXO]		= 0,
-+	[P_PLL8]	= 3,
-+};
-+
-+static const char *gcc_pxo_pll8[] = {
-+	"pxo",
-+	"pll8_vote",
-+};
-+
-+static const u8 gcc_pxo_pll8_cxo_map[] = {
-+	[P_PXO]		= 0,
-+	[P_PLL8]	= 3,
-+	[P_CXO]		= 5,
-+};
-+
-+static const char *gcc_pxo_pll8_cxo[] = {
-+	"pxo",
-+	"pll8_vote",
-+	"cxo",
-+};
-+
-+static const u8 gcc_pxo_pll3_map[] = {
-+	[P_PXO]		= 0,
-+	[P_PLL3]	= 1,
-+};
-+
-+static const u8 gcc_pxo_pll3_sata_map[] = {
-+	[P_PXO]		= 0,
-+	[P_PLL3]	= 6,
-+};
-+
-+static const char *gcc_pxo_pll3[] = {
-+	"pxo",
-+	"pll3",
-+};
-+
-+static const u8 gcc_pxo_pll8_pll0[] = {
-+	[P_PXO]		= 0,
-+	[P_PLL8]	= 3,
-+	[P_PLL0]	= 2,
-+};
-+
-+static const char *gcc_pxo_pll8_pll0_map[] = {
-+	"pxo",
-+	"pll8_vote",
-+	"pll0",
-+};
-+
-+static struct freq_tbl clk_tbl_gsbi_uart[] = {
-+	{  1843200, P_PLL8, 2,  6, 625 },
-+	{  3686400, P_PLL8, 2, 12, 625 },
-+	{  7372800, P_PLL8, 2, 24, 625 },
-+	{ 14745600, P_PLL8, 2, 48, 625 },
-+	{ 16000000, P_PLL8, 4,  1,   6 },
-+	{ 24000000, P_PLL8, 4,  1,   4 },
-+	{ 32000000, P_PLL8, 4,  1,   3 },
-+	{ 40000000, P_PLL8, 1,  5,  48 },
-+	{ 46400000, P_PLL8, 1, 29, 240 },
-+	{ 48000000, P_PLL8, 4,  1,   2 },
-+	{ 51200000, P_PLL8, 1,  2,  15 },
-+	{ 56000000, P_PLL8, 1,  7,  48 },
-+	{ 58982400, P_PLL8, 1, 96, 625 },
-+	{ 64000000, P_PLL8, 2,  1,   3 },
-+	{ }
-+};
-+
-+static struct clk_rcg gsbi1_uart_src = {
-+	.ns_reg = 0x29d4,
-+	.md_reg = 0x29d0,
-+	.mn = {
-+		.mnctr_en_bit = 8,
-+		.mnctr_reset_bit = 7,
-+		.mnctr_mode_shift = 5,
-+		.n_val_shift = 16,
-+		.m_val_shift = 16,
-+		.width = 16,
-+	},
-+	.p = {
-+		.pre_div_shift = 3,
-+		.pre_div_width = 2,
-+	},
-+	.s = {
-+		.src_sel_shift = 0,
-+		.parent_map = gcc_pxo_pll8_map,
-+	},
-+	.freq_tbl = clk_tbl_gsbi_uart,
-+	.clkr = {
-+		.enable_reg = 0x29d4,
-+		.enable_mask = BIT(11),
-+		.hw.init = &(struct clk_init_data){
-+			.name = "gsbi1_uart_src",
-+			.parent_names = gcc_pxo_pll8,
-+			.num_parents = 2,
-+			.ops = &clk_rcg_ops,
-+			.flags = CLK_SET_PARENT_GATE,
-+		},
-+	},
-+};
-+
-+static struct clk_branch gsbi1_uart_clk = {
-+	.halt_reg = 0x2fcc,
-+	.halt_bit = 12,
-+	.clkr = {
-+		.enable_reg = 0x29d4,
-+		.enable_mask = BIT(9),
-+		.hw.init = &(struct clk_init_data){
-+			.name = "gsbi1_uart_clk",
-+			.parent_names = (const char *[]){
-+				"gsbi1_uart_src",
-+			},
-+			.num_parents = 1,
-+			.ops = &clk_branch_ops,
-+			.flags = CLK_SET_RATE_PARENT,
-+		},
-+	},
-+};
-+
-+static struct clk_rcg gsbi2_uart_src = {
-+	.ns_reg = 0x29f4,
-+	.md_reg = 0x29f0,
-+	.mn = {
-+		.mnctr_en_bit = 8,
-+		.mnctr_reset_bit = 7,
-+		.mnctr_mode_shift = 5,
-+		.n_val_shift = 16,
-+		.m_val_shift = 16,
-+		.width = 16,
-+	},
-+	.p = {
-+		.pre_div_shift = 3,
-+		.pre_div_width = 2,
-+	},
-+	.s = {
-+		.src_sel_shift = 0,
-+		.parent_map = gcc_pxo_pll8_map,
-+	},
-+	.freq_tbl = clk_tbl_gsbi_uart,
-+	.clkr = {
-+		.enable_reg = 0x29f4,
-+		.enable_mask = BIT(11),
-+		.hw.init = &(struct clk_init_data){
-+			.name = "gsbi2_uart_src",
-+			.parent_names = gcc_pxo_pll8,
-+			.num_parents = 2,
-+			.ops = &clk_rcg_ops,
-+			.flags = CLK_SET_PARENT_GATE,
-+		},
-+	},
-+};
-+
-+static struct clk_branch gsbi2_uart_clk = {
-+	.halt_reg = 0x2fcc,
-+	.halt_bit = 8,
-+	.clkr = {
-+		.enable_reg = 0x29f4,
-+		.enable_mask = BIT(9),
-+		.hw.init = &(struct clk_init_data){
-+			.name = "gsbi2_uart_clk",
-+			.parent_names = (const char *[]){
-+				"gsbi2_uart_src",
-+			},
-+			.num_parents = 1,
-+			.ops = &clk_branch_ops,
-+			.flags = CLK_SET_RATE_PARENT,
-+		},
-+	},
-+};
-+
-+static struct clk_rcg gsbi4_uart_src = {
-+	.ns_reg = 0x2a34,
-+	.md_reg = 0x2a30,
-+	.mn = {
-+		.mnctr_en_bit = 8,
-+		.mnctr_reset_bit = 7,
-+		.mnctr_mode_shift = 5,
-+		.n_val_shift = 16,
-+		.m_val_shift = 16,
-+		.width = 16,
-+	},
-+	.p = {
-+		.pre_div_shift = 3,
-+		.pre_div_width = 2,
-+	},
-+	.s = {
-+		.src_sel_shift = 0,
-+		.parent_map = gcc_pxo_pll8_map,
-+	},
-+	.freq_tbl = clk_tbl_gsbi_uart,
-+	.clkr = {
-+		.enable_reg = 0x2a34,
-+		.enable_mask = BIT(11),
-+		.hw.init = &(struct clk_init_data){
-+			.name = "gsbi4_uart_src",
-+			.parent_names = gcc_pxo_pll8,
-+			.num_parents = 2,
-+			.ops = &clk_rcg_ops,
-+			.flags = CLK_SET_PARENT_GATE,
-+		},
-+	},
-+};
-+
-+static struct clk_branch gsbi4_uart_clk = {
-+	.halt_reg = 0x2fd0,
-+	.halt_bit = 26,
-+	.clkr = {
-+		.enable_reg = 0x2a34,
-+		.enable_mask = BIT(9),
-+		.hw.init = &(struct clk_init_data){
-+			.name = "gsbi4_uart_clk",
-+			.parent_names = (const char *[]){
-+				"gsbi4_uart_src",
-+			},
-+			.num_parents = 1,
-+			.ops = &clk_branch_ops,
-+			.flags = CLK_SET_RATE_PARENT,
-+		},
-+	},
-+};
-+
-+static struct clk_rcg gsbi5_uart_src = {
-+	.ns_reg = 0x2a54,
-+	.md_reg = 0x2a50,
-+	.mn = {
-+		.mnctr_en_bit = 8,
-+		.mnctr_reset_bit = 7,
-+		.mnctr_mode_shift = 5,
-+		.n_val_shift = 16,
-+		.m_val_shift = 16,
-+		.width = 16,
-+	},
-+	.p = {
-+		.pre_div_shift = 3,
-+		.pre_div_width = 2,
-+	},
-+	.s = {
-+		.src_sel_shift = 0,
-+		.parent_map = gcc_pxo_pll8_map,
-+	},
-+	.freq_tbl = clk_tbl_gsbi_uart,
-+	.clkr = {
-+		.enable_reg = 0x2a54,
-+		.enable_mask = BIT(11),
-+		.hw.init = &(struct clk_init_data){
-+			.name = "gsbi5_uart_src",
-+			.parent_names = gcc_pxo_pll8,
-+			.num_parents = 2,
-+			.ops = &clk_rcg_ops,
-+			.flags = CLK_SET_PARENT_GATE,
-+		},
-+	},
-+};
-+
-+static struct clk_branch gsbi5_uart_clk = {
-+	.halt_reg = 0x2fd0,
-+	.halt_bit = 22,
-+	.clkr = {
-+		.enable_reg = 0x2a54,
-+		.enable_mask = BIT(9),
-+		.hw.init = &(struct clk_init_data){
-+			.name = "gsbi5_uart_clk",
-+			.parent_names = (const char *[]){
-+				"gsbi5_uart_src",
-+			},
-+			.num_parents = 1,
-+			.ops = &clk_branch_ops,
-+			.flags = CLK_SET_RATE_PARENT,
-+		},
-+	},
-+};
-+
-+static struct clk_rcg gsbi6_uart_src = {
-+	.ns_reg = 0x2a74,
-+	.md_reg = 0x2a70,
-+	.mn = {
-+		.mnctr_en_bit = 8,
-+		.mnctr_reset_bit = 7,
-+		.mnctr_mode_shift = 5,
-+		.n_val_shift = 16,
-+		.m_val_shift = 16,
-+		.width = 16,
-+	},
-+	.p = {
-+		.pre_div_shift = 3,
-+		.pre_div_width = 2,
-+	},
-+	.s = {
-+		.src_sel_shift = 0,
-+		.parent_map = gcc_pxo_pll8_map,
-+	},
-+	.freq_tbl = clk_tbl_gsbi_uart,
-+	.clkr = {
-+		.enable_reg = 0x2a74,
-+		.enable_mask = BIT(11),
-+		.hw.init = &(struct clk_init_data){
-+			.name = "gsbi6_uart_src",
-+			.parent_names = gcc_pxo_pll8,
-+			.num_parents = 2,
-+			.ops = &clk_rcg_ops,
-+			.flags = CLK_SET_PARENT_GATE,
-+		},
-+	},
-+};
-+
-+static struct clk_branch gsbi6_uart_clk = {
-+	.halt_reg = 0x2fd0,
-+	.halt_bit = 18,
-+	.clkr = {
-+		.enable_reg = 0x2a74,
-+		.enable_mask = BIT(9),
-+		.hw.init = &(struct clk_init_data){
-+			.name = "gsbi6_uart_clk",
-+			.parent_names = (const char *[]){
-+				"gsbi6_uart_src",
-+			},
-+			.num_parents = 1,
-+			.ops = &clk_branch_ops,
-+			.flags = CLK_SET_RATE_PARENT,
-+		},
-+	},
-+};
-+
-+static struct clk_rcg gsbi7_uart_src = {
-+	.ns_reg = 0x2a94,
-+	.md_reg = 0x2a90,
-+	.mn = {
-+		.mnctr_en_bit = 8,
-+		.mnctr_reset_bit = 7,
-+		.mnctr_mode_shift = 5,
-+		.n_val_shift = 16,
-+		.m_val_shift = 16,
-+		.width = 16,
-+	},
-+	.p = {
-+		.pre_div_shift = 3,
-+		.pre_div_width = 2,
-+	},
-+	.s = {
-+		.src_sel_shift = 0,
-+		.parent_map = gcc_pxo_pll8_map,
-+	},
-+	.freq_tbl = clk_tbl_gsbi_uart,
-+	.clkr = {
-+		.enable_reg = 0x2a94,
-+		.enable_mask = BIT(11),
-+		.hw.init = &(struct clk_init_data){
-+			.name = "gsbi7_uart_src",
-+			.parent_names = gcc_pxo_pll8,
-+			.num_parents = 2,
-+			.ops = &clk_rcg_ops,
-+			.flags = CLK_SET_PARENT_GATE,
-+		},
-+	},
-+};
-+
-+static struct clk_branch gsbi7_uart_clk = {
-+	.halt_reg = 0x2fd0,
-+	.halt_bit = 14,
-+	.clkr = {
-+		.enable_reg = 0x2a94,
-+		.enable_mask = BIT(9),
-+		.hw.init = &(struct clk_init_data){
-+			.name = "gsbi7_uart_clk",
-+			.parent_names = (const char *[]){
-+				"gsbi7_uart_src",
-+			},
-+			.num_parents = 1,
-+			.ops = &clk_branch_ops,
-+			.flags = CLK_SET_RATE_PARENT,
-+		},
-+	},
-+};
-+
-+static struct freq_tbl clk_tbl_gsbi_qup[] = {
-+	{  1100000, P_PXO,  1, 2, 49 },
-+	{  5400000, P_PXO,  1, 1,  5 },
-+	{ 10800000, P_PXO,  1, 2,  5 },
-+	{ 15060000, P_PLL8, 1, 2, 51 },
-+	{ 24000000, P_PLL8, 4, 1,  4 },
-+	{ 25600000, P_PLL8, 1, 1, 15 },
-+	{ 27000000, P_PXO,  1, 0,  0 },
-+	{ 48000000, P_PLL8, 4, 1,  2 },
-+	{ 51200000, P_PLL8, 1, 2, 15 },
-+	{ }
-+};
-+
-+static struct clk_rcg gsbi1_qup_src = {
-+	.ns_reg = 0x29cc,
-+	.md_reg = 0x29c8,
-+	.mn = {
-+		.mnctr_en_bit = 8,
-+		.mnctr_reset_bit = 7,
-+		.mnctr_mode_shift = 5,
-+		.n_val_shift = 16,
-+		.m_val_shift = 16,
-+		.width = 8,
-+	},
-+	.p = {
-+		.pre_div_shift = 3,
-+		.pre_div_width = 2,
-+	},
-+	.s = {
-+		.src_sel_shift = 0,
-+		.parent_map = gcc_pxo_pll8_map,
-+	},
-+	.freq_tbl = clk_tbl_gsbi_qup,
-+	.clkr = {
-+		.enable_reg = 0x29cc,
-+		.enable_mask = BIT(11),
-+		.hw.init = &(struct clk_init_data){
-+			.name = "gsbi1_qup_src",
-+			.parent_names = gcc_pxo_pll8,
-+			.num_parents = 2,
-+			.ops = &clk_rcg_ops,
-+			.flags = CLK_SET_PARENT_GATE,
-+		},
-+	},
-+};
-+
-+static struct clk_branch gsbi1_qup_clk = {
-+	.halt_reg = 0x2fcc,
-+	.halt_bit = 11,
-+	.clkr = {
-+		.enable_reg = 0x29cc,
-+		.enable_mask = BIT(9),
-+		.hw.init = &(struct clk_init_data){
-+			.name = "gsbi1_qup_clk",
-+			.parent_names = (const char *[]){ "gsbi1_qup_src" },
-+			.num_parents = 1,
-+			.ops = &clk_branch_ops,
-+			.flags = CLK_SET_RATE_PARENT,
-+		},
-+	},
-+};
-+
-+static struct clk_rcg gsbi2_qup_src = {
-+	.ns_reg = 0x29ec,
-+	.md_reg = 0x29e8,
-+	.mn = {
-+		.mnctr_en_bit = 8,
-+		.mnctr_reset_bit = 7,
-+		.mnctr_mode_shift = 5,
-+		.n_val_shift = 16,
-+		.m_val_shift = 16,
-+		.width = 8,
-+	},
-+	.p = {
-+		.pre_div_shift = 3,
-+		.pre_div_width = 2,
-+	},
-+	.s = {
-+		.src_sel_shift = 0,
-+		.parent_map = gcc_pxo_pll8_map,
-+	},
-+	.freq_tbl = clk_tbl_gsbi_qup,
-+	.clkr = {
-+		.enable_reg = 0x29ec,
-+		.enable_mask = BIT(11),
-+		.hw.init = &(struct clk_init_data){
-+			.name = "gsbi2_qup_src",
-+			.parent_names = gcc_pxo_pll8,
-+			.num_parents = 2,
-+			.ops = &clk_rcg_ops,
-+			.flags = CLK_SET_PARENT_GATE,
-+		},
-+	},
-+};
-+
-+static struct clk_branch gsbi2_qup_clk = {
-+	.halt_reg = 0x2fcc,
-+	.halt_bit = 6,
-+	.clkr = {
-+		.enable_reg = 0x29ec,
-+		.enable_mask = BIT(9),
-+		.hw.init = &(struct clk_init_data){
-+			.name = "gsbi2_qup_clk",
-+			.parent_names = (const char *[]){ "gsbi2_qup_src" },
-+			.num_parents = 1,
-+			.ops = &clk_branch_ops,
-+			.flags = CLK_SET_RATE_PARENT,
-+		},
-+	},
-+};
-+
-+static struct clk_rcg gsbi4_qup_src = {
-+	.ns_reg = 0x2a2c,
-+	.md_reg = 0x2a28,
-+	.mn = {
-+		.mnctr_en_bit = 8,
-+		.mnctr_reset_bit = 7,
-+		.mnctr_mode_shift = 5,
-+		.n_val_shift = 16,
-+		.m_val_shift = 16,
-+		.width = 8,
-+	},
-+	.p = {
-+		.pre_div_shift = 3,
-+		.pre_div_width = 2,
-+	},
-+	.s = {
-+		.src_sel_shift = 0,
-+		.parent_map = gcc_pxo_pll8_map,
-+	},
-+	.freq_tbl = clk_tbl_gsbi_qup,
-+	.clkr = {
-+		.enable_reg = 0x2a2c,
-+		.enable_mask = BIT(11),
-+		.hw.init = &(struct clk_init_data){
-+			.name = "gsbi4_qup_src",
-+			.parent_names = gcc_pxo_pll8,
-+			.num_parents = 2,
-+			.ops = &clk_rcg_ops,
-+			.flags = CLK_SET_PARENT_GATE,
-+		},
-+	},
-+};
-+
-+static struct clk_branch gsbi4_qup_clk = {
-+	.halt_reg = 0x2fd0,
-+	.halt_bit = 24,
-+	.clkr = {
-+		.enable_reg = 0x2a2c,
-+		.enable_mask = BIT(9),
-+		.hw.init = &(struct clk_init_data){
-+			.name = "gsbi4_qup_clk",
-+			.parent_names = (const char *[]){ "gsbi4_qup_src" },
-+			.num_parents = 1,
-+			.ops = &clk_branch_ops,
-+			.flags = CLK_SET_RATE_PARENT,
-+		},
-+	},
-+};
-+
-+static struct clk_rcg gsbi5_qup_src = {
-+	.ns_reg = 0x2a4c,
-+	.md_reg = 0x2a48,
-+	.mn = {
-+		.mnctr_en_bit = 8,
-+		.mnctr_reset_bit = 7,
-+		.mnctr_mode_shift = 5,
-+		.n_val_shift = 16,
-+		.m_val_shift = 16,
-+		.width = 8,
-+	},
-+	.p = {
-+		.pre_div_shift = 3,
-+		.pre_div_width = 2,
-+	},
-+	.s = {
-+		.src_sel_shift = 0,
-+		.parent_map = gcc_pxo_pll8_map,
-+	},
-+	.freq_tbl = clk_tbl_gsbi_qup,
-+	.clkr = {
-+		.enable_reg = 0x2a4c,
-+		.enable_mask = BIT(11),
-+		.hw.init = &(struct clk_init_data){
-+			.name = "gsbi5_qup_src",
-+			.parent_names = gcc_pxo_pll8,
-+			.num_parents = 2,
-+			.ops = &clk_rcg_ops,
-+			.flags = CLK_SET_PARENT_GATE,
-+		},
-+	},
-+};
-+
-+static struct clk_branch gsbi5_qup_clk = {
-+	.halt_reg = 0x2fd0,
-+	.halt_bit = 20,
-+	.clkr = {
-+		.enable_reg = 0x2a4c,
-+		.enable_mask = BIT(9),
-+		.hw.init = &(struct clk_init_data){
-+			.name = "gsbi5_qup_clk",
-+			.parent_names = (const char *[]){ "gsbi5_qup_src" },
-+			.num_parents = 1,
-+			.ops = &clk_branch_ops,
-+			.flags = CLK_SET_RATE_PARENT,
-+		},
-+	},
-+};
-+
-+static struct clk_rcg gsbi6_qup_src = {
-+	.ns_reg = 0x2a6c,
-+	.md_reg = 0x2a68,
-+	.mn = {
-+		.mnctr_en_bit = 8,
-+		.mnctr_reset_bit = 7,
-+		.mnctr_mode_shift = 5,
-+		.n_val_shift = 16,
-+		.m_val_shift = 16,
-+		.width = 8,
-+	},
-+	.p = {
-+		.pre_div_shift = 3,
-+		.pre_div_width = 2,
-+	},
-+	.s = {
-+		.src_sel_shift = 0,
-+		.parent_map = gcc_pxo_pll8_map,
-+	},
-+	.freq_tbl = clk_tbl_gsbi_qup,
-+	.clkr = {
-+		.enable_reg = 0x2a6c,
-+		.enable_mask = BIT(11),
-+		.hw.init = &(struct clk_init_data){
-+			.name = "gsbi6_qup_src",
-+			.parent_names = gcc_pxo_pll8,
-+			.num_parents = 2,
-+			.ops = &clk_rcg_ops,
-+			.flags = CLK_SET_PARENT_GATE,
-+		},
-+	},
-+};
-+
-+static struct clk_branch gsbi6_qup_clk = {
-+	.halt_reg = 0x2fd0,
-+	.halt_bit = 16,
-+	.clkr = {
-+		.enable_reg = 0x2a6c,
-+		.enable_mask = BIT(9),
-+		.hw.init = &(struct clk_init_data){
-+			.name = "gsbi6_qup_clk",
-+			.parent_names = (const char *[]){ "gsbi6_qup_src" },
-+			.num_parents = 1,
-+			.ops = &clk_branch_ops,
-+			.flags = CLK_SET_RATE_PARENT,
-+		},
-+	},
-+};
-+
-+static struct clk_rcg gsbi7_qup_src = {
-+	.ns_reg = 0x2a8c,
-+	.md_reg = 0x2a88,
-+	.mn = {
-+		.mnctr_en_bit = 8,
-+		.mnctr_reset_bit = 7,
-+		.mnctr_mode_shift = 5,
-+		.n_val_shift = 16,
-+		.m_val_shift = 16,
-+		.width = 8,
-+	},
-+	.p = {
-+		.pre_div_shift = 3,
-+		.pre_div_width = 2,
-+	},
-+	.s = {
-+		.src_sel_shift = 0,
-+		.parent_map = gcc_pxo_pll8_map,
-+	},
-+	.freq_tbl = clk_tbl_gsbi_qup,
-+	.clkr = {
-+		.enable_reg = 0x2a8c,
-+		.enable_mask = BIT(11),
-+		.hw.init = &(struct clk_init_data){
-+			.name = "gsbi7_qup_src",
-+			.parent_names = gcc_pxo_pll8,
-+			.num_parents = 2,
-+			.ops = &clk_rcg_ops,
-+			.flags = CLK_SET_PARENT_GATE,
-+		},
-+	},
-+};
-+
-+static struct clk_branch gsbi7_qup_clk = {
-+	.halt_reg = 0x2fd0,
-+	.halt_bit = 12,
-+	.clkr = {
-+		.enable_reg = 0x2a8c,
-+		.enable_mask = BIT(9),
-+		.hw.init = &(struct clk_init_data){
-+			.name = "gsbi7_qup_clk",
-+			.parent_names = (const char *[]){ "gsbi7_qup_src" },
-+			.num_parents = 1,
-+			.ops = &clk_branch_ops,
-+			.flags = CLK_SET_RATE_PARENT,
-+		},
-+	},
-+};
-+
-+static struct clk_branch gsbi1_h_clk = {
-+	.hwcg_reg = 0x29c0,
-+	.hwcg_bit = 6,
-+	.halt_reg = 0x2fcc,
-+	.halt_bit = 13,
-+	.clkr = {
-+		.enable_reg = 0x29c0,
-+		.enable_mask = BIT(4),
-+		.hw.init = &(struct clk_init_data){
-+			.name = "gsbi1_h_clk",
-+			.ops = &clk_branch_ops,
-+			.flags = CLK_IS_ROOT,
-+		},
-+	},
-+};
-+
-+static struct clk_branch gsbi2_h_clk = {
-+	.hwcg_reg = 0x29e0,
-+	.hwcg_bit = 6,
-+	.halt_reg = 0x2fcc,
-+	.halt_bit = 9,
-+	.clkr = {
-+		.enable_reg = 0x29e0,
-+		.enable_mask = BIT(4),
-+		.hw.init = &(struct clk_init_data){
-+			.name = "gsbi2_h_clk",
-+			.ops = &clk_branch_ops,
-+			.flags = CLK_IS_ROOT,
-+		},
-+	},
-+};
-+
-+static struct clk_branch gsbi4_h_clk = {
-+	.hwcg_reg = 0x2a20,
-+	.hwcg_bit = 6,
-+	.halt_reg = 0x2fd0,
-+	.halt_bit = 27,
-+	.clkr = {
-+		.enable_reg = 0x2a20,
-+		.enable_mask = BIT(4),
-+		.hw.init = &(struct clk_init_data){
-+			.name = "gsbi4_h_clk",
-+			.ops = &clk_branch_ops,
-+			.flags = CLK_IS_ROOT,
-+		},
-+	},
-+};
-+
-+static struct clk_branch gsbi5_h_clk = {
-+	.hwcg_reg = 0x2a40,
-+	.hwcg_bit = 6,
-+	.halt_reg = 0x2fd0,
-+	.halt_bit = 23,
-+	.clkr = {
-+		.enable_reg = 0x2a40,
-+		.enable_mask = BIT(4),
-+		.hw.init = &(struct clk_init_data){
-+			.name = "gsbi5_h_clk",
-+			.ops = &clk_branch_ops,
-+			.flags = CLK_IS_ROOT,
-+		},
-+	},
-+};
-+
-+static struct clk_branch gsbi6_h_clk = {
-+	.hwcg_reg = 0x2a60,
-+	.hwcg_bit = 6,
-+	.halt_reg = 0x2fd0,
-+	.halt_bit = 19,
-+	.clkr = {
-+		.enable_reg = 0x2a60,
-+		.enable_mask = BIT(4),
-+		.hw.init = &(struct clk_init_data){
-+			.name = "gsbi6_h_clk",
-+			.ops = &clk_branch_ops,
-+			.flags = CLK_IS_ROOT,
-+		},
-+	},
-+};
-+
-+static struct clk_branch gsbi7_h_clk = {
-+	.hwcg_reg = 0x2a80,
-+	.hwcg_bit = 6,
-+	.halt_reg = 0x2fd0,
-+	.halt_bit = 15,
-+	.clkr = {
-+		.enable_reg = 0x2a80,
-+		.enable_mask = BIT(4),
-+		.hw.init = &(struct clk_init_data){
-+			.name = "gsbi7_h_clk",
-+			.ops = &clk_branch_ops,
-+			.flags = CLK_IS_ROOT,
-+		},
-+	},
-+};
-+
-+static const struct freq_tbl clk_tbl_gp[] = {
-+	{ 12500000, P_PXO,  2, 0, 0 },
-+	{ 25000000, P_PXO,  1, 0, 0 },
-+	{ 64000000, P_PLL8, 2, 1, 3 },
-+	{ 76800000, P_PLL8, 1, 1, 5 },
-+	{ 96000000, P_PLL8, 4, 0, 0 },
-+	{ 128000000, P_PLL8, 3, 0, 0 },
-+	{ 192000000, P_PLL8, 2, 0, 0 },
-+	{ }
-+};
-+
-+static struct clk_rcg gp0_src = {
-+	.ns_reg = 0x2d24,
-+	.md_reg = 0x2d00,
-+	.mn = {
-+		.mnctr_en_bit = 8,
-+		.mnctr_reset_bit = 7,
-+		.mnctr_mode_shift = 5,
-+		.n_val_shift = 16,
-+		.m_val_shift = 16,
-+		.width = 8,
-+	},
-+	.p = {
-+		.pre_div_shift = 3,
-+		.pre_div_width = 2,
-+	},
-+	.s = {
-+		.src_sel_shift = 0,
-+		.parent_map = gcc_pxo_pll8_cxo_map,
-+	},
-+	.freq_tbl = clk_tbl_gp,
-+	.clkr = {
-+		.enable_reg = 0x2d24,
-+		.enable_mask = BIT(11),
-+		.hw.init = &(struct clk_init_data){
-+			.name = "gp0_src",
-+			.parent_names = gcc_pxo_pll8_cxo,
-+			.num_parents = 3,
-+			.ops = &clk_rcg_ops,
-+			.flags = CLK_SET_PARENT_GATE,
-+		},
-+	}
-+};
-+
-+static struct clk_branch gp0_clk = {
-+	.halt_reg = 0x2fd8,
-+	.halt_bit = 7,
-+	.clkr = {
-+		.enable_reg = 0x2d24,
-+		.enable_mask = BIT(9),
-+		.hw.init = &(struct clk_init_data){
-+			.name = "gp0_clk",
-+			.parent_names = (const char *[]){ "gp0_src" },
-+			.num_parents = 1,
-+			.ops = &clk_branch_ops,
-+			.flags = CLK_SET_RATE_PARENT,
-+		},
-+	},
-+};
-+
-+static struct clk_rcg gp1_src = {
-+	.ns_reg = 0x2d44,
-+	.md_reg = 0x2d40,
-+	.mn = {
-+		.mnctr_en_bit = 8,
-+		.mnctr_reset_bit = 7,
-+		.mnctr_mode_shift = 5,
-+		.n_val_shift = 16,
-+		.m_val_shift = 16,
-+		.width = 8,
-+	},
-+	.p = {
-+		.pre_div_shift = 3,
-+		.pre_div_width = 2,
-+	},
-+	.s = {
-+		.src_sel_shift = 0,
-+		.parent_map = gcc_pxo_pll8_cxo_map,
-+	},
-+	.freq_tbl = clk_tbl_gp,
-+	.clkr = {
-+		.enable_reg = 0x2d44,
-+		.enable_mask = BIT(11),
-+		.hw.init = &(struct clk_init_data){
-+			.name = "gp1_src",
-+			.parent_names = gcc_pxo_pll8_cxo,
-+			.num_parents = 3,
-+			.ops = &clk_rcg_ops,
-+			.flags = CLK_SET_RATE_GATE,
-+		},
-+	}
-+};
-+
-+static struct clk_branch gp1_clk = {
-+	.halt_reg = 0x2fd8,
-+	.halt_bit = 6,
-+	.clkr = {
-+		.enable_reg = 0x2d44,
-+		.enable_mask = BIT(9),
-+		.hw.init = &(struct clk_init_data){
-+			.name = "gp1_clk",
-+			.parent_names = (const char *[]){ "gp1_src" },
-+			.num_parents = 1,
-+			.ops = &clk_branch_ops,
-+			.flags = CLK_SET_RATE_PARENT,
-+		},
-+	},
-+};
-+
-+static struct clk_rcg gp2_src = {
-+	.ns_reg = 0x2d64,
-+	.md_reg = 0x2d60,
-+	.mn = {
-+		.mnctr_en_bit = 8,
-+		.mnctr_reset_bit = 7,
-+		.mnctr_mode_shift = 5,
-+		.n_val_shift = 16,
-+		.m_val_shift = 16,
-+		.width = 8,
-+	},
-+	.p = {
-+		.pre_div_shift = 3,
-+		.pre_div_width = 2,
-+	},
-+	.s = {
-+		.src_sel_shift = 0,
-+		.parent_map = gcc_pxo_pll8_cxo_map,
-+	},
-+	.freq_tbl = clk_tbl_gp,
-+	.clkr = {
-+		.enable_reg = 0x2d64,
-+		.enable_mask = BIT(11),
-+		.hw.init = &(struct clk_init_data){
-+			.name = "gp2_src",
-+			.parent_names = gcc_pxo_pll8_cxo,
-+			.num_parents = 3,
-+			.ops = &clk_rcg_ops,
-+			.flags = CLK_SET_RATE_GATE,
-+		},
-+	}
-+};
-+
-+static struct clk_branch gp2_clk = {
-+	.halt_reg = 0x2fd8,
-+	.halt_bit = 5,
-+	.clkr = {
-+		.enable_reg = 0x2d64,
-+		.enable_mask = BIT(9),
-+		.hw.init = &(struct clk_init_data){
-+			.name = "gp2_clk",
-+			.parent_names = (const char *[]){ "gp2_src" },
-+			.num_parents = 1,
-+			.ops = &clk_branch_ops,
-+			.flags = CLK_SET_RATE_PARENT,
-+		},
-+	},
-+};
-+
-+static struct clk_branch pmem_clk = {
-+	.hwcg_reg = 0x25a0,
-+	.hwcg_bit = 6,
-+	.halt_reg = 0x2fc8,
-+	.halt_bit = 20,
-+	.clkr = {
-+		.enable_reg = 0x25a0,
-+		.enable_mask = BIT(4),
-+		.hw.init = &(struct clk_init_data){
-+			.name = "pmem_clk",
-+			.ops = &clk_branch_ops,
-+			.flags = CLK_IS_ROOT,
-+		},
-+	},
-+};
-+
-+static struct clk_rcg prng_src = {
-+	.ns_reg = 0x2e80,
-+	.p = {
-+		.pre_div_shift = 3,
-+		.pre_div_width = 4,
-+	},
-+	.s = {
-+		.src_sel_shift = 0,
-+		.parent_map = gcc_pxo_pll8_map,
-+	},
-+	.clkr = {
-+		.hw.init = &(struct clk_init_data){
-+			.name = "prng_src",
-+			.parent_names = gcc_pxo_pll8,
-+			.num_parents = 2,
-+			.ops = &clk_rcg_ops,
-+		},
-+	},
-+};
-+
-+static struct clk_branch prng_clk = {
-+	.halt_reg = 0x2fd8,
-+	.halt_check = BRANCH_HALT_VOTED,
-+	.halt_bit = 10,
-+	.clkr = {
-+		.enable_reg = 0x3080,
-+		.enable_mask = BIT(10),
-+		.hw.init = &(struct clk_init_data){
-+			.name = "prng_clk",
-+			.parent_names = (const char *[]){ "prng_src" },
-+			.num_parents = 1,
-+			.ops = &clk_branch_ops,
-+		},
-+	},
-+};
-+
-+static const struct freq_tbl clk_tbl_sdc[] = {
-+	{    144000, P_PXO,   5, 18,625 },
-+	{    400000, P_PLL8,  4, 1, 240 },
-+	{  16000000, P_PLL8,  4, 1,   6 },
-+	{  17070000, P_PLL8,  1, 2,  45 },
-+	{  20210000, P_PLL8,  1, 1,  19 },
-+	{  24000000, P_PLL8,  4, 1,   4 },
-+	{  48000000, P_PLL8,  4, 1,   2 },
-+	{  64000000, P_PLL8,  3, 1,   2 },
-+	{  96000000, P_PLL8,  4, 0,   0 },
-+	{ 192000000, P_PLL8,  2, 0,   0 },
-+	{ }
-+};
-+
-+static struct clk_rcg sdc1_src = {
-+	.ns_reg = 0x282c,
-+	.md_reg = 0x2828,
-+	.mn = {
-+		.mnctr_en_bit = 8,
-+		.mnctr_reset_bit = 7,
-+		.mnctr_mode_shift = 5,
-+		.n_val_shift = 16,
-+		.m_val_shift = 16,
-+		.width = 8,
-+	},
-+	.p = {
-+		.pre_div_shift = 3,
-+		.pre_div_width = 2,
-+	},
-+	.s = {
-+		.src_sel_shift = 0,
-+		.parent_map = gcc_pxo_pll8_map,
-+	},
-+	.freq_tbl = clk_tbl_sdc,
-+	.clkr = {
-+		.enable_reg = 0x282c,
-+		.enable_mask = BIT(11),
-+		.hw.init = &(struct clk_init_data){
-+			.name = "sdc1_src",
-+			.parent_names = gcc_pxo_pll8,
-+			.num_parents = 2,
-+			.ops = &clk_rcg_ops,
-+			.flags = CLK_SET_RATE_GATE,
-+		},
-+	}
-+};
-+
-+static struct clk_branch sdc1_clk = {
-+	.halt_reg = 0x2fc8,
-+	.halt_bit = 6,
-+	.clkr = {
-+		.enable_reg = 0x282c,
-+		.enable_mask = BIT(9),
-+		.hw.init = &(struct clk_init_data){
-+			.name = "sdc1_clk",
-+			.parent_names = (const char *[]){ "sdc1_src" },
-+			.num_parents = 1,
-+			.ops = &clk_branch_ops,
-+			.flags = CLK_SET_RATE_PARENT,
-+		},
-+	},
-+};
-+
-+static struct clk_rcg sdc3_src = {
-+	.ns_reg = 0x286c,
-+	.md_reg = 0x2868,
-+	.mn = {
-+		.mnctr_en_bit = 8,
-+		.mnctr_reset_bit = 7,
-+		.mnctr_mode_shift = 5,
-+		.n_val_shift = 16,
-+		.m_val_shift = 16,
-+		.width = 8,
-+	},
-+	.p = {
-+		.pre_div_shift = 3,
-+		.pre_div_width = 2,
-+	},
-+	.s = {
-+		.src_sel_shift = 0,
-+		.parent_map = gcc_pxo_pll8_map,
-+	},
-+	.freq_tbl = clk_tbl_sdc,
-+	.clkr = {
-+		.enable_reg = 0x286c,
-+		.enable_mask = BIT(11),
-+		.hw.init = &(struct clk_init_data){
-+			.name = "sdc3_src",
-+			.parent_names = gcc_pxo_pll8,
-+			.num_parents = 2,
-+			.ops = &clk_rcg_ops,
-+			.flags = CLK_SET_RATE_GATE,
-+		},
-+	}
-+};
-+
-+static struct clk_branch sdc3_clk = {
-+	.halt_reg = 0x2fc8,
-+	.halt_bit = 4,
-+	.clkr = {
-+		.enable_reg = 0x286c,
-+		.enable_mask = BIT(9),
-+		.hw.init = &(struct clk_init_data){
-+			.name = "sdc3_clk",
-+			.parent_names = (const char *[]){ "sdc3_src" },
-+			.num_parents = 1,
-+			.ops = &clk_branch_ops,
-+			.flags = CLK_SET_RATE_PARENT,
-+		},
-+	},
-+};
-+
-+static struct clk_branch sdc1_h_clk = {
-+	.hwcg_reg = 0x2820,
-+	.hwcg_bit = 6,
-+	.halt_reg = 0x2fc8,
-+	.halt_bit = 11,
-+	.clkr = {
-+		.enable_reg = 0x2820,
-+		.enable_mask = BIT(4),
-+		.hw.init = &(struct clk_init_data){
-+			.name = "sdc1_h_clk",
-+			.ops = &clk_branch_ops,
-+			.flags = CLK_IS_ROOT,
-+		},
-+	},
-+};
-+
-+static struct clk_branch sdc3_h_clk = {
-+	.hwcg_reg = 0x2860,
-+	.hwcg_bit = 6,
-+	.halt_reg = 0x2fc8,
-+	.halt_bit = 9,
-+	.clkr = {
-+		.enable_reg = 0x2860,
-+		.enable_mask = BIT(4),
-+		.hw.init = &(struct clk_init_data){
-+			.name = "sdc3_h_clk",
-+			.ops = &clk_branch_ops,
-+			.flags = CLK_IS_ROOT,
-+		},
-+	},
-+};
-+
-+static const struct freq_tbl clk_tbl_tsif_ref[] = {
-+	{ 105000, P_PXO,  1, 1, 256 },
-+	{ }
-+};
-+
-+static struct clk_rcg tsif_ref_src = {
-+	.ns_reg = 0x2710,
-+	.md_reg = 0x270c,
-+	.mn = {
-+		.mnctr_en_bit = 8,
-+		.mnctr_reset_bit = 7,
-+		.mnctr_mode_shift = 5,
-+		.n_val_shift = 16,
-+		.m_val_shift = 16,
-+		.width = 16,
-+	},
-+	.p = {
-+		.pre_div_shift = 3,
-+		.pre_div_width = 2,
-+	},
-+	.s = {
-+		.src_sel_shift = 0,
-+		.parent_map = gcc_pxo_pll8_map,
-+	},
-+	.freq_tbl = clk_tbl_tsif_ref,
-+	.clkr = {
-+		.enable_reg = 0x2710,
-+		.enable_mask = BIT(11),
-+		.hw.init = &(struct clk_init_data){
-+			.name = "tsif_ref_src",
-+			.parent_names = gcc_pxo_pll8,
-+			.num_parents = 2,
-+			.ops = &clk_rcg_ops,
-+			.flags = CLK_SET_RATE_GATE,
-+		},
-+	}
-+};
-+
-+static struct clk_branch tsif_ref_clk = {
-+	.halt_reg = 0x2fd4,
-+	.halt_bit = 5,
-+	.clkr = {
-+		.enable_reg = 0x2710,
-+		.enable_mask = BIT(9),
-+		.hw.init = &(struct clk_init_data){
-+			.name = "tsif_ref_clk",
-+			.parent_names = (const char *[]){ "tsif_ref_src" },
-+			.num_parents = 1,
-+			.ops = &clk_branch_ops,
-+			.flags = CLK_SET_RATE_PARENT,
-+		},
-+	},
-+};
-+
-+static struct clk_branch tsif_h_clk = {
-+	.hwcg_reg = 0x2700,
-+	.hwcg_bit = 6,
-+	.halt_reg = 0x2fd4,
-+	.halt_bit = 7,
-+	.clkr = {
-+		.enable_reg = 0x2700,
-+		.enable_mask = BIT(4),
-+		.hw.init = &(struct clk_init_data){
-+			.name = "tsif_h_clk",
-+			.ops = &clk_branch_ops,
-+			.flags = CLK_IS_ROOT,
-+		},
-+	},
-+};
-+
-+static struct clk_branch dma_bam_h_clk = {
-+	.hwcg_reg = 0x25c0,
-+	.hwcg_bit = 6,
-+	.halt_reg = 0x2fc8,
-+	.halt_bit = 12,
-+	.clkr = {
-+		.enable_reg = 0x25c0,
-+		.enable_mask = BIT(4),
-+		.hw.init = &(struct clk_init_data){
-+			.name = "dma_bam_h_clk",
-+			.ops = &clk_branch_ops,
-+			.flags = CLK_IS_ROOT,
-+		},
-+	},
-+};
-+
-+static struct clk_branch adm0_clk = {
-+	.halt_reg = 0x2fdc,
-+	.halt_check = BRANCH_HALT_VOTED,
-+	.halt_bit = 12,
-+	.clkr = {
-+		.enable_reg = 0x3080,
-+		.enable_mask = BIT(2),
-+		.hw.init = &(struct clk_init_data){
-+			.name = "adm0_clk",
-+			.ops = &clk_branch_ops,
-+			.flags = CLK_IS_ROOT,
-+		},
-+	},
-+};
-+
-+static struct clk_branch adm0_pbus_clk = {
-+	.hwcg_reg = 0x2208,
-+	.hwcg_bit = 6,
-+	.halt_reg = 0x2fdc,
-+	.halt_check = BRANCH_HALT_VOTED,
-+	.halt_bit = 11,
-+	.clkr = {
-+		.enable_reg = 0x3080,
-+		.enable_mask = BIT(3),
-+		.hw.init = &(struct clk_init_data){
-+			.name = "adm0_pbus_clk",
-+			.ops = &clk_branch_ops,
-+			.flags = CLK_IS_ROOT,
-+		},
-+	},
-+};
-+
-+static struct clk_branch pmic_arb0_h_clk = {
-+	.halt_reg = 0x2fd8,
-+	.halt_check = BRANCH_HALT_VOTED,
-+	.halt_bit = 22,
-+	.clkr = {
-+		.enable_reg = 0x3080,
-+		.enable_mask = BIT(8),
-+		.hw.init = &(struct clk_init_data){
-+			.name = "pmic_arb0_h_clk",
-+			.ops = &clk_branch_ops,
-+			.flags = CLK_IS_ROOT,
-+		},
-+	},
-+};
-+
-+static struct clk_branch pmic_arb1_h_clk = {
-+	.halt_reg = 0x2fd8,
-+	.halt_check = BRANCH_HALT_VOTED,
-+	.halt_bit = 21,
-+	.clkr = {
-+		.enable_reg = 0x3080,
-+		.enable_mask = BIT(9),
-+		.hw.init = &(struct clk_init_data){
-+			.name = "pmic_arb1_h_clk",
-+			.ops = &clk_branch_ops,
-+			.flags = CLK_IS_ROOT,
-+		},
-+	},
-+};
-+
-+static struct clk_branch pmic_ssbi2_clk = {
-+	.halt_reg = 0x2fd8,
-+	.halt_check = BRANCH_HALT_VOTED,
-+	.halt_bit = 23,
-+	.clkr = {
-+		.enable_reg = 0x3080,
-+		.enable_mask = BIT(7),
-+		.hw.init = &(struct clk_init_data){
-+			.name = "pmic_ssbi2_clk",
-+			.ops = &clk_branch_ops,
-+			.flags = CLK_IS_ROOT,
-+		},
-+	},
-+};
-+
-+static struct clk_branch rpm_msg_ram_h_clk = {
-+	.hwcg_reg = 0x27e0,
-+	.hwcg_bit = 6,
-+	.halt_reg = 0x2fd8,
-+	.halt_check = BRANCH_HALT_VOTED,
-+	.halt_bit = 12,
-+	.clkr = {
-+		.enable_reg = 0x3080,
-+		.enable_mask = BIT(6),
-+		.hw.init = &(struct clk_init_data){
-+			.name = "rpm_msg_ram_h_clk",
-+			.ops = &clk_branch_ops,
-+			.flags = CLK_IS_ROOT,
-+		},
-+	},
-+};
-+
-+static const struct freq_tbl clk_tbl_pcie_ref[] = {
-+	{ 100000000, P_PLL3,  12, 0, 0 },
-+	{ }
-+};
-+
-+static struct clk_rcg pcie_ref_src = {
-+	.ns_reg = 0x3860,
-+	.p = {
-+		.pre_div_shift = 3,
-+		.pre_div_width = 4,
-+	},
-+	.s = {
-+		.src_sel_shift = 0,
-+		.parent_map = gcc_pxo_pll3_map,
-+	},
-+	.freq_tbl = clk_tbl_pcie_ref,
-+	.clkr = {
-+		.enable_reg = 0x3860,
-+		.enable_mask = BIT(11),
-+		.hw.init = &(struct clk_init_data){
-+			.name = "pcie_ref_src",
-+			.parent_names = gcc_pxo_pll3,
-+			.num_parents = 2,
-+			.ops = &clk_rcg_ops,
-+			.flags = CLK_SET_RATE_GATE,
-+		},
-+	},
-+};
-+
-+static struct clk_branch pcie_ref_src_clk = {
-+	.halt_reg = 0x2fdc,
-+	.halt_bit = 30,
-+	.clkr = {
-+		.enable_reg = 0x3860,
-+		.enable_mask = BIT(9),
-+		.hw.init = &(struct clk_init_data){
-+			.name = "pcie_ref_src_clk",
-+			.parent_names = (const char *[]){ "pcie_ref_src" },
-+			.num_parents = 1,
-+			.ops = &clk_branch_ops,
-+			.flags = CLK_SET_RATE_PARENT,
-+		},
-+	},
-+};
-+
-+static struct clk_branch pcie_a_clk = {
-+	.halt_reg = 0x2fc0,
-+	.halt_bit = 13,
-+	.clkr = {
-+		.enable_reg = 0x22c0,
-+		.enable_mask = BIT(4),
-+		.hw.init = &(struct clk_init_data){
-+			.name = "pcie_a_clk",
-+			.ops = &clk_branch_ops,
-+			.flags = CLK_IS_ROOT,
-+		},
-+	},
-+};
-+
-+static struct clk_branch pcie_aux_clk = {
-+	.halt_reg = 0x2fdc,
-+	.halt_bit = 31,
-+	.clkr = {
-+		.enable_reg = 0x22c8,
-+		.enable_mask = BIT(4),
-+		.hw.init = &(struct clk_init_data){
-+			.name = "pcie_aux_clk",
-+			.ops = &clk_branch_ops,
-+			.flags = CLK_IS_ROOT,
-+		},
-+	},
-+};
-+
-+static struct clk_branch pcie_h_clk = {
-+	.halt_reg = 0x2fd4,
-+	.halt_bit = 8,
-+	.clkr = {
-+		.enable_reg = 0x22cc,
-+		.enable_mask = BIT(4),
-+		.hw.init = &(struct clk_init_data){
-+			.name = "pcie_h_clk",
-+			.ops = &clk_branch_ops,
-+			.flags = CLK_IS_ROOT,
-+		},
-+	},
-+};
-+
-+static struct clk_branch pcie_phy_clk = {
-+	.halt_reg = 0x2fdc,
-+	.halt_bit = 29,
-+	.clkr = {
-+		.enable_reg = 0x22d0,
-+		.enable_mask = BIT(4),
-+		.hw.init = &(struct clk_init_data){
-+			.name = "pcie_phy_clk",
-+			.ops = &clk_branch_ops,
-+			.flags = CLK_IS_ROOT,
-+		},
-+	},
-+};
-+
-+static struct clk_rcg pcie1_ref_src = {
-+	.ns_reg = 0x3aa0,
-+	.p = {
-+		.pre_div_shift = 3,
-+		.pre_div_width = 4,
-+	},
-+	.s = {
-+		.src_sel_shift = 0,
-+		.parent_map = gcc_pxo_pll3_map,
-+	},
-+	.freq_tbl = clk_tbl_pcie_ref,
-+	.clkr = {
-+		.enable_reg = 0x3aa0,
-+		.enable_mask = BIT(11),
-+		.hw.init = &(struct clk_init_data){
-+			.name = "pcie1_ref_src",
-+			.parent_names = gcc_pxo_pll3,
-+			.num_parents = 2,
-+			.ops = &clk_rcg_ops,
-+			.flags = CLK_SET_RATE_GATE,
-+		},
-+	},
-+};
-+
-+static struct clk_branch pcie1_ref_src_clk = {
-+	.halt_reg = 0x2fdc,
-+	.halt_bit = 27,
-+	.clkr = {
-+		.enable_reg = 0x3aa0,
-+		.enable_mask = BIT(9),
-+		.hw.init = &(struct clk_init_data){
-+			.name = "pcie1_ref_src_clk",
-+			.parent_names = (const char *[]){ "pcie1_ref_src" },
-+			.num_parents = 1,
-+			.ops = &clk_branch_ops,
-+			.flags = CLK_SET_RATE_PARENT,
-+		},
-+	},
-+};
-+
-+static struct clk_branch pcie1_a_clk = {
-+	.halt_reg = 0x2fc0,
-+	.halt_bit = 10,
-+	.clkr = {
-+		.enable_reg = 0x3a80,
-+		.enable_mask = BIT(4),
-+		.hw.init = &(struct clk_init_data){
-+			.name = "pcie1_a_clk",
-+			.ops = &clk_branch_ops,
-+			.flags = CLK_IS_ROOT,
-+		},
-+	},
-+};
-+
-+static struct clk_branch pcie1_aux_clk = {
-+	.halt_reg = 0x2fdc,
-+	.halt_bit = 28,
-+	.clkr = {
-+		.enable_reg = 0x3a88,
-+		.enable_mask = BIT(4),
-+		.hw.init = &(struct clk_init_data){
-+			.name = "pcie1_aux_clk",
-+			.ops = &clk_branch_ops,
-+			.flags = CLK_IS_ROOT,
-+		},
-+	},
-+};
-+
-+static struct clk_branch pcie1_h_clk = {
-+	.halt_reg = 0x2fd4,
-+	.halt_bit = 9,
-+	.clkr = {
-+		.enable_reg = 0x3a8c,
-+		.enable_mask = BIT(4),
-+		.hw.init = &(struct clk_init_data){
-+			.name = "pcie1_h_clk",
-+			.ops = &clk_branch_ops,
-+			.flags = CLK_IS_ROOT,
-+		},
-+	},
-+};
-+
-+static struct clk_branch pcie1_phy_clk = {
-+	.halt_reg = 0x2fdc,
-+	.halt_bit = 26,
-+	.clkr = {
-+		.enable_reg = 0x3a90,
-+		.enable_mask = BIT(4),
-+		.hw.init = &(struct clk_init_data){
-+			.name = "pcie1_phy_clk",
-+			.ops = &clk_branch_ops,
-+			.flags = CLK_IS_ROOT,
-+		},
-+	},
-+};
-+
-+static struct clk_rcg pcie2_ref_src = {
-+	.ns_reg = 0x3ae0,
-+	.p = {
-+		.pre_div_shift = 3,
-+		.pre_div_width = 4,
-+	},
-+	.s = {
-+		.src_sel_shift = 0,
-+		.parent_map = gcc_pxo_pll3_map,
-+	},
-+	.freq_tbl = clk_tbl_pcie_ref,
-+	.clkr = {
-+		.enable_reg = 0x3ae0,
-+		.enable_mask = BIT(11),
-+		.hw.init = &(struct clk_init_data){
-+			.name = "pcie2_ref_src",
-+			.parent_names = gcc_pxo_pll3,
-+			.num_parents = 2,
-+			.ops = &clk_rcg_ops,
-+			.flags = CLK_SET_RATE_GATE,
-+		},
-+	},
-+};
-+
-+static struct clk_branch pcie2_ref_src_clk = {
-+	.halt_reg = 0x2fdc,
-+	.halt_bit = 24,
-+	.clkr = {
-+		.enable_reg = 0x3ae0,
-+		.enable_mask = BIT(9),
-+		.hw.init = &(struct clk_init_data){
-+			.name = "pcie2_ref_src_clk",
-+			.parent_names = (const char *[]){ "pcie2_ref_src" },
-+			.num_parents = 1,
-+			.ops = &clk_branch_ops,
-+			.flags = CLK_SET_RATE_PARENT,
-+		},
-+	},
-+};
-+
-+static struct clk_branch pcie2_a_clk = {
-+	.halt_reg = 0x2fc0,
-+	.halt_bit = 9,
-+	.clkr = {
-+		.enable_reg = 0x3ac0,
-+		.enable_mask = BIT(4),
-+		.hw.init = &(struct clk_init_data){
-+			.name = "pcie2_a_clk",
-+			.ops = &clk_branch_ops,
-+			.flags = CLK_IS_ROOT,
-+		},
-+	},
-+};
-+
-+static struct clk_branch pcie2_aux_clk = {
-+	.halt_reg = 0x2fdc,
-+	.halt_bit = 25,
-+	.clkr = {
-+		.enable_reg = 0x3ac8,
-+		.enable_mask = BIT(4),
-+		.hw.init = &(struct clk_init_data){
-+			.name = "pcie2_aux_clk",
-+			.ops = &clk_branch_ops,
-+			.flags = CLK_IS_ROOT,
-+		},
-+	},
-+};
-+
-+static struct clk_branch pcie2_h_clk = {
-+	.halt_reg = 0x2fd4,
-+	.halt_bit = 10,
-+	.clkr = {
-+		.enable_reg = 0x3acc,
-+		.enable_mask = BIT(4),
-+		.hw.init = &(struct clk_init_data){
-+			.name = "pcie2_h_clk",
-+			.ops = &clk_branch_ops,
-+			.flags = CLK_IS_ROOT,
-+		},
-+	},
-+};
-+
-+static struct clk_branch pcie2_phy_clk = {
-+	.halt_reg = 0x2fdc,
-+	.halt_bit = 23,
-+	.clkr = {
-+		.enable_reg = 0x3ad0,
-+		.enable_mask = BIT(4),
-+		.hw.init = &(struct clk_init_data){
-+			.name = "pcie2_phy_clk",
-+			.ops = &clk_branch_ops,
-+			.flags = CLK_IS_ROOT,
-+		},
-+	},
-+};
-+
-+static const struct freq_tbl clk_tbl_sata_ref[] = {
-+	{ 100000000, P_PLL3,  12, 0, 0 },
-+	{ }
-+};
-+
-+static struct clk_rcg sata_ref_src = {
-+	.ns_reg = 0x2c08,
-+	.p = {
-+		.pre_div_shift = 3,
-+		.pre_div_width = 4,
-+	},
-+	.s = {
-+		.src_sel_shift = 0,
-+		.parent_map = gcc_pxo_pll3_sata_map,
-+	},
-+	.freq_tbl = clk_tbl_sata_ref,
-+	.clkr = {
-+		.enable_reg = 0x2c08,
-+		.enable_mask = BIT(7),
-+		.hw.init = &(struct clk_init_data){
-+			.name = "sata_ref_src",
-+			.parent_names = gcc_pxo_pll3,
-+			.num_parents = 2,
-+			.ops = &clk_rcg_ops,
-+			.flags = CLK_SET_RATE_GATE,
-+		},
-+	},
-+};
-+
-+static struct clk_branch sata_rxoob_clk = {
-+	.halt_reg = 0x2fdc,
-+	.halt_bit = 20,
-+	.clkr = {
-+		.enable_reg = 0x2c0c,
-+		.enable_mask = BIT(4),
-+		.hw.init = &(struct clk_init_data){
-+			.name = "sata_rxoob_clk",
-+			.parent_names = (const char *[]){ "sata_ref_src" },
-+			.num_parents = 1,
-+			.ops = &clk_branch_ops,
-+			.flags = CLK_SET_RATE_PARENT,
-+		},
-+	},
-+};
-+
-+static struct clk_branch sata_pmalive_clk = {
-+	.halt_reg = 0x2fdc,
-+	.halt_bit = 19,
-+	.clkr = {
-+		.enable_reg = 0x2c10,
-+		.enable_mask = BIT(4),
-+		.hw.init = &(struct clk_init_data){
-+			.name = "sata_pmalive_clk",
-+			.parent_names = (const char *[]){ "sata_ref_src" },
-+			.num_parents = 1,
-+			.ops = &clk_branch_ops,
-+			.flags = CLK_SET_RATE_PARENT,
-+		},
-+	},
-+};
-+
-+static struct clk_branch sata_phy_ref_clk = {
-+	.halt_reg = 0x2fdc,
-+	.halt_bit = 18,
-+	.clkr = {
-+		.enable_reg = 0x2c14,
-+		.enable_mask = BIT(4),
-+		.hw.init = &(struct clk_init_data){
-+			.name = "sata_phy_ref_clk",
-+			.parent_names = (const char *[]){ "pxo" },
-+			.num_parents = 1,
-+			.ops = &clk_branch_ops,
-+		},
-+	},
-+};
-+
-+static struct clk_branch sata_a_clk = {
-+	.halt_reg = 0x2fc0,
-+	.halt_bit = 12,
-+	.clkr = {
-+		.enable_reg = 0x2c20,
-+		.enable_mask = BIT(4),
-+		.hw.init = &(struct clk_init_data){
-+			.name = "sata_a_clk",
-+			.ops = &clk_branch_ops,
-+			.flags = CLK_IS_ROOT,
-+		},
-+	},
-+};
-+
-+static struct clk_branch sata_h_clk = {
-+	.halt_reg = 0x2fdc,
-+	.halt_bit = 21,
-+	.clkr = {
-+		.enable_reg = 0x2c00,
-+		.enable_mask = BIT(4),
-+		.hw.init = &(struct clk_init_data){
-+			.name = "sata_h_clk",
-+			.ops = &clk_branch_ops,
-+			.flags = CLK_IS_ROOT,
-+		},
-+	},
-+};
-+
-+static struct clk_branch sfab_sata_s_h_clk = {
-+	.halt_reg = 0x2fc4,
-+	.halt_bit = 14,
-+	.clkr = {
-+		.enable_reg = 0x2480,
-+		.enable_mask = BIT(4),
-+		.hw.init = &(struct clk_init_data){
-+			.name = "sfab_sata_s_h_clk",
-+			.ops = &clk_branch_ops,
-+			.flags = CLK_IS_ROOT,
-+		},
-+	},
-+};
-+
-+static struct clk_branch sata_phy_cfg_clk = {
-+	.halt_reg = 0x2fcc,
-+	.halt_bit = 14,
-+	.clkr = {
-+		.enable_reg = 0x2c40,
-+		.enable_mask = BIT(4),
-+		.hw.init = &(struct clk_init_data){
-+			.name = "sata_phy_cfg_clk",
-+			.ops = &clk_branch_ops,
-+			.flags = CLK_IS_ROOT,
-+		},
-+	},
-+};
-+
-+static const struct freq_tbl clk_tbl_usb30_master[] = {
-+	{ 125000000, P_PLL0,  1, 5, 32 },
-+	{ }
-+};
-+
-+static struct clk_rcg usb30_master_clk_src = {
-+	.ns_reg = 0x3b2c,
-+	.md_reg = 0x3b28,
-+	.mn = {
-+		.mnctr_en_bit = 8,
-+		.mnctr_reset_bit = 7,
-+		.mnctr_mode_shift = 5,
-+		.n_val_shift = 16,
-+		.m_val_shift = 16,
-+		.width = 8,
-+	},
-+	.p = {
-+		.pre_div_shift = 3,
-+		.pre_div_width = 2,
-+	},
-+	.s = {
-+		.src_sel_shift = 0,
-+		.parent_map = gcc_pxo_pll8_pll0,
-+	},
-+	.freq_tbl = clk_tbl_usb30_master,
-+	.clkr = {
-+		.enable_reg = 0x3b2c,
-+		.enable_mask = BIT(11),
-+		.hw.init = &(struct clk_init_data){
-+			.name = "usb30_master_ref_src",
-+			.parent_names = gcc_pxo_pll8_pll0_map,
-+			.num_parents = 3,
-+			.ops = &clk_rcg_ops,
-+			.flags = CLK_SET_RATE_GATE,
-+		},
-+	},
-+};
-+
-+static struct clk_branch usb30_0_branch_clk = {
-+	.halt_reg = 0x2fc4,
-+	.halt_bit = 22,
-+	.clkr = {
-+		.enable_reg = 0x3b24,
-+		.enable_mask = BIT(4),
-+		.hw.init = &(struct clk_init_data){
-+			.name = "usb30_0_branch_clk",
-+			.parent_names = (const char *[]){ "usb30_master_ref_src", },
-+			.num_parents = 1,
-+			.ops = &clk_branch_ops,
-+			.flags = CLK_SET_RATE_PARENT,
-+		},
-+	},
-+};
-+
-+static struct clk_branch usb30_1_branch_clk = {
-+	.halt_reg = 0x2fc4,
-+	.halt_bit = 17,
-+	.clkr = {
-+		.enable_reg = 0x3b34,
-+		.enable_mask = BIT(4),
-+		.hw.init = &(struct clk_init_data){
-+			.name = "usb30_1_branch_clk",
-+			.parent_names = (const char *[]){ "usb30_master_ref_src", },
-+			.num_parents = 1,
-+			.ops = &clk_branch_ops,
-+			.flags = CLK_SET_RATE_PARENT,
-+		},
-+	},
-+};
-+
-+static const struct freq_tbl clk_tbl_usb30_utmi[] = {
-+	{ 60000000, P_PLL0,  1, 1, 40 },
-+	{ }
-+};
-+
-+static struct clk_rcg usb30_utmi_clk = {
-+	.ns_reg = 0x3b44,
-+	.md_reg = 0x3b40,
-+	.mn = {
-+		.mnctr_en_bit = 8,
-+		.mnctr_reset_bit = 7,
-+		.mnctr_mode_shift = 5,
-+		.n_val_shift = 16,
-+		.m_val_shift = 16,
-+		.width = 8,
-+	},
-+	.p = {
-+		.pre_div_shift = 3,
-+		.pre_div_width = 2,
-+	},
-+	.s = {
-+		.src_sel_shift = 0,
-+		.parent_map = gcc_pxo_pll8_pll0,
-+	},
-+	.freq_tbl = clk_tbl_usb30_utmi,
-+	.clkr = {
-+		.enable_reg = 0x3b44,
-+		.enable_mask = BIT(11),
-+		.hw.init = &(struct clk_init_data){
-+			.name = "usb30_utmi_clk",
-+			.parent_names = gcc_pxo_pll8_pll0_map,
-+			.num_parents = 3,
-+			.ops = &clk_rcg_ops,
-+			.flags = CLK_SET_RATE_GATE,
-+		},
-+	},
-+};
-+
-+static struct clk_branch usb30_0_utmi_clk_ctl = {
-+	.halt_reg = 0x2fc4,
-+	.halt_bit = 21,
-+	.clkr = {
-+		.enable_reg = 0x3b48,
-+		.enable_mask = BIT(4),
-+		.hw.init = &(struct clk_init_data){
-+			.name = "usb30_0_utmi_clk_ctl",
-+			.parent_names = (const char *[]){ "usb30_utmi_clk", },
-+			.num_parents = 1,
-+			.ops = &clk_branch_ops,
-+			.flags = CLK_SET_RATE_PARENT,
-+		},
-+	},
-+};
-+
-+static struct clk_branch usb30_1_utmi_clk_ctl = {
-+	.halt_reg = 0x2fc4,
-+	.halt_bit = 15,
-+	.clkr = {
-+		.enable_reg = 0x3b4c,
-+		.enable_mask = BIT(4),
-+		.hw.init = &(struct clk_init_data){
-+			.name = "usb30_1_utmi_clk_ctl",
-+			.parent_names = (const char *[]){ "usb30_utmi_clk", },
-+			.num_parents = 1,
-+			.ops = &clk_branch_ops,
-+			.flags = CLK_SET_RATE_PARENT,
-+		},
-+	},
-+};
-+
-+static const struct freq_tbl clk_tbl_usb[] = {
-+	{ 60000000, P_PLL8,  1, 5, 32 },
-+	{ }
-+};
-+
-+static struct clk_rcg usb_hs1_xcvr_clk_src = {
-+	.ns_reg = 0x290C,
-+	.md_reg = 0x2908,
-+	.mn = {
-+		.mnctr_en_bit = 8,
-+		.mnctr_reset_bit = 7,
-+		.mnctr_mode_shift = 5,
-+		.n_val_shift = 16,
-+		.m_val_shift = 16,
-+		.width = 8,
-+	},
-+	.p = {
-+		.pre_div_shift = 3,
-+		.pre_div_width = 2,
-+	},
-+	.s = {
-+		.src_sel_shift = 0,
-+		.parent_map = gcc_pxo_pll8_pll0,
-+	},
-+	.freq_tbl = clk_tbl_usb,
-+	.clkr = {
-+		.enable_reg = 0x2968,
-+		.enable_mask = BIT(11),
-+		.hw.init = &(struct clk_init_data){
-+			.name = "usb_hs1_xcvr_src",
-+			.parent_names = gcc_pxo_pll8_pll0_map,
-+			.num_parents = 3,
-+			.ops = &clk_rcg_ops,
-+			.flags = CLK_SET_RATE_GATE,
-+		},
-+	},
-+};
-+
-+static struct clk_branch usb_hs1_xcvr_clk = {
-+	.halt_reg = 0x2fcc,
-+	.halt_bit = 17,
-+	.clkr = {
-+		.enable_reg = 0x290c,
-+		.enable_mask = BIT(9),
-+		.hw.init = &(struct clk_init_data){
-+			.name = "usb_hs1_xcvr_clk",
-+			.parent_names = (const char *[]){ "usb_hs1_xcvr_src" },
-+			.num_parents = 1,
-+			.ops = &clk_branch_ops,
-+			.flags = CLK_SET_RATE_PARENT,
-+		},
-+	},
-+};
-+
-+static struct clk_branch usb_hs1_h_clk = {
-+	.hwcg_reg = 0x2900,
-+	.hwcg_bit = 6,
-+	.halt_reg = 0x2fc8,
-+	.halt_bit = 1,
-+	.clkr = {
-+		.enable_reg = 0x2900,
-+		.enable_mask = BIT(4),
-+		.hw.init = &(struct clk_init_data){
-+			.name = "usb_hs1_h_clk",
-+			.ops = &clk_branch_ops,
-+			.flags = CLK_IS_ROOT,
-+		},
-+	},
-+};
-+
-+static struct clk_rcg usb_fs1_xcvr_clk_src = {
-+	.ns_reg = 0x2968,
-+	.md_reg = 0x2964,
-+	.mn = {
-+		.mnctr_en_bit = 8,
-+		.mnctr_reset_bit = 7,
-+		.mnctr_mode_shift = 5,
-+		.n_val_shift = 16,
-+		.m_val_shift = 16,
-+		.width = 8,
-+	},
-+	.p = {
-+		.pre_div_shift = 3,
-+		.pre_div_width = 2,
-+	},
-+	.s = {
-+		.src_sel_shift = 0,
-+		.parent_map = gcc_pxo_pll8_pll0,
-+	},
-+	.freq_tbl = clk_tbl_usb,
-+	.clkr = {
-+		.enable_reg = 0x2968,
-+		.enable_mask = BIT(11),
-+		.hw.init = &(struct clk_init_data){
-+			.name = "usb_fs1_xcvr_src",
-+			.parent_names = gcc_pxo_pll8_pll0_map,
-+			.num_parents = 3,
-+			.ops = &clk_rcg_ops,
-+			.flags = CLK_SET_RATE_GATE,
-+		},
-+	},
-+};
-+
-+static struct clk_branch usb_fs1_xcvr_clk = {
-+	.halt_reg = 0x2fcc,
-+	.halt_bit = 17,
-+	.clkr = {
-+		.enable_reg = 0x2968,
-+		.enable_mask = BIT(9),
-+		.hw.init = &(struct clk_init_data){
-+			.name = "usb_fs1_xcvr_clk",
-+			.parent_names = (const char *[]){ "usb_fs1_xcvr_src", },
-+			.num_parents = 1,
-+			.ops = &clk_branch_ops,
-+			.flags = CLK_SET_RATE_PARENT,
-+		},
-+	},
-+};
-+
-+static struct clk_branch usb_fs1_sys_clk = {
-+	.halt_reg = 0x2fcc,
-+	.halt_bit = 18,
-+	.clkr = {
-+		.enable_reg = 0x296c,
-+		.enable_mask = BIT(4),
-+		.hw.init = &(struct clk_init_data){
-+			.name = "usb_fs1_sys_clk",
-+			.parent_names = (const char *[]){ "usb_fs1_xcvr_src", },
-+			.num_parents = 1,
-+			.ops = &clk_branch_ops,
-+			.flags = CLK_SET_RATE_PARENT,
-+		},
-+	},
-+};
-+
-+static struct clk_branch usb_fs1_h_clk = {
-+	.halt_reg = 0x2fcc,
-+	.halt_bit = 19,
-+	.clkr = {
-+		.enable_reg = 0x2960,
-+		.enable_mask = BIT(4),
-+		.hw.init = &(struct clk_init_data){
-+			.name = "usb_fs1_h_clk",
-+			.ops = &clk_branch_ops,
-+			.flags = CLK_IS_ROOT,
-+		},
-+	},
-+};
-+
-+static struct clk_regmap *gcc_ipq806x_clks[] = {
-+	[PLL3] = &pll3.clkr,
-+	[PLL8] = &pll8.clkr,
-+	[PLL8_VOTE] = &pll8_vote,
-+	[PLL14] = &pll14.clkr,
-+	[PLL14_VOTE] = &pll14_vote,
-+	[GSBI1_UART_SRC] = &gsbi1_uart_src.clkr,
-+	[GSBI1_UART_CLK] = &gsbi1_uart_clk.clkr,
-+	[GSBI2_UART_SRC] = &gsbi2_uart_src.clkr,
-+	[GSBI2_UART_CLK] = &gsbi2_uart_clk.clkr,
-+	[GSBI4_UART_SRC] = &gsbi4_uart_src.clkr,
-+	[GSBI4_UART_CLK] = &gsbi4_uart_clk.clkr,
-+	[GSBI5_UART_SRC] = &gsbi5_uart_src.clkr,
-+	[GSBI5_UART_CLK] = &gsbi5_uart_clk.clkr,
-+	[GSBI6_UART_SRC] = &gsbi6_uart_src.clkr,
-+	[GSBI6_UART_CLK] = &gsbi6_uart_clk.clkr,
-+	[GSBI7_UART_SRC] = &gsbi7_uart_src.clkr,
-+	[GSBI7_UART_CLK] = &gsbi7_uart_clk.clkr,
-+	[GSBI1_QUP_SRC] = &gsbi1_qup_src.clkr,
-+	[GSBI1_QUP_CLK] = &gsbi1_qup_clk.clkr,
-+	[GSBI2_QUP_SRC] = &gsbi2_qup_src.clkr,
-+	[GSBI2_QUP_CLK] = &gsbi2_qup_clk.clkr,
-+	[GSBI4_QUP_SRC] = &gsbi4_qup_src.clkr,
-+	[GSBI4_QUP_CLK] = &gsbi4_qup_clk.clkr,
-+	[GSBI5_QUP_SRC] = &gsbi5_qup_src.clkr,
-+	[GSBI5_QUP_CLK] = &gsbi5_qup_clk.clkr,
-+	[GSBI6_QUP_SRC] = &gsbi6_qup_src.clkr,
-+	[GSBI6_QUP_CLK] = &gsbi6_qup_clk.clkr,
-+	[GSBI7_QUP_SRC] = &gsbi7_qup_src.clkr,
-+	[GSBI7_QUP_CLK] = &gsbi7_qup_clk.clkr,
-+	[GP0_SRC] = &gp0_src.clkr,
-+	[GP0_CLK] = &gp0_clk.clkr,
-+	[GP1_SRC] = &gp1_src.clkr,
-+	[GP1_CLK] = &gp1_clk.clkr,
-+	[GP2_SRC] = &gp2_src.clkr,
-+	[GP2_CLK] = &gp2_clk.clkr,
-+	[PMEM_A_CLK] = &pmem_clk.clkr,
-+	[PRNG_SRC] = &prng_src.clkr,
-+	[PRNG_CLK] = &prng_clk.clkr,
-+	[SDC1_SRC] = &sdc1_src.clkr,
-+	[SDC1_CLK] = &sdc1_clk.clkr,
-+	[SDC3_SRC] = &sdc3_src.clkr,
-+	[SDC3_CLK] = &sdc3_clk.clkr,
-+	[TSIF_REF_SRC] = &tsif_ref_src.clkr,
-+	[TSIF_REF_CLK] = &tsif_ref_clk.clkr,
-+	[DMA_BAM_H_CLK] = &dma_bam_h_clk.clkr,
-+	[GSBI1_H_CLK] = &gsbi1_h_clk.clkr,
-+	[GSBI2_H_CLK] = &gsbi2_h_clk.clkr,
-+	[GSBI4_H_CLK] = &gsbi4_h_clk.clkr,
-+	[GSBI5_H_CLK] = &gsbi5_h_clk.clkr,
-+	[GSBI6_H_CLK] = &gsbi6_h_clk.clkr,
-+	[GSBI7_H_CLK] = &gsbi7_h_clk.clkr,
-+	[TSIF_H_CLK] = &tsif_h_clk.clkr,
-+	[SDC1_H_CLK] = &sdc1_h_clk.clkr,
-+	[SDC3_H_CLK] = &sdc3_h_clk.clkr,
-+	[ADM0_CLK] = &adm0_clk.clkr,
-+	[ADM0_PBUS_CLK] = &adm0_pbus_clk.clkr,
-+	[PCIE_A_CLK] = &pcie_a_clk.clkr,
-+	[PCIE_AUX_CLK] = &pcie_aux_clk.clkr,
-+	[PCIE_H_CLK] = &pcie_h_clk.clkr,
-+	[PCIE_PHY_CLK] = &pcie_phy_clk.clkr,
-+	[SFAB_SATA_S_H_CLK] = &sfab_sata_s_h_clk.clkr,
-+	[PMIC_ARB0_H_CLK] = &pmic_arb0_h_clk.clkr,
-+	[PMIC_ARB1_H_CLK] = &pmic_arb1_h_clk.clkr,
-+	[PMIC_SSBI2_CLK] = &pmic_ssbi2_clk.clkr,
-+	[RPM_MSG_RAM_H_CLK] = &rpm_msg_ram_h_clk.clkr,
-+	[SATA_H_CLK] = &sata_h_clk.clkr,
-+	[SATA_CLK_SRC] = &sata_ref_src.clkr,
-+	[SATA_RXOOB_CLK] = &sata_rxoob_clk.clkr,
-+	[SATA_PMALIVE_CLK] = &sata_pmalive_clk.clkr,
-+	[SATA_PHY_REF_CLK] = &sata_phy_ref_clk.clkr,
-+	[SATA_A_CLK] = &sata_a_clk.clkr,
-+	[SATA_PHY_CFG_CLK] = &sata_phy_cfg_clk.clkr,
-+	[PCIE_ALT_REF_SRC] = &pcie_ref_src.clkr,
-+	[PCIE_ALT_REF_CLK] = &pcie_ref_src_clk.clkr,
-+	[PCIE_1_A_CLK] = &pcie1_a_clk.clkr,
-+	[PCIE_1_AUX_CLK] = &pcie1_aux_clk.clkr,
-+	[PCIE_1_H_CLK] = &pcie1_h_clk.clkr,
-+	[PCIE_1_PHY_CLK] = &pcie1_phy_clk.clkr,
-+	[PCIE_1_ALT_REF_SRC] = &pcie1_ref_src.clkr,
-+	[PCIE_1_ALT_REF_CLK] = &pcie1_ref_src_clk.clkr,
-+	[PCIE_2_A_CLK] = &pcie2_a_clk.clkr,
-+	[PCIE_2_AUX_CLK] = &pcie2_aux_clk.clkr,
-+	[PCIE_2_H_CLK] = &pcie2_h_clk.clkr,
-+	[PCIE_2_PHY_CLK] = &pcie2_phy_clk.clkr,
-+	[PCIE_2_ALT_REF_SRC] = &pcie2_ref_src.clkr,
-+	[PCIE_2_ALT_REF_CLK] = &pcie2_ref_src_clk.clkr,
-+	[USB30_MASTER_SRC] = &usb30_master_clk_src.clkr,
-+	[USB30_0_MASTER_CLK] = &usb30_0_branch_clk.clkr,
-+	[USB30_1_MASTER_CLK] = &usb30_1_branch_clk.clkr,
-+	[USB30_UTMI_SRC] = &usb30_utmi_clk.clkr,
-+	[USB30_0_UTMI_CLK] = &usb30_0_utmi_clk_ctl.clkr,
-+	[USB30_1_UTMI_CLK] = &usb30_1_utmi_clk_ctl.clkr,
-+	[USB_HS1_H_CLK] = &usb_hs1_h_clk.clkr,
-+	[USB_HS1_XCVR_SRC] = &usb_hs1_xcvr_clk_src.clkr,
-+	[USB_HS1_XCVR_CLK] = &usb_hs1_xcvr_clk.clkr,
-+	[USB_FS1_H_CLK] = &usb_fs1_h_clk.clkr,
-+	[USB_FS1_XCVR_SRC] = &usb_fs1_xcvr_clk_src.clkr,
-+	[USB_FS1_XCVR_CLK] = &usb_fs1_xcvr_clk.clkr,
-+	[USB_FS1_SYSTEM_CLK] = &usb_fs1_sys_clk.clkr,
-+};
-+
-+static const struct qcom_reset_map gcc_ipq806x_resets[] = {
-+	[QDSS_STM_RESET] = { 0x2060, 6 },
-+	[AFAB_SMPSS_S_RESET] = { 0x20b8, 2 },
-+	[AFAB_SMPSS_M1_RESET] = { 0x20b8, 1 },
-+	[AFAB_SMPSS_M0_RESET] = { 0x20b8, 0 },
-+	[AFAB_EBI1_CH0_RESET] = { 0x20c0, 7 },
-+	[AFAB_EBI1_CH1_RESET] = { 0x20c4, 7 },
-+	[SFAB_ADM0_M0_RESET] = { 0x21e0, 7 },
-+	[SFAB_ADM0_M1_RESET] = { 0x21e4, 7 },
-+	[SFAB_ADM0_M2_RESET] = { 0x21e8, 7 },
-+	[ADM0_C2_RESET] = { 0x220c, 4 },
-+	[ADM0_C1_RESET] = { 0x220c, 3 },
-+	[ADM0_C0_RESET] = { 0x220c, 2 },
-+	[ADM0_PBUS_RESET] = { 0x220c, 1 },
-+	[ADM0_RESET] = { 0x220c, 0 },
-+	[QDSS_CLKS_SW_RESET] = { 0x2260, 5 },
-+	[QDSS_POR_RESET] = { 0x2260, 4 },
-+	[QDSS_TSCTR_RESET] = { 0x2260, 3 },
-+	[QDSS_HRESET_RESET] = { 0x2260, 2 },
-+	[QDSS_AXI_RESET] = { 0x2260, 1 },
-+	[QDSS_DBG_RESET] = { 0x2260, 0 },
-+	[SFAB_PCIE_M_RESET] = { 0x22d8, 1 },
-+	[SFAB_PCIE_S_RESET] = { 0x22d8, 0 },
-+	[PCIE_EXT_RESET] = { 0x22dc, 6 },
-+	[PCIE_PHY_RESET] = { 0x22dc, 5 },
-+	[PCIE_PCI_RESET] = { 0x22dc, 4 },
-+	[PCIE_POR_RESET] = { 0x22dc, 3 },
-+	[PCIE_HCLK_RESET] = { 0x22dc, 2 },
-+	[PCIE_ACLK_RESET] = { 0x22dc, 0 },
-+	[SFAB_LPASS_RESET] = { 0x23a0, 7 },
-+	[SFAB_AFAB_M_RESET] = { 0x23e0, 7 },
-+	[AFAB_SFAB_M0_RESET] = { 0x2420, 7 },
-+	[AFAB_SFAB_M1_RESET] = { 0x2424, 7 },
-+	[SFAB_SATA_S_RESET] = { 0x2480, 7 },
-+	[SFAB_DFAB_M_RESET] = { 0x2500, 7 },
-+	[DFAB_SFAB_M_RESET] = { 0x2520, 7 },
-+	[DFAB_SWAY0_RESET] = { 0x2540, 7 },
-+	[DFAB_SWAY1_RESET] = { 0x2544, 7 },
-+	[DFAB_ARB0_RESET] = { 0x2560, 7 },
-+	[DFAB_ARB1_RESET] = { 0x2564, 7 },
-+	[PPSS_PROC_RESET] = { 0x2594, 1 },
-+	[PPSS_RESET] = { 0x2594, 0 },
-+	[DMA_BAM_RESET] = { 0x25c0, 7 },
-+	[SPS_TIC_H_RESET] = { 0x2600, 7 },
-+	[SFAB_CFPB_M_RESET] = { 0x2680, 7 },
-+	[SFAB_CFPB_S_RESET] = { 0x26c0, 7 },
-+	[TSIF_H_RESET] = { 0x2700, 7 },
-+	[CE1_H_RESET] = { 0x2720, 7 },
-+	[CE1_CORE_RESET] = { 0x2724, 7 },
-+	[CE1_SLEEP_RESET] = { 0x2728, 7 },
-+	[CE2_H_RESET] = { 0x2740, 7 },
-+	[CE2_CORE_RESET] = { 0x2744, 7 },
-+	[SFAB_SFPB_M_RESET] = { 0x2780, 7 },
-+	[SFAB_SFPB_S_RESET] = { 0x27a0, 7 },
-+	[RPM_PROC_RESET] = { 0x27c0, 7 },
-+	[PMIC_SSBI2_RESET] = { 0x280c, 12 },
-+	[SDC1_RESET] = { 0x2830, 0 },
-+	[SDC2_RESET] = { 0x2850, 0 },
-+	[SDC3_RESET] = { 0x2870, 0 },
-+	[SDC4_RESET] = { 0x2890, 0 },
-+	[USB_HS1_RESET] = { 0x2910, 0 },
-+	[USB_HSIC_RESET] = { 0x2934, 0 },
-+	[USB_FS1_XCVR_RESET] = { 0x2974, 1 },
-+	[USB_FS1_RESET] = { 0x2974, 0 },
-+	[GSBI1_RESET] = { 0x29dc, 0 },
-+	[GSBI2_RESET] = { 0x29fc, 0 },
-+	[GSBI3_RESET] = { 0x2a1c, 0 },
-+	[GSBI4_RESET] = { 0x2a3c, 0 },
-+	[GSBI5_RESET] = { 0x2a5c, 0 },
-+	[GSBI6_RESET] = { 0x2a7c, 0 },
-+	[GSBI7_RESET] = { 0x2a9c, 0 },
-+	[SPDM_RESET] = { 0x2b6c, 0 },
-+	[SEC_CTRL_RESET] = { 0x2b80, 7 },
-+	[TLMM_H_RESET] = { 0x2ba0, 7 },
-+	[SFAB_SATA_M_RESET] = { 0x2c18, 0 },
-+	[SATA_RESET] = { 0x2c1c, 0 },
-+	[TSSC_RESET] = { 0x2ca0, 7 },
-+	[PDM_RESET] = { 0x2cc0, 12 },
-+	[MPM_H_RESET] = { 0x2da0, 7 },
-+	[MPM_RESET] = { 0x2da4, 0 },
-+	[SFAB_SMPSS_S_RESET] = { 0x2e00, 7 },
-+	[PRNG_RESET] = { 0x2e80, 12 },
-+	[SFAB_CE3_M_RESET] = { 0x36c8, 1 },
-+	[SFAB_CE3_S_RESET] = { 0x36c8, 0 },
-+	[CE3_SLEEP_RESET] = { 0x36d0, 7 },
-+	[PCIE_1_M_RESET] = { 0x3a98, 1 },
-+	[PCIE_1_S_RESET] = { 0x3a98, 0 },
-+	[PCIE_1_EXT_RESET] = { 0x3a9c, 6 },
-+	[PCIE_1_PHY_RESET] = { 0x3a9c, 5 },
-+	[PCIE_1_PCI_RESET] = { 0x3a9c, 4 },
-+	[PCIE_1_POR_RESET] = { 0x3a9c, 3 },
-+	[PCIE_1_HCLK_RESET] = { 0x3a9c, 2 },
-+	[PCIE_1_ACLK_RESET] = { 0x3a9c, 0 },
-+	[PCIE_2_M_RESET] = { 0x3ad8, 1 },
-+	[PCIE_2_S_RESET] = { 0x3ad8, 0 },
-+	[PCIE_2_EXT_RESET] = { 0x3adc, 6 },
-+	[PCIE_2_PHY_RESET] = { 0x3adc, 5 },
-+	[PCIE_2_PCI_RESET] = { 0x3adc, 4 },
-+	[PCIE_2_POR_RESET] = { 0x3adc, 3 },
-+	[PCIE_2_HCLK_RESET] = { 0x3adc, 2 },
-+	[PCIE_2_ACLK_RESET] = { 0x3adc, 0 },
-+	[SFAB_USB30_S_RESET] = { 0x3b54, 1 },
-+	[SFAB_USB30_M_RESET] = { 0x3b54, 0 },
-+	[USB30_0_PORT2_HS_PHY_RESET] = { 0x3b50, 5 },
-+	[USB30_0_MASTER_RESET] = { 0x3b50, 4 },
-+	[USB30_0_SLEEP_RESET] = { 0x3b50, 3 },
-+	[USB30_0_UTMI_PHY_RESET] = { 0x3b50, 2 },
-+	[USB30_0_POWERON_RESET] = { 0x3b50, 1 },
-+	[USB30_0_PHY_RESET] = { 0x3b50, 0 },
-+	[USB30_1_MASTER_RESET] = { 0x3b58, 4 },
-+	[USB30_1_SLEEP_RESET] = { 0x3b58, 3 },
-+	[USB30_1_UTMI_PHY_RESET] = { 0x3b58, 2 },
-+	[USB30_1_POWERON_RESET] = { 0x3b58, 1 },
-+	[USB30_1_PHY_RESET] = { 0x3b58, 0 },
-+	[NSSFB0_RESET] = { 0x3b60, 6 },
-+	[NSSFB1_RESET] = { 0x3b60, 7 },
-+};
-+
-+static const struct regmap_config gcc_ipq806x_regmap_config = {
-+	.reg_bits	= 32,
-+	.reg_stride	= 4,
-+	.val_bits	= 32,
-+	.max_register	= 0x3e40,
-+	.fast_io	= true,
-+};
-+
-+static const struct qcom_cc_desc gcc_ipq806x_desc = {
-+	.config = &gcc_ipq806x_regmap_config,
-+	.clks = gcc_ipq806x_clks,
-+	.num_clks = ARRAY_SIZE(gcc_ipq806x_clks),
-+	.resets = gcc_ipq806x_resets,
-+	.num_resets = ARRAY_SIZE(gcc_ipq806x_resets),
-+};
-+
-+static const struct of_device_id gcc_ipq806x_match_table[] = {
-+	{ .compatible = "qcom,gcc-ipq8064" },
-+	{ }
-+};
-+MODULE_DEVICE_TABLE(of, gcc_ipq806x_match_table);
-+
-+static int gcc_ipq806x_probe(struct platform_device *pdev)
-+{
-+	struct clk *clk;
-+	struct device *dev = &pdev->dev;
-+
-+	/* Temporary until RPM clocks supported */
-+	clk = clk_register_fixed_rate(dev, "cxo", NULL, CLK_IS_ROOT, 25000000);
-+	if (IS_ERR(clk))
-+		return PTR_ERR(clk);
-+
-+	clk = clk_register_fixed_rate(dev, "pxo", NULL, CLK_IS_ROOT, 25000000);
-+	if (IS_ERR(clk))
-+		return PTR_ERR(clk);
-+
-+	return qcom_cc_probe(pdev, &gcc_ipq806x_desc);
-+}
-+
-+static int gcc_ipq806x_remove(struct platform_device *pdev)
-+{
-+	qcom_cc_remove(pdev);
-+	return 0;
-+}
-+
-+static struct platform_driver gcc_ipq806x_driver = {
-+	.probe		= gcc_ipq806x_probe,
-+	.remove		= gcc_ipq806x_remove,
-+	.driver		= {
-+		.name	= "gcc-ipq806x",
-+		.owner	= THIS_MODULE,
-+		.of_match_table = gcc_ipq806x_match_table,
-+	},
-+};
-+
-+static int __init gcc_ipq806x_init(void)
-+{
-+	return platform_driver_register(&gcc_ipq806x_driver);
-+}
-+core_initcall(gcc_ipq806x_init);
-+
-+static void __exit gcc_ipq806x_exit(void)
-+{
-+	platform_driver_unregister(&gcc_ipq806x_driver);
-+}
-+module_exit(gcc_ipq806x_exit);
-+
-+MODULE_DESCRIPTION("QCOM GCC IPQ806x Driver");
-+MODULE_LICENSE("GPL v2");
-+MODULE_ALIAS("platform:gcc-ipq806x");
---- /dev/null
-+++ b/include/dt-bindings/clock/qcom,gcc-ipq806x.h
-@@ -0,0 +1,293 @@
-+/*
-+ * Copyright (c) 2014, The Linux Foundation. All rights reserved.
-+ *
-+ * This software is licensed under the terms of the GNU General Public
-+ * License version 2, as published by the Free Software Foundation, and
-+ * may be copied, distributed, and modified under those terms.
-+ *
-+ * 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 _DT_BINDINGS_CLK_GCC_IPQ806X_H
-+#define _DT_BINDINGS_CLK_GCC_IPQ806X_H
-+
-+#define AFAB_CLK_SRC				0
-+#define QDSS_STM_CLK				1
-+#define SCSS_A_CLK				2
-+#define SCSS_H_CLK				3
-+#define AFAB_CORE_CLK				4
-+#define SCSS_XO_SRC_CLK				5
-+#define AFAB_EBI1_CH0_A_CLK			6
-+#define AFAB_EBI1_CH1_A_CLK			7
-+#define AFAB_AXI_S0_FCLK			8
-+#define AFAB_AXI_S1_FCLK			9
-+#define AFAB_AXI_S2_FCLK			10
-+#define AFAB_AXI_S3_FCLK			11
-+#define AFAB_AXI_S4_FCLK			12
-+#define SFAB_CORE_CLK				13
-+#define SFAB_AXI_S0_FCLK			14
-+#define SFAB_AXI_S1_FCLK			15
-+#define SFAB_AXI_S2_FCLK			16
-+#define SFAB_AXI_S3_FCLK			17
-+#define SFAB_AXI_S4_FCLK			18
-+#define SFAB_AXI_S5_FCLK			19
-+#define SFAB_AHB_S0_FCLK			20
-+#define SFAB_AHB_S1_FCLK			21
-+#define SFAB_AHB_S2_FCLK			22
-+#define SFAB_AHB_S3_FCLK			23
-+#define SFAB_AHB_S4_FCLK			24
-+#define SFAB_AHB_S5_FCLK			25
-+#define SFAB_AHB_S6_FCLK			26
-+#define SFAB_AHB_S7_FCLK			27
-+#define QDSS_AT_CLK_SRC				28
-+#define QDSS_AT_CLK				29
-+#define QDSS_TRACECLKIN_CLK_SRC			30
-+#define QDSS_TRACECLKIN_CLK			31
-+#define QDSS_TSCTR_CLK_SRC			32
-+#define QDSS_TSCTR_CLK				33
-+#define SFAB_ADM0_M0_A_CLK			34
-+#define SFAB_ADM0_M1_A_CLK			35
-+#define SFAB_ADM0_M2_H_CLK			36
-+#define ADM0_CLK				37
-+#define ADM0_PBUS_CLK				38
-+#define IMEM0_A_CLK				39
-+#define QDSS_H_CLK				40
-+#define PCIE_A_CLK				41
-+#define PCIE_AUX_CLK				42
-+#define PCIE_H_CLK				43
-+#define PCIE_PHY_CLK				44
-+#define SFAB_CLK_SRC				45
-+#define SFAB_LPASS_Q6_A_CLK			46
-+#define SFAB_AFAB_M_A_CLK			47
-+#define AFAB_SFAB_M0_A_CLK			48
-+#define AFAB_SFAB_M1_A_CLK			49
-+#define SFAB_SATA_S_H_CLK			50
-+#define DFAB_CLK_SRC				51
-+#define DFAB_CLK				52
-+#define SFAB_DFAB_M_A_CLK			53
-+#define DFAB_SFAB_M_A_CLK			54
-+#define DFAB_SWAY0_H_CLK			55
-+#define DFAB_SWAY1_H_CLK			56
-+#define DFAB_ARB0_H_CLK				57
-+#define DFAB_ARB1_H_CLK				58
-+#define PPSS_H_CLK				59
-+#define PPSS_PROC_CLK				60
-+#define PPSS_TIMER0_CLK				61
-+#define PPSS_TIMER1_CLK				62
-+#define PMEM_A_CLK				63
-+#define DMA_BAM_H_CLK				64
-+#define SIC_H_CLK				65
-+#define SPS_TIC_H_CLK				66
-+#define CFPB_2X_CLK_SRC				67
-+#define CFPB_CLK				68
-+#define CFPB0_H_CLK				69
-+#define CFPB1_H_CLK				70
-+#define CFPB2_H_CLK				71
-+#define SFAB_CFPB_M_H_CLK			72
-+#define CFPB_MASTER_H_CLK			73
-+#define SFAB_CFPB_S_H_CLK			74
-+#define CFPB_SPLITTER_H_CLK			75
-+#define TSIF_H_CLK				76
-+#define TSIF_INACTIVITY_TIMERS_CLK		77
-+#define TSIF_REF_SRC				78
-+#define TSIF_REF_CLK				79
-+#define CE1_H_CLK				80
-+#define CE1_CORE_CLK				81
-+#define CE1_SLEEP_CLK				82
-+#define CE2_H_CLK				83
-+#define CE2_CORE_CLK				84
-+#define SFPB_H_CLK_SRC				85
-+#define SFPB_H_CLK				86
-+#define SFAB_SFPB_M_H_CLK			87
-+#define SFAB_SFPB_S_H_CLK			88
-+#define RPM_PROC_CLK				89
-+#define RPM_BUS_H_CLK				90
-+#define RPM_SLEEP_CLK				91
-+#define RPM_TIMER_CLK				92
-+#define RPM_MSG_RAM_H_CLK			93
-+#define PMIC_ARB0_H_CLK				94
-+#define PMIC_ARB1_H_CLK				95
-+#define PMIC_SSBI2_SRC				96
-+#define PMIC_SSBI2_CLK				97
-+#define SDC1_H_CLK				98
-+#define SDC2_H_CLK				99
-+#define SDC3_H_CLK				100
-+#define SDC4_H_CLK				101
-+#define SDC1_SRC				102
-+#define SDC1_CLK				103
-+#define SDC2_SRC				104
-+#define SDC2_CLK				105
-+#define SDC3_SRC				106
-+#define SDC3_CLK				107
-+#define SDC4_SRC				108
-+#define SDC4_CLK				109
-+#define USB_HS1_H_CLK				110
-+#define USB_HS1_XCVR_SRC			111
-+#define USB_HS1_XCVR_CLK			112
-+#define USB_HSIC_H_CLK				113
-+#define USB_HSIC_XCVR_SRC			114
-+#define USB_HSIC_XCVR_CLK			115
-+#define USB_HSIC_SYSTEM_CLK_SRC			116
-+#define USB_HSIC_SYSTEM_CLK			117
-+#define CFPB0_C0_H_CLK				118
-+#define CFPB0_D0_H_CLK				119
-+#define CFPB0_C1_H_CLK				120
-+#define CFPB0_D1_H_CLK				121
-+#define USB_FS1_H_CLK				122
-+#define USB_FS1_XCVR_SRC			123
-+#define USB_FS1_XCVR_CLK			124
-+#define USB_FS1_SYSTEM_CLK			125
-+#define GSBI_COMMON_SIM_SRC			126
-+#define GSBI1_H_CLK				127
-+#define GSBI2_H_CLK				128
-+#define GSBI3_H_CLK				129
-+#define GSBI4_H_CLK				130
-+#define GSBI5_H_CLK				131
-+#define GSBI6_H_CLK				132
-+#define GSBI7_H_CLK				133
-+#define GSBI1_QUP_SRC				134
-+#define GSBI1_QUP_CLK				135
-+#define GSBI2_QUP_SRC				136
-+#define GSBI2_QUP_CLK				137
-+#define GSBI3_QUP_SRC				138
-+#define GSBI3_QUP_CLK				139
-+#define GSBI4_QUP_SRC				140
-+#define GSBI4_QUP_CLK				141
-+#define GSBI5_QUP_SRC				142
-+#define GSBI5_QUP_CLK				143
-+#define GSBI6_QUP_SRC				144
-+#define GSBI6_QUP_CLK				145
-+#define GSBI7_QUP_SRC				146
-+#define GSBI7_QUP_CLK				147
-+#define GSBI1_UART_SRC				148
-+#define GSBI1_UART_CLK				149
-+#define GSBI2_UART_SRC				150
-+#define GSBI2_UART_CLK				151
-+#define GSBI3_UART_SRC				152
-+#define GSBI3_UART_CLK				153
-+#define GSBI4_UART_SRC				154
-+#define GSBI4_UART_CLK				155
-+#define GSBI5_UART_SRC				156
-+#define GSBI5_UART_CLK				157
-+#define GSBI6_UART_SRC				158
-+#define GSBI6_UART_CLK				159
-+#define GSBI7_UART_SRC				160
-+#define GSBI7_UART_CLK				161
-+#define GSBI1_SIM_CLK				162
-+#define GSBI2_SIM_CLK				163
-+#define GSBI3_SIM_CLK				164
-+#define GSBI4_SIM_CLK				165
-+#define GSBI5_SIM_CLK				166
-+#define GSBI6_SIM_CLK				167
-+#define GSBI7_SIM_CLK				168
-+#define USB_HSIC_HSIC_CLK_SRC			169
-+#define USB_HSIC_HSIC_CLK			170
-+#define USB_HSIC_HSIO_CAL_CLK			171
-+#define SPDM_CFG_H_CLK				172
-+#define SPDM_MSTR_H_CLK				173
-+#define SPDM_FF_CLK_SRC				174
-+#define SPDM_FF_CLK				175
-+#define SEC_CTRL_CLK				176
-+#define SEC_CTRL_ACC_CLK_SRC			177
-+#define SEC_CTRL_ACC_CLK			178
-+#define TLMM_H_CLK				179
-+#define TLMM_CLK				180
-+#define SATA_H_CLK				181
-+#define SATA_CLK_SRC				182
-+#define SATA_RXOOB_CLK				183
-+#define SATA_PMALIVE_CLK			184
-+#define SATA_PHY_REF_CLK			185
-+#define SATA_A_CLK				186
-+#define SATA_PHY_CFG_CLK			187
-+#define TSSC_CLK_SRC				188
-+#define TSSC_CLK				189
-+#define PDM_SRC					190
-+#define PDM_CLK					191
-+#define GP0_SRC					192
-+#define GP0_CLK					193
-+#define GP1_SRC					194
-+#define GP1_CLK					195
-+#define GP2_SRC					196
-+#define GP2_CLK					197
-+#define MPM_CLK					198
-+#define EBI1_CLK_SRC				199
-+#define EBI1_CH0_CLK				200
-+#define EBI1_CH1_CLK				201
-+#define EBI1_2X_CLK				202
-+#define EBI1_CH0_DQ_CLK				203
-+#define EBI1_CH1_DQ_CLK				204
-+#define EBI1_CH0_CA_CLK				205
-+#define EBI1_CH1_CA_CLK				206
-+#define EBI1_XO_CLK				207
-+#define SFAB_SMPSS_S_H_CLK			208
-+#define PRNG_SRC				209
-+#define PRNG_CLK				210
-+#define PXO_SRC					211
-+#define SPDM_CY_PORT0_CLK			212
-+#define SPDM_CY_PORT1_CLK			213
-+#define SPDM_CY_PORT2_CLK			214
-+#define SPDM_CY_PORT3_CLK			215
-+#define SPDM_CY_PORT4_CLK			216
-+#define SPDM_CY_PORT5_CLK			217
-+#define SPDM_CY_PORT6_CLK			218
-+#define SPDM_CY_PORT7_CLK			219
-+#define PLL0					220
-+#define PLL0_VOTE				221
-+#define PLL3					222
-+#define PLL3_VOTE				223
-+#define PLL4					224
-+#define PLL4_VOTE				225
-+#define PLL8					226
-+#define PLL8_VOTE				227
-+#define PLL9					228
-+#define PLL10					229
-+#define PLL11					230
-+#define PLL12					231
-+#define PLL14					232
-+#define PLL14_VOTE				233
-+#define PLL18					234
-+#define CE5_SRC					235
-+#define CE5_H_CLK				236
-+#define CE5_CORE_CLK				237
-+#define CE3_SLEEP_CLK				238
-+#define SFAB_AHB_S8_FCLK			239
-+#define SPDM_CY_PORT8_CLK			246
-+#define PCIE_ALT_REF_SRC			247
-+#define PCIE_ALT_REF_CLK			248
-+#define PCIE_1_A_CLK				249
-+#define PCIE_1_AUX_CLK				250
-+#define PCIE_1_H_CLK				251
-+#define PCIE_1_PHY_CLK				252
-+#define PCIE_1_ALT_REF_SRC			253
-+#define PCIE_1_ALT_REF_CLK			254
-+#define PCIE_2_A_CLK				255
-+#define PCIE_2_AUX_CLK				256
-+#define PCIE_2_H_CLK				257
-+#define PCIE_2_PHY_CLK				258
-+#define PCIE_2_ALT_REF_SRC			259
-+#define PCIE_2_ALT_REF_CLK			260
-+#define EBI2_CLK				261
-+#define USB30_SLEEP_CLK				262
-+#define USB30_UTMI_SRC				263
-+#define USB30_0_UTMI_CLK			264
-+#define USB30_1_UTMI_CLK			264
-+#define USB30_MASTER_SRC			265
-+#define USB30_0_MASTER_CLK			266
-+#define USB30_1_MASTER_CLK			267
-+#define GMAC_CORE1_CLK_SRC			268
-+#define GMAC_CORE2_CLK_SRC			269
-+#define GMAC_CORE3_CLK_SRC			270
-+#define GMAC_CORE4_CLK_SRC			271
-+#define GMAC_CORE1_CLK				272
-+#define GMAC_CORE2_CLK				273
-+#define GMAC_CORE3_CLK				274
-+#define GMAC_CORE4_CLK				275
-+#define UBI32_CORE1_CLK_SRC			276
-+#define UBI32_CORE2_CLK_SRC			277
-+#define UBI32_CORE1_CLK				278
-+#define UBI32_CORE2_CLK				279
-+
-+#endif
---- /dev/null
-+++ b/include/dt-bindings/reset/qcom,gcc-ipq806x.h
-@@ -0,0 +1,132 @@
-+/*
-+ * Copyright (c) 2014, The Linux Foundation. All rights reserved.
-+ *
-+ * This software is licensed under the terms of the GNU General Public
-+ * License version 2, as published by the Free Software Foundation, and
-+ * may be copied, distributed, and modified under those terms.
-+ *
-+ * 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 _DT_BINDINGS_RESET_IPQ_806X_H
-+#define _DT_BINDINGS_RESET_IPQ_806X_H
-+
-+#define QDSS_STM_RESET					0
-+#define AFAB_SMPSS_S_RESET				1
-+#define AFAB_SMPSS_M1_RESET				2
-+#define AFAB_SMPSS_M0_RESET				3
-+#define AFAB_EBI1_CH0_RESET				4
-+#define AFAB_EBI1_CH1_RESET				5
-+#define SFAB_ADM0_M0_RESET				6
-+#define SFAB_ADM0_M1_RESET				7
-+#define SFAB_ADM0_M2_RESET				8
-+#define ADM0_C2_RESET					9
-+#define ADM0_C1_RESET					10
-+#define ADM0_C0_RESET					11
-+#define ADM0_PBUS_RESET					12
-+#define ADM0_RESET					13
-+#define QDSS_CLKS_SW_RESET				14
-+#define QDSS_POR_RESET					15
-+#define QDSS_TSCTR_RESET				16
-+#define QDSS_HRESET_RESET				17
-+#define QDSS_AXI_RESET					18
-+#define QDSS_DBG_RESET					19
-+#define SFAB_PCIE_M_RESET				20
-+#define SFAB_PCIE_S_RESET				21
-+#define PCIE_EXT_RESET					22
-+#define PCIE_PHY_RESET					23
-+#define PCIE_PCI_RESET					24
-+#define PCIE_POR_RESET					25
-+#define PCIE_HCLK_RESET					26
-+#define PCIE_ACLK_RESET					27
-+#define SFAB_LPASS_RESET				28
-+#define SFAB_AFAB_M_RESET				29
-+#define AFAB_SFAB_M0_RESET				30
-+#define AFAB_SFAB_M1_RESET				31
-+#define SFAB_SATA_S_RESET				32
-+#define SFAB_DFAB_M_RESET				33
-+#define DFAB_SFAB_M_RESET				34
-+#define DFAB_SWAY0_RESET				35
-+#define DFAB_SWAY1_RESET				36
-+#define DFAB_ARB0_RESET					37
-+#define DFAB_ARB1_RESET					38
-+#define PPSS_PROC_RESET					39
-+#define PPSS_RESET					40
-+#define DMA_BAM_RESET					41
-+#define SPS_TIC_H_RESET					42
-+#define SFAB_CFPB_M_RESET				43
-+#define SFAB_CFPB_S_RESET				44
-+#define TSIF_H_RESET					45
-+#define CE1_H_RESET					46
-+#define CE1_CORE_RESET					47
-+#define CE1_SLEEP_RESET					48
-+#define CE2_H_RESET					49
-+#define CE2_CORE_RESET					50
-+#define SFAB_SFPB_M_RESET				51
-+#define SFAB_SFPB_S_RESET				52
-+#define RPM_PROC_RESET					53
-+#define PMIC_SSBI2_RESET				54
-+#define SDC1_RESET					55
-+#define SDC2_RESET					56
-+#define SDC3_RESET					57
-+#define SDC4_RESET					58
-+#define USB_HS1_RESET					59
-+#define USB_HSIC_RESET					60
-+#define USB_FS1_XCVR_RESET				61
-+#define USB_FS1_RESET					62
-+#define GSBI1_RESET					63
-+#define GSBI2_RESET					64
-+#define GSBI3_RESET					65
-+#define GSBI4_RESET					66
-+#define GSBI5_RESET					67
-+#define GSBI6_RESET					68
-+#define GSBI7_RESET					69
-+#define SPDM_RESET					70
-+#define SEC_CTRL_RESET					71
-+#define TLMM_H_RESET					72
-+#define SFAB_SATA_M_RESET				73
-+#define SATA_RESET					74
-+#define TSSC_RESET					75
-+#define PDM_RESET					76
-+#define MPM_H_RESET					77
-+#define MPM_RESET					78
-+#define SFAB_SMPSS_S_RESET				79
-+#define PRNG_RESET					80
-+#define SFAB_CE3_M_RESET				81
-+#define SFAB_CE3_S_RESET				82
-+#define CE3_SLEEP_RESET					83
-+#define PCIE_1_M_RESET					84
-+#define PCIE_1_S_RESET					85
-+#define PCIE_1_EXT_RESET				86
-+#define PCIE_1_PHY_RESET				87
-+#define PCIE_1_PCI_RESET				88
-+#define PCIE_1_POR_RESET				89
-+#define PCIE_1_HCLK_RESET				90
-+#define PCIE_1_ACLK_RESET				91
-+#define PCIE_2_M_RESET					92
-+#define PCIE_2_S_RESET					93
-+#define PCIE_2_EXT_RESET				94
-+#define PCIE_2_PHY_RESET				95
-+#define PCIE_2_PCI_RESET				96
-+#define PCIE_2_POR_RESET				97
-+#define PCIE_2_HCLK_RESET				98
-+#define PCIE_2_ACLK_RESET				99
-+#define SFAB_USB30_S_RESET				100
-+#define SFAB_USB30_M_RESET				101
-+#define USB30_0_PORT2_HS_PHY_RESET			102
-+#define USB30_0_MASTER_RESET				103
-+#define USB30_0_SLEEP_RESET				104
-+#define USB30_0_UTMI_PHY_RESET				105
-+#define USB30_0_POWERON_RESET				106
-+#define USB30_0_PHY_RESET				107
-+#define USB30_1_MASTER_RESET				108
-+#define USB30_1_SLEEP_RESET				109
-+#define USB30_1_UTMI_PHY_RESET				110
-+#define USB30_1_POWERON_RESET				111
-+#define USB30_1_PHY_RESET				112
-+#define NSSFB0_RESET					113
-+#define NSSFB1_RESET					114
-+#endif
diff --git a/target/linux/ipq806x/patches/0126-clk-Add-safe-switch-hook.patch b/target/linux/ipq806x/patches/0126-clk-Add-safe-switch-hook.patch
deleted file mode 100644
index a78319f..0000000
--- a/target/linux/ipq806x/patches/0126-clk-Add-safe-switch-hook.patch
+++ /dev/null
@@ -1,146 +0,0 @@
-From b7b3ceec506179d59e46e3a8ea8b370872cc7fcb Mon Sep 17 00:00:00 2001
-From: Stephen Boyd <sboyd@codeaurora.org>
-Date: Mon, 31 Mar 2014 16:52:29 -0700
-Subject: [PATCH 126/182] clk: Add safe switch hook
-
-Sometimes clocks can't accept their parent source turning off
-while the source is reprogrammed to a different rate. Most
-notably CPU clocks require a way to switch away from the current
-PLL they're running on, reprogram that PLL to a new rate, and
-then switch back to the PLL with the new rate once they're done.
-Add a hook that drivers can implement allowing them to return a
-'safe parent' that they can switch their parent to while the
-upstream source is reprogrammed to support this.
-
-Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
----
- drivers/clk/clk.c            |   53 ++++++++++++++++++++++++++++++++++++------
- include/linux/clk-private.h  |    2 ++
- include/linux/clk-provider.h |    1 +
- 3 files changed, 49 insertions(+), 7 deletions(-)
-
---- a/drivers/clk/clk.c
-+++ b/drivers/clk/clk.c
-@@ -1356,6 +1356,7 @@ static void clk_calc_subtree(struct clk
- 			     struct clk *new_parent, u8 p_index)
- {
- 	struct clk *child;
-+	struct clk *parent;
- 
- 	clk->new_rate = new_rate;
- 	clk->new_parent = new_parent;
-@@ -1365,6 +1366,17 @@ static void clk_calc_subtree(struct clk
- 	if (new_parent && new_parent != clk->parent)
- 		new_parent->new_child = clk;
- 
-+	if (clk->ops->get_safe_parent) {
-+		parent = clk->ops->get_safe_parent(clk->hw);
-+		if (parent) {
-+			p_index = clk_fetch_parent_index(clk, parent);
-+			clk->safe_parent_index = p_index;
-+			clk->safe_parent = parent;
-+		}
-+	} else {
-+		clk->safe_parent = NULL;
-+	}
-+
- 	hlist_for_each_entry(child, &clk->children, child_node) {
- 		if (child->ops->recalc_rate)
- 			child->new_rate = child->ops->recalc_rate(child->hw, new_rate);
-@@ -1450,14 +1462,42 @@ out:
- static struct clk *clk_propagate_rate_change(struct clk *clk, unsigned long event)
- {
- 	struct clk *child, *tmp_clk, *fail_clk = NULL;
-+	struct clk *old_parent;
- 	int ret = NOTIFY_DONE;
- 
--	if (clk->rate == clk->new_rate)
-+	if (clk->rate == clk->new_rate && event != POST_RATE_CHANGE)
- 		return NULL;
- 
-+	switch (event) {
-+	case PRE_RATE_CHANGE:
-+		if (clk->safe_parent)
-+			clk->ops->set_parent(clk->hw, clk->safe_parent_index);
-+		break;
-+	case POST_RATE_CHANGE:
-+		if (clk->safe_parent) {
-+			old_parent = __clk_set_parent_before(clk,
-+							     clk->new_parent);
-+			if (clk->ops->set_rate_and_parent) {
-+				clk->ops->set_rate_and_parent(clk->hw,
-+						clk->new_rate,
-+						clk->new_parent ?
-+						clk->new_parent->rate : 0,
-+						clk->new_parent_index);
-+			} else if (clk->ops->set_parent) {
-+				clk->ops->set_parent(clk->hw,
-+						clk->new_parent_index);
-+			}
-+			__clk_set_parent_after(clk, clk->new_parent,
-+					       old_parent);
-+		}
-+		break;
-+	}
-+
- 	if (clk->notifier_count) {
--		ret = __clk_notify(clk, event, clk->rate, clk->new_rate);
--		if (ret & NOTIFY_STOP_MASK)
-+		if (event != POST_RATE_CHANGE)
-+			ret = __clk_notify(clk, event, clk->rate,
-+					   clk->new_rate);
-+		if (ret & NOTIFY_STOP_MASK && event != POST_RATE_CHANGE)
- 			fail_clk = clk;
- 	}
- 
-@@ -1500,7 +1540,8 @@ static void clk_change_rate(struct clk *
- 	else if (clk->parent)
- 		best_parent_rate = clk->parent->rate;
- 
--	if (clk->new_parent && clk->new_parent != clk->parent) {
-+	if (clk->new_parent && clk->new_parent != clk->parent &&
-+			!clk->safe_parent) {
- 		old_parent = __clk_set_parent_before(clk, clk->new_parent);
- 
- 		if (clk->ops->set_rate_and_parent) {
-@@ -1523,9 +1564,6 @@ static void clk_change_rate(struct clk *
- 	else
- 		clk->rate = best_parent_rate;
- 
--	if (clk->notifier_count && old_rate != clk->rate)
--		__clk_notify(clk, POST_RATE_CHANGE, old_rate, clk->rate);
--
- 	/*
- 	 * Use safe iteration, as change_rate can actually swap parents
- 	 * for certain clock types.
-@@ -1603,6 +1641,7 @@ int clk_set_rate(struct clk *clk, unsign
- 	/* change the rates */
- 	clk_change_rate(top);
- 
-+	clk_propagate_rate_change(top, POST_RATE_CHANGE);
- out:
- 	clk_prepare_unlock();
- 
---- a/include/linux/clk-private.h
-+++ b/include/linux/clk-private.h
-@@ -38,8 +38,10 @@ struct clk {
- 	struct clk		**parents;
- 	u8			num_parents;
- 	u8			new_parent_index;
-+	u8			safe_parent_index;
- 	unsigned long		rate;
- 	unsigned long		new_rate;
-+	struct clk		*safe_parent;
- 	struct clk		*new_parent;
- 	struct clk		*new_child;
- 	unsigned long		flags;
---- a/include/linux/clk-provider.h
-+++ b/include/linux/clk-provider.h
-@@ -157,6 +157,7 @@ struct clk_ops {
- 					struct clk **best_parent_clk);
- 	int		(*set_parent)(struct clk_hw *hw, u8 index);
- 	u8		(*get_parent)(struct clk_hw *hw);
-+	struct clk	*(*get_safe_parent)(struct clk_hw *hw);
- 	int		(*set_rate)(struct clk_hw *hw, unsigned long,
- 				    unsigned long);
- 	int		(*set_rate_and_parent)(struct clk_hw *hw,
diff --git a/target/linux/ipq806x/patches/0127-clk-qcom-Add-support-for-setting-rates-on-PLLs.patch b/target/linux/ipq806x/patches/0127-clk-qcom-Add-support-for-setting-rates-on-PLLs.patch
deleted file mode 100644
index 07ffdac..0000000
--- a/target/linux/ipq806x/patches/0127-clk-qcom-Add-support-for-setting-rates-on-PLLs.patch
+++ /dev/null
@@ -1,148 +0,0 @@
-From fd06a2cc719296f65a280cb1533b125f63cfcb34 Mon Sep 17 00:00:00 2001
-From: Stephen Boyd <sboyd@codeaurora.org>
-Date: Mon, 28 Apr 2014 15:58:11 -0700
-Subject: [PATCH 127/182] clk: qcom: Add support for setting rates on PLLs
-
-Some PLLs may require changing their rate at runtime. Add support
-for these PLLs.
-
-Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
----
- drivers/clk/qcom/clk-pll.c |   68 +++++++++++++++++++++++++++++++++++++++++++-
- drivers/clk/qcom/clk-pll.h |   20 +++++++++++++
- 2 files changed, 87 insertions(+), 1 deletion(-)
-
---- a/drivers/clk/qcom/clk-pll.c
-+++ b/drivers/clk/qcom/clk-pll.c
-@@ -97,7 +97,7 @@ static unsigned long
- clk_pll_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)
- {
- 	struct clk_pll *pll = to_clk_pll(hw);
--	u32 l, m, n;
-+	u32 l, m, n, config;
- 	unsigned long rate;
- 	u64 tmp;
- 
-@@ -116,13 +116,79 @@ clk_pll_recalc_rate(struct clk_hw *hw, u
- 		do_div(tmp, n);
- 		rate += tmp;
- 	}
-+	if (pll->post_div_width) {
-+		regmap_read(pll->clkr.regmap, pll->config_reg, &config);
-+		config >>= pll->post_div_shift;
-+		config &= BIT(pll->post_div_width) - 1;
-+		rate /= config + 1;
-+	}
-+
- 	return rate;
- }
- 
-+static const
-+struct pll_freq_tbl *find_freq(const struct pll_freq_tbl *f, unsigned long rate)
-+{
-+	if (!f)
-+		return NULL;
-+
-+	for (; f->freq; f++)
-+		if (rate <= f->freq)
-+			return f;
-+
-+	return NULL;
-+}
-+
-+static long
-+clk_pll_determine_rate(struct clk_hw *hw, unsigned long rate,
-+		       unsigned long *p_rate, struct clk **p)
-+{
-+	struct clk_pll *pll = to_clk_pll(hw);
-+	const struct pll_freq_tbl *f;
-+
-+	f = find_freq(pll->freq_tbl, rate);
-+	if (!f)
-+		return clk_pll_recalc_rate(hw, *p_rate);
-+
-+	return f->freq;
-+}
-+
-+static int
-+clk_pll_set_rate(struct clk_hw *hw, unsigned long rate, unsigned long p_rate)
-+{
-+	struct clk_pll *pll = to_clk_pll(hw);
-+	const struct pll_freq_tbl *f;
-+	bool enabled;
-+	u32 mode;
-+	u32 enable_mask = PLL_OUTCTRL | PLL_BYPASSNL | PLL_RESET_N;
-+
-+	f = find_freq(pll->freq_tbl, rate);
-+	if (!f)
-+		return -EINVAL;
-+
-+	regmap_read(pll->clkr.regmap, pll->mode_reg, &mode);
-+	enabled = (mode & enable_mask) == enable_mask;
-+
-+	if (enabled)
-+		clk_pll_disable(hw);
-+
-+	regmap_update_bits(pll->clkr.regmap, pll->l_reg, 0x3ff, f->l);
-+	regmap_update_bits(pll->clkr.regmap, pll->m_reg, 0x7ffff, f->m);
-+	regmap_update_bits(pll->clkr.regmap, pll->n_reg, 0x7ffff, f->n);
-+	regmap_write(pll->clkr.regmap, pll->config_reg, f->ibits);
-+
-+	if (enabled)
-+		clk_pll_enable(hw);
-+
-+	return 0;
-+}
-+
- const struct clk_ops clk_pll_ops = {
- 	.enable = clk_pll_enable,
- 	.disable = clk_pll_disable,
- 	.recalc_rate = clk_pll_recalc_rate,
-+	.determine_rate = clk_pll_determine_rate,
-+	.set_rate = clk_pll_set_rate,
- };
- EXPORT_SYMBOL_GPL(clk_pll_ops);
- 
---- a/drivers/clk/qcom/clk-pll.h
-+++ b/drivers/clk/qcom/clk-pll.h
-@@ -18,6 +18,21 @@
- #include "clk-regmap.h"
- 
- /**
-+ * struct pll_freq_tbl - PLL frequency table
-+ * @l: L value
-+ * @m: M value
-+ * @n: N value
-+ * @ibits: internal values
-+ */
-+struct pll_freq_tbl {
-+	unsigned long freq;
-+	u16 l;
-+	u16 m;
-+	u16 n;
-+	u32 ibits;
-+};
-+
-+/**
-  * struct clk_pll - phase locked loop (PLL)
-  * @l_reg: L register
-  * @m_reg: M register
-@@ -26,6 +41,7 @@
-  * @mode_reg: mode register
-  * @status_reg: status register
-  * @status_bit: ANDed with @status_reg to determine if PLL is enabled
-+ * @freq_tbl: PLL frequency table
-  * @hw: handle between common and hardware-specific interfaces
-  */
- struct clk_pll {
-@@ -36,6 +52,10 @@ struct clk_pll {
- 	u32	mode_reg;
- 	u32	status_reg;
- 	u8	status_bit;
-+	u8	post_div_width;
-+	u8	post_div_shift;
-+
-+	const struct pll_freq_tbl *freq_tbl;
- 
- 	struct clk_regmap clkr;
- };
diff --git a/target/linux/ipq806x/patches/0128-clk-qcom-Add-support-for-banked-MD-RCGs.patch b/target/linux/ipq806x/patches/0128-clk-qcom-Add-support-for-banked-MD-RCGs.patch
deleted file mode 100644
index 38104b9..0000000
--- a/target/linux/ipq806x/patches/0128-clk-qcom-Add-support-for-banked-MD-RCGs.patch
+++ /dev/null
@@ -1,308 +0,0 @@
-From 856324d2daa3246ac62d7920d6a274e1fa35bcf5 Mon Sep 17 00:00:00 2001
-From: Stephen Boyd <sboyd@codeaurora.org>
-Date: Mon, 28 Apr 2014 15:59:16 -0700
-Subject: [PATCH 128/182] clk: qcom: Add support for banked MD RCGs
-
-The banked MD RCGs in global clock control have a different
-register layout than the ones implemented in multimedia clock
-control. Add support for these types of clocks so we can change
-the rates of the UBI32 clocks.
-
-Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
----
- drivers/clk/qcom/clk-rcg.c      |   99 ++++++++++++++++++++-------------------
- drivers/clk/qcom/clk-rcg.h      |    5 +-
- drivers/clk/qcom/mmcc-msm8960.c |   24 +++++++---
- 3 files changed, 73 insertions(+), 55 deletions(-)
-
---- a/drivers/clk/qcom/clk-rcg.c
-+++ b/drivers/clk/qcom/clk-rcg.c
-@@ -67,16 +67,16 @@ static u8 clk_dyn_rcg_get_parent(struct
- {
- 	struct clk_dyn_rcg *rcg = to_clk_dyn_rcg(hw);
- 	int num_parents = __clk_get_num_parents(hw->clk);
--	u32 ns, ctl;
-+	u32 ns, reg;
- 	int bank;
- 	int i;
- 	struct src_sel *s;
- 
--	regmap_read(rcg->clkr.regmap, rcg->clkr.enable_reg, &ctl);
--	bank = reg_to_bank(rcg, ctl);
-+	regmap_read(rcg->clkr.regmap, rcg->bank_reg, &reg);
-+	bank = reg_to_bank(rcg, reg);
- 	s = &rcg->s[bank];
- 
--	regmap_read(rcg->clkr.regmap, rcg->ns_reg, &ns);
-+	regmap_read(rcg->clkr.regmap, rcg->ns_reg[bank], &ns);
- 	ns = ns_to_src(s, ns);
- 
- 	for (i = 0; i < num_parents; i++)
-@@ -192,90 +192,93 @@ static u32 mn_to_reg(struct mn *mn, u32
- 
- static void configure_bank(struct clk_dyn_rcg *rcg, const struct freq_tbl *f)
- {
--	u32 ns, md, ctl, *regp;
-+	u32 ns, md, reg;
- 	int bank, new_bank;
- 	struct mn *mn;
- 	struct pre_div *p;
- 	struct src_sel *s;
- 	bool enabled;
--	u32 md_reg;
--	u32 bank_reg;
-+	u32 md_reg, ns_reg;
- 	bool banked_mn = !!rcg->mn[1].width;
-+	bool banked_p = !!rcg->p[1].pre_div_width;
- 	struct clk_hw *hw = &rcg->clkr.hw;
- 
- 	enabled = __clk_is_enabled(hw->clk);
- 
--	regmap_read(rcg->clkr.regmap, rcg->ns_reg, &ns);
--	regmap_read(rcg->clkr.regmap, rcg->clkr.enable_reg, &ctl);
--
--	if (banked_mn) {
--		regp = &ctl;
--		bank_reg = rcg->clkr.enable_reg;
--	} else {
--		regp = &ns;
--		bank_reg = rcg->ns_reg;
--	}
--
--	bank = reg_to_bank(rcg, *regp);
-+	regmap_read(rcg->clkr.regmap, rcg->bank_reg, &reg);
-+	bank = reg_to_bank(rcg, reg);
- 	new_bank = enabled ? !bank : bank;
- 
-+	ns_reg = rcg->ns_reg[new_bank];
-+	regmap_read(rcg->clkr.regmap, ns_reg, &ns);
-+
- 	if (banked_mn) {
- 		mn = &rcg->mn[new_bank];
- 		md_reg = rcg->md_reg[new_bank];
- 
- 		ns |= BIT(mn->mnctr_reset_bit);
--		regmap_write(rcg->clkr.regmap, rcg->ns_reg, ns);
-+		regmap_write(rcg->clkr.regmap, ns_reg, ns);
- 
- 		regmap_read(rcg->clkr.regmap, md_reg, &md);
- 		md = mn_to_md(mn, f->m, f->n, md);
- 		regmap_write(rcg->clkr.regmap, md_reg, md);
- 
- 		ns = mn_to_ns(mn, f->m, f->n, ns);
--		regmap_write(rcg->clkr.regmap, rcg->ns_reg, ns);
-+		regmap_write(rcg->clkr.regmap, ns_reg, ns);
- 
--		ctl = mn_to_reg(mn, f->m, f->n, ctl);
--		regmap_write(rcg->clkr.regmap, rcg->clkr.enable_reg, ctl);
-+		/* Two NS registers means mode control is in NS register */
-+		if (rcg->ns_reg[0] != rcg->ns_reg[1]) {
-+			ns = mn_to_reg(mn, f->m, f->n, ns);
-+			regmap_write(rcg->clkr.regmap, ns_reg, ns);
-+		} else {
-+			reg = mn_to_reg(mn, f->m, f->n, reg);
-+			regmap_write(rcg->clkr.regmap, rcg->bank_reg, reg);
-+		}
- 
- 		ns &= ~BIT(mn->mnctr_reset_bit);
--		regmap_write(rcg->clkr.regmap, rcg->ns_reg, ns);
--	} else {
-+		regmap_write(rcg->clkr.regmap, ns_reg, ns);
-+	}
-+
-+	if (banked_p) {
- 		p = &rcg->p[new_bank];
- 		ns = pre_div_to_ns(p, f->pre_div - 1, ns);
- 	}
- 
- 	s = &rcg->s[new_bank];
- 	ns = src_to_ns(s, s->parent_map[f->src], ns);
--	regmap_write(rcg->clkr.regmap, rcg->ns_reg, ns);
-+	regmap_write(rcg->clkr.regmap, ns_reg, ns);
- 
- 	if (enabled) {
--		*regp ^= BIT(rcg->mux_sel_bit);
--		regmap_write(rcg->clkr.regmap, bank_reg, *regp);
-+		regmap_read(rcg->clkr.regmap, rcg->bank_reg, &reg);
-+		reg ^= BIT(rcg->mux_sel_bit);
-+		regmap_write(rcg->clkr.regmap, rcg->bank_reg, reg);
- 	}
- }
- 
- static int clk_dyn_rcg_set_parent(struct clk_hw *hw, u8 index)
- {
- 	struct clk_dyn_rcg *rcg = to_clk_dyn_rcg(hw);
--	u32 ns, ctl, md, reg;
-+	u32 ns, md, reg;
- 	int bank;
- 	struct freq_tbl f = { 0 };
- 	bool banked_mn = !!rcg->mn[1].width;
-+	bool banked_p = !!rcg->p[1].pre_div_width;
- 
--	regmap_read(rcg->clkr.regmap, rcg->ns_reg, &ns);
--	regmap_read(rcg->clkr.regmap, rcg->clkr.enable_reg, &ctl);
--	reg = banked_mn ? ctl : ns;
--
-+	regmap_read(rcg->clkr.regmap, rcg->bank_reg, &reg);
- 	bank = reg_to_bank(rcg, reg);
- 
-+	regmap_read(rcg->clkr.regmap, rcg->ns_reg[bank], &ns);
-+
- 	if (banked_mn) {
- 		regmap_read(rcg->clkr.regmap, rcg->md_reg[bank], &md);
- 		f.m = md_to_m(&rcg->mn[bank], md);
- 		f.n = ns_m_to_n(&rcg->mn[bank], ns, f.m);
--	} else {
--		f.pre_div = ns_to_pre_div(&rcg->p[bank], ns) + 1;
- 	}
--	f.src = index;
- 
-+	if (banked_p)
-+		f.pre_div = ns_to_pre_div(&rcg->p[bank], ns) + 1;
-+
-+	f.src = index;
- 	configure_bank(rcg, &f);
- 
- 	return 0;
-@@ -336,28 +339,30 @@ clk_dyn_rcg_recalc_rate(struct clk_hw *h
- 	u32 m, n, pre_div, ns, md, mode, reg;
- 	int bank;
- 	struct mn *mn;
-+	bool banked_p = !!rcg->p[1].pre_div_width;
- 	bool banked_mn = !!rcg->mn[1].width;
- 
--	regmap_read(rcg->clkr.regmap, rcg->ns_reg, &ns);
--
--	if (banked_mn)
--		regmap_read(rcg->clkr.regmap, rcg->clkr.enable_reg, &reg);
--	else
--		reg = ns;
--
-+	regmap_read(rcg->clkr.regmap, rcg->bank_reg, &reg);
- 	bank = reg_to_bank(rcg, reg);
- 
-+	regmap_read(rcg->clkr.regmap, rcg->ns_reg[bank], &ns);
-+	m = n = pre_div = mode = 0;
-+
- 	if (banked_mn) {
- 		mn = &rcg->mn[bank];
- 		regmap_read(rcg->clkr.regmap, rcg->md_reg[bank], &md);
- 		m = md_to_m(mn, md);
- 		n = ns_m_to_n(mn, ns, m);
-+		/* Two NS registers means mode control is in NS register */
-+		if (rcg->ns_reg[0] != rcg->ns_reg[1])
-+			reg = ns;
- 		mode = reg_to_mnctr_mode(mn, reg);
--		return calc_rate(parent_rate, m, n, mode, 0);
--	} else {
--		pre_div = ns_to_pre_div(&rcg->p[bank], ns);
--		return calc_rate(parent_rate, 0, 0, 0, pre_div);
- 	}
-+
-+	if (banked_p)
-+		pre_div = ns_to_pre_div(&rcg->p[bank], ns);
-+
-+	return calc_rate(parent_rate, m, n, mode, pre_div);
- }
- 
- static const
---- a/drivers/clk/qcom/clk-rcg.h
-+++ b/drivers/clk/qcom/clk-rcg.h
-@@ -102,7 +102,7 @@ extern const struct clk_ops clk_rcg_ops;
-  * struct clk_dyn_rcg - root clock generator with glitch free mux
-  *
-  * @mux_sel_bit: bit to switch glitch free mux
-- * @ns_reg: NS register
-+ * @ns_reg: NS0 and NS1 register
-  * @md_reg: MD0 and MD1 register
-  * @mn: mn counter (banked)
-  * @s: source selector (banked)
-@@ -112,8 +112,9 @@ extern const struct clk_ops clk_rcg_ops;
-  *
-  */
- struct clk_dyn_rcg {
--	u32	ns_reg;
-+	u32	ns_reg[2];
- 	u32	md_reg[2];
-+	u32	bank_reg;
- 
- 	u8	mux_sel_bit;
- 
---- a/drivers/clk/qcom/mmcc-msm8960.c
-+++ b/drivers/clk/qcom/mmcc-msm8960.c
-@@ -728,9 +728,11 @@ static struct freq_tbl clk_tbl_gfx2d[] =
- };
- 
- static struct clk_dyn_rcg gfx2d0_src = {
--	.ns_reg = 0x0070,
-+	.ns_reg[0] = 0x0070,
-+	.ns_reg[1] = 0x0070,
- 	.md_reg[0] = 0x0064,
- 	.md_reg[1] = 0x0068,
-+	.bank_reg = 0x0060,
- 	.mn[0] = {
- 		.mnctr_en_bit = 8,
- 		.mnctr_reset_bit = 25,
-@@ -786,9 +788,11 @@ static struct clk_branch gfx2d0_clk = {
- };
- 
- static struct clk_dyn_rcg gfx2d1_src = {
--	.ns_reg = 0x007c,
-+	.ns_reg[0] = 0x007c,
-+	.ns_reg[1] = 0x007c,
- 	.md_reg[0] = 0x0078,
- 	.md_reg[1] = 0x006c,
-+	.bank_reg = 0x0074,
- 	.mn[0] = {
- 		.mnctr_en_bit = 8,
- 		.mnctr_reset_bit = 25,
-@@ -864,9 +868,11 @@ static struct freq_tbl clk_tbl_gfx3d[] =
- };
- 
- static struct clk_dyn_rcg gfx3d_src = {
--	.ns_reg = 0x008c,
-+	.ns_reg[0] = 0x008c,
-+	.ns_reg[1] = 0x008c,
- 	.md_reg[0] = 0x0084,
- 	.md_reg[1] = 0x0088,
-+	.bank_reg = 0x0080,
- 	.mn[0] = {
- 		.mnctr_en_bit = 8,
- 		.mnctr_reset_bit = 25,
-@@ -1053,9 +1059,11 @@ static struct freq_tbl clk_tbl_mdp[] = {
- };
- 
- static struct clk_dyn_rcg mdp_src = {
--	.ns_reg = 0x00d0,
-+	.ns_reg[0] = 0x00d0,
-+	.ns_reg[1] = 0x00d0,
- 	.md_reg[0] = 0x00c4,
- 	.md_reg[1] = 0x00c8,
-+	.bank_reg = 0x00c0,
- 	.mn[0] = {
- 		.mnctr_en_bit = 8,
- 		.mnctr_reset_bit = 31,
-@@ -1160,7 +1168,9 @@ static struct freq_tbl clk_tbl_rot[] = {
- };
- 
- static struct clk_dyn_rcg rot_src = {
--	.ns_reg = 0x00e8,
-+	.ns_reg[0] = 0x00e8,
-+	.ns_reg[1] = 0x00e8,
-+	.bank_reg = 0x00e8,
- 	.p[0] = {
- 		.pre_div_shift = 22,
- 		.pre_div_width = 4,
-@@ -1357,9 +1367,11 @@ static struct freq_tbl clk_tbl_vcodec[]
- };
- 
- static struct clk_dyn_rcg vcodec_src = {
--	.ns_reg = 0x0100,
-+	.ns_reg[0] = 0x0100,
-+	.ns_reg[1] = 0x0100,
- 	.md_reg[0] = 0x00fc,
- 	.md_reg[1] = 0x0128,
-+	.bank_reg = 0x00f8,
- 	.mn[0] = {
- 		.mnctr_en_bit = 5,
- 		.mnctr_reset_bit = 31,
diff --git a/target/linux/ipq806x/patches/0129-clk-qcom-Add-support-for-NSS-GMAC-clocks-and-resets.patch b/target/linux/ipq806x/patches/0129-clk-qcom-Add-support-for-NSS-GMAC-clocks-and-resets.patch
deleted file mode 100644
index 8b8839a..0000000
--- a/target/linux/ipq806x/patches/0129-clk-qcom-Add-support-for-NSS-GMAC-clocks-and-resets.patch
+++ /dev/null
@@ -1,860 +0,0 @@
-From 92fde23153240a6173645dabe4d99f4aa6570bb7 Mon Sep 17 00:00:00 2001
-From: Stephen Boyd <sboyd@codeaurora.org>
-Date: Mon, 28 Apr 2014 16:01:03 -0700
-Subject: [PATCH 129/182] clk: qcom: Add support for NSS/GMAC clocks and
- resets
-
-The NSS driver expects one virtual clock that actually represents
-two clocks (one for each UBI32 core). Register the ubi32 core
-clocks and also make a wrapper virtual clock called nss_core_clk
-to be used by the driver. This will properly handle switching the
-rates of both clocks at the same time like how the NSS driver
-expects it. Also add the TCM clock and the NSS resets.
-
-Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
----
- drivers/clk/qcom/gcc-ipq806x.c               |  710 +++++++++++++++++++++++++-
- include/dt-bindings/clock/qcom,gcc-ipq806x.h |    3 +
- include/dt-bindings/reset/qcom,gcc-ipq806x.h |   43 ++
- 3 files changed, 755 insertions(+), 1 deletion(-)
-
---- a/drivers/clk/qcom/gcc-ipq806x.c
-+++ b/drivers/clk/qcom/gcc-ipq806x.c
-@@ -32,6 +32,33 @@
- #include "clk-branch.h"
- #include "reset.h"
- 
-+static struct clk_pll pll0 = {
-+	.l_reg = 0x30c4,
-+	.m_reg = 0x30c8,
-+	.n_reg = 0x30cc,
-+	.config_reg = 0x30d4,
-+	.mode_reg = 0x30c0,
-+	.status_reg = 0x30d8,
-+	.status_bit = 16,
-+	.clkr.hw.init = &(struct clk_init_data){
-+		.name = "pll0",
-+		.parent_names = (const char *[]){ "pxo" },
-+		.num_parents = 1,
-+		.ops = &clk_pll_ops,
-+	},
-+};
-+
-+static struct clk_regmap pll0_vote = {
-+	.enable_reg = 0x34c0,
-+	.enable_mask = BIT(0),
-+	.hw.init = &(struct clk_init_data){
-+		.name = "pll0_vote",
-+		.parent_names = (const char *[]){ "pll0" },
-+		.num_parents = 1,
-+		.ops = &clk_pll_vote_ops,
-+	},
-+};
-+
- static struct clk_pll pll3 = {
- 	.l_reg = 0x3164,
- 	.m_reg = 0x3168,
-@@ -102,11 +129,46 @@ static struct clk_regmap pll14_vote = {
- 	},
- };
- 
-+#define NSS_PLL_RATE(f, _l, _m, _n, i) \
-+	{  \
-+		.freq = f,  \
-+		.l = _l, \
-+		.m = _m, \
-+		.n = _n, \
-+		.ibits = i, \
-+	}
-+
-+static struct pll_freq_tbl pll18_freq_tbl[] = {
-+	NSS_PLL_RATE(550000000, 44, 0, 1, 0x01495625),
-+	NSS_PLL_RATE(733000000, 58, 16, 25, 0x014b5625),
-+};
-+
-+static struct clk_pll pll18 = {
-+	.l_reg = 0x31a4,
-+	.m_reg = 0x31a8,
-+	.n_reg = 0x31ac,
-+	.config_reg = 0x31b4,
-+	.mode_reg = 0x31a0,
-+	.status_reg = 0x31b8,
-+	.status_bit = 16,
-+	.post_div_shift = 16,
-+	.post_div_width = 1,
-+	.freq_tbl = pll18_freq_tbl,
-+	.clkr.hw.init = &(struct clk_init_data){
-+		.name = "pll18",
-+		.parent_names = (const char *[]){ "pxo" },
-+		.num_parents = 1,
-+		.ops = &clk_pll_ops,
-+	},
-+};
-+
- #define P_PXO	0
- #define P_PLL8	1
- #define P_PLL3	1
- #define P_PLL0	2
- #define P_CXO	2
-+#define P_PLL14	3
-+#define P_PLL18	4
- 
- static const u8 gcc_pxo_pll8_map[] = {
- 	[P_PXO]		= 0,
-@@ -157,6 +219,22 @@ static const char *gcc_pxo_pll8_pll0_map
- 	"pll0",
- };
- 
-+static const u8 gcc_pxo_pll8_pll14_pll18_pll0_map[] = {
-+	[P_PXO]		= 0,
-+	[P_PLL8]	= 4,
-+	[P_PLL0]	= 2,
-+	[P_PLL14]	= 5,
-+	[P_PLL18]	= 1,
-+};
-+
-+static const char *gcc_pxo_pll8_pll14_pll18_pll0[] = {
-+	"pxo",
-+	"pll8_vote",
-+	"pll0_vote",
-+	"pll14",
-+	"pll18",
-+};
-+
- static struct freq_tbl clk_tbl_gsbi_uart[] = {
- 	{  1843200, P_PLL8, 2,  6, 625 },
- 	{  3686400, P_PLL8, 2, 12, 625 },
-@@ -2132,12 +2210,567 @@ static struct clk_branch usb_fs1_h_clk =
- 	},
- };
- 
-+static const struct freq_tbl clk_tbl_gmac[] = {
-+	{ 133000000, P_PLL0, 1, 50, 301 },
-+	{ }
-+};
-+
-+static struct clk_dyn_rcg gmac_core1_src = {
-+	.ns_reg[0] = 0x3cac,
-+	.ns_reg[1] = 0x3cb0,
-+	.md_reg[0] = 0x3ca4,
-+	.md_reg[1] = 0x3ca8,
-+	.bank_reg = 0x3ca0,
-+	.mn[0] = {
-+		.mnctr_en_bit = 8,
-+		.mnctr_reset_bit = 7,
-+		.mnctr_mode_shift = 5,
-+		.n_val_shift = 16,
-+		.m_val_shift = 16,
-+		.width = 8,
-+	},
-+	.mn[1] = {
-+		.mnctr_en_bit = 8,
-+		.mnctr_reset_bit = 7,
-+		.mnctr_mode_shift = 5,
-+		.n_val_shift = 16,
-+		.m_val_shift = 16,
-+		.width = 8,
-+	},
-+	.s[0] = {
-+		.src_sel_shift = 0,
-+		.parent_map = gcc_pxo_pll8_pll14_pll18_pll0_map,
-+	},
-+	.s[1] = {
-+		.src_sel_shift = 0,
-+		.parent_map = gcc_pxo_pll8_pll14_pll18_pll0_map,
-+	},
-+	.p[0] = {
-+		.pre_div_shift = 3,
-+		.pre_div_width = 2,
-+	},
-+	.p[1] = {
-+		.pre_div_shift = 3,
-+		.pre_div_width = 2,
-+	},
-+	.mux_sel_bit = 0,
-+	.freq_tbl = clk_tbl_gmac,
-+	.clkr = {
-+		.enable_reg = 0x3ca0,
-+		.enable_mask = BIT(1),
-+		.hw.init = &(struct clk_init_data){
-+			.name = "gmac_core1_src",
-+			.parent_names = gcc_pxo_pll8_pll14_pll18_pll0,
-+			.num_parents = 5,
-+			.ops = &clk_dyn_rcg_ops,
-+		},
-+	},
-+};
-+
-+static struct clk_branch gmac_core1_clk = {
-+	.halt_reg = 0x3c20,
-+	.halt_bit = 4,
-+	.hwcg_reg = 0x3cb4,
-+	.hwcg_bit = 6,
-+	.clkr = {
-+		.enable_reg = 0x3cb4,
-+		.enable_mask = BIT(4),
-+		.hw.init = &(struct clk_init_data){
-+			.name = "gmac_core1_clk",
-+			.parent_names = (const char *[]){
-+				"gmac_core1_src",
-+			},
-+			.num_parents = 1,
-+			.ops = &clk_branch_ops,
-+			.flags = CLK_SET_RATE_PARENT,
-+		},
-+	},
-+};
-+
-+static struct clk_dyn_rcg gmac_core2_src = {
-+	.ns_reg[0] = 0x3ccc,
-+	.ns_reg[1] = 0x3cd0,
-+	.md_reg[0] = 0x3cc4,
-+	.md_reg[1] = 0x3cc8,
-+	.bank_reg = 0x3ca0,
-+	.mn[0] = {
-+		.mnctr_en_bit = 8,
-+		.mnctr_reset_bit = 7,
-+		.mnctr_mode_shift = 5,
-+		.n_val_shift = 16,
-+		.m_val_shift = 16,
-+		.width = 8,
-+	},
-+	.mn[1] = {
-+		.mnctr_en_bit = 8,
-+		.mnctr_reset_bit = 7,
-+		.mnctr_mode_shift = 5,
-+		.n_val_shift = 16,
-+		.m_val_shift = 16,
-+		.width = 8,
-+	},
-+	.s[0] = {
-+		.src_sel_shift = 0,
-+		.parent_map = gcc_pxo_pll8_pll14_pll18_pll0_map,
-+	},
-+	.s[1] = {
-+		.src_sel_shift = 0,
-+		.parent_map = gcc_pxo_pll8_pll14_pll18_pll0_map,
-+	},
-+	.p[0] = {
-+		.pre_div_shift = 3,
-+		.pre_div_width = 2,
-+	},
-+	.p[1] = {
-+		.pre_div_shift = 3,
-+		.pre_div_width = 2,
-+	},
-+	.mux_sel_bit = 0,
-+	.freq_tbl = clk_tbl_gmac,
-+	.clkr = {
-+		.enable_reg = 0x3cc0,
-+		.enable_mask = BIT(1),
-+		.hw.init = &(struct clk_init_data){
-+			.name = "gmac_core2_src",
-+			.parent_names = gcc_pxo_pll8_pll14_pll18_pll0,
-+			.num_parents = 5,
-+			.ops = &clk_dyn_rcg_ops,
-+		},
-+	},
-+};
-+
-+static struct clk_branch gmac_core2_clk = {
-+	.halt_reg = 0x3c20,
-+	.halt_bit = 5,
-+	.hwcg_reg = 0x3cd4,
-+	.hwcg_bit = 6,
-+	.clkr = {
-+		.enable_reg = 0x3cd4,
-+		.enable_mask = BIT(4),
-+		.hw.init = &(struct clk_init_data){
-+			.name = "gmac_core2_clk",
-+			.parent_names = (const char *[]){
-+				"gmac_core2_src",
-+			},
-+			.num_parents = 1,
-+			.ops = &clk_branch_ops,
-+			.flags = CLK_SET_RATE_PARENT,
-+		},
-+	},
-+};
-+
-+static struct clk_dyn_rcg gmac_core3_src = {
-+	.ns_reg[0] = 0x3cec,
-+	.ns_reg[1] = 0x3cf0,
-+	.md_reg[0] = 0x3ce4,
-+	.md_reg[1] = 0x3ce8,
-+	.bank_reg = 0x3ce0,
-+	.mn[0] = {
-+		.mnctr_en_bit = 8,
-+		.mnctr_reset_bit = 7,
-+		.mnctr_mode_shift = 5,
-+		.n_val_shift = 16,
-+		.m_val_shift = 16,
-+		.width = 8,
-+	},
-+	.mn[1] = {
-+		.mnctr_en_bit = 8,
-+		.mnctr_reset_bit = 7,
-+		.mnctr_mode_shift = 5,
-+		.n_val_shift = 16,
-+		.m_val_shift = 16,
-+		.width = 8,
-+	},
-+	.s[0] = {
-+		.src_sel_shift = 0,
-+		.parent_map = gcc_pxo_pll8_pll14_pll18_pll0_map,
-+	},
-+	.s[1] = {
-+		.src_sel_shift = 0,
-+		.parent_map = gcc_pxo_pll8_pll14_pll18_pll0_map,
-+	},
-+	.p[0] = {
-+		.pre_div_shift = 3,
-+		.pre_div_width = 2,
-+	},
-+	.p[1] = {
-+		.pre_div_shift = 3,
-+		.pre_div_width = 2,
-+	},
-+	.mux_sel_bit = 0,
-+	.freq_tbl = clk_tbl_gmac,
-+	.clkr = {
-+		.enable_reg = 0x3ce0,
-+		.enable_mask = BIT(1),
-+		.hw.init = &(struct clk_init_data){
-+			.name = "gmac_core3_src",
-+			.parent_names = gcc_pxo_pll8_pll14_pll18_pll0,
-+			.num_parents = 5,
-+			.ops = &clk_dyn_rcg_ops,
-+		},
-+	},
-+};
-+
-+static struct clk_branch gmac_core3_clk = {
-+	.halt_reg = 0x3c20,
-+	.halt_bit = 6,
-+	.hwcg_reg = 0x3cf4,
-+	.hwcg_bit = 6,
-+	.clkr = {
-+		.enable_reg = 0x3cf4,
-+		.enable_mask = BIT(4),
-+		.hw.init = &(struct clk_init_data){
-+			.name = "gmac_core3_clk",
-+			.parent_names = (const char *[]){
-+				"gmac_core3_src",
-+			},
-+			.num_parents = 1,
-+			.ops = &clk_branch_ops,
-+			.flags = CLK_SET_RATE_PARENT,
-+		},
-+	},
-+};
-+
-+static struct clk_dyn_rcg gmac_core4_src = {
-+	.ns_reg[0] = 0x3d0c,
-+	.ns_reg[1] = 0x3d10,
-+	.md_reg[0] = 0x3d04,
-+	.md_reg[1] = 0x3d08,
-+	.bank_reg = 0x3d00,
-+	.mn[0] = {
-+		.mnctr_en_bit = 8,
-+		.mnctr_reset_bit = 7,
-+		.mnctr_mode_shift = 5,
-+		.n_val_shift = 16,
-+		.m_val_shift = 16,
-+		.width = 8,
-+	},
-+	.mn[1] = {
-+		.mnctr_en_bit = 8,
-+		.mnctr_reset_bit = 7,
-+		.mnctr_mode_shift = 5,
-+		.n_val_shift = 16,
-+		.m_val_shift = 16,
-+		.width = 8,
-+	},
-+	.s[0] = {
-+		.src_sel_shift = 0,
-+		.parent_map = gcc_pxo_pll8_pll14_pll18_pll0_map,
-+	},
-+	.s[1] = {
-+		.src_sel_shift = 0,
-+		.parent_map = gcc_pxo_pll8_pll14_pll18_pll0_map,
-+	},
-+	.p[0] = {
-+		.pre_div_shift = 3,
-+		.pre_div_width = 2,
-+	},
-+	.p[1] = {
-+		.pre_div_shift = 3,
-+		.pre_div_width = 2,
-+	},
-+	.mux_sel_bit = 0,
-+	.freq_tbl = clk_tbl_gmac,
-+	.clkr = {
-+		.enable_reg = 0x3d00,
-+		.enable_mask = BIT(1),
-+		.hw.init = &(struct clk_init_data){
-+			.name = "gmac_core4_src",
-+			.parent_names = gcc_pxo_pll8_pll14_pll18_pll0,
-+			.num_parents = 5,
-+			.ops = &clk_dyn_rcg_ops,
-+		},
-+	},
-+};
-+
-+static struct clk_branch gmac_core4_clk = {
-+	.halt_reg = 0x3c20,
-+	.halt_bit = 7,
-+	.hwcg_reg = 0x3d14,
-+	.hwcg_bit = 6,
-+	.clkr = {
-+		.enable_reg = 0x3d14,
-+		.enable_mask = BIT(4),
-+		.hw.init = &(struct clk_init_data){
-+			.name = "gmac_core4_clk",
-+			.parent_names = (const char *[]){
-+				"gmac_core4_src",
-+			},
-+			.num_parents = 1,
-+			.ops = &clk_branch_ops,
-+			.flags = CLK_SET_RATE_PARENT,
-+		},
-+	},
-+};
-+
-+static const struct freq_tbl clk_tbl_nss_tcm[] = {
-+	{ 266000000, P_PLL0, 3, 0, 0 },
-+	{ 400000000, P_PLL0, 2, 0, 0 },
-+	{ }
-+};
-+
-+static struct clk_dyn_rcg nss_tcm_src = {
-+	.ns_reg[0] = 0x3dc4,
-+	.ns_reg[1] = 0x3dc8,
-+	.bank_reg = 0x3dc0,
-+	.s[0] = {
-+		.src_sel_shift = 0,
-+		.parent_map = gcc_pxo_pll8_pll14_pll18_pll0_map,
-+	},
-+	.s[1] = {
-+		.src_sel_shift = 0,
-+		.parent_map = gcc_pxo_pll8_pll14_pll18_pll0_map,
-+	},
-+	.p[0] = {
-+		.pre_div_shift = 3,
-+		.pre_div_width = 4,
-+	},
-+	.p[1] = {
-+		.pre_div_shift = 3,
-+		.pre_div_width = 4,
-+	},
-+	.mux_sel_bit = 0,
-+	.freq_tbl = clk_tbl_nss_tcm,
-+	.clkr = {
-+		.enable_reg = 0x3dc0,
-+		.enable_mask = BIT(1),
-+		.hw.init = &(struct clk_init_data){
-+			.name = "nss_tcm_src",
-+			.parent_names = gcc_pxo_pll8_pll14_pll18_pll0,
-+			.num_parents = 5,
-+			.ops = &clk_dyn_rcg_ops,
-+		},
-+	},
-+};
-+
-+static struct clk_branch nss_tcm_clk = {
-+	.halt_reg = 0x3c20,
-+	.halt_bit = 14,
-+	.clkr = {
-+		.enable_reg = 0x3dd0,
-+		.enable_mask = BIT(6) | BIT(4),
-+		.hw.init = &(struct clk_init_data){
-+			.name = "nss_tcm_clk",
-+			.parent_names = (const char *[]){
-+				"nss_tcm_src",
-+			},
-+			.num_parents = 1,
-+			.ops = &clk_branch_ops,
-+			.flags = CLK_SET_RATE_PARENT,
-+		},
-+	},
-+};
-+
-+static const struct freq_tbl clk_tbl_nss[] = {
-+	{ 110000000, P_PLL18, 1, 1, 5 },
-+	{ 275000000, P_PLL18, 2, 0, 0 },
-+	{ 550000000, P_PLL18, 1, 0, 0 },
-+	{ 733000000, P_PLL18, 1, 0, 0 },
-+	{ }
-+};
-+
-+static struct clk_dyn_rcg ubi32_core1_src_clk = {
-+	.ns_reg[0] = 0x3d2c,
-+	.ns_reg[1] = 0x3d30,
-+	.md_reg[0] = 0x3d24,
-+	.md_reg[1] = 0x3d28,
-+	.bank_reg = 0x3d20,
-+	.mn[0] = {
-+		.mnctr_en_bit = 8,
-+		.mnctr_reset_bit = 7,
-+		.mnctr_mode_shift = 5,
-+		.n_val_shift = 16,
-+		.m_val_shift = 16,
-+		.width = 8,
-+	},
-+	.mn[1] = {
-+		.mnctr_en_bit = 8,
-+		.mnctr_reset_bit = 7,
-+		.mnctr_mode_shift = 5,
-+		.n_val_shift = 16,
-+		.m_val_shift = 16,
-+		.width = 8,
-+	},
-+	.s[0] = {
-+		.src_sel_shift = 0,
-+		.parent_map = gcc_pxo_pll8_pll14_pll18_pll0_map,
-+	},
-+	.s[1] = {
-+		.src_sel_shift = 0,
-+		.parent_map = gcc_pxo_pll8_pll14_pll18_pll0_map,
-+	},
-+	.p[0] = {
-+		.pre_div_shift = 3,
-+		.pre_div_width = 2,
-+	},
-+	.p[1] = {
-+		.pre_div_shift = 3,
-+		.pre_div_width = 2,
-+	},
-+	.mux_sel_bit = 0,
-+	.freq_tbl = clk_tbl_nss,
-+	.clkr = {
-+		.enable_reg = 0x3d20,
-+		.enable_mask = BIT(1),
-+		.hw.init = &(struct clk_init_data){
-+			.name = "ubi32_core1_src_clk",
-+			.parent_names = gcc_pxo_pll8_pll14_pll18_pll0,
-+			.num_parents = 5,
-+			.ops = &clk_dyn_rcg_ops,
-+			.flags = CLK_SET_RATE_PARENT | CLK_GET_RATE_NOCACHE,
-+		},
-+	},
-+};
-+
-+static struct clk_dyn_rcg ubi32_core2_src_clk = {
-+	.ns_reg[0] = 0x3d4c,
-+	.ns_reg[1] = 0x3d50,
-+	.md_reg[0] = 0x3d44,
-+	.md_reg[1] = 0x3d48,
-+	.bank_reg = 0x3d40,
-+	.mn[0] = {
-+		.mnctr_en_bit = 8,
-+		.mnctr_reset_bit = 7,
-+		.mnctr_mode_shift = 5,
-+		.n_val_shift = 16,
-+		.m_val_shift = 16,
-+		.width = 8,
-+	},
-+	.mn[1] = {
-+		.mnctr_en_bit = 8,
-+		.mnctr_reset_bit = 7,
-+		.mnctr_mode_shift = 5,
-+		.n_val_shift = 16,
-+		.m_val_shift = 16,
-+		.width = 8,
-+	},
-+	.s[0] = {
-+		.src_sel_shift = 0,
-+		.parent_map = gcc_pxo_pll8_pll14_pll18_pll0_map,
-+	},
-+	.s[1] = {
-+		.src_sel_shift = 0,
-+		.parent_map = gcc_pxo_pll8_pll14_pll18_pll0_map,
-+	},
-+	.p[0] = {
-+		.pre_div_shift = 3,
-+		.pre_div_width = 2,
-+	},
-+	.p[1] = {
-+		.pre_div_shift = 3,
-+		.pre_div_width = 2,
-+	},
-+	.mux_sel_bit = 0,
-+	.freq_tbl = clk_tbl_nss,
-+	.clkr = {
-+		.enable_reg = 0x3d40,
-+		.enable_mask = BIT(1),
-+		.hw.init = &(struct clk_init_data){
-+			.name = "ubi32_core2_src_clk",
-+			.parent_names = gcc_pxo_pll8_pll14_pll18_pll0,
-+			.num_parents = 5,
-+			.ops = &clk_dyn_rcg_ops,
-+			.flags = CLK_SET_RATE_PARENT | CLK_GET_RATE_NOCACHE,
-+		},
-+	},
-+};
-+
-+static int nss_core_clk_set_rate(struct clk_hw *hw, unsigned long rate,
-+				 unsigned long parent_rate)
-+{
-+	int ret;
-+
-+	ret = clk_dyn_rcg_ops.set_rate(&ubi32_core1_src_clk.clkr.hw, rate,
-+				    parent_rate);
-+	if (ret)
-+		return ret;
-+
-+	return clk_dyn_rcg_ops.set_rate(&ubi32_core2_src_clk.clkr.hw, rate,
-+				    parent_rate);
-+}
-+
-+static int
-+nss_core_clk_set_rate_and_parent(struct clk_hw *hw, unsigned long rate,
-+				 unsigned long parent_rate, u8 index)
-+{
-+	int ret;
-+
-+	ret = clk_dyn_rcg_ops.set_rate_and_parent(
-+			&ubi32_core1_src_clk.clkr.hw, rate, parent_rate, index);
-+	if (ret)
-+		return ret;
-+
-+	ret = clk_dyn_rcg_ops.set_rate_and_parent(
-+			&ubi32_core2_src_clk.clkr.hw, rate, parent_rate, index);
-+	return ret;
-+}
-+
-+static long nss_core_clk_determine_rate(struct clk_hw *hw, unsigned long rate,
-+				 unsigned long *p_rate, struct clk **p)
-+{
-+	return clk_dyn_rcg_ops.determine_rate(&ubi32_core1_src_clk.clkr.hw,
-+						 rate, p_rate, p);
-+}
-+
-+static unsigned long
-+nss_core_clk_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)
-+{
-+	return clk_dyn_rcg_ops.recalc_rate(&ubi32_core1_src_clk.clkr.hw,
-+						 parent_rate);
-+}
-+
-+static u8 nss_core_clk_get_parent(struct clk_hw *hw)
-+{
-+	return clk_dyn_rcg_ops.get_parent(&ubi32_core1_src_clk.clkr.hw);
-+}
-+
-+static int nss_core_clk_set_parent(struct clk_hw *hw, u8 i)
-+{
-+	int ret;
-+
-+	ret = clk_dyn_rcg_ops.set_parent(&ubi32_core1_src_clk.clkr.hw, i);
-+	if (ret)
-+		return ret;
-+
-+	return clk_dyn_rcg_ops.set_parent(&ubi32_core2_src_clk.clkr.hw, i);
-+}
-+
-+static struct clk *nss_core_clk_get_safe_parent(struct clk_hw *hw)
-+{
-+	return clk_get_parent_by_index(hw->clk,
-+			ubi32_core2_src_clk.s[0].parent_map[P_PLL8]);
-+}
-+
-+static const struct clk_ops clk_ops_nss_core = {
-+	.set_rate = nss_core_clk_set_rate,
-+	.set_rate_and_parent = nss_core_clk_set_rate_and_parent,
-+	.determine_rate = nss_core_clk_determine_rate,
-+	.recalc_rate = nss_core_clk_recalc_rate,
-+	.get_parent = nss_core_clk_get_parent,
-+	.set_parent = nss_core_clk_set_parent,
-+	.get_safe_parent = nss_core_clk_get_safe_parent,
-+};
-+
-+/* Virtual clock for nss core clocks */
-+static struct clk_regmap nss_core_clk = {
-+	.hw.init = &(struct clk_init_data){
-+		.name = "nss_core_clk",
-+		.ops = &clk_ops_nss_core,
-+		.parent_names = gcc_pxo_pll8_pll14_pll18_pll0,
-+		.num_parents = 5,
-+		.flags = CLK_SET_RATE_PARENT,
-+	},
-+};
-+
- static struct clk_regmap *gcc_ipq806x_clks[] = {
-+	[PLL0] = &pll0.clkr,
-+	[PLL0_VOTE] = &pll0_vote,
- 	[PLL3] = &pll3.clkr,
- 	[PLL8] = &pll8.clkr,
- 	[PLL8_VOTE] = &pll8_vote,
- 	[PLL14] = &pll14.clkr,
- 	[PLL14_VOTE] = &pll14_vote,
-+	[PLL18] = &pll18.clkr,
- 	[GSBI1_UART_SRC] = &gsbi1_uart_src.clkr,
- 	[GSBI1_UART_CLK] = &gsbi1_uart_clk.clkr,
- 	[GSBI2_UART_SRC] = &gsbi2_uart_src.clkr,
-@@ -2232,6 +2865,19 @@ static struct clk_regmap *gcc_ipq806x_cl
- 	[USB_FS1_XCVR_SRC] = &usb_fs1_xcvr_clk_src.clkr,
- 	[USB_FS1_XCVR_CLK] = &usb_fs1_xcvr_clk.clkr,
- 	[USB_FS1_SYSTEM_CLK] = &usb_fs1_sys_clk.clkr,
-+	[GMAC_CORE1_CLK_SRC] = &gmac_core1_src.clkr,
-+	[GMAC_CORE1_CLK] = &gmac_core1_clk.clkr,
-+	[GMAC_CORE2_CLK_SRC] = &gmac_core2_src.clkr,
-+	[GMAC_CORE2_CLK] = &gmac_core2_clk.clkr,
-+	[GMAC_CORE3_CLK_SRC] = &gmac_core3_src.clkr,
-+	[GMAC_CORE3_CLK] = &gmac_core3_clk.clkr,
-+	[GMAC_CORE4_CLK_SRC] = &gmac_core4_src.clkr,
-+	[GMAC_CORE4_CLK] = &gmac_core4_clk.clkr,
-+	[UBI32_CORE1_CLK_SRC] = &ubi32_core1_src_clk.clkr,
-+	[UBI32_CORE2_CLK_SRC] = &ubi32_core2_src_clk.clkr,
-+	[NSSTCM_CLK_SRC] = &nss_tcm_src.clkr,
-+	[NSSTCM_CLK] = &nss_tcm_clk.clkr,
-+	[NSS_CORE_CLK] = &nss_core_clk,
- };
- 
- static const struct qcom_reset_map gcc_ipq806x_resets[] = {
-@@ -2350,6 +2996,48 @@ static const struct qcom_reset_map gcc_i
- 	[USB30_1_PHY_RESET] = { 0x3b58, 0 },
- 	[NSSFB0_RESET] = { 0x3b60, 6 },
- 	[NSSFB1_RESET] = { 0x3b60, 7 },
-+	[UBI32_CORE1_CLKRST_CLAMP_RESET] = { 0x3d3c, 3},
-+	[UBI32_CORE1_CLAMP_RESET] = { 0x3d3c, 2 },
-+	[UBI32_CORE1_AHB_RESET] = { 0x3d3c, 1 },
-+	[UBI32_CORE1_AXI_RESET] = { 0x3d3c, 0 },
-+	[UBI32_CORE2_CLKRST_CLAMP_RESET] = { 0x3d5c, 3 },
-+	[UBI32_CORE2_CLAMP_RESET] = { 0x3d5c, 2 },
-+	[UBI32_CORE2_AHB_RESET] = { 0x3d5c, 1 },
-+	[UBI32_CORE2_AXI_RESET] = { 0x3d5c, 0 },
-+	[GMAC_CORE1_RESET] = { 0x3cbc, 0 },
-+	[GMAC_CORE2_RESET] = { 0x3cdc, 0 },
-+	[GMAC_CORE3_RESET] = { 0x3cfc, 0 },
-+	[GMAC_CORE4_RESET] = { 0x3d1c, 0 },
-+	[GMAC_AHB_RESET] = { 0x3e24, 0 },
-+	[NSS_CH0_RST_RX_CLK_N_RESET] = { 0x3b60, 0 },
-+	[NSS_CH0_RST_TX_CLK_N_RESET] = { 0x3b60, 1 },
-+	[NSS_CH0_RST_RX_125M_N_RESET] = { 0x3b60, 2 },
-+	[NSS_CH0_HW_RST_RX_125M_N_RESET] = { 0x3b60, 3 },
-+	[NSS_CH0_RST_TX_125M_N_RESET] = { 0x3b60, 4 },
-+	[NSS_CH1_RST_RX_CLK_N_RESET] = { 0x3b60, 5 },
-+	[NSS_CH1_RST_TX_CLK_N_RESET] = { 0x3b60, 6 },
-+	[NSS_CH1_RST_RX_125M_N_RESET] = { 0x3b60, 7 },
-+	[NSS_CH1_HW_RST_RX_125M_N_RESET] = { 0x3b60, 8 },
-+	[NSS_CH1_RST_TX_125M_N_RESET] = { 0x3b60, 9 },
-+	[NSS_CH2_RST_RX_CLK_N_RESET] = { 0x3b60, 10 },
-+	[NSS_CH2_RST_TX_CLK_N_RESET] = { 0x3b60, 11 },
-+	[NSS_CH2_RST_RX_125M_N_RESET] = { 0x3b60, 12 },
-+	[NSS_CH2_HW_RST_RX_125M_N_RESET] = { 0x3b60, 13 },
-+	[NSS_CH2_RST_TX_125M_N_RESET] = { 0x3b60, 14 },
-+	[NSS_CH3_RST_RX_CLK_N_RESET] = { 0x3b60, 15 },
-+	[NSS_CH3_RST_TX_CLK_N_RESET] = { 0x3b60, 16 },
-+	[NSS_CH3_RST_RX_125M_N_RESET] = { 0x3b60, 17 },
-+	[NSS_CH3_HW_RST_RX_125M_N_RESET] = { 0x3b60, 18 },
-+	[NSS_CH3_RST_TX_125M_N_RESET] = { 0x3b60, 19 },
-+	[NSS_RST_RX_250M_125M_N_RESET] = { 0x3b60, 20 },
-+	[NSS_RST_TX_250M_125M_N_RESET] = { 0x3b60, 21 },
-+	[NSS_QSGMII_TXPI_RST_N_RESET] = { 0x3b60, 22 },
-+	[NSS_QSGMII_CDR_RST_N_RESET] = { 0x3b60, 23 },
-+	[NSS_SGMII2_CDR_RST_N_RESET] = { 0x3b60, 24 },
-+	[NSS_SGMII3_CDR_RST_N_RESET] = { 0x3b60, 25 },
-+	[NSS_CAL_PRBS_RST_N_RESET] = { 0x3b60, 26 },
-+	[NSS_LCKDT_RST_N_RESET] = { 0x3b60, 27 },
-+	[NSS_SRDS_N_RESET] = { 0x3b60, 28 },
- };
- 
- static const struct regmap_config gcc_ipq806x_regmap_config = {
-@@ -2378,6 +3066,8 @@ static int gcc_ipq806x_probe(struct plat
- {
- 	struct clk *clk;
- 	struct device *dev = &pdev->dev;
-+	struct regmap *regmap;
-+	int ret;
- 
- 	/* Temporary until RPM clocks supported */
- 	clk = clk_register_fixed_rate(dev, "cxo", NULL, CLK_IS_ROOT, 25000000);
-@@ -2388,7 +3078,25 @@ static int gcc_ipq806x_probe(struct plat
- 	if (IS_ERR(clk))
- 		return PTR_ERR(clk);
- 
--	return qcom_cc_probe(pdev, &gcc_ipq806x_desc);
-+	ret = qcom_cc_probe(pdev, &gcc_ipq806x_desc);
-+	if (ret)
-+		return ret;
-+
-+	regmap = dev_get_regmap(dev, NULL);
-+	if (!regmap)
-+		return -ENODEV;
-+
-+	/* Setup PLL18 static bits */
-+	regmap_update_bits(regmap, 0x31a4, 0xffffffc0, 0x40000400);
-+	regmap_write(regmap, 0x31b0, 0x3080);
-+
-+	/* Set GMAC footswitch sleep/wakeup values */
-+	regmap_write(regmap, 0x3cb8, 8);
-+	regmap_write(regmap, 0x3cd8, 8);
-+	regmap_write(regmap, 0x3cf8, 8);
-+	regmap_write(regmap, 0x3d18, 8);
-+
-+	return 0;
- }
- 
- static int gcc_ipq806x_remove(struct platform_device *pdev)
---- a/include/dt-bindings/clock/qcom,gcc-ipq806x.h
-+++ b/include/dt-bindings/clock/qcom,gcc-ipq806x.h
-@@ -289,5 +289,8 @@
- #define UBI32_CORE2_CLK_SRC			277
- #define UBI32_CORE1_CLK				278
- #define UBI32_CORE2_CLK				279
-+#define NSSTCM_CLK_SRC				280
-+#define NSSTCM_CLK				281
-+#define NSS_CORE_CLK				282 /* Virtual */
- 
- #endif
---- a/include/dt-bindings/reset/qcom,gcc-ipq806x.h
-+++ b/include/dt-bindings/reset/qcom,gcc-ipq806x.h
-@@ -129,4 +129,47 @@
- #define USB30_1_PHY_RESET				112
- #define NSSFB0_RESET					113
- #define NSSFB1_RESET					114
-+#define UBI32_CORE1_CLKRST_CLAMP_RESET			115
-+#define UBI32_CORE1_CLAMP_RESET				116
-+#define UBI32_CORE1_AHB_RESET				117
-+#define UBI32_CORE1_AXI_RESET				118
-+#define UBI32_CORE2_CLKRST_CLAMP_RESET			119
-+#define UBI32_CORE2_CLAMP_RESET				120
-+#define UBI32_CORE2_AHB_RESET				121
-+#define UBI32_CORE2_AXI_RESET				122
-+#define GMAC_CORE1_RESET				123
-+#define GMAC_CORE2_RESET				124
-+#define GMAC_CORE3_RESET				125
-+#define GMAC_CORE4_RESET				126
-+#define GMAC_AHB_RESET					127
-+#define NSS_CH0_RST_RX_CLK_N_RESET			128
-+#define NSS_CH0_RST_TX_CLK_N_RESET			129
-+#define NSS_CH0_RST_RX_125M_N_RESET			130
-+#define NSS_CH0_HW_RST_RX_125M_N_RESET			131
-+#define NSS_CH0_RST_TX_125M_N_RESET			132
-+#define NSS_CH1_RST_RX_CLK_N_RESET			133
-+#define NSS_CH1_RST_TX_CLK_N_RESET			134
-+#define NSS_CH1_RST_RX_125M_N_RESET			135
-+#define NSS_CH1_HW_RST_RX_125M_N_RESET			136
-+#define NSS_CH1_RST_TX_125M_N_RESET			137
-+#define NSS_CH2_RST_RX_CLK_N_RESET			138
-+#define NSS_CH2_RST_TX_CLK_N_RESET			139
-+#define NSS_CH2_RST_RX_125M_N_RESET			140
-+#define NSS_CH2_HW_RST_RX_125M_N_RESET			141
-+#define NSS_CH2_RST_TX_125M_N_RESET			142
-+#define NSS_CH3_RST_RX_CLK_N_RESET			143
-+#define NSS_CH3_RST_TX_CLK_N_RESET			144
-+#define NSS_CH3_RST_RX_125M_N_RESET			145
-+#define NSS_CH3_HW_RST_RX_125M_N_RESET			146
-+#define NSS_CH3_RST_TX_125M_N_RESET			147
-+#define NSS_RST_RX_250M_125M_N_RESET			148
-+#define NSS_RST_TX_250M_125M_N_RESET			149
-+#define NSS_QSGMII_TXPI_RST_N_RESET			150
-+#define NSS_QSGMII_CDR_RST_N_RESET			151
-+#define NSS_SGMII2_CDR_RST_N_RESET			152
-+#define NSS_SGMII3_CDR_RST_N_RESET			153
-+#define NSS_CAL_PRBS_RST_N_RESET			154
-+#define NSS_LCKDT_RST_N_RESET				155
-+#define NSS_SRDS_N_RESET				156
-+
- #endif
diff --git a/target/linux/ipq806x/patches/0130-ARM-qcom-Add-initial-IPQ8064-SoC-and-AP148-device-tr.patch b/target/linux/ipq806x/patches/0130-ARM-qcom-Add-initial-IPQ8064-SoC-and-AP148-device-tr.patch
deleted file mode 100644
index 8fda0a1..0000000
--- a/target/linux/ipq806x/patches/0130-ARM-qcom-Add-initial-IPQ8064-SoC-and-AP148-device-tr.patch
+++ /dev/null
@@ -1,253 +0,0 @@
-From 1c6e51ffb10f5bf93a3018c7c1e04d7ed93f944e Mon Sep 17 00:00:00 2001
-From: Kumar Gala <galak@codeaurora.org>
-Date: Fri, 7 Mar 2014 10:56:59 -0600
-Subject: [PATCH 130/182] ARM: qcom: Add initial IPQ8064 SoC and AP148 device
- trees
-
-Add basic IPQ8064 SoC include device tree and support for basic booting on
-the AP148 Reference board.
-
-Signed-off-by: Kumar Gala <galak@codeaurora.org>
----
- arch/arm/boot/dts/Makefile               |    1 +
- arch/arm/boot/dts/qcom-ipq8064-ap148.dts |   25 +++++
- arch/arm/boot/dts/qcom-ipq8064-v1.0.dtsi |    1 +
- arch/arm/boot/dts/qcom-ipq8064.dtsi      |  176 ++++++++++++++++++++++++++++++
- arch/arm/mach-qcom/board.c               |    2 +
- 5 files changed, 205 insertions(+)
- create mode 100644 arch/arm/boot/dts/qcom-ipq8064-ap148.dts
- create mode 100644 arch/arm/boot/dts/qcom-ipq8064-v1.0.dtsi
- create mode 100644 arch/arm/boot/dts/qcom-ipq8064.dtsi
-
---- a/arch/arm/boot/dts/Makefile
-+++ b/arch/arm/boot/dts/Makefile
-@@ -235,6 +235,7 @@ dtb-$(CONFIG_ARCH_QCOM) += \
- 	qcom-apq8064-ifc6410.dtb \
- 	qcom-apq8074-dragonboard.dtb \
- 	qcom-apq8084-mtp.dtb \
-+	qcom-ipq8064-ap148.dtb \
- 	qcom-msm8660-surf.dtb \
- 	qcom-msm8960-cdp.dtb
- dtb-$(CONFIG_ARCH_U8500) += ste-snowball.dtb \
---- /dev/null
-+++ b/arch/arm/boot/dts/qcom-ipq8064-ap148.dts
-@@ -0,0 +1,25 @@
-+#include "qcom-ipq8064-v1.0.dtsi"
-+
-+/ {
-+	model = "Qualcomm IPQ8064/AP148";
-+	compatible = "qcom,ipq8064-ap148", "qcom,ipq8064";
-+
-+	reserved-memory {
-+		#address-cells = <1>;
-+		#size-cells = <1>;
-+		rsvd@41200000 {
-+			reg = <0x41200000 0x300000>;
-+			no-map;
-+		};
-+	};
-+
-+	soc {
-+		gsbi@16300000 {
-+			qcom,mode = <GSBI_PROT_I2C_UART>;
-+			status = "ok";
-+			serial@16340000 {
-+				status = "ok";
-+			};
-+		};
-+	};
-+};
---- /dev/null
-+++ b/arch/arm/boot/dts/qcom-ipq8064-v1.0.dtsi
-@@ -0,0 +1 @@
-+#include "qcom-ipq8064.dtsi"
---- /dev/null
-+++ b/arch/arm/boot/dts/qcom-ipq8064.dtsi
-@@ -0,0 +1,176 @@
-+/dts-v1/;
-+
-+#include "skeleton.dtsi"
-+#include <dt-bindings/clock/qcom,gcc-ipq806x.h>
-+#include <dt-bindings/soc/qcom,gsbi.h>
-+
-+/ {
-+	model = "Qualcomm IPQ8064";
-+	compatible = "qcom,ipq8064";
-+	interrupt-parent = <&intc>;
-+
-+	cpus {
-+		#address-cells = <1>;
-+		#size-cells = <0>;
-+
-+		cpu@0 {
-+			compatible = "qcom,krait";
-+			enable-method = "qcom,kpss-acc-v1";
-+			device_type = "cpu";
-+			reg = <0>;
-+			next-level-cache = <&L2>;
-+			qcom,acc = <&acc0>;
-+			qcom,saw = <&saw0>;
-+		};
-+
-+		cpu@1 {
-+			compatible = "qcom,krait";
-+			enable-method = "qcom,kpss-acc-v1";
-+			device_type = "cpu";
-+			reg = <1>;
-+			next-level-cache = <&L2>;
-+			qcom,acc = <&acc1>;
-+			qcom,saw = <&saw1>;
-+		};
-+
-+		L2: l2-cache {
-+			compatible = "cache";
-+			cache-level = <2>;
-+		};
-+	};
-+
-+	cpu-pmu {
-+		compatible = "qcom,krait-pmu";
-+		interrupts = <1 10 0x304>;
-+	};
-+
-+	reserved-memory {
-+		#address-cells = <1>;
-+		#size-cells = <1>;
-+		ranges;
-+
-+		nss@40000000 {
-+			reg = <0x40000000 0x1000000>;
-+			no-map;
-+		};
-+
-+		smem@41000000 {
-+			reg = <0x41000000 0x200000>;
-+			no-map;
-+		};
-+	};
-+
-+	soc: soc {
-+		#address-cells = <1>;
-+		#size-cells = <1>;
-+		ranges;
-+		compatible = "simple-bus";
-+
-+		qcom_pinmux: pinmux@800000 {
-+			compatible = "qcom,ipq8064-pinctrl";
-+			reg = <0x800000 0x4000>;
-+
-+			gpio-controller;
-+			#gpio-cells = <2>;
-+			interrupt-controller;
-+			#interrupt-cells = <2>;
-+			interrupts = <0 32 0x4>;
-+		};
-+
-+		intc: interrupt-controller@2000000 {
-+			compatible = "qcom,msm-qgic2";
-+			interrupt-controller;
-+			#interrupt-cells = <3>;
-+			reg = <0x02000000 0x1000>,
-+			      <0x02002000 0x1000>;
-+		};
-+
-+		timer@200a000 {
-+			compatible = "qcom,kpss-timer", "qcom,msm-timer";
-+			interrupts = <1 1 0x301>,
-+				     <1 2 0x301>,
-+				     <1 3 0x301>;
-+			reg = <0x0200a000 0x100>;
-+			clock-frequency = <25000000>,
-+					  <32768>;
-+			cpu-offset = <0x80000>;
-+		};
-+
-+		acc0: clock-controller@2088000 {
-+			compatible = "qcom,kpss-acc-v1";
-+			reg = <0x02088000 0x1000>, <0x02008000 0x1000>;
-+		};
-+
-+		acc1: clock-controller@2098000 {
-+			compatible = "qcom,kpss-acc-v1";
-+			reg = <0x02098000 0x1000>, <0x02008000 0x1000>;
-+		};
-+
-+		saw0: regulator@2089000 {
-+			compatible = "qcom,saw2";
-+			reg = <0x02089000 0x1000>, <0x02009000 0x1000>;
-+			regulator;
-+		};
-+
-+		saw1: regulator@2099000 {
-+			compatible = "qcom,saw2";
-+			reg = <0x02099000 0x1000>, <0x02009000 0x1000>;
-+			regulator;
-+		};
-+
-+		gsbi2: gsbi@12480000 {
-+			compatible = "qcom,gsbi-v1.0.0";
-+			reg = <0x12480000 0x100>;
-+			clocks = <&gcc GSBI2_H_CLK>;
-+			clock-names = "iface";
-+			#address-cells = <1>;
-+			#size-cells = <1>;
-+			ranges;
-+			status = "disabled";
-+
-+			serial@12490000 {
-+				compatible = "qcom,msm-uartdm-v1.3", "qcom,msm-uartdm";
-+				reg = <0x12490000 0x1000>,
-+				      <0x12480000 0x1000>;
-+				interrupts = <0 195 0x0>;
-+				clocks = <&gcc GSBI2_UART_CLK>, <&gcc GSBI2_H_CLK>;
-+				clock-names = "core", "iface";
-+				status = "disabled";
-+			};
-+		};
-+
-+		gsbi4: gsbi@16300000 {
-+			compatible = "qcom,gsbi-v1.0.0";
-+			reg = <0x16300000 0x100>;
-+			clocks = <&gcc GSBI4_H_CLK>;
-+			clock-names = "iface";
-+			#address-cells = <1>;
-+			#size-cells = <1>;
-+			ranges;
-+			status = "disabled";
-+
-+			serial@16340000 {
-+				compatible = "qcom,msm-uartdm-v1.3", "qcom,msm-uartdm";
-+				reg = <0x16340000 0x1000>,
-+				      <0x16300000 0x1000>;
-+				interrupts = <0 152 0x0>;
-+				clocks = <&gcc GSBI4_UART_CLK>, <&gcc GSBI4_H_CLK>;
-+				clock-names = "core", "iface";
-+				status = "disabled";
-+			};
-+		};
-+
-+		qcom,ssbi@500000 {
-+			compatible = "qcom,ssbi";
-+			reg = <0x00500000 0x1000>;
-+			qcom,controller-type = "pmic-arbiter";
-+		};
-+
-+		gcc: clock-controller@900000 {
-+			compatible = "qcom,gcc-ipq8064";
-+			reg = <0x00900000 0x4000>;
-+			#clock-cells = <1>;
-+			#reset-cells = <1>;
-+		};
-+	};
-+};
---- a/arch/arm/mach-qcom/board.c
-+++ b/arch/arm/mach-qcom/board.c
-@@ -18,6 +18,8 @@ static const char * const qcom_dt_match[
- 	"qcom,apq8064",
- 	"qcom,apq8074-dragonboard",
- 	"qcom,apq8084",
-+	"qcom,ipq8062",
-+	"qcom,ipq8064",
- 	"qcom,msm8660-surf",
- 	"qcom,msm8960-cdp",
- 	NULL
diff --git a/target/linux/ipq806x/patches/0131-ARM-qcom-config-Enable-IPQ806x-support.patch b/target/linux/ipq806x/patches/0131-ARM-qcom-config-Enable-IPQ806x-support.patch
deleted file mode 100644
index 3a0e3ea..0000000
--- a/target/linux/ipq806x/patches/0131-ARM-qcom-config-Enable-IPQ806x-support.patch
+++ /dev/null
@@ -1,20 +0,0 @@
-From df1564829c4abe206d354f7c1b745cc1e864f4bd Mon Sep 17 00:00:00 2001
-From: Kumar Gala <galak@codeaurora.org>
-Date: Fri, 11 Apr 2014 14:18:29 -0500
-Subject: [PATCH 131/182] ARM: qcom: config: Enable IPQ806x support
-
-Signed-off-by: Kumar Gala <galak@codeaurora.org>
----
- arch/arm/configs/qcom_defconfig |    1 +
- 1 file changed, 1 insertion(+)
-
---- a/arch/arm/configs/qcom_defconfig
-+++ b/arch/arm/configs/qcom_defconfig
-@@ -133,6 +133,7 @@ CONFIG_QCOM_BAM_DMA=y
- CONFIG_STAGING=y
- CONFIG_QCOM_GSBI=y
- CONFIG_COMMON_CLK_QCOM=y
-+CONFIG_IPQ_GCC_806X=y
- CONFIG_MSM_GCC_8660=y
- CONFIG_MSM_MMCC_8960=y
- CONFIG_MSM_MMCC_8974=y
diff --git a/target/linux/ipq806x/patches/0132-XXX-Add-boot-support-for-u-boot.ipq-image.patch b/target/linux/ipq806x/patches/0132-XXX-Add-boot-support-for-u-boot.ipq-image.patch
deleted file mode 100644
index c09c3a6..0000000
--- a/target/linux/ipq806x/patches/0132-XXX-Add-boot-support-for-u-boot.ipq-image.patch
+++ /dev/null
@@ -1,48 +0,0 @@
-From 776fff11c1bf57e564a386521e56c277287a568c Mon Sep 17 00:00:00 2001
-From: Kumar Gala <galak@codeaurora.org>
-Date: Thu, 8 May 2014 13:40:16 -0500
-Subject: [PATCH 132/182] XXX: Add boot support for u-boot.ipq image
-
----
- arch/arm/Makefile      |    2 +-
- arch/arm/boot/Makefile |   11 ++++++++++-
- 2 files changed, 11 insertions(+), 2 deletions(-)
-
---- a/arch/arm/Makefile
-+++ b/arch/arm/Makefile
-@@ -302,7 +302,7 @@ archprepare:
- # Convert bzImage to zImage
- bzImage: zImage
- 
--BOOT_TARGETS	= zImage Image xipImage bootpImage uImage
-+BOOT_TARGETS	= zImage Image xipImage bootpImage uImage uImage.ipq Image.gz
- INSTALL_TARGETS	= zinstall uinstall install
- 
- PHONY += bzImage $(BOOT_TARGETS) $(INSTALL_TARGETS)
---- a/arch/arm/boot/Makefile
-+++ b/arch/arm/boot/Makefile
-@@ -25,7 +25,7 @@ INITRD_PHYS := $(initrd_phys-y)
- 
- export ZRELADDR INITRD_PHYS PARAMS_PHYS
- 
--targets := Image zImage xipImage bootpImage uImage
-+targets := Image zImage xipImage bootpImage uImage uImage.ipq Image.gz
- 
- ifeq ($(CONFIG_XIP_KERNEL),y)
- 
-@@ -80,6 +80,15 @@ $(obj)/uImage:	$(obj)/zImage FORCE
- 	$(call if_changed,uimage)
- 	@$(kecho) '  Image $@ is ready'
- 
-+$(obj)/uImage.ipq: $(obj)/Image.gz FORCE
-+	@$(check_for_multiple_loadaddr)
-+	$(call if_changed,uimage,gzip)
-+	@$(kecho) '  Image $@ is ready'
-+
-+$(obj)/Image.gz: $(obj)/Image FORCE
-+	$(call if_changed,gzip)
-+	@$(kecho) '  Image $@ is ready'
-+
- $(obj)/bootp/bootp: $(obj)/zImage initrd FORCE
- 	$(Q)$(MAKE) $(build)=$(obj)/bootp $@
- 	@:
diff --git a/target/linux/ipq806x/patches/0133-spi-qup-Remove-chip-select-function.patch b/target/linux/ipq806x/patches/0133-spi-qup-Remove-chip-select-function.patch
deleted file mode 100644
index 14ae782..0000000
--- a/target/linux/ipq806x/patches/0133-spi-qup-Remove-chip-select-function.patch
+++ /dev/null
@@ -1,83 +0,0 @@
-From 9bc674f40f22596ef8c2ff6d7f9e53da0baa57e9 Mon Sep 17 00:00:00 2001
-From: Andy Gross <agross@codeaurora.org>
-Date: Thu, 12 Jun 2014 14:34:10 -0500
-Subject: [PATCH 133/182] spi: qup: Remove chip select function
-
-This patch removes the chip select function.  Chip select should instead be
-supported using GPIOs, defining the DT entry "cs-gpios", and letting the SPI
-core assert/deassert the chip select as it sees fit.
-
-Signed-off-by: Andy Gross <agross@codeaurora.org>
----
- .../devicetree/bindings/spi/qcom,spi-qup.txt       |    6 ++++
- drivers/spi/spi-qup.c                              |   33 ++++----------------
- 2 files changed, 12 insertions(+), 27 deletions(-)
-
---- a/Documentation/devicetree/bindings/spi/qcom,spi-qup.txt
-+++ b/Documentation/devicetree/bindings/spi/qcom,spi-qup.txt
-@@ -23,6 +23,12 @@ Optional properties:
- - spi-max-frequency: Specifies maximum SPI clock frequency,
-                      Units - Hz. Definition as per
-                      Documentation/devicetree/bindings/spi/spi-bus.txt
-+- num-cs:	total number of chipselects
-+- cs-gpios:	should specify GPIOs used for chipselects.
-+		The gpios will be referred to as reg = <index> in the SPI child
-+		nodes.  If unspecified, a single SPI device without a chip
-+		select can be used.
-+
- 
- SPI slave nodes must be children of the SPI master node and can contain
- properties described in Documentation/devicetree/bindings/spi/spi-bus.txt
---- a/drivers/spi/spi-qup.c
-+++ b/drivers/spi/spi-qup.c
-@@ -424,31 +424,6 @@ static int spi_qup_io_config(struct spi_
- 	return 0;
- }
- 
--static void spi_qup_set_cs(struct spi_device *spi, bool enable)
--{
--	struct spi_qup *controller = spi_master_get_devdata(spi->master);
--
--	u32 iocontol, mask;
--
--	iocontol = readl_relaxed(controller->base + SPI_IO_CONTROL);
--
--	/* Disable auto CS toggle and use manual */
--	iocontol &= ~SPI_IO_C_MX_CS_MODE;
--	iocontol |= SPI_IO_C_FORCE_CS;
--
--	iocontol &= ~SPI_IO_C_CS_SELECT_MASK;
--	iocontol |= SPI_IO_C_CS_SELECT(spi->chip_select);
--
--	mask = SPI_IO_C_CS_N_POLARITY_0 << spi->chip_select;
--
--	if (enable)
--		iocontol |= mask;
--	else
--		iocontol &= ~mask;
--
--	writel_relaxed(iocontol, controller->base + SPI_IO_CONTROL);
--}
--
- static int spi_qup_transfer_one(struct spi_master *master,
- 			      struct spi_device *spi,
- 			      struct spi_transfer *xfer)
-@@ -571,12 +546,16 @@ static int spi_qup_probe(struct platform
- 		return -ENOMEM;
- 	}
- 
-+	/* use num-cs unless not present or out of range */
-+	if (of_property_read_u16(dev->of_node, "num-cs",
-+			&master->num_chipselect) ||
-+			(master->num_chipselect > SPI_NUM_CHIPSELECTS))
-+		master->num_chipselect = SPI_NUM_CHIPSELECTS;
-+
- 	master->bus_num = pdev->id;
- 	master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH | SPI_LOOP;
--	master->num_chipselect = SPI_NUM_CHIPSELECTS;
- 	master->bits_per_word_mask = SPI_BPW_RANGE_MASK(4, 32);
- 	master->max_speed_hz = max_freq;
--	master->set_cs = spi_qup_set_cs;
- 	master->transfer_one = spi_qup_transfer_one;
- 	master->dev.of_node = pdev->dev.of_node;
- 	master->auto_runtime_pm = true;
diff --git a/target/linux/ipq806x/patches/0134-spi-qup-Fix-order-of-spi_register_master.patch b/target/linux/ipq806x/patches/0134-spi-qup-Fix-order-of-spi_register_master.patch
deleted file mode 100644
index 93afe28..0000000
--- a/target/linux/ipq806x/patches/0134-spi-qup-Fix-order-of-spi_register_master.patch
+++ /dev/null
@@ -1,41 +0,0 @@
-From a7357be131e30fd1fb987b2cb343bc81db487f96 Mon Sep 17 00:00:00 2001
-From: Andy Gross <agross@codeaurora.org>
-Date: Thu, 12 Jun 2014 14:34:11 -0500
-Subject: [PATCH 134/182] spi: qup: Fix order of spi_register_master
-
-This patch moves the devm_spi_register_master below the initialization of the
-runtime_pm.  If done in the wrong order, the spi_register_master fails if any
-probed slave devices issue SPI transactions.
-
-Signed-off-by: Andy Gross <agross@codeaurora.org>
-Acked-by: Ivan T. Ivanov <iivanov@mm-sol.com>
----
- drivers/spi/spi-qup.c |   11 +++++++----
- 1 file changed, 7 insertions(+), 4 deletions(-)
-
---- a/drivers/spi/spi-qup.c
-+++ b/drivers/spi/spi-qup.c
-@@ -619,16 +619,19 @@ static int spi_qup_probe(struct platform
- 	if (ret)
- 		goto error;
- 
--	ret = devm_spi_register_master(dev, master);
--	if (ret)
--		goto error;
--
- 	pm_runtime_set_autosuspend_delay(dev, MSEC_PER_SEC);
- 	pm_runtime_use_autosuspend(dev);
- 	pm_runtime_set_active(dev);
- 	pm_runtime_enable(dev);
-+
-+	ret = devm_spi_register_master(dev, master);
-+	if (ret)
-+		goto disable_pm;
-+
- 	return 0;
- 
-+disable_pm:
-+	pm_runtime_disable(&pdev->dev);
- error:
- 	clk_disable_unprepare(cclk);
- 	clk_disable_unprepare(iclk);
diff --git a/target/linux/ipq806x/patches/0135-spi-qup-Add-support-for-v1.1.1.patch b/target/linux/ipq806x/patches/0135-spi-qup-Add-support-for-v1.1.1.patch
deleted file mode 100644
index 86cce61..0000000
--- a/target/linux/ipq806x/patches/0135-spi-qup-Add-support-for-v1.1.1.patch
+++ /dev/null
@@ -1,125 +0,0 @@
-From 8b9de04ef3aaa154f30baf1ac703a2d3b474ad4e Mon Sep 17 00:00:00 2001
-From: Andy Gross <agross@codeaurora.org>
-Date: Thu, 12 Jun 2014 14:34:12 -0500
-Subject: [PATCH 135/182] spi: qup: Add support for v1.1.1
-
-This patch adds support for v1.1.1 of the SPI QUP controller.
-
-Signed-off-by: Andy Gross <agross@codeaurora.org>
----
- .../devicetree/bindings/spi/qcom,spi-qup.txt       |    6 +++-
- drivers/spi/spi-qup.c                              |   36 ++++++++++++--------
- 2 files changed, 27 insertions(+), 15 deletions(-)
-
---- a/Documentation/devicetree/bindings/spi/qcom,spi-qup.txt
-+++ b/Documentation/devicetree/bindings/spi/qcom,spi-qup.txt
-@@ -7,7 +7,11 @@ SPI in master mode supports up to 50MHz,
- data path from 4 bits to 32 bits and numerous protocol variants.
- 
- Required properties:
--- compatible:     Should contain "qcom,spi-qup-v2.1.1" or "qcom,spi-qup-v2.2.1"
-+- compatible:     Should contain:
-+		  "qcom,spi-qup-v1.1.1" for 8660, 8960 and 8064.
-+		  "qcom,spi-qup-v2.1.1" for 8974 and later
-+		  "qcom,spi-qup-v2.2.1" for 8974 v2 and later.
-+
- - reg:            Should contain base register location and length
- - interrupts:     Interrupt number used by this controller
- 
---- a/drivers/spi/spi-qup.c
-+++ b/drivers/spi/spi-qup.c
-@@ -142,6 +142,7 @@ struct spi_qup {
- 	int			w_size;	/* bytes per SPI word */
- 	int			tx_bytes;
- 	int			rx_bytes;
-+	int			qup_v1;
- };
- 
- 
-@@ -420,7 +421,9 @@ static int spi_qup_io_config(struct spi_
- 	config |= QUP_CONFIG_SPI_MODE;
- 	writel_relaxed(config, controller->base + QUP_CONFIG);
- 
--	writel_relaxed(0, controller->base + QUP_OPERATIONAL_MASK);
-+	/* only write to OPERATIONAL_MASK when register is present */
-+	if (!controller->qup_v1)
-+		writel_relaxed(0, controller->base + QUP_OPERATIONAL_MASK);
- 	return 0;
- }
- 
-@@ -486,7 +489,7 @@ static int spi_qup_probe(struct platform
- 	struct resource *res;
- 	struct device *dev;
- 	void __iomem *base;
--	u32 data, max_freq, iomode;
-+	u32 max_freq, iomode;
- 	int ret, irq, size;
- 
- 	dev = &pdev->dev;
-@@ -529,15 +532,6 @@ static int spi_qup_probe(struct platform
- 		return ret;
- 	}
- 
--	data = readl_relaxed(base + QUP_HW_VERSION);
--
--	if (data < QUP_HW_VERSION_2_1_1) {
--		clk_disable_unprepare(cclk);
--		clk_disable_unprepare(iclk);
--		dev_err(dev, "v.%08x is not supported\n", data);
--		return -ENXIO;
--	}
--
- 	master = spi_alloc_master(dev, sizeof(struct spi_qup));
- 	if (!master) {
- 		clk_disable_unprepare(cclk);
-@@ -570,6 +564,10 @@ static int spi_qup_probe(struct platform
- 	controller->cclk = cclk;
- 	controller->irq = irq;
- 
-+	/* set v1 flag if device is version 1 */
-+	if (of_device_is_compatible(dev->of_node, "qcom,spi-qup-v1.1.1"))
-+		controller->qup_v1 = 1;
-+
- 	spin_lock_init(&controller->lock);
- 	init_completion(&controller->done);
- 
-@@ -593,8 +591,8 @@ static int spi_qup_probe(struct platform
- 	size = QUP_IO_M_INPUT_FIFO_SIZE(iomode);
- 	controller->in_fifo_sz = controller->in_blk_sz * (2 << size);
- 
--	dev_info(dev, "v.%08x IN:block:%d, fifo:%d, OUT:block:%d, fifo:%d\n",
--		 data, controller->in_blk_sz, controller->in_fifo_sz,
-+	dev_info(dev, "IN:block:%d, fifo:%d, OUT:block:%d, fifo:%d\n",
-+		 controller->in_blk_sz, controller->in_fifo_sz,
- 		 controller->out_blk_sz, controller->out_fifo_sz);
- 
- 	writel_relaxed(1, base + QUP_SW_RESET);
-@@ -607,10 +605,19 @@ static int spi_qup_probe(struct platform
- 
- 	writel_relaxed(0, base + QUP_OPERATIONAL);
- 	writel_relaxed(0, base + QUP_IO_M_MODES);
--	writel_relaxed(0, base + QUP_OPERATIONAL_MASK);
-+
-+	if (!controller->qup_v1)
-+		writel_relaxed(0, base + QUP_OPERATIONAL_MASK);
-+
- 	writel_relaxed(SPI_ERROR_CLK_UNDER_RUN | SPI_ERROR_CLK_OVER_RUN,
- 		       base + SPI_ERROR_FLAGS_EN);
- 
-+	/* if earlier version of the QUP, disable INPUT_OVERRUN */
-+	if (controller->qup_v1)
-+		writel_relaxed(QUP_ERROR_OUTPUT_OVER_RUN |
-+			QUP_ERROR_INPUT_UNDER_RUN | QUP_ERROR_OUTPUT_UNDER_RUN,
-+			base + QUP_ERROR_FLAGS_EN);
-+
- 	writel_relaxed(0, base + SPI_CONFIG);
- 	writel_relaxed(SPI_IO_C_NO_TRI_STATE, base + SPI_IO_CONTROL);
- 
-@@ -732,6 +739,7 @@ static int spi_qup_remove(struct platfor
- }
- 
- static struct of_device_id spi_qup_dt_match[] = {
-+	{ .compatible = "qcom,spi-qup-v1.1.1", },
- 	{ .compatible = "qcom,spi-qup-v2.1.1", },
- 	{ .compatible = "qcom,spi-qup-v2.2.1", },
- 	{ }
diff --git a/target/linux/ipq806x/patches/0136-ARM-ipq8064-ap148-Add-i2c-pinctrl-nodes.patch b/target/linux/ipq806x/patches/0136-ARM-ipq8064-ap148-Add-i2c-pinctrl-nodes.patch
deleted file mode 100644
index 7e9776e..0000000
--- a/target/linux/ipq806x/patches/0136-ARM-ipq8064-ap148-Add-i2c-pinctrl-nodes.patch
+++ /dev/null
@@ -1,86 +0,0 @@
-From e93b9480667cbd0e3a4276e8749279693fe239f4 Mon Sep 17 00:00:00 2001
-From: Andy Gross <agross@codeaurora.org>
-Date: Wed, 14 May 2014 22:49:03 -0500
-Subject: [PATCH 136/182] ARM: ipq8064-ap148: Add i2c pinctrl nodes
-
-Signed-off-by: Andy Gross <agross@codeaurora.org>
----
- arch/arm/boot/dts/qcom-ipq8064-ap148.dts |   17 +++++++++++++++++
- arch/arm/boot/dts/qcom-ipq8064.dtsi      |   27 +++++++++++++++++++++++++++
- 2 files changed, 44 insertions(+)
-
---- a/arch/arm/boot/dts/qcom-ipq8064-ap148.dts
-+++ b/arch/arm/boot/dts/qcom-ipq8064-ap148.dts
-@@ -14,12 +14,29 @@
- 	};
- 
- 	soc {
-+		pinmux@800000 {
-+			i2c4_pins: i2c4_pinmux {
-+				pins = "gpio12", "gpio13";
-+				function = "gsbi4";
-+				bias-disable;
-+			};
-+		};
-+
- 		gsbi@16300000 {
- 			qcom,mode = <GSBI_PROT_I2C_UART>;
- 			status = "ok";
- 			serial@16340000 {
- 				status = "ok";
- 			};
-+
-+			i2c4: i2c@16380000 {
-+				status = "ok";
-+
-+				clock-frequency = <200000>;
-+
-+				pinctrl-0 = <&i2c4_pins>;
-+				pinctrl-names = "default";
-+			};
- 		};
- 	};
- };
---- a/arch/arm/boot/dts/qcom-ipq8064.dtsi
-+++ b/arch/arm/boot/dts/qcom-ipq8064.dtsi
-@@ -137,6 +137,20 @@
- 				clock-names = "core", "iface";
- 				status = "disabled";
- 			};
-+
-+			i2c@124a0000 {
-+				compatible = "qcom,i2c-qup-v1.1.1";
-+				reg = <0x124a0000 0x1000>;
-+				interrupts = <0 196 0>;
-+
-+				clocks = <&gcc GSBI2_QUP_CLK>, <&gcc GSBI2_H_CLK>;
-+				clock-names = "core", "iface";
-+				status = "disabled";
-+
-+				#address-cells = <1>;
-+				#size-cells = <0>;
-+			};
-+
- 		};
- 
- 		gsbi4: gsbi@16300000 {
-@@ -158,6 +172,19 @@
- 				clock-names = "core", "iface";
- 				status = "disabled";
- 			};
-+
-+			i2c@16380000 {
-+				compatible = "qcom,i2c-qup-v1.1.1";
-+				reg = <0x16380000 0x1000>;
-+				interrupts = <0 153 0>;
-+
-+				clocks = <&gcc GSBI4_QUP_CLK>, <&gcc GSBI4_H_CLK>;
-+				clock-names = "core", "iface";
-+				status = "disabled";
-+
-+				#address-cells = <1>;
-+				#size-cells = <0>;
-+			};
- 		};
- 
- 		qcom,ssbi@500000 {
diff --git a/target/linux/ipq806x/patches/0137-ARM-qcom-ipq8064-ap148-Add-SPI-related-bindings.patch b/target/linux/ipq806x/patches/0137-ARM-qcom-ipq8064-ap148-Add-SPI-related-bindings.patch
deleted file mode 100644
index f72446e..0000000
--- a/target/linux/ipq806x/patches/0137-ARM-qcom-ipq8064-ap148-Add-SPI-related-bindings.patch
+++ /dev/null
@@ -1,124 +0,0 @@
-From b9eaa80146abb09bcc7e6d8b33fca476453c839c Mon Sep 17 00:00:00 2001
-From: Andy Gross <agross@codeaurora.org>
-Date: Wed, 14 May 2014 22:01:16 -0500
-Subject: [PATCH 137/182] ARM: qcom-ipq8064-ap148: Add SPI related bindings
-
-Signed-off-by: Andy Gross <agross@codeaurora.org>
----
- arch/arm/boot/dts/qcom-ipq8064-ap148.dts |   42 ++++++++++++++++++++++++++
- arch/arm/boot/dts/qcom-ipq8064.dtsi      |   47 ++++++++++++++++++++++++++++++
- 2 files changed, 89 insertions(+)
-
---- a/arch/arm/boot/dts/qcom-ipq8064-ap148.dts
-+++ b/arch/arm/boot/dts/qcom-ipq8064-ap148.dts
-@@ -20,6 +20,15 @@
- 				function = "gsbi4";
- 				bias-disable;
- 			};
-+
-+			spi_pins: spi_pins {
-+				mux {
-+					pins = "gpio18", "gpio19", "gpio21";
-+					function = "gsbi5";
-+					drive-strength = <10>;
-+					bias-none;
-+				};
-+			};
- 		};
- 
- 		gsbi@16300000 {
-@@ -38,5 +47,38 @@
- 				pinctrl-names = "default";
- 			};
- 		};
-+
-+		gsbi5: gsbi@1a200000 {
-+			qcom,mode = <GSBI_PROT_SPI>;
-+			status = "ok";
-+
-+			spi4: spi@1a280000 {
-+				status = "ok";
-+				spi-max-frequency = <50000000>;
-+
-+				pinctrl-0 = <&spi_pins>;
-+				pinctrl-names = "default";
-+
-+				cs-gpios = <&qcom_pinmux 20 0>;
-+
-+				flash: m25p80@0 {
-+					compatible = "s25fl256s1";
-+					#address-cells = <1>;
-+					#size-cells = <1>;
-+					spi-max-frequency = <50000000>;
-+					reg = <0>;
-+
-+					partition@0 {
-+						label = "rootfs";
-+						reg = <0x0 0x1000000>;
-+					};
-+
-+					partition@1 {
-+						label = "scratch";
-+						reg = <0x1000000 0x1000000>;
-+					};
-+				};
-+			};
-+		};
- 	};
- };
---- a/arch/arm/boot/dts/qcom-ipq8064.dtsi
-+++ b/arch/arm/boot/dts/qcom-ipq8064.dtsi
-@@ -187,6 +187,53 @@
- 			};
- 		};
- 
-+		gsbi5: gsbi@1a200000 {
-+			compatible = "qcom,gsbi-v1.0.0";
-+			reg = <0x1a200000 0x100>;
-+			clocks = <&gcc GSBI5_H_CLK>;
-+			clock-names = "iface";
-+			#address-cells = <1>;
-+			#size-cells = <1>;
-+			ranges;
-+			status = "disabled";
-+
-+			serial@1a240000 {
-+				compatible = "qcom,msm-uartdm-v1.3", "qcom,msm-uartdm";
-+				reg = <0x1a240000 0x1000>,
-+				      <0x1a200000 0x1000>;
-+				interrupts = <0 154 0x0>;
-+				clocks = <&gcc GSBI5_UART_CLK>, <&gcc GSBI5_H_CLK>;
-+				clock-names = "core", "iface";
-+				status = "disabled";
-+			};
-+
-+			i2c@1a280000 {
-+				compatible = "qcom,i2c-qup-v1.1.1";
-+				reg = <0x1a280000 0x1000>;
-+				interrupts = <0 155 0>;
-+
-+				clocks = <&gcc GSBI5_QUP_CLK>, <&gcc GSBI5_H_CLK>;
-+				clock-names = "core", "iface";
-+				status = "disabled";
-+
-+				#address-cells = <1>;
-+				#size-cells = <0>;
-+			};
-+
-+			spi@1a280000 {
-+				compatible = "qcom,spi-qup-v1.1.1";
-+				reg = <0x1a280000 0x1000>;
-+				interrupts = <0 155 0>;
-+
-+				clocks = <&gcc GSBI5_QUP_CLK>, <&gcc GSBI5_H_CLK>;
-+				clock-names = "core", "iface";
-+				status = "disabled";
-+
-+				#address-cells = <1>;
-+				#size-cells = <0>;
-+			};
-+		};
-+
- 		qcom,ssbi@500000 {
- 			compatible = "qcom,ssbi";
- 			reg = <0x00500000 0x1000>;
diff --git a/target/linux/ipq806x/patches/0138-PCI-qcom-Add-support-for-pcie-controllers-on-IPQ8064.patch b/target/linux/ipq806x/patches/0138-PCI-qcom-Add-support-for-pcie-controllers-on-IPQ8064.patch
deleted file mode 100644
index 8aaa766..0000000
--- a/target/linux/ipq806x/patches/0138-PCI-qcom-Add-support-for-pcie-controllers-on-IPQ8064.patch
+++ /dev/null
@@ -1,716 +0,0 @@
-From 98567c99b4dcd80fc9e5dd97229ebb9a7f6dab03 Mon Sep 17 00:00:00 2001
-From: Kumar Gala <galak@codeaurora.org>
-Date: Fri, 16 May 2014 11:53:23 -0500
-Subject: [PATCH 138/182] PCI: qcom: Add support for pcie controllers on
- IPQ8064
-
----
- arch/arm/mach-qcom/Kconfig  |    2 +
- drivers/pci/host/Makefile   |    1 +
- drivers/pci/host/pci-qcom.c |  682 +++++++++++++++++++++++++++++++++++++++++++
- 3 files changed, 685 insertions(+)
- create mode 100644 drivers/pci/host/pci-qcom.c
-
---- a/arch/arm/mach-qcom/Kconfig
-+++ b/arch/arm/mach-qcom/Kconfig
-@@ -7,6 +7,8 @@ config ARCH_QCOM
- 	select GENERIC_CLOCKEVENTS
- 	select HAVE_SMP
- 	select PINCTRL
-+	select MIGHT_HAVE_PCI
-+	select PCI_DOMAINS if PCI
- 	select QCOM_SCM if SMP
- 	help
- 	  Support for Qualcomm's devicetree based systems.
---- a/drivers/pci/host/Makefile
-+++ b/drivers/pci/host/Makefile
-@@ -4,3 +4,4 @@ obj-$(CONFIG_PCI_IMX6) += pci-imx6.o
- obj-$(CONFIG_PCI_MVEBU) += pci-mvebu.o
- obj-$(CONFIG_PCI_TEGRA) += pci-tegra.o
- obj-$(CONFIG_PCI_RCAR_GEN2) += pci-rcar-gen2.o
-+obj-$(CONFIG_ARCH_QCOM) += pci-qcom.o
---- /dev/null
-+++ b/drivers/pci/host/pci-qcom.c
-@@ -0,0 +1,682 @@
-+/* Copyright (c) 2012-2014, The Linux Foundation. All rights reserved.
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 and
-+ * only version 2 as published by the Free Software Foundation.
-+ *
-+ * 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.
-+ */
-+
-+/*
-+ * QCOM MSM PCIe controller driver.
-+ */
-+
-+#include <linux/kernel.h>
-+#include <linux/pci.h>
-+#include <linux/gpio.h>
-+#include <linux/of_gpio.h>
-+#include <linux/platform_device.h>
-+#include <linux/of_address.h>
-+#include <linux/clk.h>
-+#include <linux/reset.h>
-+#include <linux/delay.h>
-+
-+/* Root Complex Port vendor/device IDs */
-+#define PCIE_VENDOR_ID_RCP		0x17cb
-+#define PCIE_DEVICE_ID_RCP		0x0101
-+
-+#define __set(v, a, b)	(((v) << (b)) & GENMASK(a, b))
-+
-+#define PCIE20_PARF_PCS_DEEMPH		0x34
-+#define PCIE20_PARF_PCS_DEEMPH_TX_DEEMPH_GEN1(x)	__set(x, 21, 16)
-+#define PCIE20_PARF_PCS_DEEMPH_TX_DEEMPH_GEN2_3_5DB(x)	__set(x, 13, 8)
-+#define PCIE20_PARF_PCS_DEEMPH_TX_DEEMPH_GEN2_6DB(x)	__set(x, 5, 0)
-+
-+#define PCIE20_PARF_PCS_SWING		0x38
-+#define PCIE20_PARF_PCS_SWING_TX_SWING_FULL(x)		__set(x, 14, 8)
-+#define PCIE20_PARF_PCS_SWING_TX_SWING_LOW(x)		__set(x, 6, 0)
-+
-+#define PCIE20_PARF_PHY_CTRL		0x40
-+#define PCIE20_PARF_PHY_CTRL_PHY_TX0_TERM_OFFST(x)	__set(x, 20, 16)
-+#define PCIE20_PARF_PHY_CTRL_PHY_LOS_LEVEL(x)		__set(x, 12, 8)
-+#define PCIE20_PARF_PHY_CTRL_PHY_RTUNE_REQ		(1 << 4)
-+#define PCIE20_PARF_PHY_CTRL_PHY_TEST_BURNIN		(1 << 2)
-+#define PCIE20_PARF_PHY_CTRL_PHY_TEST_BYPASS		(1 << 1)
-+#define PCIE20_PARF_PHY_CTRL_PHY_TEST_PWR_DOWN		(1 << 0)
-+
-+#define PCIE20_PARF_PHY_REFCLK		0x4C
-+#define PCIE20_PARF_CONFIG_BITS		0x50
-+
-+#define PCIE20_ELBI_SYS_CTRL		0x04
-+#define PCIE20_ELBI_SYS_CTRL_LTSSM_EN	0x01
-+
-+#define PCIE20_CAP			0x70
-+#define PCIE20_CAP_LINKCTRLSTATUS	(PCIE20_CAP + 0x10)
-+
-+#define PCIE20_COMMAND_STATUS		0x04
-+#define PCIE20_BUSNUMBERS		0x18
-+#define PCIE20_MEMORY_BASE_LIMIT	0x20
-+
-+#define PCIE20_AXI_MSTR_RESP_COMP_CTRL0 0x818
-+#define PCIE20_AXI_MSTR_RESP_COMP_CTRL1 0x81c
-+#define PCIE20_PLR_IATU_VIEWPORT	0x900
-+#define PCIE20_PLR_IATU_CTRL1		0x904
-+#define PCIE20_PLR_IATU_CTRL2		0x908
-+#define PCIE20_PLR_IATU_LBAR		0x90C
-+#define PCIE20_PLR_IATU_UBAR		0x910
-+#define PCIE20_PLR_IATU_LAR		0x914
-+#define PCIE20_PLR_IATU_LTAR		0x918
-+#define PCIE20_PLR_IATU_UTAR		0x91c
-+
-+#define MSM_PCIE_DEV_CFG_ADDR		0x01000000
-+
-+#define RD 0
-+#define WR 1
-+
-+#define MAX_RC_NUM	3
-+#define PCIE_BUS_PRIV_DATA(pdev) \
-+	(((struct pci_sys_data *)pdev->bus->sysdata)->private_data)
-+
-+/* PCIe TLP types that we are interested in */
-+#define PCI_CFG0_RDWR	0x4
-+#define PCI_CFG1_RDWR	0x5
-+
-+#define readl_poll_timeout(addr, val, cond, sleep_us, timeout_us) \
-+({ \
-+	unsigned long timeout = jiffies + usecs_to_jiffies(timeout_us); \
-+	might_sleep_if(timeout_us); \
-+	for (;;) { \
-+		(val) = readl(addr); \
-+		if (cond) \
-+			break; \
-+		if (timeout_us && time_after(jiffies, timeout)) { \
-+			(val) = readl(addr); \
-+			break; \
-+		} \
-+		if (sleep_us) \
-+			usleep_range(DIV_ROUND_UP(sleep_us, 4), sleep_us); \
-+	} \
-+	(cond) ? 0 : -ETIMEDOUT; \
-+})
-+
-+struct qcom_pcie {
-+	void __iomem		*elbi_base;
-+	void __iomem		*parf_base;
-+	void __iomem		*dwc_base;
-+	void __iomem		*cfg_base;
-+	int			reset_gpio;
-+	struct clk		*iface_clk;
-+	struct clk		*bus_clk;
-+	struct clk		*phy_clk;
-+	int			irq_int[4];
-+	struct reset_control	*axi_reset;
-+	struct reset_control	*ahb_reset;
-+	struct reset_control	*por_reset;
-+	struct reset_control	*pci_reset;
-+	struct reset_control	*phy_reset;
-+
-+	struct resource		conf;
-+	struct resource		io;
-+	struct resource		mem;
-+};
-+
-+static int qcom_pcie_map_irq(const struct pci_dev *dev, u8 slot, u8 pin);
-+static int qcom_pcie_setup(int nr, struct pci_sys_data *sys);
-+static int msm_pcie_rd_conf(struct pci_bus *bus, u32 devfn, int where,
-+			    int size, u32 *val);
-+static int msm_pcie_wr_conf(struct pci_bus *bus, u32 devfn,
-+			    int where, int size, u32 val);
-+
-+static struct pci_ops qcom_pcie_ops = {
-+	.read = msm_pcie_rd_conf,
-+	.write = msm_pcie_wr_conf,
-+};
-+
-+static struct hw_pci qcom_hw_pci[MAX_RC_NUM] = {
-+	{
-+#ifdef CONFIG_PCI_DOMAINS
-+		.domain = 0,
-+#endif
-+		.ops		= &qcom_pcie_ops,
-+		.nr_controllers	= 1,
-+		.swizzle	= pci_common_swizzle,
-+		.setup		= qcom_pcie_setup,
-+		.map_irq	= qcom_pcie_map_irq,
-+	},
-+	{
-+#ifdef CONFIG_PCI_DOMAINS
-+		.domain = 1,
-+#endif
-+		.ops		= &qcom_pcie_ops,
-+		.nr_controllers	= 1,
-+		.swizzle	= pci_common_swizzle,
-+		.setup		= qcom_pcie_setup,
-+		.map_irq	= qcom_pcie_map_irq,
-+	},
-+	{
-+#ifdef CONFIG_PCI_DOMAINS
-+		.domain = 2,
-+#endif
-+		.ops		= &qcom_pcie_ops,
-+		.nr_controllers	= 1,
-+		.swizzle	= pci_common_swizzle,
-+		.setup		= qcom_pcie_setup,
-+		.map_irq	= qcom_pcie_map_irq,
-+	},
-+};
-+
-+static int nr_controllers;
-+static DEFINE_SPINLOCK(qcom_hw_pci_lock);
-+
-+static inline struct qcom_pcie *sys_to_pcie(struct pci_sys_data *sys)
-+{
-+	return sys->private_data;
-+}
-+
-+inline int is_msm_pcie_rc(struct pci_bus *bus)
-+{
-+	return (bus->number == 0);
-+}
-+
-+static int qcom_pcie_is_link_up(struct qcom_pcie *dev)
-+{
-+	return readl_relaxed(dev->dwc_base + PCIE20_CAP_LINKCTRLSTATUS) & BIT(29);
-+}
-+
-+inline int msm_pcie_get_cfgtype(struct pci_bus *bus)
-+{
-+	/*
-+	 * http://www.tldp.org/LDP/tlk/dd/pci.html
-+	 * Pass it onto the secondary bus interface unchanged if the
-+	 * bus number specified is greater than the secondary bus
-+	 * number and less than or equal to the subordinate bus
-+	 * number.
-+	 *
-+	 * Read/Write to the RC and Device/Switch connected to the RC
-+	 * are CFG0 type transactions. Rest have to be forwarded
-+	 * down stream as CFG1 transactions.
-+	 *
-+	 */
-+	if (bus->number == 0)
-+		return PCI_CFG0_RDWR;
-+
-+	return PCI_CFG0_RDWR;
-+}
-+
-+void msm_pcie_config_cfgtype(struct pci_bus *bus, u32 devfn)
-+{
-+	uint32_t bdf, cfgtype;
-+	struct qcom_pcie *dev = sys_to_pcie(bus->sysdata);
-+
-+	cfgtype = msm_pcie_get_cfgtype(bus);
-+
-+	if (cfgtype == PCI_CFG0_RDWR) {
-+		bdf = MSM_PCIE_DEV_CFG_ADDR;
-+	} else {
-+		/*
-+		 * iATU Lower Target Address Register
-+		 *	Bits	Description
-+		 *	*-1:0	Forms bits [*:0] of the
-+		 *		start address of the new
-+		 *		address of the translated
-+		 *		region. The start address
-+		 *		must be aligned to a
-+		 *		CX_ATU_MIN_REGION_SIZE kB
-+		 *		boundary, so these bits are
-+		 *		always 0. A write to this
-+		 *		location is ignored by the
-+		 *		PCIe core.
-+		 *	31:*1	Forms bits [31:*] of the of
-+		 *		the new address of the
-+		 *		translated region.
-+		 *
-+		 *	* is log2(CX_ATU_MIN_REGION_SIZE)
-+		 */
-+		bdf = (((bus->number & 0xff) << 24) & 0xff000000) |
-+				(((devfn & 0xff) << 16) & 0x00ff0000);
-+	}
-+
-+	writel_relaxed(0, dev->dwc_base + PCIE20_PLR_IATU_VIEWPORT);
-+	wmb();
-+
-+	/* Program Bdf Address */
-+	writel_relaxed(bdf, dev->dwc_base + PCIE20_PLR_IATU_LTAR);
-+	wmb();
-+
-+	/* Write Config Request Type */
-+	writel_relaxed(cfgtype, dev->dwc_base + PCIE20_PLR_IATU_CTRL1);
-+	wmb();
-+}
-+
-+static inline int msm_pcie_oper_conf(struct pci_bus *bus, u32 devfn, int oper,
-+				     int where, int size, u32 *val)
-+{
-+	uint32_t word_offset, byte_offset, mask;
-+	uint32_t rd_val, wr_val;
-+	struct qcom_pcie *dev = sys_to_pcie(bus->sysdata);
-+	void __iomem *config_base;
-+	int rc;
-+
-+	rc = is_msm_pcie_rc(bus);
-+
-+	/*
-+	 * For downstream bus, make sure link is up
-+	 */
-+	if (rc && (devfn != 0)) {
-+		*val = ~0;
-+		return PCIBIOS_DEVICE_NOT_FOUND;
-+	} else if ((!rc) && (!qcom_pcie_is_link_up(dev))) {
-+		*val = ~0;
-+		return PCIBIOS_DEVICE_NOT_FOUND;
-+	}
-+
-+	msm_pcie_config_cfgtype(bus, devfn);
-+
-+	word_offset = where & ~0x3;
-+	byte_offset = where & 0x3;
-+	mask = (~0 >> (8 * (4 - size))) << (8 * byte_offset);
-+
-+	config_base = (rc) ? dev->dwc_base : dev->cfg_base;
-+	rd_val = readl_relaxed(config_base + word_offset);
-+
-+	if (oper == RD) {
-+		*val = ((rd_val & mask) >> (8 * byte_offset));
-+	} else {
-+		wr_val = (rd_val & ~mask) |
-+				((*val << (8 * byte_offset)) & mask);
-+		writel_relaxed(wr_val, config_base + word_offset);
-+		wmb(); /* ensure config data is written to hardware register */
-+	}
-+
-+	return 0;
-+}
-+
-+static int msm_pcie_rd_conf(struct pci_bus *bus, u32 devfn, int where,
-+			    int size, u32 *val)
-+{
-+	return msm_pcie_oper_conf(bus, devfn, RD, where, size, val);
-+}
-+
-+static int msm_pcie_wr_conf(struct pci_bus *bus, u32 devfn,
-+			    int where, int size, u32 val)
-+{
-+	/*
-+	 *Attempt to reset secondary bus is causing PCIE core to reset.
-+	 *Disable secondary bus reset functionality.
-+	 */
-+	if ((bus->number == 0) && (where == PCI_BRIDGE_CONTROL) &&
-+	    (val & PCI_BRIDGE_CTL_BUS_RESET)) {
-+		pr_info("PCIE secondary bus reset not supported\n");
-+		val &= ~PCI_BRIDGE_CTL_BUS_RESET;
-+	}
-+
-+	return msm_pcie_oper_conf(bus, devfn, WR, where, size, &val);
-+}
-+
-+static int qcom_pcie_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
-+{
-+	struct qcom_pcie *pcie_dev = PCIE_BUS_PRIV_DATA(dev);
-+
-+	return pcie_dev->irq_int[pin-1];
-+}
-+
-+static int qcom_pcie_setup(int nr, struct pci_sys_data *sys)
-+{
-+	struct qcom_pcie *qcom_pcie = sys->private_data;
-+
-+	/*
-+	 * specify linux PCI framework to allocate device memory (BARs)
-+	 * from msm_pcie_dev.dev_mem_res resource.
-+	 */
-+	sys->mem_offset = 0;
-+	sys->io_offset = 0;
-+
-+	pci_add_resource(&sys->resources, &qcom_pcie->mem);
-+	pci_add_resource(&sys->resources, &qcom_pcie->io);
-+
-+	return 1;
-+}
-+
-+static inline void qcom_elbi_writel_relaxed(struct qcom_pcie *pcie, u32 val, u32 reg)
-+{
-+	writel_relaxed(val, pcie->elbi_base + reg);
-+}
-+
-+static inline u32 qcom_elbi_readl_relaxed(struct qcom_pcie *pcie, u32 reg)
-+{
-+	return readl_relaxed(pcie->elbi_base + reg);
-+}
-+
-+static inline void qcom_parf_writel_relaxed(struct qcom_pcie *pcie, u32 val, u32 reg)
-+{
-+	writel_relaxed(val, pcie->parf_base + reg);
-+}
-+
-+static inline u32 qcom_parf_readl_relaxed(struct qcom_pcie *pcie, u32 reg)
-+{
-+	return readl_relaxed(pcie->parf_base + reg);
-+}
-+
-+static void msm_pcie_write_mask(void __iomem *addr,
-+				uint32_t clear_mask, uint32_t set_mask)
-+{
-+	uint32_t val;
-+
-+	val = (readl_relaxed(addr) & ~clear_mask) | set_mask;
-+	writel_relaxed(val, addr);
-+	wmb();  /* ensure data is written to hardware register */
-+}
-+
-+static void qcom_pcie_config_controller(struct qcom_pcie *dev)
-+{
-+	/*
-+	 * program and enable address translation region 0 (device config
-+	 * address space); region type config;
-+	 * axi config address range to device config address range
-+	 */
-+	writel_relaxed(0, dev->dwc_base + PCIE20_PLR_IATU_VIEWPORT);
-+	/* ensure that hardware locks the region before programming it */
-+	wmb();
-+
-+	writel_relaxed(4, dev->dwc_base + PCIE20_PLR_IATU_CTRL1);
-+	writel_relaxed(BIT(31), dev->dwc_base + PCIE20_PLR_IATU_CTRL2);
-+	writel_relaxed(dev->conf.start, dev->dwc_base + PCIE20_PLR_IATU_LBAR);
-+	writel_relaxed(0, dev->dwc_base + PCIE20_PLR_IATU_UBAR);
-+	writel_relaxed(dev->conf.end, dev->dwc_base + PCIE20_PLR_IATU_LAR);
-+	writel_relaxed(MSM_PCIE_DEV_CFG_ADDR,
-+		       dev->dwc_base + PCIE20_PLR_IATU_LTAR);
-+	writel_relaxed(0, dev->dwc_base + PCIE20_PLR_IATU_UTAR);
-+	/* ensure that hardware registers the configuration */
-+	wmb();
-+
-+	/*
-+	 * program and enable address translation region 2 (device resource
-+	 * address space); region type memory;
-+	 * axi device bar address range to device bar address range
-+	 */
-+	writel_relaxed(2, dev->dwc_base + PCIE20_PLR_IATU_VIEWPORT);
-+	/* ensure that hardware locks the region before programming it */
-+	wmb();
-+
-+	writel_relaxed(0, dev->dwc_base + PCIE20_PLR_IATU_CTRL1);
-+	writel_relaxed(BIT(31), dev->dwc_base + PCIE20_PLR_IATU_CTRL2);
-+	writel_relaxed(dev->mem.start, dev->dwc_base + PCIE20_PLR_IATU_LBAR);
-+	writel_relaxed(0, dev->dwc_base + PCIE20_PLR_IATU_UBAR);
-+	writel_relaxed(dev->mem.end, dev->dwc_base + PCIE20_PLR_IATU_LAR);
-+	writel_relaxed(dev->mem.start,
-+		       dev->dwc_base + PCIE20_PLR_IATU_LTAR);
-+	writel_relaxed(0, dev->dwc_base + PCIE20_PLR_IATU_UTAR);
-+	/* ensure that hardware registers the configuration */
-+	wmb();
-+
-+	/* 1K PCIE buffer setting */
-+	writel_relaxed(0x3, dev->dwc_base + PCIE20_AXI_MSTR_RESP_COMP_CTRL0);
-+	writel_relaxed(0x1, dev->dwc_base + PCIE20_AXI_MSTR_RESP_COMP_CTRL1);
-+	/* ensure that hardware registers the configuration */
-+	wmb();
-+}
-+
-+static int qcom_pcie_probe(struct platform_device *pdev)
-+{
-+	unsigned long flags;
-+	struct qcom_pcie *qcom_pcie;
-+	struct device_node *np = pdev->dev.of_node;
-+	struct resource *elbi_base, *parf_base, *dwc_base;
-+	struct hw_pci *hw;
-+	struct of_pci_range range;
-+	struct of_pci_range_parser parser;
-+	int ret, i;
-+	u32 val;
-+
-+	qcom_pcie = devm_kzalloc(&pdev->dev, sizeof(*qcom_pcie), GFP_KERNEL);
-+	if (!qcom_pcie) {
-+		dev_err(&pdev->dev, "no memory for qcom_pcie\n");
-+		return -ENOMEM;
-+	}
-+
-+	elbi_base = platform_get_resource_byname(pdev, IORESOURCE_MEM, "elbi");
-+	qcom_pcie->elbi_base = devm_ioremap_resource(&pdev->dev, elbi_base);
-+	if (IS_ERR(qcom_pcie->elbi_base)) {
-+		dev_err(&pdev->dev, "Failed to ioremap elbi space\n");
-+		return PTR_ERR(qcom_pcie->elbi_base);
-+	}
-+
-+	parf_base = platform_get_resource_byname(pdev, IORESOURCE_MEM, "parf");
-+	qcom_pcie->parf_base = devm_ioremap_resource(&pdev->dev, parf_base);
-+	if (IS_ERR(qcom_pcie->parf_base)) {
-+		dev_err(&pdev->dev, "Failed to ioremap parf space\n");
-+		return PTR_ERR(qcom_pcie->parf_base);
-+	}
-+
-+	dwc_base = platform_get_resource_byname(pdev, IORESOURCE_MEM, "base");
-+	qcom_pcie->dwc_base = devm_ioremap_resource(&pdev->dev, dwc_base);
-+	if (IS_ERR(qcom_pcie->dwc_base)) {
-+		dev_err(&pdev->dev, "Failed to ioremap dwc_base space\n");
-+		return PTR_ERR(qcom_pcie->dwc_base);
-+	}
-+
-+	if (of_pci_range_parser_init(&parser, np)) {
-+		dev_err(&pdev->dev, "missing ranges property\n");
-+		return -EINVAL;
-+	}
-+
-+	/* Get the I/O and memory ranges from DT */
-+	for_each_of_pci_range(&parser, &range) {
-+		switch (range.pci_space & 0x3) {
-+		case 0:		/* cfg */
-+			of_pci_range_to_resource(&range, np, &qcom_pcie->conf);
-+			qcom_pcie->conf.flags = IORESOURCE_MEM;
-+			break;
-+		case 1:		/* io */
-+			of_pci_range_to_resource(&range, np, &qcom_pcie->io);
-+			break;
-+		default:	/* mem */
-+			of_pci_range_to_resource(&range, np, &qcom_pcie->mem);
-+			break;
-+		}
-+	}
-+
-+	qcom_pcie->cfg_base = devm_ioremap_resource(&pdev->dev, &qcom_pcie->conf);
-+	if (IS_ERR(qcom_pcie->cfg_base)) {
-+		dev_err(&pdev->dev, "Failed to ioremap PCIe cfg space\n");
-+		return PTR_ERR(qcom_pcie->cfg_base);
-+        }
-+
-+	qcom_pcie->reset_gpio = of_get_named_gpio(np, "reset-gpio", 0);
-+	if (!gpio_is_valid(qcom_pcie->reset_gpio)) {
-+		dev_err(&pdev->dev, "pcie reset gpio is not valid\n");
-+		return -EINVAL;
-+	}
-+
-+	ret = devm_gpio_request_one(&pdev->dev, qcom_pcie->reset_gpio,
-+				    GPIOF_DIR_OUT, "pcie_reset");
-+	if (ret) {
-+		dev_err(&pdev->dev, "Failed to request pcie reset gpio\n");
-+		return ret;
-+	}
-+
-+	qcom_pcie->iface_clk = devm_clk_get(&pdev->dev, "iface");
-+	if (IS_ERR(qcom_pcie->iface_clk)) {
-+		dev_err(&pdev->dev, "Failed to get pcie iface clock\n");
-+		return PTR_ERR(qcom_pcie->iface_clk);
-+	}
-+
-+	qcom_pcie->phy_clk = devm_clk_get(&pdev->dev, "phy");
-+	if (IS_ERR(qcom_pcie->phy_clk)) {
-+		dev_err(&pdev->dev, "Failed to get pcie phy clock\n");
-+		return PTR_ERR(qcom_pcie->phy_clk);
-+	}
-+
-+	qcom_pcie->bus_clk = devm_clk_get(&pdev->dev, "core");
-+	if (IS_ERR(qcom_pcie->bus_clk)) {
-+		dev_err(&pdev->dev, "Failed to get pcie core clock\n");
-+		return PTR_ERR(qcom_pcie->bus_clk);
-+	}
-+
-+	qcom_pcie->axi_reset = devm_reset_control_get(&pdev->dev, "axi");
-+	if (IS_ERR(qcom_pcie->axi_reset)) {
-+		dev_err(&pdev->dev, "Failed to get axi reset\n");
-+		return PTR_ERR(qcom_pcie->axi_reset);
-+	}
-+
-+	qcom_pcie->ahb_reset = devm_reset_control_get(&pdev->dev, "ahb");
-+	if (IS_ERR(qcom_pcie->ahb_reset)) {
-+		dev_err(&pdev->dev, "Failed to get ahb reset\n");
-+		return PTR_ERR(qcom_pcie->ahb_reset);
-+	}
-+
-+	qcom_pcie->por_reset = devm_reset_control_get(&pdev->dev, "por");
-+	if (IS_ERR(qcom_pcie->por_reset)) {
-+		dev_err(&pdev->dev, "Failed to get por reset\n");
-+		return PTR_ERR(qcom_pcie->por_reset);
-+	}
-+
-+	qcom_pcie->pci_reset = devm_reset_control_get(&pdev->dev, "pci");
-+	if (IS_ERR(qcom_pcie->pci_reset)) {
-+		dev_err(&pdev->dev, "Failed to get pci reset\n");
-+		return PTR_ERR(qcom_pcie->pci_reset);
-+	}
-+
-+	qcom_pcie->phy_reset = devm_reset_control_get(&pdev->dev, "phy");
-+	if (IS_ERR(qcom_pcie->phy_reset)) {
-+		dev_err(&pdev->dev, "Failed to get phy reset\n");
-+		return PTR_ERR(qcom_pcie->phy_reset);
-+	}
-+
-+	for (i = 0; i < 4; i++) {
-+		qcom_pcie->irq_int[i] = platform_get_irq(pdev, i+1);
-+		if (qcom_pcie->irq_int[i] < 0) {
-+			dev_err(&pdev->dev, "failed to get irq resource\n");
-+			return qcom_pcie->irq_int[i];
-+		}
-+	}
-+
-+	gpio_set_value(qcom_pcie->reset_gpio, 0);
-+	usleep_range(10000, 15000);
-+
-+	/* assert PCIe PARF reset while powering the core */
-+	reset_control_assert(qcom_pcie->ahb_reset);
-+
-+	/* enable clocks */
-+	ret = clk_prepare_enable(qcom_pcie->iface_clk);
-+	if (ret)
-+		return ret;
-+	ret = clk_prepare_enable(qcom_pcie->phy_clk);
-+	if (ret)
-+		return ret;
-+	ret = clk_prepare_enable(qcom_pcie->bus_clk);
-+	if (ret)
-+		return ret;
-+
-+	/*
-+	 * de-assert PCIe PARF reset;
-+	 * wait 1us before accessing PARF registers
-+	 */
-+	reset_control_deassert(qcom_pcie->ahb_reset);
-+	udelay(1);
-+
-+	/* enable PCIe clocks and resets */
-+	msm_pcie_write_mask(qcom_pcie->parf_base + PCIE20_PARF_PHY_CTRL, BIT(0), 0);
-+
-+	/* Set Tx Termination Offset */
-+	val = qcom_parf_readl_relaxed(qcom_pcie, PCIE20_PARF_PHY_CTRL);
-+	val |= PCIE20_PARF_PHY_CTRL_PHY_TX0_TERM_OFFST(7);
-+	qcom_parf_writel_relaxed(qcom_pcie, val, PCIE20_PARF_PHY_CTRL);
-+
-+	/* PARF programming */
-+	qcom_parf_writel_relaxed(qcom_pcie, PCIE20_PARF_PCS_DEEMPH_TX_DEEMPH_GEN1(0x18) |
-+			PCIE20_PARF_PCS_DEEMPH_TX_DEEMPH_GEN2_3_5DB(0x18) |
-+			PCIE20_PARF_PCS_DEEMPH_TX_DEEMPH_GEN2_6DB(0x22),
-+			PCIE20_PARF_PCS_DEEMPH);
-+	qcom_parf_writel_relaxed(qcom_pcie, PCIE20_PARF_PCS_SWING_TX_SWING_FULL(0x78) |
-+			PCIE20_PARF_PCS_SWING_TX_SWING_LOW(0x78),
-+			PCIE20_PARF_PCS_SWING);
-+	qcom_parf_writel_relaxed(qcom_pcie, (4<<24), PCIE20_PARF_CONFIG_BITS);
-+	/* ensure that hardware registers the PARF configuration */
-+	wmb();
-+
-+	/* enable reference clock */
-+	msm_pcie_write_mask(qcom_pcie->parf_base + PCIE20_PARF_PHY_REFCLK, BIT(12), BIT(16));
-+
-+	/* ensure that access is enabled before proceeding */
-+	wmb();
-+
-+	/* de-assert PICe PHY, Core, POR and AXI clk domain resets */
-+	reset_control_deassert(qcom_pcie->phy_reset);
-+	reset_control_deassert(qcom_pcie->pci_reset);
-+	reset_control_deassert(qcom_pcie->por_reset);
-+	reset_control_deassert(qcom_pcie->axi_reset);
-+
-+	/* wait 150ms for clock acquisition */
-+	usleep_range(10000, 15000);
-+
-+	/* de-assert PCIe reset link to bring EP out of reset */
-+	gpio_set_value(qcom_pcie->reset_gpio, 1 - 0);
-+	usleep_range(10000, 15000);
-+
-+	/* enable link training */
-+	val = qcom_elbi_readl_relaxed(qcom_pcie, PCIE20_ELBI_SYS_CTRL);
-+	val |= PCIE20_ELBI_SYS_CTRL_LTSSM_EN;
-+	qcom_elbi_writel_relaxed(qcom_pcie, val, PCIE20_ELBI_SYS_CTRL);
-+	wmb();
-+
-+	/* poll for link to come up for upto 100ms */
-+	ret = readl_poll_timeout(
-+			(qcom_pcie->dwc_base + PCIE20_CAP_LINKCTRLSTATUS),
-+			val, (val & BIT(29)), 10000, 100000);
-+
-+	printk("link initialized %d\n", ret);
-+
-+	qcom_pcie_config_controller(qcom_pcie);
-+
-+	platform_set_drvdata(pdev, qcom_pcie);
-+
-+	spin_lock_irqsave(&qcom_hw_pci_lock, flags);
-+	qcom_hw_pci[nr_controllers].private_data = (void **)&qcom_pcie;
-+	hw = &qcom_hw_pci[nr_controllers];
-+	nr_controllers++;
-+	spin_unlock_irqrestore(&qcom_hw_pci_lock, flags);
-+
-+	pci_common_init(hw);
-+
-+	return 0;
-+}
-+
-+static int __exit qcom_pcie_remove(struct platform_device *pdev)
-+{
-+	struct qcom_pcie *qcom_pcie = platform_get_drvdata(pdev);
-+
-+	return 0;
-+}
-+
-+static struct of_device_id qcom_pcie_match[] = {
-+	{	.compatible = "qcom,pcie-ipq8064", },
-+	{}
-+};
-+
-+static struct platform_driver qcom_pcie_driver = {
-+	.probe	= qcom_pcie_probe,
-+	.remove	= qcom_pcie_remove,
-+	.driver	= {
-+		.name		= "qcom_pcie",
-+		.owner		= THIS_MODULE,
-+		.of_match_table	= qcom_pcie_match,
-+	},
-+};
-+
-+static int qcom_pcie_init(void)
-+{
-+	return platform_driver_register(&qcom_pcie_driver);
-+}
-+subsys_initcall(qcom_pcie_init);
-+
-+/* RC do not represent the right class; set it to PCI_CLASS_BRIDGE_PCI */
-+static void msm_pcie_fixup_early(struct pci_dev *dev)
-+{
-+	if (dev->hdr_type == 1)
-+		dev->class = (dev->class & 0xff) | (PCI_CLASS_BRIDGE_PCI << 8);
-+}
-+DECLARE_PCI_FIXUP_EARLY(PCIE_VENDOR_ID_RCP, PCIE_DEVICE_ID_RCP, msm_pcie_fixup_early);
diff --git a/target/linux/ipq806x/patches/0139-ARM-dts-msm-Add-PCIe-related-nodes-for-IPQ8064-AP148.patch b/target/linux/ipq806x/patches/0139-ARM-dts-msm-Add-PCIe-related-nodes-for-IPQ8064-AP148.patch
deleted file mode 100644
index 1fd2052..0000000
--- a/target/linux/ipq806x/patches/0139-ARM-dts-msm-Add-PCIe-related-nodes-for-IPQ8064-AP148.patch
+++ /dev/null
@@ -1,172 +0,0 @@
-From 7c6525a0d5cf88f9244187fbe8ee293fa4ee43c1 Mon Sep 17 00:00:00 2001
-From: Kumar Gala <galak@codeaurora.org>
-Date: Mon, 12 May 2014 19:36:23 -0500
-Subject: [PATCH 139/182] ARM: dts: msm: Add PCIe related nodes for
- IPQ8064/AP148
-
----
- arch/arm/boot/dts/qcom-ipq8064-ap148.dts |   38 ++++++++++++
- arch/arm/boot/dts/qcom-ipq8064.dtsi      |   93 ++++++++++++++++++++++++++++++
- 2 files changed, 131 insertions(+)
-
---- a/arch/arm/boot/dts/qcom-ipq8064-ap148.dts
-+++ b/arch/arm/boot/dts/qcom-ipq8064-ap148.dts
-@@ -21,6 +21,22 @@
- 				bias-disable;
- 			};
- 
-+			pcie1_pins: pcie1_pinmux {
-+				mux {
-+					pins = "gpio3";
-+					drive-strength = <2>;
-+					bias-disable;
-+				};
-+			};
-+
-+			pcie2_pins: pcie2_pinmux {
-+				mux {
-+					pins = "gpio48";
-+					drive-strength = <2>;
-+					bias-disable;
-+				};
-+			};
-+
- 			spi_pins: spi_pins {
- 				mux {
- 					pins = "gpio18", "gpio19", "gpio21";
-@@ -80,5 +96,27 @@
- 				};
- 			};
- 		};
-+
-+		pci@1b500000 {
-+			status = "ok";
-+			reset-gpio = <&qcom_pinmux 3 0>;
-+			pinctrl-0 = <&pcie1_pins>;
-+			pinctrl-names = "default";
-+
-+			ranges = <0x00000000 0 0x00000000 0x0ff00000 0 0x00100000   /* configuration space */
-+				  0x81000000 0 0	  0x0fe00000 0 0x00100000   /* downstream I/O */
-+				  0x82000000 0 0x00000000 0x08000000 0 0x07e00000>; /* non-prefetchable memory */
-+		};
-+
-+		pci@1b700000 {
-+			status = "ok";
-+			reset-gpio = <&qcom_pinmux 48 0>;
-+			pinctrl-0 = <&pcie2_pins>;
-+			pinctrl-names = "default";
-+
-+			ranges = <0x00000000 0 0x00000000 0x31f00000 0 0x00100000   /* configuration space */
-+				  0x81000000 0 0	  0x31e00000 0 0x00100000   /* downstream I/O */
-+				  0x82000000 0 0x00000000 0x2e000000 0 0x03e00000>; /* non-prefetchable memory */
-+		};
- 	};
- };
---- a/arch/arm/boot/dts/qcom-ipq8064.dtsi
-+++ b/arch/arm/boot/dts/qcom-ipq8064.dtsi
-@@ -2,6 +2,7 @@
- 
- #include "skeleton.dtsi"
- #include <dt-bindings/clock/qcom,gcc-ipq806x.h>
-+#include <dt-bindings/reset/qcom,gcc-ipq806x.h>
- #include <dt-bindings/soc/qcom,gsbi.h>
- 
- / {
-@@ -246,5 +247,97 @@
- 			#clock-cells = <1>;
- 			#reset-cells = <1>;
- 		};
-+
-+		pci@1b500000 {
-+			compatible = "qcom,pcie-ipq8064";
-+			reg = <0x1b500000 0x1000
-+			       0x1b502000 0x80
-+			       0x1b600000 0x100
-+				>;
-+			reg-names = "base", "elbi", "parf";
-+
-+			#address-cells = <3>;
-+			#size-cells = <2>;
-+			device_type = "pci";
-+			interrupts = <0 35 0x0
-+				      0 36 0x0
-+				      0 37 0x0
-+				      0 38 0x0
-+				      0 39 0x0>;
-+			resets = <&gcc PCIE_ACLK_RESET>,
-+				 <&gcc PCIE_HCLK_RESET>,
-+				 <&gcc PCIE_POR_RESET>,
-+				 <&gcc PCIE_PCI_RESET>,
-+				 <&gcc PCIE_PHY_RESET>;
-+			reset-names = "axi", "ahb", "por", "pci", "phy";
-+
-+			clocks = <&gcc PCIE_A_CLK>,
-+				 <&gcc PCIE_H_CLK>,
-+				 <&gcc PCIE_PHY_CLK>;
-+			clock-names = "core", "iface", "phy";
-+			status = "disabled";
-+		};
-+
-+		pci@1b700000 {
-+			compatible = "qcom,pcie-ipq8064";
-+			reg = <0x1b700000 0x1000
-+			       0x1b702000 0x80
-+			       0x1b800000 0x100
-+				>;
-+			reg-names = "base", "elbi", "parf";
-+
-+			#address-cells = <3>;
-+			#size-cells = <2>;
-+			device_type = "pci";
-+
-+			interrupts = <0 57 0x0
-+				      0 58 0x0
-+				      0 59 0x0
-+				      0 60 0x0
-+				      0 61 0x0>;
-+			resets = <&gcc PCIE_1_ACLK_RESET>,
-+				 <&gcc PCIE_1_HCLK_RESET>,
-+				 <&gcc PCIE_1_POR_RESET>,
-+				 <&gcc PCIE_1_PCI_RESET>,
-+				 <&gcc PCIE_1_PHY_RESET>;
-+			reset-names = "axi", "ahb", "por", "pci", "phy";
-+
-+			clocks = <&gcc PCIE_1_A_CLK>,
-+				 <&gcc PCIE_1_H_CLK>,
-+				 <&gcc PCIE_1_PHY_CLK>;
-+			clock-names = "core", "iface", "phy";
-+			status = "disabled";
-+		};
-+
-+		pci@1b900000 {
-+			compatible = "qcom,pcie-ipq8064";
-+			reg = <0x1b900000 0x1000
-+			       0x1b902000 0x80
-+			       0x1ba00000 0x100
-+				>;
-+			reg-names = "base", "elbi", "parf";
-+
-+			#address-cells = <3>;
-+			#size-cells = <2>;
-+			device_type = "pci";
-+
-+			interrupts = <0 71 0x0
-+				      0 72 0x0
-+				      0 73 0x0
-+				      0 74 0x0
-+				      0 75 0x0>;
-+			resets = <&gcc PCIE_2_ACLK_RESET>,
-+				 <&gcc PCIE_2_HCLK_RESET>,
-+				 <&gcc PCIE_2_POR_RESET>,
-+				 <&gcc PCIE_2_PCI_RESET>,
-+				 <&gcc PCIE_2_PHY_RESET>;
-+			reset-names = "axi", "ahb", "por", "pci", "phy";
-+
-+			clocks = <&gcc PCIE_2_A_CLK>,
-+				 <&gcc PCIE_2_H_CLK>,
-+				 <&gcc PCIE_2_PHY_CLK>;
-+			clock-names = "core", "iface", "phy";
-+			status = "disabled";
-+		};
- 	};
- };
diff --git a/target/linux/ipq806x/patches/0140-ARM-qcom-config-Enable-PCI-support-for-IPQ806x.patch b/target/linux/ipq806x/patches/0140-ARM-qcom-config-Enable-PCI-support-for-IPQ806x.patch
deleted file mode 100644
index 14a5db4..0000000
--- a/target/linux/ipq806x/patches/0140-ARM-qcom-config-Enable-PCI-support-for-IPQ806x.patch
+++ /dev/null
@@ -1,28 +0,0 @@
-From a7e90802be401083098511e72866a0f824c10e15 Mon Sep 17 00:00:00 2001
-From: Kumar Gala <galak@codeaurora.org>
-Date: Fri, 16 May 2014 16:54:48 -0500
-Subject: [PATCH 140/182] ARM: qcom: config: Enable PCI support for IPQ806x
-
----
- arch/arm/configs/qcom_defconfig |    3 +++
- 1 file changed, 3 insertions(+)
-
---- a/arch/arm/configs/qcom_defconfig
-+++ b/arch/arm/configs/qcom_defconfig
-@@ -21,6 +21,8 @@ CONFIG_ARCH_QCOM=y
- CONFIG_ARCH_MSM8X60=y
- CONFIG_ARCH_MSM8960=y
- CONFIG_ARCH_MSM8974=y
-+CONFIG_PCI=y
-+CONFIG_PCI_MSI=y
- CONFIG_SMP=y
- CONFIG_PREEMPT=y
- CONFIG_AEABI=y
-@@ -83,6 +85,7 @@ CONFIG_INPUT_MISC=y
- CONFIG_INPUT_UINPUT=y
- CONFIG_SERIO_LIBPS2=y
- # CONFIG_LEGACY_PTYS is not set
-+CONFIG_SERIAL_8250=y
- CONFIG_SERIAL_MSM=y
- CONFIG_SERIAL_MSM_CONSOLE=y
- CONFIG_HW_RANDOM=y
diff --git a/target/linux/ipq806x/patches/0141-ahci-platform-Bump-max-number-of-clocks-to-5.patch b/target/linux/ipq806x/patches/0141-ahci-platform-Bump-max-number-of-clocks-to-5.patch
deleted file mode 100644
index 2f5adca..0000000
--- a/target/linux/ipq806x/patches/0141-ahci-platform-Bump-max-number-of-clocks-to-5.patch
+++ /dev/null
@@ -1,23 +0,0 @@
-From fd475809eefc0870515d0b04815e2bbae67be906 Mon Sep 17 00:00:00 2001
-From: Kumar Gala <galak@codeaurora.org>
-Date: Fri, 6 Jun 2014 12:09:01 -0500
-Subject: [PATCH 141/182] ahci-platform: Bump max number of clocks to 5
-
-Qualcomm IPQ806x SoCs with SATA controllers need 5 clocks to be enabled.
-
-Signed-off-by: Kumar Gala <galak@codeaurora.org>
----
- drivers/ata/ahci.h |    2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/drivers/ata/ahci.h
-+++ b/drivers/ata/ahci.h
-@@ -53,7 +53,7 @@
- 
- enum {
- 	AHCI_MAX_PORTS		= 32,
--	AHCI_MAX_CLKS		= 3,
-+	AHCI_MAX_CLKS		= 5,
- 	AHCI_MAX_SG		= 168, /* hardware max is 64K */
- 	AHCI_DMA_BOUNDARY	= 0xffffffff,
- 	AHCI_MAX_CMDS		= 32,
diff --git a/target/linux/ipq806x/patches/0142-ata-Add-Qualcomm-ARM-SoC-AHCI-SATA-host-controller-d.patch b/target/linux/ipq806x/patches/0142-ata-Add-Qualcomm-ARM-SoC-AHCI-SATA-host-controller-d.patch
deleted file mode 100644
index 5db5d9d..0000000
--- a/target/linux/ipq806x/patches/0142-ata-Add-Qualcomm-ARM-SoC-AHCI-SATA-host-controller-d.patch
+++ /dev/null
@@ -1,136 +0,0 @@
-From c5ea64dcf7b5d45e402e78b9f291d521669b7b80 Mon Sep 17 00:00:00 2001
-From: Kumar Gala <galak@codeaurora.org>
-Date: Fri, 30 May 2014 15:35:40 -0500
-Subject: [PATCH 142/182] ata: Add Qualcomm ARM SoC AHCI SATA host controller
- driver
-
-Add support for the Qualcomm AHCI SATA controller that exists on several
-SoC and specifically the IPQ806x family of chips.  The IPQ806x SATA support
-requires the associated IPQ806x SATA PHY Driver to be enabled as well.
-
-Signed-off-by: Kumar Gala <galak@codeaurora.org>
----
- drivers/ata/Kconfig     |   10 ++++++
- drivers/ata/Makefile    |    1 +
- drivers/ata/ahci_qcom.c |   86 +++++++++++++++++++++++++++++++++++++++++++++++
- 3 files changed, 97 insertions(+)
- create mode 100644 drivers/ata/ahci_qcom.c
-
---- a/drivers/ata/Kconfig
-+++ b/drivers/ata/Kconfig
-@@ -122,6 +122,16 @@ config AHCI_IMX
- 
- 	  If unsure, say N.
- 
-+config AHCI_QCOM
-+	tristate "Qualcomm AHCI SATA support"
-+	depends on ARCH_QCOM
-+	help
-+	  This option enables support for AHCI SATA controller
-+	  integrated into Qualcomm ARM SoC chipsets. For more
-+	  information please refer to http://www.qualcomm.com/chipsets.
-+
-+	  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 libahci.o libahci_platform.o
-+obj-$(CONFIG_AHCI_QCOM)		+= ahci_qcom.o libahci.o libahci_platform.o
- 
- # SFF w/ custom DMA
- obj-$(CONFIG_PDC_ADMA)		+= pdc_adma.o
---- /dev/null
-+++ b/drivers/ata/ahci_qcom.c
-@@ -0,0 +1,86 @@
-+/*
-+ * Qualcomm ARM SoC AHCI SATA platform driver
-+ *
-+ * based on the AHCI SATA platform driver by Jeff Garzik and Anton Vorontsov
-+ *
-+ * Copyright (c) 2014, The Linux Foundation. All rights reserved.
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 and
-+ * only version 2 as published by the Free Software Foundation.
-+ *
-+ * 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/kernel.h>
-+#include <linux/module.h>
-+#include <linux/pm.h>
-+#include <linux/device.h>
-+#include <linux/platform_device.h>
-+#include <linux/libata.h>
-+#include <linux/ahci_platform.h>
-+#include "ahci.h"
-+
-+static const struct ata_port_info qcom_ahci_port_info = {
-+	.flags		= AHCI_FLAG_COMMON,
-+	.pio_mask	= ATA_PIO4,
-+	.udma_mask	= ATA_UDMA6,
-+	.port_ops	= &ahci_platform_ops,
-+};
-+
-+static int qcom_ahci_probe(struct platform_device *pdev)
-+{
-+	struct ahci_host_priv *hpriv;
-+	struct clk *rxoob_clk;
-+	int rc;
-+
-+	hpriv = ahci_platform_get_resources(pdev);
-+	if (IS_ERR(hpriv))
-+		return PTR_ERR(hpriv);
-+
-+	/* Try and set the rxoob clk to 100Mhz */
-+	rxoob_clk = of_clk_get_by_name(pdev->dev.of_node, "rxoob");
-+	if (IS_ERR(rxoob_clk))
-+		return PTR_ERR(rxoob_clk);
-+
-+	rc = clk_set_rate(rxoob_clk, 100000000);
-+	if (rc)
-+		return rc;
-+
-+	rc = ahci_platform_enable_resources(hpriv);
-+	if (rc)
-+		return rc;
-+
-+	rc = ahci_platform_init_host(pdev, hpriv, &qcom_ahci_port_info, 0, 0);
-+	if (rc)
-+		goto disable_resources;
-+
-+	return 0;
-+disable_resources:
-+	ahci_platform_disable_resources(hpriv);
-+	return rc;
-+}
-+
-+static const struct of_device_id qcom_ahci_of_match[] = {
-+	{ .compatible = "qcom,msm-ahci", },
-+	{},
-+};
-+MODULE_DEVICE_TABLE(of, qcom_ahci_of_match);
-+
-+static struct platform_driver qcom_ahci_driver = {
-+	.probe = qcom_ahci_probe,
-+	.remove = ata_platform_remove_one,
-+	.driver = {
-+		.name = "qcom_ahci_qcom",
-+		.owner = THIS_MODULE,
-+		.of_match_table = qcom_ahci_of_match,
-+	},
-+};
-+module_platform_driver(qcom_ahci_driver);
-+
-+MODULE_DESCRIPTION("Qualcomm AHCI SATA platform driver");
-+MODULE_LICENSE("GPL v2");
-+MODULE_ALIAS("ahci:qcom");
diff --git a/target/linux/ipq806x/patches/0143-ata-qcom-Add-device-tree-bindings-information.patch b/target/linux/ipq806x/patches/0143-ata-qcom-Add-device-tree-bindings-information.patch
deleted file mode 100644
index 01ca733..0000000
--- a/target/linux/ipq806x/patches/0143-ata-qcom-Add-device-tree-bindings-information.patch
+++ /dev/null
@@ -1,57 +0,0 @@
-From dd280a4cf6b826144f74d3fc4285633f1c337a1d Mon Sep 17 00:00:00 2001
-From: Kumar Gala <galak@codeaurora.org>
-Date: Thu, 12 Jun 2014 11:28:47 -0500
-Subject: [PATCH 143/182] ata: qcom: Add device tree bindings information
-
-Add device tree binding for Qualcomm AHCI SATA controller and specifically
-the sata controller on the IPQ806x family of SoCs.
-
-Signed-off-by: Kumar Gala <galak@codeaurora.org>
----
- .../devicetree/bindings/ata/qcom-sata.txt          |   40 ++++++++++++++++++++
- 1 file changed, 40 insertions(+)
- create mode 100644 Documentation/devicetree/bindings/ata/qcom-sata.txt
-
---- /dev/null
-+++ b/Documentation/devicetree/bindings/ata/qcom-sata.txt
-@@ -0,0 +1,40 @@
-+* Qualcomm AHCI SATA Controller
-+
-+SATA nodes are defined to describe on-chip Serial ATA controllers.
-+Each SATA controller should have its own node.
-+
-+Required properties:
-+- compatible		: compatible list, contains "qcom,msm-ahci"
-+- interrupts		: <interrupt mapping for SATA IRQ>
-+- reg			: <registers mapping>
-+- phys			: Must contain exactly one entry as specified
-+			  in phy-bindings.txt
-+- phy-names		: Must be "sata-phy"
-+
-+Required properties for "qcom,ipq806x-ahci" compatible:
-+- clocks		: Must contain an entry for each entry in clock-names.
-+- clock-names		: Shall be:
-+				"slave_iface" - Fabric port AHB clock for SATA
-+				"iface" - AHB clock
-+				"core" - core clock
-+				"rxoob" - RX out-of-band clock
-+				"pmalive" - Power Module Alive clock
-+
-+Example:
-+	sata@29000000 {
-+		compatible = "qcom,ipq806x-ahci", "qcom,msm-ahci";
-+		reg = <0x29000000 0x180>;
-+
-+		interrupts = <0 209 0x0>;
-+
-+		clocks = <&gcc SFAB_SATA_S_H_CLK>,
-+			 <&gcc SATA_H_CLK>,
-+			 <&gcc SATA_A_CLK>,
-+			 <&gcc SATA_RXOOB_CLK>,
-+			 <&gcc SATA_PMALIVE_CLK>;
-+		clock-names = "slave_iface", "iface", "core",
-+				"rxoob", "pmalive";
-+
-+		phys = <&sata_phy>;
-+		phy-names = "sata-phy";
-+	};
diff --git a/target/linux/ipq806x/patches/0144-phy-qcom-Add-driver-for-QCOM-IPQ806x-SATA-PHY.patch b/target/linux/ipq806x/patches/0144-phy-qcom-Add-driver-for-QCOM-IPQ806x-SATA-PHY.patch
deleted file mode 100644
index 9a5457d..0000000
--- a/target/linux/ipq806x/patches/0144-phy-qcom-Add-driver-for-QCOM-IPQ806x-SATA-PHY.patch
+++ /dev/null
@@ -1,251 +0,0 @@
-From 7554dfbbec255e4cd5dd4445841c28c48fd4a855 Mon Sep 17 00:00:00 2001
-From: Kumar Gala <galak@codeaurora.org>
-Date: Tue, 3 Jun 2014 11:59:09 -0500
-Subject: [PATCH 144/182] phy: qcom: Add driver for QCOM IPQ806x SATA PHY
-
-Add a PHY driver for uses with AHCI based SATA controller driver on the
-IPQ806x family of SoCs.
-
-Signed-off-by: Kumar Gala <galak@codeaurora.org>
----
- drivers/phy/Kconfig                 |    7 ++
- drivers/phy/Makefile                |    1 +
- drivers/phy/phy-qcom-ipq806x-sata.c |  211 +++++++++++++++++++++++++++++++++++
- 3 files changed, 219 insertions(+)
- create mode 100644 drivers/phy/phy-qcom-ipq806x-sata.c
-
---- a/drivers/phy/Kconfig
-+++ b/drivers/phy/Kconfig
-@@ -65,4 +65,11 @@ config BCM_KONA_USB2_PHY
- 	help
- 	  Enable this to support the Broadcom Kona USB 2.0 PHY.
- 
-+config PHY_QCOM_IPQ806X_SATA
-+	tristate "Qualcomm IPQ806x SATA SerDes/PHY driver"
-+	depends on ARCH_QCOM
-+	depends on HAS_IOMEM
-+	depends on OF
-+	select GENERIC_PHY
-+
- 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_QCOM_IPQ806X_SATA)	+= phy-qcom-ipq806x-sata.o
---- /dev/null
-+++ b/drivers/phy/phy-qcom-ipq806x-sata.c
-@@ -0,0 +1,211 @@
-+/*
-+ * Copyright (c) 2014, The Linux Foundation. All rights reserved.
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 and
-+ * only version 2 as published by the Free Software Foundation.
-+ *
-+ * 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/io.h>
-+#include <linux/kernel.h>
-+#include <linux/module.h>
-+#include <linux/of.h>
-+#include <linux/of_address.h>
-+#include <linux/time.h>
-+#include <linux/delay.h>
-+#include <linux/clk.h>
-+#include <linux/slab.h>
-+#include <linux/platform_device.h>
-+#include <linux/phy/phy.h>
-+
-+struct qcom_ipq806x_sata_phy {
-+	void __iomem *mmio;
-+	struct clk *cfg_clk;
-+};
-+
-+#define __set(v, a, b)	(((v) << (b)) & GENMASK(a, b))
-+
-+#define SATA_PHY_P0_PARAM0		0x200
-+#define SATA_PHY_P0_PARAM0_P0_TX_PREEMPH_GEN3(x)	__set(x, 17, 12)
-+#define SATA_PHY_P0_PARAM0_P0_TX_PREEMPH_GEN3_MASK	GENMASK(17, 12)
-+#define SATA_PHY_P0_PARAM0_P0_TX_PREEMPH_GEN2(x)	__set(x, 11, 6)
-+#define SATA_PHY_P0_PARAM0_P0_TX_PREEMPH_GEN2_MASK	GENMASK(11, 6)
-+#define SATA_PHY_P0_PARAM0_P0_TX_PREEMPH_GEN1(x)	__set(x, 5, 0)
-+#define SATA_PHY_P0_PARAM0_P0_TX_PREEMPH_GEN1_MASK	GENMASK(5, 0)
-+
-+#define SATA_PHY_P0_PARAM1		0x204
-+#define SATA_PHY_P0_PARAM1_RESERVED_BITS31_21(x)	__set(x, 31, 21)
-+#define SATA_PHY_P0_PARAM1_P0_TX_AMPLITUDE_GEN3(x)	__set(x, 20, 14)
-+#define SATA_PHY_P0_PARAM1_P0_TX_AMPLITUDE_GEN3_MASK	GENMASK(20, 14)
-+#define SATA_PHY_P0_PARAM1_P0_TX_AMPLITUDE_GEN2(x)	__set(x, 13, 7)
-+#define SATA_PHY_P0_PARAM1_P0_TX_AMPLITUDE_GEN2_MASK	GENMASK(13, 7)
-+#define SATA_PHY_P0_PARAM1_P0_TX_AMPLITUDE_GEN1(x)	__set(x, 6, 0)
-+#define SATA_PHY_P0_PARAM1_P0_TX_AMPLITUDE_GEN1_MASK	GENMASK(6, 0)
-+
-+#define SATA_PHY_P0_PARAM2		0x208
-+#define SATA_PHY_P0_PARAM2_RX_EQ(x)	__set(x, 20, 18)
-+#define SATA_PHY_P0_PARAM2_RX_EQ_MASK	GENMASK(20, 18)
-+
-+#define SATA_PHY_P0_PARAM3		0x20C
-+#define SATA_PHY_SSC_EN			0x8
-+#define SATA_PHY_P0_PARAM4		0x210
-+#define SATA_PHY_REF_SSP_EN		0x2
-+#define SATA_PHY_RESET			0x1
-+
-+static inline void qcom_ipq806x_sata_delay_us(unsigned int delay)
-+{
-+	/* sleep for max. 50us more to combine processor wakeups */
-+	usleep_range(delay, delay + 50);
-+}
-+
-+static int qcom_ipq806x_sata_phy_init(struct phy *generic_phy)
-+{
-+	struct qcom_ipq806x_sata_phy *phy = phy_get_drvdata(generic_phy);
-+	u32 reg;
-+
-+	/* Setting SSC_EN to 1 */
-+	reg = readl_relaxed(phy->mmio + SATA_PHY_P0_PARAM3);
-+	reg = reg | SATA_PHY_SSC_EN;
-+	writel_relaxed(reg, phy->mmio + SATA_PHY_P0_PARAM3);
-+
-+	reg = readl_relaxed(phy->mmio + SATA_PHY_P0_PARAM0) &
-+			~(SATA_PHY_P0_PARAM0_P0_TX_PREEMPH_GEN3_MASK |
-+			  SATA_PHY_P0_PARAM0_P0_TX_PREEMPH_GEN2_MASK |
-+			  SATA_PHY_P0_PARAM0_P0_TX_PREEMPH_GEN1_MASK);
-+	reg |= SATA_PHY_P0_PARAM0_P0_TX_PREEMPH_GEN3(0xf);
-+	writel_relaxed(reg, phy->mmio + SATA_PHY_P0_PARAM0);
-+
-+	reg = readl_relaxed(phy->mmio + SATA_PHY_P0_PARAM1) &
-+			~(SATA_PHY_P0_PARAM1_P0_TX_AMPLITUDE_GEN3_MASK |
-+			  SATA_PHY_P0_PARAM1_P0_TX_AMPLITUDE_GEN2_MASK |
-+			  SATA_PHY_P0_PARAM1_P0_TX_AMPLITUDE_GEN1_MASK);
-+	reg |= SATA_PHY_P0_PARAM1_P0_TX_AMPLITUDE_GEN3(0x55) |
-+		SATA_PHY_P0_PARAM1_P0_TX_AMPLITUDE_GEN2(0x55) |
-+		SATA_PHY_P0_PARAM1_P0_TX_AMPLITUDE_GEN1(0x55);
-+	writel_relaxed(reg, phy->mmio + SATA_PHY_P0_PARAM1);
-+
-+	reg = readl_relaxed(phy->mmio + SATA_PHY_P0_PARAM2) &
-+		~SATA_PHY_P0_PARAM2_RX_EQ_MASK;
-+	reg |= SATA_PHY_P0_PARAM2_RX_EQ(0x3);
-+	writel_relaxed(reg, phy->mmio + SATA_PHY_P0_PARAM2);
-+
-+	/* Setting PHY_RESET to 1 */
-+	reg = readl_relaxed(phy->mmio + SATA_PHY_P0_PARAM4);
-+	reg = reg | SATA_PHY_RESET;
-+	writel_relaxed(reg, phy->mmio + SATA_PHY_P0_PARAM4);
-+
-+	/* Setting REF_SSP_EN to 1 */
-+	reg = readl_relaxed(phy->mmio + SATA_PHY_P0_PARAM4);
-+	reg = reg | SATA_PHY_REF_SSP_EN | SATA_PHY_RESET;
-+	writel_relaxed(reg, phy->mmio + SATA_PHY_P0_PARAM4);
-+	mb();
-+	qcom_ipq806x_sata_delay_us(20);
-+
-+	/* Clearing PHY_RESET to 0 */
-+	reg = readl_relaxed(phy->mmio + SATA_PHY_P0_PARAM4);
-+	reg = reg & ~SATA_PHY_RESET;
-+	writel_relaxed(reg, phy->mmio + SATA_PHY_P0_PARAM4);
-+
-+	return 0;
-+}
-+
-+static int qcom_ipq806x_sata_phy_exit(struct phy *generic_phy)
-+{
-+	struct qcom_ipq806x_sata_phy *phy = phy_get_drvdata(generic_phy);
-+	u32 reg;
-+
-+	/* Setting PHY_RESET to 1 */
-+	reg = readl_relaxed(phy->mmio + SATA_PHY_P0_PARAM4);
-+	reg = reg | SATA_PHY_RESET;
-+	writel_relaxed(reg, phy->mmio + SATA_PHY_P0_PARAM4);
-+
-+	return 0;
-+}
-+
-+static struct phy_ops qcom_ipq806x_sata_phy_ops = {
-+	.init		= qcom_ipq806x_sata_phy_init,
-+	.exit		= qcom_ipq806x_sata_phy_exit,
-+	.owner		= THIS_MODULE,
-+};
-+
-+static int qcom_ipq806x_sata_phy_probe(struct platform_device *pdev)
-+{
-+	struct qcom_ipq806x_sata_phy *phy;
-+	struct device *dev = &pdev->dev;
-+	struct resource *res;
-+	struct phy_provider *phy_provider;
-+	struct phy *generic_phy;
-+	int ret;
-+
-+	phy = devm_kzalloc(dev, sizeof(*phy), GFP_KERNEL);
-+	if (!phy) {
-+		dev_err(dev, "%s: failed to allocate phy\n", __func__);
-+		return -ENOMEM;
-+	}
-+
-+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-+	phy->mmio = devm_ioremap_resource(dev, res);
-+	if (IS_ERR(phy->mmio))
-+		return PTR_ERR(phy->mmio);
-+
-+	generic_phy = devm_phy_create(dev, &qcom_ipq806x_sata_phy_ops, NULL);
-+	if (IS_ERR(generic_phy)) {
-+		dev_err(dev, "%s: failed to create phy\n", __func__);
-+		return PTR_ERR(generic_phy);
-+	}
-+
-+	phy_set_drvdata(generic_phy, phy);
-+
-+	phy->cfg_clk = devm_clk_get(dev, "cfg");
-+	if (IS_ERR(phy->cfg_clk)) {
-+		dev_err(dev, "Failed to get sata cfg clock\n");
-+		return PTR_ERR(phy->cfg_clk);
-+	}
-+
-+	ret = clk_prepare_enable(phy->cfg_clk);
-+	if (ret)
-+		return ret;
-+
-+	phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
-+	if (IS_ERR(phy_provider)) {
-+		clk_disable_unprepare(phy->cfg_clk);
-+		dev_err(dev, "%s: failed to register phy\n", __func__);
-+		return PTR_ERR(phy_provider);
-+	}
-+
-+	return 0;
-+}
-+
-+static int qcom_ipq806x_sata_phy_remove(struct platform_device *pdev)
-+{
-+	struct qcom_ipq806x_sata_phy *phy = platform_get_drvdata(pdev);
-+
-+	clk_disable_unprepare(phy->cfg_clk);
-+
-+	return 0;
-+}
-+
-+static const struct of_device_id qcom_ipq806x_sata_phy_of_match[] = {
-+	{ .compatible = "qcom,ipq806x-sata-phy" },
-+	{ },
-+};
-+MODULE_DEVICE_TABLE(of, qcom_ipq806x_sata_phy_of_match);
-+
-+static struct platform_driver qcom_ipq806x_sata_phy_driver = {
-+	.probe	= qcom_ipq806x_sata_phy_probe,
-+	.remove	= qcom_ipq806x_sata_phy_remove,
-+	.driver = {
-+		.name	= "qcom-ipq806x-sata-phy",
-+		.owner	= THIS_MODULE,
-+		.of_match_table	= qcom_ipq806x_sata_phy_of_match,
-+	}
-+};
-+module_platform_driver(qcom_ipq806x_sata_phy_driver);
-+
-+MODULE_DESCRIPTION("QCOM IPQ806x SATA PHY driver");
-+MODULE_LICENSE("GPL v2");
diff --git a/target/linux/ipq806x/patches/0145-phy-qcom-Add-device-tree-bindings-information.patch b/target/linux/ipq806x/patches/0145-phy-qcom-Add-device-tree-bindings-information.patch
deleted file mode 100644
index bd5e5d4..0000000
--- a/target/linux/ipq806x/patches/0145-phy-qcom-Add-device-tree-bindings-information.patch
+++ /dev/null
@@ -1,40 +0,0 @@
-From 37258bc8fe832e4c681593a864686f627f6d3455 Mon Sep 17 00:00:00 2001
-From: Kumar Gala <galak@codeaurora.org>
-Date: Tue, 10 Jun 2014 13:09:01 -0500
-Subject: [PATCH 145/182] phy: qcom: Add device tree bindings information
-
-Add binding spec for Qualcomm SoC PHYs, starting with the SATA PHY on
-the IPQ806x family of SoCs.
-
-Signed-off-by: Kumar Gala <galak@codeaurora.org>
----
- Documentation/devicetree/bindings/phy/qcom-phy.txt |   23 ++++++++++++++++++++
- 1 file changed, 23 insertions(+)
- create mode 100644 Documentation/devicetree/bindings/phy/qcom-phy.txt
-
---- /dev/null
-+++ b/Documentation/devicetree/bindings/phy/qcom-phy.txt
-@@ -0,0 +1,23 @@
-+Qualcomm IPQ806x SATA PHY Controller
-+------------------------------------
-+
-+SATA PHY nodes are defined to describe on-chip SATA Physical layer controllers.
-+Each SATA PHY controller should have its own node.
-+
-+Required properties:
-+- compatible: compatible list, contains "qcom,ipq806x-sata-phy"
-+- reg: offset and length of the SATA PHY register set;
-+- #phy-cells: must be zero
-+- clocks: must be exactly one entry
-+- clock-names: must be "cfg"
-+
-+Example:
-+	sata_phy: sata-phy@1b400000 {
-+		compatible = "qcom,ipq806x-sata-phy";
-+		reg = <0x1b400000 0x200>;
-+
-+		clocks = <&gcc SATA_PHY_CFG_CLK>;
-+		clock-names = "cfg";
-+
-+		#phy-cells = <0>;
-+	};
diff --git a/target/linux/ipq806x/patches/0146-ARM-dts-qcom-Add-SATA-support-for-IPQ8064-and-AP148-.patch b/target/linux/ipq806x/patches/0146-ARM-dts-qcom-Add-SATA-support-for-IPQ8064-and-AP148-.patch
deleted file mode 100644
index da124c7..0000000
--- a/target/linux/ipq806x/patches/0146-ARM-dts-qcom-Add-SATA-support-for-IPQ8064-and-AP148-.patch
+++ /dev/null
@@ -1,65 +0,0 @@
-From 6992cf3e8900d042a845eafc11e7841f32fec0a6 Mon Sep 17 00:00:00 2001
-From: Kumar Gala <galak@codeaurora.org>
-Date: Thu, 12 Jun 2014 10:56:54 -0500
-Subject: [PATCH 146/182] ARM: dts: qcom: Add SATA support for IPQ8064 and
- AP148 board
-
----
- arch/arm/boot/dts/qcom-ipq8064-ap148.dts |    8 ++++++++
- arch/arm/boot/dts/qcom-ipq8064.dtsi      |   30 ++++++++++++++++++++++++++++++
- 2 files changed, 38 insertions(+)
-
---- a/arch/arm/boot/dts/qcom-ipq8064-ap148.dts
-+++ b/arch/arm/boot/dts/qcom-ipq8064-ap148.dts
-@@ -118,5 +118,13 @@
- 				  0x81000000 0 0	  0x31e00000 0 0x00100000   /* downstream I/O */
- 				  0x82000000 0 0x00000000 0x2e000000 0 0x03e00000>; /* non-prefetchable memory */
- 		};
-+
-+		sata-phy@1b400000 {
-+			status = "ok";
-+		};
-+
-+		sata@29000000 {
-+			status = "ok";
-+		};
- 	};
- };
---- a/arch/arm/boot/dts/qcom-ipq8064.dtsi
-+++ b/arch/arm/boot/dts/qcom-ipq8064.dtsi
-@@ -339,5 +339,35 @@
- 			clock-names = "core", "iface", "phy";
- 			status = "disabled";
- 		};
-+
-+		sata_phy: sata-phy@1b400000 {
-+			compatible = "qcom,ipq806x-sata-phy";
-+			reg = <0x1b400000 0x200>;
-+
-+			clocks = <&gcc SATA_PHY_CFG_CLK>;
-+			clock-names = "cfg";
-+
-+			#phy-cells = <0>;
-+			status = "disabled";
-+		};
-+
-+		sata@29000000 {
-+			compatible = "qcom,ipq806x-ahci", "qcom,msm-ahci";
-+			reg = <0x29000000 0x180>;
-+
-+			interrupts = <0 209 0x0>;
-+
-+			clocks = <&gcc SFAB_SATA_S_H_CLK>,
-+				 <&gcc SATA_H_CLK>,
-+				 <&gcc SATA_A_CLK>,
-+				 <&gcc SATA_RXOOB_CLK>,
-+				 <&gcc SATA_PMALIVE_CLK>;
-+			clock-names = "slave_face", "iface", "core",
-+					"rxoob", "pmalive";
-+
-+			phys = <&sata_phy>;
-+			phy-names = "sata-phy";
-+			status = "disabled";
-+		};
- 	};
- };
diff --git a/target/linux/ipq806x/patches/0147-ARM-qcom-Enable-SATA-SATA-PHY-drivers-in-defconfig.patch b/target/linux/ipq806x/patches/0147-ARM-qcom-Enable-SATA-SATA-PHY-drivers-in-defconfig.patch
deleted file mode 100644
index 7465f56..0000000
--- a/target/linux/ipq806x/patches/0147-ARM-qcom-Enable-SATA-SATA-PHY-drivers-in-defconfig.patch
+++ /dev/null
@@ -1,37 +0,0 @@
-From 54a945eca8381fa8cda03b20eda3b2f23a88d289 Mon Sep 17 00:00:00 2001
-From: Kumar Gala <galak@codeaurora.org>
-Date: Tue, 3 Jun 2014 10:36:41 -0500
-Subject: [PATCH 147/182] ARM: qcom: Enable SATA/SATA-PHY drivers in defconfig
-
----
- arch/arm/configs/qcom_defconfig |    5 +++--
- 1 file changed, 3 insertions(+), 2 deletions(-)
-
---- a/arch/arm/configs/qcom_defconfig
-+++ b/arch/arm/configs/qcom_defconfig
-@@ -57,7 +57,6 @@ CONFIG_MTD_BLOCK=y
- CONFIG_MTD_M25P80=y
- CONFIG_BLK_DEV_LOOP=y
- CONFIG_BLK_DEV_RAM=y
--CONFIG_SCSI=y
- CONFIG_SCSI_TGT=y
- CONFIG_BLK_DEV_SD=y
- CONFIG_CHR_DEV_SG=y
-@@ -66,6 +65,8 @@ CONFIG_SCSI_MULTI_LUN=y
- CONFIG_SCSI_CONSTANTS=y
- CONFIG_SCSI_LOGGING=y
- CONFIG_SCSI_SCAN_ASYNC=y
-+CONFIG_ATA=y
-+CONFIG_AHCI_QCOM=y
- CONFIG_NETDEVICES=y
- CONFIG_DUMMY=y
- CONFIG_MDIO_BITBANG=y
-@@ -141,7 +142,7 @@ CONFIG_MSM_GCC_8660=y
- CONFIG_MSM_MMCC_8960=y
- CONFIG_MSM_MMCC_8974=y
- CONFIG_MSM_IOMMU=y
--CONFIG_GENERIC_PHY=y
-+CONFIG_PHY_QCOM_IPQ806X_SATA=y
- CONFIG_EXT2_FS=y
- CONFIG_EXT2_FS_XATTR=y
- CONFIG_EXT3_FS=y
diff --git a/target/linux/ipq806x/patches/0148-ARM-qcom-enable-default-CPU_IDLE-to-get-wfi-support-.patch b/target/linux/ipq806x/patches/0148-ARM-qcom-enable-default-CPU_IDLE-to-get-wfi-support-.patch
deleted file mode 100644
index c68a23b..0000000
--- a/target/linux/ipq806x/patches/0148-ARM-qcom-enable-default-CPU_IDLE-to-get-wfi-support-.patch
+++ /dev/null
@@ -1,21 +0,0 @@
-From 8c9156c67c3e3e37812bb0e4d24263be0e564881 Mon Sep 17 00:00:00 2001
-From: Kumar Gala <galak@codeaurora.org>
-Date: Mon, 16 Jun 2014 14:40:29 -0500
-Subject: [PATCH 148/182] ARM: qcom: enable default CPU_IDLE to get wfi
- support on IPQ806x
-
-Signed-off-by: Kumar Gala <galak@codeaurora.org>
----
- arch/arm/configs/qcom_defconfig |    1 +
- 1 file changed, 1 insertion(+)
-
---- a/arch/arm/configs/qcom_defconfig
-+++ b/arch/arm/configs/qcom_defconfig
-@@ -31,6 +31,7 @@ CONFIG_HIGHPTE=y
- CONFIG_CLEANCACHE=y
- CONFIG_ARM_APPENDED_DTB=y
- CONFIG_ARM_ATAG_DTB_COMPAT=y
-+CONFIG_CPU_IDLE=y
- CONFIG_VFP=y
- CONFIG_NEON=y
- # CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
diff --git a/target/linux/ipq806x/patches/0149-pinctrl-qcom-Add-BUS_HOLD-Keeper-bias.patch b/target/linux/ipq806x/patches/0149-pinctrl-qcom-Add-BUS_HOLD-Keeper-bias.patch
deleted file mode 100644
index 8b2e18a..0000000
--- a/target/linux/ipq806x/patches/0149-pinctrl-qcom-Add-BUS_HOLD-Keeper-bias.patch
+++ /dev/null
@@ -1,50 +0,0 @@
-From b1325bfad3ad0e543ce90a6b08d74500dc96f4b9 Mon Sep 17 00:00:00 2001
-From: Andy Gross <agross@codeaurora.org>
-Date: Mon, 16 Jun 2014 16:52:55 -0500
-Subject: [PATCH 149/182] pinctrl: qcom: Add BUS_HOLD/Keeper bias
-
-This patch adds the bus_hold bias option for pins.
-
-Signed-off-by: Andy Gross <agross@codeaurora.org>
----
- drivers/pinctrl/pinctrl-msm.c |    8 ++++++++
- 1 file changed, 8 insertions(+)
-
---- a/drivers/pinctrl/pinctrl-msm.c
-+++ b/drivers/pinctrl/pinctrl-msm.c
-@@ -207,6 +207,7 @@ static int msm_config_reg(struct msm_pin
- 	case PIN_CONFIG_BIAS_DISABLE:
- 	case PIN_CONFIG_BIAS_PULL_DOWN:
- 	case PIN_CONFIG_BIAS_PULL_UP:
-+	case PIN_CONFIG_BIAS_BUS_HOLD:
- 		*bit = g->pull_bit;
- 		*mask = 3;
- 		break;
-@@ -243,6 +244,7 @@ static int msm_config_set(struct pinctrl
- 
- #define MSM_NO_PULL	0
- #define MSM_PULL_DOWN	1
-+#define MSM_KEEPER	2
- #define MSM_PULL_UP	3
- 
- static unsigned msm_regval_to_drive(u32 val)
-@@ -280,6 +282,9 @@ static int msm_config_group_get(struct p
- 	case PIN_CONFIG_BIAS_PULL_DOWN:
- 		arg = arg == MSM_PULL_DOWN;
- 		break;
-+	case PIN_CONFIG_BIAS_BUS_HOLD:
-+		arg = arg == MSM_KEEPER;
-+		break;
- 	case PIN_CONFIG_BIAS_PULL_UP:
- 		arg = arg == MSM_PULL_UP;
- 		break;
-@@ -339,6 +344,9 @@ static int msm_config_group_set(struct p
- 		case PIN_CONFIG_BIAS_PULL_DOWN:
- 			arg = MSM_PULL_DOWN;
- 			break;
-+		case PIN_CONFIG_BIAS_BUS_HOLD:
-+			arg = MSM_KEEPER;
-+			break;
- 		case PIN_CONFIG_BIAS_PULL_UP:
- 			arg = MSM_PULL_UP;
- 			break;
diff --git a/target/linux/ipq806x/patches/0150-mtd-nand-Add-Qualcomm-NAND-controller.patch b/target/linux/ipq806x/patches/0150-mtd-nand-Add-Qualcomm-NAND-controller.patch
deleted file mode 100644
index f19045e..0000000
--- a/target/linux/ipq806x/patches/0150-mtd-nand-Add-Qualcomm-NAND-controller.patch
+++ /dev/null
@@ -1,8784 +0,0 @@
-From d2981ca1343b837fc574c4e46806d041b258720d Mon Sep 17 00:00:00 2001
-From: Andy Gross <agross@codeaurora.org>
-Date: Mon, 16 Jun 2014 17:13:22 -0500
-Subject: [PATCH 150/182] mtd: nand: Add Qualcomm NAND controller
-
-This patch adds the Qualcomm NAND controller and required infrastructure.
-
-Signed-off-by: Andy Gross <agross@codeaurora.org>
----
- drivers/mtd/nand/Kconfig        |   18 +
- drivers/mtd/nand/Makefile       |    2 +
- drivers/mtd/nand/qcom_adm_dma.c |  797 +++++
- drivers/mtd/nand/qcom_adm_dma.h |  268 ++
- drivers/mtd/nand/qcom_nand.c    | 7455 +++++++++++++++++++++++++++++++++++++++
- drivers/mtd/nand/qcom_nand.h    |  196 +
- 6 files changed, 8736 insertions(+)
- create mode 100644 drivers/mtd/nand/qcom_adm_dma.c
- create mode 100644 drivers/mtd/nand/qcom_adm_dma.h
- create mode 100644 drivers/mtd/nand/qcom_nand.c
- create mode 100644 drivers/mtd/nand/qcom_nand.h
-
---- a/drivers/mtd/nand/Kconfig
-+++ b/drivers/mtd/nand/Kconfig
-@@ -510,4 +510,22 @@ config MTD_NAND_XWAY
- 	  Enables support for NAND Flash chips on Lantiq XWAY SoCs. NAND is attached
- 	  to the External Bus Unit (EBU).
- 
-+config MTD_QCOM_DMA
-+	tristate "QCMO NAND DMA Support"
-+	depends on ARCH_QCOM && MTD_QCOM_NAND
-+	default n
-+	help
-+	  DMA support for QCOM NAND
-+
-+config MTD_QCOM_NAND
-+	tristate "QCOM NAND Device Support"
-+	depends on MTD && ARCH_QCOM
-+	select CRC16
-+	select BITREVERSE
-+	select MTD_NAND_IDS
-+	select MTD_QCOM_DMA
-+	default y
-+	help
-+	  Support for some NAND chips connected to the QCOM NAND controller.
-+
- endif # MTD_NAND
---- a/drivers/mtd/nand/Makefile
-+++ b/drivers/mtd/nand/Makefile
-@@ -49,5 +49,7 @@ obj-$(CONFIG_MTD_NAND_JZ4740)		+= jz4740
- obj-$(CONFIG_MTD_NAND_GPMI_NAND)	+= gpmi-nand/
- obj-$(CONFIG_MTD_NAND_XWAY)		+= xway_nand.o
- obj-$(CONFIG_MTD_NAND_BCM47XXNFLASH)	+= bcm47xxnflash/
-+obj-$(CONFIG_MTD_QCOM_NAND)	+= qcom_nand.o
-+obj-$(CONFIG_MTD_QCOM_DMA)	+= qcom_adm_dma.o
- 
- nand-objs := nand_base.o nand_bbt.o
---- /dev/null
-+++ b/drivers/mtd/nand/qcom_adm_dma.c
-@@ -0,0 +1,797 @@
-+/* * Copyright (c) 2012 The Linux Foundation. All rights reserved.* */
-+/* linux/arch/arm/mach-msm/dma.c
-+ *
-+ * Copyright (C) 2007 Google, Inc.
-+ * Copyright (c) 2008-2010, 2012 The Linux Foundation. All rights reserved.
-+ *
-+ * This software is licensed under the terms of the GNU General Public
-+ * License version 2, as published by the Free Software Foundation, and
-+ * may be copied, distributed, and modified under those terms.
-+ *
-+ * 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/err.h>
-+#include <linux/io.h>
-+#include <linux/interrupt.h>
-+#include <linux/module.h>
-+#include <linux/platform_device.h>
-+#include <linux/spinlock.h>
-+#include <linux/pm_runtime.h>
-+#include <linux/reset.h>
-+#include <linux/reset-controller.h>
-+#include "qcom_adm_dma.h"
-+
-+#define MODULE_NAME "msm_dmov"
-+
-+#define MSM_DMOV_CHANNEL_COUNT 16
-+#define MSM_DMOV_CRCI_COUNT 16
-+
-+enum {
-+	CLK_DIS,
-+	CLK_TO_BE_DIS,
-+	CLK_EN
-+};
-+
-+struct msm_dmov_ci_conf {
-+	int start;
-+	int end;
-+	int burst;
-+};
-+
-+struct msm_dmov_crci_conf {
-+	int sd;
-+	int blk_size;
-+};
-+
-+struct msm_dmov_chan_conf {
-+	int sd;
-+	int block;
-+	int priority;
-+};
-+
-+struct msm_dmov_conf {
-+	void *base;
-+	struct msm_dmov_crci_conf *crci_conf;
-+	struct msm_dmov_chan_conf *chan_conf;
-+	int channel_active;
-+	int sd;
-+	size_t sd_size;
-+	struct list_head staged_commands[MSM_DMOV_CHANNEL_COUNT];
-+	struct list_head ready_commands[MSM_DMOV_CHANNEL_COUNT];
-+	struct list_head active_commands[MSM_DMOV_CHANNEL_COUNT];
-+	struct mutex lock;
-+	spinlock_t list_lock;
-+	unsigned int irq;
-+	struct clk *clk;
-+	struct clk *pclk;
-+	struct clk *ebiclk;
-+	unsigned int clk_ctl;
-+	struct delayed_work work;
-+	struct workqueue_struct *cmd_wq;
-+
-+	struct reset_control *adm_reset;
-+	struct reset_control *pbus_reset;
-+	struct reset_control *c0_reset;
-+	struct reset_control *c1_reset;
-+	struct reset_control *c2_reset;
-+	
-+};
-+
-+static void msm_dmov_clock_work(struct work_struct *);
-+
-+#define DMOV_CRCI_DEFAULT_CONF { .sd = 0, .blk_size = 0 }
-+#define DMOV_CRCI_CONF(secd, blk) { .sd = secd, .blk_size = blk }
-+
-+static struct msm_dmov_crci_conf adm_crci_conf[] = {
-+	DMOV_CRCI_DEFAULT_CONF,
-+	DMOV_CRCI_DEFAULT_CONF,
-+	DMOV_CRCI_DEFAULT_CONF,
-+	DMOV_CRCI_DEFAULT_CONF,
-+	DMOV_CRCI_DEFAULT_CONF,
-+	DMOV_CRCI_DEFAULT_CONF,
-+	DMOV_CRCI_DEFAULT_CONF,
-+	DMOV_CRCI_DEFAULT_CONF,
-+	DMOV_CRCI_DEFAULT_CONF,
-+	DMOV_CRCI_DEFAULT_CONF,
-+	DMOV_CRCI_CONF(0, 1),
-+	DMOV_CRCI_DEFAULT_CONF,
-+	DMOV_CRCI_DEFAULT_CONF,
-+	DMOV_CRCI_DEFAULT_CONF,
-+	DMOV_CRCI_DEFAULT_CONF,
-+	DMOV_CRCI_DEFAULT_CONF,
-+};
-+
-+#define DMOV_CHANNEL_DEFAULT_CONF { .sd = 0, .block = 0, .priority = 1 }
-+
-+static struct msm_dmov_chan_conf adm_chan_conf[] = {
-+	DMOV_CHANNEL_DEFAULT_CONF,
-+	DMOV_CHANNEL_DEFAULT_CONF,
-+	DMOV_CHANNEL_DEFAULT_CONF,
-+	DMOV_CHANNEL_DEFAULT_CONF,
-+	DMOV_CHANNEL_DEFAULT_CONF,
-+	DMOV_CHANNEL_DEFAULT_CONF,
-+	DMOV_CHANNEL_DEFAULT_CONF,
-+	DMOV_CHANNEL_DEFAULT_CONF,
-+	DMOV_CHANNEL_DEFAULT_CONF,
-+	DMOV_CHANNEL_DEFAULT_CONF,
-+	DMOV_CHANNEL_DEFAULT_CONF,
-+	DMOV_CHANNEL_DEFAULT_CONF,
-+	DMOV_CHANNEL_DEFAULT_CONF,
-+	DMOV_CHANNEL_DEFAULT_CONF,
-+	DMOV_CHANNEL_DEFAULT_CONF,
-+	DMOV_CHANNEL_DEFAULT_CONF,
-+};
-+
-+#define DMOV_IRQ_TO_ADM(irq) 0
-+
-+static struct msm_dmov_conf dmov_conf[] = {
-+	{
-+		.crci_conf = adm_crci_conf,
-+		.chan_conf = adm_chan_conf,
-+		.lock = __MUTEX_INITIALIZER(dmov_conf[0].lock),
-+		.list_lock = __SPIN_LOCK_UNLOCKED(dmov_list_lock),
-+		.clk_ctl = CLK_EN,
-+		.work = __DELAYED_WORK_INITIALIZER(dmov_conf[0].work,
-+				msm_dmov_clock_work,0),
-+	}
-+};
-+
-+#define MSM_DMOV_ID_COUNT (MSM_DMOV_CHANNEL_COUNT * ARRAY_SIZE(dmov_conf))
-+#define DMOV_REG(name, adm)    ((name) + (dmov_conf[adm].base) +\
-+	(dmov_conf[adm].sd * dmov_conf[adm].sd_size))
-+#define DMOV_ID_TO_ADM(id)   ((id) / MSM_DMOV_CHANNEL_COUNT)
-+#define DMOV_ID_TO_CHAN(id)   ((id) % MSM_DMOV_CHANNEL_COUNT)
-+#define DMOV_CHAN_ADM_TO_ID(ch, adm) ((ch) + (adm) * MSM_DMOV_CHANNEL_COUNT)
-+
-+enum {
-+	MSM_DMOV_PRINT_ERRORS = 1,
-+	MSM_DMOV_PRINT_IO = 2,
-+	MSM_DMOV_PRINT_FLOW = 4
-+};
-+
-+unsigned int msm_dmov_print_mask = MSM_DMOV_PRINT_ERRORS;
-+
-+#define MSM_DMOV_DPRINTF(mask, format, args...) \
-+	do { \
-+		if ((mask) & msm_dmov_print_mask) \
-+			printk(KERN_ERR format, args); \
-+	} while (0)
-+#define PRINT_ERROR(format, args...) \
-+	MSM_DMOV_DPRINTF(MSM_DMOV_PRINT_ERRORS, format, args);
-+#define PRINT_IO(format, args...) \
-+	MSM_DMOV_DPRINTF(MSM_DMOV_PRINT_IO, format, args);
-+#define PRINT_FLOW(format, args...) \
-+	MSM_DMOV_DPRINTF(MSM_DMOV_PRINT_FLOW, format, args);
-+
-+static int msm_dmov_clk_on(int adm)
-+{
-+	int ret;
-+
-+return 0;
-+	ret = clk_prepare_enable(dmov_conf[adm].clk);
-+	if (ret)
-+		return ret;
-+	if (dmov_conf[adm].pclk) {
-+		ret = clk_prepare_enable(dmov_conf[adm].pclk);
-+		if (ret) {
-+			clk_disable_unprepare(dmov_conf[adm].clk);
-+			return ret;
-+		}
-+	}
-+	if (dmov_conf[adm].ebiclk) {
-+		ret = clk_prepare_enable(dmov_conf[adm].ebiclk);
-+		if (ret) {
-+			if (dmov_conf[adm].pclk)
-+				clk_disable_unprepare(dmov_conf[adm].pclk);
-+			clk_disable_unprepare(dmov_conf[adm].clk);
-+		}
-+	}
-+	return ret;
-+}
-+
-+static void msm_dmov_clk_off(int adm)
-+{
-+#if 0
-+	if (dmov_conf[adm].ebiclk)
-+		clk_disable_unprepare(dmov_conf[adm].ebiclk);
-+	if (dmov_conf[adm].pclk)
-+		clk_disable_unprepare(dmov_conf[adm].pclk);
-+	clk_disable_unprepare(dmov_conf[adm].clk);
-+#endif
-+}
-+
-+static void msm_dmov_clock_work(struct work_struct *work)
-+{
-+	struct msm_dmov_conf *conf =
-+		container_of(to_delayed_work(work), struct msm_dmov_conf, work);
-+	int adm = DMOV_IRQ_TO_ADM(conf->irq);
-+	mutex_lock(&conf->lock);
-+	if (conf->clk_ctl == CLK_TO_BE_DIS) {
-+		BUG_ON(conf->channel_active);
-+		msm_dmov_clk_off(adm);
-+		conf->clk_ctl = CLK_DIS;
-+	}
-+	mutex_unlock(&conf->lock);
-+}
-+
-+enum {
-+	NOFLUSH = 0,
-+	GRACEFUL,
-+	NONGRACEFUL,
-+};
-+
-+/* Caller must hold the list lock */
-+static struct msm_dmov_cmd *start_ready_cmd(unsigned ch, int adm)
-+{
-+	struct msm_dmov_cmd *cmd;
-+
-+	if (list_empty(&dmov_conf[adm].ready_commands[ch])) {
-+		return NULL;
-+	}
-+
-+	cmd = list_entry(dmov_conf[adm].ready_commands[ch].next, typeof(*cmd),
-+			 list);
-+	list_del(&cmd->list);
-+	if (cmd->exec_func)
-+		cmd->exec_func(cmd);
-+	list_add_tail(&cmd->list, &dmov_conf[adm].active_commands[ch]);
-+	if (!dmov_conf[adm].channel_active) {
-+		enable_irq(dmov_conf[adm].irq);
-+	}
-+	dmov_conf[adm].channel_active |= BIT(ch);
-+	PRINT_IO("msm dmov enqueue command, %x, ch %d\n", cmd->cmdptr, ch);
-+	writel_relaxed(cmd->cmdptr, DMOV_REG(DMOV_CMD_PTR(ch), adm));
-+
-+	return cmd;
-+}
-+
-+static void msm_dmov_enqueue_cmd_ext_work(struct work_struct *work)
-+{
-+	struct msm_dmov_cmd *cmd =
-+		container_of(work, struct msm_dmov_cmd, work);
-+	unsigned id = cmd->id;
-+	unsigned status;
-+	unsigned long flags;
-+	int adm = DMOV_ID_TO_ADM(id);
-+	int ch = DMOV_ID_TO_CHAN(id);
-+
-+	mutex_lock(&dmov_conf[adm].lock);
-+	if (dmov_conf[adm].clk_ctl == CLK_DIS) {
-+		status = msm_dmov_clk_on(adm);
-+		if (status != 0)
-+			goto error;
-+	}
-+	dmov_conf[adm].clk_ctl = CLK_EN;
-+
-+	spin_lock_irqsave(&dmov_conf[adm].list_lock, flags);
-+
-+	cmd = list_entry(dmov_conf[adm].staged_commands[ch].next, typeof(*cmd),
-+			 list);
-+	list_del(&cmd->list);
-+	list_add_tail(&cmd->list, &dmov_conf[adm].ready_commands[ch]);
-+	status = readl_relaxed(DMOV_REG(DMOV_STATUS(ch), adm));
-+	if (status & DMOV_STATUS_CMD_PTR_RDY) {
-+		PRINT_IO("msm_dmov_enqueue_cmd(%d), start command, status %x\n",
-+			id, status);
-+		cmd = start_ready_cmd(ch, adm);
-+		/*
-+		 * We added something to the ready list, and still hold the
-+		 * list lock. Thus, no need to check for cmd == NULL
-+		 */
-+		if (cmd->toflush) {
-+			int flush = (cmd->toflush == GRACEFUL) ? 1 << 31 : 0;
-+			writel_relaxed(flush, DMOV_REG(DMOV_FLUSH0(ch), adm));
-+		}
-+	} else {
-+		cmd->toflush = 0;
-+		if (list_empty(&dmov_conf[adm].active_commands[ch]) &&
-+		    !list_empty(&dmov_conf[adm].ready_commands[ch]))
-+			PRINT_ERROR("msm_dmov_enqueue_cmd_ext(%d), stalled, "
-+				"status %x\n", id, status);
-+		PRINT_IO("msm_dmov_enqueue_cmd(%d), enqueue command, status "
-+		    "%x\n", id, status);
-+	}
-+	if (!dmov_conf[adm].channel_active) {
-+		dmov_conf[adm].clk_ctl = CLK_TO_BE_DIS;
-+		schedule_delayed_work(&dmov_conf[adm].work, (HZ/10));
-+	}
-+	spin_unlock_irqrestore(&dmov_conf[adm].list_lock, flags);
-+error:
-+	mutex_unlock(&dmov_conf[adm].lock);
-+}
-+
-+static void __msm_dmov_enqueue_cmd_ext(unsigned id, struct msm_dmov_cmd *cmd)
-+{
-+	int adm = DMOV_ID_TO_ADM(id);
-+	int ch = DMOV_ID_TO_CHAN(id);
-+	unsigned long flags;
-+	cmd->id = id;
-+	cmd->toflush = 0;
-+
-+	spin_lock_irqsave(&dmov_conf[adm].list_lock, flags);
-+	list_add_tail(&cmd->list, &dmov_conf[adm].staged_commands[ch]);
-+	spin_unlock_irqrestore(&dmov_conf[adm].list_lock, flags);
-+
-+	queue_work(dmov_conf[adm].cmd_wq, &cmd->work);
-+}
-+
-+void msm_dmov_enqueue_cmd_ext(unsigned id, struct msm_dmov_cmd *cmd)
-+{
-+	INIT_WORK(&cmd->work, msm_dmov_enqueue_cmd_ext_work);
-+	__msm_dmov_enqueue_cmd_ext(id, cmd);
-+}
-+EXPORT_SYMBOL(msm_dmov_enqueue_cmd_ext);
-+
-+void msm_dmov_enqueue_cmd(unsigned id, struct msm_dmov_cmd *cmd)
-+{
-+	/* Disable callback function (for backwards compatibility) */
-+	cmd->exec_func = NULL;
-+	INIT_WORK(&cmd->work, msm_dmov_enqueue_cmd_ext_work);
-+	__msm_dmov_enqueue_cmd_ext(id, cmd);
-+}
-+EXPORT_SYMBOL(msm_dmov_enqueue_cmd);
-+
-+void msm_dmov_flush(unsigned int id, int graceful)
-+{
-+	unsigned long irq_flags;
-+	int ch = DMOV_ID_TO_CHAN(id);
-+	int adm = DMOV_ID_TO_ADM(id);
-+	int flush = graceful ? DMOV_FLUSH_TYPE : 0;
-+	struct msm_dmov_cmd *cmd;
-+
-+	spin_lock_irqsave(&dmov_conf[adm].list_lock, irq_flags);
-+	/* XXX not checking if flush cmd sent already */
-+	if (!list_empty(&dmov_conf[adm].active_commands[ch])) {
-+		PRINT_IO("msm_dmov_flush(%d), send flush cmd\n", id);
-+		writel_relaxed(flush, DMOV_REG(DMOV_FLUSH0(ch), adm));
-+	}
-+	list_for_each_entry(cmd, &dmov_conf[adm].staged_commands[ch], list)
-+		cmd->toflush = graceful ? GRACEFUL : NONGRACEFUL;
-+	/* spin_unlock_irqrestore has the necessary barrier */
-+	spin_unlock_irqrestore(&dmov_conf[adm].list_lock, irq_flags);
-+}
-+EXPORT_SYMBOL(msm_dmov_flush);
-+
-+struct msm_dmov_exec_cmdptr_cmd {
-+	struct msm_dmov_cmd dmov_cmd;
-+	struct completion complete;
-+	unsigned id;
-+	unsigned int result;
-+	struct msm_dmov_errdata err;
-+};
-+
-+static void
-+dmov_exec_cmdptr_complete_func(struct msm_dmov_cmd *_cmd,
-+			       unsigned int result,
-+			       struct msm_dmov_errdata *err)
-+{
-+	struct msm_dmov_exec_cmdptr_cmd *cmd = container_of(_cmd, struct msm_dmov_exec_cmdptr_cmd, dmov_cmd);
-+	cmd->result = result;
-+	if (result != 0x80000002 && err)
-+		memcpy(&cmd->err, err, sizeof(struct msm_dmov_errdata));
-+
-+	complete(&cmd->complete);
-+}
-+
-+int msm_dmov_exec_cmd(unsigned id, unsigned int cmdptr)
-+{
-+	struct msm_dmov_exec_cmdptr_cmd cmd;
-+
-+	PRINT_FLOW("dmov_exec_cmdptr(%d, %x)\n", id, cmdptr);
-+
-+	cmd.dmov_cmd.cmdptr = cmdptr;
-+	cmd.dmov_cmd.complete_func = dmov_exec_cmdptr_complete_func;
-+	cmd.dmov_cmd.exec_func = NULL;
-+	cmd.id = id;
-+	cmd.result = 0;
-+	INIT_WORK_ONSTACK(&cmd.dmov_cmd.work, msm_dmov_enqueue_cmd_ext_work);
-+	init_completion(&cmd.complete);
-+
-+	__msm_dmov_enqueue_cmd_ext(id, &cmd.dmov_cmd);
-+	wait_for_completion_timeout(&cmd.complete, msecs_to_jiffies(1000));
-+
-+	if (cmd.result != 0x80000002) {
-+		PRINT_ERROR("dmov_exec_cmdptr(%d): ERROR, result: %x\n", id, cmd.result);
-+		PRINT_ERROR("dmov_exec_cmdptr(%d):  flush: %x %x %x %x\n",
-+			id, cmd.err.flush[0], cmd.err.flush[1], cmd.err.flush[2], cmd.err.flush[3]);
-+		return -EIO;
-+	}
-+	PRINT_FLOW("dmov_exec_cmdptr(%d, %x) done\n", id, cmdptr);
-+	return 0;
-+}
-+EXPORT_SYMBOL(msm_dmov_exec_cmd);
-+
-+static void fill_errdata(struct msm_dmov_errdata *errdata, int ch, int adm)
-+{
-+	errdata->flush[0] = readl_relaxed(DMOV_REG(DMOV_FLUSH0(ch), adm));
-+	errdata->flush[1] = readl_relaxed(DMOV_REG(DMOV_FLUSH1(ch), adm));
-+	errdata->flush[2] = 0;
-+	errdata->flush[3] = readl_relaxed(DMOV_REG(DMOV_FLUSH3(ch), adm));
-+	errdata->flush[4] = readl_relaxed(DMOV_REG(DMOV_FLUSH4(ch), adm));
-+	errdata->flush[5] = readl_relaxed(DMOV_REG(DMOV_FLUSH5(ch), adm));
-+}
-+
-+static irqreturn_t msm_dmov_isr(int irq, void *dev_id)
-+{
-+        unsigned int int_status;
-+	unsigned int mask;
-+	unsigned int id;
-+	unsigned int ch;
-+	unsigned long irq_flags;
-+	unsigned int ch_status;
-+	unsigned int ch_result;
-+	unsigned int valid = 0;
-+	struct msm_dmov_cmd *cmd;
-+	int adm = DMOV_IRQ_TO_ADM(irq);
-+
-+	mutex_lock(&dmov_conf[adm].lock);
-+	/* read and clear isr */
-+	int_status = readl_relaxed(DMOV_REG(DMOV_ISR, adm));
-+	PRINT_FLOW("msm_datamover_irq_handler: DMOV_ISR %x\n", int_status);
-+
-+	spin_lock_irqsave(&dmov_conf[adm].list_lock, irq_flags);
-+	while (int_status) {
-+		mask = int_status & -int_status;
-+		ch = fls(mask) - 1;
-+		id = DMOV_CHAN_ADM_TO_ID(ch, adm);
-+		PRINT_FLOW("msm_datamover_irq_handler %08x %08x id %d\n", int_status, mask, id);
-+		int_status &= ~mask;
-+		ch_status = readl_relaxed(DMOV_REG(DMOV_STATUS(ch), adm));
-+		if (!(ch_status & DMOV_STATUS_RSLT_VALID)) {
-+			PRINT_FLOW("msm_datamover_irq_handler id %d, "
-+				"result not valid %x\n", id, ch_status);
-+			continue;
-+		}
-+		do {
-+			valid = 1;
-+			ch_result = readl_relaxed(DMOV_REG(DMOV_RSLT(ch), adm));
-+			if (list_empty(&dmov_conf[adm].active_commands[ch])) {
-+				PRINT_ERROR("msm_datamover_irq_handler id %d, got result "
-+					"with no active command, status %x, result %x\n",
-+					id, ch_status, ch_result);
-+				cmd = NULL;
-+			} else {
-+				cmd = list_entry(dmov_conf[adm].
-+					active_commands[ch].next, typeof(*cmd),
-+					list);
-+			}
-+			PRINT_FLOW("msm_datamover_irq_handler id %d, status %x, result %x\n", id, ch_status, ch_result);
-+			if (ch_result & DMOV_RSLT_DONE) {
-+				PRINT_FLOW("msm_datamover_irq_handler id %d, status %x\n",
-+					id, ch_status);
-+				PRINT_IO("msm_datamover_irq_handler id %d, got result "
-+					"for %p, result %x\n", id, cmd, ch_result);
-+				if (cmd) {
-+					list_del(&cmd->list);
-+					cmd->complete_func(cmd, ch_result, NULL);
-+				}
-+			}
-+			if (ch_result & DMOV_RSLT_FLUSH) {
-+				struct msm_dmov_errdata errdata;
-+
-+				fill_errdata(&errdata, ch, adm);
-+				PRINT_FLOW("msm_datamover_irq_handler id %d, status %x\n", id, ch_status);
-+				PRINT_FLOW("msm_datamover_irq_handler id %d, flush, result %x, flush0 %x\n", id, ch_result, errdata.flush[0]);
-+				if (cmd) {
-+					list_del(&cmd->list);
-+					cmd->complete_func(cmd, ch_result, &errdata);
-+				}
-+			}
-+			if (ch_result & DMOV_RSLT_ERROR) {
-+				struct msm_dmov_errdata errdata;
-+
-+				fill_errdata(&errdata, ch, adm);
-+
-+				PRINT_ERROR("msm_datamover_irq_handler id %d, status %x\n", id, ch_status);
-+				PRINT_ERROR("msm_datamover_irq_handler id %d, error, result %x, flush0 %x\n", id, ch_result, errdata.flush[0]);
-+				if (cmd) {
-+					list_del(&cmd->list);
-+					cmd->complete_func(cmd, ch_result, &errdata);
-+				}
-+				/* this does not seem to work, once we get an error */
-+				/* the datamover will no longer accept commands */
-+				writel_relaxed(0, DMOV_REG(DMOV_FLUSH0(ch),
-+					       adm));
-+			}
-+			rmb();
-+			ch_status = readl_relaxed(DMOV_REG(DMOV_STATUS(ch),
-+						  adm));
-+			PRINT_FLOW("msm_datamover_irq_handler id %d, status %x\n", id, ch_status);
-+			if (ch_status & DMOV_STATUS_CMD_PTR_RDY)
-+				start_ready_cmd(ch, adm);
-+		} while (ch_status & DMOV_STATUS_RSLT_VALID);
-+		if (list_empty(&dmov_conf[adm].active_commands[ch]) &&
-+		    list_empty(&dmov_conf[adm].ready_commands[ch]))
-+			dmov_conf[adm].channel_active &= ~(1U << ch);
-+		PRINT_FLOW("msm_datamover_irq_handler id %d, status %x\n", id, ch_status);
-+	}
-+	spin_unlock_irqrestore(&dmov_conf[adm].list_lock, irq_flags);
-+
-+	if (!dmov_conf[adm].channel_active && valid) {
-+		disable_irq_nosync(dmov_conf[adm].irq);
-+		dmov_conf[adm].clk_ctl = CLK_TO_BE_DIS;
-+		schedule_delayed_work(&dmov_conf[adm].work, (HZ/10));
-+	}
-+
-+	mutex_unlock(&dmov_conf[adm].lock);
-+
-+	return valid ? IRQ_HANDLED : IRQ_NONE;
-+}
-+
-+static int msm_dmov_suspend_late(struct device *dev)
-+{
-+	struct platform_device *pdev = to_platform_device(dev);
-+	int adm = (pdev->id >= 0) ? pdev->id : 0;
-+	mutex_lock(&dmov_conf[adm].lock);
-+	if (dmov_conf[adm].clk_ctl == CLK_TO_BE_DIS) {
-+		BUG_ON(dmov_conf[adm].channel_active);
-+		msm_dmov_clk_off(adm);
-+		dmov_conf[adm].clk_ctl = CLK_DIS;
-+	}
-+	mutex_unlock(&dmov_conf[adm].lock);
-+	return 0;
-+}
-+
-+static int msm_dmov_runtime_suspend(struct device *dev)
-+{
-+	dev_dbg(dev, "pm_runtime: suspending...\n");
-+	return 0;
-+}
-+
-+static int msm_dmov_runtime_resume(struct device *dev)
-+{
-+	dev_dbg(dev, "pm_runtime: resuming...\n");
-+	return 0;
-+}
-+
-+static int msm_dmov_runtime_idle(struct device *dev)
-+{
-+	dev_dbg(dev, "pm_runtime: idling...\n");
-+	return 0;
-+}
-+
-+static struct dev_pm_ops msm_dmov_dev_pm_ops = {
-+	.runtime_suspend = msm_dmov_runtime_suspend,
-+	.runtime_resume = msm_dmov_runtime_resume,
-+	.runtime_idle = msm_dmov_runtime_idle,
-+	.suspend = msm_dmov_suspend_late,
-+};
-+
-+static int msm_dmov_init_clocks(struct platform_device *pdev)
-+{
-+	int adm = (pdev->id >= 0) ? pdev->id : 0;
-+	int ret;
-+
-+	dmov_conf[adm].clk = devm_clk_get(&pdev->dev, "core_clk");
-+	if (IS_ERR(dmov_conf[adm].clk)) {
-+		printk(KERN_ERR "%s: Error getting adm_clk\n", __func__);
-+		dmov_conf[adm].clk = NULL;
-+		return -ENOENT;
-+	}
-+
-+	dmov_conf[adm].pclk = devm_clk_get(&pdev->dev, "iface_clk");
-+	if (IS_ERR(dmov_conf[adm].pclk)) {
-+		dmov_conf[adm].pclk = NULL;
-+		/* pclk not present on all SoCs, don't bail on failure */
-+	}
-+
-+	dmov_conf[adm].ebiclk = devm_clk_get(&pdev->dev, "mem_clk");
-+	if (IS_ERR(dmov_conf[adm].ebiclk)) {
-+		dmov_conf[adm].ebiclk = NULL;
-+		/* ebiclk not present on all SoCs, don't bail on failure */
-+	} else {
-+		ret = clk_set_rate(dmov_conf[adm].ebiclk, 27000000);
-+		if (ret)
-+			return -ENOENT;
-+	}
-+
-+	return 0;
-+}
-+
-+static void config_datamover(int adm)
-+{
-+	int i;
-+
-+	/* Reset the ADM */
-+	reset_control_assert(dmov_conf[adm].adm_reset);
-+	reset_control_assert(dmov_conf[adm].c0_reset);
-+	reset_control_assert(dmov_conf[adm].c1_reset);
-+	reset_control_assert(dmov_conf[adm].c2_reset);
-+
-+	reset_control_deassert(dmov_conf[adm].c2_reset);
-+	reset_control_deassert(dmov_conf[adm].c1_reset);
-+	reset_control_deassert(dmov_conf[adm].c0_reset);
-+	reset_control_deassert(dmov_conf[adm].adm_reset);
-+
-+	for (i = 0; i < MSM_DMOV_CHANNEL_COUNT; i++) {
-+		struct msm_dmov_chan_conf *chan_conf =
-+			dmov_conf[adm].chan_conf;
-+		unsigned conf;
-+		/* Only configure scorpion channels */
-+		if (chan_conf[i].sd <= 1) {
-+			conf = readl_relaxed(DMOV_REG(DMOV_CONF(i), adm));
-+			conf |= DMOV_CONF_MPU_DISABLE |
-+				DMOV_CONF_PERM_MPU_CONF |
-+				DMOV_CONF_FLUSH_RSLT_EN |
-+				DMOV_CONF_FORCE_RSLT_EN |
-+				DMOV_CONF_IRQ_EN |
-+				DMOV_CONF_PRIORITY(chan_conf[i].priority);
-+
-+			conf &= ~DMOV_CONF_SD(7);
-+			conf |= DMOV_CONF_SD(chan_conf[i].sd);
-+			writel_relaxed(conf, DMOV_REG(DMOV_CONF(i), adm));
-+		}
-+	}
-+
-+	for (i = 0; i < MSM_DMOV_CRCI_COUNT; i++) {
-+		writel_relaxed(DMOV_CRCI_CTL_RST,
-+		       DMOV_REG(DMOV_CRCI_CTL(i), adm));
-+	}
-+
-+	/* NAND CRCI Enable */
-+	writel_relaxed(0, DMOV_REG(DMOV_CRCI_CTL(DMOV_NAND_CRCI_DATA), adm));
-+	writel_relaxed(0, DMOV_REG(DMOV_CRCI_CTL(DMOV_NAND_CRCI_CMD), adm));
-+
-+	/* GSBI5 CRCI Enable */
-+	writel_relaxed(0, DMOV_REG(DMOV_CRCI_CTL(DMOV_SPI_GSBI5_RX_CRCI), adm));
-+	writel_relaxed(0, DMOV_REG(DMOV_CRCI_CTL(DMOV_SPI_GSBI5_TX_CRCI), adm));
-+
-+	writel_relaxed(DMOV_CI_CONF_RANGE_START(0x40) |	/* EBI1 */
-+			DMOV_CI_CONF_RANGE_END(0xb0) |
-+			DMOV_CI_CONF_MAX_BURST(0x8),
-+		       DMOV_REG(DMOV_CI_CONF(0), adm));
-+
-+	writel_relaxed(DMOV_CI_CONF_RANGE_START(0x2a) |	/* IMEM */
-+			DMOV_CI_CONF_RANGE_END(0x2c) |
-+			DMOV_CI_CONF_MAX_BURST(0x8),
-+		       DMOV_REG(DMOV_CI_CONF(1), adm));
-+
-+	writel_relaxed(DMOV_CI_CONF_RANGE_START(0x12) |	/* CPSS/SPS */
-+			DMOV_CI_CONF_RANGE_END(0x28) |
-+			DMOV_CI_CONF_MAX_BURST(0x8),
-+		       DMOV_REG(DMOV_CI_CONF(2), adm));
-+
-+	writel_relaxed(DMOV_HI_GP_CTL_CORE_CLK_LP_EN | /* will disable LP */
-+			DMOV_HI_GP_CTL_LP_CNT(0xf),
-+		       DMOV_REG(DMOV_HI_GP_CTL, adm));
-+
-+}
-+
-+static int msm_dmov_probe(struct platform_device *pdev)
-+{
-+	
-+        int adm = (pdev->id >= 0) ? pdev->id : 0;
-+	int i;
-+	int ret;
-+	struct resource *irqres =
-+		platform_get_resource(pdev, IORESOURCE_IRQ, 0);
-+	struct resource *mres =
-+		platform_get_resource(pdev, IORESOURCE_MEM, 0);
-+
-+        dmov_conf[adm].sd=0;
-+        dmov_conf[adm].sd_size=0x800;
-+	   
-+	dmov_conf[adm].irq = irqres->start;
-+
-+	dmov_conf[adm].base = devm_ioremap_resource(&pdev->dev, mres);
-+	if (!dmov_conf[adm].base)
-+		return -ENOMEM;
-+
-+	dmov_conf[adm].cmd_wq = alloc_ordered_workqueue("dmov%d_wq", 0, adm);
-+	if (!dmov_conf[adm].cmd_wq) {
-+		PRINT_ERROR("Couldn't allocate ADM%d workqueue.\n", adm);
-+		return -ENOMEM;
-+	}
-+
-+	/* get resets */
-+	dmov_conf[adm].adm_reset = devm_reset_control_get(&pdev->dev, "adm");
-+	if (IS_ERR(dmov_conf[adm].adm_reset)) {
-+		dev_err(&pdev->dev, "failed to get adm reset\n");
-+		ret = PTR_ERR(dmov_conf[adm].adm_reset);
-+		goto out_wq;
-+	}
-+
-+	dmov_conf[adm].pbus_reset = devm_reset_control_get(&pdev->dev, "pbus");
-+	if (IS_ERR(dmov_conf[adm].pbus_reset)) {
-+		dev_err(&pdev->dev, "failed to get pbus reset\n");
-+		ret = PTR_ERR(dmov_conf[adm].pbus_reset);
-+		goto out_wq;
-+	}
-+
-+	dmov_conf[adm].c0_reset = devm_reset_control_get(&pdev->dev, "c0");
-+	if (IS_ERR(dmov_conf[adm].c0_reset)) {
-+		dev_err(&pdev->dev, "failed to get c0 reset\n");
-+		ret = PTR_ERR(dmov_conf[adm].c0_reset);
-+		goto out_wq;
-+	}
-+
-+	dmov_conf[adm].c1_reset = devm_reset_control_get(&pdev->dev, "c1");
-+	if (IS_ERR(dmov_conf[adm].c1_reset)) {
-+		dev_err(&pdev->dev, "failed to get c1 reset\n");
-+		ret = PTR_ERR(dmov_conf[adm].c1_reset);
-+		goto out_wq;
-+	}
-+
-+	dmov_conf[adm].c2_reset = devm_reset_control_get(&pdev->dev, "c2");
-+	if (IS_ERR(dmov_conf[adm].c2_reset)) {
-+		dev_err(&pdev->dev, "failed to get c2 reset\n");
-+		ret = PTR_ERR(dmov_conf[adm].c2_reset);
-+		goto out_wq;
-+	}
-+
-+	ret = devm_request_threaded_irq(&pdev->dev, dmov_conf[adm].irq, NULL,
-+		msm_dmov_isr, IRQF_ONESHOT, "msmdatamover", NULL);
-+
-+	if (ret) {
-+		PRINT_ERROR("Requesting ADM%d irq %d failed\n", adm,
-+			dmov_conf[adm].irq);
-+		goto out_wq;
-+	}
-+
-+	disable_irq(dmov_conf[adm].irq);
-+	ret = msm_dmov_init_clocks(pdev);
-+	if (ret) {
-+		PRINT_ERROR("Requesting ADM%d clocks failed\n", adm);
-+		goto out_wq;
-+	}
-+	clk_prepare_enable(dmov_conf[adm].clk);
-+	clk_prepare_enable(dmov_conf[adm].pclk);
-+
-+//	ret = msm_dmov_clk_on(adm);
-+//	if (ret) {
-+//		PRINT_ERROR("Enabling ADM%d clocks failed\n", adm);
-+//		goto out_wq;
-+//	}
-+
-+	config_datamover(adm);
-+	for (i = 0; i < MSM_DMOV_CHANNEL_COUNT; i++) {
-+		INIT_LIST_HEAD(&dmov_conf[adm].staged_commands[i]);
-+		INIT_LIST_HEAD(&dmov_conf[adm].ready_commands[i]);
-+		INIT_LIST_HEAD(&dmov_conf[adm].active_commands[i]);
-+
-+		writel_relaxed(DMOV_RSLT_CONF_IRQ_EN
-+		     | DMOV_RSLT_CONF_FORCE_FLUSH_RSLT,
-+		     DMOV_REG(DMOV_RSLT_CONF(i), adm));
-+	}
-+	wmb();
-+//	msm_dmov_clk_off(adm);
-+	return ret;
-+out_wq:
-+	destroy_workqueue(dmov_conf[adm].cmd_wq);
-+	return ret;
-+}
-+
-+#ifdef CONFIG_OF
-+static const struct of_device_id adm_of_match[] = {
-+        { .compatible = "qcom,adm", },
-+        {},
-+};
-+MODULE_DEVICE_TABLE(of, adm_of_match);
-+#endif
-+
-+static struct platform_driver msm_dmov_driver = {
-+	.probe = msm_dmov_probe,
-+	.driver = {
-+		.name = MODULE_NAME,
-+		.owner = THIS_MODULE,
-+                .of_match_table = adm_of_match,
-+		.pm = &msm_dmov_dev_pm_ops,
-+	},
-+};
-+
-+/* static int __init */
-+static int __init msm_init_datamover(void)
-+{
-+	int ret;
-+	ret = platform_driver_register(&msm_dmov_driver);
-+	if (ret)
-+		return ret;
-+	return 0;
-+}
-+arch_initcall(msm_init_datamover);
---- /dev/null
-+++ b/drivers/mtd/nand/qcom_adm_dma.h
-@@ -0,0 +1,268 @@
-+/* * Copyright (c) 2012 The Linux Foundation. All rights reserved.* */
-+/* linux/include/asm-arm/arch-msm/dma.h
-+ *
-+ * Copyright (C) 2007 Google, Inc.
-+ * Copyright (c) 2008-2012, The Linux Foundation. All rights reserved.
-+ *
-+ * This software is licensed under the terms of the GNU General Public
-+ * License version 2, as published by the Free Software Foundation, and
-+ * may be copied, distributed, and modified under those terms.
-+ *
-+ * 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 __ASM_ARCH_MSM_DMA_H
-+#define __ASM_ARCH_MSM_DMA_H
-+#include <linux/list.h>
-+
-+struct msm_dmov_errdata {
-+	uint32_t flush[6];
-+};
-+
-+struct msm_dmov_cmd {
-+	struct list_head list;
-+	unsigned int cmdptr;
-+	void (*complete_func)(struct msm_dmov_cmd *cmd,
-+			      unsigned int result,
-+			      struct msm_dmov_errdata *err);
-+	void (*exec_func)(struct msm_dmov_cmd *cmd);
-+	struct work_struct work;
-+	unsigned id;    /* For internal use */
-+	void *user;	/* Pointer for caller's reference */
-+	u8 toflush;
-+};
-+
-+struct msm_dmov_pdata {
-+	int sd;
-+	size_t sd_size;
-+};
-+
-+void msm_dmov_enqueue_cmd(unsigned id, struct msm_dmov_cmd *cmd);
-+void msm_dmov_enqueue_cmd_ext(unsigned id, struct msm_dmov_cmd *cmd);
-+void msm_dmov_flush(unsigned int id, int graceful);
-+int msm_dmov_exec_cmd(unsigned id, unsigned int cmdptr);
-+
-+#define DMOV_CRCIS_PER_CONF 10
-+
-+#define DMOV_ADDR(off, ch) ((off) + ((ch) << 2))
-+
-+#define DMOV_CMD_PTR(ch)      DMOV_ADDR(0x000, ch)
-+#define DMOV_CMD_LIST         (0 << 29) /* does not work */
-+#define DMOV_CMD_PTR_LIST     (1 << 29) /* works */
-+#define DMOV_CMD_INPUT_CFG    (2 << 29) /* untested */
-+#define DMOV_CMD_OUTPUT_CFG   (3 << 29) /* untested */
-+#define DMOV_CMD_ADDR(addr)   ((addr) >> 3)
-+
-+#define DMOV_RSLT(ch)         DMOV_ADDR(0x040, ch)
-+#define DMOV_RSLT_VALID       (1 << 31) /* 0 == host has empties result fifo */
-+#define DMOV_RSLT_ERROR       (1 << 3)
-+#define DMOV_RSLT_FLUSH       (1 << 2)
-+#define DMOV_RSLT_DONE        (1 << 1)  /* top pointer done */
-+#define DMOV_RSLT_USER        (1 << 0)  /* command with FR force result */
-+
-+#define DMOV_FLUSH0(ch)       DMOV_ADDR(0x080, ch)
-+#define DMOV_FLUSH1(ch)       DMOV_ADDR(0x0C0, ch)
-+#define DMOV_FLUSH2(ch)       DMOV_ADDR(0x100, ch)
-+#define DMOV_FLUSH3(ch)       DMOV_ADDR(0x140, ch)
-+#define DMOV_FLUSH4(ch)       DMOV_ADDR(0x180, ch)
-+#define DMOV_FLUSH5(ch)       DMOV_ADDR(0x1C0, ch)
-+#define DMOV_FLUSH_TYPE       (1 << 31)
-+
-+#define DMOV_STATUS(ch)       DMOV_ADDR(0x200, ch)
-+#define DMOV_STATUS_RSLT_COUNT(n)    (((n) >> 29))
-+#define DMOV_STATUS_CMD_COUNT(n)     (((n) >> 27) & 3)
-+#define DMOV_STATUS_RSLT_VALID       (1 << 1)
-+#define DMOV_STATUS_CMD_PTR_RDY      (1 << 0)
-+
-+#define DMOV_CONF(ch)         DMOV_ADDR(0x240, ch)
-+#define DMOV_CONF_SD(sd)		(((sd & 4) << 11) | ((sd & 3) << 4))
-+#define DMOV_CONF_OTHER_CH_BLK_MASK(m)	((m << 0x10) & 0xffff0000)
-+#define DMOV_CONF_SHADOW_EN		(1 << 12)
-+#define DMOV_CONF_MPU_DISABLE		(1 << 11)
-+#define DMOV_CONF_PERM_MPU_CONF		(1 << 9)
-+#define DMOV_CONF_FLUSH_RSLT_EN		(1 << 8)
-+#define DMOV_CONF_IRQ_EN		(1 << 6)
-+#define DMOV_CONF_FORCE_RSLT_EN		(1 << 7)
-+#define DMOV_CONF_PRIORITY(n)		(n << 0)
-+
-+#define DMOV_DBG_ERR(ci)      DMOV_ADDR(0x280, ci)
-+
-+#define DMOV_RSLT_CONF(ch)    DMOV_ADDR(0x300, ch)
-+#define DMOV_RSLT_CONF_FORCE_TOP_PTR_RSLT (1 << 2)
-+#define DMOV_RSLT_CONF_FORCE_FLUSH_RSLT   (1 << 1)
-+#define DMOV_RSLT_CONF_IRQ_EN             (1 << 0)
-+
-+#define DMOV_ISR              DMOV_ADDR(0x380, 0)
-+
-+#define DMOV_CI_CONF(ci)      DMOV_ADDR(0x390, ci)
-+#define DMOV_CI_CONF_RANGE_END(n)      ((n) << 24)
-+#define DMOV_CI_CONF_RANGE_START(n)    ((n) << 16)
-+#define DMOV_CI_CONF_MAX_BURST(n)      ((n) << 0)
-+
-+#define DMOV_CI_DBG_ERR(ci)   DMOV_ADDR(0x3B0, ci)
-+
-+#define DMOV_CRCI_CONF0       DMOV_ADDR(0x3D0, 0)
-+#define DMOV_CRCI_CONF0_CRCI9_SD	(2 << 0x1b)
-+
-+#define DMOV_CRCI_CONF1       DMOV_ADDR(0x3D4, 0)
-+#define DMOV_CRCI_CONF0_SD(crci, sd) (sd << (crci*3))
-+#define DMOV_CRCI_CONF1_SD(crci, sd) (sd << ((crci-DMOV_CRCIS_PER_CONF)*3))
-+
-+#define DMOV_HI_GP_CTL			DMOV_ADDR(0x3D8, 0)
-+#define DMOV_HI_GP_CTL_CORE_CLK_LP_EN	(1 << 12)
-+#define DMOV_HI_GP_CTL_LP_CNT(x)	(((x) & 0xf) << 8)
-+#define DMOV_HI_GP_CTL_CI3_CLK_LP_EN	(1 << 7)
-+#define DMOV_HI_GP_CTL_CI2_CLK_LP_EN	(1 << 6)
-+#define DMOV_HI_GP_CTL_CI1_CLK_LP_EN	(1 << 5)
-+#define DMOV_HI_GP_CTL_CI0_CLK_LP_EN	(1 << 4)
-+
-+#define DMOV_CRCI_CTL(crci)   DMOV_ADDR(0x400, crci)
-+#define DMOV_CRCI_CTL_BLK_SZ(n)        ((n) << 0)
-+#define DMOV_CRCI_CTL_RST              (1 << 17)
-+#define DMOV_CRCI_MUX                  (1 << 18)
-+
-+/* channel assignments */
-+
-+/*
-+ * Format of CRCI numbers: crci number + (muxsel << 4)
-+ */
-+
-+#define DMOV_GP_CHAN           9
-+
-+#define DMOV_CE_IN_CHAN        0
-+#define DMOV_CE_IN_CRCI        2
-+
-+#define DMOV_CE_OUT_CHAN       1
-+#define DMOV_CE_OUT_CRCI       3
-+
-+#define DMOV_TSIF_CHAN         2
-+#define DMOV_TSIF_CRCI         11
-+
-+#define DMOV_HSUART_GSBI6_TX_CHAN	7
-+#define DMOV_HSUART_GSBI6_TX_CRCI	6
-+
-+#define DMOV_HSUART_GSBI6_RX_CHAN	8
-+#define DMOV_HSUART_GSBI6_RX_CRCI	11
-+
-+#define DMOV_HSUART_GSBI8_TX_CHAN	7
-+#define DMOV_HSUART_GSBI8_TX_CRCI	10
-+
-+#define DMOV_HSUART_GSBI8_RX_CHAN	8
-+#define DMOV_HSUART_GSBI8_RX_CRCI	9
-+
-+#define DMOV_HSUART_GSBI9_TX_CHAN	4
-+#define DMOV_HSUART_GSBI9_TX_CRCI	13
-+
-+#define DMOV_HSUART_GSBI9_RX_CHAN	3
-+#define DMOV_HSUART_GSBI9_RX_CRCI	12
-+
-+#define DMOV_NAND_CHAN			3
-+#define DMOV_NAND_CRCI_CMD		15
-+#define DMOV_NAND_CRCI_DATA		3
-+
-+#define DMOV_SPI_GSBI5_RX_CRCI		9
-+#define DMOV_SPI_GSBI5_TX_CRCI		10
-+#define DMOV_SPI_GSBI5_RX_CHAN		6
-+#define DMOV_SPI_GSBI5_TX_CHAN		5
-+
-+/* channels for APQ8064 */
-+#define DMOV8064_CE_IN_CHAN        0
-+#define DMOV8064_CE_IN_CRCI       14
-+
-+#define DMOV8064_CE_OUT_CHAN       1
-+#define DMOV8064_CE_OUT_CRCI       15
-+
-+#define DMOV8064_TSIF_CHAN         2
-+#define DMOV8064_TSIF_CRCI         1
-+
-+/* channels for APQ8064 SGLTE*/
-+#define DMOV_APQ8064_HSUART_GSBI4_TX_CHAN	11
-+#define DMOV_APQ8064_HSUART_GSBI4_TX_CRCI	8
-+
-+#define DMOV_APQ8064_HSUART_GSBI4_RX_CHAN	10
-+#define DMOV_APQ8064_HSUART_GSBI4_RX_CRCI	7
-+
-+/* channels for MPQ8064 */
-+#define DMOV_MPQ8064_HSUART_GSBI6_TX_CHAN	7
-+#define DMOV_MPQ8064_HSUART_GSBI6_TX_CRCI	6
-+
-+#define DMOV_MPQ8064_HSUART_GSBI6_RX_CHAN	6
-+#define DMOV_MPQ8064_HSUART_GSBI6_RX_CRCI	11
-+
-+#define DMOV_IPQ806X_HSUART_GSBI6_TX_CHAN	DMOV_MPQ8064_HSUART_GSBI6_TX_CHAN
-+#define DMOV_IPQ806X_HSUART_GSBI6_TX_CRCI	DMOV_MPQ8064_HSUART_GSBI6_TX_CRCI
-+
-+#define DMOV_IPQ806X_HSUART_GSBI6_RX_CHAN	DMOV_MPQ8064_HSUART_GSBI6_RX_CHAN
-+#define DMOV_IPQ806X_HSUART_GSBI6_RX_CRCI	DMOV_MPQ8064_HSUART_GSBI6_RX_CRCI
-+
-+/* no client rate control ifc (eg, ram) */
-+#define DMOV_NONE_CRCI        0
-+
-+
-+/* If the CMD_PTR register has CMD_PTR_LIST selected, the data mover
-+ * is going to walk a list of 32bit pointers as described below.  Each
-+ * pointer points to a *array* of dmov_s, etc structs.  The last pointer
-+ * in the list is marked with CMD_PTR_LP.  The last struct in each array
-+ * is marked with CMD_LC (see below).
-+ */
-+#define CMD_PTR_ADDR(addr)  ((addr) >> 3)
-+#define CMD_PTR_LP          (1 << 31) /* last pointer */
-+#define CMD_PTR_PT          (3 << 29) /* ? */
-+
-+/* Single Item Mode */
-+typedef struct {
-+	unsigned cmd;
-+	unsigned src;
-+	unsigned dst;
-+	unsigned len;
-+} dmov_s;
-+
-+/* Scatter/Gather Mode */
-+typedef struct {
-+	unsigned cmd;
-+	unsigned src_dscr;
-+	unsigned dst_dscr;
-+	unsigned _reserved;
-+} dmov_sg;
-+
-+/* Box mode */
-+typedef struct {
-+	uint32_t cmd;
-+	uint32_t src_row_addr;
-+	uint32_t dst_row_addr;
-+	uint32_t src_dst_len;
-+	uint32_t num_rows;
-+	uint32_t row_offset;
-+} dmov_box;
-+
-+/* bits for the cmd field of the above structures */
-+
-+#define CMD_LC      (1 << 31)  /* last command */
-+#define CMD_FR      (1 << 22)  /* force result -- does not work? */
-+#define CMD_OCU     (1 << 21)  /* other channel unblock */
-+#define CMD_OCB     (1 << 20)  /* other channel block */
-+#define CMD_TCB     (1 << 19)  /* ? */
-+#define CMD_DAH     (1 << 18)  /* destination address hold -- does not work?*/
-+#define CMD_SAH     (1 << 17)  /* source address hold -- does not work? */
-+
-+#define CMD_MODE_SINGLE     (0 << 0) /* dmov_s structure used */
-+#define CMD_MODE_SG         (1 << 0) /* untested */
-+#define CMD_MODE_IND_SG     (2 << 0) /* untested */
-+#define CMD_MODE_BOX        (3 << 0) /* untested */
-+
-+#define CMD_DST_SWAP_BYTES  (1 << 14) /* exchange each byte n with byte n+1 */
-+#define CMD_DST_SWAP_SHORTS (1 << 15) /* exchange each short n with short n+1 */
-+#define CMD_DST_SWAP_WORDS  (1 << 16) /* exchange each word n with word n+1 */
-+
-+#define CMD_SRC_SWAP_BYTES  (1 << 11) /* exchange each byte n with byte n+1 */
-+#define CMD_SRC_SWAP_SHORTS (1 << 12) /* exchange each short n with short n+1 */
-+#define CMD_SRC_SWAP_WORDS  (1 << 13) /* exchange each word n with word n+1 */
-+
-+#define CMD_DST_CRCI(n)     (((n) & 15) << 7)
-+#define CMD_SRC_CRCI(n)     (((n) & 15) << 3)
-+
-+#endif
---- /dev/null
-+++ b/drivers/mtd/nand/qcom_nand.c
-@@ -0,0 +1,7455 @@
-+/*
-+ * Copyright (C) 2007 Google, Inc.
-+ * Copyright (c) 2008-2012, The Linux Foundation. All rights reserved.
-+ *
-+ * This software is licensed under the terms of the GNU General Public
-+ * License version 2, as published by the Free Software Foundation, and
-+ * may be copied, distributed, and modified under those terms.
-+ *
-+ * 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/slab.h>
-+#include <linux/kernel.h>
-+#include <linux/module.h>
-+#include <linux/mtd/mtd.h>
-+#include <linux/mtd/nand.h>
-+#include <linux/mtd/partitions.h>
-+#include <linux/platform_device.h>
-+#include <linux/sched.h>
-+#include <linux/dma-mapping.h>
-+#include <linux/io.h>
-+#include <linux/crc16.h>
-+#include <linux/bitrev.h>
-+#include <linux/clk.h>
-+
-+#include <asm/dma.h>
-+#include <asm/mach/flash.h>
-+
-+#include "qcom_adm_dma.h"
-+
-+#include "qcom_nand.h"
-+unsigned long msm_nand_phys = 0;
-+unsigned long msm_nandc01_phys = 0;
-+unsigned long msm_nandc10_phys = 0;
-+unsigned long msm_nandc11_phys = 0;
-+unsigned long ebi2_register_base = 0;
-+static uint32_t dual_nand_ctlr_present;
-+static uint32_t interleave_enable;
-+static uint32_t enable_bch_ecc;
-+static uint32_t boot_layout;
-+
-+
-+#define MSM_NAND_DMA_BUFFER_SIZE SZ_8K
-+#define MSM_NAND_DMA_BUFFER_SLOTS \
-+	(MSM_NAND_DMA_BUFFER_SIZE / (sizeof(((atomic_t *)0)->counter) * 8))
-+
-+#define MSM_NAND_CFG0_RAW_ONFI_IDENTIFIER 0x88000800
-+#define MSM_NAND_CFG0_RAW_ONFI_PARAM_INFO 0x88040000
-+#define MSM_NAND_CFG1_RAW_ONFI_IDENTIFIER 0x0005045d
-+#define MSM_NAND_CFG1_RAW_ONFI_PARAM_INFO 0x0005045d
-+
-+#define ONFI_IDENTIFIER_LENGTH 0x0004
-+#define ONFI_PARAM_INFO_LENGTH 0x0200
-+#define ONFI_PARAM_PAGE_LENGTH 0x0100
-+
-+#define ONFI_PARAMETER_PAGE_SIGNATURE 0x49464E4F
-+
-+#define FLASH_READ_ONFI_IDENTIFIER_COMMAND 0x90
-+#define FLASH_READ_ONFI_IDENTIFIER_ADDRESS 0x20
-+#define FLASH_READ_ONFI_PARAMETERS_COMMAND 0xEC
-+#define FLASH_READ_ONFI_PARAMETERS_ADDRESS 0x00
-+
-+#define UD_SIZE_BYTES_MASK	(0x3FF << 9)
-+#define SPARE_SIZE_BYTES_MASK	(0xF << 23)
-+#define ECC_NUM_DATA_BYTES_MASK	(0x3FF << 16)
-+
-+#define VERBOSE 0
-+
-+struct msm_nand_chip {
-+	struct device *dev;
-+	wait_queue_head_t wait_queue;
-+	atomic_t dma_buffer_busy;
-+	unsigned dma_channel;
-+	uint8_t *dma_buffer;
-+	dma_addr_t dma_addr;
-+	unsigned CFG0, CFG1, CFG0_RAW, CFG1_RAW;
-+	uint32_t ecc_buf_cfg;
-+	uint32_t ecc_bch_cfg;
-+	uint32_t ecc_parity_bytes;
-+	unsigned cw_size;
-+	unsigned int uncorrectable_bit_mask;
-+	unsigned int num_err_mask;
-+};
-+
-+#define CFG1_WIDE_FLASH (1U << 1)
-+
-+/* TODO: move datamover code out */
-+
-+#define SRC_CRCI_NAND_CMD  CMD_SRC_CRCI(DMOV_NAND_CRCI_CMD)
-+#define DST_CRCI_NAND_CMD  CMD_DST_CRCI(DMOV_NAND_CRCI_CMD)
-+#define SRC_CRCI_NAND_DATA CMD_SRC_CRCI(DMOV_NAND_CRCI_DATA)
-+#define DST_CRCI_NAND_DATA CMD_DST_CRCI(DMOV_NAND_CRCI_DATA)
-+
-+#define msm_virt_to_dma(chip, vaddr) \
-+	((chip)->dma_addr + \
-+	 ((uint8_t *)(vaddr) - (chip)->dma_buffer))
-+
-+/**
-+ * msm_nand_oob_64 - oob info for 2KB page
-+ */
-+static struct nand_ecclayout msm_nand_oob_64 = {
-+	.eccbytes	= 40,
-+	.eccpos		= {
-+		0,  1,  2,  3,  4,  5,  6,  7,  8,  9,
-+		10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
-+		20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
-+		46, 47, 48, 49, 50, 51, 52, 53, 54, 55,
-+		},
-+	.oobavail	= 16,
-+	.oobfree	= {
-+		{30, 16},
-+	}
-+};
-+
-+/**
-+ * msm_nand_oob_128 - oob info for 4KB page
-+ */
-+static struct nand_ecclayout msm_nand_oob_128 = {
-+	.eccbytes	= 80,
-+	.eccpos		= {
-+		  0,   1,   2,   3,   4,   5,   6,   7,   8,   9,
-+		 10,  11,  12,  13,  14,  15,  16,  17,  18,  19,
-+		 20,  21,  22,  23,  24,  25,  26,  27,  28,  29,
-+		 30,  31,  32,  33,  34,  35,  36,  37,  38,  39,
-+		 40,  41,  42,  43,  44,  45,  46,  47,  48,  49,
-+		 50,  51,  52,  53,  54,  55,  56,  57,  58,  59,
-+		 60,  61,  62,  63,  64,  65,  66,  67,  68,  69,
-+		102, 103, 104, 105, 106, 107, 108, 109, 110, 111,
-+		},
-+	.oobavail	= 32,
-+	.oobfree	= {
-+		{70, 32},
-+	}
-+};
-+
-+/**
-+ * msm_nand_oob_224 - oob info for 4KB page 8Bit interface
-+ */
-+static struct nand_ecclayout msm_nand_oob_224_x8 = {
-+	.eccbytes	= 104,
-+	.eccpos		= {
-+		  0,   1,   2,   3,   4,   5,   6,   7,   8,   9,  10,  11,  12,
-+		 13,  14,  15,  16,  17,  18,  19,  20,  21,  22,  23,  24,  25,
-+		 26,  27,  28,  29,  30,  31,  32,  33,  34,  35,  36,  37,  38,
-+		 39,  40,  41,  42,  43,  44,  45,  46,  47,  48,  49,  50,  51,
-+		 52,  53,  54,  55,  56,  57,  58,  59,	 60,  61,  62,  63,  64,
-+		 65,  66,  67,  68,  69,  70,  71,  72,  73,  74,  75,  76,  77,
-+		 78,  79,  80,  81,  82,  83,  84,  85,  86,  87,  88,  89,  90,
-+		123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135,
-+		},
-+	.oobavail	= 32,
-+	.oobfree	= {
-+		{91, 32},
-+	}
-+};
-+
-+/**
-+ * msm_nand_oob_224 - oob info for 4KB page 16Bit interface
-+ */
-+static struct nand_ecclayout msm_nand_oob_224_x16 = {
-+	.eccbytes	= 112,
-+	.eccpos		= {
-+	  0,   1,   2,   3,   4,   5,   6,   7,   8,   9,  10,  11,  12,  13,
-+	 14,  15,  16,  17,  18,  19,  20,  21,  22,  23,  24,  25,  26,  27,
-+	 28,  29,  30,  31,  32,  33,  34,  35,  36,  37,  38,  39,  40,  41,
-+	 42,  43,  44,  45,  46,  47,  48,  49,  50,  51,  52,  53,  54,  55,
-+	 56,  57,  58,  59,  60,  61,  62,  63,  64,  65,  66,  67,  68,  69,
-+	 70,  71,  72,  73,  74,  75,  76,  77,  78,  79,  80,  81,  82,  83,
-+	 84,  85,  86,  87,  88,  89,  90,  91,  92,  93,  94,  95,  96,  97,
-+	130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143,
-+	},
-+	.oobavail	= 32,
-+	.oobfree	= {
-+		{98, 32},
-+	}
-+};
-+
-+/**
-+ * msm_nand_oob_256 - oob info for 8KB page
-+ */
-+static struct nand_ecclayout msm_nand_oob_256 = {
-+	.eccbytes 	= 160,
-+	.eccpos 	= {
-+		  0,   1,   2,   3,   4,   5,   6,   7,   8,   9,
-+		 10,  11,  12,  13,  14,  15,  16,  17,  18,  19,
-+		 20,  21,  22,  23,  24,  25,  26,  27,  28,  29,
-+		 30,  31,  32,  33,  34,  35,  36,  37,  38,  39,
-+		 40,  41,  42,  43,  44,  45,  46,  47,  48,  49,
-+		 50,  51,  52,  53,  54,  55,  56,  57,  58,  59,
-+		 60,  61,  62,  63,  64,  65,  66,  67,  68,  69,
-+		 70,  71,  72,  73,  74,  75,  76,  77,  78,  79,
-+		 80,  81,  82,  83,  84,  85,  86,  87,  88,  89,
-+		 90,  91,  92,  93,  94,  96,  97,  98 , 99, 100,
-+		101, 102, 103, 104, 105, 106, 107, 108, 109, 110,
-+		111, 112, 113, 114, 115, 116, 117, 118, 119, 120,
-+		121, 122, 123, 124, 125, 126, 127, 128, 129, 130,
-+		131, 132, 133, 134, 135, 136, 137, 138, 139, 140,
-+		141, 142, 143, 144, 145, 146, 147, 148, 149, 150,
-+		215, 216, 217, 218, 219, 220, 221, 222, 223, 224,
-+		},
-+	.oobavail	= 64,
-+	.oobfree	= {
-+		{151, 64},
-+	}
-+};
-+
-+/**
-+ * msm_onenand_oob_64 - oob info for large (2KB) page
-+ */
-+static struct nand_ecclayout msm_onenand_oob_64 = {
-+	.eccbytes	= 20,
-+	.eccpos		= {
-+		8, 9, 10, 11, 12,
-+		24, 25, 26, 27, 28,
-+		40, 41, 42, 43, 44,
-+		56, 57, 58, 59, 60,
-+		},
-+	.oobavail	= 20,
-+	.oobfree	= {
-+		{2, 3}, {14, 2}, {18, 3}, {30, 2},
-+		{34, 3}, {46, 2}, {50, 3}, {62, 2}
-+	}
-+};
-+
-+static void *msm_nand_get_dma_buffer(struct msm_nand_chip *chip, size_t size)
-+{
-+	unsigned int bitmask, free_bitmask, old_bitmask;
-+	unsigned int need_mask, current_need_mask;
-+	int free_index;
-+
-+	need_mask = (1UL << DIV_ROUND_UP(size, MSM_NAND_DMA_BUFFER_SLOTS)) - 1;
-+	bitmask = atomic_read(&chip->dma_buffer_busy);
-+	free_bitmask = ~bitmask;
-+	while (free_bitmask) {
-+		free_index = __ffs(free_bitmask);
-+		current_need_mask = need_mask << free_index;
-+
-+		if (size + free_index * MSM_NAND_DMA_BUFFER_SLOTS >=
-+						 MSM_NAND_DMA_BUFFER_SIZE)
-+			return NULL;
-+
-+		if ((bitmask & current_need_mask) == 0) {
-+			old_bitmask =
-+				atomic_cmpxchg(&chip->dma_buffer_busy,
-+					       bitmask,
-+					       bitmask | current_need_mask);
-+			if (old_bitmask == bitmask)
-+				return chip->dma_buffer +
-+					free_index * MSM_NAND_DMA_BUFFER_SLOTS;
-+			free_bitmask = 0; /* force return */
-+		}
-+		/* current free range was too small, clear all free bits */
-+		/* below the top busy bit within current_need_mask */
-+		free_bitmask &=
-+			~(~0U >> (32 - fls(bitmask & current_need_mask)));
-+	}
-+
-+	return NULL;
-+}
-+
-+static void msm_nand_release_dma_buffer(struct msm_nand_chip *chip,
-+					void *buffer, size_t size)
-+{
-+	int index;
-+	unsigned int used_mask;
-+
-+	used_mask = (1UL << DIV_ROUND_UP(size, MSM_NAND_DMA_BUFFER_SLOTS)) - 1;
-+	index = ((uint8_t *)buffer - chip->dma_buffer) /
-+		MSM_NAND_DMA_BUFFER_SLOTS;
-+	atomic_sub(used_mask << index, &chip->dma_buffer_busy);
-+
-+	wake_up(&chip->wait_queue);
-+}
-+
-+
-+unsigned flash_rd_reg(struct msm_nand_chip *chip, unsigned addr)
-+{
-+	struct {
-+		dmov_s cmd;
-+		unsigned cmdptr;
-+		unsigned data;
-+	} *dma_buffer;
-+	unsigned rv;
-+
-+	wait_event(chip->wait_queue,
-+		   (dma_buffer = msm_nand_get_dma_buffer(
-+			    chip, sizeof(*dma_buffer))));
-+
-+	dma_buffer->cmd.cmd = CMD_LC | CMD_OCB | CMD_OCU;
-+	dma_buffer->cmd.src = addr;
-+	dma_buffer->cmd.dst = msm_virt_to_dma(chip, &dma_buffer->data);
-+	dma_buffer->cmd.len = 4;
-+
-+	dma_buffer->cmdptr =
-+		(msm_virt_to_dma(chip, &dma_buffer->cmd) >> 3) | CMD_PTR_LP;
-+	dma_buffer->data = 0xeeeeeeee;
-+
-+	mb();
-+	msm_dmov_exec_cmd(
-+		chip->dma_channel, DMOV_CMD_PTR_LIST |
-+		DMOV_CMD_ADDR(msm_virt_to_dma(chip, &dma_buffer->cmdptr)));
-+	mb();
-+
-+	rv = dma_buffer->data;
-+
-+	msm_nand_release_dma_buffer(chip, dma_buffer, sizeof(*dma_buffer));
-+
-+	return rv;
-+}
-+
-+void flash_wr_reg(struct msm_nand_chip *chip, unsigned addr, unsigned val)
-+{
-+	struct {
-+		dmov_s cmd;
-+		unsigned cmdptr;
-+		unsigned data;
-+	} *dma_buffer;
-+
-+	wait_event(chip->wait_queue,
-+		   (dma_buffer = msm_nand_get_dma_buffer(
-+			    chip, sizeof(*dma_buffer))));
-+
-+	dma_buffer->cmd.cmd = CMD_LC | CMD_OCB | CMD_OCU;
-+	dma_buffer->cmd.src = msm_virt_to_dma(chip, &dma_buffer->data);
-+	dma_buffer->cmd.dst = addr;
-+	dma_buffer->cmd.len = 4;
-+
-+	dma_buffer->cmdptr =
-+		(msm_virt_to_dma(chip, &dma_buffer->cmd) >> 3) | CMD_PTR_LP;
-+	dma_buffer->data = val;
-+
-+	mb();
-+	msm_dmov_exec_cmd(
-+		chip->dma_channel, DMOV_CMD_PTR_LIST |
-+		DMOV_CMD_ADDR(msm_virt_to_dma(chip, &dma_buffer->cmdptr)));
-+	mb();
-+
-+	msm_nand_release_dma_buffer(chip, dma_buffer, sizeof(*dma_buffer));
-+}
-+
-+/*
-+ * Allocates a bounce buffer, and stores the buffer address in
-+ * variable pointed to by bounce_buf. bounce_buf should point to a
-+ * stack variable, to avoid SMP issues.
-+ */
-+static int msm_nand_alloc_bounce(void *addr, size_t size,
-+				 enum dma_data_direction dir,
-+				 uint8_t **bounce_buf)
-+{
-+	if (bounce_buf == NULL) {
-+		printk(KERN_ERR "not allocating bounce buffer\n");
-+		return -EINVAL;
-+	}
-+
-+	*bounce_buf = kmalloc(size, GFP_KERNEL | GFP_NOFS | GFP_DMA);
-+	if (*bounce_buf == NULL) {
-+		printk(KERN_ERR "error alloc bounce buffer %zu\n", size);
-+		return -ENOMEM;
-+	}
-+
-+	if (dir == DMA_TO_DEVICE || dir == DMA_BIDIRECTIONAL)
-+		memcpy(*bounce_buf, addr, size);
-+
-+	return 0;
-+}
-+
-+/*
-+ * Maps the user buffer for DMA. If the buffer is vmalloced and the
-+ * buffer crosses a page boundary, then we kmalloc a bounce buffer and
-+ * copy the data into it. The bounce buffer is stored in the variable
-+ * pointed to by bounce_buf, for freeing up later on.  The bounce_buf
-+ * should point to a stack variable, to avoid SMP issues.
-+ */
-+static dma_addr_t
-+msm_nand_dma_map(struct device *dev, void *addr, size_t size,
-+		 enum dma_data_direction dir, uint8_t **bounce_buf)
-+{
-+	int ret;
-+	struct page *page;
-+	unsigned long offset = (unsigned long)addr & ~PAGE_MASK;
-+
-+	if (virt_addr_valid(addr)) {
-+		page = virt_to_page(addr);
-+	} else {
-+		if (size + offset > PAGE_SIZE) {
-+			ret = msm_nand_alloc_bounce(addr, size, dir, bounce_buf);
-+			if (ret < 0)
-+				return DMA_ERROR_CODE;
-+
-+			offset = (unsigned long)*bounce_buf & ~PAGE_MASK;
-+			page = virt_to_page(*bounce_buf);
-+		} else {
-+			page = vmalloc_to_page(addr);
-+		}
-+	}
-+
-+	return dma_map_page(dev, page, offset, size, dir);
-+}
-+
-+static void msm_nand_dma_unmap(struct device *dev, dma_addr_t addr, size_t size,
-+			       enum dma_data_direction dir,
-+			       void *orig_buf, void *bounce_buf)
-+{
-+	dma_unmap_page(dev, addr, size, dir);
-+
-+	if (bounce_buf != NULL) {
-+		if (dir == DMA_FROM_DEVICE || dir == DMA_BIDIRECTIONAL)
-+			memcpy(orig_buf, bounce_buf, size);
-+
-+		kfree(bounce_buf);
-+	}
-+}
-+
-+uint32_t flash_read_id(struct msm_nand_chip *chip)
-+{
-+	struct {
-+		dmov_s cmd[9];
-+		unsigned cmdptr;
-+		unsigned data[7];
-+	} *dma_buffer;
-+	uint32_t rv;
-+	dmov_s *cmd;
-+
-+	wait_event(chip->wait_queue, (dma_buffer = msm_nand_get_dma_buffer
-+				(chip, sizeof(*dma_buffer))));
-+
-+	dma_buffer->data[0] = 0 | 4;
-+	dma_buffer->data[1] = MSM_NAND_CMD_FETCH_ID;
-+	dma_buffer->data[2] = 1;
-+	dma_buffer->data[3] = 0xeeeeeeee;
-+	dma_buffer->data[4] = 0xeeeeeeee;
-+	dma_buffer->data[5] = flash_rd_reg(chip, MSM_NAND_SFLASHC_BURST_CFG);
-+	dma_buffer->data[6] = 0x00000000;
-+	BUILD_BUG_ON(6 != ARRAY_SIZE(dma_buffer->data) - 1);
-+
-+	cmd = dma_buffer->cmd;
-+
-+	cmd->cmd = 0 | CMD_OCB;
-+	cmd->src = msm_virt_to_dma(chip, &dma_buffer->data[6]);
-+	cmd->dst = MSM_NAND_SFLASHC_BURST_CFG;
-+	cmd->len = 4;
-+	cmd++;
-+
-+	cmd->cmd = 0;
-+	cmd->src = msm_virt_to_dma(chip, &dma_buffer->data[6]);
-+	cmd->dst = MSM_NAND_ADDR0;
-+	cmd->len = 4;
-+	cmd++;
-+
-+	cmd->cmd = 0;
-+	cmd->src = msm_virt_to_dma(chip, &dma_buffer->data[6]);
-+	cmd->dst = MSM_NAND_ADDR1;
-+	cmd->len = 4;
-+	cmd++;
-+
-+	cmd->cmd = 0;
-+	cmd->src = msm_virt_to_dma(chip, &dma_buffer->data[0]);
-+	cmd->dst = MSM_NAND_FLASH_CHIP_SELECT;
-+	cmd->len = 4;
-+	cmd++;
-+
-+	cmd->cmd = DST_CRCI_NAND_CMD;
-+	cmd->src = msm_virt_to_dma(chip, &dma_buffer->data[1]);
-+	cmd->dst = MSM_NAND_FLASH_CMD;
-+	cmd->len = 4;
-+	cmd++;
-+
-+	cmd->cmd = 0;
-+	cmd->src = msm_virt_to_dma(chip, &dma_buffer->data[2]);
-+	cmd->dst = MSM_NAND_EXEC_CMD;
-+	cmd->len = 4;
-+	cmd++;
-+
-+	cmd->cmd = SRC_CRCI_NAND_DATA;
-+	cmd->src = MSM_NAND_FLASH_STATUS;
-+	cmd->dst = msm_virt_to_dma(chip, &dma_buffer->data[3]);
-+	cmd->len = 4;
-+	cmd++;
-+
-+	cmd->cmd = 0;
-+	cmd->src = MSM_NAND_READ_ID;
-+	cmd->dst = msm_virt_to_dma(chip, &dma_buffer->data[4]);
-+	cmd->len = 4;
-+	cmd++;
-+
-+	cmd->cmd = CMD_OCU | CMD_LC;
-+	cmd->src = msm_virt_to_dma(chip, &dma_buffer->data[5]);
-+	cmd->dst = MSM_NAND_SFLASHC_BURST_CFG;
-+	cmd->len = 4;
-+	cmd++;
-+
-+	BUILD_BUG_ON(8 != ARRAY_SIZE(dma_buffer->cmd) - 1);
-+
-+	dma_buffer->cmdptr = (msm_virt_to_dma(chip, dma_buffer->cmd) >> 3
-+			) | CMD_PTR_LP;
-+
-+	mb();
-+	msm_dmov_exec_cmd(chip->dma_channel, DMOV_CMD_PTR_LIST |
-+		DMOV_CMD_ADDR(msm_virt_to_dma(chip, &dma_buffer->cmdptr)));
-+	mb();
-+
-+	pr_info("status: %x\n", dma_buffer->data[3]);
-+	pr_info("nandid: %x maker %02x device %02x\n",
-+	       dma_buffer->data[4], dma_buffer->data[4] & 0xff,
-+	       (dma_buffer->data[4] >> 8) & 0xff);
-+	rv = dma_buffer->data[4];
-+	msm_nand_release_dma_buffer(chip, dma_buffer, sizeof(*dma_buffer));
-+	return rv;
-+}
-+
-+struct flash_identification {
-+	uint32_t flash_id;
-+	uint32_t density;
-+	uint32_t widebus;
-+	uint32_t pagesize;
-+	uint32_t blksize;
-+	uint32_t oobsize;
-+	uint32_t ecc_correctability;
-+} supported_flash;
-+
-+uint16_t flash_onfi_crc_check(uint8_t *buffer, uint16_t count)
-+{
-+	int i;
-+	uint16_t result;
-+
-+	for (i = 0; i < count; i++)
-+		buffer[i] = bitrev8(buffer[i]);
-+
-+	result = bitrev16(crc16(bitrev16(0x4f4e), buffer, count));
-+
-+	for (i = 0; i < count; i++)
-+		buffer[i] = bitrev8(buffer[i]);
-+
-+	return result;
-+}
-+
-+static void flash_reset(struct msm_nand_chip *chip)
-+{
-+	struct {
-+		dmov_s cmd[6];
-+		unsigned cmdptr;
-+		struct {
-+			uint32_t cmd;
-+			uint32_t exec;
-+			uint32_t flash_status;
-+			uint32_t sflash_bcfg_orig;
-+			uint32_t sflash_bcfg_mod;
-+			uint32_t chip_select;
-+		} data;
-+	} *dma_buffer;
-+	dmov_s *cmd;
-+	dma_addr_t dma_cmd;
-+	dma_addr_t dma_cmdptr;
-+
-+	wait_event(chip->wait_queue, (dma_buffer = msm_nand_get_dma_buffer
-+				      (chip, sizeof(*dma_buffer))));
-+
-+	dma_buffer->data.sflash_bcfg_orig
-+		= flash_rd_reg(chip, MSM_NAND_SFLASHC_BURST_CFG);
-+	dma_buffer->data.sflash_bcfg_mod = 0x00000000;
-+	dma_buffer->data.chip_select = 4;
-+	dma_buffer->data.cmd = MSM_NAND_CMD_RESET;
-+	dma_buffer->data.exec = 1;
-+	dma_buffer->data.flash_status = 0xeeeeeeee;
-+
-+	cmd = dma_buffer->cmd;
-+
-+	/* Put the Nand ctlr in Async mode and disable SFlash ctlr */
-+	cmd->cmd = 0;
-+	cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.sflash_bcfg_mod);
-+	cmd->dst = MSM_NAND_SFLASHC_BURST_CFG;
-+	cmd->len = 4;
-+	cmd++;
-+
-+	cmd->cmd = 0;
-+	cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.chip_select);
-+	cmd->dst = MSM_NAND_FLASH_CHIP_SELECT;
-+	cmd->len = 4;
-+	cmd++;
-+
-+	/* Block on cmd ready, & write Reset command */
-+	cmd->cmd = DST_CRCI_NAND_CMD;
-+	cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.cmd);
-+	cmd->dst = MSM_NAND_FLASH_CMD;
-+	cmd->len = 4;
-+	cmd++;
-+
-+	cmd->cmd = 0;
-+	cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.exec);
-+	cmd->dst = MSM_NAND_EXEC_CMD;
-+	cmd->len = 4;
-+	cmd++;
-+
-+	cmd->cmd = SRC_CRCI_NAND_DATA;
-+	cmd->src = MSM_NAND_FLASH_STATUS;
-+	cmd->dst = msm_virt_to_dma(chip, &dma_buffer->data.flash_status);
-+	cmd->len = 4;
-+	cmd++;
-+
-+	/* Restore the SFLASH_BURST_CONFIG register */
-+	cmd->cmd = 0;
-+	cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.sflash_bcfg_orig);
-+	cmd->dst = MSM_NAND_SFLASHC_BURST_CFG;
-+	cmd->len = 4;
-+	cmd++;
-+
-+	BUILD_BUG_ON(6 != ARRAY_SIZE(dma_buffer->cmd));
-+
-+	dma_buffer->cmd[0].cmd |= CMD_OCB;
-+	cmd[-1].cmd |= CMD_OCU | CMD_LC;
-+
-+	dma_cmd = msm_virt_to_dma(chip, dma_buffer->cmd);
-+	dma_buffer->cmdptr = (dma_cmd >> 3) | CMD_PTR_LP;
-+
-+	mb();
-+	dma_cmdptr = msm_virt_to_dma(chip, &dma_buffer->cmdptr);
-+	msm_dmov_exec_cmd(chip->dma_channel,
-+			  DMOV_CMD_PTR_LIST | DMOV_CMD_ADDR(dma_cmdptr));
-+	mb();
-+
-+	msm_nand_release_dma_buffer(chip, dma_buffer, sizeof(*dma_buffer));
-+}
-+
-+uint32_t flash_onfi_probe(struct msm_nand_chip *chip)
-+{
-+
-+
-+        	struct onfi_param_page {
-+		uint32_t parameter_page_signature;
-+		uint16_t revision_number;
-+		uint16_t features_supported;
-+		uint16_t optional_commands_supported;
-+		uint8_t  reserved0[22];
-+		uint8_t  device_manufacturer[12];
-+		uint8_t  device_model[20];
-+		uint8_t  jedec_manufacturer_id;
-+		uint16_t date_code;
-+		uint8_t  reserved1[13];
-+		uint32_t number_of_data_bytes_per_page;
-+		uint16_t number_of_spare_bytes_per_page;
-+		uint32_t number_of_data_bytes_per_partial_page;
-+		uint16_t number_of_spare_bytes_per_partial_page;
-+		uint32_t number_of_pages_per_block;
-+		uint32_t number_of_blocks_per_logical_unit;
-+		uint8_t  number_of_logical_units;
-+		uint8_t  number_of_address_cycles;
-+		uint8_t  number_of_bits_per_cell;
-+		uint16_t maximum_bad_blocks_per_logical_unit;
-+		uint16_t block_endurance;
-+		uint8_t  guaranteed_valid_begin_blocks;
-+		uint16_t guaranteed_valid_begin_blocks_endurance;
-+		uint8_t  number_of_programs_per_page;
-+		uint8_t  partial_program_attributes;
-+		uint8_t  number_of_bits_ecc_correctability;
-+		uint8_t  number_of_interleaved_address_bits;
-+		uint8_t  interleaved_operation_attributes;
-+		uint8_t  reserved2[13];
-+		uint8_t  io_pin_capacitance;
-+		uint16_t timing_mode_support;
-+		uint16_t program_cache_timing_mode_support;
-+		uint16_t maximum_page_programming_time;
-+		uint16_t maximum_block_erase_time;
-+		uint16_t maximum_page_read_time;
-+		uint16_t maximum_change_column_setup_time;
-+		uint8_t  reserved3[23];
-+		uint16_t vendor_specific_revision_number;
-+		uint8_t  vendor_specific[88];
-+		uint16_t integrity_crc;
-+
-+	} __attribute__((__packed__));
-+
-+	struct onfi_param_page *onfi_param_page_ptr;
-+	uint8_t *onfi_identifier_buf = NULL;
-+	uint8_t *onfi_param_info_buf = NULL;
-+
-+	struct {
-+		dmov_s cmd[12];
-+		unsigned cmdptr;
-+		struct {
-+			uint32_t cmd;
-+			uint32_t addr0;
-+			uint32_t addr1;
-+			uint32_t cfg0;
-+			uint32_t cfg1;
-+			uint32_t exec;
-+			uint32_t flash_status;
-+			uint32_t devcmd1_orig;
-+			uint32_t devcmdvld_orig;
-+			uint32_t devcmd1_mod;
-+			uint32_t devcmdvld_mod;
-+			uint32_t sflash_bcfg_orig;
-+			uint32_t sflash_bcfg_mod;
-+			uint32_t chip_select;
-+		} data;
-+	} *dma_buffer;
-+	dmov_s *cmd;
-+
-+	unsigned page_address = 0;
-+	int err = 0;
-+	dma_addr_t dma_addr_param_info = 0;
-+	dma_addr_t dma_addr_identifier = 0;
-+	unsigned cmd_set_count = 2;
-+	unsigned crc_chk_count = 0;
-+
-+	/*if (msm_nand_data.nr_parts) {
-+		page_address = ((msm_nand_data.parts[0]).offset << 6);
-+	} else {
-+		pr_err("flash_onfi_probe: "
-+				"No partition info available\n");
-+		err = -EIO;
-+		return err;
-+	}*/
-+
-+	wait_event(chip->wait_queue, (onfi_identifier_buf =
-+		msm_nand_get_dma_buffer(chip, ONFI_IDENTIFIER_LENGTH)));
-+	dma_addr_identifier = msm_virt_to_dma(chip, onfi_identifier_buf);
-+
-+	wait_event(chip->wait_queue, (onfi_param_info_buf =
-+		msm_nand_get_dma_buffer(chip, ONFI_PARAM_INFO_LENGTH)));
-+	dma_addr_param_info = msm_virt_to_dma(chip, onfi_param_info_buf);
-+
-+	wait_event(chip->wait_queue, (dma_buffer = msm_nand_get_dma_buffer
-+				(chip, sizeof(*dma_buffer))));
-+
-+	dma_buffer->data.sflash_bcfg_orig = flash_rd_reg
-+				(chip, MSM_NAND_SFLASHC_BURST_CFG);
-+	dma_buffer->data.devcmd1_orig = flash_rd_reg(chip, MSM_NAND_DEV_CMD1);
-+	dma_buffer->data.devcmdvld_orig = flash_rd_reg(chip,
-+						 MSM_NAND_DEV_CMD_VLD);
-+	dma_buffer->data.chip_select = 4;
-+
-+	while (cmd_set_count-- > 0) {
-+		cmd = dma_buffer->cmd;
-+
-+		dma_buffer->data.devcmd1_mod = (dma_buffer->data.devcmd1_orig &
-+				0xFFFFFF00) | (cmd_set_count
-+				? FLASH_READ_ONFI_IDENTIFIER_COMMAND
-+				: FLASH_READ_ONFI_PARAMETERS_COMMAND);
-+		dma_buffer->data.cmd = MSM_NAND_CMD_PAGE_READ;
-+		dma_buffer->data.addr0 = (page_address << 16) | (cmd_set_count
-+				? FLASH_READ_ONFI_IDENTIFIER_ADDRESS
-+				: FLASH_READ_ONFI_PARAMETERS_ADDRESS);
-+		dma_buffer->data.addr1 = (page_address >> 16) & 0xFF;
-+		dma_buffer->data.cfg0 =	(cmd_set_count
-+				? MSM_NAND_CFG0_RAW_ONFI_IDENTIFIER
-+				: MSM_NAND_CFG0_RAW_ONFI_PARAM_INFO);
-+		dma_buffer->data.cfg1 =	(cmd_set_count
-+				? MSM_NAND_CFG1_RAW_ONFI_IDENTIFIER
-+				: MSM_NAND_CFG1_RAW_ONFI_PARAM_INFO);
-+		dma_buffer->data.sflash_bcfg_mod = 0x00000000;
-+		dma_buffer->data.devcmdvld_mod = (dma_buffer->
-+				data.devcmdvld_orig & 0xFFFFFFFE);
-+		dma_buffer->data.exec = 1;
-+		dma_buffer->data.flash_status = 0xeeeeeeee;
-+
-+		/* Put the Nand ctlr in Async mode and disable SFlash ctlr */
-+		cmd->cmd = 0;
-+		cmd->src = msm_virt_to_dma(chip,
-+				&dma_buffer->data.sflash_bcfg_mod);
-+		cmd->dst = MSM_NAND_SFLASHC_BURST_CFG;
-+		cmd->len = 4;
-+		cmd++;
-+
-+		cmd->cmd = 0;
-+		cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.chip_select);
-+		cmd->dst = MSM_NAND_FLASH_CHIP_SELECT;
-+		cmd->len = 4;
-+		cmd++;
-+
-+		/* Block on cmd ready, & write CMD,ADDR0,ADDR1,CHIPSEL regs */
-+		cmd->cmd = DST_CRCI_NAND_CMD;
-+		cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.cmd);
-+		cmd->dst = MSM_NAND_FLASH_CMD;
-+		cmd->len = 12;
-+		cmd++;
-+
-+		/* Configure the CFG0 and CFG1 registers */
-+		cmd->cmd = 0;
-+		cmd->src = msm_virt_to_dma(chip,
-+				&dma_buffer->data.cfg0);
-+		cmd->dst = MSM_NAND_DEV0_CFG0;
-+		cmd->len = 8;
-+		cmd++;
-+
-+		/* Configure the DEV_CMD_VLD register */
-+		cmd->cmd = 0;
-+		cmd->src = msm_virt_to_dma(chip,
-+				&dma_buffer->data.devcmdvld_mod);
-+		cmd->dst = MSM_NAND_DEV_CMD_VLD;
-+		cmd->len = 4;
-+		cmd++;
-+
-+		/* Configure the DEV_CMD1 register */
-+		cmd->cmd = 0;
-+		cmd->src = msm_virt_to_dma(chip,
-+				&dma_buffer->data.devcmd1_mod);
-+		cmd->dst = MSM_NAND_DEV_CMD1;
-+		cmd->len = 4;
-+		cmd++;
-+
-+		/* Kick the execute command */
-+		cmd->cmd = 0;
-+		cmd->src = msm_virt_to_dma(chip,
-+				&dma_buffer->data.exec);
-+		cmd->dst = MSM_NAND_EXEC_CMD;
-+		cmd->len = 4;
-+		cmd++;
-+
-+		/* Block on data ready, and read the two status registers */
-+		cmd->cmd = SRC_CRCI_NAND_DATA;
-+		cmd->src = MSM_NAND_FLASH_STATUS;
-+		cmd->dst = msm_virt_to_dma(chip,
-+				&dma_buffer->data.flash_status);
-+		cmd->len = 4;
-+		cmd++;
-+
-+		/* Read data block - valid only if status says success */
-+		cmd->cmd = 0;
-+		cmd->src = MSM_NAND_FLASH_BUFFER;
-+		cmd->dst = (cmd_set_count ? dma_addr_identifier :
-+				dma_addr_param_info);
-+		cmd->len = (cmd_set_count ? ONFI_IDENTIFIER_LENGTH :
-+				ONFI_PARAM_INFO_LENGTH);
-+		cmd++;
-+
-+		/* Restore the DEV_CMD1 register */
-+		cmd->cmd = 0 ;
-+		cmd->src = msm_virt_to_dma(chip,
-+				&dma_buffer->data.devcmd1_orig);
-+		cmd->dst = MSM_NAND_DEV_CMD1;
-+		cmd->len = 4;
-+		cmd++;
-+
-+		/* Restore the DEV_CMD_VLD register */
-+		cmd->cmd = 0;
-+		cmd->src = msm_virt_to_dma(chip,
-+				&dma_buffer->data.devcmdvld_orig);
-+		cmd->dst = MSM_NAND_DEV_CMD_VLD;
-+		cmd->len = 4;
-+		cmd++;
-+
-+		/* Restore the SFLASH_BURST_CONFIG register */
-+		cmd->cmd = 0;
-+		cmd->src = msm_virt_to_dma(chip,
-+				&dma_buffer->data.sflash_bcfg_orig);
-+		cmd->dst = MSM_NAND_SFLASHC_BURST_CFG;
-+		cmd->len = 4;
-+		cmd++;
-+
-+		BUILD_BUG_ON(12 != ARRAY_SIZE(dma_buffer->cmd));
-+		BUG_ON(cmd - dma_buffer->cmd > ARRAY_SIZE(dma_buffer->cmd));
-+		dma_buffer->cmd[0].cmd |= CMD_OCB;
-+		cmd[-1].cmd |= CMD_OCU | CMD_LC;
-+
-+		dma_buffer->cmdptr = (msm_virt_to_dma(chip, dma_buffer->cmd)
-+				>> 3) | CMD_PTR_LP;
-+
-+		mb();
-+		msm_dmov_exec_cmd(chip->dma_channel,
-+			DMOV_CMD_PTR_LIST | DMOV_CMD_ADDR(msm_virt_to_dma(chip,
-+			&dma_buffer->cmdptr)));
-+		mb();
-+
-+		/* Check for errors, protection violations etc */
-+		if (dma_buffer->data.flash_status & 0x110) {
-+			pr_info("MPU/OP error (0x%x) during "
-+					"ONFI probe\n",
-+					dma_buffer->data.flash_status);
-+			err = -EIO;
-+			break;
-+		}
-+
-+		if (cmd_set_count) {
-+			onfi_param_page_ptr = (struct onfi_param_page *)
-+				(&(onfi_identifier_buf[0]));
-+			if (onfi_param_page_ptr->parameter_page_signature !=
-+					ONFI_PARAMETER_PAGE_SIGNATURE) {
-+				pr_info("ONFI probe : Found a non"
-+						"ONFI Compliant device \n");
-+				err = -EIO;
-+				break;
-+			}
-+		} else {
-+			for (crc_chk_count = 0; crc_chk_count <
-+					ONFI_PARAM_INFO_LENGTH
-+					/ ONFI_PARAM_PAGE_LENGTH;
-+					crc_chk_count++) {
-+				onfi_param_page_ptr =
-+					(struct onfi_param_page *)
-+					(&(onfi_param_info_buf
-+					[ONFI_PARAM_PAGE_LENGTH *
-+					crc_chk_count]));
-+				if (flash_onfi_crc_check(
-+					(uint8_t *)onfi_param_page_ptr,
-+					ONFI_PARAM_PAGE_LENGTH - 2) ==
-+					onfi_param_page_ptr->integrity_crc) {
-+					break;
-+				}
-+			}
-+			if (crc_chk_count >= ONFI_PARAM_INFO_LENGTH
-+					/ ONFI_PARAM_PAGE_LENGTH) {
-+				pr_info("ONFI probe : CRC Check "
-+						"failed on ONFI Parameter "
-+						"data \n");
-+				err = -EIO;
-+				break;
-+			} else {
-+				supported_flash.flash_id =
-+					flash_read_id(chip);
-+				supported_flash.widebus  =
-+					onfi_param_page_ptr->
-+					features_supported & 0x01;
-+				supported_flash.pagesize =
-+					onfi_param_page_ptr->
-+					number_of_data_bytes_per_page;
-+				supported_flash.blksize  =
-+					onfi_param_page_ptr->
-+					number_of_pages_per_block *
-+					supported_flash.pagesize;
-+				supported_flash.oobsize  =
-+					onfi_param_page_ptr->
-+					number_of_spare_bytes_per_page;
-+				supported_flash.density  =
-+					onfi_param_page_ptr->
-+					number_of_blocks_per_logical_unit
-+					* supported_flash.blksize;
-+				supported_flash.ecc_correctability =
-+					onfi_param_page_ptr->
-+					number_of_bits_ecc_correctability;
-+
-+				pr_info("ONFI probe : Found an ONFI "
-+					"compliant device %s\n",
-+					onfi_param_page_ptr->device_model);
-+
-+				/* Temporary hack for MT29F4G08ABC device.
-+				 * Since the device is not properly adhering
-+				 * to ONFi specification it is reporting
-+				 * as 16 bit device though it is 8 bit device!!!
-+				 */
-+				if (!strncmp(onfi_param_page_ptr->device_model,
-+					"MT29F4G08ABC", 12))
-+					supported_flash.widebus  = 0;
-+			}
-+		}
-+	}
-+
-+	msm_nand_release_dma_buffer(chip, dma_buffer, sizeof(*dma_buffer));
-+	msm_nand_release_dma_buffer(chip, onfi_param_info_buf,
-+			ONFI_PARAM_INFO_LENGTH);
-+	msm_nand_release_dma_buffer(chip, onfi_identifier_buf,
-+			ONFI_IDENTIFIER_LENGTH);
-+
-+	return err;
-+}
-+
-+static int msm_nand_read_oob(struct mtd_info *mtd, loff_t from,
-+			     struct mtd_oob_ops *ops)
-+{
-+	struct msm_nand_chip *chip = mtd->priv;
-+
-+	struct {
-+		dmov_s cmd[8 * 5 + 2];
-+		unsigned cmdptr;
-+		struct {
-+			uint32_t cmd;
-+			uint32_t addr0;
-+			uint32_t addr1;
-+			uint32_t chipsel;
-+			uint32_t cfg0;
-+			uint32_t cfg1;
-+			uint32_t eccbchcfg;
-+			uint32_t exec;
-+			uint32_t ecccfg;
-+			struct {
-+				uint32_t flash_status;
-+				uint32_t buffer_status;
-+			} result[8];
-+		} data;
-+	} *dma_buffer;
-+	dmov_s *cmd;
-+	unsigned n;
-+	unsigned page = 0;
-+	uint32_t oob_len;
-+	uint32_t sectordatasize;
-+	uint32_t sectoroobsize;
-+	int err, pageerr, rawerr;
-+	dma_addr_t data_dma_addr = 0;
-+	dma_addr_t oob_dma_addr = 0;
-+	dma_addr_t data_dma_addr_curr = 0;
-+	dma_addr_t oob_dma_addr_curr = 0;
-+	uint8_t *dat_bounce_buf = NULL;
-+	uint8_t *oob_bounce_buf = NULL;
-+	uint32_t oob_col = 0;
-+	unsigned page_count;
-+	unsigned pages_read = 0;
-+	unsigned start_sector = 0;
-+	uint32_t ecc_errors;
-+	uint32_t total_ecc_errors = 0;
-+	unsigned cwperpage;
-+#if VERBOSE
-+	pr_info("================================================="
-+			"================\n");
-+	pr_info("%s:\nfrom 0x%llx mode %d\ndatbuf 0x%p datlen 0x%x"
-+			"\noobbuf 0x%p ooblen 0x%x\n",
-+			__func__, from, ops->mode, ops->datbuf, ops->len,
-+			ops->oobbuf, ops->ooblen);
-+#endif
-+
-+	if (mtd->writesize == 2048)
-+		page = from >> 11;
-+
-+	if (mtd->writesize == 4096)
-+		page = from >> 12;
-+
-+	oob_len = ops->ooblen;
-+	cwperpage = (mtd->writesize >> 9);
-+
-+	if (from & (mtd->writesize - 1)) {
-+		pr_err("%s: unsupported from, 0x%llx\n",
-+		       __func__, from);
-+		return -EINVAL;
-+	}
-+	if (ops->mode != MTD_OPS_RAW) {
-+		if (ops->datbuf != NULL && (ops->len % mtd->writesize) != 0) {
-+			/* when ops->datbuf is NULL, ops->len can be ooblen */
-+			pr_err("%s: unsupported ops->len, %d\n",
-+			       __func__, ops->len);
-+			return -EINVAL;
-+		}
-+	} else {
-+		if (ops->datbuf != NULL &&
-+			(ops->len % (mtd->writesize + mtd->oobsize)) != 0) {
-+			pr_err("%s: unsupported ops->len,"
-+				" %d for MTD_OPS_RAW\n", __func__, ops->len);
-+			return -EINVAL;
-+		}
-+	}
-+
-+	if (ops->mode != MTD_OPS_RAW && ops->ooblen != 0 && ops->ooboffs != 0) {
-+		pr_err("%s: unsupported ops->ooboffs, %d\n",
-+		       __func__, ops->ooboffs);
-+		return -EINVAL;
-+	}
-+
-+	if (ops->oobbuf && !ops->datbuf && ops->mode == MTD_OPS_AUTO_OOB)
-+		start_sector = cwperpage - 1;
-+
-+	if (ops->oobbuf && !ops->datbuf) {
-+		page_count = ops->ooblen / ((ops->mode == MTD_OPS_AUTO_OOB) ?
-+			mtd->oobavail : mtd->oobsize);
-+		if ((page_count == 0) && (ops->ooblen))
-+			page_count = 1;
-+	} else if (ops->mode != MTD_OPS_RAW)
-+		page_count = ops->len / mtd->writesize;
-+	else
-+		page_count = ops->len / (mtd->writesize + mtd->oobsize);
-+
-+	if (ops->datbuf) {
-+		data_dma_addr_curr = data_dma_addr =
-+			msm_nand_dma_map(chip->dev, ops->datbuf, ops->len,
-+					 DMA_FROM_DEVICE, &dat_bounce_buf);
-+		if (dma_mapping_error(chip->dev, data_dma_addr)) {
-+			pr_err("msm_nand_read_oob: failed to get dma addr "
-+			       "for %p\n", ops->datbuf);
-+			return -EIO;
-+		}
-+	}
-+	if (ops->oobbuf) {
-+		memset(ops->oobbuf, 0xff, ops->ooblen);
-+		oob_dma_addr_curr = oob_dma_addr =
-+			msm_nand_dma_map(chip->dev, ops->oobbuf,
-+					 ops->ooblen, DMA_BIDIRECTIONAL,
-+					 &oob_bounce_buf);
-+		if (dma_mapping_error(chip->dev, oob_dma_addr)) {
-+			pr_err("msm_nand_read_oob: failed to get dma addr "
-+			       "for %p\n", ops->oobbuf);
-+			err = -EIO;
-+			goto err_dma_map_oobbuf_failed;
-+		}
-+	}
-+
-+	wait_event(chip->wait_queue,
-+		   (dma_buffer = msm_nand_get_dma_buffer(
-+			    chip, sizeof(*dma_buffer))));
-+
-+	oob_col = start_sector * chip->cw_size;
-+	if (chip->CFG1 & CFG1_WIDE_FLASH)
-+		oob_col >>= 1;
-+
-+	err = 0;
-+	while (page_count-- > 0) {
-+		cmd = dma_buffer->cmd;
-+
-+		/* CMD / ADDR0 / ADDR1 / CHIPSEL program values */
-+		if (ops->mode != MTD_OPS_RAW) {
-+			dma_buffer->data.cmd = MSM_NAND_CMD_PAGE_READ_ECC;
-+			dma_buffer->data.cfg0 =
-+			(chip->CFG0 & ~(7U << 6))
-+				| (((cwperpage-1) - start_sector) << 6);
-+			dma_buffer->data.cfg1 = chip->CFG1;
-+			if (enable_bch_ecc)
-+				dma_buffer->data.eccbchcfg = chip->ecc_bch_cfg;
-+		} else {
-+			dma_buffer->data.cmd = MSM_NAND_CMD_PAGE_READ;
-+			dma_buffer->data.cfg0 = (chip->CFG0_RAW
-+					& ~(7U << 6)) | ((cwperpage-1) << 6);
-+			dma_buffer->data.cfg1 = chip->CFG1_RAW |
-+					(chip->CFG1 & CFG1_WIDE_FLASH);
-+		}
-+
-+		dma_buffer->data.addr0 = (page << 16) | oob_col;
-+		dma_buffer->data.addr1 = (page >> 16) & 0xff;
-+		/* chipsel_0 + enable DM interface */
-+		dma_buffer->data.chipsel = 0 | 4;
-+
-+
-+		/* GO bit for the EXEC register */
-+		dma_buffer->data.exec = 1;
-+
-+
-+		BUILD_BUG_ON(8 != ARRAY_SIZE(dma_buffer->data.result));
-+
-+		for (n = start_sector; n < cwperpage; n++) {
-+			/* flash + buffer status return words */
-+			dma_buffer->data.result[n].flash_status = 0xeeeeeeee;
-+			dma_buffer->data.result[n].buffer_status = 0xeeeeeeee;
-+
-+			/* block on cmd ready, then
-+			 * write CMD / ADDR0 / ADDR1 / CHIPSEL
-+			 * regs in a burst
-+			 */
-+			cmd->cmd = DST_CRCI_NAND_CMD;
-+			cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.cmd);
-+			cmd->dst = MSM_NAND_FLASH_CMD;
-+			if (n == start_sector)
-+				cmd->len = 16;
-+			else
-+				cmd->len = 4;
-+			cmd++;
-+
-+			if (n == start_sector) {
-+				cmd->cmd = 0;
-+				cmd->src = msm_virt_to_dma(chip,
-+							&dma_buffer->data.cfg0);
-+				cmd->dst = MSM_NAND_DEV0_CFG0;
-+				if (enable_bch_ecc)
-+					cmd->len = 12;
-+				else
-+					cmd->len = 8;
-+				cmd++;
-+
-+				dma_buffer->data.ecccfg = chip->ecc_buf_cfg;
-+				cmd->cmd = 0;
-+				cmd->src = msm_virt_to_dma(chip,
-+						&dma_buffer->data.ecccfg);
-+				cmd->dst = MSM_NAND_EBI2_ECC_BUF_CFG;
-+				cmd->len = 4;
-+				cmd++;
-+			}
-+
-+			/* kick the execute register */
-+			cmd->cmd = 0;
-+			cmd->src =
-+				msm_virt_to_dma(chip, &dma_buffer->data.exec);
-+			cmd->dst = MSM_NAND_EXEC_CMD;
-+			cmd->len = 4;
-+			cmd++;
-+
-+			/* block on data ready, then
-+			 * read the status register
-+			 */
-+			cmd->cmd = SRC_CRCI_NAND_DATA;
-+			cmd->src = MSM_NAND_FLASH_STATUS;
-+			cmd->dst = msm_virt_to_dma(chip,
-+						   &dma_buffer->data.result[n]);
-+			/* MSM_NAND_FLASH_STATUS + MSM_NAND_BUFFER_STATUS */
-+			cmd->len = 8;
-+			cmd++;
-+
-+			/* read data block
-+			 * (only valid if status says success)
-+			 */
-+			if (ops->datbuf) {
-+				if (ops->mode != MTD_OPS_RAW) {
-+					if (!boot_layout)
-+						sectordatasize = (n < (cwperpage - 1))
-+							? 516 : (512 - ((cwperpage - 1) << 2));
-+					else
-+						sectordatasize = 512;
-+				} else {
-+					sectordatasize = chip->cw_size;
-+				}
-+
-+				cmd->cmd = 0;
-+				cmd->src = MSM_NAND_FLASH_BUFFER;
-+				cmd->dst = data_dma_addr_curr;
-+				data_dma_addr_curr += sectordatasize;
-+				cmd->len = sectordatasize;
-+				cmd++;
-+			}
-+
-+			if (ops->oobbuf && (n == (cwperpage - 1)
-+			     || ops->mode != MTD_OPS_AUTO_OOB)) {
-+				cmd->cmd = 0;
-+				if (n == (cwperpage - 1)) {
-+					cmd->src = MSM_NAND_FLASH_BUFFER +
-+						(512 - ((cwperpage - 1) << 2));
-+					sectoroobsize = (cwperpage << 2);
-+					if (ops->mode != MTD_OPS_AUTO_OOB)
-+						sectoroobsize +=
-+							chip->ecc_parity_bytes;
-+				} else {
-+					cmd->src = MSM_NAND_FLASH_BUFFER + 516;
-+					sectoroobsize = chip->ecc_parity_bytes;
-+				}
-+
-+				cmd->dst = oob_dma_addr_curr;
-+				if (sectoroobsize < oob_len)
-+					cmd->len = sectoroobsize;
-+				else
-+					cmd->len = oob_len;
-+				oob_dma_addr_curr += cmd->len;
-+				oob_len -= cmd->len;
-+				if (cmd->len > 0)
-+					cmd++;
-+			}
-+		}
-+
-+		BUILD_BUG_ON(8 * 5 + 2 != ARRAY_SIZE(dma_buffer->cmd));
-+		BUG_ON(cmd - dma_buffer->cmd > ARRAY_SIZE(dma_buffer->cmd));
-+		dma_buffer->cmd[0].cmd |= CMD_OCB;
-+		cmd[-1].cmd |= CMD_OCU | CMD_LC;
-+
-+		dma_buffer->cmdptr =
-+			(msm_virt_to_dma(chip, dma_buffer->cmd) >> 3)
-+			| CMD_PTR_LP;
-+
-+		mb();
-+		msm_dmov_exec_cmd(chip->dma_channel,
-+			DMOV_CMD_PTR_LIST | DMOV_CMD_ADDR(msm_virt_to_dma(chip,
-+			&dma_buffer->cmdptr)));
-+		mb();
-+
-+		/* if any of the writes failed (0x10), or there
-+		 * was a protection violation (0x100), we lose
-+		 */
-+		pageerr = rawerr = 0;
-+		for (n = start_sector; n < cwperpage; n++) {
-+			if (dma_buffer->data.result[n].flash_status & 0x110) {
-+				rawerr = -EIO;
-+				break;
-+			}
-+		}
-+		if (rawerr) {
-+			if (ops->datbuf && ops->mode != MTD_OPS_RAW) {
-+				uint8_t *datbuf = ops->datbuf +
-+					pages_read * mtd->writesize;
-+
-+				dma_sync_single_for_cpu(chip->dev,
-+					data_dma_addr_curr-mtd->writesize,
-+					mtd->writesize, DMA_BIDIRECTIONAL);
-+
-+				for (n = 0; n < mtd->writesize; n++) {
-+					/* empty blocks read 0x54 at
-+					 * these offsets
-+					 */
-+					if ((n % 516 == 3 || n % 516 == 175)
-+							&& datbuf[n] == 0x54)
-+						datbuf[n] = 0xff;
-+					if (datbuf[n] != 0xff) {
-+						pageerr = rawerr;
-+						break;
-+					}
-+				}
-+
-+				dma_sync_single_for_device(chip->dev,
-+					data_dma_addr_curr-mtd->writesize,
-+					mtd->writesize, DMA_BIDIRECTIONAL);
-+
-+			}
-+			if (ops->oobbuf) {
-+				dma_sync_single_for_cpu(chip->dev,
-+				oob_dma_addr_curr - (ops->ooblen - oob_len),
-+				ops->ooblen - oob_len, DMA_BIDIRECTIONAL);
-+
-+				for (n = 0; n < ops->ooblen; n++) {
-+					if (ops->oobbuf[n] != 0xff) {
-+						pageerr = rawerr;
-+						break;
-+					}
-+				}
-+
-+				dma_sync_single_for_device(chip->dev,
-+				oob_dma_addr_curr - (ops->ooblen - oob_len),
-+				ops->ooblen - oob_len, DMA_BIDIRECTIONAL);
-+			}
-+		}
-+		if (pageerr) {
-+			for (n = start_sector; n < cwperpage; n++) {
-+				if (dma_buffer->data.result[n].buffer_status &
-+					chip->uncorrectable_bit_mask) {
-+					/* not thread safe */
-+					mtd->ecc_stats.failed++;
-+					pageerr = -EBADMSG;
-+					break;
-+				}
-+			}
-+		}
-+		if (!rawerr) { /* check for corretable errors */
-+			for (n = start_sector; n < cwperpage; n++) {
-+				ecc_errors =
-+				(dma_buffer->data.result[n].buffer_status
-+				 & chip->num_err_mask);
-+				if (ecc_errors) {
-+					total_ecc_errors += ecc_errors;
-+					/* not thread safe */
-+					mtd->ecc_stats.corrected += ecc_errors;
-+					if (ecc_errors > 1)
-+						pageerr = -EUCLEAN;
-+				}
-+			}
-+		}
-+		if (pageerr && (pageerr != -EUCLEAN || err == 0))
-+			err = pageerr;
-+
-+#if VERBOSE
-+		if (rawerr && !pageerr) {
-+			pr_err("msm_nand_read_oob %llx %x %x empty page\n",
-+			       (loff_t)page * mtd->writesize, ops->len,
-+			       ops->ooblen);
-+		} else {
-+			for (n = start_sector; n < cwperpage; n++)
-+				pr_info("flash_status[%d] = %x,\
-+				buffr_status[%d] = %x\n",
-+				n, dma_buffer->data.result[n].flash_status,
-+				n, dma_buffer->data.result[n].buffer_status);
-+		}
-+#endif
-+		if (err && err != -EUCLEAN && err != -EBADMSG)
-+			break;
-+		pages_read++;
-+		page++;
-+	}
-+	msm_nand_release_dma_buffer(chip, dma_buffer, sizeof(*dma_buffer));
-+
-+	if (ops->oobbuf) {
-+		msm_nand_dma_unmap(chip->dev, oob_dma_addr,
-+				   ops->ooblen, DMA_FROM_DEVICE,
-+				   ops->oobbuf, oob_bounce_buf);
-+	}
-+err_dma_map_oobbuf_failed:
-+	if (ops->datbuf) {
-+		msm_nand_dma_unmap(chip->dev, data_dma_addr,
-+				   ops->len, DMA_BIDIRECTIONAL,
-+				   ops->datbuf, dat_bounce_buf);
-+	}
-+
-+	if (ops->mode != MTD_OPS_RAW)
-+		ops->retlen = mtd->writesize * pages_read;
-+	else
-+		ops->retlen = (mtd->writesize +  mtd->oobsize) *
-+							pages_read;
-+	ops->oobretlen = ops->ooblen - oob_len;
-+	if (err)
-+		pr_err("msm_nand_read_oob %llx %x %x failed %d, corrected %d\n",
-+		       from, ops->datbuf ? ops->len : 0, ops->ooblen, err,
-+		       total_ecc_errors);
-+#if VERBOSE
-+	pr_info("\n%s: ret %d, retlen %d oobretlen %d\n",
-+			__func__, err, ops->retlen, ops->oobretlen);
-+
-+	pr_info("==================================================="
-+			"==============\n");
-+#endif
-+	return err;
-+}
-+
-+static int msm_nand_read_oob_dualnandc(struct mtd_info *mtd, loff_t from,
-+			struct mtd_oob_ops *ops)
-+{
-+	struct msm_nand_chip *chip = mtd->priv;
-+
-+	struct {
-+		dmov_s cmd[16 * 6 + 20];
-+		unsigned cmdptr;
-+		struct {
-+			uint32_t cmd;
-+			uint32_t nandc01_addr0;
-+			uint32_t nandc10_addr0;
-+			uint32_t nandc11_addr1;
-+			uint32_t chipsel_cs0;
-+			uint32_t chipsel_cs1;
-+			uint32_t cfg0;
-+			uint32_t cfg1;
-+			uint32_t eccbchcfg;
-+			uint32_t exec;
-+			uint32_t ecccfg;
-+			uint32_t ebi2_chip_select_cfg0;
-+			uint32_t adm_mux_data_ack_req_nc01;
-+			uint32_t adm_mux_cmd_ack_req_nc01;
-+			uint32_t adm_mux_data_ack_req_nc10;
-+			uint32_t adm_mux_cmd_ack_req_nc10;
-+			uint32_t adm_default_mux;
-+			uint32_t default_ebi2_chip_select_cfg0;
-+			uint32_t nc10_flash_dev_cmd_vld;
-+			uint32_t nc10_flash_dev_cmd1;
-+			uint32_t nc10_flash_dev_cmd_vld_default;
-+			uint32_t nc10_flash_dev_cmd1_default;
-+			struct {
-+				uint32_t flash_status;
-+				uint32_t buffer_status;
-+			} result[16];
-+		} data;
-+	} *dma_buffer;
-+	dmov_s *cmd;
-+	unsigned n;
-+	unsigned page = 0;
-+	uint32_t oob_len;
-+	uint32_t sectordatasize;
-+	uint32_t sectoroobsize;
-+	int err, pageerr, rawerr;
-+	dma_addr_t data_dma_addr = 0;
-+	dma_addr_t oob_dma_addr = 0;
-+	dma_addr_t data_dma_addr_curr = 0;
-+	dma_addr_t oob_dma_addr_curr = 0;
-+	uint32_t oob_col = 0;
-+	unsigned page_count;
-+	unsigned pages_read = 0;
-+	unsigned start_sector = 0;
-+	uint32_t ecc_errors;
-+	uint32_t total_ecc_errors = 0;
-+	unsigned cwperpage;
-+	unsigned cw_offset = chip->cw_size;
-+#if VERBOSE
-+		pr_info("================================================="
-+				"============\n");
-+		pr_info("%s:\nfrom 0x%llx mode %d\ndatbuf 0x%p datlen 0x%x"
-+				"\noobbuf 0x%p ooblen 0x%x\n\n",
-+				__func__, from, ops->mode, ops->datbuf,
-+				ops->len, ops->oobbuf, ops->ooblen);
-+#endif
-+
-+	if (mtd->writesize == 2048)
-+		page = from >> 11;
-+
-+	if (mtd->writesize == 4096)
-+		page = from >> 12;
-+
-+	if (interleave_enable)
-+		page = (from >> 1) >> 12;
-+
-+	oob_len = ops->ooblen;
-+	cwperpage = (mtd->writesize >> 9);
-+
-+	if (from & (mtd->writesize - 1)) {
-+		pr_err("%s: unsupported from, 0x%llx\n",
-+		       __func__, from);
-+		return -EINVAL;
-+	}
-+	if (ops->mode != MTD_OPS_RAW) {
-+		if (ops->datbuf != NULL && (ops->len % mtd->writesize) != 0) {
-+			pr_err("%s: unsupported ops->len, %d\n",
-+			       __func__, ops->len);
-+			return -EINVAL;
-+		}
-+	} else {
-+		if (ops->datbuf != NULL &&
-+			(ops->len % (mtd->writesize + mtd->oobsize)) != 0) {
-+			pr_err("%s: unsupported ops->len,"
-+				" %d for MTD_OPS_RAW\n", __func__, ops->len);
-+			return -EINVAL;
-+		}
-+	}
-+
-+	if (ops->mode != MTD_OPS_RAW && ops->ooblen != 0 && ops->ooboffs != 0) {
-+		pr_err("%s: unsupported ops->ooboffs, %d\n",
-+		       __func__, ops->ooboffs);
-+		return -EINVAL;
-+	}
-+
-+	if (ops->oobbuf && !ops->datbuf && ops->mode == MTD_OPS_AUTO_OOB)
-+		start_sector = cwperpage - 1;
-+
-+	if (ops->oobbuf && !ops->datbuf) {
-+		page_count = ops->ooblen / ((ops->mode == MTD_OPS_AUTO_OOB) ?
-+			mtd->oobavail : mtd->oobsize);
-+		if ((page_count == 0) && (ops->ooblen))
-+			page_count = 1;
-+	} else if (ops->mode != MTD_OPS_RAW)
-+		page_count = ops->len / mtd->writesize;
-+	else
-+		page_count = ops->len / (mtd->writesize + mtd->oobsize);
-+
-+	if (ops->datbuf) {
-+		data_dma_addr_curr = data_dma_addr =
-+			msm_nand_dma_map(chip->dev, ops->datbuf, ops->len,
-+					 DMA_FROM_DEVICE, NULL);
-+		if (dma_mapping_error(chip->dev, data_dma_addr)) {
-+			pr_err("msm_nand_read_oob_dualnandc: "
-+				"failed to get dma addr for %p\n",
-+				ops->datbuf);
-+			return -EIO;
-+		}
-+	}
-+	if (ops->oobbuf) {
-+		memset(ops->oobbuf, 0xff, ops->ooblen);
-+		oob_dma_addr_curr = oob_dma_addr =
-+			msm_nand_dma_map(chip->dev, ops->oobbuf,
-+					 ops->ooblen, DMA_BIDIRECTIONAL, NULL);
-+		if (dma_mapping_error(chip->dev, oob_dma_addr)) {
-+			pr_err("msm_nand_read_oob_dualnandc: "
-+				"failed to get dma addr for %p\n",
-+				ops->oobbuf);
-+			err = -EIO;
-+			goto err_dma_map_oobbuf_failed;
-+		}
-+	}
-+
-+	wait_event(chip->wait_queue,
-+		   (dma_buffer = msm_nand_get_dma_buffer(
-+			    chip, sizeof(*dma_buffer))));
-+
-+	oob_col = start_sector * chip->cw_size;
-+	if (chip->CFG1 & CFG1_WIDE_FLASH) {
-+		oob_col >>= 1;
-+		cw_offset >>= 1;
-+	}
-+
-+	err = 0;
-+	while (page_count-- > 0) {
-+		cmd = dma_buffer->cmd;
-+
-+		if (ops->mode != MTD_OPS_RAW) {
-+			dma_buffer->data.cmd = MSM_NAND_CMD_PAGE_READ_ECC;
-+			if (start_sector == (cwperpage - 1)) {
-+				dma_buffer->data.cfg0 = (chip->CFG0 &
-+							~(7U << 6));
-+			} else {
-+				dma_buffer->data.cfg0 = (chip->CFG0 &
-+				~(7U << 6))
-+				| (((cwperpage >> 1)-1) << 6);
-+			}
-+			dma_buffer->data.cfg1 = chip->CFG1;
-+			if (enable_bch_ecc)
-+				dma_buffer->data.eccbchcfg = chip->ecc_bch_cfg;
-+		} else {
-+			dma_buffer->data.cmd = MSM_NAND_CMD_PAGE_READ;
-+			dma_buffer->data.cfg0 = ((chip->CFG0_RAW &
-+				~(7U << 6)) | ((((cwperpage >> 1)-1) << 6)));
-+			dma_buffer->data.cfg1 = chip->CFG1_RAW |
-+					(chip->CFG1 & CFG1_WIDE_FLASH);
-+		}
-+
-+		if (!interleave_enable) {
-+			if (start_sector == (cwperpage - 1)) {
-+				dma_buffer->data.nandc10_addr0 =
-+							(page << 16) | oob_col;
-+				dma_buffer->data.nc10_flash_dev_cmd_vld = 0xD;
-+				dma_buffer->data.nc10_flash_dev_cmd1 =
-+								0xF00F3000;
-+			} else {
-+				dma_buffer->data.nandc01_addr0 = page << 16;
-+				/* NC10 ADDR0 points to the next code word */
-+				dma_buffer->data.nandc10_addr0 = (page << 16) |
-+								cw_offset;
-+				dma_buffer->data.nc10_flash_dev_cmd_vld = 0x1D;
-+				dma_buffer->data.nc10_flash_dev_cmd1 =
-+								0xF00FE005;
-+			}
-+		} else {
-+			dma_buffer->data.nandc01_addr0 =
-+			dma_buffer->data.nandc10_addr0 =
-+						(page << 16) | oob_col;
-+		}
-+		/* ADDR1 */
-+		dma_buffer->data.nandc11_addr1 = (page >> 16) & 0xff;
-+
-+		dma_buffer->data.adm_mux_data_ack_req_nc01 = 0x00000A3C;
-+		dma_buffer->data.adm_mux_cmd_ack_req_nc01  = 0x0000053C;
-+		dma_buffer->data.adm_mux_data_ack_req_nc10 = 0x00000F28;
-+		dma_buffer->data.adm_mux_cmd_ack_req_nc10  = 0x00000F14;
-+		dma_buffer->data.adm_default_mux = 0x00000FC0;
-+		dma_buffer->data.nc10_flash_dev_cmd_vld_default = 0x1D;
-+		dma_buffer->data.nc10_flash_dev_cmd1_default = 0xF00F3000;
-+
-+		dma_buffer->data.ebi2_chip_select_cfg0 = 0x00000805;
-+		dma_buffer->data.default_ebi2_chip_select_cfg0 = 0x00000801;
-+
-+		/* chipsel_0 + enable DM interface */
-+		dma_buffer->data.chipsel_cs0 = (1<<4) | 4;
-+		/* chipsel_1 + enable DM interface */
-+		dma_buffer->data.chipsel_cs1 = (1<<4) | 5;
-+
-+		/* GO bit for the EXEC register */
-+		dma_buffer->data.exec = 1;
-+
-+		BUILD_BUG_ON(16 != ARRAY_SIZE(dma_buffer->data.result));
-+
-+		for (n = start_sector; n < cwperpage; n++) {
-+			/* flash + buffer status return words */
-+			dma_buffer->data.result[n].flash_status = 0xeeeeeeee;
-+			dma_buffer->data.result[n].buffer_status = 0xeeeeeeee;
-+
-+			if (n == start_sector) {
-+				if (!interleave_enable) {
-+					cmd->cmd = 0;
-+					cmd->src = msm_virt_to_dma(chip,
-+					&dma_buffer->
-+						data.nc10_flash_dev_cmd_vld);
-+					cmd->dst = NC10(MSM_NAND_DEV_CMD_VLD);
-+					cmd->len = 4;
-+					cmd++;
-+
-+					cmd->cmd = 0;
-+					cmd->src = msm_virt_to_dma(chip,
-+					&dma_buffer->data.nc10_flash_dev_cmd1);
-+					cmd->dst = NC10(MSM_NAND_DEV_CMD1);
-+					cmd->len = 4;
-+					cmd++;
-+
-+					/* NC01, NC10 --> ADDR1 */
-+					cmd->cmd = 0;
-+					cmd->src = msm_virt_to_dma(chip,
-+					&dma_buffer->data.nandc11_addr1);
-+					cmd->dst = NC11(MSM_NAND_ADDR1);
-+					cmd->len = 8;
-+					cmd++;
-+
-+					cmd->cmd = 0;
-+					cmd->src = msm_virt_to_dma(chip,
-+						&dma_buffer->data.cfg0);
-+					cmd->dst = NC11(MSM_NAND_DEV0_CFG0);
-+					if (enable_bch_ecc)
-+						cmd->len = 12;
-+					else
-+						cmd->len = 8;
-+					cmd++;
-+				} else {
-+					/* enable CS0 & CS1 */
-+					cmd->cmd = 0;
-+					cmd->src = msm_virt_to_dma(chip,
-+					&dma_buffer->
-+						data.ebi2_chip_select_cfg0);
-+					cmd->dst = EBI2_CHIP_SELECT_CFG0;
-+					cmd->len = 4;
-+					cmd++;
-+
-+					/* NC01, NC10 --> ADDR1 */
-+					cmd->cmd = 0;
-+					cmd->src = msm_virt_to_dma(chip,
-+					&dma_buffer->data.nandc11_addr1);
-+					cmd->dst = NC11(MSM_NAND_ADDR1);
-+					cmd->len = 4;
-+					cmd++;
-+
-+					/* Enable CS0 for NC01 */
-+					cmd->cmd = 0;
-+					cmd->src = msm_virt_to_dma(chip,
-+					&dma_buffer->data.chipsel_cs0);
-+					cmd->dst =
-+					NC01(MSM_NAND_FLASH_CHIP_SELECT);
-+					cmd->len = 4;
-+					cmd++;
-+
-+					/* Enable CS1 for NC10 */
-+					cmd->cmd = 0;
-+					cmd->src = msm_virt_to_dma(chip,
-+					&dma_buffer->data.chipsel_cs1);
-+					cmd->dst =
-+					NC10(MSM_NAND_FLASH_CHIP_SELECT);
-+					cmd->len = 4;
-+					cmd++;
-+
-+					/* config DEV0_CFG0 & CFG1 for CS0 */
-+					cmd->cmd = 0;
-+					cmd->src = msm_virt_to_dma(chip,
-+					&dma_buffer->data.cfg0);
-+					cmd->dst = NC01(MSM_NAND_DEV0_CFG0);
-+					cmd->len = 8;
-+					cmd++;
-+
-+					/* config DEV1_CFG0 & CFG1 for CS1 */
-+					cmd->cmd = 0;
-+					cmd->src = msm_virt_to_dma(chip,
-+					&dma_buffer->data.cfg0);
-+					cmd->dst = NC10(MSM_NAND_DEV1_CFG0);
-+					cmd->len = 8;
-+					cmd++;
-+				}
-+
-+				dma_buffer->data.ecccfg = chip->ecc_buf_cfg;
-+				cmd->cmd = 0;
-+				cmd->src = msm_virt_to_dma(chip,
-+						&dma_buffer->data.ecccfg);
-+				cmd->dst = NC11(MSM_NAND_EBI2_ECC_BUF_CFG);
-+				cmd->len = 4;
-+				cmd++;
-+
-+				/* if 'only' the last code word */
-+				if (n == cwperpage - 1) {
-+					/* MASK CMD ACK/REQ --> NC01 (0x53C)*/
-+					cmd->cmd = 0;
-+					cmd->src = msm_virt_to_dma(chip,
-+					&dma_buffer->
-+						data.adm_mux_cmd_ack_req_nc01);
-+					cmd->dst = EBI2_NAND_ADM_MUX;
-+					cmd->len = 4;
-+					cmd++;
-+
-+					/* CMD */
-+					cmd->cmd = DST_CRCI_NAND_CMD;
-+					cmd->src = msm_virt_to_dma(chip,
-+							&dma_buffer->data.cmd);
-+					cmd->dst = NC10(MSM_NAND_FLASH_CMD);
-+					cmd->len = 4;
-+					cmd++;
-+
-+					/* NC10 --> ADDR0 ( 0x0 ) */
-+					cmd->cmd = 0;
-+					cmd->src = msm_virt_to_dma(chip,
-+					&dma_buffer->data.nandc10_addr0);
-+					cmd->dst = NC10(MSM_NAND_ADDR0);
-+					cmd->len = 4;
-+					cmd++;
-+
-+					/* kick the execute reg for NC10 */
-+					cmd->cmd = 0;
-+					cmd->src = msm_virt_to_dma(chip,
-+						&dma_buffer->data.exec);
-+					cmd->dst = NC10(MSM_NAND_EXEC_CMD);
-+					cmd->len = 4;
-+					cmd++;
-+
-+					/* MASK DATA ACK/REQ --> NC01 (0xA3C)*/
-+					cmd->cmd = 0;
-+					cmd->src = msm_virt_to_dma(chip,
-+					&dma_buffer->
-+					data.adm_mux_data_ack_req_nc01);
-+					cmd->dst = EBI2_NAND_ADM_MUX;
-+					cmd->len = 4;
-+					cmd++;
-+
-+					/* block on data ready from NC10, then
-+					 * read the status register
-+					 */
-+					cmd->cmd = SRC_CRCI_NAND_DATA;
-+					cmd->src = NC10(MSM_NAND_FLASH_STATUS);
-+					cmd->dst = msm_virt_to_dma(chip,
-+						&dma_buffer->data.result[n]);
-+					/* MSM_NAND_FLASH_STATUS +
-+					 * MSM_NAND_BUFFER_STATUS
-+					 */
-+					cmd->len = 8;
-+					cmd++;
-+				} else {
-+					/* NC01 --> ADDR0 */
-+					cmd->cmd = 0;
-+					cmd->src = msm_virt_to_dma(chip,
-+					&dma_buffer->data.nandc01_addr0);
-+					cmd->dst = NC01(MSM_NAND_ADDR0);
-+					cmd->len = 4;
-+					cmd++;
-+
-+					/* NC10 --> ADDR1 */
-+					cmd->cmd = 0;
-+					cmd->src = msm_virt_to_dma(chip,
-+					&dma_buffer->data.nandc10_addr0);
-+					cmd->dst = NC10(MSM_NAND_ADDR0);
-+					cmd->len = 4;
-+					cmd++;
-+
-+					/* MASK CMD ACK/REQ --> NC10 (0xF14)*/
-+					cmd->cmd = 0;
-+					cmd->src = msm_virt_to_dma(chip,
-+					&dma_buffer->
-+						data.adm_mux_cmd_ack_req_nc10);
-+					cmd->dst = EBI2_NAND_ADM_MUX;
-+					cmd->len = 4;
-+					cmd++;
-+
-+					/* CMD */
-+					cmd->cmd = DST_CRCI_NAND_CMD;
-+					cmd->src = msm_virt_to_dma(chip,
-+							&dma_buffer->data.cmd);
-+					cmd->dst = NC01(MSM_NAND_FLASH_CMD);
-+					cmd->len = 4;
-+					cmd++;
-+
-+					/* kick the execute register for NC01*/
-+					cmd->cmd = 0;
-+					cmd->src = msm_virt_to_dma(chip,
-+						 &dma_buffer->data.exec);
-+					cmd->dst = NC01(MSM_NAND_EXEC_CMD);
-+					cmd->len = 4;
-+					cmd++;
-+				}
-+			}
-+
-+			/* read data block
-+			 * (only valid if status says success)
-+			 */
-+			if (ops->datbuf || (ops->oobbuf &&
-+						 ops->mode != MTD_OPS_AUTO_OOB)) {
-+				if (ops->mode != MTD_OPS_RAW)
-+					sectordatasize = (n < (cwperpage - 1))
-+					? 516 : (512 - ((cwperpage - 1) << 2));
-+				else
-+					sectordatasize = chip->cw_size;
-+
-+				if (n % 2 == 0) {
-+					/* MASK DATA ACK/REQ --> NC10 (0xF28)*/
-+					cmd->cmd = 0;
-+					cmd->src = msm_virt_to_dma(chip,
-+					&dma_buffer->
-+					data.adm_mux_data_ack_req_nc10);
-+					cmd->dst = EBI2_NAND_ADM_MUX;
-+					cmd->len = 4;
-+					cmd++;
-+
-+					/* block on data ready from NC01, then
-+					 * read the status register
-+					 */
-+					cmd->cmd = SRC_CRCI_NAND_DATA;
-+					cmd->src = NC01(MSM_NAND_FLASH_STATUS);
-+					cmd->dst = msm_virt_to_dma(chip,
-+						&dma_buffer->data.result[n]);
-+					/* MSM_NAND_FLASH_STATUS +
-+					 * MSM_NAND_BUFFER_STATUS
-+					 */
-+					cmd->len = 8;
-+					cmd++;
-+
-+					/* MASK CMD ACK/REQ --> NC01 (0x53C)*/
-+					cmd->cmd = 0;
-+					cmd->src = msm_virt_to_dma(chip,
-+					&dma_buffer->
-+						data.adm_mux_cmd_ack_req_nc01);
-+					cmd->dst = EBI2_NAND_ADM_MUX;
-+					cmd->len = 4;
-+					cmd++;
-+
-+					/* CMD */
-+					cmd->cmd = DST_CRCI_NAND_CMD;
-+					cmd->src = msm_virt_to_dma(chip,
-+							&dma_buffer->data.cmd);
-+					cmd->dst = NC10(MSM_NAND_FLASH_CMD);
-+					cmd->len = 4;
-+					cmd++;
-+
-+					/* kick the execute register for NC10 */
-+					cmd->cmd = 0;
-+					cmd->src = msm_virt_to_dma(chip,
-+						&dma_buffer->data.exec);
-+					cmd->dst = NC10(MSM_NAND_EXEC_CMD);
-+					cmd->len = 4;
-+					cmd++;
-+
-+					/* Read only when there is data
-+					 * buffer
-+					 */
-+					if (ops->datbuf) {
-+						cmd->cmd = 0;
-+						cmd->src =
-+						NC01(MSM_NAND_FLASH_BUFFER);
-+						cmd->dst = data_dma_addr_curr;
-+						data_dma_addr_curr +=
-+						sectordatasize;
-+						cmd->len = sectordatasize;
-+						cmd++;
-+					}
-+				} else {
-+					/* MASK DATA ACK/REQ -->
-+					 * NC01 (0xA3C)
-+					 */
-+					cmd->cmd = 0;
-+					cmd->src = msm_virt_to_dma(chip,
-+					&dma_buffer->
-+					data.adm_mux_data_ack_req_nc01);
-+					cmd->dst = EBI2_NAND_ADM_MUX;
-+					cmd->len = 4;
-+					cmd++;
-+
-+					/* block on data ready from NC10
-+					 * then read the status register
-+					 */
-+					cmd->cmd = SRC_CRCI_NAND_DATA;
-+					cmd->src =
-+					NC10(MSM_NAND_FLASH_STATUS);
-+					cmd->dst = msm_virt_to_dma(chip,
-+					   &dma_buffer->data.result[n]);
-+					/* MSM_NAND_FLASH_STATUS +
-+					 * MSM_NAND_BUFFER_STATUS
-+					 */
-+					cmd->len = 8;
-+					cmd++;
-+					if (n != cwperpage - 1) {
-+						/* MASK CMD ACK/REQ -->
-+						 * NC10 (0xF14)
-+						 */
-+						cmd->cmd = 0;
-+						cmd->src =
-+						msm_virt_to_dma(chip,
-+						&dma_buffer->
-+						data.adm_mux_cmd_ack_req_nc10);
-+						cmd->dst = EBI2_NAND_ADM_MUX;
-+						cmd->len = 4;
-+						cmd++;
-+
-+						/* CMD */
-+						cmd->cmd = DST_CRCI_NAND_CMD;
-+						cmd->src = msm_virt_to_dma(chip,
-+							&dma_buffer->data.cmd);
-+						cmd->dst =
-+						NC01(MSM_NAND_FLASH_CMD);
-+						cmd->len = 4;
-+						cmd++;
-+
-+						/* EXEC */
-+						cmd->cmd = 0;
-+						cmd->src = msm_virt_to_dma(chip,
-+							&dma_buffer->data.exec);
-+						cmd->dst =
-+						NC01(MSM_NAND_EXEC_CMD);
-+						cmd->len = 4;
-+						cmd++;
-+					}
-+
-+					/* Read only when there is data
-+					 * buffer
-+					 */
-+					if (ops->datbuf) {
-+						cmd->cmd = 0;
-+						cmd->src =
-+						NC10(MSM_NAND_FLASH_BUFFER);
-+						cmd->dst = data_dma_addr_curr;
-+						data_dma_addr_curr +=
-+						sectordatasize;
-+						cmd->len = sectordatasize;
-+						cmd++;
-+					}
-+				}
-+			}
-+
-+			if (ops->oobbuf && (n == (cwperpage - 1)
-+			     || ops->mode != MTD_OPS_AUTO_OOB)) {
-+				cmd->cmd = 0;
-+				if (n == (cwperpage - 1)) {
-+					/* Use NC10 for reading the
-+					 * last codeword!!!
-+					 */
-+					cmd->src = NC10(MSM_NAND_FLASH_BUFFER) +
-+						(512 - ((cwperpage - 1) << 2));
-+					sectoroobsize = (cwperpage << 2);
-+					if (ops->mode != MTD_OPS_AUTO_OOB)
-+						sectoroobsize +=
-+							chip->ecc_parity_bytes;
-+				} else {
-+					if (n % 2 == 0)
-+						cmd->src =
-+						NC01(MSM_NAND_FLASH_BUFFER)
-+						+ 516;
-+					else
-+						cmd->src =
-+						NC10(MSM_NAND_FLASH_BUFFER)
-+						+ 516;
-+					sectoroobsize = chip->ecc_parity_bytes;
-+				}
-+				cmd->dst = oob_dma_addr_curr;
-+				if (sectoroobsize < oob_len)
-+					cmd->len = sectoroobsize;
-+				else
-+					cmd->len = oob_len;
-+				oob_dma_addr_curr += cmd->len;
-+				oob_len -= cmd->len;
-+				if (cmd->len > 0)
-+					cmd++;
-+			}
-+		}
-+		/* ADM --> Default mux state (0xFC0) */
-+		cmd->cmd = 0;
-+		cmd->src = msm_virt_to_dma(chip,
-+			&dma_buffer->data.adm_default_mux);
-+		cmd->dst = EBI2_NAND_ADM_MUX;
-+		cmd->len = 4;
-+		cmd++;
-+
-+		if (!interleave_enable) {
-+			cmd->cmd = 0;
-+			cmd->src = msm_virt_to_dma(chip,
-+			&dma_buffer->data.nc10_flash_dev_cmd_vld_default);
-+			cmd->dst = NC10(MSM_NAND_DEV_CMD_VLD);
-+			cmd->len = 4;
-+			cmd++;
-+
-+			cmd->cmd = 0;
-+			cmd->src = msm_virt_to_dma(chip,
-+			&dma_buffer->data.nc10_flash_dev_cmd1_default);
-+			cmd->dst = NC10(MSM_NAND_DEV_CMD1);
-+			cmd->len = 4;
-+			cmd++;
-+		} else {
-+			/* disable CS1 */
-+			cmd->cmd = 0;
-+			cmd->src = msm_virt_to_dma(chip,
-+			&dma_buffer->data.default_ebi2_chip_select_cfg0);
-+			cmd->dst = EBI2_CHIP_SELECT_CFG0;
-+			cmd->len = 4;
-+			cmd++;
-+		}
-+
-+		BUILD_BUG_ON(16 * 6 + 20 != ARRAY_SIZE(dma_buffer->cmd));
-+		BUG_ON(cmd - dma_buffer->cmd > ARRAY_SIZE(dma_buffer->cmd));
-+		dma_buffer->cmd[0].cmd |= CMD_OCB;
-+		cmd[-1].cmd |= CMD_OCU | CMD_LC;
-+
-+		dma_buffer->cmdptr =
-+			(msm_virt_to_dma(chip, dma_buffer->cmd) >> 3)
-+			| CMD_PTR_LP;
-+
-+		mb();
-+		msm_dmov_exec_cmd(chip->dma_channel,
-+			DMOV_CMD_PTR_LIST | DMOV_CMD_ADDR(msm_virt_to_dma(chip,
-+			&dma_buffer->cmdptr)));
-+		mb();
-+
-+		/* if any of the writes failed (0x10), or there
-+		 * was a protection violation (0x100), we lose
-+		 */
-+		pageerr = rawerr = 0;
-+		for (n = start_sector; n < cwperpage; n++) {
-+			if (dma_buffer->data.result[n].flash_status & 0x110) {
-+				rawerr = -EIO;
-+				break;
-+			}
-+		}
-+		if (rawerr) {
-+			if (ops->datbuf && ops->mode != MTD_OPS_RAW) {
-+				uint8_t *datbuf = ops->datbuf +
-+					pages_read * mtd->writesize;
-+
-+				dma_sync_single_for_cpu(chip->dev,
-+					data_dma_addr_curr-mtd->writesize,
-+					mtd->writesize, DMA_BIDIRECTIONAL);
-+
-+				for (n = 0; n < mtd->writesize; n++) {
-+					/* empty blocks read 0x54 at
-+					 * these offsets
-+					 */
-+					if ((n % 516 == 3 || n % 516 == 175)
-+							&& datbuf[n] == 0x54)
-+						datbuf[n] = 0xff;
-+					if (datbuf[n] != 0xff) {
-+						pageerr = rawerr;
-+						break;
-+					}
-+				}
-+
-+				dma_sync_single_for_device(chip->dev,
-+					data_dma_addr_curr-mtd->writesize,
-+					mtd->writesize, DMA_BIDIRECTIONAL);
-+
-+			}
-+			if (ops->oobbuf) {
-+				dma_sync_single_for_cpu(chip->dev,
-+				oob_dma_addr_curr - (ops->ooblen - oob_len),
-+				ops->ooblen - oob_len, DMA_BIDIRECTIONAL);
-+
-+				for (n = 0; n < ops->ooblen; n++) {
-+					if (ops->oobbuf[n] != 0xff) {
-+						pageerr = rawerr;
-+						break;
-+					}
-+				}
-+
-+				dma_sync_single_for_device(chip->dev,
-+				oob_dma_addr_curr - (ops->ooblen - oob_len),
-+				ops->ooblen - oob_len, DMA_BIDIRECTIONAL);
-+			}
-+		}
-+		if (pageerr) {
-+			for (n = start_sector; n < cwperpage; n++) {
-+				if (dma_buffer->data.result[n].buffer_status
-+					& chip->uncorrectable_bit_mask) {
-+					/* not thread safe */
-+					mtd->ecc_stats.failed++;
-+					pageerr = -EBADMSG;
-+					break;
-+				}
-+			}
-+		}
-+		if (!rawerr) { /* check for corretable errors */
-+			for (n = start_sector; n < cwperpage; n++) {
-+				ecc_errors = dma_buffer->data.
-+					result[n].buffer_status
-+					& chip->num_err_mask;
-+				if (ecc_errors) {
-+					total_ecc_errors += ecc_errors;
-+					/* not thread safe */
-+					mtd->ecc_stats.corrected += ecc_errors;
-+					if (ecc_errors > 1)
-+						pageerr = -EUCLEAN;
-+				}
-+			}
-+		}
-+		if (pageerr && (pageerr != -EUCLEAN || err == 0))
-+			err = pageerr;
-+
-+#if VERBOSE
-+		if (rawerr && !pageerr) {
-+			pr_err("msm_nand_read_oob_dualnandc "
-+				"%llx %x %x empty page\n",
-+			       (loff_t)page * mtd->writesize, ops->len,
-+			       ops->ooblen);
-+		} else {
-+			for (n = start_sector; n < cwperpage; n++) {
-+				if (n%2) {
-+					pr_info("NC10: flash_status[%d] = %x, "
-+					 "buffr_status[%d] = %x\n",
-+					n, dma_buffer->
-+						data.result[n].flash_status,
-+					n, dma_buffer->
-+						data.result[n].buffer_status);
-+				} else {
-+					pr_info("NC01: flash_status[%d] = %x, "
-+					 "buffr_status[%d] = %x\n",
-+					n, dma_buffer->
-+						data.result[n].flash_status,
-+					n, dma_buffer->
-+						data.result[n].buffer_status);
-+				}
-+			}
-+		}
-+#endif
-+		if (err && err != -EUCLEAN && err != -EBADMSG)
-+			break;
-+		pages_read++;
-+		page++;
-+	}
-+
-+	msm_nand_release_dma_buffer(chip, dma_buffer, sizeof(*dma_buffer));
-+
-+	if (ops->oobbuf) {
-+		dma_unmap_page(chip->dev, oob_dma_addr,
-+				 ops->ooblen, DMA_FROM_DEVICE);
-+	}
-+err_dma_map_oobbuf_failed:
-+	if (ops->datbuf) {
-+		dma_unmap_page(chip->dev, data_dma_addr,
-+				 ops->len, DMA_BIDIRECTIONAL);
-+	}
-+
-+	if (ops->mode != MTD_OPS_RAW)
-+		ops->retlen = mtd->writesize * pages_read;
-+	else
-+		ops->retlen = (mtd->writesize +  mtd->oobsize) *
-+							pages_read;
-+	ops->oobretlen = ops->ooblen - oob_len;
-+	if (err)
-+		pr_err("msm_nand_read_oob_dualnandc "
-+			"%llx %x %x failed %d, corrected %d\n",
-+			from, ops->datbuf ? ops->len : 0, ops->ooblen, err,
-+			total_ecc_errors);
-+#if VERBOSE
-+	pr_info("\n%s: ret %d, retlen %d oobretlen %d\n",
-+			__func__, err, ops->retlen, ops->oobretlen);
-+
-+	pr_info("==================================================="
-+			"==========\n");
-+#endif
-+	return err;
-+}
-+
-+static int
-+msm_nand_read(struct mtd_info *mtd, loff_t from, size_t len,
-+	      size_t *retlen, u_char *buf)
-+{
-+	int ret;
-+	struct mtd_ecc_stats stats;
-+	struct mtd_oob_ops ops;
-+	int (*read_oob)(struct mtd_info *, loff_t, struct mtd_oob_ops *);
-+
-+	if (!dual_nand_ctlr_present)
-+		read_oob = msm_nand_read_oob;
-+	else
-+		read_oob = msm_nand_read_oob_dualnandc;
-+
-+	ops.mode = MTD_OPS_PLACE_OOB;
-+	ops.retlen = 0;
-+	ops.ooblen = 0;
-+	ops.oobbuf = NULL;
-+	ret = 0;
-+	*retlen = 0;
-+	stats = mtd->ecc_stats;
-+
-+	if ((from & (mtd->writesize - 1)) == 0 && len == mtd->writesize) {
-+		/* reading a page on page boundary */
-+		ops.len = len;
-+		ops.datbuf = buf;
-+		ret = read_oob(mtd, from, &ops);
-+		*retlen = ops.retlen;
-+	} else if (len > 0) {
-+		/* reading any size on any offset. partial page is supported */
-+		u8 *bounce_buf;
-+		loff_t aligned_from;
-+		loff_t offset;
-+		size_t actual_len;
-+
-+		bounce_buf = kmalloc(mtd->writesize, GFP_KERNEL);
-+		if (!bounce_buf) {
-+			pr_err("%s: could not allocate memory\n", __func__);
-+			ret = -ENOMEM;
-+			goto out;
-+		}
-+
-+		ops.len = mtd->writesize;
-+		offset = from & (mtd->writesize - 1);
-+		aligned_from = from - offset;
-+
-+		for (;;) {
-+			int no_copy;
-+
-+			actual_len = mtd->writesize - offset;
-+			if (actual_len > len)
-+				actual_len = len;
-+
-+			no_copy = (offset == 0 && actual_len == mtd->writesize);
-+			ops.datbuf = (no_copy) ? buf : bounce_buf;
-+
-+			/*
-+			 * MTD API requires that all the pages are to
-+			 * be read even if uncorrectable or
-+			 * correctable ECC errors occur.
-+			 */
-+			ret = read_oob(mtd, aligned_from, &ops);
-+			if (ret == -EBADMSG || ret == -EUCLEAN)
-+				ret = 0;
-+
-+			if (ret < 0)
-+				break;
-+
-+			if (!no_copy)
-+				memcpy(buf, bounce_buf + offset, actual_len);
-+
-+			len -= actual_len;
-+			*retlen += actual_len;
-+			if (len == 0)
-+				break;
-+
-+			buf += actual_len;
-+			offset = 0;
-+			aligned_from += mtd->writesize;
-+		}
-+
-+		kfree(bounce_buf);
-+	}
-+
-+out:
-+	if (ret)
-+		return ret;
-+
-+	if (mtd->ecc_stats.failed - stats.failed)
-+		return -EBADMSG;
-+
-+	if (mtd->ecc_stats.corrected - stats.corrected)
-+		return -EUCLEAN;
-+
-+	return 0;
-+}
-+
-+static int
-+msm_nand_write_oob(struct mtd_info *mtd, loff_t to, struct mtd_oob_ops *ops)
-+{
-+        struct msm_nand_chip *chip = mtd->priv;
-+	struct {
-+		dmov_s cmd[8 * 7 + 2];
-+		unsigned cmdptr;
-+		struct {
-+			uint32_t cmd;
-+			uint32_t addr0;
-+			uint32_t addr1;
-+			uint32_t chipsel;
-+			uint32_t cfg0;
-+			uint32_t cfg1;
-+			uint32_t eccbchcfg;
-+			uint32_t exec;
-+			uint32_t ecccfg;
-+			uint32_t clrfstatus;
-+			uint32_t clrrstatus;
-+			uint32_t flash_status[8];
-+		} data;
-+	} *dma_buffer;
-+	dmov_s *cmd;
-+	unsigned n;
-+	unsigned page = 0;
-+	uint32_t oob_len;
-+	uint32_t sectordatawritesize;
-+	int err = 0;
-+	dma_addr_t data_dma_addr = 0;
-+	dma_addr_t oob_dma_addr = 0;
-+	dma_addr_t data_dma_addr_curr = 0;
-+	dma_addr_t oob_dma_addr_curr = 0;
-+	uint8_t *dat_bounce_buf = NULL;
-+	uint8_t *oob_bounce_buf = NULL;
-+	unsigned page_count;
-+	unsigned pages_written = 0;
-+	unsigned cwperpage;
-+#if VERBOSE
-+	pr_info("================================================="
-+			"================\n");
-+	pr_info("%s:\nto 0x%llx mode %d\ndatbuf 0x%p datlen 0x%x"
-+			"\noobbuf 0x%p ooblen 0x%x\n",
-+			__func__, to, ops->mode, ops->datbuf, ops->len,
-+			ops->oobbuf, ops->ooblen);
-+#endif
-+
-+	if (mtd->writesize == 2048)
-+		page = to >> 11;
-+
-+	if (mtd->writesize == 4096)
-+		page = to >> 12;
-+
-+	oob_len = ops->ooblen;
-+	cwperpage = (mtd->writesize >> 9);
-+
-+	if (to & (mtd->writesize - 1)) {
-+		pr_err("%s: unsupported to, 0x%llx\n", __func__, to);
-+		return -EINVAL;
-+	}
-+
-+	if (ops->mode != MTD_OPS_RAW) {
-+		if (ops->ooblen != 0 && ops->mode != MTD_OPS_AUTO_OOB) {
-+			pr_err("%s: unsupported ops->mode,%d\n",
-+					 __func__, ops->mode);
-+			return -EINVAL;
-+		}
-+		if ((ops->len % mtd->writesize) != 0) {
-+			pr_err("%s: unsupported ops->len, %d\n",
-+					__func__, ops->len);
-+			return -EINVAL;
-+		}
-+	} else {
-+		if ((ops->len % (mtd->writesize + mtd->oobsize)) != 0) {
-+			pr_err("%s: unsupported ops->len, "
-+				"%d for MTD_OPS_RAW mode\n",
-+				 __func__, ops->len);
-+			return -EINVAL;
-+		}
-+	}
-+
-+	if (ops->datbuf == NULL) {
-+		pr_err("%s: unsupported ops->datbuf == NULL\n", __func__);
-+		return -EINVAL;
-+	}
-+	if (ops->mode != MTD_OPS_RAW && ops->ooblen != 0 && ops->ooboffs != 0) {
-+		pr_err("%s: unsupported ops->ooboffs, %d\n",
-+		       __func__, ops->ooboffs);
-+		return -EINVAL;
-+	}
-+
-+	if (ops->datbuf) {
-+		data_dma_addr_curr = data_dma_addr =
-+			msm_nand_dma_map(chip->dev, ops->datbuf,
-+					 ops->len, DMA_TO_DEVICE,
-+					 &dat_bounce_buf);
-+		if (dma_mapping_error(chip->dev, data_dma_addr)) {
-+			pr_err("msm_nand_write_oob: failed to get dma addr "
-+			       "for %p\n", ops->datbuf);
-+			return -EIO;
-+		}
-+	}
-+	if (ops->oobbuf) {
-+		oob_dma_addr_curr = oob_dma_addr =
-+			msm_nand_dma_map(chip->dev, ops->oobbuf,
-+					 ops->ooblen, DMA_TO_DEVICE,
-+					 &oob_bounce_buf);
-+		if (dma_mapping_error(chip->dev, oob_dma_addr)) {
-+			pr_err("msm_nand_write_oob: failed to get dma addr "
-+			       "for %p\n", ops->oobbuf);
-+			err = -EIO;
-+			goto err_dma_map_oobbuf_failed;
-+		}
-+	}
-+	if (ops->mode != MTD_OPS_RAW)
-+		page_count = ops->len / mtd->writesize;
-+	else
-+		page_count = ops->len / (mtd->writesize + mtd->oobsize);
-+
-+	wait_event(chip->wait_queue, (dma_buffer =
-+			msm_nand_get_dma_buffer(chip, sizeof(*dma_buffer))));
-+
-+	while (page_count-- > 0) {
-+		cmd = dma_buffer->cmd;
-+
-+		if (ops->mode != MTD_OPS_RAW) {
-+			dma_buffer->data.cfg0 = chip->CFG0;
-+			dma_buffer->data.cfg1 = chip->CFG1;
-+			if (enable_bch_ecc)
-+				dma_buffer->data.eccbchcfg = chip->ecc_bch_cfg;
-+		} else {
-+			dma_buffer->data.cfg0 = (chip->CFG0_RAW &
-+					~(7U << 6)) | ((cwperpage-1) << 6);
-+			dma_buffer->data.cfg1 = chip->CFG1_RAW |
-+						(chip->CFG1 & CFG1_WIDE_FLASH);
-+		}
-+
-+		/* CMD / ADDR0 / ADDR1 / CHIPSEL program values */
-+		dma_buffer->data.cmd = MSM_NAND_CMD_PRG_PAGE;
-+		dma_buffer->data.addr0 = page << 16;
-+		dma_buffer->data.addr1 = (page >> 16) & 0xff;
-+		/* chipsel_0 + enable DM interface */
-+		dma_buffer->data.chipsel = 0 | 4;
-+
-+
-+		/* GO bit for the EXEC register */
-+		dma_buffer->data.exec = 1;
-+		dma_buffer->data.clrfstatus = 0x00000020;
-+		dma_buffer->data.clrrstatus = 0x000000C0;
-+
-+		BUILD_BUG_ON(8 != ARRAY_SIZE(dma_buffer->data.flash_status));
-+
-+		for (n = 0; n < cwperpage ; n++) {
-+			/* status return words */
-+			dma_buffer->data.flash_status[n] = 0xeeeeeeee;
-+			/* block on cmd ready, then
-+			 * write CMD / ADDR0 / ADDR1 / CHIPSEL regs in a burst
-+			 */
-+			cmd->cmd = DST_CRCI_NAND_CMD;
-+			cmd->src =
-+				msm_virt_to_dma(chip, &dma_buffer->data.cmd);
-+			cmd->dst = MSM_NAND_FLASH_CMD;
-+			if (n == 0)
-+				cmd->len = 16;
-+			else
-+				cmd->len = 4;
-+			cmd++;
-+
-+			if (n == 0) {
-+				cmd->cmd = 0;
-+				cmd->src = msm_virt_to_dma(chip,
-+							&dma_buffer->data.cfg0);
-+				cmd->dst = MSM_NAND_DEV0_CFG0;
-+				if (enable_bch_ecc)
-+					cmd->len = 12;
-+				else
-+					cmd->len = 8;
-+				cmd++;
-+
-+				dma_buffer->data.ecccfg = chip->ecc_buf_cfg;
-+				cmd->cmd = 0;
-+				cmd->src = msm_virt_to_dma(chip,
-+						 &dma_buffer->data.ecccfg);
-+				cmd->dst = MSM_NAND_EBI2_ECC_BUF_CFG;
-+				cmd->len = 4;
-+				cmd++;
-+			}
-+
-+			/* write data block */
-+			if (ops->mode != MTD_OPS_RAW) {
-+				if (!boot_layout)
-+					sectordatawritesize = (n < (cwperpage - 1)) ?
-+						516 : (512 - ((cwperpage - 1) << 2));
-+				else
-+					sectordatawritesize = 512;
-+			} else {
-+				sectordatawritesize = chip->cw_size;
-+			}
-+
-+			cmd->cmd = 0;
-+			cmd->src = data_dma_addr_curr;
-+			data_dma_addr_curr += sectordatawritesize;
-+			cmd->dst = MSM_NAND_FLASH_BUFFER;
-+			cmd->len = sectordatawritesize;
-+			cmd++;
-+
-+			if (ops->oobbuf) {
-+				if (n == (cwperpage - 1)) {
-+					cmd->cmd = 0;
-+					cmd->src = oob_dma_addr_curr;
-+					cmd->dst = MSM_NAND_FLASH_BUFFER +
-+						(512 - ((cwperpage - 1) << 2));
-+					if ((cwperpage << 2) < oob_len)
-+						cmd->len = (cwperpage << 2);
-+					else
-+						cmd->len = oob_len;
-+					oob_dma_addr_curr += cmd->len;
-+					oob_len -= cmd->len;
-+					if (cmd->len > 0)
-+						cmd++;
-+				}
-+				if (ops->mode != MTD_OPS_AUTO_OOB) {
-+					/* skip ecc bytes in oobbuf */
-+					if (oob_len < chip->ecc_parity_bytes) {
-+						oob_dma_addr_curr +=
-+							chip->ecc_parity_bytes;
-+						oob_len -=
-+							chip->ecc_parity_bytes;
-+					} else {
-+						oob_dma_addr_curr += oob_len;
-+						oob_len = 0;
-+					}
-+				}
-+			}
-+
-+			/* kick the execute register */
-+			cmd->cmd = 0;
-+			cmd->src =
-+				msm_virt_to_dma(chip, &dma_buffer->data.exec);
-+			cmd->dst = MSM_NAND_EXEC_CMD;
-+			cmd->len = 4;
-+			cmd++;
-+
-+			/* block on data ready, then
-+			 * read the status register
-+			 */
-+			cmd->cmd = SRC_CRCI_NAND_DATA;
-+			cmd->src = MSM_NAND_FLASH_STATUS;
-+			cmd->dst = msm_virt_to_dma(chip,
-+					     &dma_buffer->data.flash_status[n]);
-+			cmd->len = 4;
-+			cmd++;
-+
-+			cmd->cmd = 0;
-+			cmd->src = msm_virt_to_dma(chip,
-+						&dma_buffer->data.clrfstatus);
-+			cmd->dst = MSM_NAND_FLASH_STATUS;
-+			cmd->len = 4;
-+			cmd++;
-+
-+			cmd->cmd = 0;
-+			cmd->src = msm_virt_to_dma(chip,
-+						&dma_buffer->data.clrrstatus);
-+			cmd->dst = MSM_NAND_READ_STATUS;
-+			cmd->len = 4;
-+			cmd++;
-+
-+		}
-+
-+		dma_buffer->cmd[0].cmd |= CMD_OCB;
-+		cmd[-1].cmd |= CMD_OCU | CMD_LC;
-+		BUILD_BUG_ON(8 * 7 + 2 != ARRAY_SIZE(dma_buffer->cmd));
-+		BUG_ON(cmd - dma_buffer->cmd > ARRAY_SIZE(dma_buffer->cmd));
-+		dma_buffer->cmdptr =
-+			(msm_virt_to_dma(chip, dma_buffer->cmd) >> 3) |
-+			CMD_PTR_LP;
-+
-+		mb();
-+		msm_dmov_exec_cmd(chip->dma_channel,
-+			DMOV_CMD_PTR_LIST | DMOV_CMD_ADDR(
-+				msm_virt_to_dma(chip, &dma_buffer->cmdptr)));
-+		mb();
-+
-+		/* if any of the writes failed (0x10), or there was a
-+		 * protection violation (0x100), or the program success
-+		 * bit (0x80) is unset, we lose
-+		 */
-+		err = 0;
-+		for (n = 0; n < cwperpage; n++) {
-+			if (dma_buffer->data.flash_status[n] & 0x110) {
-+				err = -EIO;
-+				break;
-+			}
-+			if (!(dma_buffer->data.flash_status[n] & 0x80)) {
-+				err = -EIO;
-+				break;
-+			}
-+		}
-+
-+#if VERBOSE
-+		for (n = 0; n < cwperpage; n++)
-+			pr_info("write pg %d: flash_status[%d] = %x\n", page,
-+				n, dma_buffer->data.flash_status[n]);
-+
-+#endif
-+		if (err)
-+			break;
-+		pages_written++;
-+		page++;
-+	}
-+	if (ops->mode != MTD_OPS_RAW)
-+		ops->retlen = mtd->writesize * pages_written;
-+	else
-+		ops->retlen = (mtd->writesize + mtd->oobsize) * pages_written;
-+
-+	ops->oobretlen = ops->ooblen - oob_len;
-+
-+	msm_nand_release_dma_buffer(chip, dma_buffer, sizeof(*dma_buffer));
-+
-+	if (ops->oobbuf) {
-+		msm_nand_dma_unmap(chip->dev, oob_dma_addr,
-+				   ops->ooblen, DMA_TO_DEVICE,
-+				   ops->oobbuf, oob_bounce_buf);
-+	}
-+err_dma_map_oobbuf_failed:
-+	if (ops->datbuf) {
-+		msm_nand_dma_unmap(chip->dev, data_dma_addr, ops->len,
-+				   DMA_TO_DEVICE, ops->datbuf,
-+				   dat_bounce_buf);
-+	}
-+	if (err)
-+		pr_err("msm_nand_write_oob %llx %x %x failed %d\n",
-+		       to, ops->len, ops->ooblen, err);
-+
-+#if VERBOSE
-+		pr_info("\n%s: ret %d, retlen %d oobretlen %d\n",
-+				__func__, err, ops->retlen, ops->oobretlen);
-+
-+		pr_info("==================================================="
-+				"==============\n");
-+#endif
-+	return err;
-+}
-+
-+static int
-+msm_nand_write_oob_dualnandc(struct mtd_info *mtd, loff_t to,
-+				struct mtd_oob_ops *ops)
-+{
-+	struct msm_nand_chip *chip = mtd->priv;
-+	struct {
-+		dmov_s cmd[16 * 6 + 18];
-+		unsigned cmdptr;
-+		struct {
-+			uint32_t cmd;
-+			uint32_t nandc01_addr0;
-+			uint32_t nandc10_addr0;
-+			uint32_t nandc11_addr1;
-+			uint32_t chipsel_cs0;
-+			uint32_t chipsel_cs1;
-+			uint32_t cfg0;
-+			uint32_t cfg1;
-+			uint32_t eccbchcfg;
-+			uint32_t exec;
-+			uint32_t ecccfg;
-+			uint32_t cfg0_nc01;
-+			uint32_t ebi2_chip_select_cfg0;
-+			uint32_t adm_mux_data_ack_req_nc01;
-+			uint32_t adm_mux_cmd_ack_req_nc01;
-+			uint32_t adm_mux_data_ack_req_nc10;
-+			uint32_t adm_mux_cmd_ack_req_nc10;
-+			uint32_t adm_default_mux;
-+			uint32_t default_ebi2_chip_select_cfg0;
-+			uint32_t nc01_flash_dev_cmd_vld;
-+			uint32_t nc10_flash_dev_cmd0;
-+			uint32_t nc01_flash_dev_cmd_vld_default;
-+			uint32_t nc10_flash_dev_cmd0_default;
-+			uint32_t flash_status[16];
-+			uint32_t clrfstatus;
-+			uint32_t clrrstatus;
-+		} data;
-+	} *dma_buffer;
-+	dmov_s *cmd;
-+	unsigned n;
-+	unsigned page = 0;
-+	uint32_t oob_len;
-+	uint32_t sectordatawritesize;
-+	int err = 0;
-+	dma_addr_t data_dma_addr = 0;
-+	dma_addr_t oob_dma_addr = 0;
-+	dma_addr_t data_dma_addr_curr = 0;
-+	dma_addr_t oob_dma_addr_curr = 0;
-+	unsigned page_count;
-+	unsigned pages_written = 0;
-+	unsigned cwperpage;
-+	unsigned cw_offset = chip->cw_size;
-+#if VERBOSE
-+		pr_info("================================================="
-+				"============\n");
-+		pr_info("%s:\nto 0x%llx mode %d\ndatbuf 0x%p datlen 0x%x"
-+				"\noobbuf 0x%p ooblen 0x%x\n\n",
-+				__func__, to, ops->mode, ops->datbuf, ops->len,
-+				ops->oobbuf, ops->ooblen);
-+#endif
-+
-+	if (mtd->writesize == 2048)
-+		page = to >> 11;
-+
-+	if (mtd->writesize == 4096)
-+		page = to >> 12;
-+
-+	if (interleave_enable)
-+		page = (to >> 1) >> 12;
-+
-+	oob_len = ops->ooblen;
-+	cwperpage = (mtd->writesize >> 9);
-+
-+	if (to & (mtd->writesize - 1)) {
-+		pr_err("%s: unsupported to, 0x%llx\n", __func__, to);
-+		return -EINVAL;
-+	}
-+
-+	if (ops->mode != MTD_OPS_RAW) {
-+		if (ops->ooblen != 0 && ops->mode != MTD_OPS_AUTO_OOB) {
-+			pr_err("%s: unsupported ops->mode,%d\n",
-+					 __func__, ops->mode);
-+			return -EINVAL;
-+		}
-+		if ((ops->len % mtd->writesize) != 0) {
-+			pr_err("%s: unsupported ops->len, %d\n",
-+					__func__, ops->len);
-+			return -EINVAL;
-+		}
-+	} else {
-+		if ((ops->len % (mtd->writesize + mtd->oobsize)) != 0) {
-+			pr_err("%s: unsupported ops->len, "
-+				"%d for MTD_OPS_RAW mode\n",
-+				 __func__, ops->len);
-+			return -EINVAL;
-+		}
-+	}
-+
-+	if (ops->datbuf == NULL) {
-+		pr_err("%s: unsupported ops->datbuf == NULL\n", __func__);
-+		return -EINVAL;
-+	}
-+
-+	if (ops->mode != MTD_OPS_RAW && ops->ooblen != 0 && ops->ooboffs != 0) {
-+		pr_err("%s: unsupported ops->ooboffs, %d\n",
-+		       __func__, ops->ooboffs);
-+		return -EINVAL;
-+	}
-+
-+	if (ops->datbuf) {
-+		data_dma_addr_curr = data_dma_addr =
-+			msm_nand_dma_map(chip->dev, ops->datbuf,
-+					 ops->len, DMA_TO_DEVICE, NULL);
-+		if (dma_mapping_error(chip->dev, data_dma_addr)) {
-+			pr_err("msm_nand_write_oob_dualnandc:"
-+				"failed to get dma addr "
-+			       "for %p\n", ops->datbuf);
-+			return -EIO;
-+		}
-+	}
-+	if (ops->oobbuf) {
-+		oob_dma_addr_curr = oob_dma_addr =
-+			msm_nand_dma_map(chip->dev, ops->oobbuf,
-+					 ops->ooblen, DMA_TO_DEVICE, NULL);
-+		if (dma_mapping_error(chip->dev, oob_dma_addr)) {
-+			pr_err("msm_nand_write_oob_dualnandc:"
-+				"failed to get dma addr "
-+			       "for %p\n", ops->oobbuf);
-+			err = -EIO;
-+			goto err_dma_map_oobbuf_failed;
-+		}
-+	}
-+	if (ops->mode != MTD_OPS_RAW)
-+		page_count = ops->len / mtd->writesize;
-+	else
-+		page_count = ops->len / (mtd->writesize + mtd->oobsize);
-+
-+	wait_event(chip->wait_queue, (dma_buffer =
-+			msm_nand_get_dma_buffer(chip, sizeof(*dma_buffer))));
-+
-+	if (chip->CFG1 & CFG1_WIDE_FLASH)
-+		cw_offset >>= 1;
-+
-+	dma_buffer->data.ebi2_chip_select_cfg0 = 0x00000805;
-+	dma_buffer->data.adm_mux_data_ack_req_nc01 = 0x00000A3C;
-+	dma_buffer->data.adm_mux_cmd_ack_req_nc01  = 0x0000053C;
-+	dma_buffer->data.adm_mux_data_ack_req_nc10 = 0x00000F28;
-+	dma_buffer->data.adm_mux_cmd_ack_req_nc10  = 0x00000F14;
-+	dma_buffer->data.adm_default_mux = 0x00000FC0;
-+	dma_buffer->data.default_ebi2_chip_select_cfg0 = 0x00000801;
-+	dma_buffer->data.nc01_flash_dev_cmd_vld = 0x9;
-+	dma_buffer->data.nc10_flash_dev_cmd0 = 0x1085D060;
-+	dma_buffer->data.nc01_flash_dev_cmd_vld_default = 0x1D;
-+	dma_buffer->data.nc10_flash_dev_cmd0_default = 0x1080D060;
-+	dma_buffer->data.clrfstatus = 0x00000020;
-+	dma_buffer->data.clrrstatus = 0x000000C0;
-+
-+	while (page_count-- > 0) {
-+		cmd = dma_buffer->cmd;
-+
-+		if (ops->mode != MTD_OPS_RAW) {
-+			dma_buffer->data.cfg0 = ((chip->CFG0 & ~(7U << 6))
-+				& ~(1 << 4)) | ((((cwperpage >> 1)-1)) << 6);
-+			dma_buffer->data.cfg1 = chip->CFG1;
-+			if (enable_bch_ecc)
-+				dma_buffer->data.eccbchcfg = chip->ecc_bch_cfg;
-+		} else {
-+			dma_buffer->data.cfg0 = ((chip->CFG0_RAW &
-+			~(7U << 6)) & ~(1 << 4)) | (((cwperpage >> 1)-1) << 6);
-+			dma_buffer->data.cfg1 = chip->CFG1_RAW |
-+					(chip->CFG1 & CFG1_WIDE_FLASH);
-+		}
-+
-+		/* Disables the automatic issuing of the read
-+		 * status command for first NAND controller.
-+		 */
-+		if (!interleave_enable)
-+			dma_buffer->data.cfg0_nc01 = dma_buffer->data.cfg0
-+							| (1 << 4);
-+		else
-+			dma_buffer->data.cfg0 |= (1 << 4);
-+
-+		dma_buffer->data.cmd = MSM_NAND_CMD_PRG_PAGE;
-+		dma_buffer->data.chipsel_cs0 = (1<<4) | 4;
-+		dma_buffer->data.chipsel_cs1 = (1<<4) | 5;
-+
-+		/* GO bit for the EXEC register */
-+		dma_buffer->data.exec = 1;
-+
-+		if (!interleave_enable) {
-+			dma_buffer->data.nandc01_addr0 = (page << 16) | 0x0;
-+			/* NC10 ADDR0 points to the next code word */
-+			dma_buffer->data.nandc10_addr0 =
-+					(page << 16) | cw_offset;
-+		} else {
-+			dma_buffer->data.nandc01_addr0 =
-+			dma_buffer->data.nandc10_addr0 = (page << 16) | 0x0;
-+		}
-+		/* ADDR1 */
-+		dma_buffer->data.nandc11_addr1 = (page >> 16) & 0xff;
-+
-+		BUILD_BUG_ON(16 != ARRAY_SIZE(dma_buffer->data.flash_status));
-+
-+		for (n = 0; n < cwperpage; n++) {
-+			/* status return words */
-+			dma_buffer->data.flash_status[n] = 0xeeeeeeee;
-+
-+			if (n == 0) {
-+				if (!interleave_enable) {
-+					cmd->cmd = 0;
-+					cmd->src = msm_virt_to_dma(chip,
-+					&dma_buffer->
-+					data.nc01_flash_dev_cmd_vld);
-+					cmd->dst = NC01(MSM_NAND_DEV_CMD_VLD);
-+					cmd->len = 4;
-+					cmd++;
-+
-+					cmd->cmd = 0;
-+					cmd->src = msm_virt_to_dma(chip,
-+					&dma_buffer->data.nc10_flash_dev_cmd0);
-+					cmd->dst = NC10(MSM_NAND_DEV_CMD0);
-+					cmd->len = 4;
-+					cmd++;
-+
-+					/* common settings for both NC01 & NC10
-+					 * NC01, NC10 --> ADDR1 / CHIPSEL
-+					 */
-+					cmd->cmd = 0;
-+					cmd->src = msm_virt_to_dma(chip,
-+					&dma_buffer->data.nandc11_addr1);
-+					cmd->dst = NC11(MSM_NAND_ADDR1);
-+					cmd->len = 8;
-+					cmd++;
-+
-+					/* Disables the automatic issue of the
-+					 * read status command after the write
-+					 * operation.
-+					 */
-+					cmd->cmd = 0;
-+					cmd->src = msm_virt_to_dma(chip,
-+						&dma_buffer->data.cfg0_nc01);
-+					cmd->dst = NC01(MSM_NAND_DEV0_CFG0);
-+					cmd->len = 4;
-+					cmd++;
-+
-+					cmd->cmd = 0;
-+					cmd->src = msm_virt_to_dma(chip,
-+						&dma_buffer->data.cfg0);
-+					cmd->dst = NC10(MSM_NAND_DEV0_CFG0);
-+					cmd->len = 4;
-+					cmd++;
-+
-+					cmd->cmd = 0;
-+					cmd->src = msm_virt_to_dma(chip,
-+						&dma_buffer->data.cfg1);
-+					cmd->dst = NC11(MSM_NAND_DEV0_CFG1);
-+					if (enable_bch_ecc)
-+						cmd->len = 8;
-+					else
-+						cmd->len = 4;
-+					cmd++;
-+				} else {
-+					/* enable CS1 */
-+					cmd->cmd = 0;
-+					cmd->src = msm_virt_to_dma(chip,
-+					&dma_buffer->
-+					data.ebi2_chip_select_cfg0);
-+					cmd->dst = EBI2_CHIP_SELECT_CFG0;
-+					cmd->len = 4;
-+					cmd++;
-+
-+					/* NC11 --> ADDR1 */
-+					cmd->cmd = 0;
-+					cmd->src = msm_virt_to_dma(chip,
-+					&dma_buffer->data.nandc11_addr1);
-+					cmd->dst = NC11(MSM_NAND_ADDR1);
-+					cmd->len = 4;
-+					cmd++;
-+
-+					/* Enable CS0 for NC01 */
-+					cmd->cmd = 0;
-+					cmd->src = msm_virt_to_dma(chip,
-+					&dma_buffer->data.chipsel_cs0);
-+					cmd->dst =
-+					NC01(MSM_NAND_FLASH_CHIP_SELECT);
-+					cmd->len = 4;
-+					cmd++;
-+
-+					/* Enable CS1 for NC10 */
-+					cmd->cmd = 0;
-+					cmd->src = msm_virt_to_dma(chip,
-+					&dma_buffer->data.chipsel_cs1);
-+					cmd->dst =
-+					NC10(MSM_NAND_FLASH_CHIP_SELECT);
-+					cmd->len = 4;
-+					cmd++;
-+
-+					/* config DEV0_CFG0 & CFG1 for CS0 */
-+					cmd->cmd = 0;
-+					cmd->src = msm_virt_to_dma(chip,
-+						&dma_buffer->data.cfg0);
-+					cmd->dst = NC01(MSM_NAND_DEV0_CFG0);
-+					cmd->len = 8;
-+					cmd++;
-+
-+					/* config DEV1_CFG0 & CFG1 for CS1 */
-+					cmd->cmd = 0;
-+					cmd->src = msm_virt_to_dma(chip,
-+					&dma_buffer->data.cfg0);
-+					cmd->dst = NC10(MSM_NAND_DEV1_CFG0);
-+					cmd->len = 8;
-+					cmd++;
-+				}
-+
-+				dma_buffer->data.ecccfg = chip->ecc_buf_cfg;
-+				cmd->cmd = 0;
-+				cmd->src = msm_virt_to_dma(chip,
-+						&dma_buffer->data.ecccfg);
-+				cmd->dst = NC11(MSM_NAND_EBI2_ECC_BUF_CFG);
-+				cmd->len = 4;
-+				cmd++;
-+
-+				/* NC01 --> ADDR0 */
-+				cmd->cmd = 0;
-+				cmd->src = msm_virt_to_dma(chip,
-+					&dma_buffer->data.nandc01_addr0);
-+				cmd->dst = NC01(MSM_NAND_ADDR0);
-+				cmd->len = 4;
-+				cmd++;
-+
-+				/* NC10 --> ADDR0 */
-+				cmd->cmd = 0;
-+				cmd->src = msm_virt_to_dma(chip,
-+				&dma_buffer->data.nandc10_addr0);
-+				cmd->dst = NC10(MSM_NAND_ADDR0);
-+				cmd->len = 4;
-+				cmd++;
-+			}
-+
-+			if (n % 2 == 0) {
-+				/* MASK CMD ACK/REQ --> NC10 (0xF14)*/
-+				cmd->cmd = 0;
-+				cmd->src = msm_virt_to_dma(chip,
-+				&dma_buffer->data.adm_mux_cmd_ack_req_nc10);
-+				cmd->dst = EBI2_NAND_ADM_MUX;
-+				cmd->len = 4;
-+				cmd++;
-+
-+				/* CMD */
-+				cmd->cmd = DST_CRCI_NAND_CMD;
-+				cmd->src = msm_virt_to_dma(chip,
-+						&dma_buffer->data.cmd);
-+				cmd->dst = NC01(MSM_NAND_FLASH_CMD);
-+				cmd->len = 4;
-+				cmd++;
-+			} else {
-+				/* MASK CMD ACK/REQ --> NC01 (0x53C)*/
-+				cmd->cmd = 0;
-+				cmd->src = msm_virt_to_dma(chip,
-+				&dma_buffer->data.adm_mux_cmd_ack_req_nc01);
-+				cmd->dst = EBI2_NAND_ADM_MUX;
-+				cmd->len = 4;
-+				cmd++;
-+
-+				/* CMD */
-+				cmd->cmd = DST_CRCI_NAND_CMD;
-+				cmd->src = msm_virt_to_dma(chip,
-+						&dma_buffer->data.cmd);
-+				cmd->dst = NC10(MSM_NAND_FLASH_CMD);
-+				cmd->len = 4;
-+				cmd++;
-+			}
-+
-+			if (ops->mode != MTD_OPS_RAW)
-+				sectordatawritesize = (n < (cwperpage - 1)) ?
-+					516 : (512 - ((cwperpage - 1) << 2));
-+			else
-+				sectordatawritesize = chip->cw_size;
-+
-+			cmd->cmd = 0;
-+			cmd->src = data_dma_addr_curr;
-+			data_dma_addr_curr += sectordatawritesize;
-+
-+			if (n % 2 == 0)
-+				cmd->dst = NC01(MSM_NAND_FLASH_BUFFER);
-+			else
-+				cmd->dst = NC10(MSM_NAND_FLASH_BUFFER);
-+			cmd->len = sectordatawritesize;
-+			cmd++;
-+
-+			if (ops->oobbuf) {
-+				if (n == (cwperpage - 1)) {
-+					cmd->cmd = 0;
-+					cmd->src = oob_dma_addr_curr;
-+					cmd->dst = NC10(MSM_NAND_FLASH_BUFFER) +
-+						(512 - ((cwperpage - 1) << 2));
-+					if ((cwperpage << 2) < oob_len)
-+						cmd->len = (cwperpage << 2);
-+					else
-+						cmd->len = oob_len;
-+					oob_dma_addr_curr += cmd->len;
-+					oob_len -= cmd->len;
-+					if (cmd->len > 0)
-+						cmd++;
-+				}
-+				if (ops->mode != MTD_OPS_AUTO_OOB) {
-+					/* skip ecc bytes in oobbuf */
-+					if (oob_len < chip->ecc_parity_bytes) {
-+						oob_dma_addr_curr +=
-+							chip->ecc_parity_bytes;
-+						oob_len -=
-+							chip->ecc_parity_bytes;
-+					} else {
-+						oob_dma_addr_curr += oob_len;
-+						oob_len = 0;
-+					}
-+				}
-+			}
-+
-+			if (n % 2 == 0) {
-+				if (n != 0) {
-+					/* MASK DATA ACK/REQ --> NC01 (0xA3C)*/
-+					cmd->cmd = 0;
-+					cmd->src = msm_virt_to_dma(chip,
-+					&dma_buffer->
-+					data.adm_mux_data_ack_req_nc01);
-+					cmd->dst = EBI2_NAND_ADM_MUX;
-+					cmd->len = 4;
-+					cmd++;
-+
-+					/* block on data ready from NC10, then
-+					* read the status register
-+					*/
-+					cmd->cmd = SRC_CRCI_NAND_DATA;
-+					cmd->src = NC10(MSM_NAND_FLASH_STATUS);
-+					cmd->dst = msm_virt_to_dma(chip,
-+					&dma_buffer->data.flash_status[n-1]);
-+					cmd->len = 4;
-+					cmd++;
-+				}
-+				/* kick the NC01 execute register */
-+				cmd->cmd = 0;
-+				cmd->src = msm_virt_to_dma(chip,
-+						&dma_buffer->data.exec);
-+				cmd->dst = NC01(MSM_NAND_EXEC_CMD);
-+				cmd->len = 4;
-+				cmd++;
-+			} else {
-+				/* MASK DATA ACK/REQ --> NC10 (0xF28)*/
-+				cmd->cmd = 0;
-+				cmd->src = msm_virt_to_dma(chip,
-+				&dma_buffer->data.adm_mux_data_ack_req_nc10);
-+				cmd->dst = EBI2_NAND_ADM_MUX;
-+				cmd->len = 4;
-+				cmd++;
-+
-+				/* block on data ready from NC01, then
-+				 * read the status register
-+				 */
-+				cmd->cmd = SRC_CRCI_NAND_DATA;
-+				cmd->src = NC01(MSM_NAND_FLASH_STATUS);
-+				cmd->dst = msm_virt_to_dma(chip,
-+				&dma_buffer->data.flash_status[n-1]);
-+				cmd->len = 4;
-+				cmd++;
-+
-+				/* kick the execute register */
-+				cmd->cmd = 0;
-+				cmd->src =
-+				msm_virt_to_dma(chip, &dma_buffer->data.exec);
-+				cmd->dst = NC10(MSM_NAND_EXEC_CMD);
-+				cmd->len = 4;
-+				cmd++;
-+			}
-+		}
-+
-+		/* MASK DATA ACK/REQ --> NC01 (0xA3C)*/
-+		cmd->cmd = 0;
-+		cmd->src = msm_virt_to_dma(chip,
-+				&dma_buffer->data.adm_mux_data_ack_req_nc01);
-+		cmd->dst = EBI2_NAND_ADM_MUX;
-+		cmd->len = 4;
-+		cmd++;
-+
-+		/* we should process outstanding request */
-+		/* block on data ready, then
-+		 * read the status register
-+		 */
-+		cmd->cmd = SRC_CRCI_NAND_DATA;
-+		cmd->src = NC10(MSM_NAND_FLASH_STATUS);
-+		cmd->dst = msm_virt_to_dma(chip,
-+			     &dma_buffer->data.flash_status[n-1]);
-+		cmd->len = 4;
-+		cmd++;
-+
-+		cmd->cmd = 0;
-+		cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.clrfstatus);
-+		cmd->dst = NC11(MSM_NAND_FLASH_STATUS);
-+		cmd->len = 4;
-+		cmd++;
-+
-+		cmd->cmd = 0;
-+		cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.clrrstatus);
-+		cmd->dst = NC11(MSM_NAND_READ_STATUS);
-+		cmd->len = 4;
-+		cmd++;
-+
-+		/* MASK DATA ACK/REQ --> NC01 (0xFC0)*/
-+		cmd->cmd = 0;
-+		cmd->src = msm_virt_to_dma(chip,
-+				&dma_buffer->data.adm_default_mux);
-+		cmd->dst = EBI2_NAND_ADM_MUX;
-+		cmd->len = 4;
-+		cmd++;
-+
-+		if (!interleave_enable) {
-+			/* setting to defalut values back */
-+			cmd->cmd = 0;
-+			cmd->src = msm_virt_to_dma(chip,
-+			&dma_buffer->data.nc01_flash_dev_cmd_vld_default);
-+			cmd->dst = NC01(MSM_NAND_DEV_CMD_VLD);
-+			cmd->len = 4;
-+			cmd++;
-+
-+			cmd->cmd = 0;
-+			cmd->src = msm_virt_to_dma(chip,
-+			&dma_buffer->data.nc10_flash_dev_cmd0_default);
-+			cmd->dst = NC10(MSM_NAND_DEV_CMD0);
-+			cmd->len = 4;
-+			cmd++;
-+		} else {
-+			/* disable CS1 */
-+			cmd->cmd = 0;
-+			cmd->src = msm_virt_to_dma(chip,
-+			&dma_buffer->data.default_ebi2_chip_select_cfg0);
-+			cmd->dst = EBI2_CHIP_SELECT_CFG0;
-+			cmd->len = 4;
-+			cmd++;
-+		}
-+
-+		dma_buffer->cmd[0].cmd |= CMD_OCB;
-+		cmd[-1].cmd |= CMD_OCU | CMD_LC;
-+		BUILD_BUG_ON(16 * 6 + 18 != ARRAY_SIZE(dma_buffer->cmd));
-+		BUG_ON(cmd - dma_buffer->cmd > ARRAY_SIZE(dma_buffer->cmd));
-+		dma_buffer->cmdptr =
-+		((msm_virt_to_dma(chip, dma_buffer->cmd) >> 3) | CMD_PTR_LP);
-+
-+		mb();
-+		msm_dmov_exec_cmd(chip->dma_channel,
-+			DMOV_CMD_PTR_LIST | DMOV_CMD_ADDR(
-+				msm_virt_to_dma(chip, &dma_buffer->cmdptr)));
-+		mb();
-+
-+		/* if any of the writes failed (0x10), or there was a
-+		 * protection violation (0x100), or the program success
-+		 * bit (0x80) is unset, we lose
-+		 */
-+		err = 0;
-+		for (n = 0; n < cwperpage; n++) {
-+			if (dma_buffer->data.flash_status[n] & 0x110) {
-+				err = -EIO;
-+				break;
-+			}
-+			if (!(dma_buffer->data.flash_status[n] & 0x80)) {
-+				err = -EIO;
-+				break;
-+			}
-+		}
-+		/* check for flash status busy for the last codeword */
-+		if (!interleave_enable)
-+			if (!(dma_buffer->data.flash_status[cwperpage - 1]
-+								& 0x20)) {
-+				err = -EIO;
-+				break;
-+			}
-+#if VERBOSE
-+	for (n = 0; n < cwperpage; n++) {
-+		if (n%2) {
-+			pr_info("NC10: write pg %d: flash_status[%d] = %x\n",
-+				page, n, dma_buffer->data.flash_status[n]);
-+		} else {
-+			pr_info("NC01: write pg %d: flash_status[%d] = %x\n",
-+				page, n, dma_buffer->data.flash_status[n]);
-+		}
-+	}
-+#endif
-+		if (err)
-+			break;
-+		pages_written++;
-+		page++;
-+	}
-+	if (ops->mode != MTD_OPS_RAW)
-+		ops->retlen = mtd->writesize * pages_written;
-+	else
-+		ops->retlen = (mtd->writesize + mtd->oobsize) * pages_written;
-+
-+	ops->oobretlen = ops->ooblen - oob_len;
-+
-+	msm_nand_release_dma_buffer(chip, dma_buffer, sizeof(*dma_buffer));
-+
-+	if (ops->oobbuf)
-+		dma_unmap_page(chip->dev, oob_dma_addr,
-+				 ops->ooblen, DMA_TO_DEVICE);
-+err_dma_map_oobbuf_failed:
-+	if (ops->datbuf)
-+		dma_unmap_page(chip->dev, data_dma_addr, ops->len,
-+				DMA_TO_DEVICE);
-+	if (err)
-+		pr_err("msm_nand_write_oob_dualnandc %llx %x %x failed %d\n",
-+		       to, ops->len, ops->ooblen, err);
-+
-+#if VERBOSE
-+	pr_info("\n%s: ret %d, retlen %d oobretlen %d\n",
-+			__func__, err, ops->retlen, ops->oobretlen);
-+
-+	pr_info("==================================================="
-+			"==========\n");
-+#endif
-+	return err;
-+}
-+
-+static int msm_nand_write(struct mtd_info *mtd, loff_t to, size_t len,
-+			  size_t *retlen, const u_char *buf)
-+{
-+        int ret;
-+	struct mtd_oob_ops ops;
-+	int (*write_oob)(struct mtd_info *, loff_t, struct mtd_oob_ops *);
-+
-+	if (!dual_nand_ctlr_present)
-+		write_oob = msm_nand_write_oob;
-+	else
-+		write_oob = msm_nand_write_oob_dualnandc;
-+
-+	ops.mode = MTD_OPS_PLACE_OOB;
-+	ops.retlen = 0;
-+	ops.ooblen = 0;
-+	ops.oobbuf = NULL;
-+	ret = 0;
-+	*retlen = 0;
-+
-+	if (!virt_addr_valid(buf) &&
-+	    ((to | len) & (mtd->writesize - 1)) == 0 &&
-+	    ((unsigned long) buf & ~PAGE_MASK) + len > PAGE_SIZE) {
-+		/*
-+		 * Handle writing of large size write buffer in vmalloc
-+		 * address space that does not fit in an MMU page.
-+		 * The destination address must be on page boundary,
-+		 * and the size must be multiple of NAND page size.
-+		 * Writing partial page is not supported.
-+		 */
-+		ops.len = mtd->writesize;
-+
-+		for (;;) {
-+			ops.datbuf = (uint8_t *) buf;
-+
-+			ret = write_oob(mtd, to, &ops);
-+			if (ret < 0)
-+				break;
-+
-+			len -= mtd->writesize;
-+			*retlen += mtd->writesize;
-+			if (len == 0)
-+				break;
-+
-+			buf += mtd->writesize;
-+			to += mtd->writesize;
-+		}
-+	} else {
-+		ops.len = len;
-+		ops.datbuf = (uint8_t *) buf;
-+		ret = write_oob(mtd, to, &ops);
-+		*retlen = ops.retlen;
-+	}
-+
-+	return ret;
-+}
-+
-+static int
-+msm_nand_erase(struct mtd_info *mtd, struct erase_info *instr)
-+{
-+	int err;
-+	struct msm_nand_chip *chip = mtd->priv;
-+	struct {
-+		dmov_s cmd[6];
-+		unsigned cmdptr;
-+		struct {
-+			uint32_t cmd;
-+			uint32_t addr0;
-+			uint32_t addr1;
-+			uint32_t chipsel;
-+			uint32_t cfg0;
-+			uint32_t cfg1;
-+			uint32_t exec;
-+			uint32_t flash_status;
-+			uint32_t clrfstatus;
-+			uint32_t clrrstatus;
-+		} data;
-+	} *dma_buffer;
-+	dmov_s *cmd;
-+	unsigned page = 0;
-+
-+	if (mtd->writesize == 2048)
-+		page = instr->addr >> 11;
-+
-+	if (mtd->writesize == 4096)
-+		page = instr->addr >> 12;
-+
-+	if (instr->addr & (mtd->erasesize - 1)) {
-+		pr_err("%s: unsupported erase address, 0x%llx\n",
-+		       __func__, instr->addr);
-+		return -EINVAL;
-+	}
-+	if (instr->len != mtd->erasesize) {
-+		pr_err("%s: unsupported erase len, %lld\n",
-+		       __func__, instr->len);
-+		return -EINVAL;
-+	}
-+
-+	wait_event(chip->wait_queue,
-+		   (dma_buffer = msm_nand_get_dma_buffer(
-+			    chip, sizeof(*dma_buffer))));
-+
-+	cmd = dma_buffer->cmd;
-+
-+	dma_buffer->data.cmd = MSM_NAND_CMD_BLOCK_ERASE;
-+	dma_buffer->data.addr0 = page;
-+	dma_buffer->data.addr1 = 0;
-+	dma_buffer->data.chipsel = 0 | 4;
-+	dma_buffer->data.exec = 1;
-+	dma_buffer->data.flash_status = 0xeeeeeeee;
-+	dma_buffer->data.cfg0 = chip->CFG0 & (~(7 << 6));  /* CW_PER_PAGE = 0 */
-+	dma_buffer->data.cfg1 = chip->CFG1;
-+	dma_buffer->data.clrfstatus = 0x00000020;
-+	dma_buffer->data.clrrstatus = 0x000000C0;
-+
-+	cmd->cmd = DST_CRCI_NAND_CMD | CMD_OCB;
-+	cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.cmd);
-+	cmd->dst = MSM_NAND_FLASH_CMD;
-+	cmd->len = 16;
-+	cmd++;
-+
-+	cmd->cmd = 0;
-+	cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.cfg0);
-+	cmd->dst = MSM_NAND_DEV0_CFG0;
-+	cmd->len = 8;
-+	cmd++;
-+
-+	cmd->cmd = 0;
-+	cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.exec);
-+	cmd->dst = MSM_NAND_EXEC_CMD;
-+	cmd->len = 4;
-+	cmd++;
-+
-+	cmd->cmd = SRC_CRCI_NAND_DATA;
-+	cmd->src = MSM_NAND_FLASH_STATUS;
-+	cmd->dst = msm_virt_to_dma(chip, &dma_buffer->data.flash_status);
-+	cmd->len = 4;
-+	cmd++;
-+
-+	cmd->cmd = 0;
-+	cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.clrfstatus);
-+	cmd->dst = MSM_NAND_FLASH_STATUS;
-+	cmd->len = 4;
-+	cmd++;
-+
-+	cmd->cmd = CMD_OCU | CMD_LC;
-+	cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.clrrstatus);
-+	cmd->dst = MSM_NAND_READ_STATUS;
-+	cmd->len = 4;
-+	cmd++;
-+
-+	BUILD_BUG_ON(5 != ARRAY_SIZE(dma_buffer->cmd) - 1);
-+	BUG_ON(cmd - dma_buffer->cmd > ARRAY_SIZE(dma_buffer->cmd));
-+	dma_buffer->cmdptr =
-+		(msm_virt_to_dma(chip, dma_buffer->cmd) >> 3) | CMD_PTR_LP;
-+
-+	mb();
-+	msm_dmov_exec_cmd(
-+		chip->dma_channel, DMOV_CMD_PTR_LIST |
-+		DMOV_CMD_ADDR(msm_virt_to_dma(chip, &dma_buffer->cmdptr)));
-+	mb();
-+
-+	/* we fail if there was an operation error, a mpu error, or the
-+	 * erase success bit was not set.
-+	 */
-+
-+	if (dma_buffer->data.flash_status & 0x110 ||
-+			!(dma_buffer->data.flash_status & 0x80))
-+		err = -EIO;
-+	else
-+		err = 0;
-+
-+	msm_nand_release_dma_buffer(chip, dma_buffer, sizeof(*dma_buffer));
-+	if (err) {
-+		pr_err("%s: erase failed, 0x%llx\n", __func__, instr->addr);
-+		instr->fail_addr = instr->addr;
-+		instr->state = MTD_ERASE_FAILED;
-+	} else {
-+		instr->state = MTD_ERASE_DONE;
-+		instr->fail_addr = 0xffffffff;
-+		mtd_erase_callback(instr);
-+	}
-+	return err;
-+}
-+
-+static int
-+msm_nand_erase_dualnandc(struct mtd_info *mtd, struct erase_info *instr)
-+{
-+	int err;
-+	struct msm_nand_chip *chip = mtd->priv;
-+	struct {
-+		dmov_s cmd[18];
-+		unsigned cmdptr;
-+		struct {
-+			uint32_t cmd;
-+			uint32_t addr0;
-+			uint32_t addr1;
-+			uint32_t chipsel_cs0;
-+			uint32_t chipsel_cs1;
-+			uint32_t cfg0;
-+			uint32_t cfg1;
-+			uint32_t exec;
-+			uint32_t ecccfg;
-+			uint32_t ebi2_chip_select_cfg0;
-+			uint32_t adm_mux_data_ack_req_nc01;
-+			uint32_t adm_mux_cmd_ack_req_nc01;
-+			uint32_t adm_mux_data_ack_req_nc10;
-+			uint32_t adm_mux_cmd_ack_req_nc10;
-+			uint32_t adm_default_mux;
-+			uint32_t default_ebi2_chip_select_cfg0;
-+			uint32_t nc01_flash_dev_cmd0;
-+			uint32_t nc01_flash_dev_cmd0_default;
-+			uint32_t flash_status[2];
-+			uint32_t clrfstatus;
-+			uint32_t clrrstatus;
-+		} data;
-+	} *dma_buffer;
-+	dmov_s *cmd;
-+	unsigned page = 0;
-+
-+	if (mtd->writesize == 2048)
-+		page = instr->addr >> 11;
-+
-+	if (mtd->writesize == 4096)
-+		page = instr->addr >> 12;
-+
-+	if (mtd->writesize == 8192)
-+		page = (instr->addr >> 1) >> 12;
-+
-+	if (instr->addr & (mtd->erasesize - 1)) {
-+		pr_err("%s: unsupported erase address, 0x%llx\n",
-+		       __func__, instr->addr);
-+		return -EINVAL;
-+	}
-+	if (instr->len != mtd->erasesize) {
-+		pr_err("%s: unsupported erase len, %lld\n",
-+		       __func__, instr->len);
-+		return -EINVAL;
-+	}
-+
-+	wait_event(chip->wait_queue,
-+		   (dma_buffer = msm_nand_get_dma_buffer(
-+			    chip, sizeof(*dma_buffer))));
-+
-+	cmd = dma_buffer->cmd;
-+
-+	dma_buffer->data.cmd = MSM_NAND_CMD_BLOCK_ERASE;
-+	dma_buffer->data.addr0 = page;
-+	dma_buffer->data.addr1 = 0;
-+	dma_buffer->data.chipsel_cs0 = (1<<4) | 4;
-+	dma_buffer->data.chipsel_cs1 = (1<<4) | 5;
-+	dma_buffer->data.exec = 1;
-+	dma_buffer->data.flash_status[0] = 0xeeeeeeee;
-+	dma_buffer->data.flash_status[1] = 0xeeeeeeee;
-+	dma_buffer->data.cfg0 = chip->CFG0 & (~(7 << 6));  /* CW_PER_PAGE = 0 */
-+	dma_buffer->data.cfg1 = chip->CFG1;
-+	dma_buffer->data.clrfstatus = 0x00000020;
-+	dma_buffer->data.clrrstatus = 0x000000C0;
-+
-+	dma_buffer->data.ebi2_chip_select_cfg0 = 0x00000805;
-+	dma_buffer->data.adm_mux_data_ack_req_nc01 = 0x00000A3C;
-+	dma_buffer->data.adm_mux_cmd_ack_req_nc01  = 0x0000053C;
-+	dma_buffer->data.adm_mux_data_ack_req_nc10 = 0x00000F28;
-+	dma_buffer->data.adm_mux_cmd_ack_req_nc10  = 0x00000F14;
-+	dma_buffer->data.adm_default_mux = 0x00000FC0;
-+	dma_buffer->data.default_ebi2_chip_select_cfg0 = 0x00000801;
-+
-+	/* enable CS1 */
-+	cmd->cmd = 0 | CMD_OCB;
-+	cmd->src = msm_virt_to_dma(chip,
-+			&dma_buffer->data.ebi2_chip_select_cfg0);
-+	cmd->dst = EBI2_CHIP_SELECT_CFG0;
-+	cmd->len = 4;
-+	cmd++;
-+
-+	/* erase CS0 block now !!! */
-+	/* 0xF14 */
-+	cmd->cmd = 0;
-+	cmd->src = msm_virt_to_dma(chip,
-+			&dma_buffer->data.adm_mux_cmd_ack_req_nc10);
-+	cmd->dst = EBI2_NAND_ADM_MUX;
-+	cmd->len = 4;
-+	cmd++;
-+
-+	cmd->cmd = DST_CRCI_NAND_CMD;
-+	cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.cmd);
-+	cmd->dst = NC01(MSM_NAND_FLASH_CMD);
-+	cmd->len = 16;
-+	cmd++;
-+
-+	cmd->cmd = 0;
-+	cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.cfg0);
-+	cmd->dst = NC01(MSM_NAND_DEV0_CFG0);
-+	cmd->len = 8;
-+	cmd++;
-+
-+	cmd->cmd = 0;
-+	cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.exec);
-+	cmd->dst = NC01(MSM_NAND_EXEC_CMD);
-+	cmd->len = 4;
-+	cmd++;
-+
-+	/* 0xF28 */
-+	cmd->cmd = 0;
-+	cmd->src = msm_virt_to_dma(chip,
-+			&dma_buffer->data.adm_mux_data_ack_req_nc10);
-+	cmd->dst = EBI2_NAND_ADM_MUX;
-+	cmd->len = 4;
-+	cmd++;
-+
-+	cmd->cmd = SRC_CRCI_NAND_DATA;
-+	cmd->src = NC01(MSM_NAND_FLASH_STATUS);
-+	cmd->dst = msm_virt_to_dma(chip, &dma_buffer->data.flash_status[0]);
-+	cmd->len = 4;
-+	cmd++;
-+
-+	/* erase CS1 block now !!! */
-+	/* 0x53C */
-+	cmd->cmd = 0;
-+	cmd->src = msm_virt_to_dma(chip,
-+			       &dma_buffer->data.adm_mux_cmd_ack_req_nc01);
-+	cmd->dst = EBI2_NAND_ADM_MUX;
-+	cmd->len = 4;
-+	cmd++;
-+
-+	cmd->cmd = DST_CRCI_NAND_CMD;
-+	cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.cmd);
-+	cmd->dst = NC10(MSM_NAND_FLASH_CMD);
-+	cmd->len = 12;
-+	cmd++;
-+
-+	cmd->cmd = 0;
-+	cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.chipsel_cs1);
-+	cmd->dst = NC10(MSM_NAND_FLASH_CHIP_SELECT);
-+	cmd->len = 4;
-+	cmd++;
-+
-+	cmd->cmd = 0;
-+	cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.cfg0);
-+	cmd->dst = NC10(MSM_NAND_DEV1_CFG0);
-+	cmd->len = 8;
-+
-+	cmd->cmd = 0;
-+	cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.exec);
-+	cmd->dst = NC10(MSM_NAND_EXEC_CMD);
-+	cmd->len = 4;
-+	cmd++;
-+
-+	/* 0xA3C */
-+	cmd->cmd = 0;
-+	cmd->src = msm_virt_to_dma(chip,
-+			     &dma_buffer->data.adm_mux_data_ack_req_nc01);
-+	cmd->dst = EBI2_NAND_ADM_MUX;
-+	cmd->len = 4;
-+	cmd++;
-+
-+	cmd->cmd = SRC_CRCI_NAND_DATA;
-+	cmd->src = NC10(MSM_NAND_FLASH_STATUS);
-+	cmd->dst = msm_virt_to_dma(chip, &dma_buffer->data.flash_status[1]);
-+	cmd->len = 4;
-+	cmd++;
-+
-+	cmd->cmd = 0;
-+	cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.clrfstatus);
-+	cmd->dst = NC11(MSM_NAND_FLASH_STATUS);
-+	cmd->len = 4;
-+	cmd++;
-+
-+	cmd->cmd = 0;
-+	cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.clrrstatus);
-+	cmd->dst = NC11(MSM_NAND_READ_STATUS);
-+	cmd->len = 4;
-+	cmd++;
-+
-+	cmd->cmd = 0;
-+	cmd->src = msm_virt_to_dma(chip,
-+			&dma_buffer->data.adm_default_mux);
-+	cmd->dst = EBI2_NAND_ADM_MUX;
-+	cmd->len = 4;
-+	cmd++;
-+
-+	/* disable CS1 */
-+	cmd->cmd = CMD_OCU | CMD_LC;
-+	cmd->src = msm_virt_to_dma(chip,
-+			&dma_buffer->data.default_ebi2_chip_select_cfg0);
-+	cmd->dst = EBI2_CHIP_SELECT_CFG0;
-+	cmd->len = 4;
-+	cmd++;
-+
-+	BUILD_BUG_ON(17 != ARRAY_SIZE(dma_buffer->cmd) - 1);
-+	BUG_ON(cmd - dma_buffer->cmd > ARRAY_SIZE(dma_buffer->cmd));
-+
-+	dma_buffer->cmdptr =
-+		(msm_virt_to_dma(chip, dma_buffer->cmd) >> 3) | CMD_PTR_LP;
-+
-+	mb();
-+	msm_dmov_exec_cmd(
-+		chip->dma_channel, DMOV_CMD_PTR_LIST |
-+		DMOV_CMD_ADDR(msm_virt_to_dma(chip, &dma_buffer->cmdptr)));
-+	mb();
-+
-+	/* we fail if there was an operation error, a mpu error, or the
-+	 * erase success bit was not set.
-+	 */
-+
-+	if (dma_buffer->data.flash_status[0] & 0x110 ||
-+			!(dma_buffer->data.flash_status[0] & 0x80) ||
-+			dma_buffer->data.flash_status[1] & 0x110 ||
-+			!(dma_buffer->data.flash_status[1] & 0x80))
-+		err = -EIO;
-+	else
-+		err = 0;
-+
-+	msm_nand_release_dma_buffer(chip, dma_buffer, sizeof(*dma_buffer));
-+	if (err) {
-+		pr_err("%s: erase failed, 0x%llx\n", __func__, instr->addr);
-+		instr->fail_addr = instr->addr;
-+		instr->state = MTD_ERASE_FAILED;
-+	} else {
-+		instr->state = MTD_ERASE_DONE;
-+		instr->fail_addr = 0xffffffff;
-+		mtd_erase_callback(instr);
-+	}
-+	return err;
-+}
-+
-+static int
-+msm_nand_block_isbad(struct mtd_info *mtd, loff_t ofs)
-+{
-+	struct msm_nand_chip *chip = mtd->priv;
-+	int ret;
-+	struct {
-+		dmov_s cmd[5];
-+		unsigned cmdptr;
-+		struct {
-+			uint32_t cmd;
-+			uint32_t addr0;
-+			uint32_t addr1;
-+			uint32_t chipsel;
-+			uint32_t cfg0;
-+			uint32_t cfg1;
-+			uint32_t eccbchcfg;
-+			uint32_t exec;
-+			uint32_t ecccfg;
-+			struct {
-+				uint32_t flash_status;
-+				uint32_t buffer_status;
-+			} result;
-+		} data;
-+	} *dma_buffer;
-+	dmov_s *cmd;
-+	uint8_t *buf;
-+	unsigned page = 0;
-+	unsigned cwperpage;
-+
-+	if (mtd->writesize == 2048)
-+		page = ofs >> 11;
-+
-+	if (mtd->writesize == 4096)
-+		page = ofs >> 12;
-+
-+	cwperpage = (mtd->writesize >> 9);
-+
-+	/* Check for invalid offset */
-+	if (ofs > mtd->size)
-+		return -EINVAL;
-+	if (ofs & (mtd->erasesize - 1)) {
-+		pr_err("%s: unsupported block address, 0x%x\n",
-+			 __func__, (uint32_t)ofs);
-+		return -EINVAL;
-+	}
-+
-+	wait_event(chip->wait_queue,
-+		(dma_buffer = msm_nand_get_dma_buffer(chip ,
-+					 sizeof(*dma_buffer) + 4)));
-+	buf = (uint8_t *)dma_buffer + sizeof(*dma_buffer);
-+
-+	/* Read 4 bytes starting from the bad block marker location
-+	 * in the last code word of the page
-+	 */
-+
-+	cmd = dma_buffer->cmd;
-+
-+	dma_buffer->data.cmd = MSM_NAND_CMD_PAGE_READ;
-+	dma_buffer->data.cfg0 = chip->CFG0_RAW & ~(7U << 6);
-+	dma_buffer->data.cfg1 = chip->CFG1_RAW |
-+				(chip->CFG1 & CFG1_WIDE_FLASH);
-+	if (enable_bch_ecc)
-+		dma_buffer->data.eccbchcfg = chip->ecc_bch_cfg;
-+
-+	if (chip->CFG1 & CFG1_WIDE_FLASH)
-+		dma_buffer->data.addr0 = (page << 16) |
-+			((chip->cw_size * (cwperpage-1)) >> 1);
-+	else
-+		dma_buffer->data.addr0 = (page << 16) |
-+			(chip->cw_size * (cwperpage-1));
-+
-+	dma_buffer->data.addr1 = (page >> 16) & 0xff;
-+	dma_buffer->data.chipsel = 0 | 4;
-+
-+	dma_buffer->data.exec = 1;
-+
-+	dma_buffer->data.result.flash_status = 0xeeeeeeee;
-+	dma_buffer->data.result.buffer_status = 0xeeeeeeee;
-+
-+	cmd->cmd = DST_CRCI_NAND_CMD;
-+	cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.cmd);
-+	cmd->dst = MSM_NAND_FLASH_CMD;
-+	cmd->len = 16;
-+	cmd++;
-+
-+	cmd->cmd = 0;
-+	cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.cfg0);
-+	cmd->dst = MSM_NAND_DEV0_CFG0;
-+	if (enable_bch_ecc)
-+		cmd->len = 12;
-+	else
-+		cmd->len = 8;
-+	cmd++;
-+
-+	cmd->cmd = 0;
-+	cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.exec);
-+	cmd->dst = MSM_NAND_EXEC_CMD;
-+	cmd->len = 4;
-+	cmd++;
-+
-+	cmd->cmd = SRC_CRCI_NAND_DATA;
-+	cmd->src = MSM_NAND_FLASH_STATUS;
-+	cmd->dst = msm_virt_to_dma(chip, &dma_buffer->data.result);
-+	cmd->len = 8;
-+	cmd++;
-+
-+	cmd->cmd = 0;
-+	cmd->src = MSM_NAND_FLASH_BUFFER +
-+	(mtd->writesize - (chip->cw_size * (cwperpage-1)));
-+	cmd->dst = msm_virt_to_dma(chip, buf);
-+	cmd->len = 4;
-+	cmd++;
-+
-+	BUILD_BUG_ON(5 != ARRAY_SIZE(dma_buffer->cmd));
-+	BUG_ON(cmd - dma_buffer->cmd > ARRAY_SIZE(dma_buffer->cmd));
-+	dma_buffer->cmd[0].cmd |= CMD_OCB;
-+	cmd[-1].cmd |= CMD_OCU | CMD_LC;
-+
-+	dma_buffer->cmdptr = (msm_virt_to_dma(chip,
-+				dma_buffer->cmd) >> 3) | CMD_PTR_LP;
-+
-+	mb();
-+	msm_dmov_exec_cmd(chip->dma_channel, DMOV_CMD_PTR_LIST |
-+		DMOV_CMD_ADDR(msm_virt_to_dma(chip, &dma_buffer->cmdptr)));
-+	mb();
-+
-+	ret = 0;
-+	if (dma_buffer->data.result.flash_status & 0x110)
-+		ret = -EIO;
-+
-+	if (!ret) {
-+		/* Check for bad block marker byte */
-+		if (chip->CFG1 & CFG1_WIDE_FLASH) {
-+			if (buf[0] != 0xFF || buf[1] != 0xFF)
-+				ret = 1;
-+		} else {
-+			if (buf[0] != 0xFF)
-+				ret = 1;
-+		}
-+	}
-+
-+	msm_nand_release_dma_buffer(chip, dma_buffer, sizeof(*dma_buffer) + 4);
-+	return ret;
-+}
-+
-+static int
-+msm_nand_block_isbad_dualnandc(struct mtd_info *mtd, loff_t ofs)
-+{
-+	struct msm_nand_chip *chip = mtd->priv;
-+	int ret;
-+	struct {
-+		dmov_s cmd[18];
-+		unsigned cmdptr;
-+		struct {
-+			uint32_t cmd;
-+			uint32_t addr0;
-+			uint32_t addr1;
-+			uint32_t chipsel_cs0;
-+			uint32_t chipsel_cs1;
-+			uint32_t cfg0;
-+			uint32_t cfg1;
-+			uint32_t exec;
-+			uint32_t ecccfg;
-+			uint32_t ebi2_chip_select_cfg0;
-+			uint32_t adm_mux_data_ack_req_nc01;
-+			uint32_t adm_mux_cmd_ack_req_nc01;
-+			uint32_t adm_mux_data_ack_req_nc10;
-+			uint32_t adm_mux_cmd_ack_req_nc10;
-+			uint32_t adm_default_mux;
-+			uint32_t default_ebi2_chip_select_cfg0;
-+			struct {
-+				uint32_t flash_status;
-+				uint32_t buffer_status;
-+			} result[2];
-+		} data;
-+	} *dma_buffer;
-+	dmov_s *cmd;
-+	uint8_t *buf01;
-+	uint8_t *buf10;
-+	unsigned page = 0;
-+	unsigned cwperpage;
-+
-+	if (mtd->writesize == 2048)
-+		page = ofs >> 11;
-+
-+	if (mtd->writesize == 4096)
-+		page = ofs >> 12;
-+
-+	if (mtd->writesize == 8192)
-+		page = (ofs >> 1) >> 12;
-+
-+	cwperpage = ((mtd->writesize >> 1) >> 9);
-+
-+	/* Check for invalid offset */
-+	if (ofs > mtd->size)
-+		return -EINVAL;
-+	if (ofs & (mtd->erasesize - 1)) {
-+		pr_err("%s: unsupported block address, 0x%x\n",
-+			 __func__, (uint32_t)ofs);
-+		return -EINVAL;
-+	}
-+
-+	wait_event(chip->wait_queue,
-+		(dma_buffer = msm_nand_get_dma_buffer(chip ,
-+					 sizeof(*dma_buffer) + 8)));
-+	buf01 = (uint8_t *)dma_buffer + sizeof(*dma_buffer);
-+	buf10 = buf01 + 4;
-+
-+	/* Read 4 bytes starting from the bad block marker location
-+	 * in the last code word of the page
-+	 */
-+	cmd = dma_buffer->cmd;
-+
-+	dma_buffer->data.cmd = MSM_NAND_CMD_PAGE_READ;
-+	dma_buffer->data.cfg0 = chip->CFG0_RAW & ~(7U << 6);
-+	dma_buffer->data.cfg1 = chip->CFG1_RAW |
-+				(chip->CFG1 & CFG1_WIDE_FLASH);
-+
-+	if (chip->CFG1 & CFG1_WIDE_FLASH)
-+		dma_buffer->data.addr0 = (page << 16) |
-+			((528*(cwperpage-1)) >> 1);
-+	else
-+		dma_buffer->data.addr0 = (page << 16) |
-+			(528*(cwperpage-1));
-+
-+	dma_buffer->data.addr1 = (page >> 16) & 0xff;
-+	dma_buffer->data.chipsel_cs0 = (1<<4) | 4;
-+	dma_buffer->data.chipsel_cs1 = (1<<4) | 5;
-+
-+	dma_buffer->data.exec = 1;
-+
-+	dma_buffer->data.result[0].flash_status = 0xeeeeeeee;
-+	dma_buffer->data.result[0].buffer_status = 0xeeeeeeee;
-+	dma_buffer->data.result[1].flash_status = 0xeeeeeeee;
-+	dma_buffer->data.result[1].buffer_status = 0xeeeeeeee;
-+
-+	dma_buffer->data.ebi2_chip_select_cfg0 = 0x00000805;
-+	dma_buffer->data.adm_mux_data_ack_req_nc01 = 0x00000A3C;
-+	dma_buffer->data.adm_mux_cmd_ack_req_nc01  = 0x0000053C;
-+	dma_buffer->data.adm_mux_data_ack_req_nc10 = 0x00000F28;
-+	dma_buffer->data.adm_mux_cmd_ack_req_nc10  = 0x00000F14;
-+	dma_buffer->data.adm_default_mux = 0x00000FC0;
-+	dma_buffer->data.default_ebi2_chip_select_cfg0 = 0x00000801;
-+
-+	/* Reading last code word from NC01 */
-+	/* enable CS1 */
-+	cmd->cmd = 0;
-+	cmd->src = msm_virt_to_dma(chip,
-+			&dma_buffer->data.ebi2_chip_select_cfg0);
-+	cmd->dst = EBI2_CHIP_SELECT_CFG0;
-+	cmd->len = 4;
-+	cmd++;
-+
-+	/* 0xF14 */
-+	cmd->cmd = 0;
-+	cmd->src = msm_virt_to_dma(chip,
-+			&dma_buffer->data.adm_mux_cmd_ack_req_nc10);
-+	cmd->dst = EBI2_NAND_ADM_MUX;
-+	cmd->len = 4;
-+	cmd++;
-+
-+	cmd->cmd = DST_CRCI_NAND_CMD;
-+	cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.cmd);
-+	cmd->dst = NC01(MSM_NAND_FLASH_CMD);
-+	cmd->len = 16;
-+	cmd++;
-+
-+	cmd->cmd = 0;
-+	cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.cfg0);
-+	cmd->dst = NC01(MSM_NAND_DEV0_CFG0);
-+	cmd->len = 8;
-+	cmd++;
-+
-+	cmd->cmd = 0;
-+	cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.exec);
-+	cmd->dst = NC01(MSM_NAND_EXEC_CMD);
-+	cmd->len = 4;
-+	cmd++;
-+
-+	/* 0xF28 */
-+	cmd->cmd = 0;
-+	cmd->src = msm_virt_to_dma(chip,
-+			&dma_buffer->data.adm_mux_data_ack_req_nc10);
-+	cmd->dst = EBI2_NAND_ADM_MUX;
-+	cmd->len = 4;
-+	cmd++;
-+
-+	cmd->cmd = SRC_CRCI_NAND_DATA;
-+	cmd->src = NC01(MSM_NAND_FLASH_STATUS);
-+	cmd->dst = msm_virt_to_dma(chip, &dma_buffer->data.result[0]);
-+	cmd->len = 8;
-+	cmd++;
-+
-+	cmd->cmd = 0;
-+	cmd->src = NC01(MSM_NAND_FLASH_BUFFER) + ((mtd->writesize >> 1) -
-+							(528*(cwperpage-1)));
-+	cmd->dst = msm_virt_to_dma(chip, buf01);
-+	cmd->len = 4;
-+	cmd++;
-+
-+	/* Reading last code word from NC10 */
-+	/* 0x53C */
-+	cmd->cmd = 0;
-+	cmd->src = msm_virt_to_dma(chip,
-+	&dma_buffer->data.adm_mux_cmd_ack_req_nc01);
-+	cmd->dst = EBI2_NAND_ADM_MUX;
-+	cmd->len = 4;
-+	cmd++;
-+
-+	cmd->cmd = DST_CRCI_NAND_CMD;
-+	cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.cmd);
-+	cmd->dst = NC10(MSM_NAND_FLASH_CMD);
-+	cmd->len = 12;
-+	cmd++;
-+
-+	cmd->cmd = 0;
-+	cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.chipsel_cs1);
-+	cmd->dst = NC10(MSM_NAND_FLASH_CHIP_SELECT);
-+	cmd->len = 4;
-+	cmd++;
-+
-+	cmd->cmd = 0;
-+	cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.cfg0);
-+	cmd->dst = NC10(MSM_NAND_DEV1_CFG0);
-+	cmd->len = 8;
-+	cmd++;
-+
-+	cmd->cmd = 0;
-+	cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.exec);
-+	cmd->dst = NC10(MSM_NAND_EXEC_CMD);
-+	cmd->len = 4;
-+	cmd++;
-+
-+	/* A3C */
-+	cmd->cmd = 0;
-+	cmd->src = msm_virt_to_dma(chip,
-+			&dma_buffer->data.adm_mux_data_ack_req_nc01);
-+	cmd->dst = EBI2_NAND_ADM_MUX;
-+	cmd->len = 4;
-+	cmd++;
-+
-+	cmd->cmd = SRC_CRCI_NAND_DATA;
-+	cmd->src = NC10(MSM_NAND_FLASH_STATUS);
-+	cmd->dst = msm_virt_to_dma(chip, &dma_buffer->data.result[1]);
-+	cmd->len = 8;
-+	cmd++;
-+
-+	cmd->cmd = 0;
-+	cmd->src = NC10(MSM_NAND_FLASH_BUFFER) + ((mtd->writesize >> 1) -
-+							(528*(cwperpage-1)));
-+	cmd->dst = msm_virt_to_dma(chip, buf10);
-+	cmd->len = 4;
-+	cmd++;
-+
-+	/* FC0 */
-+	cmd->cmd = 0;
-+	cmd->src = msm_virt_to_dma(chip,
-+			&dma_buffer->data.adm_default_mux);
-+	cmd->dst = EBI2_NAND_ADM_MUX;
-+	cmd->len = 4;
-+	cmd++;
-+
-+	/* disble CS1 */
-+	cmd->cmd = 0;
-+	cmd->src = msm_virt_to_dma(chip,
-+			&dma_buffer->data.ebi2_chip_select_cfg0);
-+	cmd->dst = EBI2_CHIP_SELECT_CFG0;
-+	cmd->len = 4;
-+	cmd++;
-+
-+	BUILD_BUG_ON(18 != ARRAY_SIZE(dma_buffer->cmd));
-+	BUG_ON(cmd - dma_buffer->cmd > ARRAY_SIZE(dma_buffer->cmd));
-+	dma_buffer->cmd[0].cmd |= CMD_OCB;
-+	cmd[-1].cmd |= CMD_OCU | CMD_LC;
-+
-+	dma_buffer->cmdptr = (msm_virt_to_dma(chip,
-+				dma_buffer->cmd) >> 3) | CMD_PTR_LP;
-+
-+	mb();
-+	msm_dmov_exec_cmd(chip->dma_channel, DMOV_CMD_PTR_LIST |
-+		DMOV_CMD_ADDR(msm_virt_to_dma(chip, &dma_buffer->cmdptr)));
-+	mb();
-+
-+	ret = 0;
-+	if ((dma_buffer->data.result[0].flash_status & 0x110) ||
-+			(dma_buffer->data.result[1].flash_status & 0x110))
-+		ret = -EIO;
-+
-+	if (!ret) {
-+		/* Check for bad block marker byte for NC01 & NC10 */
-+		if (chip->CFG1 & CFG1_WIDE_FLASH) {
-+			if ((buf01[0] != 0xFF || buf01[1] != 0xFF) ||
-+				(buf10[0] != 0xFF || buf10[1] != 0xFF))
-+				ret = 1;
-+		} else {
-+			if (buf01[0] != 0xFF || buf10[0] != 0xFF)
-+				ret = 1;
-+		}
-+	}
-+
-+	msm_nand_release_dma_buffer(chip, dma_buffer, sizeof(*dma_buffer) + 8);
-+	return ret;
-+}
-+
-+static int
-+msm_nand_block_markbad(struct mtd_info *mtd, loff_t ofs)
-+{
-+	struct mtd_oob_ops ops;
-+	int ret;
-+	uint8_t *buf;
-+
-+	/* Check for invalid offset */
-+	if (ofs > mtd->size)
-+		return -EINVAL;
-+	if (ofs & (mtd->erasesize - 1)) {
-+		pr_err("%s: unsupported block address, 0x%x\n",
-+				 __func__, (uint32_t)ofs);
-+		return -EINVAL;
-+	}
-+
-+	/*
-+	Write all 0s to the first page
-+	This will set the BB marker to 0
-+	*/
-+	buf = page_address(ZERO_PAGE());
-+
-+	ops.mode = MTD_OPS_RAW;
-+	ops.len = mtd->writesize + mtd->oobsize;
-+	ops.retlen = 0;
-+	ops.ooblen = 0;
-+	ops.datbuf = buf;
-+	ops.oobbuf = NULL;
-+	if (!interleave_enable)
-+		ret =  msm_nand_write_oob(mtd, ofs, &ops);
-+	else
-+		ret = msm_nand_write_oob_dualnandc(mtd, ofs, &ops);
-+
-+	return ret;
-+}
-+
-+/**
-+ * msm_nand_suspend - [MTD Interface] Suspend the msm_nand flash
-+ * @param mtd		MTD device structure
-+ */
-+static int msm_nand_suspend(struct mtd_info *mtd)
-+{
-+	return 0;
-+}
-+
-+/**
-+ * msm_nand_resume - [MTD Interface] Resume the msm_nand flash
-+ * @param mtd		MTD device structure
-+ */
-+static void msm_nand_resume(struct mtd_info *mtd)
-+{
-+}
-+
-+struct onenand_information {
-+	uint16_t manufacturer_id;
-+	uint16_t device_id;
-+	uint16_t version_id;
-+	uint16_t data_buf_size;
-+	uint16_t boot_buf_size;
-+	uint16_t num_of_buffers;
-+	uint16_t technology;
-+};
-+
-+static struct onenand_information onenand_info;
-+static uint32_t nand_sfcmd_mode;
-+
-+uint32_t flash_onenand_probe(struct msm_nand_chip *chip)
-+{
-+               struct {
-+		dmov_s cmd[7];
-+		unsigned cmdptr;
-+		struct {
-+			uint32_t bcfg;
-+			uint32_t cmd;
-+			uint32_t exec;
-+			uint32_t status;
-+			uint32_t addr0;
-+			uint32_t addr1;
-+			uint32_t addr2;
-+			uint32_t addr3;
-+			uint32_t addr4;
-+			uint32_t addr5;
-+			uint32_t addr6;
-+			uint32_t data0;
-+			uint32_t data1;
-+			uint32_t data2;
-+			uint32_t data3;
-+			uint32_t data4;
-+			uint32_t data5;
-+			uint32_t data6;
-+		} data;
-+	} *dma_buffer;
-+	dmov_s *cmd;
-+
-+	int err = 0;
-+	uint32_t initialsflashcmd = 0;
-+
-+	initialsflashcmd = flash_rd_reg(chip, MSM_NAND_SFLASHC_CMD);
-+
-+	if ((initialsflashcmd & 0x10) == 0x10)
-+		nand_sfcmd_mode = MSM_NAND_SFCMD_ASYNC;
-+	else
-+		nand_sfcmd_mode = MSM_NAND_SFCMD_BURST;
-+
-+	printk(KERN_INFO "SFLASHC Async Mode bit: %x \n", nand_sfcmd_mode);
-+
-+	wait_event(chip->wait_queue, (dma_buffer = msm_nand_get_dma_buffer
-+				(chip, sizeof(*dma_buffer))));
-+
-+	cmd = dma_buffer->cmd;
-+
-+	dma_buffer->data.bcfg = SFLASH_BCFG |
-+					(nand_sfcmd_mode ? 0 : (1 << 24));
-+	dma_buffer->data.cmd = SFLASH_PREPCMD(7, 0, 0,
-+						MSM_NAND_SFCMD_DATXS,
-+						nand_sfcmd_mode,
-+						MSM_NAND_SFCMD_REGRD);
-+	dma_buffer->data.exec = 1;
-+	dma_buffer->data.status = CLEAN_DATA_32;
-+	dma_buffer->data.addr0 = (ONENAND_DEVICE_ID << 16) |
-+						(ONENAND_MANUFACTURER_ID);
-+	dma_buffer->data.addr1 = (ONENAND_DATA_BUFFER_SIZE << 16) |
-+						(ONENAND_VERSION_ID);
-+	dma_buffer->data.addr2 = (ONENAND_AMOUNT_OF_BUFFERS << 16) |
-+						(ONENAND_BOOT_BUFFER_SIZE);
-+	dma_buffer->data.addr3 = (CLEAN_DATA_16 << 16) |
-+						(ONENAND_TECHNOLOGY << 0);
-+	dma_buffer->data.data0 = CLEAN_DATA_32;
-+	dma_buffer->data.data1 = CLEAN_DATA_32;
-+	dma_buffer->data.data2 = CLEAN_DATA_32;
-+	dma_buffer->data.data3 = CLEAN_DATA_32;
-+
-+	/* Enable and configure the SFlash controller */
-+	cmd->cmd = 0;
-+	cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.bcfg);
-+	cmd->dst = MSM_NAND_SFLASHC_BURST_CFG;
-+	cmd->len = 4;
-+	cmd++;
-+
-+	/* Block on cmd ready and write CMD register */
-+	cmd->cmd = DST_CRCI_NAND_CMD;
-+	cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.cmd);
-+	cmd->dst = MSM_NAND_SFLASHC_CMD;
-+	cmd->len = 4;
-+	cmd++;
-+
-+	/* Configure the ADDR0 and ADDR1 registers */
-+	cmd->cmd = 0;
-+	cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.addr0);
-+	cmd->dst = MSM_NAND_ADDR0;
-+	cmd->len = 8;
-+	cmd++;
-+
-+	/* Configure the ADDR2 and ADDR3 registers */
-+	cmd->cmd = 0;
-+	cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.addr2);
-+	cmd->dst = MSM_NAND_ADDR2;
-+	cmd->len = 8;
-+	cmd++;
-+
-+	/* Kick the execute command */
-+	cmd->cmd = 0;
-+	cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.exec);
-+	cmd->dst = MSM_NAND_SFLASHC_EXEC_CMD;
-+	cmd->len = 4;
-+	cmd++;
-+
-+	/* Block on data ready, and read the two status registers */
-+	cmd->cmd = SRC_CRCI_NAND_DATA;
-+	cmd->src = MSM_NAND_SFLASHC_STATUS;
-+	cmd->dst = msm_virt_to_dma(chip, &dma_buffer->data.status);
-+	cmd->len = 4;
-+	cmd++;
-+
-+	/* Read data registers - valid only if status says success */
-+	cmd->cmd = 0;
-+	cmd->src = MSM_NAND_GENP_REG0;
-+	cmd->dst = msm_virt_to_dma(chip, &dma_buffer->data.data0);
-+	cmd->len = 16;
-+	cmd++;
-+
-+	BUILD_BUG_ON(7 != ARRAY_SIZE(dma_buffer->cmd));
-+	BUG_ON(cmd - dma_buffer->cmd > ARRAY_SIZE(dma_buffer->cmd));
-+	dma_buffer->cmd[0].cmd |= CMD_OCB;
-+	cmd[-1].cmd |= CMD_OCU | CMD_LC;
-+
-+	dma_buffer->cmdptr = (msm_virt_to_dma(chip, dma_buffer->cmd)
-+			>> 3) | CMD_PTR_LP;
-+
-+	mb();
-+	msm_dmov_exec_cmd(chip->dma_channel, DMOV_CMD_PTR_LIST
-+			| DMOV_CMD_ADDR(msm_virt_to_dma(chip,
-+			&dma_buffer->cmdptr)));
-+	mb();
-+
-+	/* Check for errors, protection violations etc */
-+	if (dma_buffer->data.status & 0x110) {
-+		pr_info("%s: MPU/OP error"
-+				"(0x%x) during Onenand probe\n",
-+				__func__, dma_buffer->data.status);
-+		err = -EIO;
-+	} else {
-+
-+		onenand_info.manufacturer_id =
-+			(dma_buffer->data.data0 >> 0) & 0x0000FFFF;
-+		onenand_info.device_id =
-+			(dma_buffer->data.data0 >> 16) & 0x0000FFFF;
-+		onenand_info.version_id =
-+			(dma_buffer->data.data1 >> 0) & 0x0000FFFF;
-+		onenand_info.data_buf_size =
-+			(dma_buffer->data.data1 >> 16) & 0x0000FFFF;
-+		onenand_info.boot_buf_size =
-+			(dma_buffer->data.data2 >> 0) & 0x0000FFFF;
-+		onenand_info.num_of_buffers =
-+			(dma_buffer->data.data2 >> 16) & 0x0000FFFF;
-+		onenand_info.technology =
-+			(dma_buffer->data.data3 >> 0) & 0x0000FFFF;
-+
-+
-+		pr_info("======================================="
-+				"==========================\n");
-+
-+		pr_info("%s: manufacturer_id = 0x%x\n"
-+				, __func__, onenand_info.manufacturer_id);
-+		pr_info("%s: device_id = 0x%x\n"
-+				, __func__, onenand_info.device_id);
-+		pr_info("%s: version_id = 0x%x\n"
-+				, __func__, onenand_info.version_id);
-+		pr_info("%s: data_buf_size = 0x%x\n"
-+				, __func__, onenand_info.data_buf_size);
-+		pr_info("%s: boot_buf_size = 0x%x\n"
-+				, __func__, onenand_info.boot_buf_size);
-+		pr_info("%s: num_of_buffers = 0x%x\n"
-+				, __func__, onenand_info.num_of_buffers);
-+		pr_info("%s: technology = 0x%x\n"
-+				, __func__, onenand_info.technology);
-+
-+		pr_info("======================================="
-+				"==========================\n");
-+
-+		if ((onenand_info.manufacturer_id != 0x00EC)
-+			|| ((onenand_info.device_id & 0x0040) != 0x0040)
-+			|| (onenand_info.data_buf_size != 0x0800)
-+			|| (onenand_info.boot_buf_size != 0x0200)
-+			|| (onenand_info.num_of_buffers != 0x0201)
-+			|| (onenand_info.technology != 0)) {
-+
-+			pr_info("%s: Detected an unsupported device\n"
-+				, __func__);
-+			err = -EIO;
-+		}
-+	}
-+
-+	msm_nand_release_dma_buffer(chip, dma_buffer, sizeof(*dma_buffer));
-+
-+	return err;
-+}
-+
-+int msm_onenand_read_oob(struct mtd_info *mtd,
-+		loff_t from, struct mtd_oob_ops *ops)
-+{
-+	struct msm_nand_chip *chip = mtd->priv;
-+
-+	struct {
-+		dmov_s cmd[53];
-+		unsigned cmdptr;
-+		struct {
-+			uint32_t sfbcfg;
-+			uint32_t sfcmd[9];
-+			uint32_t sfexec;
-+			uint32_t sfstat[9];
-+			uint32_t addr0;
-+			uint32_t addr1;
-+			uint32_t addr2;
-+			uint32_t addr3;
-+			uint32_t addr4;
-+			uint32_t addr5;
-+			uint32_t addr6;
-+			uint32_t data0;
-+			uint32_t data1;
-+			uint32_t data2;
-+			uint32_t data3;
-+			uint32_t data4;
-+			uint32_t data5;
-+			uint32_t data6;
-+			uint32_t macro[5];
-+		} data;
-+	} *dma_buffer;
-+	dmov_s *cmd;
-+
-+	int err = 0;
-+	int i;
-+	dma_addr_t data_dma_addr = 0;
-+	dma_addr_t oob_dma_addr = 0;
-+	dma_addr_t data_dma_addr_curr = 0;
-+	dma_addr_t oob_dma_addr_curr = 0;
-+
-+	loff_t from_curr = 0;
-+	unsigned page_count;
-+	unsigned pages_read = 0;
-+
-+	uint16_t onenand_startaddr1;
-+	uint16_t onenand_startaddr8;
-+	uint16_t onenand_startaddr2;
-+	uint16_t onenand_startbuffer;
-+	uint16_t onenand_sysconfig1;
-+	uint16_t controller_status;
-+	uint16_t interrupt_status;
-+	uint16_t ecc_status;
-+#if VERBOSE
-+	pr_info("================================================="
-+			"================\n");
-+	pr_info("%s: from 0x%llx mode %d \ndatbuf 0x%p datlen 0x%x"
-+			"\noobbuf 0x%p ooblen 0x%x\n",
-+			__func__, from, ops->mode, ops->datbuf, ops->len,
-+			ops->oobbuf, ops->ooblen);
-+#endif
-+	if (!mtd) {
-+		pr_err("%s: invalid mtd pointer, 0x%x\n", __func__,
-+				(uint32_t)mtd);
-+		return -EINVAL;
-+	}
-+	if (from & (mtd->writesize - 1)) {
-+		pr_err("%s: unsupported from, 0x%llx\n", __func__,
-+				from);
-+		return -EINVAL;
-+	}
-+
-+	if ((ops->mode != MTD_OPS_PLACE_OOB) && (ops->mode != MTD_OPS_AUTO_OOB) &&
-+			(ops->mode != MTD_OPS_RAW)) {
-+		pr_err("%s: unsupported ops->mode, %d\n", __func__,
-+				ops->mode);
-+		return -EINVAL;
-+	}
-+
-+	if (((ops->datbuf == NULL) || (ops->len == 0)) &&
-+			((ops->oobbuf == NULL) || (ops->ooblen == 0))) {
-+		pr_err("%s: incorrect ops fields - nothing to do\n",
-+				__func__);
-+		return -EINVAL;
-+	}
-+
-+	if ((ops->datbuf != NULL) && (ops->len == 0)) {
-+		pr_err("%s: data buffer passed but length 0\n",
-+				__func__);
-+		return -EINVAL;
-+	}
-+
-+	if ((ops->oobbuf != NULL) && (ops->ooblen == 0)) {
-+		pr_err("%s: oob buffer passed but length 0\n",
-+				__func__);
-+		return -EINVAL;
-+	}
-+
-+	if (ops->mode != MTD_OPS_RAW) {
-+		if (ops->datbuf != NULL && (ops->len % mtd->writesize) != 0) {
-+			/* when ops->datbuf is NULL, ops->len can be ooblen */
-+			pr_err("%s: unsupported ops->len, %d\n", __func__,
-+					ops->len);
-+			return -EINVAL;
-+		}
-+	} else {
-+		if (ops->datbuf != NULL &&
-+			(ops->len % (mtd->writesize + mtd->oobsize)) != 0) {
-+			pr_err("%s: unsupported ops->len,"
-+				" %d for MTD_OPS_RAW\n", __func__, ops->len);
-+			return -EINVAL;
-+		}
-+	}
-+
-+	if ((ops->mode == MTD_OPS_RAW) && (ops->oobbuf)) {
-+		pr_err("%s: unsupported operation, oobbuf pointer "
-+				"passed in for RAW mode, %x\n", __func__,
-+				(uint32_t)ops->oobbuf);
-+		return -EINVAL;
-+	}
-+
-+	if (ops->oobbuf && !ops->datbuf) {
-+		page_count = ops->ooblen / ((ops->mode == MTD_OPS_AUTO_OOB) ?
-+			mtd->oobavail : mtd->oobsize);
-+		if ((page_count == 0) && (ops->ooblen))
-+			page_count = 1;
-+	} else if (ops->mode != MTD_OPS_RAW)
-+			page_count = ops->len / mtd->writesize;
-+		else
-+			page_count = ops->len / (mtd->writesize + mtd->oobsize);
-+
-+	if ((ops->mode == MTD_OPS_PLACE_OOB) && (ops->oobbuf != NULL)) {
-+		if (page_count * mtd->oobsize > ops->ooblen) {
-+			pr_err("%s: unsupported ops->ooblen for "
-+				"PLACE, %d\n", __func__, ops->ooblen);
-+			return -EINVAL;
-+		}
-+	}
-+
-+	if ((ops->mode == MTD_OPS_PLACE_OOB) && (ops->ooblen != 0) &&
-+							(ops->ooboffs != 0)) {
-+		pr_err("%s: unsupported ops->ooboffs, %d\n", __func__,
-+				ops->ooboffs);
-+		return -EINVAL;
-+	}
-+
-+	if (ops->datbuf) {
-+		memset(ops->datbuf, 0x55, ops->len);
-+		data_dma_addr_curr = data_dma_addr = msm_nand_dma_map(chip->dev,
-+				ops->datbuf, ops->len, DMA_FROM_DEVICE, NULL);
-+		if (dma_mapping_error(chip->dev, data_dma_addr)) {
-+			pr_err("%s: failed to get dma addr for %p\n",
-+					__func__, ops->datbuf);
-+			return -EIO;
-+		}
-+	}
-+	if (ops->oobbuf) {
-+		memset(ops->oobbuf, 0x55, ops->ooblen);
-+		oob_dma_addr_curr = oob_dma_addr = msm_nand_dma_map(chip->dev,
-+				ops->oobbuf, ops->ooblen, DMA_FROM_DEVICE, NULL);
-+		if (dma_mapping_error(chip->dev, oob_dma_addr)) {
-+			pr_err("%s: failed to get dma addr for %p\n",
-+					__func__, ops->oobbuf);
-+			err = -EIO;
-+			goto err_dma_map_oobbuf_failed;
-+		}
-+	}
-+
-+	wait_event(chip->wait_queue, (dma_buffer = msm_nand_get_dma_buffer
-+				(chip, sizeof(*dma_buffer))));
-+
-+	from_curr = from;
-+
-+	while (page_count-- > 0) {
-+
-+		cmd = dma_buffer->cmd;
-+
-+		if ((onenand_info.device_id & ONENAND_DEVICE_IS_DDP)
-+			&& (from_curr >= (mtd->size>>1))) { /* DDP Device */
-+				onenand_startaddr1 = DEVICE_FLASHCORE_1 |
-+					(((uint32_t)(from_curr-(mtd->size>>1))
-+					/ mtd->erasesize));
-+				onenand_startaddr2 = DEVICE_BUFFERRAM_1;
-+		} else {
-+				onenand_startaddr1 = DEVICE_FLASHCORE_0 |
-+				((uint32_t)from_curr / mtd->erasesize) ;
-+				onenand_startaddr2 = DEVICE_BUFFERRAM_0;
-+		}
-+
-+		onenand_startaddr8 = (((uint32_t)from_curr &
-+				(mtd->erasesize - 1)) / mtd->writesize) << 2;
-+		onenand_startbuffer = DATARAM0_0 << 8;
-+		onenand_sysconfig1 = (ops->mode == MTD_OPS_RAW) ?
-+			ONENAND_SYSCFG1_ECCDIS(nand_sfcmd_mode) :
-+			ONENAND_SYSCFG1_ECCENA(nand_sfcmd_mode);
-+
-+		dma_buffer->data.sfbcfg = SFLASH_BCFG |
-+					(nand_sfcmd_mode ? 0 : (1 << 24));
-+		dma_buffer->data.sfcmd[0] =  SFLASH_PREPCMD(7, 0, 0,
-+							MSM_NAND_SFCMD_CMDXS,
-+							nand_sfcmd_mode,
-+							MSM_NAND_SFCMD_REGWR);
-+		dma_buffer->data.sfcmd[1] =  SFLASH_PREPCMD(0, 0, 32,
-+							MSM_NAND_SFCMD_CMDXS,
-+							nand_sfcmd_mode,
-+							MSM_NAND_SFCMD_INTHI);
-+		dma_buffer->data.sfcmd[2] =  SFLASH_PREPCMD(3, 7, 0,
-+							MSM_NAND_SFCMD_DATXS,
-+							nand_sfcmd_mode,
-+							MSM_NAND_SFCMD_REGRD);
-+		dma_buffer->data.sfcmd[3] =  SFLASH_PREPCMD(256, 0, 0,
-+							MSM_NAND_SFCMD_DATXS,
-+							nand_sfcmd_mode,
-+							MSM_NAND_SFCMD_DATRD);
-+		dma_buffer->data.sfcmd[4] =  SFLASH_PREPCMD(256, 0, 0,
-+							MSM_NAND_SFCMD_DATXS,
-+							nand_sfcmd_mode,
-+							MSM_NAND_SFCMD_DATRD);
-+		dma_buffer->data.sfcmd[5] =  SFLASH_PREPCMD(256, 0, 0,
-+							MSM_NAND_SFCMD_DATXS,
-+							nand_sfcmd_mode,
-+							MSM_NAND_SFCMD_DATRD);
-+		dma_buffer->data.sfcmd[6] =  SFLASH_PREPCMD(256, 0, 0,
-+							MSM_NAND_SFCMD_DATXS,
-+							nand_sfcmd_mode,
-+							MSM_NAND_SFCMD_DATRD);
-+		dma_buffer->data.sfcmd[7] =  SFLASH_PREPCMD(32, 0, 0,
-+							MSM_NAND_SFCMD_DATXS,
-+							nand_sfcmd_mode,
-+							MSM_NAND_SFCMD_DATRD);
-+		dma_buffer->data.sfcmd[8] =  SFLASH_PREPCMD(4, 10, 0,
-+							MSM_NAND_SFCMD_CMDXS,
-+							nand_sfcmd_mode,
-+							MSM_NAND_SFCMD_REGWR);
-+		dma_buffer->data.sfexec = 1;
-+		dma_buffer->data.sfstat[0] = CLEAN_DATA_32;
-+		dma_buffer->data.sfstat[1] = CLEAN_DATA_32;
-+		dma_buffer->data.sfstat[2] = CLEAN_DATA_32;
-+		dma_buffer->data.sfstat[3] = CLEAN_DATA_32;
-+		dma_buffer->data.sfstat[4] = CLEAN_DATA_32;
-+		dma_buffer->data.sfstat[5] = CLEAN_DATA_32;
-+		dma_buffer->data.sfstat[6] = CLEAN_DATA_32;
-+		dma_buffer->data.sfstat[7] = CLEAN_DATA_32;
-+		dma_buffer->data.sfstat[8] = CLEAN_DATA_32;
-+		dma_buffer->data.addr0 = (ONENAND_INTERRUPT_STATUS << 16) |
-+						(ONENAND_SYSTEM_CONFIG_1);
-+		dma_buffer->data.addr1 = (ONENAND_START_ADDRESS_8 << 16) |
-+						(ONENAND_START_ADDRESS_1);
-+		dma_buffer->data.addr2 = (ONENAND_START_BUFFER << 16) |
-+						(ONENAND_START_ADDRESS_2);
-+		dma_buffer->data.addr3 = (ONENAND_ECC_STATUS << 16) |
-+						(ONENAND_COMMAND);
-+		dma_buffer->data.addr4 = (ONENAND_CONTROLLER_STATUS << 16) |
-+						(ONENAND_INTERRUPT_STATUS);
-+		dma_buffer->data.addr5 = (ONENAND_INTERRUPT_STATUS << 16) |
-+						(ONENAND_SYSTEM_CONFIG_1);
-+		dma_buffer->data.addr6 = (ONENAND_START_ADDRESS_3 << 16) |
-+						(ONENAND_START_ADDRESS_1);
-+		dma_buffer->data.data0 = (ONENAND_CLRINTR << 16) |
-+						(onenand_sysconfig1);
-+		dma_buffer->data.data1 = (onenand_startaddr8 << 16) |
-+						(onenand_startaddr1);
-+		dma_buffer->data.data2 = (onenand_startbuffer << 16) |
-+						(onenand_startaddr2);
-+		dma_buffer->data.data3 = (CLEAN_DATA_16 << 16) |
-+						(ONENAND_CMDLOADSPARE);
-+		dma_buffer->data.data4 = (CLEAN_DATA_16 << 16) |
-+						(CLEAN_DATA_16);
-+		dma_buffer->data.data5 = (ONENAND_CLRINTR << 16) |
-+				(ONENAND_SYSCFG1_ECCENA(nand_sfcmd_mode));
-+		dma_buffer->data.data6 = (ONENAND_STARTADDR3_RES << 16) |
-+						(ONENAND_STARTADDR1_RES);
-+		dma_buffer->data.macro[0] = 0x0200;
-+		dma_buffer->data.macro[1] = 0x0300;
-+		dma_buffer->data.macro[2] = 0x0400;
-+		dma_buffer->data.macro[3] = 0x0500;
-+		dma_buffer->data.macro[4] = 0x8010;
-+
-+		/*************************************************************/
-+		/* Write necessary address registers in the onenand device   */
-+		/*************************************************************/
-+
-+		/* Enable and configure the SFlash controller */
-+		cmd->cmd = 0;
-+		cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.sfbcfg);
-+		cmd->dst = MSM_NAND_SFLASHC_BURST_CFG;
-+		cmd->len = 4;
-+		cmd++;
-+
-+		/* Block on cmd ready and write CMD register */
-+		cmd->cmd = DST_CRCI_NAND_CMD;
-+		cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.sfcmd[0]);
-+		cmd->dst = MSM_NAND_SFLASHC_CMD;
-+		cmd->len = 4;
-+		cmd++;
-+
-+		/* Write the ADDR0 and ADDR1 registers */
-+		cmd->cmd = 0;
-+		cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.addr0);
-+		cmd->dst = MSM_NAND_ADDR0;
-+		cmd->len = 8;
-+		cmd++;
-+
-+		/* Write the ADDR2 ADDR3 ADDR4 ADDR5 registers */
-+		cmd->cmd = 0;
-+		cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.addr2);
-+		cmd->dst = MSM_NAND_ADDR2;
-+		cmd->len = 16;
-+		cmd++;
-+
-+		/* Write the ADDR6 registers */
-+		cmd->cmd = 0;
-+		cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.addr6);
-+		cmd->dst = MSM_NAND_ADDR6;
-+		cmd->len = 4;
-+		cmd++;
-+
-+		/* Write the GENP0, GENP1, GENP2, GENP3 registers */
-+		cmd->cmd = 0;
-+		cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.data0);
-+		cmd->dst = MSM_NAND_GENP_REG0;
-+		cmd->len = 16;
-+		cmd++;
-+
-+		/* Write the FLASH_DEV_CMD4,5,6 registers */
-+		cmd->cmd = 0;
-+		cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.data4);
-+		cmd->dst = MSM_NAND_DEV_CMD4;
-+		cmd->len = 12;
-+		cmd++;
-+
-+		/* Kick the execute command */
-+		cmd->cmd = 0;
-+		cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.sfexec);
-+		cmd->dst = MSM_NAND_SFLASHC_EXEC_CMD;
-+		cmd->len = 4;
-+		cmd++;
-+
-+		/* Block on data ready, and read the status register */
-+		cmd->cmd = SRC_CRCI_NAND_DATA;
-+		cmd->src = MSM_NAND_SFLASHC_STATUS;
-+		cmd->dst = msm_virt_to_dma(chip, &dma_buffer->data.sfstat[0]);
-+		cmd->len = 4;
-+		cmd++;
-+
-+		/*************************************************************/
-+		/* Wait for the interrupt from the Onenand device controller */
-+		/*************************************************************/
-+
-+		/* Block on cmd ready and write CMD register */
-+		cmd->cmd = DST_CRCI_NAND_CMD;
-+		cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.sfcmd[1]);
-+		cmd->dst = MSM_NAND_SFLASHC_CMD;
-+		cmd->len = 4;
-+		cmd++;
-+
-+		/* Kick the execute command */
-+		cmd->cmd = 0;
-+		cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.sfexec);
-+		cmd->dst = MSM_NAND_SFLASHC_EXEC_CMD;
-+		cmd->len = 4;
-+		cmd++;
-+
-+		/* Block on data ready, and read the status register */
-+		cmd->cmd = SRC_CRCI_NAND_DATA;
-+		cmd->src = MSM_NAND_SFLASHC_STATUS;
-+		cmd->dst = msm_virt_to_dma(chip, &dma_buffer->data.sfstat[1]);
-+		cmd->len = 4;
-+		cmd++;
-+
-+		/*************************************************************/
-+		/* Read necessary status registers from the onenand device   */
-+		/*************************************************************/
-+
-+		/* Block on cmd ready and write CMD register */
-+		cmd->cmd = DST_CRCI_NAND_CMD;
-+		cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.sfcmd[2]);
-+		cmd->dst = MSM_NAND_SFLASHC_CMD;
-+		cmd->len = 4;
-+		cmd++;
-+
-+		/* Kick the execute command */
-+		cmd->cmd = 0;
-+		cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.sfexec);
-+		cmd->dst = MSM_NAND_SFLASHC_EXEC_CMD;
-+		cmd->len = 4;
-+		cmd++;
-+
-+		/* Block on data ready, and read the status register */
-+		cmd->cmd = SRC_CRCI_NAND_DATA;
-+		cmd->src = MSM_NAND_SFLASHC_STATUS;
-+		cmd->dst = msm_virt_to_dma(chip, &dma_buffer->data.sfstat[2]);
-+		cmd->len = 4;
-+		cmd++;
-+
-+		/* Read the GENP3 register */
-+		cmd->cmd = 0;
-+		cmd->src = MSM_NAND_GENP_REG3;
-+		cmd->dst = msm_virt_to_dma(chip, &dma_buffer->data.data3);
-+		cmd->len = 4;
-+		cmd++;
-+
-+		/* Read the DEVCMD4 register */
-+		cmd->cmd = 0;
-+		cmd->src = MSM_NAND_DEV_CMD4;
-+		cmd->dst = msm_virt_to_dma(chip, &dma_buffer->data.data4);
-+		cmd->len = 4;
-+		cmd++;
-+
-+		/*************************************************************/
-+		/* Read the data ram area from the onenand buffer ram        */
-+		/*************************************************************/
-+
-+		if (ops->datbuf) {
-+
-+			dma_buffer->data.data3 = (CLEAN_DATA_16 << 16) |
-+							(ONENAND_CMDLOAD);
-+
-+			for (i = 0; i < 4; i++) {
-+
-+				/* Block on cmd ready and write CMD register */
-+				cmd->cmd = DST_CRCI_NAND_CMD;
-+				cmd->src = msm_virt_to_dma(chip,
-+						&dma_buffer->data.sfcmd[3+i]);
-+				cmd->dst = MSM_NAND_SFLASHC_CMD;
-+				cmd->len = 4;
-+				cmd++;
-+
-+				/* Write the MACRO1 register */
-+				cmd->cmd = 0;
-+				cmd->src = msm_virt_to_dma(chip,
-+						&dma_buffer->data.macro[i]);
-+				cmd->dst = MSM_NAND_MACRO1_REG;
-+				cmd->len = 4;
-+				cmd++;
-+
-+				/* Kick the execute command */
-+				cmd->cmd = 0;
-+				cmd->src = msm_virt_to_dma(chip,
-+						&dma_buffer->data.sfexec);
-+				cmd->dst = MSM_NAND_SFLASHC_EXEC_CMD;
-+				cmd->len = 4;
-+				cmd++;
-+
-+				/* Block on data rdy, & read status register */
-+				cmd->cmd = SRC_CRCI_NAND_DATA;
-+				cmd->src = MSM_NAND_SFLASHC_STATUS;
-+				cmd->dst = msm_virt_to_dma(chip,
-+						&dma_buffer->data.sfstat[3+i]);
-+				cmd->len = 4;
-+				cmd++;
-+
-+				/* Transfer nand ctlr buf contents to usr buf */
-+				cmd->cmd = 0;
-+				cmd->src = MSM_NAND_FLASH_BUFFER;
-+				cmd->dst = data_dma_addr_curr;
-+				cmd->len = 512;
-+				data_dma_addr_curr += 512;
-+				cmd++;
-+			}
-+		}
-+
-+		if ((ops->oobbuf) || (ops->mode == MTD_OPS_RAW)) {
-+
-+			/* Block on cmd ready and write CMD register */
-+			cmd->cmd = DST_CRCI_NAND_CMD;
-+			cmd->src = msm_virt_to_dma(chip,
-+					&dma_buffer->data.sfcmd[7]);
-+			cmd->dst = MSM_NAND_SFLASHC_CMD;
-+			cmd->len = 4;
-+			cmd++;
-+
-+			/* Write the MACRO1 register */
-+			cmd->cmd = 0;
-+			cmd->src = msm_virt_to_dma(chip,
-+					&dma_buffer->data.macro[4]);
-+			cmd->dst = MSM_NAND_MACRO1_REG;
-+			cmd->len = 4;
-+			cmd++;
-+
-+			/* Kick the execute command */
-+			cmd->cmd = 0;
-+			cmd->src = msm_virt_to_dma(chip,
-+					&dma_buffer->data.sfexec);
-+			cmd->dst = MSM_NAND_SFLASHC_EXEC_CMD;
-+			cmd->len = 4;
-+			cmd++;
-+
-+			/* Block on data ready, and read status register */
-+			cmd->cmd = SRC_CRCI_NAND_DATA;
-+			cmd->src = MSM_NAND_SFLASHC_STATUS;
-+			cmd->dst = msm_virt_to_dma(chip,
-+					&dma_buffer->data.sfstat[7]);
-+			cmd->len = 4;
-+			cmd++;
-+
-+			/* Transfer nand ctlr buffer contents into usr buf */
-+			if (ops->mode == MTD_OPS_AUTO_OOB) {
-+				for (i = 0; i < MTD_MAX_OOBFREE_ENTRIES; i++) {
-+					cmd->cmd = 0;
-+					cmd->src = MSM_NAND_FLASH_BUFFER +
-+					mtd->ecclayout->oobfree[i].offset;
-+					cmd->dst = oob_dma_addr_curr;
-+					cmd->len =
-+					mtd->ecclayout->oobfree[i].length;
-+					oob_dma_addr_curr +=
-+					mtd->ecclayout->oobfree[i].length;
-+					cmd++;
-+				}
-+			}
-+			if (ops->mode == MTD_OPS_PLACE_OOB) {
-+					cmd->cmd = 0;
-+					cmd->src = MSM_NAND_FLASH_BUFFER;
-+					cmd->dst = oob_dma_addr_curr;
-+					cmd->len = mtd->oobsize;
-+					oob_dma_addr_curr += mtd->oobsize;
-+					cmd++;
-+			}
-+			if (ops->mode == MTD_OPS_RAW) {
-+					cmd->cmd = 0;
-+					cmd->src = MSM_NAND_FLASH_BUFFER;
-+					cmd->dst = data_dma_addr_curr;
-+					cmd->len = mtd->oobsize;
-+					data_dma_addr_curr += mtd->oobsize;
-+					cmd++;
-+			}
-+		}
-+
-+		/*************************************************************/
-+		/* Restore the necessary registers to proper values          */
-+		/*************************************************************/
-+
-+		/* Block on cmd ready and write CMD register */
-+		cmd->cmd = DST_CRCI_NAND_CMD;
-+		cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.sfcmd[8]);
-+		cmd->dst = MSM_NAND_SFLASHC_CMD;
-+		cmd->len = 4;
-+		cmd++;
-+
-+		/* Kick the execute command */
-+		cmd->cmd = 0;
-+		cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.sfexec);
-+		cmd->dst = MSM_NAND_SFLASHC_EXEC_CMD;
-+		cmd->len = 4;
-+		cmd++;
-+
-+		/* Block on data ready, and read the status register */
-+		cmd->cmd = SRC_CRCI_NAND_DATA;
-+		cmd->src = MSM_NAND_SFLASHC_STATUS;
-+		cmd->dst = msm_virt_to_dma(chip, &dma_buffer->data.sfstat[8]);
-+		cmd->len = 4;
-+		cmd++;
-+
-+
-+		BUILD_BUG_ON(53 != ARRAY_SIZE(dma_buffer->cmd));
-+		BUG_ON(cmd - dma_buffer->cmd > ARRAY_SIZE(dma_buffer->cmd));
-+		dma_buffer->cmd[0].cmd |= CMD_OCB;
-+		cmd[-1].cmd |= CMD_OCU | CMD_LC;
-+
-+		dma_buffer->cmdptr = (msm_virt_to_dma(chip, dma_buffer->cmd)
-+				>> 3) | CMD_PTR_LP;
-+
-+		mb();
-+		msm_dmov_exec_cmd(chip->dma_channel,
-+			DMOV_CMD_PTR_LIST | DMOV_CMD_ADDR(msm_virt_to_dma(chip,
-+				&dma_buffer->cmdptr)));
-+		mb();
-+
-+		ecc_status = (dma_buffer->data.data3 >> 16) &
-+							0x0000FFFF;
-+		interrupt_status = (dma_buffer->data.data4 >> 0) &
-+							0x0000FFFF;
-+		controller_status = (dma_buffer->data.data4 >> 16) &
-+							0x0000FFFF;
-+
-+#if VERBOSE
-+		pr_info("\n%s: sflash status %x %x %x %x %x %x %x"
-+				"%x %x\n", __func__,
-+					dma_buffer->data.sfstat[0],
-+					dma_buffer->data.sfstat[1],
-+					dma_buffer->data.sfstat[2],
-+					dma_buffer->data.sfstat[3],
-+					dma_buffer->data.sfstat[4],
-+					dma_buffer->data.sfstat[5],
-+					dma_buffer->data.sfstat[6],
-+					dma_buffer->data.sfstat[7],
-+					dma_buffer->data.sfstat[8]);
-+
-+		pr_info("%s: controller_status = %x\n", __func__,
-+					controller_status);
-+		pr_info("%s: interrupt_status = %x\n", __func__,
-+					interrupt_status);
-+		pr_info("%s: ecc_status = %x\n", __func__,
-+					ecc_status);
-+#endif
-+		/* Check for errors, protection violations etc */
-+		if ((controller_status != 0)
-+				|| (dma_buffer->data.sfstat[0] & 0x110)
-+				|| (dma_buffer->data.sfstat[1] & 0x110)
-+				|| (dma_buffer->data.sfstat[2] & 0x110)
-+				|| (dma_buffer->data.sfstat[8] & 0x110)
-+				|| ((dma_buffer->data.sfstat[3] & 0x110) &&
-+								(ops->datbuf))
-+				|| ((dma_buffer->data.sfstat[4] & 0x110) &&
-+								(ops->datbuf))
-+				|| ((dma_buffer->data.sfstat[5] & 0x110) &&
-+								(ops->datbuf))
-+				|| ((dma_buffer->data.sfstat[6] & 0x110) &&
-+								(ops->datbuf))
-+				|| ((dma_buffer->data.sfstat[7] & 0x110) &&
-+								((ops->oobbuf)
-+					|| (ops->mode == MTD_OPS_RAW)))) {
-+			pr_info("%s: ECC/MPU/OP error\n", __func__);
-+			err = -EIO;
-+		}
-+
-+		if (err)
-+			break;
-+		pages_read++;
-+		from_curr += mtd->writesize;
-+	}
-+
-+	msm_nand_release_dma_buffer(chip, dma_buffer, sizeof(*dma_buffer));
-+
-+	if (ops->oobbuf) {
-+		dma_unmap_page(chip->dev, oob_dma_addr, ops->ooblen,
-+				DMA_FROM_DEVICE);
-+	}
-+err_dma_map_oobbuf_failed:
-+	if (ops->datbuf) {
-+		dma_unmap_page(chip->dev, data_dma_addr, ops->len,
-+				DMA_FROM_DEVICE);
-+	}
-+
-+	if (err) {
-+		pr_err("%s: %llx %x %x failed\n", __func__, from_curr,
-+				ops->datbuf ? ops->len : 0, ops->ooblen);
-+	} else {
-+		ops->retlen = ops->oobretlen = 0;
-+		if (ops->datbuf != NULL) {
-+			if (ops->mode != MTD_OPS_RAW)
-+				ops->retlen = mtd->writesize * pages_read;
-+			else
-+				ops->retlen = (mtd->writesize +  mtd->oobsize)
-+							* pages_read;
-+		}
-+		if (ops->oobbuf != NULL) {
-+			if (ops->mode == MTD_OPS_AUTO_OOB)
-+				ops->oobretlen = mtd->oobavail * pages_read;
-+			else
-+				ops->oobretlen = mtd->oobsize * pages_read;
-+		}
-+	}
-+
-+#if VERBOSE
-+	pr_info("\n%s: ret %d, retlen %d oobretlen %d\n",
-+			__func__, err, ops->retlen, ops->oobretlen);
-+
-+	pr_info("==================================================="
-+			"==============\n");
-+#endif
-+	return err;
-+}
-+
-+int msm_onenand_read(struct mtd_info *mtd, loff_t from, size_t len,
-+		size_t *retlen, u_char *buf)
-+{
-+	int ret;
-+	struct mtd_oob_ops ops;
-+
-+	ops.mode = MTD_OPS_PLACE_OOB;
-+	ops.datbuf = buf;
-+	ops.len = len;
-+	ops.retlen = 0;
-+	ops.oobbuf = NULL;
-+	ops.ooblen = 0;
-+	ops.oobretlen = 0;
-+	ret =  msm_onenand_read_oob(mtd, from, &ops);
-+	*retlen = ops.retlen;
-+
-+	return ret;
-+}
-+
-+static int msm_onenand_write_oob(struct mtd_info *mtd, loff_t to,
-+		struct mtd_oob_ops *ops)
-+{
-+	struct msm_nand_chip *chip = mtd->priv;
-+
-+	struct {
-+		dmov_s cmd[53];
-+		unsigned cmdptr;
-+		struct {
-+			uint32_t sfbcfg;
-+			uint32_t sfcmd[10];
-+			uint32_t sfexec;
-+			uint32_t sfstat[10];
-+			uint32_t addr0;
-+			uint32_t addr1;
-+			uint32_t addr2;
-+			uint32_t addr3;
-+			uint32_t addr4;
-+			uint32_t addr5;
-+			uint32_t addr6;
-+			uint32_t data0;
-+			uint32_t data1;
-+			uint32_t data2;
-+			uint32_t data3;
-+			uint32_t data4;
-+			uint32_t data5;
-+			uint32_t data6;
-+			uint32_t macro[5];
-+		} data;
-+	} *dma_buffer;
-+	dmov_s *cmd;
-+
-+	int err = 0;
-+	int i, j, k;
-+	dma_addr_t data_dma_addr = 0;
-+	dma_addr_t oob_dma_addr = 0;
-+	dma_addr_t init_dma_addr = 0;
-+	dma_addr_t data_dma_addr_curr = 0;
-+	dma_addr_t oob_dma_addr_curr = 0;
-+	uint8_t *init_spare_bytes;
-+
-+	loff_t to_curr = 0;
-+	unsigned page_count;
-+	unsigned pages_written = 0;
-+
-+	uint16_t onenand_startaddr1;
-+	uint16_t onenand_startaddr8;
-+	uint16_t onenand_startaddr2;
-+	uint16_t onenand_startbuffer;
-+	uint16_t onenand_sysconfig1;
-+
-+	uint16_t controller_status;
-+	uint16_t interrupt_status;
-+	uint16_t ecc_status;
-+
-+#if VERBOSE
-+	pr_info("================================================="
-+			"================\n");
-+	pr_info("%s: to 0x%llx mode %d \ndatbuf 0x%p datlen 0x%x"
-+			"\noobbuf 0x%p ooblen 0x%x\n",
-+			__func__, to, ops->mode, ops->datbuf, ops->len,
-+			ops->oobbuf, ops->ooblen);
-+#endif
-+	if (!mtd) {
-+		pr_err("%s: invalid mtd pointer, 0x%x\n", __func__,
-+				(uint32_t)mtd);
-+		return -EINVAL;
-+	}
-+	if (to & (mtd->writesize - 1)) {
-+		pr_err("%s: unsupported to, 0x%llx\n", __func__, to);
-+		return -EINVAL;
-+	}
-+
-+	if ((ops->mode != MTD_OPS_PLACE_OOB) && (ops->mode != MTD_OPS_AUTO_OOB) &&
-+			(ops->mode != MTD_OPS_RAW)) {
-+		pr_err("%s: unsupported ops->mode, %d\n", __func__,
-+				ops->mode);
-+		return -EINVAL;
-+	}
-+
-+	if (((ops->datbuf == NULL) || (ops->len == 0)) &&
-+			((ops->oobbuf == NULL) || (ops->ooblen == 0))) {
-+		pr_err("%s: incorrect ops fields - nothing to do\n",
-+				__func__);
-+		return -EINVAL;
-+	}
-+
-+	if ((ops->datbuf != NULL) && (ops->len == 0)) {
-+		pr_err("%s: data buffer passed but length 0\n",
-+				__func__);
-+		return -EINVAL;
-+	}
-+
-+	if ((ops->oobbuf != NULL) && (ops->ooblen == 0)) {
-+		pr_err("%s: oob buffer passed but length 0\n",
-+				__func__);
-+		return -EINVAL;
-+	}
-+
-+	if (ops->mode != MTD_OPS_RAW) {
-+		if (ops->datbuf != NULL && (ops->len % mtd->writesize) != 0) {
-+			/* when ops->datbuf is NULL, ops->len can be ooblen */
-+			pr_err("%s: unsupported ops->len, %d\n", __func__,
-+					ops->len);
-+			return -EINVAL;
-+		}
-+	} else {
-+		if (ops->datbuf != NULL &&
-+			(ops->len % (mtd->writesize + mtd->oobsize)) != 0) {
-+			pr_err("%s: unsupported ops->len,"
-+				" %d for MTD_OPS_RAW\n", __func__, ops->len);
-+			return -EINVAL;
-+		}
-+	}
-+
-+	if ((ops->mode == MTD_OPS_RAW) && (ops->oobbuf)) {
-+		pr_err("%s: unsupported operation, oobbuf pointer "
-+				"passed in for RAW mode, %x\n", __func__,
-+				(uint32_t)ops->oobbuf);
-+		return -EINVAL;
-+	}
-+
-+	if (ops->oobbuf && !ops->datbuf) {
-+		page_count = ops->ooblen / ((ops->mode == MTD_OPS_AUTO_OOB) ?
-+			mtd->oobavail : mtd->oobsize);
-+		if ((page_count == 0) && (ops->ooblen))
-+			page_count = 1;
-+	} else if (ops->mode != MTD_OPS_RAW)
-+			page_count = ops->len / mtd->writesize;
-+		else
-+			page_count = ops->len / (mtd->writesize + mtd->oobsize);
-+
-+	if ((ops->mode == MTD_OPS_AUTO_OOB) && (ops->oobbuf != NULL)) {
-+		if (page_count > 1) {
-+			pr_err("%s: unsupported ops->ooblen for"
-+				"AUTO, %d\n", __func__, ops->ooblen);
-+			return -EINVAL;
-+		}
-+	}
-+
-+	if ((ops->mode == MTD_OPS_PLACE_OOB) && (ops->oobbuf != NULL)) {
-+		if (page_count * mtd->oobsize > ops->ooblen) {
-+			pr_err("%s: unsupported ops->ooblen for"
-+				"PLACE,	%d\n", __func__, ops->ooblen);
-+			return -EINVAL;
-+		}
-+	}
-+
-+	if ((ops->mode == MTD_OPS_PLACE_OOB) && (ops->ooblen != 0) &&
-+						(ops->ooboffs != 0)) {
-+		pr_err("%s: unsupported ops->ooboffs, %d\n",
-+				__func__, ops->ooboffs);
-+		return -EINVAL;
-+	}
-+
-+	init_spare_bytes = kmalloc(64, GFP_KERNEL);
-+	if (!init_spare_bytes) {
-+		pr_err("%s: failed to alloc init_spare_bytes buffer\n",
-+				__func__);
-+		return -ENOMEM;
-+	}
-+	for (i = 0; i < 64; i++)
-+		init_spare_bytes[i] = 0xFF;
-+
-+	if ((ops->oobbuf) && (ops->mode == MTD_OPS_AUTO_OOB)) {
-+		for (i = 0, k = 0; i < MTD_MAX_OOBFREE_ENTRIES; i++)
-+			for (j = 0; j < mtd->ecclayout->oobfree[i].length;
-+					j++) {
-+				init_spare_bytes[j +
-+					mtd->ecclayout->oobfree[i].offset]
-+						= (ops->oobbuf)[k];
-+				k++;
-+			}
-+	}
-+
-+	if (ops->datbuf) {
-+		data_dma_addr_curr = data_dma_addr = msm_nand_dma_map(chip->dev,
-+				ops->datbuf, ops->len, DMA_TO_DEVICE, NULL);
-+		if (dma_mapping_error(chip->dev, data_dma_addr)) {
-+			pr_err("%s: failed to get dma addr for %p\n",
-+					__func__, ops->datbuf);
-+			return -EIO;
-+		}
-+	}
-+	if (ops->oobbuf) {
-+		oob_dma_addr_curr = oob_dma_addr = msm_nand_dma_map(chip->dev,
-+				ops->oobbuf, ops->ooblen, DMA_TO_DEVICE, NULL);
-+		if (dma_mapping_error(chip->dev, oob_dma_addr)) {
-+			pr_err("%s: failed to get dma addr for %p\n",
-+					__func__, ops->oobbuf);
-+			err = -EIO;
-+			goto err_dma_map_oobbuf_failed;
-+		}
-+	}
-+
-+	init_dma_addr = msm_nand_dma_map(chip->dev, init_spare_bytes, 64,
-+					 DMA_TO_DEVICE, NULL);
-+	if (dma_mapping_error(chip->dev, init_dma_addr)) {
-+		pr_err("%s: failed to get dma addr for %p\n",
-+				__func__, init_spare_bytes);
-+		err = -EIO;
-+		goto err_dma_map_initbuf_failed;
-+	}
-+
-+
-+	wait_event(chip->wait_queue, (dma_buffer = msm_nand_get_dma_buffer
-+				(chip, sizeof(*dma_buffer))));
-+
-+	to_curr = to;
-+
-+	while (page_count-- > 0) {
-+		cmd = dma_buffer->cmd;
-+
-+		if ((onenand_info.device_id & ONENAND_DEVICE_IS_DDP)
-+			&& (to_curr >= (mtd->size>>1))) { /* DDP Device */
-+				onenand_startaddr1 = DEVICE_FLASHCORE_1 |
-+					(((uint32_t)(to_curr-(mtd->size>>1))
-+					/ mtd->erasesize));
-+				onenand_startaddr2 = DEVICE_BUFFERRAM_1;
-+		} else {
-+				onenand_startaddr1 = DEVICE_FLASHCORE_0 |
-+					((uint32_t)to_curr / mtd->erasesize) ;
-+				onenand_startaddr2 = DEVICE_BUFFERRAM_0;
-+		}
-+
-+		onenand_startaddr8 = (((uint32_t)to_curr &
-+				(mtd->erasesize - 1)) / mtd->writesize) << 2;
-+		onenand_startbuffer = DATARAM0_0 << 8;
-+		onenand_sysconfig1 = (ops->mode == MTD_OPS_RAW) ?
-+			ONENAND_SYSCFG1_ECCDIS(nand_sfcmd_mode) :
-+			ONENAND_SYSCFG1_ECCENA(nand_sfcmd_mode);
-+
-+		dma_buffer->data.sfbcfg = SFLASH_BCFG |
-+					(nand_sfcmd_mode ? 0 : (1 << 24));
-+		dma_buffer->data.sfcmd[0] =  SFLASH_PREPCMD(6, 0, 0,
-+							MSM_NAND_SFCMD_CMDXS,
-+							nand_sfcmd_mode,
-+							MSM_NAND_SFCMD_REGWR);
-+		dma_buffer->data.sfcmd[1] =  SFLASH_PREPCMD(256, 0, 0,
-+							MSM_NAND_SFCMD_CMDXS,
-+							nand_sfcmd_mode,
-+							MSM_NAND_SFCMD_DATWR);
-+		dma_buffer->data.sfcmd[2] =  SFLASH_PREPCMD(256, 0, 0,
-+							MSM_NAND_SFCMD_CMDXS,
-+							nand_sfcmd_mode,
-+							MSM_NAND_SFCMD_DATWR);
-+		dma_buffer->data.sfcmd[3] =  SFLASH_PREPCMD(256, 0, 0,
-+							MSM_NAND_SFCMD_CMDXS,
-+							nand_sfcmd_mode,
-+							MSM_NAND_SFCMD_DATWR);
-+		dma_buffer->data.sfcmd[4] =  SFLASH_PREPCMD(256, 0, 0,
-+							MSM_NAND_SFCMD_CMDXS,
-+							nand_sfcmd_mode,
-+							MSM_NAND_SFCMD_DATWR);
-+		dma_buffer->data.sfcmd[5] =  SFLASH_PREPCMD(32, 0, 0,
-+							MSM_NAND_SFCMD_CMDXS,
-+							nand_sfcmd_mode,
-+							MSM_NAND_SFCMD_DATWR);
-+		dma_buffer->data.sfcmd[6] =  SFLASH_PREPCMD(1, 6, 0,
-+							MSM_NAND_SFCMD_CMDXS,
-+							nand_sfcmd_mode,
-+							MSM_NAND_SFCMD_REGWR);
-+		dma_buffer->data.sfcmd[7] =  SFLASH_PREPCMD(0, 0, 32,
-+							MSM_NAND_SFCMD_CMDXS,
-+							nand_sfcmd_mode,
-+							MSM_NAND_SFCMD_INTHI);
-+		dma_buffer->data.sfcmd[8] =  SFLASH_PREPCMD(3, 7, 0,
-+							MSM_NAND_SFCMD_DATXS,
-+							nand_sfcmd_mode,
-+							MSM_NAND_SFCMD_REGRD);
-+		dma_buffer->data.sfcmd[9] =  SFLASH_PREPCMD(4, 10, 0,
-+							MSM_NAND_SFCMD_CMDXS,
-+							nand_sfcmd_mode,
-+							MSM_NAND_SFCMD_REGWR);
-+		dma_buffer->data.sfexec = 1;
-+		dma_buffer->data.sfstat[0] = CLEAN_DATA_32;
-+		dma_buffer->data.sfstat[1] = CLEAN_DATA_32;
-+		dma_buffer->data.sfstat[2] = CLEAN_DATA_32;
-+		dma_buffer->data.sfstat[3] = CLEAN_DATA_32;
-+		dma_buffer->data.sfstat[4] = CLEAN_DATA_32;
-+		dma_buffer->data.sfstat[5] = CLEAN_DATA_32;
-+		dma_buffer->data.sfstat[6] = CLEAN_DATA_32;
-+		dma_buffer->data.sfstat[7] = CLEAN_DATA_32;
-+		dma_buffer->data.sfstat[8] = CLEAN_DATA_32;
-+		dma_buffer->data.sfstat[9] = CLEAN_DATA_32;
-+		dma_buffer->data.addr0 = (ONENAND_INTERRUPT_STATUS << 16) |
-+						(ONENAND_SYSTEM_CONFIG_1);
-+		dma_buffer->data.addr1 = (ONENAND_START_ADDRESS_8 << 16) |
-+						(ONENAND_START_ADDRESS_1);
-+		dma_buffer->data.addr2 = (ONENAND_START_BUFFER << 16) |
-+						(ONENAND_START_ADDRESS_2);
-+		dma_buffer->data.addr3 = (ONENAND_ECC_STATUS << 16) |
-+						(ONENAND_COMMAND);
-+		dma_buffer->data.addr4 = (ONENAND_CONTROLLER_STATUS << 16) |
-+						(ONENAND_INTERRUPT_STATUS);
-+		dma_buffer->data.addr5 = (ONENAND_INTERRUPT_STATUS << 16) |
-+						(ONENAND_SYSTEM_CONFIG_1);
-+		dma_buffer->data.addr6 = (ONENAND_START_ADDRESS_3 << 16) |
-+						(ONENAND_START_ADDRESS_1);
-+		dma_buffer->data.data0 = (ONENAND_CLRINTR << 16) |
-+						(onenand_sysconfig1);
-+		dma_buffer->data.data1 = (onenand_startaddr8 << 16) |
-+						(onenand_startaddr1);
-+		dma_buffer->data.data2 = (onenand_startbuffer << 16) |
-+						(onenand_startaddr2);
-+		dma_buffer->data.data3 = (CLEAN_DATA_16 << 16) |
-+						(ONENAND_CMDPROGSPARE);
-+		dma_buffer->data.data4 = (CLEAN_DATA_16 << 16) |
-+						(CLEAN_DATA_16);
-+		dma_buffer->data.data5 = (ONENAND_CLRINTR << 16) |
-+				(ONENAND_SYSCFG1_ECCENA(nand_sfcmd_mode));
-+		dma_buffer->data.data6 = (ONENAND_STARTADDR3_RES << 16) |
-+						(ONENAND_STARTADDR1_RES);
-+		dma_buffer->data.macro[0] = 0x0200;
-+		dma_buffer->data.macro[1] = 0x0300;
-+		dma_buffer->data.macro[2] = 0x0400;
-+		dma_buffer->data.macro[3] = 0x0500;
-+		dma_buffer->data.macro[4] = 0x8010;
-+
-+
-+		/*************************************************************/
-+		/* Write necessary address registers in the onenand device   */
-+		/*************************************************************/
-+
-+		/* Enable and configure the SFlash controller */
-+		cmd->cmd = 0;
-+		cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.sfbcfg);
-+		cmd->dst = MSM_NAND_SFLASHC_BURST_CFG;
-+		cmd->len = 4;
-+		cmd++;
-+
-+		/* Block on cmd ready and write CMD register */
-+		cmd->cmd = DST_CRCI_NAND_CMD;
-+		cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.sfcmd[0]);
-+		cmd->dst = MSM_NAND_SFLASHC_CMD;
-+		cmd->len = 4;
-+		cmd++;
-+
-+		/* Write the ADDR0 and ADDR1 registers */
-+		cmd->cmd = 0;
-+		cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.addr0);
-+		cmd->dst = MSM_NAND_ADDR0;
-+		cmd->len = 8;
-+		cmd++;
-+
-+		/* Write the ADDR2 ADDR3 ADDR4 ADDR5 registers */
-+		cmd->cmd = 0;
-+		cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.addr2);
-+		cmd->dst = MSM_NAND_ADDR2;
-+		cmd->len = 16;
-+		cmd++;
-+
-+		/* Write the ADDR6 registers */
-+		cmd->cmd = 0;
-+		cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.addr6);
-+		cmd->dst = MSM_NAND_ADDR6;
-+		cmd->len = 4;
-+		cmd++;
-+
-+		/* Write the GENP0, GENP1, GENP2, GENP3 registers */
-+		cmd->cmd = 0;
-+		cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.data0);
-+		cmd->dst = MSM_NAND_GENP_REG0;
-+		cmd->len = 16;
-+		cmd++;
-+
-+		/* Write the FLASH_DEV_CMD4,5,6 registers */
-+		cmd->cmd = 0;
-+		cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.data4);
-+		cmd->dst = MSM_NAND_DEV_CMD4;
-+		cmd->len = 12;
-+		cmd++;
-+
-+		/* Kick the execute command */
-+		cmd->cmd = 0;
-+		cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.sfexec);
-+		cmd->dst = MSM_NAND_SFLASHC_EXEC_CMD;
-+		cmd->len = 4;
-+		cmd++;
-+
-+		/* Block on data ready, and read the status register */
-+		cmd->cmd = SRC_CRCI_NAND_DATA;
-+		cmd->src = MSM_NAND_SFLASHC_STATUS;
-+		cmd->dst = msm_virt_to_dma(chip, &dma_buffer->data.sfstat[0]);
-+		cmd->len = 4;
-+		cmd++;
-+
-+		/*************************************************************/
-+		/* Write the data ram area in the onenand buffer ram         */
-+		/*************************************************************/
-+
-+		if (ops->datbuf) {
-+			dma_buffer->data.data3 = (CLEAN_DATA_16 << 16) |
-+							(ONENAND_CMDPROG);
-+
-+			for (i = 0; i < 4; i++) {
-+
-+				/* Block on cmd ready and write CMD register */
-+				cmd->cmd = DST_CRCI_NAND_CMD;
-+				cmd->src = msm_virt_to_dma(chip,
-+						&dma_buffer->data.sfcmd[1+i]);
-+				cmd->dst = MSM_NAND_SFLASHC_CMD;
-+				cmd->len = 4;
-+				cmd++;
-+
-+				/* Trnsfr usr buf contents to nand ctlr buf */
-+				cmd->cmd = 0;
-+				cmd->src = data_dma_addr_curr;
-+				cmd->dst = MSM_NAND_FLASH_BUFFER;
-+				cmd->len = 512;
-+				data_dma_addr_curr += 512;
-+				cmd++;
-+
-+				/* Write the MACRO1 register */
-+				cmd->cmd = 0;
-+				cmd->src = msm_virt_to_dma(chip,
-+						&dma_buffer->data.macro[i]);
-+				cmd->dst = MSM_NAND_MACRO1_REG;
-+				cmd->len = 4;
-+				cmd++;
-+
-+				/* Kick the execute command */
-+				cmd->cmd = 0;
-+				cmd->src = msm_virt_to_dma(chip,
-+						&dma_buffer->data.sfexec);
-+				cmd->dst = MSM_NAND_SFLASHC_EXEC_CMD;
-+				cmd->len = 4;
-+				cmd++;
-+
-+				/* Block on data rdy, & read status register */
-+				cmd->cmd = SRC_CRCI_NAND_DATA;
-+				cmd->src = MSM_NAND_SFLASHC_STATUS;
-+				cmd->dst = msm_virt_to_dma(chip,
-+						&dma_buffer->data.sfstat[1+i]);
-+				cmd->len = 4;
-+				cmd++;
-+
-+			}
-+		}
-+
-+		/* Block on cmd ready and write CMD register */
-+		cmd->cmd = DST_CRCI_NAND_CMD;
-+		cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.sfcmd[5]);
-+		cmd->dst = MSM_NAND_SFLASHC_CMD;
-+		cmd->len = 4;
-+		cmd++;
-+
-+		if ((ops->oobbuf) || (ops->mode == MTD_OPS_RAW)) {
-+
-+			/* Transfer user buf contents into nand ctlr buffer */
-+			if (ops->mode == MTD_OPS_AUTO_OOB) {
-+				cmd->cmd = 0;
-+				cmd->src = init_dma_addr;
-+				cmd->dst = MSM_NAND_FLASH_BUFFER;
-+				cmd->len = mtd->oobsize;
-+				cmd++;
-+			}
-+			if (ops->mode == MTD_OPS_PLACE_OOB) {
-+				cmd->cmd = 0;
-+				cmd->src = oob_dma_addr_curr;
-+				cmd->dst = MSM_NAND_FLASH_BUFFER;
-+				cmd->len = mtd->oobsize;
-+				oob_dma_addr_curr += mtd->oobsize;
-+				cmd++;
-+			}
-+			if (ops->mode == MTD_OPS_RAW) {
-+				cmd->cmd = 0;
-+				cmd->src = data_dma_addr_curr;
-+				cmd->dst = MSM_NAND_FLASH_BUFFER;
-+				cmd->len = mtd->oobsize;
-+				data_dma_addr_curr += mtd->oobsize;
-+				cmd++;
-+			}
-+		} else {
-+				cmd->cmd = 0;
-+				cmd->src = init_dma_addr;
-+				cmd->dst = MSM_NAND_FLASH_BUFFER;
-+				cmd->len = mtd->oobsize;
-+				cmd++;
-+		}
-+
-+		/* Write the MACRO1 register */
-+		cmd->cmd = 0;
-+		cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.macro[4]);
-+		cmd->dst = MSM_NAND_MACRO1_REG;
-+		cmd->len = 4;
-+		cmd++;
-+
-+		/* Kick the execute command */
-+		cmd->cmd = 0;
-+		cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.sfexec);
-+		cmd->dst = MSM_NAND_SFLASHC_EXEC_CMD;
-+		cmd->len = 4;
-+		cmd++;
-+
-+		/* Block on data ready, and read the status register */
-+		cmd->cmd = SRC_CRCI_NAND_DATA;
-+		cmd->src = MSM_NAND_SFLASHC_STATUS;
-+		cmd->dst = msm_virt_to_dma(chip, &dma_buffer->data.sfstat[5]);
-+		cmd->len = 4;
-+		cmd++;
-+
-+		/*********************************************************/
-+		/* Issuing write command                                 */
-+		/*********************************************************/
-+
-+		/* Block on cmd ready and write CMD register */
-+		cmd->cmd = DST_CRCI_NAND_CMD;
-+		cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.sfcmd[6]);
-+		cmd->dst = MSM_NAND_SFLASHC_CMD;
-+		cmd->len = 4;
-+		cmd++;
-+
-+		/* Kick the execute command */
-+		cmd->cmd = 0;
-+		cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.sfexec);
-+		cmd->dst = MSM_NAND_SFLASHC_EXEC_CMD;
-+		cmd->len = 4;
-+		cmd++;
-+
-+		/* Block on data ready, and read the status register */
-+		cmd->cmd = SRC_CRCI_NAND_DATA;
-+		cmd->src = MSM_NAND_SFLASHC_STATUS;
-+		cmd->dst = msm_virt_to_dma(chip, &dma_buffer->data.sfstat[6]);
-+		cmd->len = 4;
-+		cmd++;
-+
-+		/*************************************************************/
-+		/* Wait for the interrupt from the Onenand device controller */
-+		/*************************************************************/
-+
-+		/* Block on cmd ready and write CMD register */
-+		cmd->cmd = DST_CRCI_NAND_CMD;
-+		cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.sfcmd[7]);
-+		cmd->dst = MSM_NAND_SFLASHC_CMD;
-+		cmd->len = 4;
-+		cmd++;
-+
-+		/* Kick the execute command */
-+		cmd->cmd = 0;
-+		cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.sfexec);
-+		cmd->dst = MSM_NAND_SFLASHC_EXEC_CMD;
-+		cmd->len = 4;
-+		cmd++;
-+
-+		/* Block on data ready, and read the status register */
-+		cmd->cmd = SRC_CRCI_NAND_DATA;
-+		cmd->src = MSM_NAND_SFLASHC_STATUS;
-+		cmd->dst = msm_virt_to_dma(chip, &dma_buffer->data.sfstat[7]);
-+		cmd->len = 4;
-+		cmd++;
-+
-+		/*************************************************************/
-+		/* Read necessary status registers from the onenand device   */
-+		/*************************************************************/
-+
-+		/* Block on cmd ready and write CMD register */
-+		cmd->cmd = DST_CRCI_NAND_CMD;
-+		cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.sfcmd[8]);
-+		cmd->dst = MSM_NAND_SFLASHC_CMD;
-+		cmd->len = 4;
-+		cmd++;
-+
-+		/* Kick the execute command */
-+		cmd->cmd = 0;
-+		cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.sfexec);
-+		cmd->dst = MSM_NAND_SFLASHC_EXEC_CMD;
-+		cmd->len = 4;
-+		cmd++;
-+
-+		/* Block on data ready, and read the status register */
-+		cmd->cmd = SRC_CRCI_NAND_DATA;
-+		cmd->src = MSM_NAND_SFLASHC_STATUS;
-+		cmd->dst = msm_virt_to_dma(chip, &dma_buffer->data.sfstat[8]);
-+		cmd->len = 4;
-+		cmd++;
-+
-+		/* Read the GENP3 register */
-+		cmd->cmd = 0;
-+		cmd->src = MSM_NAND_GENP_REG3;
-+		cmd->dst = msm_virt_to_dma(chip, &dma_buffer->data.data3);
-+		cmd->len = 4;
-+		cmd++;
-+
-+		/* Read the DEVCMD4 register */
-+		cmd->cmd = 0;
-+		cmd->src = MSM_NAND_DEV_CMD4;
-+		cmd->dst = msm_virt_to_dma(chip, &dma_buffer->data.data4);
-+		cmd->len = 4;
-+		cmd++;
-+
-+		/*************************************************************/
-+		/* Restore the necessary registers to proper values          */
-+		/*************************************************************/
-+
-+		/* Block on cmd ready and write CMD register */
-+		cmd->cmd = DST_CRCI_NAND_CMD;
-+		cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.sfcmd[9]);
-+		cmd->dst = MSM_NAND_SFLASHC_CMD;
-+		cmd->len = 4;
-+		cmd++;
-+
-+		/* Kick the execute command */
-+		cmd->cmd = 0;
-+		cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.sfexec);
-+		cmd->dst = MSM_NAND_SFLASHC_EXEC_CMD;
-+		cmd->len = 4;
-+		cmd++;
-+
-+		/* Block on data ready, and read the status register */
-+		cmd->cmd = SRC_CRCI_NAND_DATA;
-+		cmd->src = MSM_NAND_SFLASHC_STATUS;
-+		cmd->dst = msm_virt_to_dma(chip, &dma_buffer->data.sfstat[9]);
-+		cmd->len = 4;
-+		cmd++;
-+
-+
-+		BUILD_BUG_ON(53 != ARRAY_SIZE(dma_buffer->cmd));
-+		BUG_ON(cmd - dma_buffer->cmd > ARRAY_SIZE(dma_buffer->cmd));
-+		dma_buffer->cmd[0].cmd |= CMD_OCB;
-+		cmd[-1].cmd |= CMD_OCU | CMD_LC;
-+
-+		dma_buffer->cmdptr = (msm_virt_to_dma(chip, dma_buffer->cmd)
-+				>> 3) | CMD_PTR_LP;
-+
-+		mb();
-+		msm_dmov_exec_cmd(chip->dma_channel,
-+			DMOV_CMD_PTR_LIST | DMOV_CMD_ADDR(msm_virt_to_dma(chip,
-+				&dma_buffer->cmdptr)));
-+		mb();
-+
-+		ecc_status = (dma_buffer->data.data3 >> 16) & 0x0000FFFF;
-+		interrupt_status = (dma_buffer->data.data4 >> 0)&0x0000FFFF;
-+		controller_status = (dma_buffer->data.data4 >> 16)&0x0000FFFF;
-+
-+#if VERBOSE
-+		pr_info("\n%s: sflash status %x %x %x %x %x %x %x"
-+				" %x %x %x\n", __func__,
-+					dma_buffer->data.sfstat[0],
-+					dma_buffer->data.sfstat[1],
-+					dma_buffer->data.sfstat[2],
-+					dma_buffer->data.sfstat[3],
-+					dma_buffer->data.sfstat[4],
-+					dma_buffer->data.sfstat[5],
-+					dma_buffer->data.sfstat[6],
-+					dma_buffer->data.sfstat[7],
-+					dma_buffer->data.sfstat[8],
-+					dma_buffer->data.sfstat[9]);
-+
-+		pr_info("%s: controller_status = %x\n", __func__,
-+					controller_status);
-+		pr_info("%s: interrupt_status = %x\n", __func__,
-+					interrupt_status);
-+		pr_info("%s: ecc_status = %x\n", __func__,
-+					ecc_status);
-+#endif
-+		/* Check for errors, protection violations etc */
-+		if ((controller_status != 0)
-+				|| (dma_buffer->data.sfstat[0] & 0x110)
-+				|| (dma_buffer->data.sfstat[6] & 0x110)
-+				|| (dma_buffer->data.sfstat[7] & 0x110)
-+				|| (dma_buffer->data.sfstat[8] & 0x110)
-+				|| (dma_buffer->data.sfstat[9] & 0x110)
-+				|| ((dma_buffer->data.sfstat[1] & 0x110) &&
-+								(ops->datbuf))
-+				|| ((dma_buffer->data.sfstat[2] & 0x110) &&
-+								(ops->datbuf))
-+				|| ((dma_buffer->data.sfstat[3] & 0x110) &&
-+								(ops->datbuf))
-+				|| ((dma_buffer->data.sfstat[4] & 0x110) &&
-+								(ops->datbuf))
-+				|| ((dma_buffer->data.sfstat[5] & 0x110) &&
-+								((ops->oobbuf)
-+					|| (ops->mode == MTD_OPS_RAW)))) {
-+			pr_info("%s: ECC/MPU/OP error\n", __func__);
-+			err = -EIO;
-+		}
-+
-+		if (err)
-+			break;
-+		pages_written++;
-+		to_curr += mtd->writesize;
-+	}
-+
-+	msm_nand_release_dma_buffer(chip, dma_buffer, sizeof(*dma_buffer));
-+
-+	dma_unmap_page(chip->dev, init_dma_addr, 64, DMA_TO_DEVICE);
-+
-+err_dma_map_initbuf_failed:
-+	if (ops->oobbuf) {
-+		dma_unmap_page(chip->dev, oob_dma_addr, ops->ooblen,
-+							DMA_TO_DEVICE);
-+	}
-+err_dma_map_oobbuf_failed:
-+	if (ops->datbuf) {
-+		dma_unmap_page(chip->dev, data_dma_addr, ops->len,
-+							DMA_TO_DEVICE);
-+	}
-+
-+	if (err) {
-+		pr_err("%s: %llx %x %x failed\n", __func__, to_curr,
-+				ops->datbuf ? ops->len : 0, ops->ooblen);
-+	} else {
-+		ops->retlen = ops->oobretlen = 0;
-+		if (ops->datbuf != NULL) {
-+			if (ops->mode != MTD_OPS_RAW)
-+				ops->retlen = mtd->writesize * pages_written;
-+			else
-+				ops->retlen = (mtd->writesize +  mtd->oobsize)
-+							* pages_written;
-+		}
-+		if (ops->oobbuf != NULL) {
-+			if (ops->mode == MTD_OPS_AUTO_OOB)
-+				ops->oobretlen = mtd->oobavail * pages_written;
-+			else
-+				ops->oobretlen = mtd->oobsize * pages_written;
-+		}
-+	}
-+
-+#if VERBOSE
-+	pr_info("\n%s: ret %d, retlen %d oobretlen %d\n",
-+			__func__, err, ops->retlen, ops->oobretlen);
-+
-+	pr_info("================================================="
-+			"================\n");
-+#endif
-+	kfree(init_spare_bytes);
-+	return err;
-+}
-+
-+static int msm_onenand_write(struct mtd_info *mtd, loff_t to, size_t len,
-+		size_t *retlen, const u_char *buf)
-+{
-+	int ret;
-+	struct mtd_oob_ops ops;
-+
-+	ops.mode = MTD_OPS_PLACE_OOB;
-+	ops.datbuf = (uint8_t *)buf;
-+	ops.len = len;
-+	ops.retlen = 0;
-+	ops.oobbuf = NULL;
-+	ops.ooblen = 0;
-+	ops.oobretlen = 0;
-+	ret =  msm_onenand_write_oob(mtd, to, &ops);
-+	*retlen = ops.retlen;
-+
-+	return ret;
-+}
-+
-+static int msm_onenand_erase(struct mtd_info *mtd, struct erase_info *instr)
-+{
-+	struct msm_nand_chip *chip = mtd->priv;
-+
-+	struct {
-+		dmov_s cmd[20];
-+		unsigned cmdptr;
-+		struct {
-+			uint32_t sfbcfg;
-+			uint32_t sfcmd[4];
-+			uint32_t sfexec;
-+			uint32_t sfstat[4];
-+			uint32_t addr0;
-+			uint32_t addr1;
-+			uint32_t addr2;
-+			uint32_t addr3;
-+			uint32_t addr4;
-+			uint32_t addr5;
-+			uint32_t addr6;
-+			uint32_t data0;
-+			uint32_t data1;
-+			uint32_t data2;
-+			uint32_t data3;
-+			uint32_t data4;
-+			uint32_t data5;
-+			uint32_t data6;
-+		} data;
-+	} *dma_buffer;
-+	dmov_s *cmd;
-+
-+	int err = 0;
-+
-+	uint16_t onenand_startaddr1;
-+	uint16_t onenand_startaddr8;
-+	uint16_t onenand_startaddr2;
-+	uint16_t onenand_startbuffer;
-+
-+	uint16_t controller_status;
-+	uint16_t interrupt_status;
-+	uint16_t ecc_status;
-+
-+	uint64_t temp;
-+
-+#if VERBOSE
-+	pr_info("================================================="
-+			"================\n");
-+	pr_info("%s: addr 0x%llx len 0x%llx\n",
-+			__func__, instr->addr, instr->len);
-+#endif
-+	if (instr->addr & (mtd->erasesize - 1)) {
-+		pr_err("%s: Unsupported erase address, 0x%llx\n",
-+				__func__, instr->addr);
-+		return -EINVAL;
-+	}
-+	if (instr->len != mtd->erasesize) {
-+		pr_err("%s: Unsupported erase len, %lld\n",
-+				__func__, instr->len);
-+		return -EINVAL;
-+	}
-+
-+	wait_event(chip->wait_queue, (dma_buffer = msm_nand_get_dma_buffer
-+				(chip, sizeof(*dma_buffer))));
-+
-+	cmd = dma_buffer->cmd;
-+
-+	temp = instr->addr;
-+
-+	if ((onenand_info.device_id & ONENAND_DEVICE_IS_DDP)
-+		&& (temp >= (mtd->size>>1))) { /* DDP Device */
-+			onenand_startaddr1 = DEVICE_FLASHCORE_1 |
-+				(((uint32_t)(temp-(mtd->size>>1))
-+						/ mtd->erasesize));
-+			onenand_startaddr2 = DEVICE_BUFFERRAM_1;
-+	} else {
-+		onenand_startaddr1 = DEVICE_FLASHCORE_0 |
-+			((uint32_t)temp / mtd->erasesize) ;
-+		onenand_startaddr2 = DEVICE_BUFFERRAM_0;
-+	}
-+
-+	onenand_startaddr8 = 0x0000;
-+	onenand_startbuffer = DATARAM0_0 << 8;
-+
-+	dma_buffer->data.sfbcfg = SFLASH_BCFG |
-+					(nand_sfcmd_mode ? 0 : (1 << 24));
-+	dma_buffer->data.sfcmd[0] = SFLASH_PREPCMD(7, 0, 0,
-+						MSM_NAND_SFCMD_CMDXS,
-+						nand_sfcmd_mode,
-+						MSM_NAND_SFCMD_REGWR);
-+	dma_buffer->data.sfcmd[1] = SFLASH_PREPCMD(0, 0, 32,
-+						MSM_NAND_SFCMD_CMDXS,
-+						nand_sfcmd_mode,
-+						MSM_NAND_SFCMD_INTHI);
-+	dma_buffer->data.sfcmd[2] = SFLASH_PREPCMD(3, 7, 0,
-+						MSM_NAND_SFCMD_DATXS,
-+						nand_sfcmd_mode,
-+						MSM_NAND_SFCMD_REGRD);
-+	dma_buffer->data.sfcmd[3] = SFLASH_PREPCMD(4, 10, 0,
-+						MSM_NAND_SFCMD_CMDXS,
-+						nand_sfcmd_mode,
-+						MSM_NAND_SFCMD_REGWR);
-+	dma_buffer->data.sfexec = 1;
-+	dma_buffer->data.sfstat[0] = CLEAN_DATA_32;
-+	dma_buffer->data.sfstat[1] = CLEAN_DATA_32;
-+	dma_buffer->data.sfstat[2] = CLEAN_DATA_32;
-+	dma_buffer->data.sfstat[3] = CLEAN_DATA_32;
-+	dma_buffer->data.addr0 = (ONENAND_INTERRUPT_STATUS << 16) |
-+						(ONENAND_SYSTEM_CONFIG_1);
-+	dma_buffer->data.addr1 = (ONENAND_START_ADDRESS_8 << 16) |
-+						(ONENAND_START_ADDRESS_1);
-+	dma_buffer->data.addr2 = (ONENAND_START_BUFFER << 16) |
-+						(ONENAND_START_ADDRESS_2);
-+	dma_buffer->data.addr3 = (ONENAND_ECC_STATUS << 16) |
-+						(ONENAND_COMMAND);
-+	dma_buffer->data.addr4 = (ONENAND_CONTROLLER_STATUS << 16) |
-+						(ONENAND_INTERRUPT_STATUS);
-+	dma_buffer->data.addr5 = (ONENAND_INTERRUPT_STATUS << 16) |
-+						(ONENAND_SYSTEM_CONFIG_1);
-+	dma_buffer->data.addr6 = (ONENAND_START_ADDRESS_3 << 16) |
-+						(ONENAND_START_ADDRESS_1);
-+	dma_buffer->data.data0 = (ONENAND_CLRINTR << 16) |
-+				(ONENAND_SYSCFG1_ECCENA(nand_sfcmd_mode));
-+	dma_buffer->data.data1 = (onenand_startaddr8 << 16) |
-+						(onenand_startaddr1);
-+	dma_buffer->data.data2 = (onenand_startbuffer << 16) |
-+						(onenand_startaddr2);
-+	dma_buffer->data.data3 = (CLEAN_DATA_16 << 16) |
-+						(ONENAND_CMDERAS);
-+	dma_buffer->data.data4 = (CLEAN_DATA_16 << 16) |
-+						(CLEAN_DATA_16);
-+	dma_buffer->data.data5 = (ONENAND_CLRINTR << 16) |
-+				(ONENAND_SYSCFG1_ECCENA(nand_sfcmd_mode));
-+	dma_buffer->data.data6 = (ONENAND_STARTADDR3_RES << 16) |
-+						(ONENAND_STARTADDR1_RES);
-+
-+	/***************************************************************/
-+	/* Write the necessary address registers in the onenand device */
-+	/***************************************************************/
-+
-+	/* Enable and configure the SFlash controller */
-+	cmd->cmd = 0;
-+	cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.sfbcfg);
-+	cmd->dst = MSM_NAND_SFLASHC_BURST_CFG;
-+	cmd->len = 4;
-+	cmd++;
-+
-+	/* Block on cmd ready and write CMD register */
-+	cmd->cmd = DST_CRCI_NAND_CMD;
-+	cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.sfcmd[0]);
-+	cmd->dst = MSM_NAND_SFLASHC_CMD;
-+	cmd->len = 4;
-+	cmd++;
-+
-+	/* Write the ADDR0 and ADDR1 registers */
-+	cmd->cmd = 0;
-+	cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.addr0);
-+	cmd->dst = MSM_NAND_ADDR0;
-+	cmd->len = 8;
-+	cmd++;
-+
-+	/* Write the ADDR2 ADDR3 ADDR4 ADDR5 registers */
-+	cmd->cmd = 0;
-+	cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.addr2);
-+	cmd->dst = MSM_NAND_ADDR2;
-+	cmd->len = 16;
-+	cmd++;
-+
-+	/* Write the ADDR6 registers */
-+	cmd->cmd = 0;
-+	cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.addr6);
-+	cmd->dst = MSM_NAND_ADDR6;
-+	cmd->len = 4;
-+	cmd++;
-+
-+	/* Write the GENP0, GENP1, GENP2, GENP3, GENP4 registers */
-+	cmd->cmd = 0;
-+	cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.data0);
-+	cmd->dst = MSM_NAND_GENP_REG0;
-+	cmd->len = 16;
-+	cmd++;
-+
-+	/* Write the FLASH_DEV_CMD4,5,6 registers */
-+	cmd->cmd = 0;
-+	cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.data4);
-+	cmd->dst = MSM_NAND_DEV_CMD4;
-+	cmd->len = 12;
-+	cmd++;
-+
-+	/* Kick the execute command */
-+	cmd->cmd = 0;
-+	cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.sfexec);
-+	cmd->dst = MSM_NAND_SFLASHC_EXEC_CMD;
-+	cmd->len = 4;
-+	cmd++;
-+
-+	/* Block on data ready, and read the status register */
-+	cmd->cmd = SRC_CRCI_NAND_DATA;
-+	cmd->src = MSM_NAND_SFLASHC_STATUS;
-+	cmd->dst = msm_virt_to_dma(chip, &dma_buffer->data.sfstat[0]);
-+	cmd->len = 4;
-+	cmd++;
-+
-+	/***************************************************************/
-+	/* Wait for the interrupt from the Onenand device controller   */
-+	/***************************************************************/
-+
-+	/* Block on cmd ready and write CMD register */
-+	cmd->cmd = DST_CRCI_NAND_CMD;
-+	cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.sfcmd[1]);
-+	cmd->dst = MSM_NAND_SFLASHC_CMD;
-+	cmd->len = 4;
-+	cmd++;
-+
-+	/* Kick the execute command */
-+	cmd->cmd = 0;
-+	cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.sfexec);
-+	cmd->dst = MSM_NAND_SFLASHC_EXEC_CMD;
-+	cmd->len = 4;
-+	cmd++;
-+
-+	/* Block on data ready, and read the status register */
-+	cmd->cmd = SRC_CRCI_NAND_DATA;
-+	cmd->src = MSM_NAND_SFLASHC_STATUS;
-+	cmd->dst = msm_virt_to_dma(chip, &dma_buffer->data.sfstat[1]);
-+	cmd->len = 4;
-+	cmd++;
-+
-+	/***************************************************************/
-+	/* Read the necessary status registers from the onenand device */
-+	/***************************************************************/
-+
-+	/* Block on cmd ready and write CMD register */
-+	cmd->cmd = DST_CRCI_NAND_CMD;
-+	cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.sfcmd[2]);
-+	cmd->dst = MSM_NAND_SFLASHC_CMD;
-+	cmd->len = 4;
-+	cmd++;
-+
-+	/* Kick the execute command */
-+	cmd->cmd = 0;
-+	cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.sfexec);
-+	cmd->dst = MSM_NAND_SFLASHC_EXEC_CMD;
-+	cmd->len = 4;
-+	cmd++;
-+
-+	/* Block on data ready, and read the status register */
-+	cmd->cmd = SRC_CRCI_NAND_DATA;
-+	cmd->src = MSM_NAND_SFLASHC_STATUS;
-+	cmd->dst = msm_virt_to_dma(chip, &dma_buffer->data.sfstat[2]);
-+	cmd->len = 4;
-+	cmd++;
-+
-+	/* Read the GENP3 register */
-+	cmd->cmd = 0;
-+	cmd->src = MSM_NAND_GENP_REG3;
-+	cmd->dst = msm_virt_to_dma(chip, &dma_buffer->data.data3);
-+	cmd->len = 4;
-+	cmd++;
-+
-+	/* Read the DEVCMD4 register */
-+	cmd->cmd = 0;
-+	cmd->src = MSM_NAND_DEV_CMD4;
-+	cmd->dst = msm_virt_to_dma(chip, &dma_buffer->data.data4);
-+	cmd->len = 4;
-+	cmd++;
-+
-+	/***************************************************************/
-+	/* Restore the necessary registers to proper values            */
-+	/***************************************************************/
-+
-+	/* Block on cmd ready and write CMD register */
-+	cmd->cmd = DST_CRCI_NAND_CMD;
-+	cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.sfcmd[3]);
-+	cmd->dst = MSM_NAND_SFLASHC_CMD;
-+	cmd->len = 4;
-+	cmd++;
-+
-+	/* Kick the execute command */
-+	cmd->cmd = 0;
-+	cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.sfexec);
-+	cmd->dst = MSM_NAND_SFLASHC_EXEC_CMD;
-+	cmd->len = 4;
-+	cmd++;
-+
-+	/* Block on data ready, and read the status register */
-+	cmd->cmd = SRC_CRCI_NAND_DATA;
-+	cmd->src = MSM_NAND_SFLASHC_STATUS;
-+	cmd->dst = msm_virt_to_dma(chip, &dma_buffer->data.sfstat[3]);
-+	cmd->len = 4;
-+	cmd++;
-+
-+
-+	BUILD_BUG_ON(20 != ARRAY_SIZE(dma_buffer->cmd));
-+	BUG_ON(cmd - dma_buffer->cmd > ARRAY_SIZE(dma_buffer->cmd));
-+	dma_buffer->cmd[0].cmd |= CMD_OCB;
-+	cmd[-1].cmd |= CMD_OCU | CMD_LC;
-+
-+	dma_buffer->cmdptr = (msm_virt_to_dma(chip, dma_buffer->cmd)
-+			>> 3) | CMD_PTR_LP;
-+
-+	mb();
-+	msm_dmov_exec_cmd(chip->dma_channel, DMOV_CMD_PTR_LIST
-+			| DMOV_CMD_ADDR(msm_virt_to_dma(chip,
-+			&dma_buffer->cmdptr)));
-+	mb();
-+
-+	ecc_status = (dma_buffer->data.data3 >> 16) & 0x0000FFFF;
-+	interrupt_status = (dma_buffer->data.data4 >> 0) & 0x0000FFFF;
-+	controller_status = (dma_buffer->data.data4 >> 16) & 0x0000FFFF;
-+
-+#if VERBOSE
-+	pr_info("\n%s: sflash status %x %x %x %x\n", __func__,
-+				dma_buffer->data.sfstat[0],
-+				dma_buffer->data.sfstat[1],
-+				dma_buffer->data.sfstat[2],
-+				dma_buffer->data.sfstat[3]);
-+
-+	pr_info("%s: controller_status = %x\n", __func__,
-+				controller_status);
-+	pr_info("%s: interrupt_status = %x\n", __func__,
-+				interrupt_status);
-+	pr_info("%s: ecc_status = %x\n", __func__,
-+				ecc_status);
-+#endif
-+	/* Check for errors, protection violations etc */
-+	if ((controller_status != 0)
-+			|| (dma_buffer->data.sfstat[0] & 0x110)
-+			|| (dma_buffer->data.sfstat[1] & 0x110)
-+			|| (dma_buffer->data.sfstat[2] & 0x110)
-+			|| (dma_buffer->data.sfstat[3] & 0x110)) {
-+		pr_err("%s: ECC/MPU/OP error\n", __func__);
-+		err = -EIO;
-+	}
-+
-+	msm_nand_release_dma_buffer(chip, dma_buffer, sizeof(*dma_buffer));
-+
-+	if (err) {
-+		pr_err("%s: Erase failed, 0x%llx\n", __func__,
-+				instr->addr);
-+		instr->fail_addr = instr->addr;
-+		instr->state = MTD_ERASE_FAILED;
-+	} else {
-+		instr->state = MTD_ERASE_DONE;
-+		instr->fail_addr = 0xffffffff;
-+		mtd_erase_callback(instr);
-+	}
-+
-+#if VERBOSE
-+	pr_info("\n%s: ret %d\n", __func__, err);
-+	pr_info("===================================================="
-+			"=============\n");
-+#endif
-+	return err;
-+}
-+
-+static int msm_onenand_block_isbad(struct mtd_info *mtd, loff_t ofs)
-+{
-+	struct mtd_oob_ops ops;
-+	int rval, i;
-+	int ret = 0;
-+	uint8_t *buffer;
-+	uint8_t *oobptr;
-+
-+	if ((ofs > mtd->size) || (ofs & (mtd->erasesize - 1))) {
-+		pr_err("%s: unsupported block address, 0x%x\n",
-+			 __func__, (uint32_t)ofs);
-+		return -EINVAL;
-+	}
-+
-+	buffer = kmalloc(2112, GFP_KERNEL|GFP_DMA);
-+	if (buffer == 0) {
-+		pr_err("%s: Could not kmalloc for buffer\n",
-+				__func__);
-+		return -ENOMEM;
-+	}
-+
-+	memset(buffer, 0x00, 2112);
-+	oobptr = &(buffer[2048]);
-+
-+	ops.mode = MTD_OPS_RAW;
-+	ops.len = 2112;
-+	ops.retlen = 0;
-+	ops.ooblen = 0;
-+	ops.oobretlen = 0;
-+	ops.ooboffs = 0;
-+	ops.datbuf = buffer;
-+	ops.oobbuf = NULL;
-+
-+	for (i = 0; i < 2; i++) {
-+		ofs = ofs + i*mtd->writesize;
-+		rval = msm_onenand_read_oob(mtd, ofs, &ops);
-+		if (rval) {
-+			pr_err("%s: Error in reading bad blk info\n",
-+					__func__);
-+			ret = rval;
-+			break;
-+		}
-+		if ((oobptr[0] != 0xFF) || (oobptr[1] != 0xFF) ||
-+		    (oobptr[16] != 0xFF) || (oobptr[17] != 0xFF) ||
-+		    (oobptr[32] != 0xFF) || (oobptr[33] != 0xFF) ||
-+		    (oobptr[48] != 0xFF) || (oobptr[49] != 0xFF)
-+		   ) {
-+			ret = 1;
-+			break;
-+		}
-+	}
-+
-+	kfree(buffer);
-+
-+#if VERBOSE
-+	if (ret == 1)
-+		pr_info("%s : Block containing 0x%x is bad\n",
-+				__func__, (unsigned int)ofs);
-+#endif
-+	return ret;
-+}
-+
-+static int msm_onenand_block_markbad(struct mtd_info *mtd, loff_t ofs)
-+{
-+	struct mtd_oob_ops ops;
-+	int rval, i;
-+	int ret = 0;
-+	uint8_t *buffer;
-+
-+	if ((ofs > mtd->size) || (ofs & (mtd->erasesize - 1))) {
-+		pr_err("%s: unsupported block address, 0x%x\n",
-+			 __func__, (uint32_t)ofs);
-+		return -EINVAL;
-+	}
-+
-+	buffer = page_address(ZERO_PAGE());
-+
-+	ops.mode = MTD_OPS_RAW;
-+	ops.len = 2112;
-+	ops.retlen = 0;
-+	ops.ooblen = 0;
-+	ops.oobretlen = 0;
-+	ops.ooboffs = 0;
-+	ops.datbuf = buffer;
-+	ops.oobbuf = NULL;
-+
-+	for (i = 0; i < 2; i++) {
-+		ofs = ofs + i*mtd->writesize;
-+		rval = msm_onenand_write_oob(mtd, ofs, &ops);
-+		if (rval) {
-+			pr_err("%s: Error in writing bad blk info\n",
-+					__func__);
-+			ret = rval;
-+			break;
-+		}
-+	}
-+
-+	return ret;
-+}
-+
-+static int msm_onenand_unlock(struct mtd_info *mtd, loff_t ofs, uint64_t len)
-+{
-+	struct msm_nand_chip *chip = mtd->priv;
-+
-+	struct {
-+		dmov_s cmd[20];
-+		unsigned cmdptr;
-+		struct {
-+			uint32_t sfbcfg;
-+			uint32_t sfcmd[4];
-+			uint32_t sfexec;
-+			uint32_t sfstat[4];
-+			uint32_t addr0;
-+			uint32_t addr1;
-+			uint32_t addr2;
-+			uint32_t addr3;
-+			uint32_t addr4;
-+			uint32_t addr5;
-+			uint32_t addr6;
-+			uint32_t data0;
-+			uint32_t data1;
-+			uint32_t data2;
-+			uint32_t data3;
-+			uint32_t data4;
-+			uint32_t data5;
-+			uint32_t data6;
-+		} data;
-+	} *dma_buffer;
-+	dmov_s *cmd;
-+
-+	int err = 0;
-+
-+	uint16_t onenand_startaddr1;
-+	uint16_t onenand_startaddr8;
-+	uint16_t onenand_startaddr2;
-+	uint16_t onenand_startblock;
-+
-+	uint16_t controller_status;
-+	uint16_t interrupt_status;
-+	uint16_t write_prot_status;
-+
-+	uint64_t start_ofs;
-+
-+#if VERBOSE
-+	pr_info("===================================================="
-+			"=============\n");
-+	pr_info("%s: ofs 0x%llx len %lld\n", __func__, ofs, len);
-+#endif
-+	/* 'ofs' & 'len' should align to block size */
-+	if (ofs&(mtd->erasesize - 1)) {
-+		pr_err("%s: Unsupported ofs address, 0x%llx\n",
-+				__func__, ofs);
-+		return -EINVAL;
-+	}
-+
-+	if (len&(mtd->erasesize - 1)) {
-+		pr_err("%s: Unsupported len, %lld\n",
-+				__func__, len);
-+		return -EINVAL;
-+	}
-+
-+	if (ofs+len > mtd->size) {
-+		pr_err("%s: Maximum chip size exceeded\n", __func__);
-+		return -EINVAL;
-+	}
-+
-+	wait_event(chip->wait_queue, (dma_buffer = msm_nand_get_dma_buffer
-+				(chip, sizeof(*dma_buffer))));
-+
-+	for (start_ofs = ofs; ofs < start_ofs+len; ofs = ofs+mtd->erasesize) {
-+#if VERBOSE
-+		pr_info("%s: ofs 0x%llx len %lld\n", __func__, ofs, len);
-+#endif
-+
-+		cmd = dma_buffer->cmd;
-+		if ((onenand_info.device_id & ONENAND_DEVICE_IS_DDP)
-+			&& (ofs >= (mtd->size>>1))) { /* DDP Device */
-+			onenand_startaddr1 = DEVICE_FLASHCORE_1 |
-+				(((uint32_t)(ofs - (mtd->size>>1))
-+						/ mtd->erasesize));
-+			onenand_startaddr2 = DEVICE_BUFFERRAM_1;
-+			onenand_startblock = ((uint32_t)(ofs - (mtd->size>>1))
-+						/ mtd->erasesize);
-+		} else {
-+			onenand_startaddr1 = DEVICE_FLASHCORE_0 |
-+					((uint32_t)ofs / mtd->erasesize) ;
-+			onenand_startaddr2 = DEVICE_BUFFERRAM_0;
-+			onenand_startblock = ((uint32_t)ofs
-+						/ mtd->erasesize);
-+		}
-+
-+		onenand_startaddr8 = 0x0000;
-+		dma_buffer->data.sfbcfg = SFLASH_BCFG |
-+					(nand_sfcmd_mode ? 0 : (1 << 24));
-+		dma_buffer->data.sfcmd[0] = SFLASH_PREPCMD(7, 0, 0,
-+							MSM_NAND_SFCMD_CMDXS,
-+							nand_sfcmd_mode,
-+							MSM_NAND_SFCMD_REGWR);
-+		dma_buffer->data.sfcmd[1] = SFLASH_PREPCMD(0, 0, 32,
-+							MSM_NAND_SFCMD_CMDXS,
-+							nand_sfcmd_mode,
-+							MSM_NAND_SFCMD_INTHI);
-+		dma_buffer->data.sfcmd[2] = SFLASH_PREPCMD(3, 7, 0,
-+							MSM_NAND_SFCMD_DATXS,
-+							nand_sfcmd_mode,
-+							MSM_NAND_SFCMD_REGRD);
-+		dma_buffer->data.sfcmd[3] = SFLASH_PREPCMD(4, 10, 0,
-+							MSM_NAND_SFCMD_CMDXS,
-+							nand_sfcmd_mode,
-+							MSM_NAND_SFCMD_REGWR);
-+		dma_buffer->data.sfexec = 1;
-+		dma_buffer->data.sfstat[0] = CLEAN_DATA_32;
-+		dma_buffer->data.sfstat[1] = CLEAN_DATA_32;
-+		dma_buffer->data.sfstat[2] = CLEAN_DATA_32;
-+		dma_buffer->data.sfstat[3] = CLEAN_DATA_32;
-+		dma_buffer->data.addr0 = (ONENAND_INTERRUPT_STATUS << 16) |
-+						(ONENAND_SYSTEM_CONFIG_1);
-+		dma_buffer->data.addr1 = (ONENAND_START_ADDRESS_8 << 16) |
-+						(ONENAND_START_ADDRESS_1);
-+		dma_buffer->data.addr2 = (ONENAND_START_BLOCK_ADDRESS << 16) |
-+						(ONENAND_START_ADDRESS_2);
-+		dma_buffer->data.addr3 = (ONENAND_WRITE_PROT_STATUS << 16) |
-+						(ONENAND_COMMAND);
-+		dma_buffer->data.addr4 = (ONENAND_CONTROLLER_STATUS << 16) |
-+						(ONENAND_INTERRUPT_STATUS);
-+		dma_buffer->data.addr5 = (ONENAND_INTERRUPT_STATUS << 16) |
-+						(ONENAND_SYSTEM_CONFIG_1);
-+		dma_buffer->data.addr6 = (ONENAND_START_ADDRESS_3 << 16) |
-+						(ONENAND_START_ADDRESS_1);
-+		dma_buffer->data.data0 = (ONENAND_CLRINTR << 16) |
-+				(ONENAND_SYSCFG1_ECCENA(nand_sfcmd_mode));
-+		dma_buffer->data.data1 = (onenand_startaddr8 << 16) |
-+						(onenand_startaddr1);
-+		dma_buffer->data.data2 = (onenand_startblock << 16) |
-+						(onenand_startaddr2);
-+		dma_buffer->data.data3 = (CLEAN_DATA_16 << 16) |
-+						(ONENAND_CMD_UNLOCK);
-+		dma_buffer->data.data4 = (CLEAN_DATA_16 << 16) |
-+						(CLEAN_DATA_16);
-+		dma_buffer->data.data5 = (ONENAND_CLRINTR << 16) |
-+				(ONENAND_SYSCFG1_ECCENA(nand_sfcmd_mode));
-+		dma_buffer->data.data6 = (ONENAND_STARTADDR3_RES << 16) |
-+						(ONENAND_STARTADDR1_RES);
-+
-+		/*************************************************************/
-+		/* Write the necessary address reg in the onenand device     */
-+		/*************************************************************/
-+
-+		/* Enable and configure the SFlash controller */
-+		cmd->cmd = 0;
-+		cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.sfbcfg);
-+		cmd->dst = MSM_NAND_SFLASHC_BURST_CFG;
-+		cmd->len = 4;
-+		cmd++;
-+
-+		/* Block on cmd ready and write CMD register */
-+		cmd->cmd = DST_CRCI_NAND_CMD;
-+		cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.sfcmd[0]);
-+		cmd->dst = MSM_NAND_SFLASHC_CMD;
-+		cmd->len = 4;
-+		cmd++;
-+
-+		/* Write the ADDR0 and ADDR1 registers */
-+		cmd->cmd = 0;
-+		cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.addr0);
-+		cmd->dst = MSM_NAND_ADDR0;
-+		cmd->len = 8;
-+		cmd++;
-+
-+		/* Write the ADDR2 ADDR3 ADDR4 ADDR5 registers */
-+		cmd->cmd = 0;
-+		cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.addr2);
-+		cmd->dst = MSM_NAND_ADDR2;
-+		cmd->len = 16;
-+		cmd++;
-+
-+		/* Write the ADDR6 registers */
-+		cmd->cmd = 0;
-+		cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.addr6);
-+		cmd->dst = MSM_NAND_ADDR6;
-+		cmd->len = 4;
-+		cmd++;
-+
-+		/* Write the GENP0, GENP1, GENP2, GENP3, GENP4 registers */
-+		cmd->cmd = 0;
-+		cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.data0);
-+		cmd->dst = MSM_NAND_GENP_REG0;
-+		cmd->len = 16;
-+		cmd++;
-+
-+		/* Write the FLASH_DEV_CMD4,5,6 registers */
-+		cmd->cmd = 0;
-+		cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.data4);
-+		cmd->dst = MSM_NAND_DEV_CMD4;
-+		cmd->len = 12;
-+		cmd++;
-+
-+		/* Kick the execute command */
-+		cmd->cmd = 0;
-+		cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.sfexec);
-+		cmd->dst = MSM_NAND_SFLASHC_EXEC_CMD;
-+		cmd->len = 4;
-+		cmd++;
-+
-+		/* Block on data ready, and read the status register */
-+		cmd->cmd = SRC_CRCI_NAND_DATA;
-+		cmd->src = MSM_NAND_SFLASHC_STATUS;
-+		cmd->dst = msm_virt_to_dma(chip, &dma_buffer->data.sfstat[0]);
-+		cmd->len = 4;
-+		cmd++;
-+
-+		/*************************************************************/
-+		/* Wait for the interrupt from the Onenand device controller */
-+		/*************************************************************/
-+
-+		/* Block on cmd ready and write CMD register */
-+		cmd->cmd = DST_CRCI_NAND_CMD;
-+		cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.sfcmd[1]);
-+		cmd->dst = MSM_NAND_SFLASHC_CMD;
-+		cmd->len = 4;
-+		cmd++;
-+
-+		/* Kick the execute command */
-+		cmd->cmd = 0;
-+		cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.sfexec);
-+		cmd->dst = MSM_NAND_SFLASHC_EXEC_CMD;
-+		cmd->len = 4;
-+		cmd++;
-+
-+		/* Block on data ready, and read the status register */
-+		cmd->cmd = SRC_CRCI_NAND_DATA;
-+		cmd->src = MSM_NAND_SFLASHC_STATUS;
-+		cmd->dst = msm_virt_to_dma(chip, &dma_buffer->data.sfstat[1]);
-+		cmd->len = 4;
-+		cmd++;
-+
-+		/*********************************************************/
-+		/* Read the necessary status reg from the onenand device */
-+		/*********************************************************/
-+
-+		/* Block on cmd ready and write CMD register */
-+		cmd->cmd = DST_CRCI_NAND_CMD;
-+		cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.sfcmd[2]);
-+		cmd->dst = MSM_NAND_SFLASHC_CMD;
-+		cmd->len = 4;
-+		cmd++;
-+
-+		/* Kick the execute command */
-+		cmd->cmd = 0;
-+		cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.sfexec);
-+		cmd->dst = MSM_NAND_SFLASHC_EXEC_CMD;
-+		cmd->len = 4;
-+		cmd++;
-+
-+		/* Block on data ready, and read the status register */
-+		cmd->cmd = SRC_CRCI_NAND_DATA;
-+		cmd->src = MSM_NAND_SFLASHC_STATUS;
-+		cmd->dst = msm_virt_to_dma(chip, &dma_buffer->data.sfstat[2]);
-+		cmd->len = 4;
-+		cmd++;
-+
-+		/* Read the GENP3 register */
-+		cmd->cmd = 0;
-+		cmd->src = MSM_NAND_GENP_REG3;
-+		cmd->dst = msm_virt_to_dma(chip, &dma_buffer->data.data3);
-+		cmd->len = 4;
-+		cmd++;
-+
-+		/* Read the DEVCMD4 register */
-+		cmd->cmd = 0;
-+		cmd->src = MSM_NAND_DEV_CMD4;
-+		cmd->dst = msm_virt_to_dma(chip, &dma_buffer->data.data4);
-+		cmd->len = 4;
-+		cmd++;
-+
-+		/************************************************************/
-+		/* Restore the necessary registers to proper values         */
-+		/************************************************************/
-+
-+		/* Block on cmd ready and write CMD register */
-+		cmd->cmd = DST_CRCI_NAND_CMD;
-+		cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.sfcmd[3]);
-+		cmd->dst = MSM_NAND_SFLASHC_CMD;
-+		cmd->len = 4;
-+		cmd++;
-+
-+		/* Kick the execute command */
-+		cmd->cmd = 0;
-+		cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.sfexec);
-+		cmd->dst = MSM_NAND_SFLASHC_EXEC_CMD;
-+		cmd->len = 4;
-+		cmd++;
-+
-+		/* Block on data ready, and read the status register */
-+		cmd->cmd = SRC_CRCI_NAND_DATA;
-+		cmd->src = MSM_NAND_SFLASHC_STATUS;
-+		cmd->dst = msm_virt_to_dma(chip, &dma_buffer->data.sfstat[3]);
-+		cmd->len = 4;
-+		cmd++;
-+
-+
-+		BUILD_BUG_ON(20 != ARRAY_SIZE(dma_buffer->cmd));
-+		BUG_ON(cmd - dma_buffer->cmd > ARRAY_SIZE(dma_buffer->cmd));
-+		dma_buffer->cmd[0].cmd |= CMD_OCB;
-+		cmd[-1].cmd |= CMD_OCU | CMD_LC;
-+
-+		dma_buffer->cmdptr = (msm_virt_to_dma(chip, dma_buffer->cmd)
-+				>> 3) | CMD_PTR_LP;
-+
-+		mb();
-+		msm_dmov_exec_cmd(chip->dma_channel,
-+			DMOV_CMD_PTR_LIST | DMOV_CMD_ADDR(msm_virt_to_dma(chip,
-+				&dma_buffer->cmdptr)));
-+		mb();
-+
-+		write_prot_status = (dma_buffer->data.data3 >> 16) & 0x0000FFFF;
-+		interrupt_status = (dma_buffer->data.data4 >> 0) & 0x0000FFFF;
-+		controller_status = (dma_buffer->data.data4 >> 16) & 0x0000FFFF;
-+
-+#if VERBOSE
-+		pr_info("\n%s: sflash status %x %x %x %x\n", __func__,
-+					dma_buffer->data.sfstat[0],
-+					dma_buffer->data.sfstat[1],
-+					dma_buffer->data.sfstat[2],
-+					dma_buffer->data.sfstat[3]);
-+
-+		pr_info("%s: controller_status = %x\n", __func__,
-+					controller_status);
-+		pr_info("%s: interrupt_status = %x\n", __func__,
-+					interrupt_status);
-+		pr_info("%s: write_prot_status = %x\n", __func__,
-+					write_prot_status);
-+#endif
-+		/* Check for errors, protection violations etc */
-+		if ((controller_status != 0)
-+				|| (dma_buffer->data.sfstat[0] & 0x110)
-+				|| (dma_buffer->data.sfstat[1] & 0x110)
-+				|| (dma_buffer->data.sfstat[2] & 0x110)
-+				|| (dma_buffer->data.sfstat[3] & 0x110)) {
-+			pr_err("%s: ECC/MPU/OP error\n", __func__);
-+			err = -EIO;
-+		}
-+
-+		if (!(write_prot_status & ONENAND_WP_US)) {
-+			pr_err("%s: Unexpected status ofs = 0x%llx,"
-+				"wp_status = %x\n",
-+				__func__, ofs, write_prot_status);
-+			err = -EIO;
-+		}
-+
-+		if (err)
-+			break;
-+	}
-+
-+	msm_nand_release_dma_buffer(chip, dma_buffer, sizeof(*dma_buffer));
-+
-+#if VERBOSE
-+	pr_info("\n%s: ret %d\n", __func__, err);
-+	pr_info("===================================================="
-+			"=============\n");
-+#endif
-+	return err;
-+}
-+
-+static int msm_onenand_lock(struct mtd_info *mtd, loff_t ofs, uint64_t len)
-+{
-+	struct msm_nand_chip *chip = mtd->priv;
-+
-+	struct {
-+		dmov_s cmd[20];
-+		unsigned cmdptr;
-+		struct {
-+			uint32_t sfbcfg;
-+			uint32_t sfcmd[4];
-+			uint32_t sfexec;
-+			uint32_t sfstat[4];
-+			uint32_t addr0;
-+			uint32_t addr1;
-+			uint32_t addr2;
-+			uint32_t addr3;
-+			uint32_t addr4;
-+			uint32_t addr5;
-+			uint32_t addr6;
-+			uint32_t data0;
-+			uint32_t data1;
-+			uint32_t data2;
-+			uint32_t data3;
-+			uint32_t data4;
-+			uint32_t data5;
-+			uint32_t data6;
-+		} data;
-+	} *dma_buffer;
-+	dmov_s *cmd;
-+
-+	int err = 0;
-+
-+	uint16_t onenand_startaddr1;
-+	uint16_t onenand_startaddr8;
-+	uint16_t onenand_startaddr2;
-+	uint16_t onenand_startblock;
-+
-+	uint16_t controller_status;
-+	uint16_t interrupt_status;
-+	uint16_t write_prot_status;
-+
-+	uint64_t start_ofs;
-+
-+#if VERBOSE
-+	pr_info("===================================================="
-+			"=============\n");
-+	pr_info("%s: ofs 0x%llx len %lld\n", __func__, ofs, len);
-+#endif
-+	/* 'ofs' & 'len' should align to block size */
-+	if (ofs&(mtd->erasesize - 1)) {
-+		pr_err("%s: Unsupported ofs address, 0x%llx\n",
-+				__func__, ofs);
-+		return -EINVAL;
-+	}
-+
-+	if (len&(mtd->erasesize - 1)) {
-+		pr_err("%s: Unsupported len, %lld\n",
-+				__func__, len);
-+		return -EINVAL;
-+	}
-+
-+	if (ofs+len > mtd->size) {
-+		pr_err("%s: Maximum chip size exceeded\n", __func__);
-+		return -EINVAL;
-+	}
-+
-+	wait_event(chip->wait_queue, (dma_buffer = msm_nand_get_dma_buffer
-+				(chip, sizeof(*dma_buffer))));
-+
-+	for (start_ofs = ofs; ofs < start_ofs+len; ofs = ofs+mtd->erasesize) {
-+#if VERBOSE
-+		pr_info("%s: ofs 0x%llx len %lld\n", __func__, ofs, len);
-+#endif
-+
-+		cmd = dma_buffer->cmd;
-+		if ((onenand_info.device_id & ONENAND_DEVICE_IS_DDP)
-+			&& (ofs >= (mtd->size>>1))) { /* DDP Device */
-+			onenand_startaddr1 = DEVICE_FLASHCORE_1 |
-+				(((uint32_t)(ofs - (mtd->size>>1))
-+						/ mtd->erasesize));
-+			onenand_startaddr2 = DEVICE_BUFFERRAM_1;
-+			onenand_startblock = ((uint32_t)(ofs - (mtd->size>>1))
-+						/ mtd->erasesize);
-+		} else {
-+			onenand_startaddr1 = DEVICE_FLASHCORE_0 |
-+					((uint32_t)ofs / mtd->erasesize) ;
-+			onenand_startaddr2 = DEVICE_BUFFERRAM_0;
-+			onenand_startblock = ((uint32_t)ofs
-+						/ mtd->erasesize);
-+		}
-+
-+		onenand_startaddr8 = 0x0000;
-+		dma_buffer->data.sfbcfg = SFLASH_BCFG |
-+					(nand_sfcmd_mode ? 0 : (1 << 24));
-+		dma_buffer->data.sfcmd[0] = SFLASH_PREPCMD(7, 0, 0,
-+							MSM_NAND_SFCMD_CMDXS,
-+							nand_sfcmd_mode,
-+							MSM_NAND_SFCMD_REGWR);
-+		dma_buffer->data.sfcmd[1] = SFLASH_PREPCMD(0, 0, 32,
-+							MSM_NAND_SFCMD_CMDXS,
-+							nand_sfcmd_mode,
-+							MSM_NAND_SFCMD_INTHI);
-+		dma_buffer->data.sfcmd[2] = SFLASH_PREPCMD(3, 7, 0,
-+							MSM_NAND_SFCMD_DATXS,
-+							nand_sfcmd_mode,
-+							MSM_NAND_SFCMD_REGRD);
-+		dma_buffer->data.sfcmd[3] = SFLASH_PREPCMD(4, 10, 0,
-+							MSM_NAND_SFCMD_CMDXS,
-+							nand_sfcmd_mode,
-+							MSM_NAND_SFCMD_REGWR);
-+		dma_buffer->data.sfexec = 1;
-+		dma_buffer->data.sfstat[0] = CLEAN_DATA_32;
-+		dma_buffer->data.sfstat[1] = CLEAN_DATA_32;
-+		dma_buffer->data.sfstat[2] = CLEAN_DATA_32;
-+		dma_buffer->data.sfstat[3] = CLEAN_DATA_32;
-+		dma_buffer->data.addr0 = (ONENAND_INTERRUPT_STATUS << 16) |
-+						(ONENAND_SYSTEM_CONFIG_1);
-+		dma_buffer->data.addr1 = (ONENAND_START_ADDRESS_8 << 16) |
-+						(ONENAND_START_ADDRESS_1);
-+		dma_buffer->data.addr2 = (ONENAND_START_BLOCK_ADDRESS << 16) |
-+						(ONENAND_START_ADDRESS_2);
-+		dma_buffer->data.addr3 = (ONENAND_WRITE_PROT_STATUS << 16) |
-+						(ONENAND_COMMAND);
-+		dma_buffer->data.addr4 = (ONENAND_CONTROLLER_STATUS << 16) |
-+						(ONENAND_INTERRUPT_STATUS);
-+		dma_buffer->data.addr5 = (ONENAND_INTERRUPT_STATUS << 16) |
-+						(ONENAND_SYSTEM_CONFIG_1);
-+		dma_buffer->data.addr6 = (ONENAND_START_ADDRESS_3 << 16) |
-+						(ONENAND_START_ADDRESS_1);
-+		dma_buffer->data.data0 = (ONENAND_CLRINTR << 16) |
-+				(ONENAND_SYSCFG1_ECCENA(nand_sfcmd_mode));
-+		dma_buffer->data.data1 = (onenand_startaddr8 << 16) |
-+						(onenand_startaddr1);
-+		dma_buffer->data.data2 = (onenand_startblock << 16) |
-+						(onenand_startaddr2);
-+		dma_buffer->data.data3 = (CLEAN_DATA_16 << 16) |
-+						(ONENAND_CMD_LOCK);
-+		dma_buffer->data.data4 = (CLEAN_DATA_16 << 16) |
-+						(CLEAN_DATA_16);
-+		dma_buffer->data.data5 = (ONENAND_CLRINTR << 16) |
-+				(ONENAND_SYSCFG1_ECCENA(nand_sfcmd_mode));
-+		dma_buffer->data.data6 = (ONENAND_STARTADDR3_RES << 16) |
-+						(ONENAND_STARTADDR1_RES);
-+
-+		/*************************************************************/
-+		/* Write the necessary address reg in the onenand device     */
-+		/*************************************************************/
-+
-+		/* Enable and configure the SFlash controller */
-+		cmd->cmd = 0;
-+		cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.sfbcfg);
-+		cmd->dst = MSM_NAND_SFLASHC_BURST_CFG;
-+		cmd->len = 4;
-+		cmd++;
-+
-+		/* Block on cmd ready and write CMD register */
-+		cmd->cmd = DST_CRCI_NAND_CMD;
-+		cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.sfcmd[0]);
-+		cmd->dst = MSM_NAND_SFLASHC_CMD;
-+		cmd->len = 4;
-+		cmd++;
-+
-+		/* Write the ADDR0 and ADDR1 registers */
-+		cmd->cmd = 0;
-+		cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.addr0);
-+		cmd->dst = MSM_NAND_ADDR0;
-+		cmd->len = 8;
-+		cmd++;
-+
-+		/* Write the ADDR2 ADDR3 ADDR4 ADDR5 registers */
-+		cmd->cmd = 0;
-+		cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.addr2);
-+		cmd->dst = MSM_NAND_ADDR2;
-+		cmd->len = 16;
-+		cmd++;
-+
-+		/* Write the ADDR6 registers */
-+		cmd->cmd = 0;
-+		cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.addr6);
-+		cmd->dst = MSM_NAND_ADDR6;
-+		cmd->len = 4;
-+		cmd++;
-+
-+		/* Write the GENP0, GENP1, GENP2, GENP3, GENP4 registers */
-+		cmd->cmd = 0;
-+		cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.data0);
-+		cmd->dst = MSM_NAND_GENP_REG0;
-+		cmd->len = 16;
-+		cmd++;
-+
-+		/* Write the FLASH_DEV_CMD4,5,6 registers */
-+		cmd->cmd = 0;
-+		cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.data4);
-+		cmd->dst = MSM_NAND_DEV_CMD4;
-+		cmd->len = 12;
-+		cmd++;
-+
-+		/* Kick the execute command */
-+		cmd->cmd = 0;
-+		cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.sfexec);
-+		cmd->dst = MSM_NAND_SFLASHC_EXEC_CMD;
-+		cmd->len = 4;
-+		cmd++;
-+
-+		/* Block on data ready, and read the status register */
-+		cmd->cmd = SRC_CRCI_NAND_DATA;
-+		cmd->src = MSM_NAND_SFLASHC_STATUS;
-+		cmd->dst = msm_virt_to_dma(chip, &dma_buffer->data.sfstat[0]);
-+		cmd->len = 4;
-+		cmd++;
-+
-+		/*************************************************************/
-+		/* Wait for the interrupt from the Onenand device controller */
-+		/*************************************************************/
-+
-+		/* Block on cmd ready and write CMD register */
-+		cmd->cmd = DST_CRCI_NAND_CMD;
-+		cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.sfcmd[1]);
-+		cmd->dst = MSM_NAND_SFLASHC_CMD;
-+		cmd->len = 4;
-+		cmd++;
-+
-+		/* Kick the execute command */
-+		cmd->cmd = 0;
-+		cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.sfexec);
-+		cmd->dst = MSM_NAND_SFLASHC_EXEC_CMD;
-+		cmd->len = 4;
-+		cmd++;
-+
-+		/* Block on data ready, and read the status register */
-+		cmd->cmd = SRC_CRCI_NAND_DATA;
-+		cmd->src = MSM_NAND_SFLASHC_STATUS;
-+		cmd->dst = msm_virt_to_dma(chip, &dma_buffer->data.sfstat[1]);
-+		cmd->len = 4;
-+		cmd++;
-+
-+		/*********************************************************/
-+		/* Read the necessary status reg from the onenand device */
-+		/*********************************************************/
-+
-+		/* Block on cmd ready and write CMD register */
-+		cmd->cmd = DST_CRCI_NAND_CMD;
-+		cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.sfcmd[2]);
-+		cmd->dst = MSM_NAND_SFLASHC_CMD;
-+		cmd->len = 4;
-+		cmd++;
-+
-+		/* Kick the execute command */
-+		cmd->cmd = 0;
-+		cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.sfexec);
-+		cmd->dst = MSM_NAND_SFLASHC_EXEC_CMD;
-+		cmd->len = 4;
-+		cmd++;
-+
-+		/* Block on data ready, and read the status register */
-+		cmd->cmd = SRC_CRCI_NAND_DATA;
-+		cmd->src = MSM_NAND_SFLASHC_STATUS;
-+		cmd->dst = msm_virt_to_dma(chip, &dma_buffer->data.sfstat[2]);
-+		cmd->len = 4;
-+		cmd++;
-+
-+		/* Read the GENP3 register */
-+		cmd->cmd = 0;
-+		cmd->src = MSM_NAND_GENP_REG3;
-+		cmd->dst = msm_virt_to_dma(chip, &dma_buffer->data.data3);
-+		cmd->len = 4;
-+		cmd++;
-+
-+		/* Read the DEVCMD4 register */
-+		cmd->cmd = 0;
-+		cmd->src = MSM_NAND_DEV_CMD4;
-+		cmd->dst = msm_virt_to_dma(chip, &dma_buffer->data.data4);
-+		cmd->len = 4;
-+		cmd++;
-+
-+		/************************************************************/
-+		/* Restore the necessary registers to proper values         */
-+		/************************************************************/
-+
-+		/* Block on cmd ready and write CMD register */
-+		cmd->cmd = DST_CRCI_NAND_CMD;
-+		cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.sfcmd[3]);
-+		cmd->dst = MSM_NAND_SFLASHC_CMD;
-+		cmd->len = 4;
-+		cmd++;
-+
-+		/* Kick the execute command */
-+		cmd->cmd = 0;
-+		cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.sfexec);
-+		cmd->dst = MSM_NAND_SFLASHC_EXEC_CMD;
-+		cmd->len = 4;
-+		cmd++;
-+
-+		/* Block on data ready, and read the status register */
-+		cmd->cmd = SRC_CRCI_NAND_DATA;
-+		cmd->src = MSM_NAND_SFLASHC_STATUS;
-+		cmd->dst = msm_virt_to_dma(chip, &dma_buffer->data.sfstat[3]);
-+		cmd->len = 4;
-+		cmd++;
-+
-+
-+		BUILD_BUG_ON(20 != ARRAY_SIZE(dma_buffer->cmd));
-+		BUG_ON(cmd - dma_buffer->cmd > ARRAY_SIZE(dma_buffer->cmd));
-+		dma_buffer->cmd[0].cmd |= CMD_OCB;
-+		cmd[-1].cmd |= CMD_OCU | CMD_LC;
-+
-+		dma_buffer->cmdptr = (msm_virt_to_dma(chip, dma_buffer->cmd)
-+				>> 3) | CMD_PTR_LP;
-+
-+		mb();
-+		msm_dmov_exec_cmd(chip->dma_channel,
-+			DMOV_CMD_PTR_LIST | DMOV_CMD_ADDR(msm_virt_to_dma(chip,
-+				&dma_buffer->cmdptr)));
-+		mb();
-+
-+		write_prot_status = (dma_buffer->data.data3 >> 16) & 0x0000FFFF;
-+		interrupt_status = (dma_buffer->data.data4 >> 0) & 0x0000FFFF;
-+		controller_status = (dma_buffer->data.data4 >> 16) & 0x0000FFFF;
-+
-+#if VERBOSE
-+		pr_info("\n%s: sflash status %x %x %x %x\n", __func__,
-+					dma_buffer->data.sfstat[0],
-+					dma_buffer->data.sfstat[1],
-+					dma_buffer->data.sfstat[2],
-+					dma_buffer->data.sfstat[3]);
-+
-+		pr_info("%s: controller_status = %x\n", __func__,
-+					controller_status);
-+		pr_info("%s: interrupt_status = %x\n", __func__,
-+					interrupt_status);
-+		pr_info("%s: write_prot_status = %x\n", __func__,
-+					write_prot_status);
-+#endif
-+		/* Check for errors, protection violations etc */
-+		if ((controller_status != 0)
-+				|| (dma_buffer->data.sfstat[0] & 0x110)
-+				|| (dma_buffer->data.sfstat[1] & 0x110)
-+				|| (dma_buffer->data.sfstat[2] & 0x110)
-+				|| (dma_buffer->data.sfstat[3] & 0x110)) {
-+			pr_err("%s: ECC/MPU/OP error\n", __func__);
-+			err = -EIO;
-+		}
-+
-+		if (!(write_prot_status & ONENAND_WP_LS)) {
-+			pr_err("%s: Unexpected status ofs = 0x%llx,"
-+				"wp_status = %x\n",
-+				__func__, ofs, write_prot_status);
-+			err = -EIO;
-+		}
-+
-+		if (err)
-+			break;
-+	}
-+
-+	msm_nand_release_dma_buffer(chip, dma_buffer, sizeof(*dma_buffer));
-+
-+#if VERBOSE
-+	pr_info("\n%s: ret %d\n", __func__, err);
-+	pr_info("===================================================="
-+			"=============\n");
-+#endif
-+	return err;
-+}
-+
-+static int msm_onenand_suspend(struct mtd_info *mtd)
-+{
-+	return 0;
-+}
-+
-+static void msm_onenand_resume(struct mtd_info *mtd)
-+{
-+}
-+
-+int msm_onenand_scan(struct mtd_info *mtd, int maxchips)
-+{
-+	struct msm_nand_chip *chip = mtd->priv;
-+
-+	/* Probe and check whether onenand device is present */
-+	if (flash_onenand_probe(chip))
-+		return -ENODEV;
-+
-+	mtd->size = 0x1000000 << ((onenand_info.device_id & 0xF0) >> 4);
-+	mtd->writesize = onenand_info.data_buf_size;
-+	mtd->oobsize = mtd->writesize >> 5;
-+	mtd->erasesize = mtd->writesize << 6;
-+	mtd->oobavail = msm_onenand_oob_64.oobavail;
-+	mtd->ecclayout = &msm_onenand_oob_64;
-+
-+	mtd->type = MTD_NANDFLASH;
-+	mtd->flags = MTD_CAP_NANDFLASH;
-+	mtd->_erase = msm_onenand_erase;
-+	mtd->_point = NULL;
-+	mtd->_unpoint = NULL;
-+	mtd->_read = msm_onenand_read;
-+	mtd->_write = msm_onenand_write;
-+	mtd->_read_oob = msm_onenand_read_oob;
-+	mtd->_write_oob = msm_onenand_write_oob;
-+	mtd->_lock = msm_onenand_lock;
-+	mtd->_unlock = msm_onenand_unlock;
-+	mtd->_suspend = msm_onenand_suspend;
-+	mtd->_resume = msm_onenand_resume;
-+	mtd->_block_isbad = msm_onenand_block_isbad;
-+	mtd->_block_markbad = msm_onenand_block_markbad;
-+	mtd->owner = THIS_MODULE;
-+
-+	pr_info("Found a supported onenand device\n");
-+
-+	return 0;
-+}
-+
-+static const unsigned int bch_sup_cntrl[] = {
-+	0x307, /* MSM7x2xA */
-+	0x4030, /* MDM 9x15 */
-+};
-+
-+static inline bool msm_nand_has_bch_ecc_engine(unsigned int hw_id)
-+{
-+	int i;
-+
-+	for (i = 0; i < ARRAY_SIZE(bch_sup_cntrl); i++) {
-+		if (hw_id == bch_sup_cntrl[i])
-+			return true;
-+	}
-+
-+	return false;
-+}
-+
-+/**
-+ * msm_nand_scan - [msm_nand Interface] Scan for the msm_nand device
-+ * @param mtd		MTD device structure
-+ * @param maxchips	Number of chips to scan for
-+ *
-+ * This fills out all the not initialized function pointers
-+ * with the defaults.
-+ * The flash ID is read and the mtd/chip structures are
-+ * filled with the appropriate values.
-+ */
-+int msm_nand_scan(struct mtd_info *mtd, int maxchips)
-+{
-+	struct msm_nand_chip *chip = mtd->priv;
-+	uint32_t flash_id = 0, i, mtd_writesize;
-+	uint8_t dev_found = 0;
-+	uint8_t wide_bus;
-+	uint32_t manid;
-+	uint32_t devid;
-+	uint32_t devcfg;
-+	struct nand_flash_dev *flashdev = NULL;
-+	struct nand_manufacturers  *flashman = NULL;
-+	unsigned int hw_id;
-+
-+	/*
-+	 * Some Spansion parts, like the S34MS04G2, requires that the
-+	 * NAND Flash be reset before issuing an ONFI probe.
-+	 */
-+	flash_reset(chip);
-+
-+	/* Probe the Flash device for ONFI compliance */
-+	if (!flash_onfi_probe(chip)) {
-+		dev_found = 1;
-+	} else {
-+		/* Read the Flash ID from the Nand Flash Device */
-+		flash_id = flash_read_id(chip);
-+		manid = flash_id & 0xFF;
-+		devid = (flash_id >> 8) & 0xFF;
-+		devcfg = (flash_id >> 24) & 0xFF;
-+
-+		for (i = 0; !flashman && nand_manuf_ids[i].id; ++i)
-+			if (nand_manuf_ids[i].id == manid)
-+				flashman = &nand_manuf_ids[i];
-+		for (i = 0; !flashdev && nand_flash_ids[i].id; ++i)
-+			if (nand_flash_ids[i].id == devid)
-+				flashdev = &nand_flash_ids[i];
-+		if (!flashdev || !flashman) {
-+			pr_err("ERROR: unknown nand device manuf=%x devid=%x\n",
-+				manid, devid);
-+			return -ENOENT;
-+		} else
-+			dev_found = 1;
-+
-+		if (!flashdev->pagesize) {
-+			supported_flash.flash_id = flash_id;
-+			supported_flash.density = flashdev->chipsize << 20;
-+			supported_flash.widebus = devcfg & (1 << 6) ? 1 : 0;
-+			supported_flash.pagesize = 1024 << (devcfg & 0x3);
-+			supported_flash.blksize = (64 * 1024) <<
-+							((devcfg >> 4) & 0x3);
-+			supported_flash.oobsize = (8 << ((devcfg >> 2) & 0x3)) *
-+				(supported_flash.pagesize >> 9);
-+
-+			if ((supported_flash.oobsize > 64) &&
-+				(supported_flash.pagesize == 2048)) {
-+				pr_info("msm_nand: Found a 2K page device with"
-+					" %d oobsize - changing oobsize to 64 "
-+					"bytes.\n", supported_flash.oobsize);
-+				supported_flash.oobsize = 64;
-+			}
-+		} else {
-+			supported_flash.flash_id = flash_id;
-+			supported_flash.density = flashdev->chipsize << 20;
-+			supported_flash.widebus = flashdev->options &
-+					 NAND_BUSWIDTH_16 ? 1 : 0;
-+			supported_flash.pagesize = flashdev->pagesize;
-+			supported_flash.blksize = flashdev->erasesize;
-+			supported_flash.oobsize = flashdev->pagesize >> 5;
-+		}
-+	}
-+
-+	if (dev_found) {
-+		(!interleave_enable) ? (i = 1) : (i = 2);
-+		wide_bus       = supported_flash.widebus;
-+		mtd->size      = supported_flash.density  * i;
-+		mtd->writesize = supported_flash.pagesize * i;
-+		mtd->oobsize   = supported_flash.oobsize  * i;
-+		mtd->erasesize = supported_flash.blksize  * i;
-+		mtd->writebufsize = mtd->writesize;
-+
-+		if (!interleave_enable)
-+			mtd_writesize = mtd->writesize;
-+		else
-+			mtd_writesize = mtd->writesize >> 1;
-+
-+		/* Check whether controller and NAND device support 8bit ECC*/
-+		hw_id = flash_rd_reg(chip, MSM_NAND_HW_INFO);
-+		if (msm_nand_has_bch_ecc_engine(hw_id)
-+				&& (supported_flash.ecc_correctability >= 8)) {
-+			pr_info("Found supported NAND device for %dbit ECC\n",
-+					supported_flash.ecc_correctability);
-+			enable_bch_ecc = 1;
-+		} else {
-+			pr_info("Found a supported NAND device\n");
-+		}
-+		pr_info("NAND Controller ID : 0x%x\n", hw_id);
-+		pr_info("NAND Device ID  : 0x%x\n", supported_flash.flash_id);
-+		pr_info("Buswidth : %d Bits\n", (wide_bus) ? 16 : 8);
-+		pr_info("Density  : %lld MByte\n", (mtd->size>>20));
-+		pr_info("Pagesize : %d Bytes\n", mtd->writesize);
-+		pr_info("Erasesize: %d Bytes\n", mtd->erasesize);
-+		pr_info("Oobsize  : %d Bytes\n", mtd->oobsize);
-+	} else {
-+		pr_err("Unsupported Nand,Id: 0x%x \n", flash_id);
-+		return -ENODEV;
-+	}
-+
-+	/* Size of each codeword is 532Bytes incase of 8bit BCH ECC*/
-+	chip->cw_size = enable_bch_ecc ? 532 : 528;
-+	chip->CFG0 = (((mtd_writesize >> 9)-1) << 6) /* 4/8 cw/pg for 2/4k */
-+		|  (516 <<  9)  /* 516 user data bytes */
-+		|   (10 << 19)  /* 10 parity bytes */
-+		|    (5 << 27)  /* 5 address cycles */
-+		|    (0 << 30)  /* Do not read status before data */
-+		|    (1 << 31)  /* Send read cmd */
-+		/* 0 spare bytes for 16 bit nand or 1/2 spare bytes for 8 bit */
-+		| (wide_bus ? 0 << 23 : (enable_bch_ecc ? 2 << 23 : 1 << 23));
-+
-+	chip->CFG1 = (0 <<  0)  /* Enable ecc */
-+		|    (7 <<  2)  /* 8 recovery cycles */
-+		|    (0 <<  5)  /* Allow CS deassertion */
-+		/* Bad block marker location */
-+		|  ((mtd_writesize - (chip->cw_size * (
-+					(mtd_writesize >> 9) - 1)) + 1) <<  6)
-+		|    (0 << 16)  /* Bad block in user data area */
-+		|    (2 << 17)  /* 6 cycle tWB/tRB */
-+		| ((wide_bus) ? CFG1_WIDE_FLASH : 0); /* Wide flash bit */
-+
-+	chip->ecc_buf_cfg = 0x203;
-+	chip->CFG0_RAW = 0xA80420C0;
-+	chip->CFG1_RAW = 0x5045D;
-+
-+	if (enable_bch_ecc) {
-+		chip->CFG1 |= (1 << 27); /* Enable BCH engine */
-+		chip->ecc_bch_cfg = (0 << 0) /* Enable ECC*/
-+			|   (0 << 1) /* Enable/Disable SW reset of ECC engine */
-+			|   (1 << 4) /* 8bit ecc*/
-+			|   ((wide_bus) ? (14 << 8) : (13 << 8))/*parity bytes*/
-+			|   (516 << 16) /* 516 user data bytes */
-+			|   (1 << 30); /* Turn on ECC engine clocks always */
-+		chip->CFG0_RAW = 0xA80428C0; /* CW size is increased to 532B */
-+	}
-+
-+	/*
-+	 * For 4bit RS ECC (default ECC), parity bytes = 10 (for x8 and x16 I/O)
-+	 * For 8bit BCH ECC, parity bytes = 13 (x8) or 14 (x16 I/O).
-+	 */
-+	chip->ecc_parity_bytes = enable_bch_ecc ? (wide_bus ? 14 : 13) : 10;
-+
-+	pr_info("CFG0 Init  : 0x%08x\n", chip->CFG0);
-+	pr_info("CFG1 Init  : 0x%08x\n", chip->CFG1);
-+	pr_info("ECCBUFCFG  : 0x%08x\n", chip->ecc_buf_cfg);
-+
-+	if (mtd->oobsize == 64) {
-+		mtd->oobavail = msm_nand_oob_64.oobavail;
-+		mtd->ecclayout = &msm_nand_oob_64;
-+	} else if (mtd->oobsize == 128) {
-+		mtd->oobavail = msm_nand_oob_128.oobavail;
-+		mtd->ecclayout = &msm_nand_oob_128;
-+	} else if (mtd->oobsize == 224) {
-+		mtd->oobavail = wide_bus ? msm_nand_oob_224_x16.oobavail :
-+			msm_nand_oob_224_x8.oobavail;
-+		mtd->ecclayout = wide_bus ? &msm_nand_oob_224_x16 :
-+			&msm_nand_oob_224_x8;
-+	} else if (mtd->oobsize == 256) {
-+		mtd->oobavail = msm_nand_oob_256.oobavail;
-+		mtd->ecclayout = &msm_nand_oob_256;
-+	} else {
-+		pr_err("Unsupported Nand, oobsize: 0x%x \n",
-+		       mtd->oobsize);
-+		return -ENODEV;
-+	}
-+
-+	/* Fill in remaining MTD driver data */
-+	mtd->type = MTD_NANDFLASH;
-+	mtd->flags = MTD_CAP_NANDFLASH;
-+	/* mtd->ecctype = MTD_ECC_SW; */
-+	mtd->_erase = msm_nand_erase;
-+	mtd->_block_isbad = msm_nand_block_isbad;
-+	mtd->_block_markbad = msm_nand_block_markbad;
-+	mtd->_point = NULL;
-+	mtd->_unpoint = NULL;
-+	mtd->_read = msm_nand_read;
-+	mtd->_write = msm_nand_write;
-+	mtd->_read_oob  = msm_nand_read_oob;
-+	mtd->_write_oob = msm_nand_write_oob;
-+	if (dual_nand_ctlr_present) {
-+		mtd->_read_oob = msm_nand_read_oob_dualnandc;
-+		mtd->_write_oob = msm_nand_write_oob_dualnandc;
-+		if (interleave_enable) {
-+			mtd->_erase = msm_nand_erase_dualnandc;
-+			mtd->_block_isbad = msm_nand_block_isbad_dualnandc;
-+		}
-+	}
-+
-+	/* mtd->sync = msm_nand_sync; */
-+	mtd->_lock = NULL;
-+	/* mtd->_unlock = msm_nand_unlock; */
-+	mtd->_suspend = msm_nand_suspend;
-+	mtd->_resume = msm_nand_resume;
-+	mtd->owner = THIS_MODULE;
-+
-+	/* Unlock whole block */
-+	/* msm_nand_unlock_all(mtd); */
-+
-+	/* return this->scan_bbt(mtd); */
-+	return 0;
-+}
-+EXPORT_SYMBOL_GPL(msm_nand_scan);
-+
-+/**
-+ * msm_nand_release - [msm_nand Interface] Free resources held by the msm_nand device
-+ * @param mtd		MTD device structure
-+ */
-+void msm_nand_release(struct mtd_info *mtd)
-+{
-+	/* struct msm_nand_chip *this = mtd->priv; */
-+
-+	/* Deregister the device */
-+	mtd_device_unregister(mtd);
-+}
-+EXPORT_SYMBOL_GPL(msm_nand_release);
-+
-+struct msm_nand_info {
-+	struct mtd_info		mtd;
-+	struct mtd_partition	*parts;
-+	struct msm_nand_chip	msm_nand;
-+};
-+
-+/* duplicating the NC01 XFR contents to NC10 */
-+static int msm_nand_nc10_xfr_settings(struct mtd_info *mtd)
-+{
-+	struct msm_nand_chip *chip = mtd->priv;
-+
-+	struct {
-+		dmov_s cmd[2];
-+		unsigned cmdptr;
-+	} *dma_buffer;
-+	dmov_s *cmd;
-+
-+	wait_event(chip->wait_queue,
-+		(dma_buffer = msm_nand_get_dma_buffer(
-+				chip, sizeof(*dma_buffer))));
-+
-+	cmd = dma_buffer->cmd;
-+
-+	/* Copying XFR register contents from NC01 --> NC10 */
-+	cmd->cmd = 0;
-+	cmd->src = NC01(MSM_NAND_XFR_STEP1);
-+	cmd->dst = NC10(MSM_NAND_XFR_STEP1);
-+	cmd->len = 28;
-+	cmd++;
-+
-+	BUILD_BUG_ON(2 != ARRAY_SIZE(dma_buffer->cmd));
-+	BUG_ON(cmd - dma_buffer->cmd > ARRAY_SIZE(dma_buffer->cmd));
-+	dma_buffer->cmd[0].cmd |= CMD_OCB;
-+	cmd[-1].cmd |= CMD_OCU | CMD_LC;
-+	dma_buffer->cmdptr = (msm_virt_to_dma(chip, dma_buffer->cmd) >> 3)
-+				| CMD_PTR_LP;
-+
-+	mb();
-+	msm_dmov_exec_cmd(chip->dma_channel, DMOV_CMD_PTR_LIST
-+			| DMOV_CMD_ADDR(msm_virt_to_dma(chip,
-+			&dma_buffer->cmdptr)));
-+	mb();
-+	msm_nand_release_dma_buffer(chip, dma_buffer, sizeof(*dma_buffer));
-+	return 0;
-+}
-+
-+static ssize_t boot_layout_show(struct device *dev,
-+                                  struct device_attribute *attr,
-+                                  char *buf)
-+{
-+	return sprintf(buf, "%d\n", boot_layout);
-+}
-+
-+static ssize_t boot_layout_store(struct device *dev,
-+                                   struct device_attribute *attr,
-+                                   const char *buf, size_t n)
-+{
-+	struct msm_nand_info *info = dev_get_drvdata(dev);
-+	struct msm_nand_chip *chip = info->mtd.priv;
-+	unsigned int ud_size;
-+	unsigned int spare_size;
-+	unsigned int ecc_num_data_bytes;
-+
-+	sscanf(buf, "%d", &boot_layout);
-+
-+	ud_size = boot_layout? 512: 516;
-+	spare_size = boot_layout? (chip->cw_size -
-+					(chip->ecc_parity_bytes+ 1+ ud_size)):
-+					(enable_bch_ecc ? 2 : 1);
-+	ecc_num_data_bytes = boot_layout? 512: 516;
-+
-+	chip->CFG0 = (chip->CFG0 & ~SPARE_SIZE_BYTES_MASK);
-+	chip->CFG0 |= (spare_size << 23);
-+
-+	chip->CFG0 = (chip->CFG0 & ~UD_SIZE_BYTES_MASK);
-+	chip->CFG0 |= (ud_size << 9);
-+
-+	chip->ecc_buf_cfg = (chip->ecc_buf_cfg & ~ECC_NUM_DATA_BYTES_MASK)
-+				| (ecc_num_data_bytes << 16);
-+
-+	return n;
-+}
-+
-+static const DEVICE_ATTR(boot_layout, 0644, boot_layout_show, boot_layout_store);
-+
-+static int msm_nand_probe(struct platform_device *pdev)
-+
-+{
-+        struct msm_nand_info *info;
-+	struct resource *res;
-+	int err;
-+	struct mtd_part_parser_data ppdata = {};
-+
-+
-+	res = platform_get_resource(pdev,
-+					IORESOURCE_MEM, 0);
-+	if (!res || !res->start) {
-+		pr_err("%s: msm_nand_phys resource invalid/absent\n",
-+				__func__);
-+		return -ENODEV;
-+	}
-+	msm_nand_phys = res->start;
-+
-+	info = devm_kzalloc(&pdev->dev, sizeof(struct msm_nand_info), GFP_KERNEL);
-+	if (!info) {
-+		pr_err("%s: No memory for msm_nand_info\n", __func__);
-+		return -ENOMEM;
-+	}
-+
-+	info->msm_nand.dev = &pdev->dev;
-+
-+	init_waitqueue_head(&info->msm_nand.wait_queue);
-+
-+	info->msm_nand.dma_channel = 3;
-+	pr_info("%s: dmac 0x%x\n", __func__, info->msm_nand.dma_channel);
-+
-+	/* this currently fails if dev is passed in */
-+	info->msm_nand.dma_buffer =
-+		dma_alloc_coherent(/*dev*/ NULL, MSM_NAND_DMA_BUFFER_SIZE,
-+				&info->msm_nand.dma_addr, GFP_KERNEL);
-+	if (info->msm_nand.dma_buffer == NULL) {
-+		pr_err("%s: No memory for msm_nand.dma_buffer\n", __func__);
-+		err = -ENOMEM;
-+		goto out_free_info;
-+	}
-+
-+	pr_info("%s: allocated dma buffer at %p, dma_addr %x\n",
-+		__func__, info->msm_nand.dma_buffer, info->msm_nand.dma_addr);
-+
-+	/* Let default be VERSION_1 for backward compatibility */
-+	info->msm_nand.uncorrectable_bit_mask = BIT(8);
-+	info->msm_nand.num_err_mask = 0x1F;
-+
-+	info->mtd.name = dev_name(&pdev->dev);
-+	info->mtd.priv = &info->msm_nand;
-+	info->mtd.owner = THIS_MODULE;
-+
-+	/* config ebi2_cfg register only for ping pong mode!!! */
-+	if (!interleave_enable && dual_nand_ctlr_present)
-+		flash_wr_reg(&info->msm_nand, EBI2_CFG_REG, 0x4010080);
-+
-+	if (dual_nand_ctlr_present)
-+		msm_nand_nc10_xfr_settings(&info->mtd);
-+
-+	if (msm_nand_scan(&info->mtd, 1))
-+		if (msm_onenand_scan(&info->mtd, 1)) {
-+			pr_err("%s: No nand device found\n", __func__);
-+			err = -ENXIO;
-+			goto out_free_dma_buffer;
-+		}
-+
-+	flash_wr_reg(&info->msm_nand, MSM_NAND_DEV_CMD_VLD,
-+				DEV_CMD_VLD_SEQ_READ_START_VLD |
-+				DEV_CMD_VLD_ERASE_START_VLD |
-+				DEV_CMD_VLD_WRITE_START_VLD |
-+				DEV_CMD_VLD_READ_START_VLD);
-+
-+	ppdata.of_node = pdev->dev.of_node;
-+	err = mtd_device_parse_register(&info->mtd, NULL, &ppdata, NULL, 0);
-+
-+	if (err < 0) {
-+		pr_err("%s: mtd_device_parse_register failed with err=%d\n",
-+				__func__, err);
-+		goto out_free_dma_buffer;
-+	}
-+
-+	err = sysfs_create_file(&pdev->dev.kobj, &dev_attr_boot_layout.attr);
-+	if (err)
-+		goto out_free_dma_buffer;
-+
-+	dev_set_drvdata(&pdev->dev, info);
-+
-+	return 0;
-+
-+out_free_dma_buffer:
-+	dma_free_coherent(NULL, MSM_NAND_DMA_BUFFER_SIZE,
-+			info->msm_nand.dma_buffer,
-+			info->msm_nand.dma_addr);
-+out_free_info:
-+	return err;
-+}
-+
-+static int msm_nand_remove(struct platform_device *pdev)
-+{
-+	struct msm_nand_info *info = dev_get_drvdata(&pdev->dev);
-+
-+	dev_set_drvdata(&pdev->dev, NULL);
-+
-+	if (info) {
-+		msm_nand_release(&info->mtd);
-+		dma_free_coherent(NULL, MSM_NAND_DMA_BUFFER_SIZE,
-+				  info->msm_nand.dma_buffer,
-+				  info->msm_nand.dma_addr);
-+	}
-+
-+	sysfs_remove_file(&pdev->dev.kobj, &dev_attr_boot_layout.attr);
-+
-+	return 0;
-+}
-+
-+
-+#ifdef CONFIG_OF
-+static const struct of_device_id msm_nand_of_match[] = {
-+        { .compatible = "qcom,qcom_nand", },
-+        {},
-+};
-+MODULE_DEVICE_TABLE(of, msm_nand_of_match);
-+#endif
-+
-+
-+static struct platform_driver msm_nand_driver = {
-+	.probe		= msm_nand_probe,
-+	.remove		= msm_nand_remove,
-+	.driver = {
-+		.name		= "qcom_nand",
-+		.owner		= THIS_MODULE,
-+                .of_match_table = msm_nand_of_match,
-+	}
-+};
-+
-+
-+module_platform_driver(msm_nand_driver);
-+
-+MODULE_LICENSE("GPL");
-+MODULE_DESCRIPTION("msm_nand flash driver code");
---- /dev/null
-+++ b/drivers/mtd/nand/qcom_nand.h
-@@ -0,0 +1,196 @@
-+/* drivers/mtd/devices/msm_nand.h
-+ *
-+ * Copyright (c) 2008-2011, The Linux Foundation. All rights reserved.
-+ * Copyright (C) 2007 Google, Inc.
-+ *
-+ * This software is licensed under the terms of the GNU General Public
-+ * License version 2, as published by the Free Software Foundation, and
-+ * may be copied, distributed, and modified under those terms.
-+ *
-+ * 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 __DRIVERS_MTD_DEVICES_MSM_NAND_H
-+#define __DRIVERS_MTD_DEVICES_MSM_NAND_H
-+
-+extern unsigned long msm_nand_phys;
-+extern unsigned long msm_nandc01_phys;
-+extern unsigned long msm_nandc10_phys;
-+extern unsigned long msm_nandc11_phys;
-+extern unsigned long ebi2_register_base;
-+
-+#define NC01(X) ((X) + msm_nandc01_phys - msm_nand_phys)
-+#define NC10(X) ((X) + msm_nandc10_phys - msm_nand_phys)
-+#define NC11(X) ((X) + msm_nandc11_phys - msm_nand_phys)
-+
-+#define MSM_NAND_REG(off) (msm_nand_phys + (off))
-+
-+#define MSM_NAND_FLASH_CMD            MSM_NAND_REG(0x0000)
-+#define MSM_NAND_ADDR0                MSM_NAND_REG(0x0004)
-+#define MSM_NAND_ADDR1                MSM_NAND_REG(0x0008)
-+#define MSM_NAND_FLASH_CHIP_SELECT    MSM_NAND_REG(0x000C)
-+#define MSM_NAND_EXEC_CMD             MSM_NAND_REG(0x0010)
-+#define MSM_NAND_FLASH_STATUS         MSM_NAND_REG(0x0014)
-+#define MSM_NAND_BUFFER_STATUS        MSM_NAND_REG(0x0018)
-+#define MSM_NAND_SFLASHC_STATUS       MSM_NAND_REG(0x001C)
-+#define MSM_NAND_DEV0_CFG0            MSM_NAND_REG(0x0020)
-+#define MSM_NAND_DEV0_CFG1            MSM_NAND_REG(0x0024)
-+#define MSM_NAND_DEV0_ECC_CFG	      MSM_NAND_REG(0x0028)
-+#define MSM_NAND_DEV1_ECC_CFG	      MSM_NAND_REG(0x002C)
-+#define MSM_NAND_DEV1_CFG0            MSM_NAND_REG(0x0030)
-+#define MSM_NAND_DEV1_CFG1            MSM_NAND_REG(0x0034)
-+#define MSM_NAND_SFLASHC_CMD          MSM_NAND_REG(0x0038)
-+#define MSM_NAND_SFLASHC_EXEC_CMD     MSM_NAND_REG(0x003C)
-+#define MSM_NAND_READ_ID              MSM_NAND_REG(0x0040)
-+#define MSM_NAND_READ_STATUS          MSM_NAND_REG(0x0044)
-+#define MSM_NAND_CONFIG_DATA          MSM_NAND_REG(0x0050)
-+#define MSM_NAND_CONFIG               MSM_NAND_REG(0x0054)
-+#define MSM_NAND_CONFIG_MODE          MSM_NAND_REG(0x0058)
-+#define MSM_NAND_CONFIG_STATUS        MSM_NAND_REG(0x0060)
-+#define MSM_NAND_MACRO1_REG           MSM_NAND_REG(0x0064)
-+#define MSM_NAND_XFR_STEP1            MSM_NAND_REG(0x0070)
-+#define MSM_NAND_XFR_STEP2            MSM_NAND_REG(0x0074)
-+#define MSM_NAND_XFR_STEP3            MSM_NAND_REG(0x0078)
-+#define MSM_NAND_XFR_STEP4            MSM_NAND_REG(0x007C)
-+#define MSM_NAND_XFR_STEP5            MSM_NAND_REG(0x0080)
-+#define MSM_NAND_XFR_STEP6            MSM_NAND_REG(0x0084)
-+#define MSM_NAND_XFR_STEP7            MSM_NAND_REG(0x0088)
-+#define MSM_NAND_GENP_REG0            MSM_NAND_REG(0x0090)
-+#define MSM_NAND_GENP_REG1            MSM_NAND_REG(0x0094)
-+#define MSM_NAND_GENP_REG2            MSM_NAND_REG(0x0098)
-+#define MSM_NAND_GENP_REG3            MSM_NAND_REG(0x009C)
-+#define MSM_NAND_DEV_CMD0             MSM_NAND_REG(0x00A0)
-+#define MSM_NAND_DEV_CMD1             MSM_NAND_REG(0x00A4)
-+#define MSM_NAND_DEV_CMD2             MSM_NAND_REG(0x00A8)
-+#define MSM_NAND_DEV_CMD_VLD          MSM_NAND_REG(0x00AC)
-+#define DEV_CMD_VLD_SEQ_READ_START_VLD		0x10
-+#define DEV_CMD_VLD_ERASE_START_VLD		0x8
-+#define DEV_CMD_VLD_WRITE_START_VLD		0x4
-+#define DEV_CMD_VLD_READ_STOP_VLD		0x2
-+#define DEV_CMD_VLD_READ_START_VLD		0x1
-+
-+#define MSM_NAND_EBI2_MISR_SIG_REG    MSM_NAND_REG(0x00B0)
-+#define MSM_NAND_ADDR2                MSM_NAND_REG(0x00C0)
-+#define MSM_NAND_ADDR3                MSM_NAND_REG(0x00C4)
-+#define MSM_NAND_ADDR4                MSM_NAND_REG(0x00C8)
-+#define MSM_NAND_ADDR5                MSM_NAND_REG(0x00CC)
-+#define MSM_NAND_DEV_CMD3             MSM_NAND_REG(0x00D0)
-+#define MSM_NAND_DEV_CMD4             MSM_NAND_REG(0x00D4)
-+#define MSM_NAND_DEV_CMD5             MSM_NAND_REG(0x00D8)
-+#define MSM_NAND_DEV_CMD6             MSM_NAND_REG(0x00DC)
-+#define MSM_NAND_SFLASHC_BURST_CFG    MSM_NAND_REG(0x00E0)
-+#define MSM_NAND_ADDR6                MSM_NAND_REG(0x00E4)
-+#define MSM_NAND_EBI2_ECC_BUF_CFG     MSM_NAND_REG(0x00F0)
-+#define MSM_NAND_HW_INFO	      MSM_NAND_REG(0x00FC)
-+#define MSM_NAND_FLASH_BUFFER         MSM_NAND_REG(0x0100)
-+
-+/* device commands */
-+
-+#define MSM_NAND_CMD_SOFT_RESET         0x01
-+#define MSM_NAND_CMD_PAGE_READ          0x32
-+#define MSM_NAND_CMD_PAGE_READ_ECC      0x33
-+#define MSM_NAND_CMD_PAGE_READ_ALL      0x34
-+#define MSM_NAND_CMD_SEQ_PAGE_READ      0x15
-+#define MSM_NAND_CMD_PRG_PAGE           0x36
-+#define MSM_NAND_CMD_PRG_PAGE_ECC       0x37
-+#define MSM_NAND_CMD_PRG_PAGE_ALL       0x39
-+#define MSM_NAND_CMD_BLOCK_ERASE        0x3A
-+#define MSM_NAND_CMD_FETCH_ID           0x0B
-+#define MSM_NAND_CMD_STATUS             0x0C
-+#define MSM_NAND_CMD_RESET              0x0D
-+
-+/* Sflash Commands */
-+
-+#define MSM_NAND_SFCMD_DATXS            0x0
-+#define MSM_NAND_SFCMD_CMDXS            0x1
-+#define MSM_NAND_SFCMD_BURST            0x0
-+#define MSM_NAND_SFCMD_ASYNC            0x1
-+#define MSM_NAND_SFCMD_ABORT            0x1
-+#define MSM_NAND_SFCMD_REGRD            0x2
-+#define MSM_NAND_SFCMD_REGWR            0x3
-+#define MSM_NAND_SFCMD_INTLO            0x4
-+#define MSM_NAND_SFCMD_INTHI            0x5
-+#define MSM_NAND_SFCMD_DATRD            0x6
-+#define MSM_NAND_SFCMD_DATWR            0x7
-+
-+#define SFLASH_PREPCMD(numxfr, offval, delval, trnstp, mode, opcode) \
-+	((numxfr<<20)|(offval<<12)|(delval<<6)|(trnstp<<5)|(mode<<4)|opcode)
-+
-+#define SFLASH_BCFG			0x20100327
-+
-+/* Onenand addresses */
-+
-+#define ONENAND_MANUFACTURER_ID		0xF000
-+#define ONENAND_DEVICE_ID		0xF001
-+#define ONENAND_VERSION_ID		0xF002
-+#define ONENAND_DATA_BUFFER_SIZE	0xF003
-+#define ONENAND_BOOT_BUFFER_SIZE	0xF004
-+#define ONENAND_AMOUNT_OF_BUFFERS	0xF005
-+#define ONENAND_TECHNOLOGY		0xF006
-+#define ONENAND_START_ADDRESS_1		0xF100
-+#define ONENAND_START_ADDRESS_2		0xF101
-+#define ONENAND_START_ADDRESS_3		0xF102
-+#define ONENAND_START_ADDRESS_4		0xF103
-+#define ONENAND_START_ADDRESS_5		0xF104
-+#define ONENAND_START_ADDRESS_6		0xF105
-+#define ONENAND_START_ADDRESS_7		0xF106
-+#define ONENAND_START_ADDRESS_8		0xF107
-+#define ONENAND_START_BUFFER		0xF200
-+#define ONENAND_COMMAND			0xF220
-+#define ONENAND_SYSTEM_CONFIG_1		0xF221
-+#define ONENAND_SYSTEM_CONFIG_2		0xF222
-+#define ONENAND_CONTROLLER_STATUS	0xF240
-+#define ONENAND_INTERRUPT_STATUS	0xF241
-+#define ONENAND_START_BLOCK_ADDRESS	0xF24C
-+#define ONENAND_WRITE_PROT_STATUS	0xF24E
-+#define ONENAND_ECC_STATUS		0xFF00
-+#define ONENAND_ECC_ERRPOS_MAIN0	0xFF01
-+#define ONENAND_ECC_ERRPOS_SPARE0	0xFF02
-+#define ONENAND_ECC_ERRPOS_MAIN1	0xFF03
-+#define ONENAND_ECC_ERRPOS_SPARE1	0xFF04
-+#define ONENAND_ECC_ERRPOS_MAIN2	0xFF05
-+#define ONENAND_ECC_ERRPOS_SPARE2	0xFF06
-+#define ONENAND_ECC_ERRPOS_MAIN3	0xFF07
-+#define ONENAND_ECC_ERRPOS_SPARE3	0xFF08
-+
-+/* Onenand commands */
-+#define ONENAND_WP_US                   (1 << 2)
-+#define ONENAND_WP_LS                   (1 << 1)
-+
-+#define ONENAND_CMDLOAD			0x0000
-+#define ONENAND_CMDLOADSPARE		0x0013
-+#define ONENAND_CMDPROG			0x0080
-+#define ONENAND_CMDPROGSPARE		0x001A
-+#define ONENAND_CMDERAS			0x0094
-+#define ONENAND_CMD_UNLOCK              0x0023
-+#define ONENAND_CMD_LOCK                0x002A
-+
-+#define ONENAND_SYSCFG1_ECCENA(mode)	(0x40E0 | (mode ? 0 : 0x8002))
-+#define ONENAND_SYSCFG1_ECCDIS(mode)	(0x41E0 | (mode ? 0 : 0x8002))
-+
-+#define ONENAND_CLRINTR			0x0000
-+#define ONENAND_STARTADDR1_RES		0x07FF
-+#define ONENAND_STARTADDR3_RES		0x07FF
-+
-+#define DATARAM0_0			0x8
-+#define DEVICE_FLASHCORE_0              (0 << 15)
-+#define DEVICE_FLASHCORE_1              (1 << 15)
-+#define DEVICE_BUFFERRAM_0              (0 << 15)
-+#define DEVICE_BUFFERRAM_1              (1 << 15)
-+#define ONENAND_DEVICE_IS_DDP		(1 << 3)
-+
-+#define CLEAN_DATA_16			0xFFFF
-+#define CLEAN_DATA_32			0xFFFFFFFF
-+
-+#define EBI2_REG(off)   		(ebi2_register_base + (off))
-+#define EBI2_CHIP_SELECT_CFG0           EBI2_REG(0x0000)
-+#define EBI2_CFG_REG		       	EBI2_REG(0x0004)
-+#define EBI2_NAND_ADM_MUX       	EBI2_REG(0x005C)
-+
-+extern struct flash_platform_data msm_nand_data;
-+
-+#endif
diff --git a/target/linux/ipq806x/patches/0151-ARM-ipq8064-Add-nand-device-info.patch b/target/linux/ipq806x/patches/0151-ARM-ipq8064-Add-nand-device-info.patch
deleted file mode 100644
index b460454..0000000
--- a/target/linux/ipq806x/patches/0151-ARM-ipq8064-Add-nand-device-info.patch
+++ /dev/null
@@ -1,108 +0,0 @@
-From 4490cfa66379909cdddc3518c8e75b7cd26d8f69 Mon Sep 17 00:00:00 2001
-From: Andy Gross <agross@codeaurora.org>
-Date: Mon, 16 Jun 2014 16:53:49 -0500
-Subject: [PATCH 151/182] ARM: ipq8064: Add nand device info
-
-Signed-off-by: Andy Gross <agross@codeaurora.org>
----
- arch/arm/boot/dts/qcom-ipq8064-ap148.dts |   34 ++++++++++++++++++++++++++++++
- arch/arm/boot/dts/qcom-ipq8064.dtsi      |   33 +++++++++++++++++++++++++++++
- 2 files changed, 67 insertions(+)
-
---- a/arch/arm/boot/dts/qcom-ipq8064-ap148.dts
-+++ b/arch/arm/boot/dts/qcom-ipq8064-ap148.dts
-@@ -45,6 +45,29 @@
- 					bias-none;
- 				};
- 			};
-+			nand_pins: nand_pins {
-+				mux {
-+					pins = "gpio34", "gpio35", "gpio36",
-+						"gpio37", "gpio38", "gpio39",
-+						"gpio40", "gpio41", "gpio42",
-+						"gpio43", "gpio44", "gpio45",
-+						"gpio46", "gpio47";
-+					function = "nand";
-+					drive-strength = <10>;
-+					bias-disable;
-+				};
-+				pullups {
-+					pins = "gpio39";
-+					bias-pull-up;
-+				};
-+				hold {
-+					pins = "gpio40", "gpio41", "gpio42",
-+						"gpio43", "gpio44", "gpio45",
-+						"gpio46", "gpio47";
-+					bias-bus-hold;
-+				};
-+			};
-+
- 		};
- 
- 		gsbi@16300000 {
-@@ -126,5 +149,16 @@
- 		sata@29000000 {
- 			status = "ok";
- 		};
-+
-+		dma@18300000 {
-+			status = "ok";
-+		};
-+
-+		nand@0x1ac00000 {
-+			status = "ok";
-+
-+			pinctrl-0 = <&nand_pins>;
-+			pinctrl-names = "default";
-+		};
- 	};
- };
---- a/arch/arm/boot/dts/qcom-ipq8064.dtsi
-+++ b/arch/arm/boot/dts/qcom-ipq8064.dtsi
-@@ -76,6 +76,7 @@
- 			interrupt-controller;
- 			#interrupt-cells = <2>;
- 			interrupts = <0 32 0x4>;
-+
- 		};
- 
- 		intc: interrupt-controller@2000000 {
-@@ -369,5 +370,37 @@
- 			phy-names = "sata-phy";
- 			status = "disabled";
- 		};
-+
-+		adm_dma: dma@18300000 {
-+			compatible = "qcom,adm";
-+			reg = <0x18300000 0x100000>;
-+			interrupts = <0 170 0>;
-+
-+			clocks = <&gcc ADM0_CLK>, <&gcc ADM0_PBUS_CLK>;
-+			clock-names = "core_clk", "iface_clk";
-+
-+			resets = <&gcc ADM0_RESET>,
-+				<&gcc ADM0_PBUS_RESET>,
-+				<&gcc ADM0_C0_RESET>,
-+				<&gcc ADM0_C1_RESET>,
-+				<&gcc ADM0_C2_RESET>;
-+
-+			reset-names = "adm", "pbus", "c0", "c1", "c2";
-+
-+			status = "disabled";
-+		};
-+
-+		nand@0x1ac00000 {
-+			compatible = "qcom,qcom_nand";
-+			reg = <0x1ac00000 0x800>;
-+			#address-cells = <1>;
-+			#size-cells = <1>;
-+
-+			clocks = <&gcc EBI2_CLK>;
-+			clock-names = "core_clk";
-+
-+
-+			status = "disabled";
-+		};
- 	};
- };
diff --git a/target/linux/ipq806x/patches/0152-ARM-qcom-config-Add-NAND-config-options.patch b/target/linux/ipq806x/patches/0152-ARM-qcom-config-Add-NAND-config-options.patch
deleted file mode 100644
index a2489e4..0000000
--- a/target/linux/ipq806x/patches/0152-ARM-qcom-config-Add-NAND-config-options.patch
+++ /dev/null
@@ -1,22 +0,0 @@
-From d04f697bf7cfe756de6187be1d0e5669d4d5bca0 Mon Sep 17 00:00:00 2001
-From: Andy Gross <agross@codeaurora.org>
-Date: Mon, 16 Jun 2014 17:30:04 -0500
-Subject: [PATCH 152/182] ARM: qcom: config: Add NAND config options
-
-Add NAND config options to enable QCOM NAND controller
-
-Signed-off-by: Andy Gross <agross@codeaurora.org>
----
- arch/arm/configs/qcom_defconfig |    1 +
- 1 file changed, 1 insertion(+)
-
---- a/arch/arm/configs/qcom_defconfig
-+++ b/arch/arm/configs/qcom_defconfig
-@@ -56,6 +56,7 @@ CONFIG_DEVTMPFS_MOUNT=y
- CONFIG_MTD=y
- CONFIG_MTD_BLOCK=y
- CONFIG_MTD_M25P80=y
-+CONFIG_MTD_NAND=y
- CONFIG_BLK_DEV_LOOP=y
- CONFIG_BLK_DEV_RAM=y
- CONFIG_SCSI_TGT=y
diff --git a/target/linux/ipq806x/patches/0153-soc-qcom-tcsr-Add-TCSR-driver.patch b/target/linux/ipq806x/patches/0153-soc-qcom-tcsr-Add-TCSR-driver.patch
deleted file mode 100644
index 65e4c2f..0000000
--- a/target/linux/ipq806x/patches/0153-soc-qcom-tcsr-Add-TCSR-driver.patch
+++ /dev/null
@@ -1,153 +0,0 @@
-From 0b469f3f4c0e6a0e0b1b60a059600e325a03b6f5 Mon Sep 17 00:00:00 2001
-From: Andy Gross <agross@codeaurora.org>
-Date: Thu, 12 Jun 2014 00:52:06 -0500
-Subject: [PATCH 153/182] soc: qcom: tcsr: Add TCSR driver
-
-This patch adds support for the TCSR IP block present in Qualcomm processors.
-
-Signed-off-by: Andy Gross <agross@codeaurora.org>
----
- .../devicetree/bindings/soc/qcom/qcom,tcsr.txt     |   25 ++++++++
- drivers/soc/qcom/Kconfig                           |    6 ++
- drivers/soc/qcom/Makefile                          |    1 +
- drivers/soc/qcom/qcom_tcsr.c                       |   64 ++++++++++++++++++++
- include/dt-bindings/soc/qcom,tcsr.h                |   19 ++++++
- 5 files changed, 115 insertions(+)
- create mode 100644 Documentation/devicetree/bindings/soc/qcom/qcom,tcsr.txt
- create mode 100644 drivers/soc/qcom/qcom_tcsr.c
- create mode 100644 include/dt-bindings/soc/qcom,tcsr.h
-
---- /dev/null
-+++ b/Documentation/devicetree/bindings/soc/qcom/qcom,tcsr.txt
-@@ -0,0 +1,25 @@
-+QCOM TCSR (Top Control and Status Register) Driver
-+
-+The TCSR provides miscellaneous control functions and status registers for
-+Qualcomm processors.
-+
-+Required properties:
-+- compatible: must contain "qcom,tcsr" for IPQ806x
-+- reg: Address range for TCSR registers
-+
-+Optional properties:
-+- qcom,usb-ctrl-select : indicates USB port type selection.  Please reference
-+  dt-bindings/soc/qcom,tcsr.h for valid USB port selection values.
-+
-+Example for IPQ8064:
-+
-+#include <dt-bindings/soc/qcom,tcsr.h>
-+
-+		tcsr: tcsr@1a400000 {
-+			compatible = "qcom,tcsr";
-+			reg = <0x1a400000 0x100>;
-+
-+			qcom,usb-ctrl-select = <TCSR_USB_SELECT_USB3_DUAL>;
-+		};
-+
-+
---- a/drivers/soc/qcom/Kconfig
-+++ b/drivers/soc/qcom/Kconfig
-@@ -9,3 +9,9 @@ config QCOM_GSBI
-           functions for connecting the underlying serial UART, SPI, and I2C
-           devices to the output pins.
- 
-+config QCOM_TCSR
-+        tristate "QCOM Top Control and Status Registers"
-+        depends on ARCH_QCOM
-+        help
-+          Say y here to enable TCSR support.  The TCSR provides control
-+          functions for various peripherals.
---- a/drivers/soc/qcom/Makefile
-+++ b/drivers/soc/qcom/Makefile
-@@ -1 +1,2 @@
- obj-$(CONFIG_QCOM_GSBI)	+=	qcom_gsbi.o
-+obj-$(CONFIG_QCOM_TCSR)	+=	qcom_tcsr.o
---- /dev/null
-+++ b/drivers/soc/qcom/qcom_tcsr.c
-@@ -0,0 +1,64 @@
-+/*
-+ * Copyright (c) 2014, The Linux foundation. All rights reserved.
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License rev 2 and
-+ * only rev 2 as published by the free Software foundation.
-+ *
-+ * 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/err.h>
-+#include <linux/io.h>
-+#include <linux/module.h>
-+#include <linux/of.h>
-+#include <linux/of_platform.h>
-+#include <linux/platform_device.h>
-+
-+#define TCSR_USB_PORT_SEL	0xb0
-+
-+static int tcsr_probe(struct platform_device *pdev)
-+{
-+	struct resource *res;
-+	const struct device_node *node = pdev->dev.of_node;
-+	void __iomem *base;
-+	u32 val;
-+
-+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-+	base = devm_ioremap_resource(&pdev->dev, res);
-+	if (IS_ERR(base))
-+		return PTR_ERR(base);
-+
-+	if (!of_property_read_u32(node, "qcom,usb-ctrl-select", &val)) {
-+		dev_err(&pdev->dev, "setting usb port select = %d\n", val);
-+		writel(val, base + TCSR_USB_PORT_SEL);
-+	}
-+
-+	return 0;
-+}
-+
-+static const struct of_device_id tcsr_dt_match[] = {
-+	{ .compatible = "qcom,tcsr", },
-+	{ },
-+};
-+
-+MODULE_DEVICE_TABLE(of, tcsr_dt_match);
-+
-+static struct platform_driver tcsr_driver = {
-+	.driver = {
-+		.name		= "tcsr",
-+		.owner		= THIS_MODULE,
-+		.of_match_table	= tcsr_dt_match,
-+	},
-+	.probe = tcsr_probe,
-+};
-+
-+module_platform_driver(tcsr_driver);
-+
-+MODULE_AUTHOR("Andy Gross <agross@codeaurora.org>");
-+MODULE_DESCRIPTION("QCOM TCSR driver");
-+MODULE_LICENSE("GPL v2");
---- /dev/null
-+++ b/include/dt-bindings/soc/qcom,tcsr.h
-@@ -0,0 +1,19 @@
-+/* Copyright (c) 2014, The Linux Foundation. All rights reserved.
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 and
-+ * only version 2 as published by the Free Software Foundation.
-+ *
-+ * 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 __DT_BINDINGS_QCOM_TCSR_H
-+#define __DT_BINDINGS_QCOM_TCSR_H
-+
-+#define TCSR_USB_SELECT_USB3_P0		0x1
-+#define TCSR_USB_SELECT_USB3_P1		0x2
-+#define TCSR_USB_SELECT_USB3_DUAL	0x3
-+
-+#endif
diff --git a/target/linux/ipq806x/patches/0154-clk-qcom-Correct-UTMI-clock-frequency-table.patch b/target/linux/ipq806x/patches/0154-clk-qcom-Correct-UTMI-clock-frequency-table.patch
deleted file mode 100644
index 1d81970..0000000
--- a/target/linux/ipq806x/patches/0154-clk-qcom-Correct-UTMI-clock-frequency-table.patch
+++ /dev/null
@@ -1,24 +0,0 @@
-From 2561c49dcf5cb35ad72df34bf225a51fe2fa87e5 Mon Sep 17 00:00:00 2001
-From: Andy Gross <agross@codeaurora.org>
-Date: Thu, 12 Jun 2014 00:53:19 -0500
-Subject: [PATCH 154/182] clk: qcom: Correct UTMI clock frequency table
-
-This patch changes the UTMI clock frequency from 20MHz to the correct value of
-60MHz.
-
-Signed-off-by: Andy Gross <agross@codeaurora.org>
----
- drivers/clk/qcom/gcc-ipq806x.c |    2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/drivers/clk/qcom/gcc-ipq806x.c
-+++ b/drivers/clk/qcom/gcc-ipq806x.c
-@@ -1992,7 +1992,7 @@ static struct clk_branch usb30_1_branch_
- };
- 
- static const struct freq_tbl clk_tbl_usb30_utmi[] = {
--	{ 60000000, P_PLL0,  1, 1, 40 },
-+	{ 60000000, P_PLL8,  1, 5, 32 },
- 	{ }
- };
- 
diff --git a/target/linux/ipq806x/patches/0155-clk-qcom-Fix-incorrect-UTMI-DT-include-values.patch b/target/linux/ipq806x/patches/0155-clk-qcom-Fix-incorrect-UTMI-DT-include-values.patch
deleted file mode 100644
index a05fc2c..0000000
--- a/target/linux/ipq806x/patches/0155-clk-qcom-Fix-incorrect-UTMI-DT-include-values.patch
+++ /dev/null
@@ -1,58 +0,0 @@
-From 9ab5cb48696dca02bf43170b50d1034a96fb9e85 Mon Sep 17 00:00:00 2001
-From: Andy Gross <agross@codeaurora.org>
-Date: Sun, 15 Jun 2014 00:39:57 -0500
-Subject: [PATCH 155/182] clk: qcom: Fix incorrect UTMI DT include values
-
-Corrected values for UTMI clock definitions.
-
-Signed-off-by: Andy Gross <agross@codeaurora.org>
----
- include/dt-bindings/clock/qcom,gcc-ipq806x.h |   38 +++++++++++++-------------
- 1 file changed, 19 insertions(+), 19 deletions(-)
-
---- a/include/dt-bindings/clock/qcom,gcc-ipq806x.h
-+++ b/include/dt-bindings/clock/qcom,gcc-ipq806x.h
-@@ -273,24 +273,24 @@
- #define USB30_SLEEP_CLK				262
- #define USB30_UTMI_SRC				263
- #define USB30_0_UTMI_CLK			264
--#define USB30_1_UTMI_CLK			264
--#define USB30_MASTER_SRC			265
--#define USB30_0_MASTER_CLK			266
--#define USB30_1_MASTER_CLK			267
--#define GMAC_CORE1_CLK_SRC			268
--#define GMAC_CORE2_CLK_SRC			269
--#define GMAC_CORE3_CLK_SRC			270
--#define GMAC_CORE4_CLK_SRC			271
--#define GMAC_CORE1_CLK				272
--#define GMAC_CORE2_CLK				273
--#define GMAC_CORE3_CLK				274
--#define GMAC_CORE4_CLK				275
--#define UBI32_CORE1_CLK_SRC			276
--#define UBI32_CORE2_CLK_SRC			277
--#define UBI32_CORE1_CLK				278
--#define UBI32_CORE2_CLK				279
--#define NSSTCM_CLK_SRC				280
--#define NSSTCM_CLK				281
--#define NSS_CORE_CLK				282 /* Virtual */
-+#define USB30_1_UTMI_CLK			265
-+#define USB30_MASTER_SRC			266
-+#define USB30_0_MASTER_CLK			267
-+#define USB30_1_MASTER_CLK			268
-+#define GMAC_CORE1_CLK_SRC			269
-+#define GMAC_CORE2_CLK_SRC			270
-+#define GMAC_CORE3_CLK_SRC			271
-+#define GMAC_CORE4_CLK_SRC			272
-+#define GMAC_CORE1_CLK				273
-+#define GMAC_CORE2_CLK				274
-+#define GMAC_CORE3_CLK				275
-+#define GMAC_CORE4_CLK				276
-+#define UBI32_CORE1_CLK_SRC			277
-+#define UBI32_CORE2_CLK_SRC			278
-+#define UBI32_CORE1_CLK				279
-+#define UBI32_CORE2_CLK				280
-+#define NSSTCM_CLK_SRC				281
-+#define NSSTCM_CLK				282
-+#define NSS_CORE_CLK				283 /* Virtual */
- 
- #endif
diff --git a/target/linux/ipq806x/patches/0156-usb-dwc3-Add-Qualcomm-DWC3-glue-layer-driver.patch b/target/linux/ipq806x/patches/0156-usb-dwc3-Add-Qualcomm-DWC3-glue-layer-driver.patch
deleted file mode 100644
index a69a5bd..0000000
--- a/target/linux/ipq806x/patches/0156-usb-dwc3-Add-Qualcomm-DWC3-glue-layer-driver.patch
+++ /dev/null
@@ -1,202 +0,0 @@
-From 364532aeb9024d0ff7b88121f9a953f559b1c136 Mon Sep 17 00:00:00 2001
-From: "Ivan T. Ivanov" <iivanov@mm-sol.com>
-Date: Mon, 7 Oct 2013 10:44:57 +0300
-Subject: [PATCH 156/182] usb: dwc3: Add Qualcomm DWC3 glue layer driver
-
-DWC3 glue layer is hardware layer around Synopsys DesignWare
-USB3 core. Its purpose is to supply Synopsys IP with required
-clocks, voltages and interface it with the rest of the SoC.
-
-Signed-off-by: Ivan T. Ivanov <iivanov@mm-sol.com>
----
- drivers/usb/dwc3/Kconfig     |    8 +++
- drivers/usb/dwc3/Makefile    |    1 +
- drivers/usb/dwc3/dwc3-qcom.c |  156 ++++++++++++++++++++++++++++++++++++++++++
- 3 files changed, 165 insertions(+)
- create mode 100644 drivers/usb/dwc3/dwc3-qcom.c
-
---- a/drivers/usb/dwc3/Kconfig
-+++ b/drivers/usb/dwc3/Kconfig
-@@ -59,6 +59,14 @@ config USB_DWC3_EXYNOS
- 	  Recent Exynos5 SoCs ship with one DesignWare Core USB3 IP inside,
- 	  say 'Y' or 'M' if you have one such device.
- 
-+config USB_DWC3_QCOM
-+       tristate "Qualcomm Platforms"
-+       default USB_DWC3
-+       select USB_QCOM_DWC3_PHYS
-+       help
-+         Recent Qualcomm SoCs ship with one DesignWare Core USB3 IP inside,
-+         say 'Y' or 'M' if you have one such device.
-+
- config USB_DWC3_PCI
- 	tristate "PCIe-based Platforms"
- 	depends on PCI
---- a/drivers/usb/dwc3/Makefile
-+++ b/drivers/usb/dwc3/Makefile
-@@ -31,5 +31,6 @@ endif
- 
- obj-$(CONFIG_USB_DWC3_OMAP)		+= dwc3-omap.o
- obj-$(CONFIG_USB_DWC3_EXYNOS)		+= dwc3-exynos.o
-+obj-$(CONFIG_USB_DWC3_QCOM)		+= dwc3-qcom.o
- obj-$(CONFIG_USB_DWC3_PCI)		+= dwc3-pci.o
- obj-$(CONFIG_USB_DWC3_KEYSTONE)		+= dwc3-keystone.o
---- /dev/null
-+++ b/drivers/usb/dwc3/dwc3-qcom.c
-@@ -0,0 +1,156 @@
-+/* Copyright (c) 2013-2014, The Linux Foundation. All rights reserved.
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 and
-+ * only version 2 as published by the Free Software Foundation.
-+ *
-+ * 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/err.h>
-+#include <linux/io.h>
-+#include <linux/module.h>
-+#include <linux/of.h>
-+#include <linux/of_platform.h>
-+#include <linux/platform_device.h>
-+#include <linux/regulator/consumer.h>
-+#include <linux/usb/phy.h>
-+
-+#include "core.h"
-+
-+
-+struct dwc3_qcom {
-+	struct device		*dev;
-+
-+	struct clk		*core_clk;
-+	struct clk		*iface_clk;
-+	struct clk		*sleep_clk;
-+
-+	struct regulator	*gdsc;
-+};
-+
-+static int dwc3_qcom_probe(struct platform_device *pdev)
-+{
-+	struct device_node *node = pdev->dev.of_node;
-+	struct dwc3_qcom *mdwc;
-+	int ret = 0;
-+
-+	mdwc = devm_kzalloc(&pdev->dev, sizeof(*mdwc), GFP_KERNEL);
-+	if (!mdwc)
-+		return -ENOMEM;
-+
-+	platform_set_drvdata(pdev, mdwc);
-+
-+	mdwc->dev = &pdev->dev;
-+
-+	mdwc->gdsc = devm_regulator_get(mdwc->dev, "gdsc");
-+
-+	mdwc->core_clk = devm_clk_get(mdwc->dev, "core");
-+	if (IS_ERR(mdwc->core_clk)) {
-+		dev_dbg(mdwc->dev, "failed to get core clock\n");
-+		return PTR_ERR(mdwc->core_clk);
-+	}
-+
-+	mdwc->iface_clk = devm_clk_get(mdwc->dev, "iface");
-+	if (IS_ERR(mdwc->iface_clk)) {
-+		dev_dbg(mdwc->dev, "failed to get iface clock, skipping\n");
-+		mdwc->iface_clk = NULL;
-+	}
-+
-+	mdwc->sleep_clk = devm_clk_get(mdwc->dev, "sleep");
-+	if (IS_ERR(mdwc->sleep_clk)) {
-+		dev_dbg(mdwc->dev, "failed to get sleep clock, skipping\n");
-+		mdwc->sleep_clk = NULL;
-+	}
-+
-+	if (!IS_ERR(mdwc->gdsc)) {
-+		ret = regulator_enable(mdwc->gdsc);
-+		if (ret)
-+			dev_err(mdwc->dev, "cannot enable gdsc\n");
-+	}
-+
-+	clk_prepare_enable(mdwc->core_clk);
-+
-+	if (mdwc->iface_clk)
-+		clk_prepare_enable(mdwc->iface_clk);
-+
-+	if (mdwc->sleep_clk)
-+		clk_prepare_enable(mdwc->sleep_clk);
-+
-+	ret = of_platform_populate(node, NULL, NULL, mdwc->dev);
-+	if (ret) {
-+		dev_err(mdwc->dev, "failed to register core - %d\n", ret);
-+		dev_dbg(mdwc->dev, "failed to add create dwc3 core\n");
-+		goto dis_clks;
-+	}
-+
-+	return 0;
-+
-+dis_clks:
-+
-+	dev_err(mdwc->dev, "disabling clocks\n");
-+
-+	if (mdwc->sleep_clk)
-+		clk_disable_unprepare(mdwc->sleep_clk);
-+
-+	if (mdwc->iface_clk)
-+		clk_disable_unprepare(mdwc->iface_clk);
-+
-+	clk_disable_unprepare(mdwc->core_clk);
-+
-+	if (!IS_ERR(mdwc->gdsc)) {
-+		ret = regulator_disable(mdwc->gdsc);
-+		if (ret)
-+			dev_dbg(mdwc->dev, "cannot disable gdsc\n");
-+	}
-+
-+	return ret;
-+}
-+
-+static int dwc3_qcom_remove(struct platform_device *pdev)
-+{
-+	int ret = 0;
-+
-+	struct dwc3_qcom *mdwc = platform_get_drvdata(pdev);
-+
-+	if (mdwc->sleep_clk)
-+		clk_disable_unprepare(mdwc->sleep_clk);
-+
-+	if (mdwc->iface_clk)
-+		clk_disable_unprepare(mdwc->iface_clk);
-+
-+	clk_disable_unprepare(mdwc->core_clk);
-+
-+	if (!IS_ERR(mdwc->gdsc)) {
-+		ret = regulator_disable(mdwc->gdsc);
-+		if (ret)
-+			dev_dbg(mdwc->dev, "cannot disable gdsc\n");
-+	}
-+	return ret;
-+}
-+
-+static const struct of_device_id of_dwc3_match[] = {
-+	{ .compatible = "qcom,dwc3" },
-+	{ /* Sentinel */ }
-+};
-+MODULE_DEVICE_TABLE(of, of_dwc3_match);
-+
-+static struct platform_driver dwc3_qcom_driver = {
-+	.probe		= dwc3_qcom_probe,
-+	.remove		= dwc3_qcom_remove,
-+	.driver		= {
-+		.name	= "qcom-dwc3",
-+		.owner	= THIS_MODULE,
-+		.of_match_table	= of_dwc3_match,
-+	},
-+};
-+
-+module_platform_driver(dwc3_qcom_driver);
-+
-+MODULE_ALIAS("platform:qcom-dwc3");
-+MODULE_LICENSE("GPL v2");
-+MODULE_DESCRIPTION("DesignWare USB3 QCOM Glue Layer");
diff --git a/target/linux/ipq806x/patches/0157-usb-phy-Add-Qualcomm-DWC3-HS-SS-PHY-drivers.patch b/target/linux/ipq806x/patches/0157-usb-phy-Add-Qualcomm-DWC3-HS-SS-PHY-drivers.patch
deleted file mode 100644
index d7fafed..0000000
--- a/target/linux/ipq806x/patches/0157-usb-phy-Add-Qualcomm-DWC3-HS-SS-PHY-drivers.patch
+++ /dev/null
@@ -1,861 +0,0 @@
-From d968f8c82db73141c6bc145148642391cb698442 Mon Sep 17 00:00:00 2001
-From: "Ivan T. Ivanov" <iivanov@mm-sol.com>
-Date: Mon, 7 Oct 2013 10:44:56 +0300
-Subject: [PATCH 157/182] usb: phy: Add Qualcomm DWC3 HS/SS PHY drivers
-
-These drivers handles control and configuration of the HS
-and SS USB PHY transceivers. They are part of the driver
-which manage Synopsys DesignWare USB3 controller stack
-inside Qualcomm SoC's.
-
-Signed-off-by: Ivan T. Ivanov <iivanov@mm-sol.com>
----
- drivers/usb/phy/Kconfig          |   13 +-
- drivers/usb/phy/Makefile         |    2 +
- drivers/usb/phy/phy-qcom-hsusb.c |  340 ++++++++++++++++++++++++++++
- drivers/usb/phy/phy-qcom-ssusb.c |  455 ++++++++++++++++++++++++++++++++++++++
- 4 files changed, 809 insertions(+), 1 deletion(-)
- create mode 100644 drivers/usb/phy/phy-qcom-hsusb.c
- create mode 100644 drivers/usb/phy/phy-qcom-ssusb.c
-
---- a/drivers/usb/phy/Kconfig
-+++ b/drivers/usb/phy/Kconfig
-@@ -193,7 +193,7 @@ config USB_ISP1301
- 
- config USB_MSM_OTG
- 	tristate "OTG support for Qualcomm on-chip USB controller"
--	depends on (USB || USB_GADGET) && ARCH_MSM
-+	depends on (USB || USB_GADGET) && ARCH_QCOM
- 	select USB_PHY
- 	help
- 	  Enable this to support the USB OTG transceiver on MSM chips. It
-@@ -251,6 +251,17 @@ config USB_RCAR_GEN2_PHY
- 	  To compile this driver as a module, choose M here: the
- 	  module will be called phy-rcar-gen2-usb.
- 
-+config USB_QCOM_DWC3_PHY
-+	tristate "Qualcomm USB controller DWC3 PHY wrappers support"
-+	depends on (USB || USB_GADGET) && ARCH_QCOM
-+	select USB_PHY
-+	help
-+	  Enable this to support the DWC3 USB PHY transceivers on QCOM chips
-+	  with DWC3 USB core. It handles PHY initialization, clock
-+	  management required after resetting the hardware and power
-+	  management. This driver is required even for peripheral only or
-+	  host only mode configurations.
-+
- config USB_ULPI
- 	bool "Generic ULPI Transceiver Driver"
- 	depends on ARM
---- a/drivers/usb/phy/Makefile
-+++ b/drivers/usb/phy/Makefile
-@@ -26,6 +26,8 @@ obj-$(CONFIG_USB_EHCI_TEGRA)		+= phy-teg
- obj-$(CONFIG_USB_GPIO_VBUS)		+= phy-gpio-vbus-usb.o
- obj-$(CONFIG_USB_ISP1301)		+= phy-isp1301.o
- obj-$(CONFIG_USB_MSM_OTG)		+= phy-msm-usb.o
-+obj-$(CONFIG_USB_QCOM_DWC3_PHY)		+= phy-qcom-hsusb.o
-+obj-$(CONFIG_USB_QCOM_DWC3_PHY)		+= phy-qcom-ssusb.o
- obj-$(CONFIG_USB_MV_OTG)		+= phy-mv-usb.o
- obj-$(CONFIG_USB_MXS_PHY)		+= phy-mxs-usb.o
- obj-$(CONFIG_USB_RCAR_PHY)		+= phy-rcar-usb.o
---- /dev/null
-+++ b/drivers/usb/phy/phy-qcom-hsusb.c
-@@ -0,0 +1,340 @@
-+/* Copyright (c) 2013-2014, Code Aurora Forum. All rights reserved.
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 and
-+ * only version 2 as published by the Free Software Foundation.
-+ *
-+ * 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/err.h>
-+#include <linux/io.h>
-+#include <linux/module.h>
-+#include <linux/of.h>
-+#include <linux/platform_device.h>
-+#include <linux/regulator/consumer.h>
-+#include <linux/usb/phy.h>
-+
-+/**
-+ *  USB QSCRATCH Hardware registers
-+ */
-+#define QSCRATCH_CTRL_REG		(0x04)
-+#define QSCRATCH_GENERAL_CFG		(0x08)
-+#define PHY_CTRL_REG			(0x10)
-+#define PARAMETER_OVERRIDE_X_REG	(0x14)
-+#define CHARGING_DET_CTRL_REG		(0x18)
-+#define CHARGING_DET_OUTPUT_REG		(0x1c)
-+#define ALT_INTERRUPT_EN_REG		(0x20)
-+#define PHY_IRQ_STAT_REG		(0x24)
-+#define CGCTL_REG			(0x28)
-+
-+#define PHY_3P3_VOL_MIN			3050000 /* uV */
-+#define PHY_3P3_VOL_MAX			3300000 /* uV */
-+#define PHY_3P3_HPM_LOAD		16000	/* uA */
-+
-+#define PHY_1P8_VOL_MIN			1800000 /* uV */
-+#define PHY_1P8_VOL_MAX			1800000 /* uV */
-+#define PHY_1P8_HPM_LOAD		19000	/* uA */
-+
-+/* TODO: these are suspicious */
-+#define USB_VDDCX_NO			1	/* index */
-+#define USB_VDDCX_MIN			5	/* index */
-+#define USB_VDDCX_MAX			7	/* index */
-+
-+struct qcom_dwc3_hs_phy {
-+	struct usb_phy		phy;
-+	void __iomem		*base;
-+	struct device		*dev;
-+
-+	struct clk		*xo_clk;
-+	struct clk		*utmi_clk;
-+
-+	struct regulator	*v3p3;
-+	struct regulator	*v1p8;
-+	struct regulator	*vddcx;
-+	struct regulator	*vbus;
-+};
-+
-+#define	phy_to_dw_phy(x)	container_of((x), struct qcom_dwc3_hs_phy, phy)
-+
-+
-+/**
-+ * Write register.
-+ *
-+ * @base - QCOM DWC3 PHY base virtual address.
-+ * @offset - register offset.
-+ * @val - value to write.
-+ */
-+static inline void qcom_dwc3_hs_write(void __iomem *base, u32 offset, u32 val)
-+{
-+	writel(val, base + offset);
-+}
-+
-+/**
-+ * Write register and read back masked value to confirm it is written
-+ *
-+ * @base - QCOM DWC3 PHY base virtual address.
-+ * @offset - register offset.
-+ * @mask - register bitmask specifying what should be updated
-+ * @val - value to write.
-+ */
-+static inline void qcom_dwc3_hs_write_readback(void __iomem *base, u32 offset,
-+					    const u32 mask, u32 val)
-+{
-+	u32 write_val, tmp = readl(base + offset);
-+
-+	tmp &= ~mask;		/* retain other bits */
-+	write_val = tmp | val;
-+
-+	writel(write_val, base + offset);
-+
-+	/* Read back to see if val was written */
-+	tmp = readl(base + offset);
-+	tmp &= mask;		/* clear other bits */
-+
-+	if (tmp != val)
-+		pr_err("write: %x to QSCRATCH: %x FAILED\n", val, offset);
-+}
-+
-+static int qcom_dwc3_hs_notify_connect(struct usb_phy *x,
-+	enum usb_device_speed speed)
-+{
-+	struct qcom_dwc3_hs_phy *phy = phy_to_dw_phy(x);
-+
-+	dev_err(phy->dev, "notify connect\n");
-+	return 0;
-+}
-+
-+static int qcom_dwc3_hs_notify_disconnect(struct usb_phy *x,
-+	enum usb_device_speed speed)
-+{
-+	struct qcom_dwc3_hs_phy *phy = phy_to_dw_phy(x);
-+
-+	dev_err(phy->dev, "notify disconnect\n");
-+	return 0;
-+}
-+
-+
-+static void qcom_dwc3_hs_phy_shutdown(struct usb_phy *x)
-+{
-+	struct qcom_dwc3_hs_phy *phy = phy_to_dw_phy(x);
-+	int ret;
-+
-+	ret = regulator_set_voltage(phy->v3p3, 0, PHY_3P3_VOL_MAX);
-+	if (ret)
-+		dev_err(phy->dev, "cannot set voltage for v3p3\n");
-+
-+	ret = regulator_set_voltage(phy->v1p8, 0, PHY_1P8_VOL_MAX);
-+	if (ret)
-+		dev_err(phy->dev, "cannot set voltage for v1p8\n");
-+
-+	ret = regulator_disable(phy->v1p8);
-+	if (ret)
-+		dev_err(phy->dev, "cannot disable v1p8\n");
-+
-+	ret = regulator_disable(phy->v3p3);
-+	if (ret)
-+		dev_err(phy->dev, "cannot disable v3p3\n");
-+
-+	ret = regulator_set_voltage(phy->vddcx, USB_VDDCX_NO, USB_VDDCX_MAX);
-+	if (ret)
-+		dev_err(phy->dev, "cannot set voltage for vddcx\n");
-+
-+	ret = regulator_disable(phy->vddcx);
-+	if (ret)
-+		dev_err(phy->dev, "cannot enable vddcx\n");
-+
-+	clk_disable_unprepare(phy->utmi_clk);
-+}
-+
-+static int qcom_dwc3_hs_phy_init(struct usb_phy *x)
-+{
-+	struct qcom_dwc3_hs_phy	*phy = phy_to_dw_phy(x);
-+	int ret;
-+	u32 val;
-+
-+	clk_prepare_enable(phy->utmi_clk);
-+
-+	ret = regulator_set_voltage(phy->vddcx, USB_VDDCX_MIN, USB_VDDCX_MAX);
-+	if (ret)
-+		dev_err(phy->dev, "cannot set voltage for vddcx\n");
-+
-+	ret = regulator_enable(phy->vddcx);
-+	if (ret)
-+		dev_err(phy->dev, "cannot enable vddcx\n");
-+
-+	ret = regulator_set_voltage(phy->v3p3, PHY_3P3_VOL_MIN,
-+				    PHY_3P3_VOL_MAX);
-+	if (ret)
-+		dev_err(phy->dev, "cannot set voltage for v3p3\n");
-+
-+	ret = regulator_set_voltage(phy->v1p8, PHY_1P8_VOL_MIN,
-+				    PHY_1P8_VOL_MAX);
-+	if (ret)
-+		dev_err(phy->dev, "cannot set voltage for v1p8\n");
-+
-+	ret = regulator_set_optimum_mode(phy->v1p8, PHY_1P8_HPM_LOAD);
-+	if (ret < 0)
-+		dev_err(phy->dev, "cannot set HPM of regulator v1p8\n");
-+
-+	ret = regulator_enable(phy->v1p8);
-+	if (ret)
-+		dev_err(phy->dev, "cannot enable v1p8\n");
-+
-+	ret = regulator_set_optimum_mode(phy->v3p3, PHY_3P3_HPM_LOAD);
-+	if (ret < 0)
-+		dev_err(phy->dev, "cannot set HPM of regulator v3p3\n");
-+
-+	ret = regulator_enable(phy->v3p3);
-+	if (ret)
-+		dev_err(phy->dev, "cannot enable v3p3\n");
-+
-+	/*
-+	 * HSPHY Initialization: Enable UTMI clock and clamp enable HVINTs,
-+	 * and disable RETENTION (power-on default is ENABLED)
-+	 */
-+	val = readl(phy->base + PHY_CTRL_REG);
-+	val |= BIT(18) | BIT(20) | BIT(11) | 0x70;
-+	qcom_dwc3_hs_write(phy->base, PHY_CTRL_REG, val);
-+	usleep_range(2000, 2200);
-+
-+	/*
-+	 * write HSPHY init value to QSCRATCH reg to set HSPHY parameters like
-+	 * VBUS valid threshold, disconnect valid threshold, DC voltage level,
-+	 * preempasis and rise/fall time.
-+	 */
-+	qcom_dwc3_hs_write_readback(phy->base, PARAMETER_OVERRIDE_X_REG,
-+				0x03ffffff, 0x00d191a4);
-+
-+	/* Disable (bypass) VBUS and ID filters */
-+	qcom_dwc3_hs_write(phy->base, QSCRATCH_GENERAL_CFG, BIT(2));
-+
-+	return 0;
-+}
-+
-+static int qcom_dwc3_hs_phy_set_vbus(struct usb_phy *x, int on)
-+{
-+	struct qcom_dwc3_hs_phy	*phy = phy_to_dw_phy(x);
-+	int ret = 0;
-+
-+	if (IS_ERR(phy->vbus))
-+		return on ? PTR_ERR(phy->vbus) : 0;
-+
-+	if (on)
-+		ret = regulator_enable(phy->vbus);
-+	else
-+		ret = regulator_disable(phy->vbus);
-+
-+	if (ret)
-+		dev_err(x->dev, "Cannot %s Vbus\n", on ? "set" : "off");
-+	return ret;
-+}
-+
-+static int qcom_dwc3_hs_probe(struct platform_device *pdev)
-+{
-+	struct qcom_dwc3_hs_phy	*phy;
-+	struct resource		*res;
-+	void __iomem		*base;
-+
-+	phy = devm_kzalloc(&pdev->dev, sizeof(*phy), GFP_KERNEL);
-+	if (!phy)
-+		return -ENOMEM;
-+
-+	platform_set_drvdata(pdev, phy);
-+
-+	phy->dev = &pdev->dev;
-+
-+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-+	base = devm_ioremap_resource(phy->dev, res);
-+	if (IS_ERR(base))
-+		return PTR_ERR(base);
-+
-+	phy->vddcx = devm_regulator_get(phy->dev, "vddcx");
-+	if (IS_ERR(phy->vddcx)) {
-+		dev_dbg(phy->dev, "cannot get vddcx\n");
-+		return  PTR_ERR(phy->vddcx);
-+	}
-+
-+	phy->v3p3 = devm_regulator_get(phy->dev, "v3p3");
-+	if (IS_ERR(phy->v3p3)) {
-+		dev_dbg(phy->dev, "cannot get v3p3\n");
-+		return PTR_ERR(phy->v3p3);
-+	}
-+
-+	phy->v1p8 = devm_regulator_get(phy->dev, "v1p8");
-+	if (IS_ERR(phy->v1p8)) {
-+		dev_dbg(phy->dev, "cannot get v1p8\n");
-+		return PTR_ERR(phy->v1p8);
-+	}
-+
-+	phy->vbus = devm_regulator_get(phy->dev, "vbus");
-+	if (IS_ERR(phy->vbus))
-+		dev_dbg(phy->dev, "Failed to get vbus\n");
-+
-+	phy->utmi_clk = devm_clk_get(phy->dev, "utmi");
-+	if (IS_ERR(phy->utmi_clk)) {
-+		dev_dbg(phy->dev, "cannot get UTMI handle\n");
-+		return PTR_ERR(phy->utmi_clk);
-+	}
-+
-+	phy->xo_clk = devm_clk_get(phy->dev, "xo");
-+	if (IS_ERR(phy->xo_clk)) {
-+		dev_dbg(phy->dev, "cannot get TCXO buffer handle\n");
-+		phy->xo_clk = NULL;
-+	}
-+
-+	clk_set_rate(phy->utmi_clk, 60000000);
-+
-+	if (phy->xo_clk)
-+		clk_prepare_enable(phy->xo_clk);
-+
-+	phy->base		= base;
-+	phy->phy.dev		= phy->dev;
-+	phy->phy.label		= "qcom-dwc3-hsphy";
-+	phy->phy.init		= qcom_dwc3_hs_phy_init;
-+	phy->phy.notify_connect	= qcom_dwc3_hs_notify_connect;
-+	phy->phy.notify_disconnect = qcom_dwc3_hs_notify_disconnect;
-+	phy->phy.shutdown	= qcom_dwc3_hs_phy_shutdown;
-+	phy->phy.set_vbus	= qcom_dwc3_hs_phy_set_vbus;
-+	phy->phy.type		= USB_PHY_TYPE_USB2;
-+	phy->phy.state          = OTG_STATE_UNDEFINED;
-+
-+	usb_add_phy_dev(&phy->phy);
-+	return 0;
-+}
-+
-+static int qcom_dwc3_hs_remove(struct platform_device *pdev)
-+{
-+	struct qcom_dwc3_hs_phy *phy = platform_get_drvdata(pdev);
-+
-+	if (phy->xo_clk)
-+		clk_disable_unprepare(phy->xo_clk);
-+	usb_remove_phy(&phy->phy);
-+	return 0;
-+}
-+
-+static const struct of_device_id qcom_dwc3_hs_id_table[] = {
-+	{ .compatible = "qcom,dwc3-hsphy" },
-+	{ /* Sentinel */ }
-+};
-+MODULE_DEVICE_TABLE(of, qcom_dwc3_hs_id_table);
-+
-+static struct platform_driver qcom_dwc3_hs_driver = {
-+	.probe		= qcom_dwc3_hs_probe,
-+	.remove		= qcom_dwc3_hs_remove,
-+	.driver		= {
-+		.name	= "qcom-dwc3-hsphy",
-+		.owner	= THIS_MODULE,
-+		.of_match_table = qcom_dwc3_hs_id_table,
-+	},
-+};
-+
-+module_platform_driver(qcom_dwc3_hs_driver);
-+
-+MODULE_ALIAS("platform:qcom-dwc3-hsphy");
-+MODULE_LICENSE("GPL v2");
-+MODULE_DESCRIPTION("DesignWare USB3 QCOM HSPHY driver");
---- /dev/null
-+++ b/drivers/usb/phy/phy-qcom-ssusb.c
-@@ -0,0 +1,455 @@
-+/* Copyright (c) 2013-2014, Code Aurora Forum. All rights reserved.
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 and
-+ * only version 2 as published by the Free Software Foundation.
-+ *
-+ * 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/err.h>
-+#include <linux/io.h>
-+#include <linux/module.h>
-+#include <linux/of.h>
-+#include <linux/platform_device.h>
-+#include <linux/regulator/consumer.h>
-+#include <linux/usb/phy.h>
-+
-+/**
-+ *  USB QSCRATCH Hardware registers
-+ */
-+#define PHY_CTRL_REG			(0x00)
-+#define PHY_PARAM_CTRL_1		(0x04)
-+#define PHY_PARAM_CTRL_2		(0x08)
-+#define CR_PROTOCOL_DATA_IN_REG		(0x0c)
-+#define CR_PROTOCOL_DATA_OUT_REG	(0x10)
-+#define CR_PROTOCOL_CAP_ADDR_REG	(0x14)
-+#define CR_PROTOCOL_CAP_DATA_REG	(0x18)
-+#define CR_PROTOCOL_READ_REG		(0x1c)
-+#define CR_PROTOCOL_WRITE_REG		(0x20)
-+
-+#define PHY_1P8_VOL_MIN			1800000 /* uV */
-+#define PHY_1P8_VOL_MAX			1800000 /* uV */
-+#define PHY_1P8_HPM_LOAD		23000	/* uA */
-+
-+/* TODO: these are suspicious */
-+#define USB_VDDCX_NO			1	/* index */
-+#define USB_VDDCX_MIN			5	/* index */
-+#define USB_VDDCX_MAX			7	/* index */
-+
-+struct qcom_dwc3_ss_phy {
-+	struct usb_phy		phy;
-+	void __iomem		*base;
-+	struct device		*dev;
-+
-+	struct regulator	*v1p8;
-+	struct regulator	*vddcx;
-+
-+	struct clk		*xo_clk;
-+	struct clk		*ref_clk;
-+};
-+
-+#define	phy_to_dw_phy(x)	container_of((x), struct qcom_dwc3_ss_phy, phy)
-+
-+
-+/**
-+ * Write register
-+ *
-+ * @base - QCOM DWC3 PHY base virtual address.
-+ * @offset - register offset.
-+ * @val - value to write.
-+ */
-+static inline void qcom_dwc3_ss_write(void __iomem *base, u32 offset, u32 val)
-+{
-+	writel(val, base + offset);
-+}
-+
-+/**
-+ * Write register and read back masked value to confirm it is written
-+ *
-+ * @base - QCOM DWC3 PHY base virtual address.
-+ * @offset - register offset.
-+ * @mask - register bitmask specifying what should be updated
-+ * @val - value to write.
-+ */
-+static inline void qcom_dwc3_ss_write_readback(void __iomem *base, u32 offset,
-+					    const u32 mask, u32 val)
-+{
-+	u32 write_val, tmp = readl(base + offset);
-+
-+	tmp &= ~mask;		/* retain other bits */
-+	write_val = tmp | val;
-+
-+	writel(write_val, base + offset);
-+
-+	/* Read back to see if val was written */
-+	tmp = readl(base + offset);
-+	tmp &= mask;		/* clear other bits */
-+
-+	if (tmp != val)
-+		pr_err("write: %x to QSCRATCH: %x FAILED\n", val, offset);
-+}
-+
-+/**
-+ * Write SSPHY register
-+ *
-+ * @base - QCOM DWC3 PHY base virtual address.
-+ * @addr - SSPHY address to write.
-+ * @val - value to write.
-+ */
-+static void qcom_dwc3_ss_write_phycreg(void __iomem *base, u32 addr, u32 val)
-+{
-+	writel(addr, base + CR_PROTOCOL_DATA_IN_REG);
-+	writel(0x1, base + CR_PROTOCOL_CAP_ADDR_REG);
-+	while (readl(base + CR_PROTOCOL_CAP_ADDR_REG))
-+		cpu_relax();
-+
-+	writel(val, base + CR_PROTOCOL_DATA_IN_REG);
-+	writel(0x1, base + CR_PROTOCOL_CAP_DATA_REG);
-+	while (readl(base + CR_PROTOCOL_CAP_DATA_REG))
-+		cpu_relax();
-+
-+	writel(0x1, base + CR_PROTOCOL_WRITE_REG);
-+	while (readl(base + CR_PROTOCOL_WRITE_REG))
-+		cpu_relax();
-+}
-+
-+/**
-+ * Read SSPHY register.
-+ *
-+ * @base - QCOM DWC3 PHY base virtual address.
-+ * @addr - SSPHY address to read.
-+ */
-+static u32 qcom_dwc3_ss_read_phycreg(void __iomem *base, u32 addr)
-+{
-+	bool first_read = true;
-+
-+	writel(addr, base + CR_PROTOCOL_DATA_IN_REG);
-+	writel(0x1, base + CR_PROTOCOL_CAP_ADDR_REG);
-+	while (readl(base + CR_PROTOCOL_CAP_ADDR_REG))
-+		cpu_relax();
-+
-+	/*
-+	 * Due to hardware bug, first read of SSPHY register might be
-+	 * incorrect. Hence as workaround, SW should perform SSPHY register
-+	 * read twice, but use only second read and ignore first read.
-+	 */
-+retry:
-+	writel(0x1, base + CR_PROTOCOL_READ_REG);
-+	while (readl(base + CR_PROTOCOL_READ_REG))
-+		cpu_relax();
-+
-+	if (first_read) {
-+		readl(base + CR_PROTOCOL_DATA_OUT_REG);
-+		first_read = false;
-+		goto retry;
-+	}
-+
-+	return readl(base + CR_PROTOCOL_DATA_OUT_REG);
-+}
-+
-+static void qcom_dwc3_ss_phy_shutdown(struct usb_phy *x)
-+{
-+	struct qcom_dwc3_ss_phy *phy = phy_to_dw_phy(x);
-+	int ret;
-+
-+	/* Sequence to put SSPHY in low power state:
-+	 * 1. Clear REF_PHY_EN in PHY_CTRL_REG
-+	 * 2. Clear REF_USE_PAD in PHY_CTRL_REG
-+	 * 3. Set TEST_POWERED_DOWN in PHY_CTRL_REG to enable PHY retention
-+	 * 4. Disable SSPHY ref clk
-+	 */
-+	qcom_dwc3_ss_write_readback(phy->base, PHY_CTRL_REG, (1 << 8), 0x0);
-+	qcom_dwc3_ss_write_readback(phy->base, PHY_CTRL_REG, (1 << 28), 0x0);
-+	qcom_dwc3_ss_write_readback(phy->base, PHY_CTRL_REG,
-+				    (1 << 26), (1 << 26));
-+
-+	usleep_range(1000, 1200);
-+	clk_disable_unprepare(phy->ref_clk);
-+
-+	ret = regulator_set_voltage(phy->vddcx, USB_VDDCX_NO, USB_VDDCX_MAX);
-+	if (ret)
-+		dev_err(phy->dev, "cannot set voltage for vddcx\n");
-+
-+	regulator_disable(phy->vddcx);
-+
-+	ret = regulator_set_voltage(phy->v1p8, 0, PHY_1P8_VOL_MAX);
-+	if (ret)
-+		dev_err(phy->dev, "cannot set v1p8\n");
-+
-+	regulator_disable(phy->v1p8);
-+}
-+
-+static int qcom_dwc3_ss_phy_init(struct usb_phy *x)
-+{
-+	struct qcom_dwc3_ss_phy *phy = phy_to_dw_phy(x);
-+	u32 data = 0;
-+	int ret;
-+
-+	ret = regulator_set_voltage(phy->vddcx, USB_VDDCX_MIN, USB_VDDCX_MAX);
-+	if (ret) {
-+		dev_err(phy->dev, "cannot set voltage for vddcx\n");
-+		return ret;
-+	}
-+
-+	ret = regulator_enable(phy->vddcx);
-+	if (ret) {
-+		dev_err(phy->dev, "cannot enable vddcx\n");
-+		return ret;
-+	}
-+
-+	ret = regulator_set_voltage(phy->v1p8, PHY_1P8_VOL_MIN,
-+				    PHY_1P8_VOL_MAX);
-+	if (ret) {
-+		regulator_disable(phy->vddcx);
-+		dev_err(phy->dev, "cannot set v1p8\n");
-+		return ret;
-+	}
-+
-+	ret = regulator_enable(phy->v1p8);
-+	if (ret) {
-+		regulator_disable(phy->vddcx);
-+		dev_err(phy->dev, "cannot enable v1p8\n");
-+		return ret;
-+	}
-+
-+	clk_prepare_enable(phy->ref_clk);
-+	usleep_range(1000, 1200);
-+
-+	/* reset phy */
-+	data = readl_relaxed(phy->base + PHY_CTRL_REG);
-+	writel_relaxed(data | BIT(7), phy->base + PHY_CTRL_REG);
-+	usleep_range(2000, 2200);
-+	writel_relaxed(data, phy->base + PHY_CTRL_REG);
-+
-+	/* clear REF_PAD, we don't have XO clk */
-+	data &= ~BIT(28);
-+	writel_relaxed(data, phy->base + PHY_CTRL_REG);
-+	msleep(30);
-+
-+	data |= BIT(8) | BIT(24);
-+	writel_relaxed(data, phy->base + PHY_CTRL_REG);
-+
-+	/*
-+	 * WORKAROUND: There is SSPHY suspend bug due to which USB enumerates
-+	 * in HS mode instead of SS mode. Workaround it by asserting
-+	 * LANE0.TX_ALT_BLOCK.EN_ALT_BUS to enable TX to use alt bus mode
-+	 */
-+	data = qcom_dwc3_ss_read_phycreg(phy->base, 0x102d);
-+	data |= (1 << 7);
-+	qcom_dwc3_ss_write_phycreg(phy->base, 0x102D, data);
-+
-+	data = qcom_dwc3_ss_read_phycreg(phy->base, 0x1010);
-+	data &= ~0xff0;
-+	data |= 0x20;
-+	qcom_dwc3_ss_write_phycreg(phy->base, 0x1010, data);
-+
-+	/*
-+	 * Fix RX Equalization setting as follows
-+	 * LANE0.RX_OVRD_IN_HI. RX_EQ_EN set to 0
-+	 * LANE0.RX_OVRD_IN_HI.RX_EQ_EN_OVRD set to 1
-+	 * LANE0.RX_OVRD_IN_HI.RX_EQ set to 3
-+	 * LANE0.RX_OVRD_IN_HI.RX_EQ_OVRD set to 1
-+	 */
-+	data = qcom_dwc3_ss_read_phycreg(phy->base, 0x1006);
-+	data &= ~(1 << 6);
-+	data |= (1 << 7);
-+	data &= ~(0x7 << 8);
-+	data |= (0x3 << 8);
-+	data |= (0x1 << 11);
-+	qcom_dwc3_ss_write_phycreg(phy->base, 0x1006, data);
-+
-+	/*
-+	 * Set EQ and TX launch amplitudes as follows
-+	 * LANE0.TX_OVRD_DRV_LO.PREEMPH set to 22
-+	 * LANE0.TX_OVRD_DRV_LO.AMPLITUDE set to 127
-+	 * LANE0.TX_OVRD_DRV_LO.EN set to 1.
-+	 */
-+	data = qcom_dwc3_ss_read_phycreg(phy->base, 0x1002);
-+	data &= ~0x3f80;
-+	data |= (0x16 << 7);
-+	data &= ~0x7f;
-+	data |= (0x7f | (1 << 14));
-+	qcom_dwc3_ss_write_phycreg(phy->base, 0x1002, data);
-+
-+	/*
-+	 * Set the QSCRATCH PHY_PARAM_CTRL1 parameters as follows
-+	 * TX_FULL_SWING [26:20] amplitude to 127
-+	 * TX_DEEMPH_3_5DB [13:8] to 22
-+	 * LOS_BIAS [2:0] to 0x5
-+	 */
-+	qcom_dwc3_ss_write_readback(phy->base, PHY_PARAM_CTRL_1,
-+				   0x07f03f07, 0x07f01605);
-+	return 0;
-+}
-+
-+static int qcom_dwc3_ss_set_suspend(struct usb_phy *x, int suspend)
-+{
-+	struct qcom_dwc3_ss_phy *phy = phy_to_dw_phy(x);
-+	u32 data;
-+
-+	if (!suspend) {
-+		/* reset phy */
-+		data = readl_relaxed(phy->base + PHY_CTRL_REG);
-+		writel_relaxed(data | BIT(7), phy->base + PHY_CTRL_REG);
-+		usleep_range(2000, 2200);
-+		writel_relaxed(data, phy->base + PHY_CTRL_REG);
-+
-+		/* clear REF_PAD, we don't have XO clk */
-+		data &= ~BIT(28);
-+		writel_relaxed(data, phy->base + PHY_CTRL_REG);
-+		msleep(30);
-+
-+		data |= BIT(8) | BIT(24);
-+		writel_relaxed(data, phy->base + PHY_CTRL_REG);
-+
-+		/*
-+		 * WORKAROUND: There is SSPHY suspend bug due to which USB
-+		 * enumerates in HS mode instead of SS mode. Workaround it by
-+		 * asserting LANE0.TX_ALT_BLOCK.EN_ALT_BUS to enable TX to use
-+		 * alt bus mode
-+		 */
-+		data = qcom_dwc3_ss_read_phycreg(phy->base, 0x102d);
-+		data |= (1 << 7);
-+		qcom_dwc3_ss_write_phycreg(phy->base, 0x102D, data);
-+
-+		data = qcom_dwc3_ss_read_phycreg(phy->base, 0x1010);
-+		data &= ~0xff0;
-+		data |= 0x20;
-+		qcom_dwc3_ss_write_phycreg(phy->base, 0x1010, data);
-+
-+		/*
-+		 * Fix RX Equalization setting as follows
-+		 * LANE0.RX_OVRD_IN_HI. RX_EQ_EN set to 0
-+		 * LANE0.RX_OVRD_IN_HI.RX_EQ_EN_OVRD set to 1
-+		 * LANE0.RX_OVRD_IN_HI.RX_EQ set to 3
-+		 * LANE0.RX_OVRD_IN_HI.RX_EQ_OVRD set to 1
-+		 */
-+		data = qcom_dwc3_ss_read_phycreg(phy->base, 0x1006);
-+		data &= ~(1 << 6);
-+		data |= (1 << 7);
-+		data &= ~(0x7 << 8);
-+		data |= (0x3 << 8);
-+		data |= (0x1 << 11);
-+		qcom_dwc3_ss_write_phycreg(phy->base, 0x1006, data);
-+
-+		/*
-+		 * Set EQ and TX launch amplitudes as follows
-+		 * LANE0.TX_OVRD_DRV_LO.PREEMPH set to 22
-+		 * LANE0.TX_OVRD_DRV_LO.AMPLITUDE set to 127
-+		 * LANE0.TX_OVRD_DRV_LO.EN set to 1.
-+		 */
-+		data = qcom_dwc3_ss_read_phycreg(phy->base, 0x1002);
-+		data &= ~0x3f80;
-+		data |= (0x16 << 7);
-+		data &= ~0x7f;
-+		data |= (0x7f | (1 << 14));
-+		qcom_dwc3_ss_write_phycreg(phy->base, 0x1002, data);
-+
-+		/*
-+		 * Set the QSCRATCH PHY_PARAM_CTRL1 parameters as follows
-+		 * TX_FULL_SWING [26:20] amplitude to 127
-+		 * TX_DEEMPH_3_5DB [13:8] to 22
-+		 * LOS_BIAS [2:0] to 0x5
-+		 */
-+		qcom_dwc3_ss_write_readback(phy->base, PHY_PARAM_CTRL_1,
-+					   0x07f03f07, 0x07f01605);
-+	}
-+	return 0;
-+}
-+
-+static int qcom_dwc3_ss_probe(struct platform_device *pdev)
-+{
-+	struct qcom_dwc3_ss_phy	*phy;
-+	struct resource		*res;
-+	void __iomem		*base;
-+	int ret;
-+
-+	phy = devm_kzalloc(&pdev->dev, sizeof(*phy), GFP_KERNEL);
-+	if (!phy)
-+		return -ENOMEM;
-+
-+	platform_set_drvdata(pdev, phy);
-+
-+	phy->dev = &pdev->dev;
-+
-+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-+	base = devm_ioremap_resource(phy->dev, res);
-+	if (IS_ERR(base))
-+		return PTR_ERR(base);
-+
-+	phy->vddcx = devm_regulator_get(phy->dev, "vddcx");
-+	if (IS_ERR(phy->vddcx)) {
-+		dev_dbg(phy->dev, "cannot get vddcx\n");
-+		return  PTR_ERR(phy->vddcx);
-+	}
-+
-+	phy->v1p8 = devm_regulator_get(phy->dev, "v1p8");
-+	if (IS_ERR(phy->v1p8)) {
-+		dev_dbg(phy->dev, "cannot get v1p8\n");
-+		return  PTR_ERR(phy->v1p8);
-+	}
-+
-+	phy->xo_clk = devm_clk_get(phy->dev, "xo");
-+	if (IS_ERR(phy->xo_clk)) {
-+		dev_dbg(phy->dev, "cannot get XO clk, assuming not present\n");
-+		phy->xo_clk = NULL;
-+	}
-+
-+	phy->ref_clk = devm_clk_get(phy->dev, "ref");
-+	if (IS_ERR(phy->ref_clk)) {
-+		dev_dbg(phy->dev, "cannot get ref clock handle\n");
-+		return PTR_ERR(phy->ref_clk);
-+	}
-+
-+	clk_set_rate(phy->ref_clk, 125000000);
-+	if (phy->xo_clk)
-+		clk_prepare_enable(phy->xo_clk);
-+
-+	phy->base		= base;
-+	phy->phy.dev		= phy->dev;
-+	phy->phy.label		= "qcom-dwc3-ssphy";
-+	phy->phy.init		= qcom_dwc3_ss_phy_init;
-+	phy->phy.shutdown       = qcom_dwc3_ss_phy_shutdown;
-+	phy->phy.set_suspend	= qcom_dwc3_ss_set_suspend;
-+	phy->phy.type		= USB_PHY_TYPE_USB3;
-+
-+	ret = usb_add_phy_dev(&phy->phy);
-+	return ret;
-+}
-+
-+static int qcom_dwc3_ss_remove(struct platform_device *pdev)
-+{
-+	struct qcom_dwc3_ss_phy *phy = platform_get_drvdata(pdev);
-+
-+	if (phy->xo_clk)
-+		clk_disable_unprepare(phy->xo_clk);
-+	usb_remove_phy(&phy->phy);
-+	return 0;
-+}
-+
-+static const struct of_device_id qcom_dwc3_ss_id_table[] = {
-+	{ .compatible = "qcom,dwc3-ssphy" },
-+	{ /* Sentinel */ }
-+};
-+MODULE_DEVICE_TABLE(of, qcom_dwc3_ss_id_table);
-+
-+static struct platform_driver qcom_dwc3_ss_driver = {
-+	.probe		= qcom_dwc3_ss_probe,
-+	.remove		= qcom_dwc3_ss_remove,
-+	.driver		= {
-+		.name	= "qcom-dwc3-ssphy",
-+		.owner	= THIS_MODULE,
-+		.of_match_table = qcom_dwc3_ss_id_table,
-+	},
-+};
-+
-+module_platform_driver(qcom_dwc3_ss_driver);
-+
-+MODULE_ALIAS("platform:qcom-dwc3-ssphy");
-+MODULE_LICENSE("GPL v2");
-+MODULE_DESCRIPTION("DesignWare USB3 QCOM SSPHY driver");
diff --git a/target/linux/ipq806x/patches/0158-usb-dwc3-qcom-Add-device-tree-binding.patch b/target/linux/ipq806x/patches/0158-usb-dwc3-qcom-Add-device-tree-binding.patch
deleted file mode 100644
index ffe2a8d..0000000
--- a/target/linux/ipq806x/patches/0158-usb-dwc3-qcom-Add-device-tree-binding.patch
+++ /dev/null
@@ -1,125 +0,0 @@
-From c7045330c5976eb31bd79bc57c5db684588d595e Mon Sep 17 00:00:00 2001
-From: "Ivan T. Ivanov" <iivanov@mm-sol.com>
-Date: Mon, 7 Oct 2013 10:44:55 +0300
-Subject: [PATCH 158/182] usb: dwc3: qcom: Add device tree binding
-
-QCOM USB3.0 core wrapper consist of USB3.0 IP from Synopsys
-(SNPS) and HS, SS PHY's control and configuration registers.
-
-It could operate in device mode (SS, HS, FS) and host
-mode (SS, HS, FS, LS).
-
-Signed-off-by: Ivan T. Ivanov <iivanov@mm-sol.com>
-Acked-by: Stephen Warren <swarren@nvidia.com>
----
- .../devicetree/bindings/usb/qcom,dwc3.txt          |  104 ++++++++++++++++++++
- 1 file changed, 104 insertions(+)
- create mode 100644 Documentation/devicetree/bindings/usb/qcom,dwc3.txt
-
---- /dev/null
-+++ b/Documentation/devicetree/bindings/usb/qcom,dwc3.txt
-@@ -0,0 +1,104 @@
-+Qualcomm SuperSpeed DWC3 USB SoC controller
-+
-+
-+QCOM DWC3 Highspeed USB PHY
-+========================
-+Required properities:
-+- compatible:	should contain "qcom,dwc3-hsphy";
-+- reg:			offset and length of the register set in the memory map
-+- clocks:		A list of phandle + clock-specifier pairs for the
-+				clocks listed in clock-names
-+- clock-names:	Should contain the following:
-+  "utmi"		UTMI clock
-+- v1p8-supply:	phandle to the regulator for the 1.8v supply to HSPHY.
-+- v3p3-supply:	phandle to the regulator for the 3.3v supply to HSPHY.
-+- vbus-supply:	phandle to the regulator for the vbus supply for host
-+		mode.
-+- vddcx-supply: phandle to the regulator for the vdd supply for HSPHY
-+                digital circuit operation.
-+
-+Optional clocks:
-+  "xo"			External reference clock
-+
-+
-+QCOM DWC3 Superspeed USB PHY
-+=========================
-+Required properities:
-+- compatible:	should contain "qcom,dwc3-ssphy";
-+- reg:			offset and length of the register set in the memory map
-+- clocks:		A list of phandle + clock-specifier pairs for the
-+				clocks listed in clock-names
-+- clock-names:	Should contain the following:
-+  "ref"			Reference clock used in host mode.
-+- v1p8-supply:	phandle to the regulator for the 1.8v supply to HSPHY.
-+- vddcx-supply: phandle to the regulator for the vdd supply for HSPHY
-+                digital circuit operation.
-+
-+Optional clocks:
-+  "xo"			External reference clock
-+
-+QCOM DWC3 controller wrapper
-+===========================
-+Required properties:
-+- compatible:	should contain "qcom,dwc3"
-+- clocks:		A list of phandle + clock-specifier pairs for the
-+				clocks listed in clock-names
-+- clock-names:	Should contain the following:
-+  "core"		Master/Core clock, have to be >= 125 MHz for SS
-+				operation and >= 60MHz for HS operation
-+
-+Optional clocks:
-+  "iface"		System bus AXI clock.  Not present on all platforms
-+  "sleep"		Sleep clock, used when USB3 core goes into low
-+				power mode (U3).
-+
-+Optional regulator:
-+- gdsc-supply:	phandle to the regulator from globally distributed
-+				switch controller
-+
-+Required child node:
-+A child node must exist to represent the core DWC3 IP block. The name of
-+the node is not important. The content of the node is defined in dwc3.txt.
-+
-+Example device nodes:
-+
-+		hs_phy_0: phy@110f8800 {
-+			compatible = "qcom,dwc3-hsphy";
-+			reg = <0x110f8800 0x30>;
-+			clocks = <&gcc USB30_0_UTMI_CLK>;
-+			clock-names = "utmi";
-+
-+			status = "disabled";
-+		};
-+
-+		ss_phy_0: phy@110f8830 {
-+			compatible = "qcom,dwc3-ssphy";
-+			reg = <0x110f8830 0x30>;
-+
-+			clocks = <&gcc USB30_0_MASTER_CLK>;
-+			clock-names = "ref";
-+
-+			status = "disabled";
-+		};
-+
-+		usb3_0: usb30@0 {
-+			compatible = "qcom,dwc3";
-+			#address-cells = <1>;
-+			#size-cells = <1>;
-+			clocks = <&gcc USB30_0_MASTER_CLK>;
-+			clock-names = "core";
-+
-+			ranges;
-+
-+			status = "disabled";
-+
-+			dwc3@11000000 {
-+				compatible = "snps,dwc3";
-+				reg = <0x11000000 0xcd00>;
-+				interrupts = <0 110 0x4>;
-+				usb-phy = <&hs_phy_0>, <&ss_phy_0>;
-+				phy-names = "usb2-phy", "usb3-phy";
-+				tx-fifo-resize;
-+				dr_mode = "host";
-+			};
-+		};
diff --git a/target/linux/ipq806x/patches/0159-arm-ipq8064-Add-USB3-DT-information.patch b/target/linux/ipq806x/patches/0159-arm-ipq8064-Add-USB3-DT-information.patch
deleted file mode 100644
index 843e94f..0000000
--- a/target/linux/ipq806x/patches/0159-arm-ipq8064-Add-USB3-DT-information.patch
+++ /dev/null
@@ -1,155 +0,0 @@
-From 269a71c81438604d27f01ec703daa7f5e3f39e8b Mon Sep 17 00:00:00 2001
-From: Andy Gross <agross@codeaurora.org>
-Date: Sun, 15 Jun 2014 00:48:18 -0500
-Subject: [PATCH 159/182] arm: ipq8064: Add USB3 DT information
-
-This patch fleshes out the USB3 specific information for the IPQ8064 platform.
-
-Signed-off-by: Andy Gross <agross@codeaurora.org>
----
- arch/arm/boot/dts/qcom-ipq8064-ap148.dts |   29 ++++++++++
- arch/arm/boot/dts/qcom-ipq8064.dtsi      |   90 ++++++++++++++++++++++++++++++
- 2 files changed, 119 insertions(+)
-
---- a/arch/arm/boot/dts/qcom-ipq8064-ap148.dts
-+++ b/arch/arm/boot/dts/qcom-ipq8064-ap148.dts
-@@ -160,5 +160,34 @@
- 			pinctrl-0 = <&nand_pins>;
- 			pinctrl-names = "default";
- 		};
-+
-+		tcsr@1a400000 {
-+			status = "ok";
-+			qcom,usb-ctrl-select = <TCSR_USB_SELECT_USB3_DUAL>;
-+		};
-+
-+		phy@100f8800 {		/* USB3 port 1 HS phy */
-+			status = "ok";
-+		};
-+
-+		phy@100f8830 {		/* USB3 port 1 SS phy */
-+			status = "ok";
-+		};
-+
-+		phy@110f8800 {		/* USB3 port 0 HS phy */
-+			status = "ok";
-+		};
-+
-+		phy@110f8830 {		/* USB3 port 0 SS phy */
-+			status = "ok";
-+		};
-+
-+		usb30@0 {
-+			status = "ok";
-+		};
-+
-+		usb30@1 {
-+			status = "ok";
-+		};
- 	};
- };
---- a/arch/arm/boot/dts/qcom-ipq8064.dtsi
-+++ b/arch/arm/boot/dts/qcom-ipq8064.dtsi
-@@ -4,6 +4,7 @@
- #include <dt-bindings/clock/qcom,gcc-ipq806x.h>
- #include <dt-bindings/reset/qcom,gcc-ipq806x.h>
- #include <dt-bindings/soc/qcom,gsbi.h>
-+#include <dt-bindings/soc/qcom,tcsr.h>
- 
- / {
- 	model = "Qualcomm IPQ8064";
-@@ -402,5 +403,94 @@
- 
- 			status = "disabled";
- 		};
-+
-+		tcsr: tcsr@1a400000 {
-+			compatible = "qcom,tcsr";
-+			reg = <0x1a400000 0x100>;
-+
-+			status = "disabled";
-+		};
-+
-+		hs_phy_1: phy@100f8800 {
-+			compatible = "qcom,dwc3-hsphy";
-+			reg = <0x100f8800 0x30>;
-+			clocks = <&gcc USB30_1_UTMI_CLK>;
-+			clock-names = "utmi";
-+
-+			status = "disabled";
-+		};
-+
-+		ss_phy_1: phy@100f8830 {
-+			compatible = "qcom,dwc3-ssphy";
-+			reg = <0x100f8830 0x30>;
-+
-+			clocks = <&gcc USB30_1_MASTER_CLK>;
-+			clock-names = "ref";
-+
-+			status = "disabled";
-+		};
-+
-+		hs_phy_0: phy@110f8800 {
-+			compatible = "qcom,dwc3-hsphy";
-+			reg = <0x110f8800 0x30>;
-+			clocks = <&gcc USB30_0_UTMI_CLK>;
-+			clock-names = "utmi";
-+
-+			status = "disabled";
-+		};
-+
-+		ss_phy_0: phy@110f8830 {
-+			compatible = "qcom,dwc3-ssphy";
-+			reg = <0x110f8830 0x30>;
-+
-+			clocks = <&gcc USB30_0_MASTER_CLK>;
-+			clock-names = "ref";
-+
-+			status = "disabled";
-+		};
-+
-+		usb3_0: usb30@0 {
-+			compatible = "qcom,dwc3";
-+			#address-cells = <1>;
-+			#size-cells = <1>;
-+			clocks = <&gcc USB30_0_MASTER_CLK>;
-+			clock-names = "core";
-+
-+			ranges;
-+
-+			status = "disabled";
-+
-+			dwc3@11000000 {
-+				compatible = "snps,dwc3";
-+				reg = <0x11000000 0xcd00>;
-+				interrupts = <0 110 0x4>;
-+				usb-phy = <&hs_phy_0>, <&ss_phy_0>;
-+				phy-names = "usb2-phy", "usb3-phy";
-+				tx-fifo-resize;
-+				dr_mode = "host";
-+			};
-+		};
-+
-+		usb3_1: usb30@1 {
-+			compatible = "qcom,dwc3";
-+			#address-cells = <1>;
-+			#size-cells = <1>;
-+			clocks = <&gcc USB30_1_MASTER_CLK>;
-+			clock-names = "core";
-+
-+			ranges;
-+
-+			status = "disabled";
-+
-+			dwc3@10000000 {
-+				compatible = "snps,dwc3";
-+				reg = <0x10000000 0xcd00>;
-+				interrupts = <0 205 0x4>;
-+				usb-phy = <&hs_phy_1>, <&ss_phy_1>;
-+				phy-names = "usb2-phy", "usb3-phy";
-+				tx-fifo-resize;
-+				dr_mode = "host";
-+			};
-+		};
- 	};
- };
diff --git a/target/linux/ipq806x/patches/0160-ARM-qcom-config-Add-TCSR-and-USB3-options.patch b/target/linux/ipq806x/patches/0160-ARM-qcom-config-Add-TCSR-and-USB3-options.patch
deleted file mode 100644
index 400c87e..0000000
--- a/target/linux/ipq806x/patches/0160-ARM-qcom-config-Add-TCSR-and-USB3-options.patch
+++ /dev/null
@@ -1,37 +0,0 @@
-From 8e69ee9a592f363476f18e91f57d871662e9a393 Mon Sep 17 00:00:00 2001
-From: Andy Gross <agross@codeaurora.org>
-Date: Mon, 16 Jun 2014 16:37:22 -0500
-Subject: [PATCH 160/182] ARM: qcom: config: Add TCSR and USB3 options
-
-Enable TCSR and USB3 options.
-
-Signed-off-by: Andy Gross <agross@codeaurora.org>
----
- arch/arm/configs/qcom_defconfig |    6 ++++++
- 1 file changed, 6 insertions(+)
-
---- a/arch/arm/configs/qcom_defconfig
-+++ b/arch/arm/configs/qcom_defconfig
-@@ -122,9 +122,14 @@ CONFIG_HID_BATTERY_STRENGTH=y
- CONFIG_USB=y
- CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
- CONFIG_USB_MON=y
-+CONFIG_USB_XHCI_HCD=y
- CONFIG_USB_EHCI_HCD=y
- CONFIG_USB_ACM=y
-+CONFIG_USB_STORAGE=y
-+CONFIG_USB_DWC3=y
-+CONFIG_USB_DWC3_HOST=y
- CONFIG_USB_SERIAL=y
-+CONFIG_USB_QCOM_DWC3_PHY=y
- CONFIG_USB_GADGET=y
- CONFIG_USB_GADGET_DEBUG_FILES=y
- CONFIG_USB_GADGET_VBUS_DRAW=500
-@@ -138,6 +143,7 @@ CONFIG_DMADEVICES=y
- CONFIG_QCOM_BAM_DMA=y
- CONFIG_STAGING=y
- CONFIG_QCOM_GSBI=y
-+CONFIG_QCOM_TCSR=y
- CONFIG_COMMON_CLK_QCOM=y
- CONFIG_IPQ_GCC_806X=y
- CONFIG_MSM_GCC_8660=y
diff --git a/target/linux/ipq806x/patches/0161-ARM-Remove-ARCH_HAS_CPUFREQ-config-option.patch b/target/linux/ipq806x/patches/0161-ARM-Remove-ARCH_HAS_CPUFREQ-config-option.patch
deleted file mode 100644
index 32f2b5d..0000000
--- a/target/linux/ipq806x/patches/0161-ARM-Remove-ARCH_HAS_CPUFREQ-config-option.patch
+++ /dev/null
@@ -1,234 +0,0 @@
-From 5d102a45ee224fa32c775deb75bf7eb9d2ee2cf0 Mon Sep 17 00:00:00 2001
-From: Stephen Boyd <sboyd@codeaurora.org>
-Date: Tue, 3 Jun 2014 11:24:23 -0700
-Subject: [PATCH 161/182] ARM: Remove ARCH_HAS_CPUFREQ config option
-
-This config exists entirely to hide the cpufreq menu from the
-kernel configuration unless a platform has selected it. Nothing
-is actually built if this config is 'Y' and it just leads to more
-patches that add a select under a platform Kconfig so that some
-other CPUfreq option can be chosen. Let's remove the option so
-that we can always enable CPUfreq drivers on ARM platforms.
-
-Acked-by: Viresh Kumar <viresh.kumar@linaro.org>
-Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
-Signed-off-by: Arnd Bergmann <arnd@arndb.de>
-Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
----
- arch/arm/Kconfig               |   17 -----------------
- arch/arm/mach-davinci/Kconfig  |    1 -
- arch/arm/mach-highbank/Kconfig |    1 -
- arch/arm/mach-imx/Kconfig      |    2 --
- arch/arm/mach-omap2/Kconfig    |    1 -
- arch/arm/mach-shmobile/Kconfig |    2 --
- arch/arm/mach-spear/Kconfig    |    1 -
- arch/arm/mach-tegra/Kconfig    |    1 -
- arch/arm/mach-ux500/Kconfig    |    1 -
- arch/arm/mach-vexpress/Kconfig |    1 -
- arch/arm/mach-vt8500/Kconfig   |    1 -
- 11 files changed, 29 deletions(-)
-
---- a/arch/arm/Kconfig
-+++ b/arch/arm/Kconfig
-@@ -181,13 +181,6 @@ config ARCH_HAS_ILOG2_U32
- config ARCH_HAS_ILOG2_U64
- 	bool
- 
--config ARCH_HAS_CPUFREQ
--	bool
--	help
--	  Internal node to signify that the ARCH has CPUFREQ support
--	  and that the relevant menu configurations are displayed for
--	  it.
--
- config ARCH_HAS_BANDGAP
- 	bool
- 
-@@ -316,7 +309,6 @@ config ARCH_MULTIPLATFORM
- 
- config ARCH_INTEGRATOR
- 	bool "ARM Ltd. Integrator family"
--	select ARCH_HAS_CPUFREQ
- 	select ARM_AMBA
- 	select ARM_PATCH_PHYS_VIRT
- 	select AUTO_ZRELADDR
-@@ -541,7 +533,6 @@ config ARCH_DOVE
- 
- config ARCH_KIRKWOOD
- 	bool "Marvell Kirkwood"
--	select ARCH_HAS_CPUFREQ
- 	select ARCH_REQUIRE_GPIOLIB
- 	select CPU_FEROCEON
- 	select GENERIC_CLOCKEVENTS
-@@ -642,7 +633,6 @@ config ARCH_LPC32XX
- config ARCH_PXA
- 	bool "PXA2xx/PXA3xx-based"
- 	depends on MMU
--	select ARCH_HAS_CPUFREQ
- 	select ARCH_MTD_XIP
- 	select ARCH_REQUIRE_GPIOLIB
- 	select ARM_CPU_SUSPEND if PM
-@@ -711,7 +701,6 @@ config ARCH_RPC
- 
- config ARCH_SA1100
- 	bool "SA1100-based"
--	select ARCH_HAS_CPUFREQ
- 	select ARCH_MTD_XIP
- 	select ARCH_REQUIRE_GPIOLIB
- 	select ARCH_SPARSEMEM_ENABLE
-@@ -729,7 +718,6 @@ config ARCH_SA1100
- 
- config ARCH_S3C24XX
- 	bool "Samsung S3C24XX SoCs"
--	select ARCH_HAS_CPUFREQ
- 	select ARCH_REQUIRE_GPIOLIB
- 	select CLKDEV_LOOKUP
- 	select CLKSRC_SAMSUNG_PWM
-@@ -749,7 +737,6 @@ config ARCH_S3C24XX
- 
- config ARCH_S3C64XX
- 	bool "Samsung S3C64XX"
--	select ARCH_HAS_CPUFREQ
- 	select ARCH_REQUIRE_GPIOLIB
- 	select ARM_AMBA
- 	select ARM_VIC
-@@ -810,7 +797,6 @@ config ARCH_S5PC100
- 
- config ARCH_S5PV210
- 	bool "Samsung S5PV210/S5PC110"
--	select ARCH_HAS_CPUFREQ
- 	select ARCH_HAS_HOLES_MEMORYMODEL
- 	select ARCH_SPARSEMEM_ENABLE
- 	select CLKDEV_LOOKUP
-@@ -864,7 +850,6 @@ config ARCH_DAVINCI
- config ARCH_OMAP1
- 	bool "TI OMAP1"
- 	depends on MMU
--	select ARCH_HAS_CPUFREQ
- 	select ARCH_HAS_HOLES_MEMORYMODEL
- 	select ARCH_OMAP
- 	select ARCH_REQUIRE_GPIOLIB
-@@ -2171,9 +2156,7 @@ endmenu
- 
- menu "CPU Power Management"
- 
--if ARCH_HAS_CPUFREQ
- source "drivers/cpufreq/Kconfig"
--endif
- 
- source "drivers/cpuidle/Kconfig"
- 
---- a/arch/arm/mach-davinci/Kconfig
-+++ b/arch/arm/mach-davinci/Kconfig
-@@ -39,7 +39,6 @@ config ARCH_DAVINCI_DA830
- config ARCH_DAVINCI_DA850
- 	bool "DA850/OMAP-L138/AM18x based system"
- 	select ARCH_DAVINCI_DA8XX
--	select ARCH_HAS_CPUFREQ
- 	select CP_INTC
- 
- config ARCH_DAVINCI_DA8XX
---- a/arch/arm/mach-highbank/Kconfig
-+++ b/arch/arm/mach-highbank/Kconfig
-@@ -1,7 +1,6 @@
- config ARCH_HIGHBANK
- 	bool "Calxeda ECX-1000/2000 (Highbank/Midway)" if ARCH_MULTI_V7
- 	select ARCH_DMA_ADDR_T_64BIT if ARM_LPAE
--	select ARCH_HAS_CPUFREQ
- 	select ARCH_HAS_HOLES_MEMORYMODEL
- 	select ARCH_HAS_OPP
- 	select ARCH_SUPPORTS_BIG_ENDIAN
---- a/arch/arm/mach-imx/Kconfig
-+++ b/arch/arm/mach-imx/Kconfig
-@@ -103,7 +103,6 @@ config SOC_IMX25
- 
- config SOC_IMX27
- 	bool
--	select ARCH_HAS_CPUFREQ
- 	select ARCH_HAS_OPP
- 	select CPU_ARM926T
- 	select IMX_HAVE_IOMUX_V1
-@@ -129,7 +128,6 @@ config SOC_IMX35
- 
- config SOC_IMX5
- 	bool
--	select ARCH_HAS_CPUFREQ
- 	select ARCH_HAS_OPP
- 	select ARCH_MXC_IOMUX_V3
- 	select CPU_V7
---- a/arch/arm/mach-omap2/Kconfig
-+++ b/arch/arm/mach-omap2/Kconfig
-@@ -93,7 +93,6 @@ config SOC_DRA7XX
- config ARCH_OMAP2PLUS
- 	bool
- 	select ARCH_HAS_BANDGAP
--	select ARCH_HAS_CPUFREQ
- 	select ARCH_HAS_HOLES_MEMORYMODEL
- 	select ARCH_OMAP
- 	select ARCH_REQUIRE_GPIOLIB
---- a/arch/arm/mach-shmobile/Kconfig
-+++ b/arch/arm/mach-shmobile/Kconfig
-@@ -85,7 +85,6 @@ config ARCH_R8A73A4
- 	select CPU_V7
- 	select SH_CLK_CPG
- 	select RENESAS_IRQC
--	select ARCH_HAS_CPUFREQ
- 	select ARCH_HAS_OPP
- 
- config ARCH_R8A7740
-@@ -271,7 +270,6 @@ config MACH_KOELSCH
- config MACH_KZM9G
- 	bool "KZM-A9-GT board"
- 	depends on ARCH_SH73A0
--	select ARCH_HAS_CPUFREQ
- 	select ARCH_HAS_OPP
- 	select ARCH_REQUIRE_GPIOLIB
- 	select REGULATOR_FIXED_VOLTAGE if REGULATOR
---- a/arch/arm/mach-spear/Kconfig
-+++ b/arch/arm/mach-spear/Kconfig
-@@ -16,7 +16,6 @@ if PLAT_SPEAR
- config ARCH_SPEAR13XX
- 	bool "ST SPEAr13xx"
- 	depends on ARCH_MULTI_V7 || PLAT_SPEAR_SINGLE
--	select ARCH_HAS_CPUFREQ
- 	select ARM_GIC
- 	select CPU_V7
- 	select GPIO_SPEAR_SPICS
---- a/arch/arm/mach-tegra/Kconfig
-+++ b/arch/arm/mach-tegra/Kconfig
-@@ -1,6 +1,5 @@
- config ARCH_TEGRA
- 	bool "NVIDIA Tegra" if ARCH_MULTI_V7
--	select ARCH_HAS_CPUFREQ
- 	select ARCH_REQUIRE_GPIOLIB
- 	select ARCH_SUPPORTS_TRUSTED_FOUNDATIONS
- 	select ARM_GIC
---- a/arch/arm/mach-ux500/Kconfig
-+++ b/arch/arm/mach-ux500/Kconfig
-@@ -3,7 +3,6 @@ config ARCH_U8500
- 	depends on MMU
- 	select AB8500_CORE
- 	select ABX500_CORE
--	select ARCH_HAS_CPUFREQ
- 	select ARCH_REQUIRE_GPIOLIB
- 	select ARM_AMBA
- 	select ARM_ERRATA_754322
---- a/arch/arm/mach-vexpress/Kconfig
-+++ b/arch/arm/mach-vexpress/Kconfig
-@@ -67,7 +67,6 @@ config ARCH_VEXPRESS_DCSCB
- 
- config ARCH_VEXPRESS_SPC
- 	bool "Versatile Express Serial Power Controller (SPC)"
--	select ARCH_HAS_CPUFREQ
- 	select ARCH_HAS_OPP
- 	select PM_OPP
- 	help
---- a/arch/arm/mach-vt8500/Kconfig
-+++ b/arch/arm/mach-vt8500/Kconfig
-@@ -1,6 +1,5 @@
- config ARCH_VT8500
- 	bool
--	select ARCH_HAS_CPUFREQ
- 	select ARCH_REQUIRE_GPIOLIB
- 	select CLKDEV_LOOKUP
- 	select CLKSRC_OF
diff --git a/target/linux/ipq806x/patches/0162-PM-OPP-Remove-ARCH_HAS_OPP.patch b/target/linux/ipq806x/patches/0162-PM-OPP-Remove-ARCH_HAS_OPP.patch
deleted file mode 100644
index d07b9e0..0000000
--- a/target/linux/ipq806x/patches/0162-PM-OPP-Remove-ARCH_HAS_OPP.patch
+++ /dev/null
@@ -1,115 +0,0 @@
-From 18e4542f7b02f586d46594977818cd6b24d9cbcb Mon Sep 17 00:00:00 2001
-From: Mark Brown <broonie@linaro.org>
-Date: Fri, 6 Jun 2014 11:36:56 +0100
-Subject: [PATCH 162/182] PM / OPP: Remove ARCH_HAS_OPP
-
-Since the OPP layer is a kernel library which has been converted to be
-directly selectable by its callers rather than user selectable and
-requiring architectures to enable it explicitly the ARCH_HAS_OPP symbol
-has become redundant and can be removed. Do so.
-
-Signed-off-by: Mark Brown <broonie@linaro.org>
-Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
----
- Documentation/power/opp.txt    |    3 ---
- arch/arm/mach-exynos/Kconfig   |    1 -
- arch/arm/mach-highbank/Kconfig |    1 -
- arch/arm/mach-omap2/Kconfig    |    1 -
- arch/arm/mach-shmobile/Kconfig |    2 --
- arch/arm/mach-vexpress/Kconfig |    1 -
- drivers/devfreq/Kconfig        |    1 -
- kernel/power/Kconfig           |    3 ---
- 8 files changed, 13 deletions(-)
-
---- a/Documentation/power/opp.txt
-+++ b/Documentation/power/opp.txt
-@@ -52,9 +52,6 @@ Typical usage of the OPP library is as f
- SoC framework	-> modifies on required cases certain OPPs	-> OPP layer
- 		-> queries to search/retrieve information	->
- 
--Architectures that provide a SoC framework for OPP should select ARCH_HAS_OPP
--to make the OPP layer available.
--
- OPP layer expects each domain to be represented by a unique device pointer. SoC
- framework registers a set of initial OPPs per device with the OPP layer. This
- list is expected to be an optimally small number typically around 5 per device.
---- a/arch/arm/mach-exynos/Kconfig
-+++ b/arch/arm/mach-exynos/Kconfig
-@@ -107,7 +107,6 @@ config SOC_EXYNOS5440
- 	depends on ARCH_EXYNOS5
- 	select ARCH_DMA_ADDR_T_64BIT if ARM_LPAE
- 	select ARCH_HAS_BANDGAP
--	select ARCH_HAS_OPP
- 	select HAVE_ARM_ARCH_TIMER
- 	select AUTO_ZRELADDR
- 	select MIGHT_HAVE_PCI
---- a/arch/arm/mach-highbank/Kconfig
-+++ b/arch/arm/mach-highbank/Kconfig
-@@ -2,7 +2,6 @@ config ARCH_HIGHBANK
- 	bool "Calxeda ECX-1000/2000 (Highbank/Midway)" if ARCH_MULTI_V7
- 	select ARCH_DMA_ADDR_T_64BIT if ARM_LPAE
- 	select ARCH_HAS_HOLES_MEMORYMODEL
--	select ARCH_HAS_OPP
- 	select ARCH_SUPPORTS_BIG_ENDIAN
- 	select ARCH_WANT_OPTIONAL_GPIOLIB
- 	select ARM_AMBA
---- a/arch/arm/mach-omap2/Kconfig
-+++ b/arch/arm/mach-omap2/Kconfig
-@@ -13,7 +13,6 @@ config ARCH_OMAP3
- 	bool "TI OMAP3"
- 	depends on ARCH_MULTI_V7
- 	select ARCH_OMAP2PLUS
--	select ARCH_HAS_OPP
- 	select ARM_CPU_SUSPEND if PM
- 	select CPU_V7
- 	select MULTI_IRQ_HANDLER
---- a/arch/arm/mach-shmobile/Kconfig
-+++ b/arch/arm/mach-shmobile/Kconfig
-@@ -85,7 +85,6 @@ config ARCH_R8A73A4
- 	select CPU_V7
- 	select SH_CLK_CPG
- 	select RENESAS_IRQC
--	select ARCH_HAS_OPP
- 
- config ARCH_R8A7740
- 	bool "R-Mobile A1 (R8A77400)"
-@@ -270,7 +269,6 @@ config MACH_KOELSCH
- config MACH_KZM9G
- 	bool "KZM-A9-GT board"
- 	depends on ARCH_SH73A0
--	select ARCH_HAS_OPP
- 	select ARCH_REQUIRE_GPIOLIB
- 	select REGULATOR_FIXED_VOLTAGE if REGULATOR
- 	select SND_SOC_AK4642 if SND_SIMPLE_CARD
---- a/arch/arm/mach-vexpress/Kconfig
-+++ b/arch/arm/mach-vexpress/Kconfig
-@@ -67,7 +67,6 @@ config ARCH_VEXPRESS_DCSCB
- 
- config ARCH_VEXPRESS_SPC
- 	bool "Versatile Express Serial Power Controller (SPC)"
--	select ARCH_HAS_OPP
- 	select PM_OPP
- 	help
- 	  The TC2 (A15x2 A7x3) versatile express core tile integrates a logic
---- a/drivers/devfreq/Kconfig
-+++ b/drivers/devfreq/Kconfig
-@@ -68,7 +68,6 @@ comment "DEVFREQ Drivers"
- config ARM_EXYNOS4_BUS_DEVFREQ
- 	bool "ARM Exynos4210/4212/4412 Memory Bus DEVFREQ Driver"
- 	depends on (CPU_EXYNOS4210 || SOC_EXYNOS4212 || SOC_EXYNOS4412) && !ARCH_MULTIPLATFORM
--	select ARCH_HAS_OPP
- 	select DEVFREQ_GOV_SIMPLE_ONDEMAND
- 	help
- 	  This adds the DEVFREQ driver for Exynos4210 memory bus (vdd_int)
---- a/kernel/power/Kconfig
-+++ b/kernel/power/Kconfig
-@@ -253,9 +253,6 @@ config APM_EMULATION
- 	  anything, try disabling/enabling this option (or disabling/enabling
- 	  APM in your BIOS).
- 
--config ARCH_HAS_OPP
--	bool
--
- config PM_OPP
- 	bool "Operating Performance Point (OPP) Layer library"
- 	depends on ARCH_HAS_OPP
diff --git a/target/linux/ipq806x/patches/0163-clk-return-probe-defer-when-DT-clock-not-yet-ready.patch b/target/linux/ipq806x/patches/0163-clk-return-probe-defer-when-DT-clock-not-yet-ready.patch
deleted file mode 100644
index 76956d5..0000000
--- a/target/linux/ipq806x/patches/0163-clk-return-probe-defer-when-DT-clock-not-yet-ready.patch
+++ /dev/null
@@ -1,42 +0,0 @@
-From 1ce8667062bc7b8813adf6103ad2374d9dd52fb0 Mon Sep 17 00:00:00 2001
-From: Jean-Francois Moine <moinejf@free.fr>
-Date: Mon, 25 Nov 2013 19:47:04 +0100
-Subject: [PATCH 163/182] clk: return probe defer when DT clock not yet ready
-
-At probe time, a clock device may not be ready when some other device
-wants to use it.
-
-This patch lets the functions clk_get/devm_clk_get return a probe defer
-when the clock is defined in the DT but not yet available.
-
-Signed-off-by: Jean-Francois Moine <moinejf@free.fr>
-Reviewed-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
-Tested-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
-Signed-off-by: Mike Turquette <mturquette@linaro.org>
----
- drivers/clk/clk.c    |    2 +-
- drivers/clk/clkdev.c |    2 ++
- 2 files changed, 3 insertions(+), 1 deletion(-)
-
---- a/drivers/clk/clk.c
-+++ b/drivers/clk/clk.c
-@@ -2507,7 +2507,7 @@ EXPORT_SYMBOL_GPL(of_clk_del_provider);
- struct clk *__of_clk_get_from_provider(struct of_phandle_args *clkspec)
- {
- 	struct of_clk_provider *provider;
--	struct clk *clk = ERR_PTR(-ENOENT);
-+	struct clk *clk = ERR_PTR(-EPROBE_DEFER);
- 
- 	/* Check if we have such a provider in our array */
- 	list_for_each_entry(provider, &of_clk_providers, link) {
---- a/drivers/clk/clkdev.c
-+++ b/drivers/clk/clkdev.c
-@@ -167,6 +167,8 @@ struct clk *clk_get(struct device *dev,
- 		clk = of_clk_get_by_name(dev->of_node, con_id);
- 		if (!IS_ERR(clk))
- 			return clk;
-+		if (PTR_ERR(clk) == -EPROBE_DEFER)
-+			return clk;
- 	}
- 
- 	return clk_get_sys(dev_id, con_id);
diff --git a/target/linux/ipq806x/patches/0164-ARM-Add-Krait-L2-register-accessor-functions.patch b/target/linux/ipq806x/patches/0164-ARM-Add-Krait-L2-register-accessor-functions.patch
deleted file mode 100644
index 1eb450e..0000000
--- a/target/linux/ipq806x/patches/0164-ARM-Add-Krait-L2-register-accessor-functions.patch
+++ /dev/null
@@ -1,133 +0,0 @@
-From d8bf5e13683e027c52476b89b874d50e5281c130 Mon Sep 17 00:00:00 2001
-From: Stephen Boyd <sboyd@codeaurora.org>
-Date: Fri, 18 Oct 2013 16:45:05 -0700
-Subject: [PATCH 164/182] ARM: Add Krait L2 register accessor functions
-
-Krait CPUs have a handful of L2 cache controller registers that
-live behind a cp15 based indirection register. First you program
-the indirection register (l2cpselr) to point the L2 'window'
-register (l2cpdr) at what you want to read/write.  Then you
-read/write the 'window' register to do what you want. The
-l2cpselr register is not banked per-cpu so we must lock around
-accesses to it to prevent other CPUs from re-pointing l2cpdr
-underneath us.
-
-Cc: Mark Rutland <mark.rutland@arm.com>
-Cc: Russell King <linux@arm.linux.org.uk>
-Cc: Courtney Cavin <courtney.cavin@sonymobile.com>
-Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
----
- arch/arm/common/Kconfig                   |    3 ++
- arch/arm/common/Makefile                  |    1 +
- arch/arm/common/krait-l2-accessors.c      |   58 +++++++++++++++++++++++++++++
- arch/arm/include/asm/krait-l2-accessors.h |   20 ++++++++++
- 4 files changed, 82 insertions(+)
- create mode 100644 arch/arm/common/krait-l2-accessors.c
- create mode 100644 arch/arm/include/asm/krait-l2-accessors.h
-
---- a/arch/arm/common/Kconfig
-+++ b/arch/arm/common/Kconfig
-@@ -9,6 +9,9 @@ config DMABOUNCE
- 	bool
- 	select ZONE_DMA
- 
-+config KRAIT_L2_ACCESSORS
-+	bool
-+
- config SHARP_LOCOMO
- 	bool
- 
---- a/arch/arm/common/Makefile
-+++ b/arch/arm/common/Makefile
-@@ -7,6 +7,7 @@ obj-y				+= firmware.o
- obj-$(CONFIG_ICST)		+= icst.o
- obj-$(CONFIG_SA1111)		+= sa1111.o
- obj-$(CONFIG_DMABOUNCE)		+= dmabounce.o
-+obj-$(CONFIG_KRAIT_L2_ACCESSORS) += krait-l2-accessors.o
- obj-$(CONFIG_SHARP_LOCOMO)	+= locomo.o
- obj-$(CONFIG_SHARP_PARAM)	+= sharpsl_param.o
- obj-$(CONFIG_SHARP_SCOOP)	+= scoop.o
---- /dev/null
-+++ b/arch/arm/common/krait-l2-accessors.c
-@@ -0,0 +1,58 @@
-+/*
-+ * Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 and
-+ * only version 2 as published by the Free Software Foundation.
-+ *
-+ * 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/spinlock.h>
-+#include <linux/export.h>
-+
-+#include <asm/barrier.h>
-+#include <asm/krait-l2-accessors.h>
-+
-+static DEFINE_RAW_SPINLOCK(krait_l2_lock);
-+
-+void krait_set_l2_indirect_reg(u32 addr, u32 val)
-+{
-+	unsigned long flags;
-+
-+	raw_spin_lock_irqsave(&krait_l2_lock, flags);
-+	/*
-+	 * Select the L2 window by poking l2cpselr, then write to the window
-+	 * via l2cpdr.
-+	 */
-+	asm volatile ("mcr p15, 3, %0, c15, c0, 6 @ l2cpselr" : : "r" (addr));
-+	isb();
-+	asm volatile ("mcr p15, 3, %0, c15, c0, 7 @ l2cpdr" : : "r" (val));
-+	isb();
-+
-+	raw_spin_unlock_irqrestore(&krait_l2_lock, flags);
-+}
-+EXPORT_SYMBOL(krait_set_l2_indirect_reg);
-+
-+u32 krait_get_l2_indirect_reg(u32 addr)
-+{
-+	u32 val;
-+	unsigned long flags;
-+
-+	raw_spin_lock_irqsave(&krait_l2_lock, flags);
-+	/*
-+	 * Select the L2 window by poking l2cpselr, then read from the window
-+	 * via l2cpdr.
-+	 */
-+	asm volatile ("mcr p15, 3, %0, c15, c0, 6 @ l2cpselr" : : "r" (addr));
-+	isb();
-+	asm volatile ("mrc p15, 3, %0, c15, c0, 7 @ l2cpdr" : "=r" (val));
-+
-+	raw_spin_unlock_irqrestore(&krait_l2_lock, flags);
-+
-+	return val;
-+}
-+EXPORT_SYMBOL(krait_get_l2_indirect_reg);
---- /dev/null
-+++ b/arch/arm/include/asm/krait-l2-accessors.h
-@@ -0,0 +1,20 @@
-+/*
-+ * Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 and
-+ * only version 2 as published by the Free Software Foundation.
-+ *
-+ * 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 __ASMARM_KRAIT_L2_ACCESSORS_H
-+#define __ASMARM_KRAIT_L2_ACCESSORS_H
-+
-+extern void krait_set_l2_indirect_reg(u32 addr, u32 val);
-+extern u32 krait_get_l2_indirect_reg(u32 addr);
-+
-+#endif
diff --git a/target/linux/ipq806x/patches/0165-clk-qcom-Add-support-for-muxes-dividers-and-mux-divi.patch b/target/linux/ipq806x/patches/0165-clk-qcom-Add-support-for-muxes-dividers-and-mux-divi.patch
deleted file mode 100644
index fa7b4e9..0000000
--- a/target/linux/ipq806x/patches/0165-clk-qcom-Add-support-for-muxes-dividers-and-mux-divi.patch
+++ /dev/null
@@ -1,652 +0,0 @@
-From 151d7e91baaa4016ba687b80e8f7ccead62d6c72 Mon Sep 17 00:00:00 2001
-From: Stephen Boyd <sboyd@codeaurora.org>
-Date: Tue, 25 Mar 2014 13:37:55 -0700
-Subject: [PATCH 165/182] clk: qcom: Add support for muxes, dividers, and mux
- dividers
-
-The Krait CPU clocks are made up of muxes and dividers with a
-handful of sources. Add a set of clk_ops that allow us to
-configure these clocks so we can support CPU frequency scaling on
-Krait CPUs.
-
-Based on code originally written by Saravana Kannan.
-
-Cc: Saravana Kannan <skannan@codeaurora.org>
-Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
----
- drivers/clk/qcom/Makefile           |    1 +
- drivers/clk/qcom/clk-generic.c      |  405 +++++++++++++++++++++++++++++++++++
- include/linux/clk/msm-clk-generic.h |  208 ++++++++++++++++++
- 3 files changed, 614 insertions(+)
- create mode 100644 drivers/clk/qcom/clk-generic.c
- create mode 100644 include/linux/clk/msm-clk-generic.h
-
---- a/drivers/clk/qcom/Makefile
-+++ b/drivers/clk/qcom/Makefile
-@@ -6,6 +6,7 @@ clk-qcom-y += clk-pll.o
- clk-qcom-y += clk-rcg.o
- clk-qcom-y += clk-rcg2.o
- clk-qcom-y += clk-branch.o
-+clk-qcom-y += clk-generic.o
- clk-qcom-y += reset.o
- 
- obj-$(CONFIG_IPQ_GCC_806X) += gcc-ipq806x.o
---- /dev/null
-+++ b/drivers/clk/qcom/clk-generic.c
-@@ -0,0 +1,405 @@
-+/*
-+ * Copyright (c) 2014, The Linux Foundation. All rights reserved.
-+ *
-+ * This software is licensed under the terms of the GNU General Public
-+ * License version 2, as published by the Free Software Foundation, and
-+ * may be copied, distributed, and modified under those terms.
-+ *
-+ * 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/kernel.h>
-+#include <linux/export.h>
-+#include <linux/bug.h>
-+#include <linux/err.h>
-+#include <linux/clk-provider.h>
-+#include <linux/clk/msm-clk-generic.h>
-+
-+
-+/* ==================== Mux clock ==================== */
-+
-+static int mux_set_parent(struct clk_hw *hw, u8 sel)
-+{
-+	struct mux_clk *mux = to_mux_clk(hw);
-+
-+	if (mux->parent_map)
-+		sel = mux->parent_map[sel];
-+
-+	return mux->ops->set_mux_sel(mux, sel);
-+}
-+
-+static u8 mux_get_parent(struct clk_hw *hw)
-+{
-+	struct mux_clk *mux = to_mux_clk(hw);
-+	int num_parents = __clk_get_num_parents(hw->clk);
-+	int i;
-+	u8 sel;
-+
-+	sel = mux->ops->get_mux_sel(mux);
-+	if (mux->parent_map) {
-+		for (i = 0; i < num_parents; i++)
-+			if (sel == mux->parent_map[i])
-+				return i;
-+		WARN(1, "Can't find parent\n");
-+		return -EINVAL;
-+	}
-+
-+	return sel;
-+}
-+
-+static int mux_enable(struct clk_hw *hw)
-+{
-+	struct mux_clk *mux = to_mux_clk(hw);
-+	if (mux->ops->enable)
-+		return mux->ops->enable(mux);
-+	return 0;
-+}
-+
-+static void mux_disable(struct clk_hw *hw)
-+{
-+	struct mux_clk *mux = to_mux_clk(hw);
-+	if (mux->ops->disable)
-+		return mux->ops->disable(mux);
-+}
-+
-+static struct clk *mux_get_safe_parent(struct clk_hw *hw)
-+{
-+	int i;
-+	struct mux_clk *mux = to_mux_clk(hw);
-+	int num_parents = __clk_get_num_parents(hw->clk);
-+
-+	if (!mux->has_safe_parent)
-+		return NULL;
-+
-+	i = mux->safe_sel;
-+	if (mux->parent_map)
-+		for (i = 0; i < num_parents; i++)
-+			if (mux->safe_sel == mux->parent_map[i])
-+				break;
-+
-+	return clk_get_parent_by_index(hw->clk, i);
-+}
-+
-+const struct clk_ops clk_ops_gen_mux = {
-+	.enable = mux_enable,
-+	.disable = mux_disable,
-+	.set_parent = mux_set_parent,
-+	.get_parent = mux_get_parent,
-+	.determine_rate = __clk_mux_determine_rate,
-+	.get_safe_parent = mux_get_safe_parent,
-+};
-+EXPORT_SYMBOL_GPL(clk_ops_gen_mux);
-+
-+/* ==================== Divider clock ==================== */
-+
-+static long __div_round_rate(struct div_data *data, unsigned long rate,
-+	struct clk *parent, unsigned int *best_div, unsigned long *best_prate,
-+	bool set_parent)
-+{
-+	unsigned int div, min_div, max_div, _best_div = 1;
-+	unsigned long prate, _best_prate = 0, rrate = 0, req_prate, actual_rate;
-+	unsigned int numer;
-+
-+	rate = max(rate, 1UL);
-+
-+	min_div = max(data->min_div, 1U);
-+	max_div = min(data->max_div, (unsigned int) (ULONG_MAX / rate));
-+
-+	/*
-+	 * div values are doubled for half dividers.
-+	 * Adjust for that by picking a numer of 2.
-+	 */
-+	numer = data->is_half_divider ? 2 : 1;
-+
-+	if (!set_parent) {
-+		prate = *best_prate * numer;
-+		div = DIV_ROUND_UP(prate, rate);
-+		div = clamp(1U, div, max_div);
-+		if (best_div)
-+			*best_div = div;
-+		return mult_frac(*best_prate, numer, div);
-+	}
-+
-+	for (div = min_div; div <= max_div; div++) {
-+		req_prate = mult_frac(rate, div, numer);
-+		prate = __clk_round_rate(parent, req_prate);
-+		if (IS_ERR_VALUE(prate))
-+			break;
-+
-+		actual_rate = mult_frac(prate, numer, div);
-+		if (is_better_rate(rate, rrate, actual_rate)) {
-+			rrate = actual_rate;
-+			_best_div = div;
-+			_best_prate = prate;
-+		}
-+
-+		/*
-+		 * Trying higher dividers is only going to ask the parent for
-+		 * a higher rate. If it can't even output a rate higher than
-+		 * the one we request for this divider, the parent is not
-+		 * going to be able to output an even higher rate required
-+		 * for a higher divider. So, stop trying higher dividers.
-+		 */
-+		if (actual_rate < rate)
-+			break;
-+
-+		if (rrate <= rate)
-+			break;
-+	}
-+
-+	if (!rrate)
-+		return -EINVAL;
-+	if (best_div)
-+		*best_div = _best_div;
-+	if (best_prate)
-+		*best_prate = _best_prate;
-+
-+	return rrate;
-+}
-+
-+static long div_round_rate(struct clk_hw *hw, unsigned long rate,
-+			   unsigned long *parent_rate)
-+{
-+	struct div_clk *d = to_div_clk(hw);
-+	bool set_parent = __clk_get_flags(hw->clk) & CLK_SET_RATE_PARENT;
-+
-+	return __div_round_rate(&d->data, rate, __clk_get_parent(hw->clk),
-+				NULL, parent_rate, set_parent);
-+}
-+
-+static int div_set_rate(struct clk_hw *hw, unsigned long rate, unsigned long
-+			parent_rate)
-+{
-+	struct div_clk *d = to_div_clk(hw);
-+	int div, rc = 0;
-+	struct div_data *data = &d->data;
-+
-+	div = parent_rate / rate;
-+	if (div != data->div)
-+		rc = d->ops->set_div(d, div);
-+	data->div = div;
-+
-+	return rc;
-+}
-+
-+static int div_enable(struct clk_hw *hw)
-+{
-+	struct div_clk *d = to_div_clk(hw);
-+	if (d->ops && d->ops->enable)
-+		return d->ops->enable(d);
-+	return 0;
-+}
-+
-+static void div_disable(struct clk_hw *hw)
-+{
-+	struct div_clk *d = to_div_clk(hw);
-+	if (d->ops && d->ops->disable)
-+		return d->ops->disable(d);
-+}
-+
-+static unsigned long div_recalc_rate(struct clk_hw *hw, unsigned long prate)
-+{
-+	struct div_clk *d = to_div_clk(hw);
-+	unsigned int div = d->data.div;
-+
-+	if (d->ops && d->ops->get_div)
-+		div = max(d->ops->get_div(d), 1);
-+	div = max(div, 1U);
-+
-+	if (!d->ops || !d->ops->set_div)
-+		d->data.min_div = d->data.max_div = div;
-+	d->data.div = div;
-+
-+	return prate / div;
-+}
-+
-+const struct clk_ops clk_ops_div = {
-+	.enable = div_enable,
-+	.disable = div_disable,
-+	.round_rate = div_round_rate,
-+	.set_rate = div_set_rate,
-+	.recalc_rate = div_recalc_rate,
-+};
-+EXPORT_SYMBOL_GPL(clk_ops_div);
-+
-+/* ==================== Mux_div clock ==================== */
-+
-+static int mux_div_clk_enable(struct clk_hw *hw)
-+{
-+	struct mux_div_clk *md = to_mux_div_clk(hw);
-+
-+	if (md->ops->enable)
-+		return md->ops->enable(md);
-+	return 0;
-+}
-+
-+static void mux_div_clk_disable(struct clk_hw *hw)
-+{
-+	struct mux_div_clk *md = to_mux_div_clk(hw);
-+
-+	if (md->ops->disable)
-+		return md->ops->disable(md);
-+}
-+
-+static long __mux_div_round_rate(struct clk_hw *hw, unsigned long rate,
-+	struct clk **best_parent, int *best_div, unsigned long *best_prate)
-+{
-+	struct mux_div_clk *md = to_mux_div_clk(hw);
-+	unsigned int i;
-+	unsigned long rrate, best = 0, _best_div = 0, _best_prate = 0;
-+	struct clk *_best_parent = 0;
-+	int num_parents = __clk_get_num_parents(hw->clk);
-+	bool set_parent = __clk_get_flags(hw->clk) & CLK_SET_RATE_PARENT;
-+
-+	for (i = 0; i < num_parents; i++) {
-+		int div;
-+		unsigned long prate;
-+		struct clk *p = clk_get_parent_by_index(hw->clk, i);
-+
-+		rrate = __div_round_rate(&md->data, rate, p, &div, &prate,
-+				set_parent);
-+
-+		if (is_better_rate(rate, best, rrate)) {
-+			best = rrate;
-+			_best_div = div;
-+			_best_prate = prate;
-+			_best_parent = p;
-+		}
-+
-+		if (rate <= rrate)
-+			break;
-+	}
-+
-+	if (best_div)
-+		*best_div = _best_div;
-+	if (best_prate)
-+		*best_prate = _best_prate;
-+	if (best_parent)
-+		*best_parent = _best_parent;
-+
-+	if (best)
-+		return best;
-+	return -EINVAL;
-+}
-+
-+static long mux_div_clk_round_rate(struct clk_hw *hw, unsigned long rate,
-+				   unsigned long *parent_rate)
-+{
-+	return __mux_div_round_rate(hw, rate, NULL, NULL, parent_rate);
-+}
-+
-+/* requires enable lock to be held */
-+static int __set_src_div(struct mux_div_clk *md, u8 src_sel, u32 div)
-+{
-+	int rc;
-+
-+	rc = md->ops->set_src_div(md, src_sel, div);
-+	if (!rc) {
-+		md->data.div = div;
-+		md->src_sel = src_sel;
-+	}
-+
-+	return rc;
-+}
-+
-+/* Must be called after handoff to ensure parent clock rates are initialized */
-+static int safe_parent_init_once(struct clk_hw *hw)
-+{
-+	unsigned long rrate;
-+	u32 best_div;
-+	struct clk *best_parent;
-+	struct mux_div_clk *md = to_mux_div_clk(hw);
-+
-+	if (IS_ERR(md->safe_parent))
-+		return -EINVAL;
-+	if (!md->safe_freq || md->safe_parent)
-+		return 0;
-+
-+	rrate = __mux_div_round_rate(hw, md->safe_freq, &best_parent,
-+			&best_div, NULL);
-+
-+	if (rrate == md->safe_freq) {
-+		md->safe_div = best_div;
-+		md->safe_parent = best_parent;
-+	} else {
-+		md->safe_parent = ERR_PTR(-EINVAL);
-+		return -EINVAL;
-+	}
-+	return 0;
-+}
-+
-+static int
-+__mux_div_clk_set_rate_and_parent(struct clk_hw *hw, u8 index, u32 div)
-+{
-+	struct mux_div_clk *md = to_mux_div_clk(hw);
-+	int rc;
-+
-+	rc = safe_parent_init_once(hw);
-+	if (rc)
-+		return rc;
-+
-+	return __set_src_div(md, index, div);
-+}
-+
-+static int mux_div_clk_set_rate_and_parent(struct clk_hw *hw,
-+		unsigned long rate, unsigned long parent_rate, u8 index)
-+{
-+	return __mux_div_clk_set_rate_and_parent(hw, index, parent_rate / rate);
-+}
-+
-+static int mux_div_clk_set_rate(struct clk_hw *hw,
-+		unsigned long rate, unsigned long parent_rate)
-+{
-+	struct mux_div_clk *md = to_mux_div_clk(hw);
-+	return __mux_div_clk_set_rate_and_parent(hw, md->src_sel,
-+			parent_rate / rate);
-+}
-+
-+static int mux_div_clk_set_parent(struct clk_hw *hw, u8 index)
-+{
-+	struct mux_div_clk *md = to_mux_div_clk(hw);
-+	return __mux_div_clk_set_rate_and_parent(hw, md->parent_map[index],
-+			md->data.div);
-+}
-+
-+static u8 mux_div_clk_get_parent(struct clk_hw *hw)
-+{
-+	struct mux_div_clk *md = to_mux_div_clk(hw);
-+	int num_parents = __clk_get_num_parents(hw->clk);
-+	u32 i, div, sel;
-+
-+	md->ops->get_src_div(md, &sel, &div);
-+	md->src_sel = sel;
-+
-+	for (i = 0; i < num_parents; i++)
-+		if (sel == md->parent_map[i])
-+			return i;
-+	WARN(1, "Can't find parent\n");
-+	return -EINVAL;
-+}
-+
-+static unsigned long
-+mux_div_clk_recalc_rate(struct clk_hw *hw, unsigned long prate)
-+{
-+	struct mux_div_clk *md = to_mux_div_clk(hw);
-+	u32 div, sel;
-+
-+	md->ops->get_src_div(md, &sel, &div);
-+
-+	return prate / div;
-+}
-+
-+const struct clk_ops clk_ops_mux_div_clk = {
-+	.enable = mux_div_clk_enable,
-+	.disable = mux_div_clk_disable,
-+	.set_rate_and_parent = mux_div_clk_set_rate_and_parent,
-+	.set_rate = mux_div_clk_set_rate,
-+	.set_parent = mux_div_clk_set_parent,
-+	.round_rate = mux_div_clk_round_rate,
-+	.get_parent = mux_div_clk_get_parent,
-+	.recalc_rate = mux_div_clk_recalc_rate,
-+};
-+EXPORT_SYMBOL_GPL(clk_ops_mux_div_clk);
---- /dev/null
-+++ b/include/linux/clk/msm-clk-generic.h
-@@ -0,0 +1,208 @@
-+/*
-+ * Copyright (c) 2014, The Linux Foundation. All rights reserved.
-+ *
-+ * This software is licensed under the terms of the GNU General Public
-+ * License version 2, as published by the Free Software Foundation, and
-+ * may be copied, distributed, and modified under those terms.
-+ *
-+ * 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 __QCOM_CLK_GENERIC_H__
-+#define __QCOM_CLK_GENERIC_H__
-+
-+#include <linux/err.h>
-+#include <linux/clk-provider.h>
-+
-+static inline bool is_better_rate(unsigned long req, unsigned long best,
-+				  unsigned long new)
-+{
-+	if (IS_ERR_VALUE(new))
-+		return false;
-+
-+	return (req <= new && new < best) || (best < req && best < new);
-+}
-+
-+/* ==================== Mux clock ==================== */
-+
-+struct mux_clk;
-+
-+struct clk_mux_ops {
-+	int (*set_mux_sel)(struct mux_clk *clk, int sel);
-+	int (*get_mux_sel)(struct mux_clk *clk);
-+
-+	/* Optional */
-+	bool (*is_enabled)(struct mux_clk *clk);
-+	int (*enable)(struct mux_clk *clk);
-+	void (*disable)(struct mux_clk *clk);
-+};
-+
-+struct mux_clk {
-+	/* Parents in decreasing order of preference for obtaining rates. */
-+	u8 		*parent_map;
-+	bool		has_safe_parent;
-+	u8		safe_sel;
-+	const struct clk_mux_ops *ops;
-+
-+	/* Fields not used by helper function. */
-+	void __iomem 	*base;
-+	u32		offset;
-+	u32		en_offset;
-+	int		en_reg;
-+	u32		mask;
-+	u32		shift;
-+	u32		en_mask;
-+	void		*priv;
-+
-+	struct clk_hw	hw;
-+};
-+
-+static inline struct mux_clk *to_mux_clk(struct clk_hw *hw)
-+{
-+	return container_of(hw, struct mux_clk, hw);
-+}
-+
-+extern const struct clk_ops clk_ops_gen_mux;
-+
-+/* ==================== Divider clock ==================== */
-+
-+struct div_clk;
-+
-+struct clk_div_ops {
-+	int (*set_div)(struct div_clk *clk, int div);
-+	int (*get_div)(struct div_clk *clk);
-+	bool (*is_enabled)(struct div_clk *clk);
-+	int (*enable)(struct div_clk *clk);
-+	void (*disable)(struct div_clk *clk);
-+};
-+
-+struct div_data {
-+	unsigned int div;
-+	unsigned int min_div;
-+	unsigned int max_div;
-+	/*
-+	 * Indicate whether this divider clock supports half-interger divider.
-+	 * If it is, all the min_div and max_div have been doubled. It means
-+	 * they are 2*N.
-+	 */
-+	bool is_half_divider;
-+};
-+
-+struct div_clk {
-+	struct div_data data;
-+
-+	/* Optional */
-+	const struct clk_div_ops *ops;
-+
-+	/* Fields not used by helper function. */
-+	void __iomem 	*base;
-+	u32		offset;
-+	u32		mask;
-+	u32		shift;
-+	u32		en_mask;
-+	void		*priv;
-+	struct clk_hw	hw;
-+};
-+
-+static inline struct div_clk *to_div_clk(struct clk_hw *hw)
-+{
-+	return container_of(hw, struct div_clk, hw);
-+}
-+
-+extern const struct clk_ops clk_ops_div;
-+
-+#define DEFINE_FIXED_DIV_CLK(clk_name, _div, _parent) \
-+static struct div_clk clk_name = {	\
-+	.data = {				\
-+		.max_div = _div,		\
-+		.min_div = _div,		\
-+		.div = _div,			\
-+	},					\
-+	.hw.init = &(struct clk_init_data){ \
-+		.parent_names = (const char *[]){ _parent }, \
-+		.num_parents = 1,		\
-+		.name = #clk_name,		\
-+		.ops = &clk_ops_div,		\
-+		.flags = CLK_SET_RATE_PARENT,	\
-+	}					\
-+}
-+
-+/* ==================== Mux Div clock ==================== */
-+
-+struct mux_div_clk;
-+
-+/*
-+ * struct mux_div_ops
-+ * the enable and disable ops are optional.
-+ */
-+
-+struct mux_div_ops {
-+	int (*set_src_div)(struct mux_div_clk *, u32 src_sel, u32 div);
-+	void (*get_src_div)(struct mux_div_clk *, u32 *src_sel, u32 *div);
-+	int (*enable)(struct mux_div_clk *);
-+	void (*disable)(struct mux_div_clk *);
-+	bool (*is_enabled)(struct mux_div_clk *);
-+};
-+
-+/*
-+ * struct mux_div_clk - combined mux/divider clock
-+ * @priv
-+		parameters needed by ops
-+ * @safe_freq
-+		when switching rates from A to B, the mux div clock will
-+		instead switch from A -> safe_freq -> B. This allows the
-+		mux_div clock to change rates while enabled, even if this
-+		behavior is not supported by the parent clocks.
-+
-+		If changing the rate of parent A also causes the rate of
-+		parent B to change, then safe_freq must be defined.
-+
-+		safe_freq is expected to have a source clock which is always
-+		on and runs at only one rate.
-+ * @parents
-+		list of parents and mux indicies
-+ * @ops
-+		function pointers for hw specific operations
-+ * @src_sel
-+		the mux index which will be used if the clock is enabled.
-+ */
-+
-+struct mux_div_clk {
-+	/* Required parameters */
-+	const struct mux_div_ops	*ops;
-+	struct div_data			data;
-+	u8				*parent_map;
-+
-+	struct clk_hw			hw;
-+
-+	/* Internal */
-+	u32				src_sel;
-+
-+	/* Optional parameters */
-+	void				*priv;
-+	void __iomem			*base;
-+	u32				div_mask;
-+	u32				div_offset;
-+	u32				div_shift;
-+	u32				src_mask;
-+	u32				src_offset;
-+	u32				src_shift;
-+	u32				en_mask;
-+	u32				en_offset;
-+
-+	u32				safe_div;
-+	struct clk			*safe_parent;
-+	unsigned long			safe_freq;
-+};
-+
-+static inline struct mux_div_clk *to_mux_div_clk(struct clk_hw *hw)
-+{
-+	return container_of(hw, struct mux_div_clk, hw);
-+}
-+
-+extern const struct clk_ops clk_ops_mux_div_clk;
-+
-+#endif
diff --git a/target/linux/ipq806x/patches/0166-clk-qcom-Add-support-for-High-Frequency-PLLs-HFPLLs.patch b/target/linux/ipq806x/patches/0166-clk-qcom-Add-support-for-High-Frequency-PLLs-HFPLLs.patch
deleted file mode 100644
index 037c6c4..0000000
--- a/target/linux/ipq806x/patches/0166-clk-qcom-Add-support-for-High-Frequency-PLLs-HFPLLs.patch
+++ /dev/null
@@ -1,348 +0,0 @@
-From 8a51ac2a4e36505e1ff82b0e49fd8b2edd0b7695 Mon Sep 17 00:00:00 2001
-From: Stephen Boyd <sboyd@codeaurora.org>
-Date: Wed, 18 Jun 2014 14:15:58 -0700
-Subject: [PATCH 166/182] clk: qcom: Add support for High-Frequency PLLs
- (HFPLLs)
-
-HFPLLs are the main frequency source for Krait CPU clocks. Add
-support for changing the rate of these PLLs.
-
-Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
----
- drivers/clk/qcom/Makefile    |    1 +
- drivers/clk/qcom/clk-hfpll.c |  260 ++++++++++++++++++++++++++++++++++++++++++
- drivers/clk/qcom/clk-hfpll.h |   54 +++++++++
- 3 files changed, 315 insertions(+)
- create mode 100644 drivers/clk/qcom/clk-hfpll.c
- create mode 100644 drivers/clk/qcom/clk-hfpll.h
-
---- a/drivers/clk/qcom/Makefile
-+++ b/drivers/clk/qcom/Makefile
-@@ -7,6 +7,7 @@ clk-qcom-y += clk-rcg.o
- clk-qcom-y += clk-rcg2.o
- clk-qcom-y += clk-branch.o
- clk-qcom-y += clk-generic.o
-+clk-qcom-y += clk-hfpll.o
- clk-qcom-y += reset.o
- 
- obj-$(CONFIG_IPQ_GCC_806X) += gcc-ipq806x.o
---- /dev/null
-+++ b/drivers/clk/qcom/clk-hfpll.c
-@@ -0,0 +1,260 @@
-+/*
-+ * Copyright (c) 2013-2014, The Linux Foundation. All rights reserved.
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 and
-+ * only version 2 as published by the Free Software Foundation.
-+ *
-+ * 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/kernel.h>
-+#include <linux/module.h>
-+#include <linux/init.h>
-+#include <linux/regmap.h>
-+#include <linux/delay.h>
-+#include <linux/err.h>
-+#include <linux/clk-provider.h>
-+#include <linux/spinlock.h>
-+
-+#include "clk-regmap.h"
-+#include "clk-hfpll.h"
-+
-+#define PLL_OUTCTRL	BIT(0)
-+#define PLL_BYPASSNL	BIT(1)
-+#define PLL_RESET_N	BIT(2)
-+
-+/* Initialize a HFPLL at a given rate and enable it. */
-+static void __clk_hfpll_init_once(struct clk_hw *hw)
-+{
-+	struct clk_hfpll *h = to_clk_hfpll(hw);
-+	struct hfpll_data const *hd = h->d;
-+	struct regmap *regmap = h->clkr.regmap;
-+
-+	if (likely(h->init_done))
-+		return;
-+
-+	/* Configure PLL parameters for integer mode. */
-+	if (hd->config_val)
-+		regmap_write(regmap, hd->config_reg, hd->config_val);
-+	regmap_write(regmap, hd->m_reg, 0);
-+	regmap_write(regmap, hd->n_reg, 1);
-+
-+	if (hd->user_reg) {
-+		u32 regval = hd->user_val;
-+		unsigned long rate;
-+
-+		rate = __clk_get_rate(hw->clk);
-+
-+		/* Pick the right VCO. */
-+		if (hd->user_vco_mask && rate > hd->low_vco_max_rate)
-+			regval |= hd->user_vco_mask;
-+		regmap_write(regmap, hd->user_reg, regval);
-+	}
-+
-+	if (hd->droop_reg)
-+		regmap_write(regmap, hd->droop_reg, hd->droop_val);
-+
-+	h->init_done = true;
-+}
-+
-+static void __clk_hfpll_enable(struct clk_hw *hw)
-+{
-+	struct clk_hfpll *h = to_clk_hfpll(hw);
-+	struct hfpll_data const *hd = h->d;
-+	struct regmap *regmap = h->clkr.regmap;
-+	u32 val;
-+
-+	__clk_hfpll_init_once(hw);
-+
-+	/* Disable PLL bypass mode. */
-+	regmap_update_bits(regmap, hd->mode_reg, PLL_BYPASSNL, PLL_BYPASSNL);
-+
-+	/*
-+	 * H/W requires a 5us delay between disabling the bypass and
-+	 * de-asserting the reset. Delay 10us just to be safe.
-+	 */
-+	mb();
-+	udelay(10);
-+
-+	/* De-assert active-low PLL reset. */
-+	regmap_update_bits(regmap, hd->mode_reg, PLL_RESET_N, PLL_RESET_N);
-+
-+	/* Wait for PLL to lock. */
-+	if (hd->status_reg) {
-+		do {
-+			regmap_read(regmap, hd->status_reg, &val);
-+		} while (!(val & BIT(hd->lock_bit)));
-+	} else {
-+		mb();
-+		udelay(60);
-+	}
-+
-+	/* Enable PLL output. */
-+	regmap_update_bits(regmap, hd->mode_reg, PLL_OUTCTRL, PLL_OUTCTRL);
-+
-+	/* Make sure the enable is done before returning. */
-+	mb();
-+}
-+
-+/* Enable an already-configured HFPLL. */
-+static int clk_hfpll_enable(struct clk_hw *hw)
-+{
-+	unsigned long flags;
-+	struct clk_hfpll *h = to_clk_hfpll(hw);
-+	struct hfpll_data const *hd = h->d;
-+	struct regmap *regmap = h->clkr.regmap;
-+	u32 mode;
-+
-+	spin_lock_irqsave(&h->lock, flags);
-+	regmap_read(regmap, hd->mode_reg, &mode);
-+	if (!(mode & (PLL_BYPASSNL | PLL_RESET_N | PLL_OUTCTRL)))
-+		__clk_hfpll_enable(hw);
-+	spin_unlock_irqrestore(&h->lock, flags);
-+
-+	return 0;
-+}
-+
-+static void __clk_hfpll_disable(struct clk_hw *hw)
-+{
-+	struct clk_hfpll *h = to_clk_hfpll(hw);
-+	struct hfpll_data const *hd = h->d;
-+	struct regmap *regmap = h->clkr.regmap;
-+
-+	/*
-+	 * Disable the PLL output, disable test mode, enable the bypass mode,
-+	 * and assert the reset.
-+	 */
-+	regmap_update_bits(regmap, hd->mode_reg,
-+			PLL_BYPASSNL | PLL_RESET_N | PLL_OUTCTRL, 0);
-+}
-+
-+static void clk_hfpll_disable(struct clk_hw *hw)
-+{
-+	struct clk_hfpll *h = to_clk_hfpll(hw);
-+	unsigned long flags;
-+
-+	spin_lock_irqsave(&h->lock, flags);
-+	__clk_hfpll_disable(hw);
-+	spin_unlock_irqrestore(&h->lock, flags);
-+}
-+
-+static long clk_hfpll_round_rate(struct clk_hw *hw, unsigned long rate,
-+				 unsigned long *parent_rate)
-+{
-+	struct clk_hfpll *h = to_clk_hfpll(hw);
-+	struct hfpll_data const *hd = h->d;
-+	unsigned long rrate;
-+
-+	rate = clamp(rate, hd->min_rate, hd->max_rate);
-+
-+	rrate = DIV_ROUND_UP(rate, *parent_rate) * *parent_rate;
-+	if (rrate > hd->max_rate)
-+		rrate -= *parent_rate;
-+
-+	return rrate;
-+}
-+
-+/*
-+ * For optimization reasons, assumes no downstream clocks are actively using
-+ * it.
-+ */
-+static int clk_hfpll_set_rate(struct clk_hw *hw, unsigned long rate,
-+			      unsigned long parent_rate)
-+{
-+	struct clk_hfpll *h = to_clk_hfpll(hw);
-+	struct hfpll_data const *hd = h->d;
-+	struct regmap *regmap = h->clkr.regmap;
-+	unsigned long flags;
-+	u32 l_val, val;
-+	bool enabled;
-+
-+	l_val = rate / parent_rate;
-+
-+	spin_lock_irqsave(&h->lock, flags);
-+
-+	enabled = __clk_is_enabled(hw->clk);
-+	if (enabled)
-+		__clk_hfpll_disable(hw);
-+
-+	/* Pick the right VCO. */
-+	if (hd->user_reg && hd->user_vco_mask) {
-+		regmap_read(regmap, hd->user_reg, &val);
-+		if (rate <= hd->low_vco_max_rate)
-+			val &= ~hd->user_vco_mask;
-+		else
-+			val |= hd->user_vco_mask;
-+		regmap_write(regmap, hd->user_reg, val);
-+	}
-+
-+	regmap_write(regmap, hd->l_reg, l_val);
-+
-+	if (enabled)
-+		__clk_hfpll_enable(hw);
-+
-+	spin_unlock_irqrestore(&h->lock, flags);
-+
-+	return 0;
-+}
-+
-+static unsigned long clk_hfpll_recalc_rate(struct clk_hw *hw,
-+					   unsigned long parent_rate)
-+{
-+	struct clk_hfpll *h = to_clk_hfpll(hw);
-+	struct hfpll_data const *hd = h->d;
-+	struct regmap *regmap = h->clkr.regmap;
-+	u32 l_val;
-+
-+	regmap_read(regmap, hd->l_reg, &l_val);
-+
-+	return l_val * parent_rate;
-+}
-+
-+static void clk_hfpll_init(struct clk_hw *hw)
-+{
-+	struct clk_hfpll *h = to_clk_hfpll(hw);
-+	struct hfpll_data const *hd = h->d;
-+	struct regmap *regmap = h->clkr.regmap;
-+	u32 mode, status;
-+
-+	regmap_read(regmap, hd->mode_reg, &mode);
-+	if (mode != (PLL_BYPASSNL | PLL_RESET_N | PLL_OUTCTRL)) {
-+		__clk_hfpll_init_once(hw);
-+		return;
-+	}
-+
-+	if (hd->status_reg) {
-+		regmap_read(regmap, hd->status_reg, &status);
-+		if (!(status & BIT(hd->lock_bit))) {
-+			WARN(1, "HFPLL %s is ON, but not locked!\n",
-+					__clk_get_name(hw->clk));
-+			clk_hfpll_disable(hw);
-+			__clk_hfpll_init_once(hw);
-+		}
-+	}
-+}
-+
-+static int hfpll_is_enabled(struct clk_hw *hw)
-+{
-+	struct clk_hfpll *h = to_clk_hfpll(hw);
-+	struct hfpll_data const *hd = h->d;
-+	struct regmap *regmap = h->clkr.regmap;
-+	u32 mode;
-+
-+	regmap_read(regmap, hd->mode_reg, &mode);
-+	mode &= 0x7;
-+	return mode == (PLL_BYPASSNL | PLL_RESET_N | PLL_OUTCTRL);
-+}
-+
-+const struct clk_ops clk_ops_hfpll = {
-+	.enable = clk_hfpll_enable,
-+	.disable = clk_hfpll_disable,
-+	.is_enabled = hfpll_is_enabled,
-+	.round_rate = clk_hfpll_round_rate,
-+	.set_rate = clk_hfpll_set_rate,
-+	.recalc_rate = clk_hfpll_recalc_rate,
-+	.init = clk_hfpll_init,
-+};
-+EXPORT_SYMBOL_GPL(clk_ops_hfpll);
---- /dev/null
-+++ b/drivers/clk/qcom/clk-hfpll.h
-@@ -0,0 +1,54 @@
-+/*
-+ * Copyright (c) 2013-2014, The Linux Foundation. All rights reserved.
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 and
-+ * only version 2 as published by the Free Software Foundation.
-+ *
-+ * 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 __QCOM_CLK_HFPLL_H__
-+#define __QCOM_CLK_HFPLL_H__
-+
-+#include <linux/clk-provider.h>
-+#include <linux/spinlock.h>
-+#include "clk-regmap.h"
-+
-+struct hfpll_data {
-+	u32 mode_reg;
-+	u32 l_reg;
-+	u32 m_reg;
-+	u32 n_reg;
-+	u32 user_reg;
-+	u32 droop_reg;
-+	u32 config_reg;
-+	u32 status_reg;
-+	u8  lock_bit;
-+
-+	u32 droop_val;
-+	u32 config_val;
-+	u32 user_val;
-+	u32 user_vco_mask;
-+	unsigned long low_vco_max_rate;
-+
-+	unsigned long min_rate;
-+	unsigned long max_rate;
-+};
-+
-+struct clk_hfpll {
-+	struct hfpll_data const *d;
-+	int init_done;
-+
-+	struct clk_regmap clkr;
-+	spinlock_t lock;
-+};
-+
-+#define to_clk_hfpll(_hw) \
-+	container_of(to_clk_regmap(_hw), struct clk_hfpll, clkr)
-+
-+extern const struct clk_ops clk_ops_hfpll;
-+
-+#endif
diff --git a/target/linux/ipq806x/patches/0167-clk-qcom-Add-HFPLL-driver.patch b/target/linux/ipq806x/patches/0167-clk-qcom-Add-HFPLL-driver.patch
deleted file mode 100644
index 1aedbda..0000000
--- a/target/linux/ipq806x/patches/0167-clk-qcom-Add-HFPLL-driver.patch
+++ /dev/null
@@ -1,152 +0,0 @@
-From 49134da893bc11e833e3d87139c57e3b84e65219 Mon Sep 17 00:00:00 2001
-From: Stephen Boyd <sboyd@codeaurora.org>
-Date: Thu, 19 Jun 2014 18:46:31 -0700
-Subject: [PATCH 167/182] clk: qcom: Add HFPLL driver
-
-On some devices (MSM8974 for example), the HFPLLs are
-instantiated within the Krait processor subsystem as separate
-register regions. Add a driver for these PLLs so that we can
-provide HFPLL clocks for use by the system.
-
-Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
----
- drivers/clk/qcom/Kconfig  |    8 ++++
- drivers/clk/qcom/Makefile |    1 +
- drivers/clk/qcom/hfpll.c  |  110 +++++++++++++++++++++++++++++++++++++++++++++
- 3 files changed, 119 insertions(+)
- create mode 100644 drivers/clk/qcom/hfpll.c
-
---- a/drivers/clk/qcom/Kconfig
-+++ b/drivers/clk/qcom/Kconfig
-@@ -53,3 +53,11 @@ config MSM_MMCC_8974
- 	  Support for the multimedia clock controller on msm8974 devices.
- 	  Say Y if you want to support multimedia devices such as display,
- 	  graphics, video encode/decode, camera, etc.
-+
-+config QCOM_HFPLL
-+	tristate "High-Frequency PLL (HFPLL) Clock Controller"
-+	depends on COMMON_CLK_QCOM
-+	help
-+	  Support for the high-frequency PLLs present on Qualcomm devices.
-+	  Say Y if you want to support CPU frequency scaling on devices
-+	  such as MSM8974, APQ8084, etc.
---- a/drivers/clk/qcom/Makefile
-+++ b/drivers/clk/qcom/Makefile
-@@ -16,3 +16,4 @@ obj-$(CONFIG_MSM_GCC_8960) += gcc-msm896
- obj-$(CONFIG_MSM_GCC_8974) += gcc-msm8974.o
- obj-$(CONFIG_MSM_MMCC_8960) += mmcc-msm8960.o
- obj-$(CONFIG_MSM_MMCC_8974) += mmcc-msm8974.o
-+obj-$(CONFIG_QCOM_HFPLL) += hfpll.o
---- /dev/null
-+++ b/drivers/clk/qcom/hfpll.c
-@@ -0,0 +1,110 @@
-+/*
-+ * Copyright (c) 2013-2014, The Linux Foundation. All rights reserved.
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 and
-+ * only version 2 as published by the Free Software Foundation.
-+ *
-+ * 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/kernel.h>
-+#include <linux/init.h>
-+#include <linux/module.h>
-+#include <linux/platform_device.h>
-+#include <linux/of.h>
-+#include <linux/clk.h>
-+#include <linux/clk-provider.h>
-+#include <linux/regmap.h>
-+
-+#include "clk-regmap.h"
-+#include "clk-hfpll.h"
-+
-+static const struct hfpll_data hdata = {
-+	.mode_reg = 0x00,
-+	.l_reg = 0x04,
-+	.m_reg = 0x08,
-+	.n_reg = 0x0c,
-+	.user_reg = 0x10,
-+	.config_reg = 0x14,
-+	.config_val = 0x430405d,
-+	.status_reg = 0x1c,
-+	.lock_bit = 16,
-+
-+	.user_val = 0x8,
-+	.user_vco_mask = 0x100000,
-+	.low_vco_max_rate = 1248000000,
-+	.min_rate = 537600000UL,
-+	.max_rate = 2900000000UL,
-+};
-+
-+static const struct of_device_id qcom_hfpll_match_table[] = {
-+	{ .compatible = "qcom,hfpll" },
-+	{ }
-+};
-+MODULE_DEVICE_TABLE(of, qcom_hfpll_match_table);
-+
-+static struct regmap_config hfpll_regmap_config = {
-+	.reg_bits	= 32,
-+	.reg_stride	= 4,
-+	.val_bits	= 32,
-+	.max_register	= 0x30,
-+	.fast_io	= true,
-+};
-+
-+static int qcom_hfpll_probe(struct platform_device *pdev)
-+{
-+	struct clk *clk;
-+	struct resource *res;
-+	struct device *dev = &pdev->dev;
-+	void __iomem *base;
-+	struct regmap *regmap;
-+	struct clk_hfpll *h;
-+	struct clk_init_data init = {
-+		.parent_names = (const char *[]){ "xo" },
-+		.num_parents = 1,
-+		.ops = &clk_ops_hfpll,
-+	};
-+
-+	h = devm_kzalloc(dev, sizeof(*h), GFP_KERNEL);
-+	if (!h)
-+		return -ENOMEM;
-+
-+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-+	base = devm_ioremap_resource(dev, res);
-+	if (IS_ERR(base))
-+		return PTR_ERR(base);
-+
-+	regmap = devm_regmap_init_mmio(&pdev->dev, base, &hfpll_regmap_config);
-+	if (IS_ERR(regmap))
-+		return PTR_ERR(regmap);
-+
-+	if (of_property_read_string_index(dev->of_node, "clock-output-names",
-+						  0, &init.name))
-+		return -ENODEV;
-+
-+	h->d = &hdata;
-+	h->clkr.hw.init = &init;
-+	spin_lock_init(&h->lock);
-+
-+	clk = devm_clk_register_regmap(&pdev->dev, &h->clkr);
-+
-+	return PTR_ERR_OR_ZERO(clk);
-+}
-+
-+static struct platform_driver qcom_hfpll_driver = {
-+	.probe		= qcom_hfpll_probe,
-+	.driver		= {
-+		.name	= "qcom-hfpll",
-+		.owner	= THIS_MODULE,
-+		.of_match_table = qcom_hfpll_match_table,
-+	},
-+};
-+module_platform_driver(qcom_hfpll_driver);
-+
-+MODULE_DESCRIPTION("QCOM HFPLL Clock Driver");
-+MODULE_LICENSE("GPL v2");
-+MODULE_ALIAS("platform:qcom-hfpll");
diff --git a/target/linux/ipq806x/patches/0168-clk-qcom-Add-MSM8960-s-HFPLLs.patch b/target/linux/ipq806x/patches/0168-clk-qcom-Add-MSM8960-s-HFPLLs.patch
deleted file mode 100644
index 04ff371..0000000
--- a/target/linux/ipq806x/patches/0168-clk-qcom-Add-MSM8960-s-HFPLLs.patch
+++ /dev/null
@@ -1,117 +0,0 @@
-From 0a38d7a21ef0e851d025e4e16f096d5579226299 Mon Sep 17 00:00:00 2001
-From: Stephen Boyd <sboyd@codeaurora.org>
-Date: Mon, 16 Jun 2014 17:44:08 -0700
-Subject: [PATCH 168/182] clk: qcom: Add MSM8960's HFPLLs
-
-Describe the HFPLLs present on MSM8960 devices.
-
-Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
----
- drivers/clk/qcom/gcc-msm8960.c |   82 ++++++++++++++++++++++++++++++++++++++++
- 1 file changed, 82 insertions(+)
-
---- a/drivers/clk/qcom/gcc-msm8960.c
-+++ b/drivers/clk/qcom/gcc-msm8960.c
-@@ -30,6 +30,7 @@
- #include "clk-pll.h"
- #include "clk-rcg.h"
- #include "clk-branch.h"
-+#include "clk-hfpll.h"
- #include "reset.h"
- 
- static struct clk_pll pll3 = {
-@@ -75,6 +76,84 @@ static struct clk_regmap pll8_vote = {
- 	},
- };
- 
-+static struct hfpll_data hfpll0_data = {
-+	.mode_reg = 0x3200,
-+	.l_reg = 0x3208,
-+	.m_reg = 0x320c,
-+	.n_reg = 0x3210,
-+	.config_reg = 0x3204,
-+	.status_reg = 0x321c,
-+        .config_val = 0x7845c665,
-+        .droop_reg = 0x3214,
-+        .droop_val = 0x0108c000,
-+	.min_rate = 600000000UL,
-+	.max_rate = 1800000000UL,
-+};
-+
-+static struct clk_hfpll hfpll0 = {
-+	.d = &hfpll0_data,
-+	.clkr.hw.init = &(struct clk_init_data){
-+		.parent_names = (const char *[]){ "pxo" },
-+		.num_parents = 1,
-+		.name = "hfpll0",
-+		.ops = &clk_ops_hfpll,
-+		.flags = CLK_IGNORE_UNUSED,
-+	},
-+	.lock = __SPIN_LOCK_UNLOCKED(hfpll0.lock),
-+};
-+
-+static struct hfpll_data hfpll1_data = {
-+	.mode_reg = 0x3300,
-+	.l_reg = 0x3308,
-+	.m_reg = 0x330c,
-+	.n_reg = 0x3310,
-+	.config_reg = 0x3304,
-+	.status_reg = 0x331c,
-+        .config_val = 0x7845c665,
-+        .droop_reg = 0x3314,
-+        .droop_val = 0x0108c000,
-+	.min_rate = 600000000UL,
-+	.max_rate = 1800000000UL,
-+};
-+
-+static struct clk_hfpll hfpll1 = {
-+	.d = &hfpll1_data,
-+	.clkr.hw.init = &(struct clk_init_data){
-+		.parent_names = (const char *[]){ "pxo" },
-+		.num_parents = 1,
-+		.name = "hfpll1",
-+		.ops = &clk_ops_hfpll,
-+		.flags = CLK_IGNORE_UNUSED,
-+	},
-+	.lock = __SPIN_LOCK_UNLOCKED(hfpll1.lock),
-+};
-+
-+static struct hfpll_data hfpll_l2_data = {
-+	.mode_reg = 0x3400,
-+	.l_reg = 0x3408,
-+	.m_reg = 0x340c,
-+	.n_reg = 0x3410,
-+	.config_reg = 0x3404,
-+	.status_reg = 0x341c,
-+        .config_val = 0x7845c665,
-+        .droop_reg = 0x3414,
-+        .droop_val = 0x0108c000,
-+	.min_rate = 600000000UL,
-+	.max_rate = 1800000000UL,
-+};
-+
-+static struct clk_hfpll hfpll_l2 = {
-+	.d = &hfpll_l2_data,
-+	.clkr.hw.init = &(struct clk_init_data){
-+		.parent_names = (const char *[]){ "pxo" },
-+		.num_parents = 1,
-+		.name = "hfpll_l2",
-+		.ops = &clk_ops_hfpll,
-+		.flags = CLK_IGNORE_UNUSED,
-+	},
-+	.lock = __SPIN_LOCK_UNLOCKED(hfpll_l2.lock),
-+};
-+
- static struct clk_pll pll14 = {
- 	.l_reg = 0x31c4,
- 	.m_reg = 0x31c8,
-@@ -2763,6 +2842,9 @@ static struct clk_regmap *gcc_msm8960_cl
- 	[PMIC_ARB1_H_CLK] = &pmic_arb1_h_clk.clkr,
- 	[PMIC_SSBI2_CLK] = &pmic_ssbi2_clk.clkr,
- 	[RPM_MSG_RAM_H_CLK] = &rpm_msg_ram_h_clk.clkr,
-+	[PLL9] = &hfpll0.clkr,
-+	[PLL10] = &hfpll1.clkr,
-+	[PLL12] = &hfpll_l2.clkr,
- };
- 
- static const struct qcom_reset_map gcc_msm8960_resets[] = {
diff --git a/target/linux/ipq806x/patches/0169-clk-qcom-Add-support-for-Krait-clocks.patch b/target/linux/ipq806x/patches/0169-clk-qcom-Add-support-for-Krait-clocks.patch
deleted file mode 100644
index 6e17acd..0000000
--- a/target/linux/ipq806x/patches/0169-clk-qcom-Add-support-for-Krait-clocks.patch
+++ /dev/null
@@ -1,190 +0,0 @@
-From 63ecfef8560631a15ee13129b2778cd4dffbcfe2 Mon Sep 17 00:00:00 2001
-From: Stephen Boyd <sboyd@codeaurora.org>
-Date: Wed, 18 Jun 2014 14:18:31 -0700
-Subject: [PATCH 169/182] clk: qcom: Add support for Krait clocks
-
-The Krait clocks are made up of a series of muxes and a divider
-that choose between a fixed rate clock and dedicated HFPLLs for
-each CPU. Instead of using mmio accesses to remux parents, the
-Krait implementation exposes the remux control via cp15
-registers. Support these clocks.
-
-Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
----
- drivers/clk/qcom/Kconfig     |    4 ++
- drivers/clk/qcom/Makefile    |    1 +
- drivers/clk/qcom/clk-krait.c |  121 ++++++++++++++++++++++++++++++++++++++++++
- drivers/clk/qcom/clk-krait.h |   22 ++++++++
- 4 files changed, 148 insertions(+)
- create mode 100644 drivers/clk/qcom/clk-krait.c
- create mode 100644 drivers/clk/qcom/clk-krait.h
-
---- a/drivers/clk/qcom/Kconfig
-+++ b/drivers/clk/qcom/Kconfig
-@@ -61,3 +61,7 @@ config QCOM_HFPLL
- 	  Support for the high-frequency PLLs present on Qualcomm devices.
- 	  Say Y if you want to support CPU frequency scaling on devices
- 	  such as MSM8974, APQ8084, etc.
-+
-+config KRAIT_CLOCKS
-+	bool
-+	select KRAIT_L2_ACCESSORS
---- a/drivers/clk/qcom/Makefile
-+++ b/drivers/clk/qcom/Makefile
-@@ -7,6 +7,7 @@ clk-qcom-y += clk-rcg.o
- clk-qcom-y += clk-rcg2.o
- clk-qcom-y += clk-branch.o
- clk-qcom-y += clk-generic.o
-+clk-qcom-$(CONFIG_KRAIT_CLOCKS) += clk-krait.o
- clk-qcom-y += clk-hfpll.o
- clk-qcom-y += reset.o
- 
---- /dev/null
-+++ b/drivers/clk/qcom/clk-krait.c
-@@ -0,0 +1,121 @@
-+/*
-+ * Copyright (c) 2013-2014, The Linux Foundation. All rights reserved.
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 and
-+ * only version 2 as published by the Free Software Foundation.
-+ *
-+ * 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/kernel.h>
-+#include <linux/module.h>
-+#include <linux/init.h>
-+#include <linux/io.h>
-+#include <linux/delay.h>
-+#include <linux/err.h>
-+#include <linux/clk-provider.h>
-+#include <linux/spinlock.h>
-+
-+#include <asm/krait-l2-accessors.h>
-+
-+#include "clk-krait.h"
-+
-+/* Secondary and primary muxes share the same cp15 register */
-+static DEFINE_SPINLOCK(kpss_clock_reg_lock);
-+
-+#define LPL_SHIFT	8
-+static void __kpss_mux_set_sel(struct mux_clk *mux, int sel)
-+{
-+	unsigned long flags;
-+	u32 regval;
-+
-+	spin_lock_irqsave(&kpss_clock_reg_lock, flags);
-+	regval = krait_get_l2_indirect_reg(mux->offset);
-+	regval &= ~(mux->mask << mux->shift);
-+	regval |= (sel & mux->mask) << mux->shift;
-+	if (mux->priv) {
-+		regval &= ~(mux->mask << (mux->shift + LPL_SHIFT));
-+		regval |= (sel & mux->mask) << (mux->shift + LPL_SHIFT);
-+	}
-+	krait_set_l2_indirect_reg(mux->offset, regval);
-+	spin_unlock_irqrestore(&kpss_clock_reg_lock, flags);
-+
-+	/* Wait for switch to complete. */
-+	mb();
-+	udelay(1);
-+}
-+
-+static int kpss_mux_set_sel(struct mux_clk *mux, int sel)
-+{
-+	mux->en_mask = sel;
-+	/* Don't touch mux if CPU is off as it won't work */
-+	if (__clk_is_enabled(mux->hw.clk))
-+		__kpss_mux_set_sel(mux, sel);
-+	return 0;
-+}
-+
-+static int kpss_mux_get_sel(struct mux_clk *mux)
-+{
-+	u32 sel;
-+
-+	sel = krait_get_l2_indirect_reg(mux->offset);
-+	sel >>= mux->shift;
-+	sel &= mux->mask;
-+	mux->en_mask = sel;
-+
-+	return sel;
-+}
-+
-+static int kpss_mux_enable(struct mux_clk *mux)
-+{
-+	__kpss_mux_set_sel(mux, mux->en_mask);
-+	return 0;
-+}
-+
-+static void kpss_mux_disable(struct mux_clk *mux)
-+{
-+	__kpss_mux_set_sel(mux, mux->safe_sel);
-+}
-+
-+const struct clk_mux_ops clk_mux_ops_kpss = {
-+	.enable = kpss_mux_enable,
-+	.disable = kpss_mux_disable,
-+	.set_mux_sel = kpss_mux_set_sel,
-+	.get_mux_sel = kpss_mux_get_sel,
-+};
-+EXPORT_SYMBOL_GPL(clk_mux_ops_kpss);
-+
-+/*
-+ * The divider can divide by 2, 4, 6 and 8. But we only really need div-2. So
-+ * force it to div-2 during handoff and treat it like a fixed div-2 clock.
-+ */
-+static int kpss_div2_get_div(struct div_clk *div)
-+{
-+	unsigned long flags;
-+	u32 regval;
-+	int val;
-+
-+	spin_lock_irqsave(&kpss_clock_reg_lock, flags);
-+	regval = krait_get_l2_indirect_reg(div->offset);
-+	val = (regval >> div->shift) & div->mask;
-+	regval &= ~(div->mask << div->shift);
-+	if (div->priv)
-+		regval &= ~(div->mask << (div->shift + LPL_SHIFT));
-+	krait_set_l2_indirect_reg(div->offset, regval);
-+	spin_unlock_irqrestore(&kpss_clock_reg_lock, flags);
-+
-+	val = (val + 1) * 2;
-+	WARN(val != 2, "Divider %s was configured to div-%d instead of 2!\n",
-+		__clk_get_name(div->hw.clk), val);
-+
-+	return 2;
-+}
-+
-+const struct clk_div_ops clk_div_ops_kpss_div2 = {
-+	.get_div = kpss_div2_get_div,
-+};
-+EXPORT_SYMBOL_GPL(clk_div_ops_kpss_div2);
---- /dev/null
-+++ b/drivers/clk/qcom/clk-krait.h
-@@ -0,0 +1,22 @@
-+/*
-+ * Copyright (c) 2013, The Linux Foundation. All rights reserved.
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 and
-+ * only version 2 as published by the Free Software Foundation.
-+ *
-+ * 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 __SOC_QCOM_CLOCK_KRAIT_H
-+#define __SOC_QCOM_CLOCK_KRAIT_H
-+
-+#include <linux/clk/msm-clk-generic.h>
-+
-+extern const struct clk_mux_ops clk_mux_ops_kpss;
-+extern const struct clk_div_ops clk_div_ops_kpss_div2;
-+
-+#endif
diff --git a/target/linux/ipq806x/patches/0170-clk-qcom-Add-KPSS-ACC-GCC-driver.patch b/target/linux/ipq806x/patches/0170-clk-qcom-Add-KPSS-ACC-GCC-driver.patch
deleted file mode 100644
index b16108e..0000000
--- a/target/linux/ipq806x/patches/0170-clk-qcom-Add-KPSS-ACC-GCC-driver.patch
+++ /dev/null
@@ -1,161 +0,0 @@
-From 67a9d5a02b178644da624ef9c32b4e6abb2c4f6e Mon Sep 17 00:00:00 2001
-From: Stephen Boyd <sboyd@codeaurora.org>
-Date: Wed, 18 Jun 2014 14:25:41 -0700
-Subject: [PATCH 170/182] clk: qcom: Add KPSS ACC/GCC driver
-
-The ACC and GCC regions present in KPSSv1 contain registers to
-control clocks and power to each Krait CPU and L2. For CPUfreq
-purposes probe these devices and expose a mux clock that chooses
-between PXO and PLL8.
-
-Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
----
- drivers/clk/qcom/Kconfig    |    8 +++
- drivers/clk/qcom/Makefile   |    1 +
- drivers/clk/qcom/kpss-xcc.c |  115 +++++++++++++++++++++++++++++++++++++++++++
- 3 files changed, 124 insertions(+)
- create mode 100644 drivers/clk/qcom/kpss-xcc.c
-
---- a/drivers/clk/qcom/Kconfig
-+++ b/drivers/clk/qcom/Kconfig
-@@ -62,6 +62,14 @@ config QCOM_HFPLL
- 	  Say Y if you want to support CPU frequency scaling on devices
- 	  such as MSM8974, APQ8084, etc.
- 
-+config KPSS_XCC
-+	tristate "KPSS Clock Controller"
-+	depends on COMMON_CLK_QCOM
-+	help
-+	  Support for the Krait ACC and GCC clock controllers. Say Y
-+	  if you want to support CPU frequency scaling on devices such
-+	  as MSM8960, APQ8064, etc.
-+
- config KRAIT_CLOCKS
- 	bool
- 	select KRAIT_L2_ACCESSORS
---- a/drivers/clk/qcom/Makefile
-+++ b/drivers/clk/qcom/Makefile
-@@ -17,4 +17,5 @@ obj-$(CONFIG_MSM_GCC_8960) += gcc-msm896
- obj-$(CONFIG_MSM_GCC_8974) += gcc-msm8974.o
- obj-$(CONFIG_MSM_MMCC_8960) += mmcc-msm8960.o
- obj-$(CONFIG_MSM_MMCC_8974) += mmcc-msm8974.o
-+obj-$(CONFIG_KPSS_XCC) += kpss-xcc.o
- obj-$(CONFIG_QCOM_HFPLL) += hfpll.o
---- /dev/null
-+++ b/drivers/clk/qcom/kpss-xcc.c
-@@ -0,0 +1,115 @@
-+/* Copyright (c) 2014, The Linux Foundation. All rights reserved.
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 and
-+ * only version 2 as published by the Free Software Foundation.
-+ *
-+ * 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/kernel.h>
-+#include <linux/init.h>
-+#include <linux/module.h>
-+#include <linux/platform_device.h>
-+#include <linux/err.h>
-+#include <linux/io.h>
-+#include <linux/of.h>
-+#include <linux/of_device.h>
-+#include <linux/clk.h>
-+#include <linux/clk-provider.h>
-+#include <linux/clk/msm-clk-generic.h>
-+
-+static int kpss_xcc_set_mux_sel(struct mux_clk *clk, int sel)
-+{
-+	writel_relaxed(sel, clk->base + clk->offset);
-+	return 0;
-+}
-+
-+static int kpss_xcc_get_mux_sel(struct mux_clk *clk)
-+{
-+	return readl_relaxed(clk->base + clk->offset);
-+}
-+
-+static const struct clk_mux_ops kpss_xcc_ops = {
-+	.set_mux_sel = kpss_xcc_set_mux_sel,
-+	.get_mux_sel = kpss_xcc_get_mux_sel,
-+};
-+
-+static const char *aux_parents[] = {
-+	"pll8_vote",
-+	"pxo",
-+};
-+
-+static u8 aux_parent_map[] = {
-+	3,
-+	0,
-+};
-+
-+static const struct of_device_id kpss_xcc_match_table[] = {
-+	{ .compatible = "qcom,kpss-acc-v1", .data = (void *)1UL },
-+	{ .compatible = "qcom,kpss-gcc" },
-+	{}
-+};
-+MODULE_DEVICE_TABLE(of, kpss_xcc_match_table);
-+
-+static int kpss_xcc_driver_probe(struct platform_device *pdev)
-+{
-+	const struct of_device_id *id;
-+	struct clk *clk;
-+	struct resource *res;
-+	void __iomem *base;
-+	struct mux_clk *mux_clk;
-+	struct clk_init_data init = {
-+		.parent_names = aux_parents,
-+		.num_parents = 2,
-+		.ops = &clk_ops_gen_mux,
-+	};
-+
-+	id = of_match_device(kpss_xcc_match_table, &pdev->dev);
-+	if (!id)
-+		return -ENODEV;
-+
-+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-+	base = devm_ioremap_resource(&pdev->dev, res);
-+	if (IS_ERR(base))
-+		return PTR_ERR(base);
-+
-+	mux_clk = devm_kzalloc(&pdev->dev, sizeof(*mux_clk), GFP_KERNEL);
-+	if (!mux_clk)
-+		return -ENOMEM;
-+
-+	mux_clk->mask = 0x3;
-+	mux_clk->parent_map = aux_parent_map;
-+	mux_clk->ops = &kpss_xcc_ops;
-+	mux_clk->base = base;
-+	mux_clk->hw.init = &init;
-+
-+	if (id->data) {
-+		if (of_property_read_string_index(pdev->dev.of_node,
-+					"clock-output-names", 0, &init.name))
-+			return -ENODEV;
-+		mux_clk->offset = 0x14;
-+	} else {
-+		init.name = "acpu_l2_aux";
-+		mux_clk->offset = 0x28;
-+	}
-+
-+	clk = devm_clk_register(&pdev->dev, &mux_clk->hw);
-+
-+	return PTR_ERR_OR_ZERO(clk);
-+}
-+
-+static struct platform_driver kpss_xcc_driver = {
-+	.probe = kpss_xcc_driver_probe,
-+	.driver = {
-+		.name = "kpss-xcc",
-+		.of_match_table = kpss_xcc_match_table,
-+		.owner = THIS_MODULE,
-+	},
-+};
-+module_platform_driver(kpss_xcc_driver);
-+
-+MODULE_LICENSE("GPL v2");
diff --git a/target/linux/ipq806x/patches/0171-clk-qcom-Add-Krait-clock-controller-driver.patch b/target/linux/ipq806x/patches/0171-clk-qcom-Add-Krait-clock-controller-driver.patch
deleted file mode 100644
index 6d0619a..0000000
--- a/target/linux/ipq806x/patches/0171-clk-qcom-Add-Krait-clock-controller-driver.patch
+++ /dev/null
@@ -1,410 +0,0 @@
-From 6912e27d97ba5671e8c2434bed0ebd23fde5e13d Mon Sep 17 00:00:00 2001
-From: Stephen Boyd <sboyd@codeaurora.org>
-Date: Wed, 18 Jun 2014 14:29:29 -0700
-Subject: [PATCH 171/182] clk: qcom: Add Krait clock controller driver
-
-The Krait CPU clocks are made up of a primary mux and secondary
-mux for each CPU and the L2, controlled via cp15 accessors. For
-Kraits within KPSSv1 each secondary mux accepts a different aux
-source, but on KPSSv2 each secondary mux accepts the same aux
-source.
-
-Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
----
- drivers/clk/qcom/Kconfig    |    8 +
- drivers/clk/qcom/Makefile   |    1 +
- drivers/clk/qcom/krait-cc.c |  364 +++++++++++++++++++++++++++++++++++++++++++
- 3 files changed, 373 insertions(+)
- create mode 100644 drivers/clk/qcom/krait-cc.c
-
---- a/drivers/clk/qcom/Kconfig
-+++ b/drivers/clk/qcom/Kconfig
-@@ -70,6 +70,14 @@ config KPSS_XCC
- 	  if you want to support CPU frequency scaling on devices such
- 	  as MSM8960, APQ8064, etc.
- 
-+config KRAITCC
-+	tristate "Krait Clock Controller"
-+	depends on COMMON_CLK_QCOM && ARM
-+	select KRAIT_CLOCKS
-+	help
-+	  Support for the Krait CPU clocks on Qualcomm devices.
-+	  Say Y if you want to support CPU frequency scaling.
-+
- config KRAIT_CLOCKS
- 	bool
- 	select KRAIT_L2_ACCESSORS
---- a/drivers/clk/qcom/Makefile
-+++ b/drivers/clk/qcom/Makefile
-@@ -19,3 +19,4 @@ obj-$(CONFIG_MSM_MMCC_8960) += mmcc-msm8
- obj-$(CONFIG_MSM_MMCC_8974) += mmcc-msm8974.o
- obj-$(CONFIG_KPSS_XCC) += kpss-xcc.o
- obj-$(CONFIG_QCOM_HFPLL) += hfpll.o
-+obj-$(CONFIG_KRAITCC) += krait-cc.o
---- /dev/null
-+++ b/drivers/clk/qcom/krait-cc.c
-@@ -0,0 +1,364 @@
-+/* Copyright (c) 2013-2014, The Linux Foundation. All rights reserved.
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 and
-+ * only version 2 as published by the Free Software Foundation.
-+ *
-+ * 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/kernel.h>
-+#include <linux/init.h>
-+#include <linux/module.h>
-+#include <linux/platform_device.h>
-+#include <linux/err.h>
-+#include <linux/io.h>
-+#include <linux/of.h>
-+#include <linux/of_device.h>
-+#include <linux/clk.h>
-+#include <linux/clk-provider.h>
-+#include <linux/slab.h>
-+
-+#include <asm/smp_plat.h>
-+
-+#include "clk-krait.h"
-+
-+DEFINE_FIXED_DIV_CLK(acpu_aux, 2, "gpll0_vote");
-+
-+static u8 sec_mux_map[] = {
-+	2,
-+	0,
-+};
-+
-+static u8 pri_mux_map[] = {
-+	1,
-+	2,
-+	0,
-+};
-+
-+static int
-+krait_add_div(struct device *dev, int id, const char *s, unsigned offset)
-+{
-+	struct div_clk *div;
-+	struct clk_init_data init = {
-+		.num_parents = 1,
-+		.ops = &clk_ops_div,
-+		.flags = CLK_SET_RATE_PARENT,
-+	};
-+	const char *p_names[1];
-+	struct clk *clk;
-+
-+	div = devm_kzalloc(dev, sizeof(*dev), GFP_KERNEL);
-+	if (!div)
-+		return -ENOMEM;
-+
-+	div->data.div = 2;
-+	div->data.min_div = 2;
-+	div->data.max_div = 2;
-+	div->ops = &clk_div_ops_kpss_div2;
-+	div->mask = 0x3;
-+	div->shift = 6;
-+	div->priv = (void *)(id >= 0);
-+	div->offset = offset;
-+	div->hw.init = &init;
-+
-+	init.name = kasprintf(GFP_KERNEL, "hfpll%s_div", s);
-+	if (!init.name)
-+		return -ENOMEM;
-+
-+	init.parent_names = p_names;
-+	p_names[0] = kasprintf(GFP_KERNEL, "hfpll%s", s);
-+	if (!p_names[0]) {
-+		kfree(init.name);
-+		return -ENOMEM;
-+	}
-+
-+	clk = devm_clk_register(dev, &div->hw);
-+	kfree(p_names[0]);
-+	kfree(init.name);
-+
-+	return PTR_ERR_OR_ZERO(clk);
-+}
-+
-+static int
-+krait_add_sec_mux(struct device *dev, int id, const char *s, unsigned offset,
-+		  bool unique_aux)
-+{
-+	struct mux_clk *mux;
-+	static const char *sec_mux_list[] = {
-+		"acpu_aux",
-+		"qsb",
-+	};
-+	struct clk_init_data init = {
-+		.parent_names = sec_mux_list,
-+		.num_parents = ARRAY_SIZE(sec_mux_list),
-+		.ops = &clk_ops_gen_mux,
-+		.flags = CLK_SET_RATE_PARENT,
-+	};
-+	struct clk *clk;
-+
-+	mux = devm_kzalloc(dev, sizeof(*mux), GFP_KERNEL);
-+	if (!mux)
-+		return -ENOMEM;
-+
-+	mux->offset = offset;
-+	mux->priv = (void *)(id >= 0);
-+	mux->has_safe_parent = true;
-+	mux->safe_sel = 2;
-+	mux->ops = &clk_mux_ops_kpss;
-+	mux->mask = 0x3;
-+	mux->shift = 2;
-+	mux->parent_map = sec_mux_map;
-+	mux->hw.init = &init;
-+
-+	init.name = kasprintf(GFP_KERNEL, "krait%s_sec_mux", s);
-+	if (!init.name)
-+		return -ENOMEM;
-+
-+	if (unique_aux) {
-+		sec_mux_list[0] = kasprintf(GFP_KERNEL, "acpu%s_aux", s);
-+		if (!sec_mux_list[0]) {
-+			clk = ERR_PTR(-ENOMEM);
-+			goto err_aux;
-+		}
-+	}
-+
-+	clk = devm_clk_register(dev, &mux->hw);
-+
-+	if (unique_aux)
-+		kfree(sec_mux_list[0]);
-+err_aux:
-+	kfree(init.name);
-+	return PTR_ERR_OR_ZERO(clk);
-+}
-+
-+static struct clk *
-+krait_add_pri_mux(struct device *dev, int id, const char * s, unsigned offset)
-+{
-+	struct mux_clk *mux;
-+	const char *p_names[3];
-+	struct clk_init_data init = {
-+		.parent_names = p_names,
-+		.num_parents = ARRAY_SIZE(p_names),
-+		.ops = &clk_ops_gen_mux,
-+		.flags = CLK_SET_RATE_PARENT,
-+	};
-+	struct clk *clk;
-+
-+	mux = devm_kzalloc(dev, sizeof(*mux), GFP_KERNEL);
-+	if (!mux)
-+		return ERR_PTR(-ENOMEM);
-+
-+	mux->has_safe_parent = true;
-+	mux->safe_sel = 0;
-+	mux->ops = &clk_mux_ops_kpss;
-+	mux->mask = 0x3;
-+	mux->shift = 0;
-+	mux->offset = offset;
-+	mux->priv = (void *)(id >= 0);
-+	mux->parent_map = pri_mux_map;
-+	mux->hw.init = &init;
-+
-+	init.name = kasprintf(GFP_KERNEL, "krait%s_pri_mux", s);
-+	if (!init.name)
-+		return ERR_PTR(-ENOMEM);
-+
-+	p_names[0] = kasprintf(GFP_KERNEL, "hfpll%s", s);
-+	if (!p_names[0]) {
-+		clk = ERR_PTR(-ENOMEM);
-+		goto err_p0;
-+	}
-+
-+	p_names[1] = kasprintf(GFP_KERNEL, "hfpll%s_div", s);
-+	if (!p_names[1]) {
-+		clk = ERR_PTR(-ENOMEM);
-+		goto err_p1;
-+	}
-+
-+	p_names[2] = kasprintf(GFP_KERNEL, "krait%s_sec_mux", s);
-+	if (!p_names[2]) {
-+		clk = ERR_PTR(-ENOMEM);
-+		goto err_p2;
-+	}
-+
-+	clk = devm_clk_register(dev, &mux->hw);
-+
-+	kfree(p_names[2]);
-+err_p2:
-+	kfree(p_names[1]);
-+err_p1:
-+	kfree(p_names[0]);
-+err_p0:
-+	kfree(init.name);
-+	return clk;
-+}
-+
-+/* id < 0 for L2, otherwise id == physical CPU number */
-+static struct clk *krait_add_clks(struct device *dev, int id, bool unique_aux)
-+{
-+	int ret;
-+	unsigned offset;
-+	void *p = NULL;
-+	const char *s;
-+	struct clk *clk;
-+
-+	if (id >= 0) {
-+		offset = 0x4501 + (0x1000 * id);
-+		s = p = kasprintf(GFP_KERNEL, "%d", id);
-+		if (!s)
-+			return ERR_PTR(-ENOMEM);
-+	} else {
-+		offset = 0x500;
-+		s = "_l2";
-+	}
-+
-+	ret = krait_add_div(dev, id, s, offset);
-+	if (ret) {
-+		clk = ERR_PTR(ret);
-+		goto err;
-+	}
-+
-+	ret = krait_add_sec_mux(dev, id, s, offset, unique_aux);
-+	if (ret) {
-+		clk = ERR_PTR(ret);
-+		goto err;
-+	}
-+
-+	clk = krait_add_pri_mux(dev, id, s, offset);
-+err:
-+	kfree(p);
-+	return clk;
-+}
-+
-+static struct clk *krait_of_get(struct of_phandle_args *clkspec, void *data)
-+{
-+	unsigned int idx = clkspec->args[0];
-+	struct clk **clks = data;
-+
-+	if (idx >= 5) {
-+		pr_err("%s: invalid clock index %d\n", __func__, idx);
-+		return ERR_PTR(-EINVAL);
-+	}
-+
-+	return clks[idx] ? : ERR_PTR(-ENODEV);
-+}
-+
-+static const struct of_device_id krait_cc_match_table[] = {
-+	{ .compatible = "qcom,krait-cc-v1", (void *)1UL },
-+	{ .compatible = "qcom,krait-cc-v2" },
-+	{}
-+};
-+MODULE_DEVICE_TABLE(of, krait_cc_match_table);
-+
-+static int krait_cc_probe(struct platform_device *pdev)
-+{
-+	struct device *dev = &pdev->dev;
-+	const struct of_device_id *id;
-+	unsigned long cur_rate, aux_rate;
-+	int i, cpu;
-+	struct clk *clk;
-+	struct clk **clks;
-+	struct clk *l2_pri_mux_clk;
-+
-+	id = of_match_device(krait_cc_match_table, &pdev->dev);
-+	if (!id)
-+		return -ENODEV;
-+
-+	/* Rate is 1 because 0 causes problems for __clk_mux_determine_rate */
-+	clk = clk_register_fixed_rate(dev, "qsb", NULL, CLK_IS_ROOT, 1);
-+	if (IS_ERR(clk))
-+		return PTR_ERR(clk);
-+
-+	if (!id->data) {
-+		clk = devm_clk_register(dev, &acpu_aux.hw);
-+		if (IS_ERR(clk))
-+			return PTR_ERR(clk);
-+	}
-+
-+	/* Krait configurations have at most 4 CPUs and one L2 */
-+	clks = devm_kcalloc(dev, 5, sizeof(*clks), GFP_KERNEL);
-+	if (!clks)
-+		return -ENOMEM;
-+
-+	for_each_possible_cpu(i) {
-+		cpu = cpu_logical_map(i);
-+		clk = krait_add_clks(dev, cpu, id->data);
-+		if (IS_ERR(clk))
-+			return PTR_ERR(clk);
-+		clks[cpu] = clk;
-+	}
-+
-+	l2_pri_mux_clk = krait_add_clks(dev, -1, id->data);
-+	if (IS_ERR(l2_pri_mux_clk))
-+		return PTR_ERR(l2_pri_mux_clk);
-+	clks[4] = l2_pri_mux_clk;
-+
-+	/*
-+	 * We don't want the CPU or L2 clocks to be turned off at late init
-+	 * if CPUFREQ or HOTPLUG configs are disabled. So, bump up the
-+	 * refcount of these clocks. Any cpufreq/hotplug manager can assume
-+	 * that the clocks have already been prepared and enabled by the time
-+	 * they take over.
-+	 */
-+	for_each_online_cpu(i) {
-+		cpu = cpu_logical_map(i);
-+		clk_prepare_enable(l2_pri_mux_clk);
-+		WARN(clk_prepare_enable(clks[cpu]),
-+			"Unable to turn on CPU%d clock", cpu);
-+	}
-+
-+	/*
-+	 * Force reinit of HFPLLs and muxes to overwrite any potential
-+	 * incorrect configuration of HFPLLs and muxes by the bootloader.
-+	 * While at it, also make sure the cores are running at known rates
-+	 * and print the current rate.
-+	 *
-+	 * The clocks are set to aux clock rate first to make sure the
-+	 * secondary mux is not sourcing off of QSB. The rate is then set to
-+	 * two different rates to force a HFPLL reinit under all
-+	 * circumstances.
-+	 */
-+	cur_rate = clk_get_rate(l2_pri_mux_clk);
-+	aux_rate = 384000000;
-+	if (cur_rate == 1) {
-+		pr_info("L2 @ QSB rate. Forcing new rate.\n");
-+		cur_rate = aux_rate;
-+	}
-+	clk_set_rate(l2_pri_mux_clk, aux_rate);
-+	clk_set_rate(l2_pri_mux_clk, 2);
-+	clk_set_rate(l2_pri_mux_clk, cur_rate);
-+	pr_info("L2 @ %lu KHz\n", clk_get_rate(l2_pri_mux_clk) / 1000);
-+	for_each_possible_cpu(i) {
-+		cpu = cpu_logical_map(i);
-+		clk = clks[cpu];
-+		cur_rate = clk_get_rate(clk);
-+		if (cur_rate == 1) {
-+			pr_info("CPU%d @ QSB rate. Forcing new rate.\n", i);
-+			cur_rate = aux_rate;
-+		}
-+		clk_set_rate(clk, aux_rate);
-+		clk_set_rate(clk, 2);
-+		clk_set_rate(clk, cur_rate);
-+		pr_info("CPU%d @ %lu KHz\n", i, clk_get_rate(clk) / 1000);
-+	}
-+
-+	of_clk_add_provider(dev->of_node, krait_of_get, clks);
-+
-+	return 0;
-+}
-+
-+static struct platform_driver krait_cc_driver = {
-+	.probe = krait_cc_probe,
-+	.driver = {
-+		.name = "clock-krait",
-+		.of_match_table = krait_cc_match_table,
-+		.owner = THIS_MODULE,
-+	},
-+};
-+module_platform_driver(krait_cc_driver);
-+
-+MODULE_DESCRIPTION("Krait CPU Clock Driver");
-+MODULE_LICENSE("GPL v2");
diff --git a/target/linux/ipq806x/patches/0172-cpufreq-Add-a-cpufreq-krait-based-on-cpufreq-cpu0.patch b/target/linux/ipq806x/patches/0172-cpufreq-Add-a-cpufreq-krait-based-on-cpufreq-cpu0.patch
deleted file mode 100644
index ea07fc1..0000000
--- a/target/linux/ipq806x/patches/0172-cpufreq-Add-a-cpufreq-krait-based-on-cpufreq-cpu0.patch
+++ /dev/null
@@ -1,245 +0,0 @@
-From 5cf343c60d7557aefb468603065cac5062f11b8d Mon Sep 17 00:00:00 2001
-From: Stephen Boyd <sboyd@codeaurora.org>
-Date: Fri, 30 May 2014 16:36:11 -0700
-Subject: [PATCH 172/182] cpufreq: Add a cpufreq-krait based on cpufreq-cpu0
-
-Krait processors have individual clocks for each CPU that can
-scale independently from one another. cpufreq-cpu0 is fairly
-close to this, but assumes that there is only one clock for all
-CPUs. Add a driver to support the Krait configuration.
-
-TODO: Merge into cpufreq-cpu0? Or make generic?
-
-Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
----
- drivers/cpufreq/Kconfig         |   13 +++
- drivers/cpufreq/Makefile        |    1 +
- drivers/cpufreq/cpufreq-krait.c |  190 +++++++++++++++++++++++++++++++++++++++
- 3 files changed, 204 insertions(+)
- create mode 100644 drivers/cpufreq/cpufreq-krait.c
-
---- a/drivers/cpufreq/Kconfig
-+++ b/drivers/cpufreq/Kconfig
-@@ -194,6 +194,19 @@ config GENERIC_CPUFREQ_CPU0
- 
- 	  If in doubt, say N.
- 
-+config GENERIC_CPUFREQ_KRAIT
-+	tristate "Krait cpufreq driver"
-+	depends on HAVE_CLK && OF
-+	# if CPU_THERMAL is on and THERMAL=m, CPU0 cannot be =y:
-+	depends on !CPU_THERMAL || THERMAL
-+	select PM_OPP
-+	help
-+	  This adds a generic cpufreq driver for CPU0 frequency management.
-+	  It supports both uniprocessor (UP) and symmetric multiprocessor (SMP)
-+	  systems which share clock and voltage across all CPUs.
-+
-+	  If in doubt, say N.
-+
- menu "x86 CPU frequency scaling drivers"
- depends on X86
- source "drivers/cpufreq/Kconfig.x86"
---- a/drivers/cpufreq/Makefile
-+++ b/drivers/cpufreq/Makefile
-@@ -12,6 +12,7 @@ obj-$(CONFIG_CPU_FREQ_GOV_CONSERVATIVE)
- obj-$(CONFIG_CPU_FREQ_GOV_COMMON)		+= cpufreq_governor.o
- 
- obj-$(CONFIG_GENERIC_CPUFREQ_CPU0)	+= cpufreq-cpu0.o
-+obj-$(CONFIG_GENERIC_CPUFREQ_KRAIT)	+= cpufreq-krait.o
- 
- ##################################################################################
- # x86 drivers.
---- /dev/null
-+++ b/drivers/cpufreq/cpufreq-krait.c
-@@ -0,0 +1,190 @@
-+/*
-+ * Copyright (C) 2012 Freescale Semiconductor, Inc.
-+ * Copyright (c) 2014, The Linux Foundation. All rights reserved.
-+ *
-+ * The OPP code in function krait_set_target() is reused from
-+ * drivers/cpufreq/omap-cpufreq.c
-+ *
-+ * 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/clk.h>
-+#include <linux/cpu.h>
-+#include <linux/cpu_cooling.h>
-+#include <linux/cpufreq.h>
-+#include <linux/cpumask.h>
-+#include <linux/err.h>
-+#include <linux/module.h>
-+#include <linux/of.h>
-+#include <linux/pm_opp.h>
-+#include <linux/platform_device.h>
-+#include <linux/slab.h>
-+#include <linux/thermal.h>
-+
-+static unsigned int transition_latency;
-+
-+static struct device *cpu_dev;
-+static DEFINE_PER_CPU(struct clk *, krait_cpu_clks);
-+static struct cpufreq_frequency_table *freq_table;
-+static struct thermal_cooling_device *cdev;
-+
-+static int krait_set_target(struct cpufreq_policy *policy, unsigned int index)
-+{
-+	unsigned long volt = 0, volt_old = 0;
-+	unsigned int old_freq, new_freq;
-+	long freq_Hz, freq_exact;
-+	int ret;
-+	struct clk *cpu_clk;
-+
-+	cpu_clk = per_cpu(krait_cpu_clks, policy->cpu);
-+
-+	freq_Hz = clk_round_rate(cpu_clk, freq_table[index].frequency * 1000);
-+	if (freq_Hz <= 0)
-+		freq_Hz = freq_table[index].frequency * 1000;
-+
-+	freq_exact = freq_Hz;
-+	new_freq = freq_Hz / 1000;
-+	old_freq = clk_get_rate(cpu_clk) / 1000;
-+
-+	pr_debug("%u MHz, %ld mV --> %u MHz, %ld mV\n",
-+		 old_freq / 1000, volt_old ? volt_old / 1000 : -1,
-+		 new_freq / 1000, volt ? volt / 1000 : -1);
-+
-+	ret = clk_set_rate(cpu_clk, freq_exact);
-+	if (ret)
-+		pr_err("failed to set clock rate: %d\n", ret);
-+
-+	return ret;
-+}
-+
-+static int krait_cpufreq_init(struct cpufreq_policy *policy)
-+{
-+	int ret;
-+
-+	policy->clk = per_cpu(krait_cpu_clks, policy->cpu);
-+
-+	ret = cpufreq_table_validate_and_show(policy, freq_table);
-+	if (ret) {
-+		pr_err("%s: invalid frequency table: %d\n", __func__, ret);
-+		return ret;
-+	}
-+
-+	policy->cpuinfo.transition_latency = transition_latency;
-+
-+	return 0;
-+}
-+
-+static struct cpufreq_driver krait_cpufreq_driver = {
-+	.flags = CPUFREQ_STICKY,
-+	.verify = cpufreq_generic_frequency_table_verify,
-+	.target_index = krait_set_target,
-+	.get = cpufreq_generic_get,
-+	.init = krait_cpufreq_init,
-+	.name = "generic_krait",
-+	.attr = cpufreq_generic_attr,
-+};
-+
-+static int krait_cpufreq_probe(struct platform_device *pdev)
-+{
-+	struct device_node *np;
-+	int ret;
-+	unsigned int cpu;
-+	struct device *dev;
-+	struct clk *clk;
-+
-+	cpu_dev = get_cpu_device(0);
-+	if (!cpu_dev) {
-+		pr_err("failed to get krait device\n");
-+		return -ENODEV;
-+	}
-+
-+	np = of_node_get(cpu_dev->of_node);
-+	if (!np) {
-+		pr_err("failed to find krait node\n");
-+		return -ENOENT;
-+	}
-+
-+	for_each_possible_cpu(cpu) {
-+		dev = get_cpu_device(cpu);
-+		if (!dev) {
-+			pr_err("failed to get krait device\n");
-+			ret = -ENOENT;
-+			goto out_put_node;
-+		}
-+		per_cpu(krait_cpu_clks, cpu) = clk = devm_clk_get(dev, NULL);
-+		if (IS_ERR(clk)) {
-+			ret = PTR_ERR(clk);
-+			goto out_put_node;
-+		}
-+	}
-+
-+	ret = of_init_opp_table(cpu_dev);
-+	if (ret) {
-+		pr_err("failed to init OPP table: %d\n", ret);
-+		goto out_put_node;
-+	}
-+
-+	ret = dev_pm_opp_init_cpufreq_table(cpu_dev, &freq_table);
-+	if (ret) {
-+		pr_err("failed to init cpufreq table: %d\n", ret);
-+		goto out_put_node;
-+	}
-+
-+	if (of_property_read_u32(np, "clock-latency", &transition_latency))
-+		transition_latency = CPUFREQ_ETERNAL;
-+
-+	ret = cpufreq_register_driver(&krait_cpufreq_driver);
-+	if (ret) {
-+		pr_err("failed register driver: %d\n", ret);
-+		goto out_free_table;
-+	}
-+	of_node_put(np);
-+
-+	/*
-+	 * For now, just loading the cooling device;
-+	 * thermal DT code takes care of matching them.
-+	 */
-+	for_each_possible_cpu(cpu) {
-+		dev = get_cpu_device(cpu);
-+		np = of_node_get(dev->of_node);
-+		if (of_find_property(np, "#cooling-cells", NULL)) {
-+			cdev = of_cpufreq_cooling_register(np, cpumask_of(cpu));
-+			if (IS_ERR(cdev))
-+				pr_err("running cpufreq without cooling device: %ld\n",
-+				       PTR_ERR(cdev));
-+		}
-+		of_node_put(np);
-+	}
-+
-+	return 0;
-+
-+out_free_table:
-+	dev_pm_opp_free_cpufreq_table(cpu_dev, &freq_table);
-+out_put_node:
-+	of_node_put(np);
-+	return ret;
-+}
-+
-+static int krait_cpufreq_remove(struct platform_device *pdev)
-+{
-+	cpufreq_cooling_unregister(cdev);
-+	cpufreq_unregister_driver(&krait_cpufreq_driver);
-+	dev_pm_opp_free_cpufreq_table(cpu_dev, &freq_table);
-+
-+	return 0;
-+}
-+
-+static struct platform_driver krait_cpufreq_platdrv = {
-+	.driver = {
-+		.name	= "cpufreq-krait",
-+		.owner	= THIS_MODULE,
-+	},
-+	.probe		= krait_cpufreq_probe,
-+	.remove		= krait_cpufreq_remove,
-+};
-+module_platform_driver(krait_cpufreq_platdrv);
-+
-+MODULE_DESCRIPTION("Krait CPUfreq driver");
-+MODULE_LICENSE("GPL v2");
diff --git a/target/linux/ipq806x/patches/0173-cpufreq-Add-module-to-register-cpufreq-krait-device.patch b/target/linux/ipq806x/patches/0173-cpufreq-Add-module-to-register-cpufreq-krait-device.patch
deleted file mode 100644
index 373c402..0000000
--- a/target/linux/ipq806x/patches/0173-cpufreq-Add-module-to-register-cpufreq-krait-device.patch
+++ /dev/null
@@ -1,94 +0,0 @@
-From f1db56284b01b1212a211023dcaa7846fd07d0ec Mon Sep 17 00:00:00 2001
-From: Stephen Boyd <sboyd@codeaurora.org>
-Date: Fri, 30 May 2014 17:16:53 -0700
-Subject: [PATCH 173/182] cpufreq: Add module to register cpufreq-krait device
-
-Register a cpufreq-krait device whenever we detect that a
-"qcom,krait" compatible CPU is present in DT.
-
-Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
----
- drivers/cpufreq/Kconfig.arm    |    8 +++++++
- drivers/cpufreq/Makefile       |    1 +
- drivers/cpufreq/qcom-cpufreq.c |   48 ++++++++++++++++++++++++++++++++++++++++
- 3 files changed, 57 insertions(+)
- create mode 100644 drivers/cpufreq/qcom-cpufreq.c
-
---- a/drivers/cpufreq/Kconfig.arm
-+++ b/drivers/cpufreq/Kconfig.arm
-@@ -123,6 +123,14 @@ config ARM_OMAP2PLUS_CPUFREQ
- 	depends on ARCH_OMAP2PLUS
- 	default ARCH_OMAP2PLUS
- 
-+config ARM_QCOM_CPUFREQ
-+	tristate "Qualcomm based"
-+	depends on ARCH_QCOM
-+	help
-+	  This adds the CPUFreq driver for Qualcomm SoC based boards.
-+
-+	  If in doubt, say N.
-+
- config ARM_S3C_CPUFREQ
- 	bool
- 	help
---- a/drivers/cpufreq/Makefile
-+++ b/drivers/cpufreq/Makefile
-@@ -60,6 +60,7 @@ obj-$(CONFIG_ARM_IMX6Q_CPUFREQ)		+= imx6
- obj-$(CONFIG_ARM_INTEGRATOR)		+= integrator-cpufreq.o
- obj-$(CONFIG_ARM_KIRKWOOD_CPUFREQ)	+= kirkwood-cpufreq.o
- obj-$(CONFIG_ARM_OMAP2PLUS_CPUFREQ)	+= omap-cpufreq.o
-+obj-$(CONFIG_ARM_QCOM_CPUFREQ)		+= qcom-cpufreq.o
- obj-$(CONFIG_PXA25x)			+= pxa2xx-cpufreq.o
- obj-$(CONFIG_PXA27x)			+= pxa2xx-cpufreq.o
- obj-$(CONFIG_PXA3xx)			+= pxa3xx-cpufreq.o
---- /dev/null
-+++ b/drivers/cpufreq/qcom-cpufreq.c
-@@ -0,0 +1,48 @@
-+/* Copyright (c) 2014, The Linux Foundation. All rights reserved.
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 and
-+ * only version 2 as published by the Free Software Foundation.
-+ *
-+ * 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/kernel.h>
-+#include <linux/module.h>
-+#include <linux/cpu.h>
-+#include <linux/of.h>
-+#include <linux/platform_device.h>
-+#include <linux/err.h>
-+
-+static int qcom_cpufreq_driver_init(void)
-+{
-+	struct platform_device_info devinfo = { .name = "cpufreq-krait", };
-+	struct device *cpu_dev;
-+	struct device_node *np;
-+	struct platform_device *pdev;
-+
-+	cpu_dev = get_cpu_device(0);
-+	if (!cpu_dev)
-+		return -ENODEV;
-+
-+	np = of_node_get(cpu_dev->of_node);
-+	if (!np)
-+		return -ENOENT;
-+
-+	if (!of_device_is_compatible(np, "qcom,krait")) {
-+		of_node_put(np);
-+		return -ENODEV;
-+	}
-+	of_node_put(np);
-+
-+	pdev = platform_device_register_full(&devinfo);
-+
-+	return PTR_ERR_OR_ZERO(pdev);
-+}
-+module_init(qcom_cpufreq_driver_init);
-+
-+MODULE_DESCRIPTION("Qualcomm CPUfreq driver");
-+MODULE_LICENSE("GPL v2");
diff --git a/target/linux/ipq806x/patches/0174-clk-qcom-Add-HFPLLs-to-IPQ806X-driver.patch b/target/linux/ipq806x/patches/0174-clk-qcom-Add-HFPLLs-to-IPQ806X-driver.patch
deleted file mode 100644
index 682a519..0000000
--- a/target/linux/ipq806x/patches/0174-clk-qcom-Add-HFPLLs-to-IPQ806X-driver.patch
+++ /dev/null
@@ -1,116 +0,0 @@
-From b9b3815f2a71af88ca68d3524ee4d9b6b4739257 Mon Sep 17 00:00:00 2001
-From: Stephen Boyd <sboyd@codeaurora.org>
-Date: Wed, 18 Jun 2014 15:57:06 -0700
-Subject: [PATCH 174/182] clk: qcom: Add HFPLLs to IPQ806X driver
-
-Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
----
- drivers/clk/qcom/gcc-ipq806x.c |   83 ++++++++++++++++++++++++++++++++++++++++
- 1 file changed, 83 insertions(+)
-
---- a/drivers/clk/qcom/gcc-ipq806x.c
-+++ b/drivers/clk/qcom/gcc-ipq806x.c
-@@ -30,6 +30,7 @@
- #include "clk-pll.h"
- #include "clk-rcg.h"
- #include "clk-branch.h"
-+#include "clk-hfpll.h"
- #include "reset.h"
- 
- static struct clk_pll pll0 = {
-@@ -102,6 +103,85 @@ static struct clk_regmap pll8_vote = {
- 	},
- };
- 
-+static struct hfpll_data hfpll0_data = {
-+	.mode_reg = 0x3200,
-+	.l_reg = 0x3208,
-+	.m_reg = 0x320c,
-+	.n_reg = 0x3210,
-+	.config_reg = 0x3204,
-+	.status_reg = 0x321c,
-+        .config_val = 0x7845c665,
-+        .droop_reg = 0x3214,
-+        .droop_val = 0x0108c000,
-+	.min_rate = 600000000UL,
-+	.max_rate = 1800000000UL,
-+};
-+
-+static struct clk_hfpll hfpll0 = {
-+	.d = &hfpll0_data,
-+	.clkr.hw.init = &(struct clk_init_data){
-+		.parent_names = (const char *[]){ "pxo" },
-+		.num_parents = 1,
-+		.name = "hfpll0",
-+		.ops = &clk_ops_hfpll,
-+		.flags = CLK_IGNORE_UNUSED,
-+	},
-+	.lock = __SPIN_LOCK_UNLOCKED(hfpll0.lock),
-+};
-+
-+static struct hfpll_data hfpll1_data = {
-+	.mode_reg = 0x3240,
-+	.l_reg = 0x3248,
-+	.m_reg = 0x324c,
-+	.n_reg = 0x3250,
-+	.config_reg = 0x3244,
-+	.status_reg = 0x325c,
-+        .config_val = 0x7845c665,
-+        .droop_reg = 0x3314,
-+        .droop_val = 0x0108c000,
-+	.min_rate = 600000000UL,
-+	.max_rate = 1800000000UL,
-+};
-+
-+static struct clk_hfpll hfpll1 = {
-+	.d = &hfpll1_data,
-+	.clkr.hw.init = &(struct clk_init_data){
-+		.parent_names = (const char *[]){ "pxo" },
-+		.num_parents = 1,
-+		.name = "hfpll1",
-+		.ops = &clk_ops_hfpll,
-+		.flags = CLK_IGNORE_UNUSED,
-+	},
-+	.lock = __SPIN_LOCK_UNLOCKED(hfpll1.lock),
-+};
-+
-+static struct hfpll_data hfpll_l2_data = {
-+	.mode_reg = 0x3300,
-+	.l_reg = 0x3308,
-+	.m_reg = 0x330c,
-+	.n_reg = 0x3310,
-+	.config_reg = 0x3304,
-+	.status_reg = 0x331c,
-+        .config_val = 0x7845c665,
-+        .droop_reg = 0x3314,
-+        .droop_val = 0x0108c000,
-+	.min_rate = 600000000UL,
-+	.max_rate = 1800000000UL,
-+};
-+
-+static struct clk_hfpll hfpll_l2 = {
-+	.d = &hfpll_l2_data,
-+	.clkr.hw.init = &(struct clk_init_data){
-+		.parent_names = (const char *[]){ "pxo" },
-+		.num_parents = 1,
-+		.name = "hfpll_l2",
-+		.ops = &clk_ops_hfpll,
-+		.flags = CLK_IGNORE_UNUSED,
-+	},
-+	.lock = __SPIN_LOCK_UNLOCKED(hfpll_l2.lock),
-+};
-+
-+
- static struct clk_pll pll14 = {
- 	.l_reg = 0x31c4,
- 	.m_reg = 0x31c8,
-@@ -2878,6 +2958,9 @@ static struct clk_regmap *gcc_ipq806x_cl
- 	[NSSTCM_CLK_SRC] = &nss_tcm_src.clkr,
- 	[NSSTCM_CLK] = &nss_tcm_clk.clkr,
- 	[NSS_CORE_CLK] = &nss_core_clk,
-+	[PLL9] = &hfpll0.clkr,
-+	[PLL10] = &hfpll1.clkr,
-+	[PLL12] = &hfpll_l2.clkr,
- };
- 
- static const struct qcom_reset_map gcc_ipq806x_resets[] = {
diff --git a/target/linux/ipq806x/patches/0175-ARM-dts-ipq8064-Add-necessary-DT-data-for-Krait-cpuf.patch b/target/linux/ipq806x/patches/0175-ARM-dts-ipq8064-Add-necessary-DT-data-for-Krait-cpuf.patch
deleted file mode 100644
index 3fddd61..0000000
--- a/target/linux/ipq806x/patches/0175-ARM-dts-ipq8064-Add-necessary-DT-data-for-Krait-cpuf.patch
+++ /dev/null
@@ -1,91 +0,0 @@
-From 258a3ea23ec048603debe1621c681b0cc733f236 Mon Sep 17 00:00:00 2001
-From: Stephen Boyd <sboyd@codeaurora.org>
-Date: Wed, 18 Jun 2014 16:04:37 -0700
-Subject: [PATCH 175/182] ARM: dts: ipq8064: Add necessary DT data for Krait
- cpufreq
-
-Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
----
- arch/arm/boot/dts/qcom-ipq8064.dtsi |   45 +++++++++++++++++++++++++++++++++++
- 1 file changed, 45 insertions(+)
-
---- a/arch/arm/boot/dts/qcom-ipq8064.dtsi
-+++ b/arch/arm/boot/dts/qcom-ipq8064.dtsi
-@@ -23,6 +23,22 @@
- 			next-level-cache = <&L2>;
- 			qcom,acc = <&acc0>;
- 			qcom,saw = <&saw0>;
-+			clocks = <&kraitcc 0>;
-+			clock-names = "cpu";
-+			operating-points = <
-+				/* kHz    ignored */
-+				1400000 1000000
-+				1200000 1000000
-+				1000000 1000000
-+				 800000 1000000
-+				 600000 1000000
-+				 384000 1000000
-+			>;
-+			clock-latency = <100000>;
-+
-+			cooling-min-state = <0>;
-+			cooling-max-state = <10>;
-+			#cooling-cells = <2>;
- 		};
- 
- 		cpu@1 {
-@@ -33,6 +49,22 @@
- 			next-level-cache = <&L2>;
- 			qcom,acc = <&acc1>;
- 			qcom,saw = <&saw1>;
-+			clocks = <&kraitcc 1>;
-+			clock-names = "cpu";
-+			operating-points = <
-+				/* kHz    ignored */
-+				1400000 1000000
-+				1200000 1000000
-+				1000000 1000000
-+				 800000 1000000
-+				 600000 1000000
-+				 384000 1000000
-+			>;
-+			clock-latency = <100000>;
-+
-+			cooling-min-state = <0>;
-+			cooling-max-state = <10>;
-+			#cooling-cells = <2>;
- 		};
- 
- 		L2: l2-cache {
-@@ -46,6 +78,11 @@
- 		interrupts = <1 10 0x304>;
- 	};
- 
-+	kraitcc: clock-controller {
-+		compatible = "qcom,krait-cc-v1";
-+		#clock-cells = <1>;
-+	};
-+
- 	reserved-memory {
- 		#address-cells = <1>;
- 		#size-cells = <1>;
-@@ -102,11 +139,19 @@
- 		acc0: clock-controller@2088000 {
- 			compatible = "qcom,kpss-acc-v1";
- 			reg = <0x02088000 0x1000>, <0x02008000 0x1000>;
-+			clock-output-names = "acpu0_aux";
- 		};
- 
- 		acc1: clock-controller@2098000 {
- 			compatible = "qcom,kpss-acc-v1";
- 			reg = <0x02098000 0x1000>, <0x02008000 0x1000>;
-+			clock-output-names = "acpu1_aux";
-+		};
-+
-+		l2cc: clock-controller@2011000 {
-+			compatible = "qcom,kpss-gcc";
-+			reg = <0x2011000 0x1000>;
-+			clock-output-names = "acpu_l2_aux";
- 		};
- 
- 		saw0: regulator@2089000 {
diff --git a/target/linux/ipq806x/patches/0176-ARM-qcom_defconfig-Enable-CPUfreq-options.patch b/target/linux/ipq806x/patches/0176-ARM-qcom_defconfig-Enable-CPUfreq-options.patch
deleted file mode 100644
index 188580a..0000000
--- a/target/linux/ipq806x/patches/0176-ARM-qcom_defconfig-Enable-CPUfreq-options.patch
+++ /dev/null
@@ -1,39 +0,0 @@
-From e8f4d4bf1e4974bf8d17c6702fa4c410637216f3 Mon Sep 17 00:00:00 2001
-From: Stephen Boyd <sboyd@codeaurora.org>
-Date: Mon, 30 Jun 2014 10:50:14 -0700
-Subject: [PATCH 176/182] ARM: qcom_defconfig: Enable CPUfreq options
-
-Enable required options to allow the CPUfreq driver to probe on
-Krait based platforms.
-
-Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
----
- arch/arm/configs/qcom_defconfig |   10 ++++++++++
- 1 file changed, 10 insertions(+)
-
---- a/arch/arm/configs/qcom_defconfig
-+++ b/arch/arm/configs/qcom_defconfig
-@@ -31,6 +31,13 @@ CONFIG_HIGHPTE=y
- CONFIG_CLEANCACHE=y
- CONFIG_ARM_APPENDED_DTB=y
- CONFIG_ARM_ATAG_DTB_COMPAT=y
-+CONFIG_CPU_FREQ=y
-+CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y
-+CONFIG_CPU_FREQ_GOV_POWERSAVE=y
-+CONFIG_CPU_FREQ_GOV_USERSPACE=y
-+CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y
-+CONFIG_GENERIC_CPUFREQ_KRAIT=y
-+CONFIG_ARM_QCOM_CPUFREQ=y
- CONFIG_CPU_IDLE=y
- CONFIG_VFP=y
- CONFIG_NEON=y
-@@ -149,6 +156,9 @@ CONFIG_IPQ_GCC_806X=y
- CONFIG_MSM_GCC_8660=y
- CONFIG_MSM_MMCC_8960=y
- CONFIG_MSM_MMCC_8974=y
-+CONFIG_QCOM_HFPLL=y
-+CONFIG_KPSS_XCC=y
-+CONFIG_KRAITCC=y
- CONFIG_MSM_IOMMU=y
- CONFIG_PHY_QCOM_IPQ806X_SATA=y
- CONFIG_EXT2_FS=y
diff --git a/target/linux/ipq806x/patches/0177-dmaengine-Add-QCOM-ADM-DMA-driver.patch b/target/linux/ipq806x/patches/0177-dmaengine-Add-QCOM-ADM-DMA-driver.patch
deleted file mode 100644
index 05c6706..0000000
--- a/target/linux/ipq806x/patches/0177-dmaengine-Add-QCOM-ADM-DMA-driver.patch
+++ /dev/null
@@ -1,921 +0,0 @@
-From 8984e3fc6db029479d6aa78882b39235379aebff Mon Sep 17 00:00:00 2001
-From: Andy Gross <agross@codeaurora.org>
-Date: Wed, 14 May 2014 13:45:07 -0500
-Subject: [PATCH 177/182] dmaengine: Add QCOM ADM DMA driver
-
-Add the DMA engine driver for the QCOM Application Data Mover (ADM) DMA
-controller found in the MSM8960 and IPQ/APQ8064 platforms.
-
-The ADM supports both memory to memory transactions and memory
-to/from peripheral device transactions.  The controller also provides flow
-control capabilities for transactions to/from peripheral devices.
-
-The initial release of this driver supports slave transfers to/from peripherals
-and also incorporates CRCI (client rate control interface) flow control.
-
-Signed-off-by: Andy Gross <agross@codeaurora.org>
----
- drivers/dma/Kconfig    |   10 +
- drivers/dma/Makefile   |    1 +
- drivers/dma/qcom_adm.c |  871 ++++++++++++++++++++++++++++++++++++++++++++++++
- 3 files changed, 882 insertions(+)
- create mode 100644 drivers/dma/qcom_adm.c
-
---- a/drivers/dma/Kconfig
-+++ b/drivers/dma/Kconfig
-@@ -410,4 +410,14 @@ config QCOM_BAM_DMA
- 	  Enable support for the QCOM BAM DMA controller.  This controller
- 	  provides DMA capabilities for a variety of on-chip devices.
- 
-+config QCOM_ADM
-+	tristate "Qualcomm ADM support"
-+	depends on ARCH_QCOM || (COMPILE_TEST && OF && ARM)
-+	select DMA_ENGINE
-+	select DMA_VIRTUAL_CHANNELS
-+	---help---
-+	  Enable support for the Qualcomm ADM DMA controller.  This controller
-+	  provides DMA capabilities for both general purpose and on-chip
-+	  peripheral devices.
-+
- endif
---- a/drivers/dma/Makefile
-+++ b/drivers/dma/Makefile
-@@ -46,3 +46,4 @@ obj-$(CONFIG_K3_DMA) += k3dma.o
- obj-$(CONFIG_MOXART_DMA) += moxart-dma.o
- obj-$(CONFIG_FSL_EDMA) += fsl-edma.o
- obj-$(CONFIG_QCOM_BAM_DMA) += qcom_bam_dma.o
-+obj-$(CONFIG_QCOM_ADM) += qcom_adm.o
---- /dev/null
-+++ b/drivers/dma/qcom_adm.c
-@@ -0,0 +1,871 @@
-+/*
-+ * Copyright (c) 2013-2014, The Linux Foundation. All rights reserved.
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 and
-+ * only version 2 as published by the Free Software Foundation.
-+ *
-+ * 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/kernel.h>
-+#include <linux/io.h>
-+#include <linux/init.h>
-+#include <linux/slab.h>
-+#include <linux/module.h>
-+#include <linux/interrupt.h>
-+#include <linux/dma-mapping.h>
-+#include <linux/scatterlist.h>
-+#include <linux/device.h>
-+#include <linux/platform_device.h>
-+#include <linux/of.h>
-+#include <linux/of_address.h>
-+#include <linux/of_irq.h>
-+#include <linux/of_dma.h>
-+#include <linux/reset.h>
-+#include <linux/clk.h>
-+#include <linux/dmaengine.h>
-+
-+#include "dmaengine.h"
-+#include "virt-dma.h"
-+
-+/* ADM registers - calculated from channel number and security domain */
-+#define HI_CH_CMD_PTR(chan, ee)		(4*chan + 0x20800*ee)
-+#define HI_CH_RSLT(chan, ee)		(0x40 + 4*chan + 0x20800*ee)
-+#define HI_CH_FLUSH_STATE0(chan, ee)	(0x80 + 4*chan + 0x20800*ee)
-+#define HI_CH_FLUSH_STATE1(chan, ee)	(0xc0 + 4*chan + 0x20800*ee)
-+#define HI_CH_FLUSH_STATE2(chan, ee)	(0x100 + 4*chan + 0x20800*ee)
-+#define HI_CH_FLUSH_STATE3(chan, ee)	(0x140 + 4*chan + 0x20800*ee)
-+#define HI_CH_FLUSH_STATE4(chan, ee)	(0x180 + 4*chan + 0x20800*ee)
-+#define HI_CH_FLUSH_STATE5(chan, ee)	(0x1c0 + 4*chan + 0x20800*ee)
-+#define HI_CH_STATUS_SD(chan, ee)	(0x200 + 4*chan + 0x20800*ee)
-+#define HI_CH_CONF(chan)		(0x240 + 4*chan)
-+#define HI_CH_RSLT_CONF(chan, ee)	(0x300 + 4*chan + 0x20800*ee)
-+#define HI_SEC_DOMAIN_IRQ_STATUS(ee)	(0x380 + 0x20800*ee)
-+#define HI_CI_CONF(ci)			(0x390 + 4*ci)
-+#define HI_CRCI_CONF0			0x3d0
-+#define HI_CRCI_CONF1			0x3d4
-+#define HI_GP_CTL			0x3d8
-+#define HI_CRCI_CTL(chan, ee)		(0x400 + 0x4*chan + 0x20800*ee)
-+
-+/* channel status */
-+#define CH_STATUS_VALID	BIT(1)
-+
-+/* channel result */
-+#define CH_RSLT_VALID	BIT(31)
-+#define CH_RSLT_ERR	BIT(3)
-+#define CH_RSLT_FLUSH	BIT(2)
-+#define CH_RSLT_TPD	BIT(1)
-+
-+/* channel conf */
-+#define CH_CONF_MPU_DISABLE	BIT(11)
-+#define CH_CONF_PERM_MPU_CONF	BIT(9)
-+#define CH_CONF_FLUSH_RSLT_EN	BIT(8)
-+#define CH_CONF_FORCE_RSLT_EN	BIT(7)
-+#define CH_CONF_IRQ_EN		BIT(6)
-+
-+/* channel result conf */
-+#define CH_RSLT_CONF_FLUSH_EN	BIT(1)
-+#define CH_RSLT_CONF_IRQ_EN	BIT(0)
-+
-+/* CRCI CTL */
-+#define CRCI_CTL_RST	BIT(17)
-+
-+/* CI configuration */
-+#define CI_RANGE_END(x)		(x << 24)
-+#define CI_RANGE_START(x)	(x << 16)
-+#define CI_BURST_4_WORDS	0x4
-+#define CI_BURST_8_WORDS	0x8
-+
-+/* GP CTL */
-+#define GP_CTL_LP_EN		BIT(12)
-+#define GP_CTL_LP_CNT(x)	(x << 8)
-+
-+/* Command pointer list entry */
-+#define CPLE_LP		BIT(31)
-+
-+/* Command list entry */
-+#define CMD_LC			BIT(31)
-+#define CMD_DST_CRCI(n)		(((n) & 0xf) << 7)
-+#define CMD_SRC_CRCI(n)		(((n) & 0xf) << 3)
-+
-+#define CMD_TYPE_SINGLE		0x0
-+#define CMD_TYPE_BOX		0x3
-+
-+#define ADM_DESC_ALIGN	8
-+#define ADM_MAX_XFER	(SZ_64K-1)
-+#define ADM_MAX_ROWS	(SZ_64K-1)
-+
-+/* Command Pointer List Entry */
-+#define CMD_LP		BIT(31)
-+#define CMD_PT_MASK	(0x3 << 29)
-+#define CMD_ADDR_MASK	0x3fffffff
-+
-+struct adm_desc_hw {
-+	u32 cmd;
-+	u32 src_addr;
-+	u32 dst_addr;
-+	u32 row_len;
-+	u32 num_rows;
-+	u32 row_offset;
-+};
-+
-+struct adm_cmd_ptr_list {
-+	u32 cple;			/* command ptr list entry */
-+	struct adm_desc_hw desc[0];
-+};
-+
-+struct adm_async_desc {
-+	struct virt_dma_desc vd;
-+	struct adm_device *adev;
-+
-+	size_t length;
-+	enum dma_transfer_direction dir;
-+	dma_addr_t dma_addr;
-+	size_t dma_len;
-+
-+	struct adm_cmd_ptr_list *cpl;
-+	u32 num_desc;
-+};
-+
-+struct adm_chan {
-+	struct virt_dma_chan vc;
-+	struct adm_device *adev;
-+
-+	/* parsed from DT */
-+	u32 id;			/* channel id */
-+	u32 crci;		/* CRCI to be used for transfers */
-+	u32 blk_size;		/* block size for CRCI, default 16 byte */
-+
-+	struct adm_async_desc *curr_txd;
-+	struct dma_slave_config slave;
-+	struct list_head node;
-+
-+	int error;
-+	int initialized;
-+};
-+
-+static inline struct adm_chan *to_adm_chan(struct dma_chan *common)
-+{
-+	return container_of(common, struct adm_chan, vc.chan);
-+}
-+
-+struct adm_device {
-+	void __iomem *regs;
-+	struct device *dev;
-+	struct dma_device common;
-+	struct device_dma_parameters dma_parms;
-+	struct adm_chan *channels;
-+	u32 num_channels;
-+
-+	u32 ee;
-+
-+	struct clk *core_clk;
-+	struct clk *iface_clk;
-+
-+	struct reset_control *clk_reset;
-+	struct reset_control *c0_reset;
-+	struct reset_control *c1_reset;
-+	struct reset_control *c2_reset;
-+	int irq;
-+};
-+
-+/**
-+ * adm_alloc_chan - Allocates channel resources for DMA channel
-+ *
-+ * This function is effectively a stub, as we don't need to setup any resources
-+ */
-+static int adm_alloc_chan(struct dma_chan *chan)
-+{
-+	return 0;
-+}
-+
-+/**
-+ * adm_free_chan - Frees dma resources associated with the specific channel
-+ *
-+ * Free all allocated descriptors associated with this channel
-+ *
-+ */
-+static void adm_free_chan(struct dma_chan *chan)
-+{
-+	/* free all queued descriptors */
-+	vchan_free_chan_resources(to_virt_chan(chan));
-+}
-+
-+/**
-+ * adm_prep_slave_sg - Prep slave sg transaction
-+ *
-+ * @chan: dma channel
-+ * @sgl: scatter gather list
-+ * @sg_len: length of sg
-+ * @direction: DMA transfer direction
-+ * @flags: DMA flags
-+ * @context: transfer context (unused)
-+ */
-+static struct dma_async_tx_descriptor *adm_prep_slave_sg(struct dma_chan *chan,
-+	struct scatterlist *sgl, unsigned int sg_len,
-+	enum dma_transfer_direction direction, unsigned long flags,
-+	void *context)
-+{
-+	struct adm_chan *achan = to_adm_chan(chan);
-+	struct adm_device *adev = achan->adev;
-+	struct adm_async_desc *async_desc;
-+	struct scatterlist *sg;
-+	u32 i, rows, num_desc = 0, idx = 0, desc_offset;
-+	struct adm_desc_hw *desc;
-+	struct adm_cmd_ptr_list *cpl;
-+	u32 burst = ADM_MAX_XFER;
-+
-+
-+	if (!is_slave_direction(direction)) {
-+		dev_err(adev->dev, "invalid dma direction\n");
-+		return NULL;
-+	}
-+
-+	/* if using CRCI flow control, validate burst settings */
-+	if (achan->slave.device_fc) {
-+		burst = (direction == DMA_MEM_TO_DEV) ?
-+			achan->slave.dst_maxburst :
-+			achan->slave.src_maxburst;
-+
-+		if (!burst) {
-+			dev_err(adev->dev, "invalid burst value w/ crci: %d\n",
-+				burst);
-+			return ERR_PTR(-EINVAL);
-+		}
-+	}
-+
-+	/* iterate through sgs and compute allocation size of structures */
-+	for_each_sg(sgl, sg, sg_len, i) {
-+
-+		/* calculate boxes using burst */
-+		rows = DIV_ROUND_UP(sg_dma_len(sg), burst);
-+		num_desc += DIV_ROUND_UP(rows, ADM_MAX_ROWS);
-+
-+		/* flow control requires length as a multiple of burst */
-+		if (achan->slave.device_fc && (sg_dma_len(sg) % burst)) {
-+			dev_err(adev->dev, "length is not multiple of burst\n");
-+			return ERR_PTR(-EINVAL);
-+		}
-+	}
-+
-+	async_desc = kzalloc(sizeof(*async_desc), GFP_NOWAIT);
-+	if (!async_desc)
-+		return ERR_PTR(-ENOMEM);
-+
-+	async_desc->dma_len = num_desc * sizeof(*desc) + sizeof(*cpl) +
-+				ADM_DESC_ALIGN;
-+	async_desc->cpl = dma_alloc_writecombine(adev->dev, async_desc->dma_len,
-+			&async_desc->dma_addr, GFP_NOWAIT);
-+
-+	if (!async_desc->cpl) {
-+		kfree(async_desc);
-+		return ERR_PTR(-ENOMEM);
-+	}
-+
-+	async_desc->num_desc = num_desc;
-+	async_desc->adev = adev;
-+	cpl = PTR_ALIGN(async_desc->cpl, ADM_DESC_ALIGN);
-+	desc = PTR_ALIGN(&cpl->desc[0], ADM_DESC_ALIGN);
-+	desc_offset = (u32)desc - (u32)async_desc->cpl;
-+
-+	/* init cmd list */
-+	cpl->cple |= CPLE_LP;
-+	cpl->cple |= (async_desc->dma_addr + desc_offset) >> 3;
-+
-+	for_each_sg(sgl, sg, sg_len, i) {
-+		unsigned int remainder = sg_dma_len(sg);
-+		unsigned int curr_offset = 0;
-+		unsigned int row_len;
-+
-+		do {
-+			desc[idx].cmd = CMD_TYPE_BOX;
-+			desc[idx].row_offset = 0;
-+
-+			if (direction == DMA_DEV_TO_MEM) {
-+				desc[idx].dst_addr = sg_dma_address(sg) +
-+							curr_offset;
-+				desc[idx].src_addr = achan->slave.src_addr;
-+				desc[idx].cmd |= CMD_SRC_CRCI(achan->crci);
-+				desc[idx].row_offset = burst;
-+			} else {
-+				desc[idx].src_addr = sg_dma_address(sg) +
-+							curr_offset;
-+				desc[idx].dst_addr = achan->slave.dst_addr;
-+				desc[idx].cmd |= CMD_DST_CRCI(achan->crci);
-+				desc[idx].row_offset = burst << 16;
-+			}
-+
-+			if (remainder < burst) {
-+				rows = 1;
-+				row_len = remainder;
-+			} else {
-+				rows = remainder / burst;
-+				rows = min_t(u32, rows, ADM_MAX_ROWS);
-+				row_len = burst;
-+			}
-+
-+			desc[idx].num_rows = rows << 16 | rows;
-+			desc[idx].row_len = row_len << 16 | row_len;
-+
-+			remainder -= row_len * rows;
-+			async_desc->length += row_len * rows;
-+			curr_offset += row_len * rows;
-+
-+			idx++;
-+		} while (remainder > 0);
-+	}
-+
-+	/* set last command flag */
-+	desc[idx - 1].cmd |= CMD_LC;
-+
-+	/* reset channel error */
-+	achan->error = 0;
-+
-+	return vchan_tx_prep(&achan->vc, &async_desc->vd, flags);
-+}
-+
-+/**
-+ * adm_slave_config - set slave configuration for channel
-+ * @chan: dma channel
-+ * @cfg: slave configuration
-+ *
-+ * Sets slave configuration for channel
-+ *
-+ */
-+static int adm_slave_config(struct adm_chan *achan,
-+		struct dma_slave_config *cfg)
-+{
-+	int ret = 0;
-+	u32 burst;
-+	struct adm_device *adev = achan->adev;
-+
-+	memcpy(&achan->slave, cfg, sizeof(*cfg));
-+
-+	/* set channel CRCI burst, if applicable */
-+	if (achan->crci) {
-+		burst = max_t(u32, cfg->src_maxburst, cfg->dst_maxburst);
-+
-+		switch (burst) {
-+		case 16:
-+			achan->blk_size = 0;
-+			break;
-+		case 32:
-+			achan->blk_size = 1;
-+			break;
-+		case 64:
-+			achan->blk_size = 2;
-+			break;
-+		case 128:
-+			achan->blk_size = 3;
-+			break;
-+		case 192:
-+			achan->blk_size = 4;
-+			break;
-+		case 256:
-+			achan->blk_size = 5;
-+			break;
-+		default:
-+			achan->slave.src_maxburst = 0;
-+			achan->slave.dst_maxburst = 0;
-+			ret = -EINVAL;
-+			break;
-+		}
-+
-+		if (!ret)
-+			writel(achan->blk_size,
-+				adev->regs + HI_CRCI_CTL(achan->id, adev->ee));
-+	}
-+
-+	return ret;
-+}
-+
-+/**
-+ * adm_terminate_all - terminate all transactions on a channel
-+ * @achan: adm dma channel
-+ *
-+ * Dequeues and frees all transactions, aborts current transaction
-+ * No callbacks are done
-+ *
-+ */
-+static void adm_terminate_all(struct adm_chan *achan)
-+{
-+	struct adm_device *adev = achan->adev;
-+	unsigned long flags;
-+	LIST_HEAD(head);
-+
-+	/* send flush command to terminate current transaction */
-+	writel_relaxed(0x0,
-+		adev->regs + HI_CH_FLUSH_STATE0(achan->id, adev->ee));
-+
-+	spin_lock_irqsave(&achan->vc.lock, flags);
-+	vchan_get_all_descriptors(&achan->vc, &head);
-+	spin_unlock_irqrestore(&achan->vc.lock, flags);
-+
-+	vchan_dma_desc_free_list(&achan->vc, &head);
-+}
-+
-+/**
-+ * adm_control - DMA device control
-+ * @chan: dma channel
-+ * @cmd: control cmd
-+ * @arg: cmd argument
-+ *
-+ * Perform DMA control command
-+ *
-+ */
-+static int adm_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd,
-+	unsigned long arg)
-+{
-+	struct adm_chan *achan = to_adm_chan(chan);
-+	unsigned long flag;
-+	int ret = 0;
-+
-+	switch (cmd) {
-+	case DMA_SLAVE_CONFIG:
-+		spin_lock_irqsave(&achan->vc.lock, flag);
-+		ret = adm_slave_config(achan, (struct dma_slave_config *)arg);
-+		spin_unlock_irqrestore(&achan->vc.lock, flag);
-+		break;
-+
-+	case DMA_TERMINATE_ALL:
-+		adm_terminate_all(achan);
-+		break;
-+
-+	default:
-+		ret = -ENXIO;
-+		break;
-+	};
-+
-+	return ret;
-+}
-+
-+/**
-+ * adm_start_dma - start next transaction
-+ * @achan - ADM dma channel
-+ */
-+static void adm_start_dma(struct adm_chan *achan)
-+{
-+	struct virt_dma_desc *vd = vchan_next_desc(&achan->vc);
-+	struct adm_device *adev = achan->adev;
-+	struct adm_async_desc *async_desc;
-+	struct adm_desc_hw *desc;
-+	struct adm_cmd_ptr_list *cpl;
-+
-+	lockdep_assert_held(&achan->vc.lock);
-+
-+	if (!vd)
-+		return;
-+
-+	list_del(&vd->node);
-+
-+	/* write next command list out to the CMD FIFO */
-+	async_desc = container_of(vd, struct adm_async_desc, vd);
-+	achan->curr_txd = async_desc;
-+
-+	cpl = PTR_ALIGN(async_desc->cpl, ADM_DESC_ALIGN);
-+	desc = PTR_ALIGN(&cpl->desc[0], ADM_DESC_ALIGN);
-+
-+	if (!achan->initialized) {
-+		/* enable interrupts */
-+		writel(CH_CONF_IRQ_EN | CH_CONF_FLUSH_RSLT_EN |
-+			CH_CONF_FORCE_RSLT_EN | CH_CONF_PERM_MPU_CONF |
-+			CH_CONF_MPU_DISABLE,
-+			adev->regs + HI_CH_CONF(achan->id));
-+
-+		writel(CH_RSLT_CONF_IRQ_EN | CH_RSLT_CONF_FLUSH_EN,
-+			adev->regs + HI_CH_RSLT_CONF(achan->id, adev->ee));
-+
-+		if (achan->crci)
-+			writel(achan->blk_size, adev->regs +
-+				HI_CRCI_CTL(achan->crci, adev->ee));
-+
-+		achan->initialized = 1;
-+	}
-+
-+	/* make sure IRQ enable doesn't get reordered */
-+	wmb();
-+
-+	/* write next command list out to the CMD FIFO */
-+	writel(round_up(async_desc->dma_addr, ADM_DESC_ALIGN) >> 3,
-+		adev->regs + HI_CH_CMD_PTR(achan->id, adev->ee));
-+}
-+
-+/**
-+ * adm_dma_irq - irq handler for ADM controller
-+ * @irq: IRQ of interrupt
-+ * @data: callback data
-+ *
-+ * IRQ handler for the bam controller
-+ */
-+static irqreturn_t adm_dma_irq(int irq, void *data)
-+{
-+	struct adm_device *adev = data;
-+	u32 srcs, i;
-+	struct adm_async_desc *async_desc;
-+	unsigned long flags;
-+
-+	srcs = readl_relaxed(adev->regs +
-+			HI_SEC_DOMAIN_IRQ_STATUS(adev->ee));
-+
-+	for (i = 0; i < 16; i++) {
-+		struct adm_chan *achan = &adev->channels[i];
-+		u32 status, result;
-+		if (srcs & BIT(i)) {
-+			status = readl_relaxed(adev->regs +
-+				HI_CH_STATUS_SD(i, adev->ee));
-+
-+			/* if no result present, skip */
-+			if (!(status & CH_STATUS_VALID))
-+				continue;
-+
-+			result = readl_relaxed(adev->regs +
-+				HI_CH_RSLT(i, adev->ee));
-+
-+			/* no valid results, skip */
-+			if (!(result & CH_RSLT_VALID))
-+				continue;
-+
-+			/* flag error if transaction was flushed or failed */
-+			if (result & (CH_RSLT_ERR | CH_RSLT_FLUSH))
-+				achan->error = 1;
-+
-+			spin_lock_irqsave(&achan->vc.lock, flags);
-+			async_desc = achan->curr_txd;
-+
-+			achan->curr_txd = NULL;
-+
-+			if (async_desc) {
-+				vchan_cookie_complete(&async_desc->vd);
-+
-+				/* kick off next DMA */
-+				adm_start_dma(achan);
-+			}
-+
-+			spin_unlock_irqrestore(&achan->vc.lock, flags);
-+		}
-+	}
-+
-+	return IRQ_HANDLED;
-+}
-+
-+/**
-+ * adm_tx_status - returns status of transaction
-+ * @chan: dma channel
-+ * @cookie: transaction cookie
-+ * @txstate: DMA transaction state
-+ *
-+ * Return status of dma transaction
-+ */
-+static enum dma_status adm_tx_status(struct dma_chan *chan, dma_cookie_t cookie,
-+	struct dma_tx_state *txstate)
-+{
-+	struct adm_chan *achan = to_adm_chan(chan);
-+	struct virt_dma_desc *vd;
-+	enum dma_status ret;
-+	unsigned long flags;
-+	size_t residue = 0;
-+
-+	ret = dma_cookie_status(chan, cookie, txstate);
-+
-+	spin_lock_irqsave(&achan->vc.lock, flags);
-+
-+	vd = vchan_find_desc(&achan->vc, cookie);
-+	if (vd)
-+		residue = container_of(vd, struct adm_async_desc, vd)->length;
-+	else if (achan->curr_txd && achan->curr_txd->vd.tx.cookie == cookie)
-+		residue = achan->curr_txd->length;
-+
-+	spin_unlock_irqrestore(&achan->vc.lock, flags);
-+
-+	dma_set_residue(txstate, residue);
-+
-+	if (achan->error)
-+		return DMA_ERROR;
-+
-+	return ret;
-+}
-+
-+static struct dma_chan *adm_dma_xlate(struct of_phandle_args *dma_spec,
-+	struct of_dma *of)
-+{
-+	struct adm_device *adev = container_of(of->of_dma_data,
-+			struct adm_device, common);
-+	struct adm_chan *achan;
-+	struct dma_chan *chan;
-+	unsigned int request;
-+	unsigned int crci;
-+
-+	if (dma_spec->args_count != 2) {
-+		dev_err(adev->dev, "incorrect number of dma arguments\n");
-+		return NULL;
-+	}
-+
-+	request = dma_spec->args[0];
-+	if (request >= adev->num_channels)
-+		return NULL;
-+
-+	crci = dma_spec->args[1];
-+
-+	chan = dma_get_slave_channel(&(adev->channels[request].vc.chan));
-+
-+	if (!chan)
-+		return NULL;
-+
-+	achan = to_adm_chan(chan);
-+	achan->crci = crci;
-+
-+	return chan;
-+}
-+
-+/**
-+ * adm_issue_pending - starts pending transactions
-+ * @chan: dma channel
-+ *
-+ * Issues all pending transactions and starts DMA
-+ */
-+static void adm_issue_pending(struct dma_chan *chan)
-+{
-+	struct adm_chan *achan = to_adm_chan(chan);
-+	unsigned long flags;
-+
-+	spin_lock_irqsave(&achan->vc.lock, flags);
-+
-+	if (vchan_issue_pending(&achan->vc) && !achan->curr_txd)
-+		adm_start_dma(achan);
-+	spin_unlock_irqrestore(&achan->vc.lock, flags);
-+}
-+
-+/**
-+ * adm_dma_free_desc - free descriptor memory
-+ * @vd: virtual descriptor
-+ *
-+ */
-+static void adm_dma_free_desc(struct virt_dma_desc *vd)
-+{
-+	struct adm_async_desc *async_desc = container_of(vd,
-+			struct adm_async_desc, vd);
-+
-+	dma_free_writecombine(async_desc->adev->dev, async_desc->dma_len,
-+		async_desc->cpl, async_desc->dma_addr);
-+	kfree(async_desc);
-+}
-+
-+static void adm_channel_init(struct adm_device *adev, struct adm_chan *achan,
-+	u32 index)
-+{
-+	achan->id = index;
-+	achan->adev = adev;
-+
-+	vchan_init(&achan->vc, &adev->common);
-+	achan->vc.desc_free = adm_dma_free_desc;
-+}
-+
-+static int adm_dma_probe(struct platform_device *pdev)
-+{
-+	struct adm_device *adev;
-+	struct resource *iores;
-+	int ret;
-+	u32 i;
-+
-+	adev = devm_kzalloc(&pdev->dev, sizeof(*adev), GFP_KERNEL);
-+	if (!adev)
-+		return -ENOMEM;
-+
-+	adev->dev = &pdev->dev;
-+
-+	iores = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-+	adev->regs = devm_ioremap_resource(&pdev->dev, iores);
-+	if (IS_ERR(adev->regs))
-+		return PTR_ERR(adev->regs);
-+
-+	adev->irq = platform_get_irq(pdev, 0);
-+	if (adev->irq < 0)
-+		return adev->irq;
-+
-+	ret = of_property_read_u32(pdev->dev.of_node, "qcom,ee", &adev->ee);
-+	if (ret) {
-+		dev_err(adev->dev, "Execution environment unspecified\n");
-+		return ret;
-+	}
-+
-+	adev->core_clk = devm_clk_get(adev->dev, "core");
-+	if (IS_ERR(adev->core_clk))
-+		return PTR_ERR(adev->core_clk);
-+
-+	ret = clk_prepare_enable(adev->core_clk);
-+	if (ret) {
-+		dev_err(adev->dev, "failed to prepare/enable core clock\n");
-+		return ret;
-+	}
-+
-+	adev->iface_clk = devm_clk_get(adev->dev, "iface");
-+	if (IS_ERR(adev->iface_clk))
-+		return PTR_ERR(adev->iface_clk);
-+
-+	ret = clk_prepare_enable(adev->iface_clk);
-+	if (ret) {
-+		dev_err(adev->dev, "failed to prepare/enable iface clock\n");
-+		return ret;
-+	}
-+
-+	adev->clk_reset = devm_reset_control_get(&pdev->dev, "clk");
-+	if (IS_ERR(adev->clk_reset)) {
-+		dev_err(adev->dev, "failed to get ADM0 reset\n");
-+		return PTR_ERR(adev->clk_reset);
-+	}
-+
-+	adev->c0_reset = devm_reset_control_get(&pdev->dev, "c0");
-+	if (IS_ERR(adev->c0_reset)) {
-+		dev_err(adev->dev, "failed to get ADM0 C0 reset\n");
-+		return PTR_ERR(adev->c0_reset);
-+	}
-+
-+	adev->c1_reset = devm_reset_control_get(&pdev->dev, "c1");
-+	if (IS_ERR(adev->c1_reset)) {
-+		dev_err(adev->dev, "failed to get ADM0 C1 reset\n");
-+		return PTR_ERR(adev->c1_reset);
-+	}
-+
-+	adev->c2_reset = devm_reset_control_get(&pdev->dev, "c2");
-+	if (IS_ERR(adev->c2_reset)) {
-+		dev_err(adev->dev, "failed to get ADM0 C2 reset\n");
-+		return PTR_ERR(adev->c2_reset);
-+	}
-+
-+	reset_control_assert(adev->clk_reset);
-+	reset_control_assert(adev->c0_reset);
-+	reset_control_assert(adev->c1_reset);
-+	reset_control_assert(adev->c2_reset);
-+
-+	reset_control_deassert(adev->clk_reset);
-+	reset_control_deassert(adev->c0_reset);
-+	reset_control_deassert(adev->c1_reset);
-+	reset_control_deassert(adev->c2_reset);
-+
-+	adev->num_channels = 16;
-+
-+	adev->channels = devm_kcalloc(adev->dev, adev->num_channels,
-+				sizeof(*adev->channels), GFP_KERNEL);
-+
-+	if (!adev->channels) {
-+		ret = -ENOMEM;
-+		goto err_disable_clk;
-+	}
-+
-+	/* allocate and initialize channels */
-+	INIT_LIST_HEAD(&adev->common.channels);
-+
-+	for (i = 0; i < adev->num_channels; i++)
-+		adm_channel_init(adev, &adev->channels[i], i);
-+
-+	/* reset CRCIs */
-+	for (i = 0; i < 16; i++)
-+		writel(CRCI_CTL_RST, adev->regs + HI_CRCI_CTL(i, adev->ee));
-+
-+	/* configure client interfaces */
-+	writel(CI_RANGE_START(0x40) | CI_RANGE_END(0xb0) | CI_BURST_8_WORDS,
-+		adev->regs + HI_CI_CONF(0));
-+	writel(CI_RANGE_START(0x2a) | CI_RANGE_END(0x2c) | CI_BURST_8_WORDS,
-+		adev->regs + HI_CI_CONF(1));
-+	writel(CI_RANGE_START(0x12) | CI_RANGE_END(0x28) | CI_BURST_8_WORDS,
-+		adev->regs + HI_CI_CONF(2));
-+	writel(GP_CTL_LP_EN | GP_CTL_LP_CNT(0xf), adev->regs + HI_GP_CTL);
-+
-+	ret = devm_request_irq(adev->dev, adev->irq, adm_dma_irq,
-+			0, "adm_dma", adev);
-+	if (ret)
-+		goto err_disable_clk;
-+
-+	platform_set_drvdata(pdev, adev);
-+
-+	adev->common.dev = adev->dev;
-+	adev->common.dev->dma_parms = &adev->dma_parms;
-+
-+	/* set capabilities */
-+	dma_cap_zero(adev->common.cap_mask);
-+	dma_cap_set(DMA_SLAVE, adev->common.cap_mask);
-+	dma_cap_set(DMA_PRIVATE, adev->common.cap_mask);
-+
-+	/* initialize dmaengine apis */
-+	adev->common.device_alloc_chan_resources = adm_alloc_chan;
-+	adev->common.device_free_chan_resources = adm_free_chan;
-+	adev->common.device_prep_slave_sg = adm_prep_slave_sg;
-+	adev->common.device_control = adm_control;
-+	adev->common.device_issue_pending = adm_issue_pending;
-+	adev->common.device_tx_status = adm_tx_status;
-+
-+	ret = dma_async_device_register(&adev->common);
-+	if (ret) {
-+		dev_err(adev->dev, "failed to register dma async device\n");
-+		goto err_disable_clk;
-+	}
-+
-+	ret = of_dma_controller_register(pdev->dev.of_node, adm_dma_xlate,
-+					&adev->common);
-+	if (ret)
-+		goto err_unregister_dma;
-+
-+	return 0;
-+
-+err_unregister_dma:
-+	dma_async_device_unregister(&adev->common);
-+err_disable_clk:
-+	clk_disable_unprepare(adev->core_clk);
-+	clk_disable_unprepare(adev->iface_clk);
-+
-+	return ret;
-+}
-+
-+static int adm_dma_remove(struct platform_device *pdev)
-+{
-+	struct adm_device *adev = platform_get_drvdata(pdev);
-+	struct adm_chan *achan;
-+	u32 i;
-+
-+	of_dma_controller_free(pdev->dev.of_node);
-+	dma_async_device_unregister(&adev->common);
-+
-+	devm_free_irq(adev->dev, adev->irq, adev);
-+
-+	for (i = 0; i < adev->num_channels; i++) {
-+		achan = &adev->channels[i];
-+		writel(CH_CONF_FLUSH_RSLT_EN,
-+			adev->regs + HI_CH_CONF(achan->id));
-+		writel(CH_RSLT_CONF_FLUSH_EN,
-+			adev->regs + HI_CH_RSLT_CONF(achan->id, adev->ee));
-+
-+		adm_terminate_all(&adev->channels[i]);
-+	}
-+
-+	clk_disable_unprepare(adev->core_clk);
-+	clk_disable_unprepare(adev->iface_clk);
-+
-+	return 0;
-+}
-+
-+static const struct of_device_id adm_of_match[] = {
-+	{ .compatible = "qcom,adm", },
-+	{}
-+};
-+MODULE_DEVICE_TABLE(of, adm_of_match);
-+
-+static struct platform_driver adm_dma_driver = {
-+	.probe = adm_dma_probe,
-+	.remove = adm_dma_remove,
-+	.driver = {
-+		.name = "adm-dma-engine",
-+		.owner = THIS_MODULE,
-+		.of_match_table = adm_of_match,
-+	},
-+};
-+
-+module_platform_driver(adm_dma_driver);
-+
-+MODULE_AUTHOR("Andy Gross <agross@codeaurora.org>");
-+MODULE_DESCRIPTION("QCOM ADM DMA engine driver");
-+MODULE_LICENSE("GPL v2");
diff --git a/target/linux/ipq806x/patches/0178-dmaengine-qcom_adm-Add-device-tree-binding.patch b/target/linux/ipq806x/patches/0178-dmaengine-qcom_adm-Add-device-tree-binding.patch
deleted file mode 100644
index 1c72a2f..0000000
--- a/target/linux/ipq806x/patches/0178-dmaengine-qcom_adm-Add-device-tree-binding.patch
+++ /dev/null
@@ -1,76 +0,0 @@
-From 331294fa5c703536e27b79e9c112d162393f725a Mon Sep 17 00:00:00 2001
-From: Andy Gross <agross@codeaurora.org>
-Date: Thu, 26 Jun 2014 13:55:10 -0500
-Subject: [PATCH 178/182] dmaengine: qcom_adm: Add device tree binding
-
-Add device tree binding support for the QCOM ADM DMA driver.
-
-Signed-off-by: Andy Gross <agross@codeaurora.org>
----
- Documentation/devicetree/bindings/dma/qcom_adm.txt |   60 ++++++++++++++++++++
- 1 file changed, 60 insertions(+)
- create mode 100644 Documentation/devicetree/bindings/dma/qcom_adm.txt
-
---- /dev/null
-+++ b/Documentation/devicetree/bindings/dma/qcom_adm.txt
-@@ -0,0 +1,60 @@
-+QCOM ADM DMA Controller
-+
-+Required properties:
-+- compatible: must contain "qcom,adm" for IPQ/APQ8064 and MSM8960
-+- reg: Address range for DMA registers
-+- interrupts: Should contain one interrupt shared by all channels
-+- #dma-cells: must be <2>.  First cell denotes the channel number.  Second cell
-+  denotes CRCI (client rate control interface) flow control assignment.
-+- clocks: Should contain the core clock and interface clock.
-+- clock-names: Must contain "core" for the core clock and "iface" for the
-+  interface clock.
-+- resets: Must contain an entry for each entry in reset names.
-+- reset-names: Must include the following entries:
-+  - clk
-+  - c0
-+  - c1
-+  - c2
-+- qcom,ee: indicates the security domain identifier used in the secure world.
-+
-+Example:
-+		adm_dma: dma@18300000 {
-+			compatible = "qcom,adm";
-+			reg = <0x18300000 0x100000>;
-+			interrupts = <0 170 0>;
-+			#dma-cells = <2>;
-+
-+			clocks = <&gcc ADM0_CLK>, <&gcc ADM0_PBUS_CLK>;
-+			clock-names = "core", "iface";
-+
-+			resets = <&gcc ADM0_RESET>,
-+				<&gcc ADM0_C0_RESET>,
-+				<&gcc ADM0_C1_RESET>,
-+				<&gcc ADM0_C2_RESET>;
-+			reset-names = "clk", "c0", "c1", "c2";
-+			qcom,ee = <0>;
-+		};
-+
-+DMA clients must use the format descripted in the dma.txt file, using a three
-+cell specifier for each channel.
-+
-+Each dmas request consists of 3 cells:
-+ 1. phandle pointing to the DMA controller
-+ 2. channel number
-+ 3. CRCI assignment, if applicable.  If no CRCI flow control is required, use 0.
-+
-+Example:
-+
-+	spi4: spi@1a280000 {
-+		status = "ok";
-+		spi-max-frequency = <50000000>;
-+
-+		pinctrl-0 = <&spi_pins>;
-+		pinctrl-names = "default";
-+
-+		cs-gpios = <&qcom_pinmux 20 0>;
-+
-+		dmas = <&adm_dma 6 9>,
-+			<&adm_dma 5 10>;
-+		dma-names = "rx", "tx";
-+	};
diff --git a/target/linux/ipq806x/patches/0179-spi-qup-Add-DMA-capabilities.patch b/target/linux/ipq806x/patches/0179-spi-qup-Add-DMA-capabilities.patch
deleted file mode 100644
index 2f7d318..0000000
--- a/target/linux/ipq806x/patches/0179-spi-qup-Add-DMA-capabilities.patch
+++ /dev/null
@@ -1,490 +0,0 @@
-From 8322bafdcee1d7eaf15540ff013415bff1eacb28 Mon Sep 17 00:00:00 2001
-From: Andy Gross <agross@codeaurora.org>
-Date: Thu, 26 Jun 2014 10:50:24 -0500
-Subject: [PATCH 179/182] spi: qup: Add DMA capabilities
-
-This patch adds DMA capabilities to the spi-qup driver.  If DMA channels are
-present, the QUP will use DMA instead of block mode for transfers to/from SPI
-peripherals for transactions larger greater than the length of a block.
-
-Signed-off-by: Andy Gross <agross@codeaurora.org>
----
- drivers/spi/spi-qup.c |  361 ++++++++++++++++++++++++++++++++++++++++++++++---
- 1 file changed, 340 insertions(+), 21 deletions(-)
-
---- a/drivers/spi/spi-qup.c
-+++ b/drivers/spi/spi-qup.c
-@@ -22,6 +22,8 @@
- #include <linux/platform_device.h>
- #include <linux/pm_runtime.h>
- #include <linux/spi/spi.h>
-+#include <linux/dmaengine.h>
-+#include <linux/dma-mapping.h>
- 
- #define QUP_CONFIG			0x0000
- #define QUP_STATE			0x0004
-@@ -116,6 +118,8 @@
- 
- #define SPI_NUM_CHIPSELECTS		4
- 
-+#define SPI_MAX_XFER			(SZ_64K - 64)
-+
- /* high speed mode is when bus rate is greater then 26MHz */
- #define SPI_HS_MIN_RATE			26000000
- #define SPI_MAX_RATE			50000000
-@@ -143,6 +147,14 @@ struct spi_qup {
- 	int			tx_bytes;
- 	int			rx_bytes;
- 	int			qup_v1;
-+	int			use_dma;
-+
-+	struct dma_chan		*rx_chan;
-+	struct dma_slave_config	rx_conf;
-+	struct dma_chan		*tx_chan;
-+	struct dma_slave_config tx_conf;
-+	void *dummy;
-+	atomic_t		dma_outstanding;
- };
- 
- 
-@@ -266,6 +278,221 @@ static void spi_qup_fifo_write(struct sp
- 	}
- }
- 
-+static void qup_dma_callback(void *data)
-+{
-+	struct spi_qup *controller = data;
-+
-+	if (atomic_dec_and_test(&controller->dma_outstanding))
-+		complete(&controller->done);
-+}
-+
-+static int spi_qup_do_dma(struct spi_qup *controller, struct spi_transfer *xfer)
-+{
-+	struct dma_async_tx_descriptor *rxd, *txd;
-+	dma_cookie_t rx_cookie, tx_cookie;
-+	u32 xfer_len, rx_align = 0, tx_align = 0, n_words;
-+	struct scatterlist tx_sg[2], rx_sg[2];
-+	int ret = 0;
-+	u32 bytes_to_xfer = xfer->len;
-+	u32 offset = 0;
-+	u32 rx_nents = 0, tx_nents = 0;
-+	dma_addr_t rx_dma = 0, tx_dma = 0, rx_dummy_dma = 0, tx_dummy_dma = 0;
-+
-+
-+	if (xfer->rx_buf) {
-+		rx_dma = dma_map_single(controller->dev, xfer->rx_buf,
-+			xfer->len, DMA_FROM_DEVICE);
-+
-+		if (dma_mapping_error(controller->dev, rx_dma)) {
-+			ret = -ENOMEM;
-+			return ret;
-+		}
-+
-+		/* check to see if we need dummy buffer for leftover bytes */
-+		rx_align = xfer->len % controller->in_blk_sz;
-+		if (rx_align) {
-+			rx_dummy_dma = dma_map_single(controller->dev,
-+				controller->dummy, controller->in_fifo_sz,
-+				DMA_FROM_DEVICE);
-+
-+			if (dma_mapping_error(controller->dev, rx_dummy_dma)) {
-+				ret = -ENOMEM;
-+				goto err_map_rx_dummy;
-+			}
-+		}
-+	}
-+
-+	if (xfer->tx_buf) {
-+		tx_dma = dma_map_single(controller->dev,
-+			(void *)xfer->tx_buf, xfer->len, DMA_TO_DEVICE);
-+
-+		if (dma_mapping_error(controller->dev, tx_dma)) {
-+			ret = -ENOMEM;
-+			goto err_map_tx;
-+		}
-+
-+		/* check to see if we need dummy buffer for leftover bytes */
-+		tx_align = xfer->len % controller->out_blk_sz;
-+		if (tx_align) {
-+			memcpy(controller->dummy + SZ_1K,
-+				xfer->tx_buf + xfer->len - tx_align,
-+				tx_align);
-+			memset(controller->dummy + SZ_1K + tx_align, 0,
-+				controller->out_blk_sz - tx_align);
-+
-+			tx_dummy_dma = dma_map_single(controller->dev,
-+				controller->dummy + SZ_1K,
-+				controller->out_blk_sz, DMA_TO_DEVICE);
-+
-+			if (dma_mapping_error(controller->dev, tx_dummy_dma)) {
-+				ret = -ENOMEM;
-+				goto err_map_tx_dummy;
-+			}
-+		}
-+	}
-+
-+	atomic_set(&controller->dma_outstanding, 0);
-+
-+	while (bytes_to_xfer > 0) {
-+		xfer_len = min_t(u32, bytes_to_xfer, SPI_MAX_XFER);
-+		n_words = DIV_ROUND_UP(xfer_len, controller->w_size);
-+
-+		/* write out current word count to controller */
-+		writel_relaxed(n_words, controller->base + QUP_MX_INPUT_CNT);
-+		writel_relaxed(n_words, controller->base + QUP_MX_OUTPUT_CNT);
-+
-+		reinit_completion(&controller->done);
-+
-+		if (xfer->tx_buf) {
-+			/* recalc align for each transaction */
-+			tx_align = xfer_len % controller->out_blk_sz;
-+
-+			if (tx_align)
-+				tx_nents = 2;
-+			else
-+				tx_nents = 1;
-+
-+			/* initialize scatterlists */
-+			sg_init_table(tx_sg, tx_nents);
-+			sg_dma_len(&tx_sg[0]) = xfer_len - tx_align;
-+			sg_dma_address(&tx_sg[0]) = tx_dma + offset;
-+
-+			/* account for non block size transfer */
-+			if (tx_align) {
-+				sg_dma_len(&tx_sg[1]) = controller->out_blk_sz;
-+				sg_dma_address(&tx_sg[1]) = tx_dummy_dma;
-+			}
-+
-+			txd = dmaengine_prep_slave_sg(controller->tx_chan,
-+					tx_sg, tx_nents, DMA_MEM_TO_DEV, 0);
-+			if (!txd) {
-+				ret = -ENOMEM;
-+				goto err_unmap;
-+			}
-+
-+			atomic_inc(&controller->dma_outstanding);
-+
-+			txd->callback = qup_dma_callback;
-+			txd->callback_param = controller;
-+
-+			tx_cookie = dmaengine_submit(txd);
-+
-+			dma_async_issue_pending(controller->tx_chan);
-+		}
-+
-+		if (xfer->rx_buf) {
-+			/* recalc align for each transaction */
-+			rx_align = xfer_len % controller->in_blk_sz;
-+
-+			if (rx_align)
-+				rx_nents = 2;
-+			else
-+				rx_nents = 1;
-+
-+			/* initialize scatterlists */
-+			sg_init_table(rx_sg, rx_nents);
-+			sg_dma_address(&rx_sg[0]) = rx_dma + offset;
-+			sg_dma_len(&rx_sg[0]) = xfer_len - rx_align;
-+
-+			/* account for non block size transfer */
-+			if (rx_align) {
-+				sg_dma_len(&rx_sg[1]) = controller->in_blk_sz;
-+				sg_dma_address(&rx_sg[1]) = rx_dummy_dma;
-+			}
-+
-+			rxd = dmaengine_prep_slave_sg(controller->rx_chan,
-+					rx_sg, rx_nents, DMA_DEV_TO_MEM, 0);
-+			if (!rxd) {
-+				ret = -ENOMEM;
-+				goto err_unmap;
-+			}
-+
-+			atomic_inc(&controller->dma_outstanding);
-+
-+			rxd->callback = qup_dma_callback;
-+			rxd->callback_param = controller;
-+
-+			rx_cookie = dmaengine_submit(rxd);
-+
-+			dma_async_issue_pending(controller->rx_chan);
-+		}
-+
-+		if (spi_qup_set_state(controller, QUP_STATE_RUN)) {
-+			dev_warn(controller->dev, "cannot set EXECUTE state\n");
-+			goto err_unmap;
-+		}
-+
-+		if (!wait_for_completion_timeout(&controller->done,
-+			msecs_to_jiffies(1000))) {
-+			ret = -ETIMEDOUT;
-+
-+			/* clear out all the DMA transactions */
-+			if (xfer->tx_buf)
-+				dmaengine_terminate_all(controller->tx_chan);
-+			if (xfer->rx_buf)
-+				dmaengine_terminate_all(controller->rx_chan);
-+
-+			goto err_unmap;
-+		}
-+
-+		if (rx_align)
-+			memcpy(xfer->rx_buf + offset + xfer->len - rx_align,
-+				controller->dummy, rx_align);
-+
-+		/* adjust remaining bytes to transfer */
-+		bytes_to_xfer -= xfer_len;
-+		offset += xfer_len;
-+
-+
-+		/* reset mini-core state so we can program next transaction */
-+		if (spi_qup_set_state(controller, QUP_STATE_RESET)) {
-+			dev_err(controller->dev, "cannot set RESET state\n");
-+			goto err_unmap;
-+		}
-+	}
-+
-+	ret = 0;
-+
-+err_unmap:
-+	if (tx_align)
-+		dma_unmap_single(controller->dev, tx_dummy_dma,
-+			controller->out_fifo_sz, DMA_TO_DEVICE);
-+err_map_tx_dummy:
-+	if (xfer->tx_buf)
-+		dma_unmap_single(controller->dev, tx_dma, xfer->len,
-+			DMA_TO_DEVICE);
-+err_map_tx:
-+	if (rx_align)
-+		dma_unmap_single(controller->dev, rx_dummy_dma,
-+			controller->in_fifo_sz, DMA_FROM_DEVICE);
-+err_map_rx_dummy:
-+	if (xfer->rx_buf)
-+		dma_unmap_single(controller->dev, rx_dma, xfer->len,
-+			DMA_FROM_DEVICE);
-+
-+	return ret;
-+}
-+
- static irqreturn_t spi_qup_qup_irq(int irq, void *dev_id)
- {
- 	struct spi_qup *controller = dev_id;
-@@ -315,11 +542,13 @@ static irqreturn_t spi_qup_qup_irq(int i
- 		error = -EIO;
- 	}
- 
--	if (opflags & QUP_OP_IN_SERVICE_FLAG)
--		spi_qup_fifo_read(controller, xfer);
-+	if (!controller->use_dma) {
-+		if (opflags & QUP_OP_IN_SERVICE_FLAG)
-+			spi_qup_fifo_read(controller, xfer);
- 
--	if (opflags & QUP_OP_OUT_SERVICE_FLAG)
--		spi_qup_fifo_write(controller, xfer);
-+		if (opflags & QUP_OP_OUT_SERVICE_FLAG)
-+			spi_qup_fifo_write(controller, xfer);
-+	}
- 
- 	spin_lock_irqsave(&controller->lock, flags);
- 	controller->error = error;
-@@ -339,6 +568,8 @@ static int spi_qup_io_config(struct spi_
- 	struct spi_qup *controller = spi_master_get_devdata(spi->master);
- 	u32 config, iomode, mode;
- 	int ret, n_words, w_size;
-+	size_t dma_align = dma_get_cache_alignment();
-+	u32 dma_available = 0;
- 
- 	if (spi->mode & SPI_LOOP && xfer->len > controller->in_fifo_sz) {
- 		dev_err(controller->dev, "too big size for loopback %d > %d\n",
-@@ -367,6 +598,13 @@ static int spi_qup_io_config(struct spi_
- 	n_words = xfer->len / w_size;
- 	controller->w_size = w_size;
- 
-+	if (controller->rx_chan &&
-+		IS_ALIGNED((size_t)xfer->tx_buf, dma_align) &&
-+		IS_ALIGNED((size_t)xfer->rx_buf, dma_align) &&
-+		!is_vmalloc_addr(xfer->tx_buf) &&
-+		!is_vmalloc_addr(xfer->rx_buf))
-+		dma_available = 1;
-+
- 	if (n_words <= (controller->in_fifo_sz / sizeof(u32))) {
- 		mode = QUP_IO_M_MODE_FIFO;
- 		writel_relaxed(n_words, controller->base + QUP_MX_READ_CNT);
-@@ -374,19 +612,30 @@ static int spi_qup_io_config(struct spi_
- 		/* must be zero for FIFO */
- 		writel_relaxed(0, controller->base + QUP_MX_INPUT_CNT);
- 		writel_relaxed(0, controller->base + QUP_MX_OUTPUT_CNT);
--	} else {
-+		controller->use_dma = 0;
-+	} else if (!dma_available) {
- 		mode = QUP_IO_M_MODE_BLOCK;
- 		writel_relaxed(n_words, controller->base + QUP_MX_INPUT_CNT);
- 		writel_relaxed(n_words, controller->base + QUP_MX_OUTPUT_CNT);
- 		/* must be zero for BLOCK and BAM */
- 		writel_relaxed(0, controller->base + QUP_MX_READ_CNT);
- 		writel_relaxed(0, controller->base + QUP_MX_WRITE_CNT);
-+		controller->use_dma = 0;
-+	} else {
-+		mode = QUP_IO_M_MODE_DMOV;
-+		writel_relaxed(0, controller->base + QUP_MX_READ_CNT);
-+		writel_relaxed(0, controller->base + QUP_MX_WRITE_CNT);
-+		controller->use_dma = 1;
- 	}
- 
- 	iomode = readl_relaxed(controller->base + QUP_IO_M_MODES);
- 	/* Set input and output transfer mode */
- 	iomode &= ~(QUP_IO_M_INPUT_MODE_MASK | QUP_IO_M_OUTPUT_MODE_MASK);
--	iomode &= ~(QUP_IO_M_PACK_EN | QUP_IO_M_UNPACK_EN);
-+	if (!controller->use_dma)
-+		iomode &= ~(QUP_IO_M_PACK_EN | QUP_IO_M_UNPACK_EN);
-+	else
-+		iomode |= QUP_IO_M_PACK_EN | QUP_IO_M_UNPACK_EN;
-+
- 	iomode |= (mode << QUP_IO_M_OUTPUT_MODE_MASK_SHIFT);
- 	iomode |= (mode << QUP_IO_M_INPUT_MODE_MASK_SHIFT);
- 
-@@ -419,11 +668,20 @@ static int spi_qup_io_config(struct spi_
- 	config &= ~(QUP_CONFIG_NO_INPUT | QUP_CONFIG_NO_OUTPUT | QUP_CONFIG_N);
- 	config |= xfer->bits_per_word - 1;
- 	config |= QUP_CONFIG_SPI_MODE;
-+
-+	if (controller->use_dma) {
-+		if (!xfer->tx_buf)
-+			config |= QUP_CONFIG_NO_OUTPUT;
-+		if (!xfer->rx_buf)
-+			config |= QUP_CONFIG_NO_INPUT;
-+	}
-+
- 	writel_relaxed(config, controller->base + QUP_CONFIG);
- 
- 	/* only write to OPERATIONAL_MASK when register is present */
- 	if (!controller->qup_v1)
- 		writel_relaxed(0, controller->base + QUP_OPERATIONAL_MASK);
-+
- 	return 0;
- }
- 
-@@ -452,26 +710,32 @@ static int spi_qup_transfer_one(struct s
- 	controller->tx_bytes = 0;
- 	spin_unlock_irqrestore(&controller->lock, flags);
- 
--	if (spi_qup_set_state(controller, QUP_STATE_RUN)) {
--		dev_warn(controller->dev, "cannot set RUN state\n");
--		goto exit;
--	}
-+	if (controller->use_dma) {
-+		ret = spi_qup_do_dma(controller, xfer);
-+	} else {
-+		if (spi_qup_set_state(controller, QUP_STATE_RUN)) {
-+			dev_warn(controller->dev, "cannot set RUN state\n");
-+			goto exit;
-+		}
- 
--	if (spi_qup_set_state(controller, QUP_STATE_PAUSE)) {
--		dev_warn(controller->dev, "cannot set PAUSE state\n");
--		goto exit;
--	}
-+		if (spi_qup_set_state(controller, QUP_STATE_PAUSE)) {
-+			dev_warn(controller->dev, "cannot set PAUSE state\n");
-+			goto exit;
-+		}
- 
--	spi_qup_fifo_write(controller, xfer);
-+		spi_qup_fifo_write(controller, xfer);
- 
--	if (spi_qup_set_state(controller, QUP_STATE_RUN)) {
--		dev_warn(controller->dev, "cannot set EXECUTE state\n");
--		goto exit;
--	}
-+		if (spi_qup_set_state(controller, QUP_STATE_RUN)) {
-+			dev_warn(controller->dev, "cannot set EXECUTE state\n");
-+			goto exit;
-+		}
- 
--	if (!wait_for_completion_timeout(&controller->done, timeout))
--		ret = -ETIMEDOUT;
-+		if (!ret && !wait_for_completion_timeout(&controller->done,
-+				timeout))
-+			ret = -ETIMEDOUT;
-+	}
- exit:
-+
- 	spi_qup_set_state(controller, QUP_STATE_RESET);
- 	spin_lock_irqsave(&controller->lock, flags);
- 	controller->xfer = NULL;
-@@ -553,6 +817,7 @@ static int spi_qup_probe(struct platform
- 	master->transfer_one = spi_qup_transfer_one;
- 	master->dev.of_node = pdev->dev.of_node;
- 	master->auto_runtime_pm = true;
-+	master->dma_alignment = dma_get_cache_alignment();
- 
- 	platform_set_drvdata(pdev, master);
- 
-@@ -612,6 +877,55 @@ static int spi_qup_probe(struct platform
- 	writel_relaxed(SPI_ERROR_CLK_UNDER_RUN | SPI_ERROR_CLK_OVER_RUN,
- 		       base + SPI_ERROR_FLAGS_EN);
- 
-+	/* allocate dma resources, if available */
-+	controller->rx_chan = dma_request_slave_channel(&pdev->dev, "rx");
-+	if (controller->rx_chan) {
-+		controller->tx_chan =
-+			dma_request_slave_channel(&pdev->dev, "tx");
-+
-+		if (!controller->tx_chan) {
-+			dev_err(&pdev->dev, "Failed to allocate dma tx chan");
-+			dma_release_channel(controller->rx_chan);
-+		}
-+
-+		/* set DMA parameters */
-+		controller->rx_conf.device_fc = 1;
-+		controller->rx_conf.src_addr = res->start + QUP_INPUT_FIFO;
-+		controller->rx_conf.src_maxburst = controller->in_blk_sz;
-+
-+		controller->tx_conf.device_fc = 1;
-+		controller->tx_conf.dst_addr = res->start + QUP_OUTPUT_FIFO;
-+		controller->tx_conf.dst_maxburst = controller->out_blk_sz;
-+
-+		if (dmaengine_slave_config(controller->rx_chan,
-+				&controller->rx_conf)) {
-+			dev_err(&pdev->dev, "failed to configure RX channel\n");
-+
-+			dma_release_channel(controller->rx_chan);
-+			dma_release_channel(controller->tx_chan);
-+			controller->tx_chan = NULL;
-+			controller->rx_chan = NULL;
-+		} else if (dmaengine_slave_config(controller->tx_chan,
-+				&controller->tx_conf)) {
-+			dev_err(&pdev->dev, "failed to configure TX channel\n");
-+
-+			dma_release_channel(controller->rx_chan);
-+			dma_release_channel(controller->tx_chan);
-+			controller->tx_chan = NULL;
-+			controller->rx_chan = NULL;
-+		}
-+
-+		controller->dummy = devm_kmalloc(controller->dev, PAGE_SIZE,
-+			GFP_KERNEL);
-+
-+		if (!controller->dummy) {
-+			dma_release_channel(controller->rx_chan);
-+			dma_release_channel(controller->tx_chan);
-+			controller->tx_chan = NULL;
-+			controller->rx_chan = NULL;
-+		}
-+	}
-+
- 	/* if earlier version of the QUP, disable INPUT_OVERRUN */
- 	if (controller->qup_v1)
- 		writel_relaxed(QUP_ERROR_OUTPUT_OVER_RUN |
-@@ -730,6 +1044,11 @@ static int spi_qup_remove(struct platfor
- 	if (ret)
- 		return ret;
- 
-+	if (controller->rx_chan)
-+		dma_release_channel(controller->rx_chan);
-+	if (controller->tx_chan)
-+		dma_release_channel(controller->tx_chan);
-+
- 	clk_disable_unprepare(controller->cclk);
- 	clk_disable_unprepare(controller->iclk);
- 
diff --git a/target/linux/ipq806x/patches/0180-ARM-dts-Add-ADM-DMA-nodes-and-SPI-linkage.patch b/target/linux/ipq806x/patches/0180-ARM-dts-Add-ADM-DMA-nodes-and-SPI-linkage.patch
deleted file mode 100644
index 05279de..0000000
--- a/target/linux/ipq806x/patches/0180-ARM-dts-Add-ADM-DMA-nodes-and-SPI-linkage.patch
+++ /dev/null
@@ -1,83 +0,0 @@
-From c78ae23b6c174c9f2e0973a247942b6b4adb7e82 Mon Sep 17 00:00:00 2001
-From: Andy Gross <agross@codeaurora.org>
-Date: Thu, 26 Jun 2014 13:02:59 -0500
-Subject: [PATCH 180/182] ARM: dts: Add ADM DMA nodes and SPI linkage
-
-This patch adds the ADM DMA controller DT nodes and also enables the use of dma
-in SPI.
-
-Signed-off-by: Andy Gross <agross@codeaurora.org>
----
- arch/arm/boot/dts/qcom-ipq8064-ap148.dts |   11 +++++++++++
- arch/arm/boot/dts/qcom-ipq8064.dtsi      |    8 +++++---
- 2 files changed, 16 insertions(+), 3 deletions(-)
-
---- a/arch/arm/boot/dts/qcom-ipq8064-ap148.dts
-+++ b/arch/arm/boot/dts/qcom-ipq8064-ap148.dts
-@@ -44,6 +44,10 @@
- 					drive-strength = <10>;
- 					bias-none;
- 				};
-+				cs {
-+					pins = "gpio20";
-+					drive-strength = <12>;
-+				};
- 			};
- 			nand_pins: nand_pins {
- 				mux {
-@@ -100,12 +104,17 @@
- 
- 				cs-gpios = <&qcom_pinmux 20 0>;
- 
-+				dmas = <&adm_dma 6 9>,
-+					<&adm_dma 5 10>;
-+				dma-names = "rx", "tx";
-+
- 				flash: m25p80@0 {
- 					compatible = "s25fl256s1";
- 					#address-cells = <1>;
- 					#size-cells = <1>;
- 					spi-max-frequency = <50000000>;
- 					reg = <0>;
-+					m25p,fast-read;
- 
- 					partition@0 {
- 						label = "rootfs";
-@@ -140,8 +149,10 @@
- 			ranges = <0x00000000 0 0x00000000 0x31f00000 0 0x00100000   /* configuration space */
- 				  0x81000000 0 0	  0x31e00000 0 0x00100000   /* downstream I/O */
- 				  0x82000000 0 0x00000000 0x2e000000 0 0x03e00000>; /* non-prefetchable memory */
-+
- 		};
- 
-+
- 		sata-phy@1b400000 {
- 			status = "ok";
- 		};
---- a/arch/arm/boot/dts/qcom-ipq8064.dtsi
-+++ b/arch/arm/boot/dts/qcom-ipq8064.dtsi
-@@ -421,19 +421,21 @@
- 			compatible = "qcom,adm";
- 			reg = <0x18300000 0x100000>;
- 			interrupts = <0 170 0>;
-+			#dma-cells = <2>;
- 
- 			clocks = <&gcc ADM0_CLK>, <&gcc ADM0_PBUS_CLK>;
--			clock-names = "core_clk", "iface_clk";
-+			clock-names = "core", "iface";
- 
- 			resets = <&gcc ADM0_RESET>,
- 				<&gcc ADM0_PBUS_RESET>,
- 				<&gcc ADM0_C0_RESET>,
- 				<&gcc ADM0_C1_RESET>,
- 				<&gcc ADM0_C2_RESET>;
--
--			reset-names = "adm", "pbus", "c0", "c1", "c2";
-+			reset-names = "clk", "pbus", "c0", "c1", "c2";
-+			qcom,ee = <0>;
- 
- 			status = "disabled";
-+
- 		};
- 
- 		nand@0x1ac00000 {
diff --git a/target/linux/ipq806x/patches/0181-mtd-nand-qcom-Align-clk-and-reset-names.patch b/target/linux/ipq806x/patches/0181-mtd-nand-qcom-Align-clk-and-reset-names.patch
deleted file mode 100644
index e2e313c..0000000
--- a/target/linux/ipq806x/patches/0181-mtd-nand-qcom-Align-clk-and-reset-names.patch
+++ /dev/null
@@ -1,41 +0,0 @@
-From ae0e9ee3bcfafc5bd5932b544e0a5c107948fc97 Mon Sep 17 00:00:00 2001
-From: Andy Gross <agross@codeaurora.org>
-Date: Mon, 30 Jun 2014 21:17:26 -0500
-Subject: [PATCH 181/182] mtd: nand: qcom: Align clk and reset names
-
-This patch aligns the clk and reset names to the same ones that the dmaengine
-driver uses.
-
-Signed-off-by: Andy Gross <agross@codeaurora.org>
----
- drivers/mtd/nand/qcom_adm_dma.c |    6 +++---
- 1 file changed, 3 insertions(+), 3 deletions(-)
-
---- a/drivers/mtd/nand/qcom_adm_dma.c
-+++ b/drivers/mtd/nand/qcom_adm_dma.c
-@@ -568,14 +568,14 @@ static int msm_dmov_init_clocks(struct p
- 	int adm = (pdev->id >= 0) ? pdev->id : 0;
- 	int ret;
- 
--	dmov_conf[adm].clk = devm_clk_get(&pdev->dev, "core_clk");
-+	dmov_conf[adm].clk = devm_clk_get(&pdev->dev, "core");
- 	if (IS_ERR(dmov_conf[adm].clk)) {
- 		printk(KERN_ERR "%s: Error getting adm_clk\n", __func__);
- 		dmov_conf[adm].clk = NULL;
- 		return -ENOENT;
- 	}
- 
--	dmov_conf[adm].pclk = devm_clk_get(&pdev->dev, "iface_clk");
-+	dmov_conf[adm].pclk = devm_clk_get(&pdev->dev, "iface");
- 	if (IS_ERR(dmov_conf[adm].pclk)) {
- 		dmov_conf[adm].pclk = NULL;
- 		/* pclk not present on all SoCs, don't bail on failure */
-@@ -690,7 +690,7 @@ static int msm_dmov_probe(struct platfor
- 	}
- 
- 	/* get resets */
--	dmov_conf[adm].adm_reset = devm_reset_control_get(&pdev->dev, "adm");
-+	dmov_conf[adm].adm_reset = devm_reset_control_get(&pdev->dev, "clk");
- 	if (IS_ERR(dmov_conf[adm].adm_reset)) {
- 		dev_err(&pdev->dev, "failed to get adm reset\n");
- 		ret = PTR_ERR(dmov_conf[adm].adm_reset);
diff --git a/target/linux/ipq806x/patches/0182-qcom-Kconfig-Make-drivers-mutually-exclusive.patch b/target/linux/ipq806x/patches/0182-qcom-Kconfig-Make-drivers-mutually-exclusive.patch
deleted file mode 100644
index f4b551b..0000000
--- a/target/linux/ipq806x/patches/0182-qcom-Kconfig-Make-drivers-mutually-exclusive.patch
+++ /dev/null
@@ -1,47 +0,0 @@
-From 0771849495b4128cac2faf7d49c85c729fc48b20 Mon Sep 17 00:00:00 2001
-From: Andy Gross <agross@codeaurora.org>
-Date: Mon, 30 Jun 2014 21:18:39 -0500
-Subject: [PATCH 182/182] qcom: Kconfig: Make drivers mutually exclusive
-
-This patch makes sure QCOM ADM dmaengine and QCOM Nand cannot be enabled at the
-same time.  This is an issue because the dma drivers will conflict with one
-another.
-
-Signed-off-by: Andy Gross <agross@codeaurora.org>
----
- drivers/dma/Kconfig      |    2 +-
- drivers/mtd/nand/Kconfig |    6 +++---
- 2 files changed, 4 insertions(+), 4 deletions(-)
-
---- a/drivers/dma/Kconfig
-+++ b/drivers/dma/Kconfig
-@@ -412,7 +412,7 @@ config QCOM_BAM_DMA
- 
- config QCOM_ADM
- 	tristate "Qualcomm ADM support"
--	depends on ARCH_QCOM || (COMPILE_TEST && OF && ARM)
-+	depends on !MTD_QCOM_ADM && (ARCH_QCOM || (COMPILE_TEST && OF && ARM))
- 	select DMA_ENGINE
- 	select DMA_VIRTUAL_CHANNELS
- 	---help---
---- a/drivers/mtd/nand/Kconfig
-+++ b/drivers/mtd/nand/Kconfig
-@@ -511,15 +511,15 @@ config MTD_NAND_XWAY
- 	  to the External Bus Unit (EBU).
- 
- config MTD_QCOM_DMA
--	tristate "QCMO NAND DMA Support"
--	depends on ARCH_QCOM && MTD_QCOM_NAND
-+	tristate "QCOM NAND DMA Support"
-+	depends on !QCOM_ADM && ARCH_QCOM && MTD_QCOM_NAND
- 	default n
- 	help
- 	  DMA support for QCOM NAND
- 
- config MTD_QCOM_NAND
- 	tristate "QCOM NAND Device Support"
--	depends on MTD && ARCH_QCOM
-+	depends on MTD && ARCH_QCOM && !QCOM_ADM
- 	select CRC16
- 	select BITREVERSE
- 	select MTD_NAND_IDS
