diff --git a/target/linux/ipq806x/Makefile b/target/linux/ipq806x/Makefile
index a4d2bff59e6bd3fa016ecdf2c5a3aa84e3f816ef..d070b05e00864d7c98dfdf71010cdb2916058a3d 100644
--- a/target/linux/ipq806x/Makefile
+++ b/target/linux/ipq806x/Makefile
@@ -10,7 +10,7 @@ CPU_TYPE:=cortex-a9
 CPU_SUBTYPE:=neon-vfpv4
 MAINTAINER:=John Crispin <john@phrozen.org>
 
-KERNEL_PATCHVER:=3.18
+KERNEL_PATCHVER:=4.4
 
 KERNELNAME:=zImage Image dtbs
 
diff --git a/target/linux/ipq806x/config-3.18 b/target/linux/ipq806x/config-3.18
deleted file mode 100644
index 68a8933748d3e54b57ab9e1267e8691ba1198b43..0000000000000000000000000000000000000000
--- a/target/linux/ipq806x/config-3.18
+++ /dev/null
@@ -1,452 +0,0 @@
-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_AR8216_PHY=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_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_APPENDED_DTB=y
-CONFIG_ARM_ARCH_TIMER=y
-CONFIG_ARM_ARCH_TIMER_EVTSTREAM=y
-# CONFIG_ARM_ATAG_DTB_COMPAT is not set
-CONFIG_ARM_CPU_SUSPEND=y
-CONFIG_ARM_GIC=y
-CONFIG_ARM_HAS_SG_CHAIN=y
-# CONFIG_ARM_KIRKWOOD_CPUFREQ is not set
-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_QCOM_CPUFREQ=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_AT803X_PHY=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_CPUFREQ_DT is not set
-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_FREQ=y
-# CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE is not set
-# CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND is not set
-CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y
-# CONFIG_CPU_FREQ_DEFAULT_GOV_POWERSAVE is not set
-# CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set
-# CONFIG_CPU_FREQ_GOV_CONSERVATIVE is not set
-# CONFIG_CPU_FREQ_GOV_ONDEMAND is not set
-CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
-# CONFIG_CPU_FREQ_GOV_POWERSAVE is not set
-# CONFIG_CPU_FREQ_GOV_USERSPACE is not set
-CONFIG_CPU_FREQ_STAT=y
-# CONFIG_CPU_FREQ_STAT_DETAILS is not set
-CONFIG_CPU_HAS_ASID=y
-# CONFIG_CPU_ICACHE_DISABLE is not set
-CONFIG_CPU_IDLE=y
-CONFIG_CPU_IDLE_GOV_LADDER=y
-CONFIG_CPU_IDLE_GOV_MENU=y
-CONFIG_CPU_PABRT_V7=y
-CONFIG_CPU_PM=y
-CONFIG_CPU_RMAP=y
-# CONFIG_CPU_THERMAL is not set
-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_DEFLATE=y
-CONFIG_CRYPTO_LZO=y
-CONFIG_CRYPTO_RNG2=y
-# CONFIG_CRYPTO_SHA1_ARM_NEON is not set
-# CONFIG_CRYPTO_SHA512_ARM_NEON is not set
-CONFIG_CRYPTO_WORKQUEUE=y
-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_DWMAC_GENERIC is not set
-CONFIG_DWMAC_IPQ806X=y
-# CONFIG_DWMAC_LPC18XX is not set
-# CONFIG_DWMAC_MESON is not set
-# CONFIG_DWMAC_ROCKCHIP is not set
-# CONFIG_DWMAC_SOCFPGA is not set
-# CONFIG_DWMAC_STI is not set
-# CONFIG_DWMAC_SUNXI is not set
-# CONFIG_DW_DMAC_CORE is not set
-# CONFIG_DW_DMAC_PCI is not set
-CONFIG_DYNAMIC_DEBUG=y
-CONFIG_ETHERNET_PACKET_MANGLE=y
-CONFIG_FIXED_PHY=y
-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_CPUFREQ_KRAIT=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_HWSPINLOCK=y
-CONFIG_HWSPINLOCK_QCOM=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_KPSS_XCC=y
-CONFIG_KRAITCC=y
-CONFIG_KRAIT_CLOCKS=y
-CONFIG_KRAIT_L2_ACCESSORS=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_QCOM_RPM=y
-# CONFIG_MFD_SPMI_PMIC is not set
-CONFIG_MFD_SYSCON=y
-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_IMPA7 is not set
-CONFIG_MTD_JEDECPROBE=y
-CONFIG_MTD_M25P80=y
-CONFIG_MTD_NAND=y
-CONFIG_MTD_NAND_ECC=y
-CONFIG_MTD_NAND_QCOM=y
-CONFIG_MTD_QCOM_SMEM_PARTS=y
-CONFIG_MTD_SPI_NOR=y
-CONFIG_MTD_SPLIT_FIRMWARE=y
-CONFIG_MTD_SPLIT_FIT_FW=y
-CONFIG_MTD_UBI=y
-CONFIG_MTD_UBI_BEB_LIMIT=20
-CONFIG_MTD_UBI_BLOCK=y
-# CONFIG_MTD_UBI_FASTMAP is not set
-# CONFIG_MTD_UBI_GLUEBI is not set
-CONFIG_MTD_UBI_WL_THRESHOLD=4096
-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_PTP_CLASSIFY=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_PCIEAER=y
-CONFIG_PCIEPORTBUS=y
-CONFIG_PCIE_DW=y
-CONFIG_PCIE_PME=y
-CONFIG_PCIE_QCOM=y
-CONFIG_PCI_DOMAINS=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_OPP=y
-CONFIG_PM_RUNTIME=y
-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_PPS=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_PTP_1588_CLOCK=y
-CONFIG_QCOM_ADM=y
-CONFIG_QCOM_BAM_DMA=y
-CONFIG_QCOM_GSBI=y
-CONFIG_QCOM_HFPLL=y
-CONFIG_QCOM_SCM=y
-CONFIG_QCOM_SMEM=y
-CONFIG_QCOM_WDT=y
-CONFIG_RAS=y
-# 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_QCOM_RPM=y
-# 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_STMMAC_ETH=y
-CONFIG_STMMAC_PLATFORM=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_UBIFS_FS=y
-# CONFIG_UBIFS_FS_ADVANCED_COMPR is not set
-CONFIG_UBIFS_FS_LZO=y
-CONFIG_UBIFS_FS_XZ=y
-CONFIG_UBIFS_FS_ZLIB=y
-CONFIG_UEVENT_HELPER_PATH=""
-CONFIG_UID16=y
-CONFIG_UNCOMPRESS_INCLUDE="debug/uncompress.h"
-CONFIG_UNINLINE_SPIN_UNLOCK=y
-CONFIG_USB_SUPPORT=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_WATCHDOG_CORE=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_XPS=y
-CONFIG_XZ_DEC_ARM=y
-CONFIG_XZ_DEC_BCJ=y
-CONFIG_ZBOOT_ROM_BSS=0
-CONFIG_ZBOOT_ROM_TEXT=0
-CONFIG_ZLIB_DEFLATE=y
-CONFIG_ZLIB_INFLATE=y
-CONFIG_ZONE_DMA_FLAG=0
diff --git a/target/linux/ipq806x/patches-3.18/001-spi-qup-Add-DMA-capabilities.patch b/target/linux/ipq806x/patches-3.18/001-spi-qup-Add-DMA-capabilities.patch
deleted file mode 100644
index e110bf726cb69adb3e9b78985a6adb1b2784a563..0000000000000000000000000000000000000000
--- a/target/linux/ipq806x/patches-3.18/001-spi-qup-Add-DMA-capabilities.patch
+++ /dev/null
@@ -1,522 +0,0 @@
-Content-Type: text/plain; charset="utf-8"
-MIME-Version: 1.0
-Content-Transfer-Encoding: 7bit
-Subject: spi: qup: Add DMA capabilities
-From: Andy Gross <agross@codeaurora.org>
-X-Patchwork-Id: 4432401
-Message-Id: <1403816781-31008-1-git-send-email-agross@codeaurora.org>
-To: Mark Brown <broonie@kernel.org>
-Cc: linux-spi@vger.kernel.org, Sagar Dharia <sdharia@codeaurora.org>,
-	Daniel Sneddon <dsneddon@codeaurora.org>,
-	Bjorn Andersson <bjorn.andersson@sonymobile.com>,
-	"Ivan T. Ivanov" <iivanov@mm-sol.com>,
-	linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org,
-	linux-arm-msm@vger.kernel.org, Andy Gross <agross@codeaurora.org>
-Date: Thu, 26 Jun 2014 16:06:21 -0500
-
-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 than the length of a block.
-
-Signed-off-by: Andy Gross <agross@codeaurora.org>
-
----
-.../devicetree/bindings/spi/qcom,spi-qup.txt       |   10 +
- drivers/spi/spi-qup.c                              |  361 ++++++++++++++++++--
- 2 files changed, 350 insertions(+), 21 deletions(-)
-
---- a/Documentation/devicetree/bindings/spi/qcom,spi-qup.txt
-+++ b/Documentation/devicetree/bindings/spi/qcom,spi-qup.txt
-@@ -27,6 +27,11 @@ Optional properties:
- - spi-max-frequency: Specifies maximum SPI clock frequency,
-                      Units - Hz. Definition as per
-                      Documentation/devicetree/bindings/spi/spi-bus.txt
-+- dmas :             Two DMA channel specifiers following the convention outlined
-+                     in bindings/dma/dma.txt
-+- dma-names:         Names for the dma channels, if present. There must be at
-+                     least one channel named "tx" for transmit and named "rx" for
-+                     receive.
- - 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
-@@ -51,6 +56,10 @@ Example:
- 		clocks = <&gcc GCC_BLSP2_QUP2_SPI_APPS_CLK>, <&gcc GCC_BLSP2_AHB_CLK>;
- 		clock-names = "core", "iface";
- 
-+		dmas = <&blsp2_bam 2>,
-+			<&blsp2_bam 3>;
-+		dma-names = "rx", "tx";
-+
- 		pinctrl-names = "default";
- 		pinctrl-0 = <&spi8_default>;
- 
---- 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,17 @@ 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;
-+	dma_addr_t		rx_dma;
-+	dma_addr_t		tx_dma;
-+	void			*dummy;
-+	atomic_t		dma_outstanding;
- };
- 
- 
-@@ -266,6 +281,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 +545,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 +571,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 +601,11 @@ 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))
-+		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 +613,31 @@ 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,6 +670,14 @@ 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 */
-@@ -452,25 +711,29 @@ 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 (!wait_for_completion_timeout(&controller->done, timeout))
-+			ret = -ETIMEDOUT;
-+	}
- exit:
- 	spi_qup_set_state(controller, QUP_STATE_RESET);
- 	spin_lock_irqsave(&controller->lock, flags);
-@@ -554,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);
- 
-@@ -619,6 +883,56 @@ static int spi_qup_probe(struct platform
- 			QUP_ERROR_INPUT_UNDER_RUN | QUP_ERROR_OUTPUT_UNDER_RUN,
- 			base + QUP_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;
-+		}
-+	}
-+
-+
- 	writel_relaxed(0, base + SPI_CONFIG);
- 	writel_relaxed(SPI_IO_C_NO_TRI_STATE, base + SPI_IO_CONTROL);
- 
-@@ -731,6 +1045,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-3.18/002-v3-spi-qup-Fix-incorrect-block-transfers.patch b/target/linux/ipq806x/patches-3.18/002-v3-spi-qup-Fix-incorrect-block-transfers.patch
deleted file mode 100644
index 62ee5b4fad09d2b41edd6ca3911e4660cd1d625f..0000000000000000000000000000000000000000
--- a/target/linux/ipq806x/patches-3.18/002-v3-spi-qup-Fix-incorrect-block-transfers.patch
+++ /dev/null
@@ -1,376 +0,0 @@
-Content-Type: text/plain; charset="utf-8"
-MIME-Version: 1.0
-Content-Transfer-Encoding: 7bit
-Subject: [v3] spi: qup: Fix incorrect block transfers
-From: Andy Gross <agross@codeaurora.org>
-X-Patchwork-Id: 5007321
-Message-Id: <1412112088-25928-1-git-send-email-agross@codeaurora.org>
-To: Mark Brown <broonie@kernel.org>
-Cc: linux-spi@vger.kernel.org, linux-kernel@vger.kernel.org,
-	linux-arm-kernel@lists.infradead.org, linux-arm-msm@vger.kernel.org,
-	"Ivan T. Ivanov" <iivanov@mm-sol.com>,
-	Bjorn Andersson <bjorn.andersson@sonymobile.com>,
-	Kumar Gala <galak@codeaurora.org>, Andy Gross <agross@codeaurora.org>
-Date: Tue, 30 Sep 2014 16:21:28 -0500
-
-This patch fixes a number of errors with the QUP block transfer mode.  Errors
-manifested themselves as input underruns, output overruns, and timed out
-transactions.
-
-The block mode does not require the priming that occurs in FIFO mode.  At the
-moment that the QUP is placed into the RUN state, the QUP will immediately raise
-an interrupt if the request is a write.  Therefore, there is no need to prime
-the pump.
-
-In addition, the block transfers require that whole blocks of data are
-read/written at a time.  The last block of data that completes a transaction may
-contain less than a full blocks worth of data.
-
-Each block of data results in an input/output service interrupt accompanied with
-a input/output block flag set.  Additional block reads/writes require clearing
-of the service flag.  It is ok to check for additional blocks of data in the
-ISR, but you have to ack every block you transfer.  Imbalanced acks result in
-early return from complete transactions with pending interrupts that still have
-to be ack'd.  The next transaction can be affected by these interrupts.
-Transactions are deemed complete when the MAX_INPUT or MAX_OUTPUT flag are set.
-
-Changes from v2:
-- Added in additional completion check so that transaction done is not
-  prematurely signaled.
-- Fixed various review comments.
-
-Changes from v1:
-- Split out read/write block function.
-- Removed extraneous checks for transfer length
-
-Signed-off-by: Andy Gross <agross@codeaurora.org>
-
----
-drivers/spi/spi-qup.c |  201 ++++++++++++++++++++++++++++++++++++-------------
- 1 file changed, 148 insertions(+), 53 deletions(-)
-
---- a/drivers/spi/spi-qup.c
-+++ b/drivers/spi/spi-qup.c
-@@ -82,6 +82,8 @@
- #define QUP_IO_M_MODE_BAM		3
- 
- /* QUP_OPERATIONAL fields */
-+#define QUP_OP_IN_BLOCK_READ_REQ	BIT(13)
-+#define QUP_OP_OUT_BLOCK_WRITE_REQ	BIT(12)
- #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)
-@@ -147,6 +149,7 @@ struct spi_qup {
- 	int			tx_bytes;
- 	int			rx_bytes;
- 	int			qup_v1;
-+	int			mode;
- 
- 	int			use_dma;
- 
-@@ -213,30 +216,14 @@ static int spi_qup_set_state(struct spi_
- 	return 0;
- }
- 
--
--static void spi_qup_fifo_read(struct spi_qup *controller,
--			    struct spi_transfer *xfer)
-+static void spi_qup_fill_read_buffer(struct spi_qup *controller,
-+	struct spi_transfer *xfer, u32 data)
- {
- 	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;
--		}
-+	int idx, shift;
- 
--		for (idx = 0; idx < w_size; idx++, controller->rx_bytes++) {
-+	if (rx_buf)
-+		for (idx = 0; idx < controller->w_size; idx++) {
- 			/*
- 			 * The data format depends on bytes per SPI word:
- 			 *  4 bytes: 0x12345678
-@@ -244,41 +231,139 @@ static void spi_qup_fifo_read(struct spi
- 			 *  1 byte : 0x00000012
- 			 */
- 			shift = BITS_PER_BYTE;
--			shift *= (w_size - idx - 1);
--			rx_buf[controller->rx_bytes] = word >> shift;
-+			shift *= (controller->w_size - idx - 1);
-+			rx_buf[controller->rx_bytes + idx] = data >> shift;
-+		}
-+
-+	controller->rx_bytes += controller->w_size;
-+}
-+
-+static void spi_qup_prepare_write_data(struct spi_qup *controller,
-+	struct spi_transfer *xfer, u32 *data)
-+{
-+	const u8 *tx_buf = xfer->tx_buf;
-+	u32 val;
-+	int idx;
-+
-+	*data = 0;
-+
-+	if (tx_buf)
-+		for (idx = 0; idx < controller->w_size; idx++) {
-+			val = tx_buf[controller->tx_bytes + idx];
-+			*data |= val << (BITS_PER_BYTE * (3 - idx));
- 		}
-+
-+	controller->tx_bytes += controller->w_size;
-+}
-+
-+static void spi_qup_fifo_read(struct spi_qup *controller,
-+			    struct spi_transfer *xfer)
-+{
-+	u32 data;
-+
-+	/* clear service request */
-+	writel_relaxed(QUP_OP_IN_SERVICE_FLAG,
-+			controller->base + QUP_OPERATIONAL);
-+
-+	while (controller->rx_bytes < xfer->len) {
-+		if (!(readl_relaxed(controller->base + QUP_OPERATIONAL) &
-+		    QUP_OP_IN_FIFO_NOT_EMPTY))
-+			break;
-+
-+		data = readl_relaxed(controller->base + QUP_INPUT_FIFO);
-+
-+		spi_qup_fill_read_buffer(controller, xfer, data);
- 	}
- }
- 
- static void spi_qup_fifo_write(struct spi_qup *controller,
--			    struct spi_transfer *xfer)
-+	struct spi_transfer *xfer)
- {
--	const u8 *tx_buf = xfer->tx_buf;
--	u32 word, state, data;
--	int idx, w_size;
-+	u32 data;
- 
--	w_size = controller->w_size;
-+	/* clear service request */
-+	writel_relaxed(QUP_OP_OUT_SERVICE_FLAG,
-+		controller->base + QUP_OPERATIONAL);
- 
- 	while (controller->tx_bytes < xfer->len) {
- 
--		state = readl_relaxed(controller->base + QUP_OPERATIONAL);
--		if (state & QUP_OP_OUT_FIFO_FULL)
-+		if (readl_relaxed(controller->base + QUP_OPERATIONAL) &
-+				QUP_OP_OUT_FIFO_FULL)
- 			break;
- 
--		word = 0;
--		for (idx = 0; idx < w_size; idx++, controller->tx_bytes++) {
-+		spi_qup_prepare_write_data(controller, xfer, &data);
-+		writel_relaxed(data, controller->base + QUP_OUTPUT_FIFO);
- 
--			if (!tx_buf) {
--				controller->tx_bytes += w_size;
--				break;
--			}
-+	}
-+}
- 
--			data = tx_buf[controller->tx_bytes];
--			word |= data << (BITS_PER_BYTE * (3 - idx));
--		}
-+static void spi_qup_block_read(struct spi_qup *controller,
-+	struct spi_transfer *xfer)
-+{
-+	u32 data;
-+	u32 reads_per_blk = controller->in_blk_sz >> 2;
-+	u32 num_words = (xfer->len - controller->rx_bytes) / controller->w_size;
-+	int i;
-+
-+	do {
-+		/* ACK by clearing service flag */
-+		writel_relaxed(QUP_OP_IN_SERVICE_FLAG,
-+			controller->base + QUP_OPERATIONAL);
-+
-+		/* transfer up to a block size of data in a single pass */
-+		for (i = 0; num_words && i < reads_per_blk; i++, num_words--) {
-+
-+			/* read data and fill up rx buffer */
-+			data = readl_relaxed(controller->base + QUP_INPUT_FIFO);
-+			spi_qup_fill_read_buffer(controller, xfer, data);
-+		}
-+
-+		/* check to see if next block is ready */
-+		if (!(readl_relaxed(controller->base + QUP_OPERATIONAL) &
-+			QUP_OP_IN_BLOCK_READ_REQ))
-+			break;
- 
--		writel_relaxed(word, controller->base + QUP_OUTPUT_FIFO);
--	}
-+	} while (num_words);
-+
-+	/*
-+	 * Due to extra stickiness of the QUP_OP_IN_SERVICE_FLAG during block
-+	 * reads, it has to be cleared again at the very end
-+	 */
-+	if (readl_relaxed(controller->base + QUP_OPERATIONAL) &
-+		QUP_OP_MAX_INPUT_DONE_FLAG)
-+		writel_relaxed(QUP_OP_IN_SERVICE_FLAG,
-+			controller->base + QUP_OPERATIONAL);
-+
-+}
-+
-+static void spi_qup_block_write(struct spi_qup *controller,
-+	struct spi_transfer *xfer)
-+{
-+	u32 data;
-+	u32 writes_per_blk = controller->out_blk_sz >> 2;
-+	u32 num_words = (xfer->len - controller->tx_bytes) / controller->w_size;
-+	int i;
-+
-+	do {
-+		/* ACK by clearing service flag */
-+		writel_relaxed(QUP_OP_OUT_SERVICE_FLAG,
-+			controller->base + QUP_OPERATIONAL);
-+
-+		/* transfer up to a block size of data in a single pass */
-+		for (i = 0; num_words && i < writes_per_blk; i++, num_words--) {
-+
-+			/* swizzle the bytes for output and write out */
-+			spi_qup_prepare_write_data(controller, xfer, &data);
-+			writel_relaxed(data,
-+				controller->base + QUP_OUTPUT_FIFO);
-+		}
-+
-+		/* check to see if next block is ready */
-+		if (!(readl_relaxed(controller->base + QUP_OPERATIONAL) &
-+			QUP_OP_OUT_BLOCK_WRITE_REQ))
-+			break;
-+
-+	} while (num_words);
- }
- 
- static void qup_dma_callback(void *data)
-@@ -515,9 +600,9 @@ static irqreturn_t spi_qup_qup_irq(int i
- 
- 	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) {
-+		writel_relaxed(opflags, controller->base + QUP_OPERATIONAL);
- 		dev_err_ratelimited(controller->dev, "unexpected irq %08x %08x %08x\n",
- 				    qup_err, spi_err, opflags);
- 		return IRQ_HANDLED;
-@@ -546,11 +631,19 @@ static irqreturn_t spi_qup_qup_irq(int i
- 	}
- 
- 	if (!controller->use_dma) {
--		if (opflags & QUP_OP_IN_SERVICE_FLAG)
--			spi_qup_fifo_read(controller, xfer);
-+		if (opflags & QUP_OP_IN_SERVICE_FLAG) {
-+			if (opflags & QUP_OP_IN_BLOCK_READ_REQ)
-+				spi_qup_block_read(controller, xfer);
-+			else
-+				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) {
-+			if (opflags & QUP_OP_OUT_BLOCK_WRITE_REQ)
-+				spi_qup_block_write(controller, xfer);
-+			else
-+				spi_qup_fifo_write(controller, xfer);
-+		}
- 	}
- 
- 	spin_lock_irqsave(&controller->lock, flags);
-@@ -558,7 +651,8 @@ static irqreturn_t spi_qup_qup_irq(int i
- 	controller->xfer = xfer;
- 	spin_unlock_irqrestore(&controller->lock, flags);
- 
--	if (controller->rx_bytes == xfer->len || error)
-+	if ((controller->rx_bytes == xfer->len &&
-+		(opflags & QUP_OP_MAX_INPUT_DONE_FLAG)) || error)
- 		complete(&controller->done);
- 
- 	return IRQ_HANDLED;
-@@ -569,7 +663,7 @@ static irqreturn_t spi_qup_qup_irq(int i
- 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;
-+	u32 config, iomode;
- 	int ret, n_words, w_size;
- 	size_t dma_align = dma_get_cache_alignment();
- 	u32 dma_available = 0;
-@@ -607,7 +701,7 @@ static int spi_qup_io_config(struct spi_
- 		dma_available = 1;
- 
- 	if (n_words <= (controller->in_fifo_sz / sizeof(u32))) {
--		mode = QUP_IO_M_MODE_FIFO;
-+		controller->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 */
-@@ -615,7 +709,7 @@ static int spi_qup_io_config(struct spi_
- 		writel_relaxed(0, controller->base + QUP_MX_OUTPUT_CNT);
- 		controller->use_dma = 0;
- 	} else if (!dma_available) {
--		mode = QUP_IO_M_MODE_BLOCK;
-+		controller->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 */
-@@ -623,7 +717,7 @@ static int spi_qup_io_config(struct spi_
- 		writel_relaxed(0, controller->base + QUP_MX_WRITE_CNT);
- 		controller->use_dma = 0;
- 	} else {
--		mode = QUP_IO_M_MODE_DMOV;
-+		controller->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;
-@@ -638,8 +732,8 @@ static int spi_qup_io_config(struct spi_
- 	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);
-+	iomode |= (controller->mode << QUP_IO_M_OUTPUT_MODE_MASK_SHIFT);
-+	iomode |= (controller->mode << QUP_IO_M_INPUT_MODE_MASK_SHIFT);
- 
- 	writel_relaxed(iomode, controller->base + QUP_IO_M_MODES);
- 
-@@ -724,7 +818,8 @@ static int spi_qup_transfer_one(struct s
- 			goto exit;
- 		}
- 
--		spi_qup_fifo_write(controller, xfer);
-+		if (controller->mode == QUP_IO_M_MODE_FIFO)
-+			spi_qup_fifo_write(controller, xfer);
- 
- 		if (spi_qup_set_state(controller, QUP_STATE_RUN)) {
- 			dev_warn(controller->dev, "cannot set EXECUTE state\n");
-@@ -741,6 +836,7 @@ exit:
- 	if (!ret)
- 		ret = controller->error;
- 	spin_unlock_irqrestore(&controller->lock, flags);
-+
- 	return ret;
- }
- 
diff --git a/target/linux/ipq806x/patches-3.18/003-spi-qup-Ensure-done-detection.patch b/target/linux/ipq806x/patches-3.18/003-spi-qup-Ensure-done-detection.patch
deleted file mode 100644
index 70522278103caa3120923900a6d41a1f57d4388d..0000000000000000000000000000000000000000
--- a/target/linux/ipq806x/patches-3.18/003-spi-qup-Ensure-done-detection.patch
+++ /dev/null
@@ -1,56 +0,0 @@
-From 4faba89e3ffbb1c5f6232651375b9b3212b50f02 Mon Sep 17 00:00:00 2001
-From: Andy Gross <agross@codeaurora.org>
-Date: Thu, 15 Jan 2015 17:56:02 -0800
-Subject: [PATCH] spi: qup: Ensure done detection
-
-This patch fixes an issue where a SPI transaction has completed, but the done
-condition is missed.  This occurs because at the time of interrupt the
-MAX_INPUT_DONE_FLAG is not asserted.  However, in the process of reading blocks
-of data from the FIFO, the last portion of data comes in.
-
-The opflags read at the beginning of the irq handler no longer matches the
-current opflag state.  To get around this condition, the block read function
-should update the opflags so that done detection is correct after the return.
-
-Change-Id: If109e0eeb432f96000d765c4b34dbb2269f8093f
-Signed-off-by: Andy Gross <agross@codeaurora.org>
----
- drivers/spi/spi-qup.c | 12 +++++++-----
- 1 file changed, 7 insertions(+), 5 deletions(-)
-
---- a/drivers/spi/spi-qup.c
-+++ b/drivers/spi/spi-qup.c
-@@ -298,7 +298,7 @@ static void spi_qup_fifo_write(struct sp
- }
- 
- static void spi_qup_block_read(struct spi_qup *controller,
--	struct spi_transfer *xfer)
-+	struct spi_transfer *xfer, u32 *opflags)
- {
- 	u32 data;
- 	u32 reads_per_blk = controller->in_blk_sz >> 2;
-@@ -327,10 +327,12 @@ static void spi_qup_block_read(struct sp
- 
- 	/*
- 	 * Due to extra stickiness of the QUP_OP_IN_SERVICE_FLAG during block
--	 * reads, it has to be cleared again at the very end
-+	 * reads, it has to be cleared again at the very end.  However, be sure
-+	 * to refresh opflags value because MAX_INPUT_DONE_FLAG may now be
-+	 * present and this is used to determine if transaction is complete
- 	 */
--	if (readl_relaxed(controller->base + QUP_OPERATIONAL) &
--		QUP_OP_MAX_INPUT_DONE_FLAG)
-+	*opflags = readl_relaxed(controller->base + QUP_OPERATIONAL);
-+	if (*opflags & QUP_OP_MAX_INPUT_DONE_FLAG)
- 		writel_relaxed(QUP_OP_IN_SERVICE_FLAG,
- 			controller->base + QUP_OPERATIONAL);
- 
-@@ -633,7 +635,7 @@ static irqreturn_t spi_qup_qup_irq(int i
- 	if (!controller->use_dma) {
- 		if (opflags & QUP_OP_IN_SERVICE_FLAG) {
- 			if (opflags & QUP_OP_IN_BLOCK_READ_REQ)
--				spi_qup_block_read(controller, xfer);
-+				spi_qup_block_read(controller, xfer, &opflags);
- 			else
- 				spi_qup_fifo_read(controller, xfer);
- 		}
diff --git a/target/linux/ipq806x/patches-3.18/011-watchdog-qcom-use-timer-devicetree-binding.patch b/target/linux/ipq806x/patches-3.18/011-watchdog-qcom-use-timer-devicetree-binding.patch
deleted file mode 100644
index 68489a83b5b53dba4a2f3dd4891aa4525cdf3d02..0000000000000000000000000000000000000000
--- a/target/linux/ipq806x/patches-3.18/011-watchdog-qcom-use-timer-devicetree-binding.patch
+++ /dev/null
@@ -1,67 +0,0 @@
-From fded70251b1b58f68de1d3757ece9965f0b75452 Mon Sep 17 00:00:00 2001
-From: Mathieu Olivari <mathieu@codeaurora.org>
-Date: Thu, 19 Feb 2015 20:19:30 -0800
-Subject: [PATCH 1/3] watchdog: qcom: use timer devicetree binding
-
-MSM watchdog configuration happens in the same register block as the
-timer, so we'll use the same binding as the existing timer.
-
-The qcom-wdt will now be probed when devicetree has an entry compatible
-with "qcom,kpss-timer" or "qcom-scss-timer".
-
-Signed-off-by: Mathieu Olivari <mathieu@codeaurora.org>
----
- drivers/watchdog/qcom-wdt.c | 21 +++++++++++++++------
- 1 file changed, 15 insertions(+), 6 deletions(-)
-
---- a/drivers/watchdog/qcom-wdt.c
-+++ b/drivers/watchdog/qcom-wdt.c
-@@ -20,9 +20,9 @@
- #include <linux/reboot.h>
- #include <linux/watchdog.h>
- 
--#define WDT_RST		0x0
--#define WDT_EN		0x8
--#define WDT_BITE_TIME	0x24
-+#define WDT_RST		0x38
-+#define WDT_EN		0x40
-+#define WDT_BITE_TIME	0x5C
- 
- struct qcom_wdt {
- 	struct watchdog_device	wdd;
-@@ -117,6 +117,8 @@ static int qcom_wdt_probe(struct platfor
- {
- 	struct qcom_wdt *wdt;
- 	struct resource *res;
-+	struct device_node *np = pdev->dev.of_node;
-+	u32 percpu_offset;
- 	int ret;
- 
- 	wdt = devm_kzalloc(&pdev->dev, sizeof(*wdt), GFP_KERNEL);
-@@ -124,6 +126,14 @@ static int qcom_wdt_probe(struct platfor
- 		return -ENOMEM;
- 
- 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-+
-+	/* We use CPU0's DGT for the watchdog */
-+	if (of_property_read_u32(np, "cpu-offset", &percpu_offset))
-+		percpu_offset = 0;
-+
-+	res->start += percpu_offset;
-+	res->end += percpu_offset;
-+
- 	wdt->base = devm_ioremap_resource(&pdev->dev, res);
- 	if (IS_ERR(wdt->base))
- 		return PTR_ERR(wdt->base);
-@@ -203,9 +213,8 @@ static int qcom_wdt_remove(struct platfo
- }
- 
- static const struct of_device_id qcom_wdt_of_table[] = {
--	{ .compatible = "qcom,kpss-wdt-msm8960", },
--	{ .compatible = "qcom,kpss-wdt-apq8064", },
--	{ .compatible = "qcom,kpss-wdt-ipq8064", },
-+	{ .compatible = "qcom,kpss-timer" },
-+	{ .compatible = "qcom,scss-timer" },
- 	{ },
- };
- MODULE_DEVICE_TABLE(of, qcom_wdt_of_table);
diff --git a/target/linux/ipq806x/patches-3.18/012-ARM-qcom-add-description-of-KPSS-WDT-for-IPQ8064.patch b/target/linux/ipq806x/patches-3.18/012-ARM-qcom-add-description-of-KPSS-WDT-for-IPQ8064.patch
deleted file mode 100644
index ae9677656e060f47f48190b861d0bbea562f1288..0000000000000000000000000000000000000000
--- a/target/linux/ipq806x/patches-3.18/012-ARM-qcom-add-description-of-KPSS-WDT-for-IPQ8064.patch
+++ /dev/null
@@ -1,48 +0,0 @@
-From 297cf8136ecd6a56520888fd28948393766b8ee7 Mon Sep 17 00:00:00 2001
-From: Mathieu Olivari <mathieu@codeaurora.org>
-Date: Thu, 19 Feb 2015 20:27:39 -0800
-Subject: [PATCH 2/3] ARM: qcom: add description of KPSS WDT for IPQ8064
-
-Add the watchdog related entries to the Krait Processor Sub-system
-(KPSS) timer IPQ8064 devicetree section. Also, add a fixed-clock
-description of SLEEP_CLK, which will do for now.
-
-Signed-off-by: Josh Cartwright <joshc@codeaurora.org>
-Signed-off-by: Mathieu Olivari <mathieu@codeaurora.org>
----
- arch/arm/boot/dts/qcom-ipq8064.dtsi | 14 +++++++++++++-
- 1 file changed, 13 insertions(+), 1 deletion(-)
-
---- a/arch/arm/boot/dts/qcom-ipq8064.dtsi
-+++ b/arch/arm/boot/dts/qcom-ipq8064.dtsi
-@@ -60,6 +60,14 @@
- 		};
- 	};
- 
-+	clocks {
-+		sleep_clk: sleep_clk {
-+			compatible = "fixed-clock";
-+			clock-frequency = <32768>;
-+			#clock-cells = <0>;
-+		};
-+	};
-+
- 	soc: soc {
- 		#address-cells = <1>;
- 		#size-cells = <1>;
-@@ -89,10 +97,14 @@
- 			compatible = "qcom,kpss-timer", "qcom,msm-timer";
- 			interrupts = <1 1 0x301>,
- 				     <1 2 0x301>,
--				     <1 3 0x301>;
-+				     <1 3 0x301>,
-+				     <1 4 0x301>,
-+				     <1 5 0x301>;
- 			reg = <0x0200a000 0x100>;
- 			clock-frequency = <25000000>,
- 					  <32768>;
-+			clocks = <&sleep_clk>;
-+			clock-names = "sleep";
- 			cpu-offset = <0x80000>;
- 		};
- 
diff --git a/target/linux/ipq806x/patches-3.18/013-ARM-msm-add-watchdog-entries-to-DT-timer-binding-doc.patch b/target/linux/ipq806x/patches-3.18/013-ARM-msm-add-watchdog-entries-to-DT-timer-binding-doc.patch
deleted file mode 100644
index 6876768962d78a306a9a7c37a3f2e13ac08bb6f0..0000000000000000000000000000000000000000
--- a/target/linux/ipq806x/patches-3.18/013-ARM-msm-add-watchdog-entries-to-DT-timer-binding-doc.patch
+++ /dev/null
@@ -1,50 +0,0 @@
-From e535f01dffb6dd9e09934fa219be52af3437a8f6 Mon Sep 17 00:00:00 2001
-From: Mathieu Olivari <mathieu@codeaurora.org>
-Date: Thu, 19 Feb 2015 20:36:27 -0800
-Subject: [PATCH 3/3] ARM: msm: add watchdog entries to DT timer binding doc
-
-The watchdog has been reworked to use the same DT node as the timer.
-This change is updating the device tree doc accordingly.
-
-Signed-off-by: Mathieu Olivari <mathieu@codeaurora.org>
----
- Documentation/devicetree/bindings/arm/msm/timer.txt | 16 +++++++++++++---
- 1 file changed, 13 insertions(+), 3 deletions(-)
-
---- a/Documentation/devicetree/bindings/arm/msm/timer.txt
-+++ b/Documentation/devicetree/bindings/arm/msm/timer.txt
-@@ -9,11 +9,17 @@ Properties:
-                "qcom,scss-timer" - scorpion subsystem
- 
- - interrupts : Interrupts for the the debug timer, the first general purpose
--               timer, and optionally a second general purpose timer in that
--               order.
-+               timer, and optionally a second general purpose timer, and
-+               optionally as well, 2 watchdog interrupts, in that order.
- 
- - reg : Specifies the base address of the timer registers.
- 
-+- clocks: Reference to the parent clocks, one per output clock. The parents
-+          must appear in the same order as the clock names.
-+
-+- clock-names: The name of the clocks as free-form strings. They should be in
-+               the same order as the clocks.
-+
- - clock-frequency : The frequency of the debug timer and the general purpose
-                     timer(s) in Hz in that order.
- 
-@@ -29,9 +35,13 @@ Example:
-                compatible = "qcom,scss-timer", "qcom,msm-timer";
-                interrupts = <1 1 0x301>,
-                             <1 2 0x301>,
--                            <1 3 0x301>;
-+                            <1 3 0x301>,
-+                            <1 4 0x301>,
-+                            <1 5 0x301>;
-                reg = <0x0200a000 0x100>;
-                clock-frequency = <19200000>,
-                                  <32768>;
-+               clocks = <&sleep_clk>;
-+               clock-names = "sleep";
-                cpu-offset = <0x40000>;
-        };
diff --git a/target/linux/ipq806x/patches-3.18/020-add-ap148-bootargs.patch b/target/linux/ipq806x/patches-3.18/020-add-ap148-bootargs.patch
deleted file mode 100644
index a61481e65238b7958e45145ef070055c1f62bc48..0000000000000000000000000000000000000000
--- a/target/linux/ipq806x/patches-3.18/020-add-ap148-bootargs.patch
+++ /dev/null
@@ -1,46 +0,0 @@
---- a/arch/arm/boot/dts/qcom-ipq8064-ap148.dts
-+++ b/arch/arm/boot/dts/qcom-ipq8064-ap148.dts
-@@ -14,6 +14,14 @@
- 		};
- 	};
- 
-+	alias {
-+		serial0 = &uart4;
-+	};
-+
-+	chosen {
-+		linux,stdout-path = "serial0:115200n8";
-+	};
-+
- 	soc {
- 		pinmux@800000 {
- 			i2c4_pins: i2c4_pinmux {
---- a/arch/arm/boot/dts/qcom-ipq8064.dtsi
-+++ b/arch/arm/boot/dts/qcom-ipq8064.dtsi
-@@ -140,7 +140,7 @@
- 			ranges;
- 			status = "disabled";
- 
--			serial@12490000 {
-+			uart2: serial@12490000 {
- 				compatible = "qcom,msm-uartdm-v1.3", "qcom,msm-uartdm";
- 				reg = <0x12490000 0x1000>,
- 				      <0x12480000 0x1000>;
-@@ -175,7 +175,7 @@
- 			ranges;
- 			status = "disabled";
- 
--			serial@16340000 {
-+			uart4: serial@16340000 {
- 				compatible = "qcom,msm-uartdm-v1.3", "qcom,msm-uartdm";
- 				reg = <0x16340000 0x1000>,
- 				      <0x16300000 0x1000>;
-@@ -209,7 +209,7 @@
- 			ranges;
- 			status = "disabled";
- 
--			serial@1a240000 {
-+			uart5: serial@1a240000 {
- 				compatible = "qcom,msm-uartdm-v1.3", "qcom,msm-uartdm";
- 				reg = <0x1a240000 0x1000>,
- 				      <0x1a200000 0x1000>;
diff --git a/target/linux/ipq806x/patches-3.18/021-add-ap148-partitions.patch b/target/linux/ipq806x/patches-3.18/021-add-ap148-partitions.patch
deleted file mode 100644
index bfdb30fe14a3f1c0e55da5972b20cb3625472279..0000000000000000000000000000000000000000
--- a/target/linux/ipq806x/patches-3.18/021-add-ap148-partitions.patch
+++ /dev/null
@@ -1,19 +0,0 @@
---- a/arch/arm/boot/dts/qcom-ipq8064-ap148.dts
-+++ b/arch/arm/boot/dts/qcom-ipq8064-ap148.dts
-@@ -77,15 +77,7 @@
- 					spi-max-frequency = <50000000>;
- 					reg = <0>;
- 
--					partition@0 {
--						label = "rootfs";
--						reg = <0x0 0x1000000>;
--					};
--
--					partition@1 {
--						label = "scratch";
--						reg = <0x1000000 0x1000000>;
--					};
-+					linux,part-probe = "qcom-smem";
- 				};
- 			};
- 		};
diff --git a/target/linux/ipq806x/patches-3.18/022-add-db149-dts.patch b/target/linux/ipq806x/patches-3.18/022-add-db149-dts.patch
deleted file mode 100644
index bd6ec1e94f38b1a308ae7417118d60c5be034dca..0000000000000000000000000000000000000000
--- a/target/linux/ipq806x/patches-3.18/022-add-db149-dts.patch
+++ /dev/null
@@ -1,160 +0,0 @@
-From a32d6e7c8fca6371a2614924b89981bc912b6378 Mon Sep 17 00:00:00 2001
-From: Mathieu Olivari <mathieu@codeaurora.org>
-Date: Tue, 7 Apr 2015 19:58:58 -0700
-Subject: [PATCH] ARM: dts: qcom: add initial DB149 device-tree
-
-Add basic DB149 (IPQ806x based platform) device-tree. It supports UART,
-SATA, USB2, USB3 and NOR flash.
-
-Signed-off-by: Mathieu Olivari <mathieu@codeaurora.org>
----
- arch/arm/boot/dts/Makefile               |   1 +
- arch/arm/boot/dts/qcom-ipq8064-db149.dts | 257 +++++++++++++++++++++++++++++++
- 2 files changed, 258 insertions(+)
- create mode 100644 arch/arm/boot/dts/qcom-ipq8064-db149.dts
-
---- a/arch/arm/boot/dts/Makefile
-+++ b/arch/arm/boot/dts/Makefile
-@@ -360,6 +360,7 @@ dtb-$(CONFIG_ARCH_QCOM) += \
- 	qcom-apq8084-ifc6540.dtb \
- 	qcom-apq8084-mtp.dtb \
- 	qcom-ipq8064-ap148.dtb \
-+	qcom-ipq8064-db149.dtb \
- 	qcom-msm8660-surf.dtb \
- 	qcom-msm8960-cdp.dtb \
- 	qcom-msm8974-sony-xperia-honami.dtb
---- /dev/null
-+++ b/arch/arm/boot/dts/qcom-ipq8064-db149.dts
-@@ -0,0 +1,132 @@
-+#include "qcom-ipq8064-v1.0.dtsi"
-+
-+/ {
-+	model = "Qualcomm IPQ8064/DB149";
-+	compatible = "qcom,ipq8064-db149", "qcom,ipq8064";
-+
-+	reserved-memory {
-+		#address-cells = <1>;
-+		#size-cells = <1>;
-+		ranges;
-+		rsvd@41200000 {
-+			reg = <0x41200000 0x300000>;
-+			no-map;
-+		};
-+	};
-+
-+	alias {
-+		serial0 = &uart2;
-+	};
-+
-+	chosen {
-+		linux,stdout-path = "serial0:115200n8";
-+	};
-+
-+	soc {
-+		pinmux@800000 {
-+			i2c4_pins: i2c4_pinmux {
-+				pins = "gpio12", "gpio13";
-+				function = "gsbi4";
-+				bias-disable;
-+			};
-+
-+			spi_pins: spi_pins {
-+				mux {
-+					pins = "gpio18", "gpio19", "gpio21";
-+					function = "gsbi5";
-+					drive-strength = <10>;
-+					bias-none;
-+				};
-+			};
-+		};
-+
-+		gsbi2: gsbi@12480000 {
-+			qcom,mode = <GSBI_PROT_I2C_UART>;
-+			status = "ok";
-+			uart2: serial@12490000 {
-+				status = "ok";
-+			};
-+		};
-+
-+		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>;
-+					m25p,fast-read;
-+
-+					partition@0 {
-+						label = "lowlevel_init";
-+						reg = <0x0 0x1b0000>;
-+					};
-+
-+					partition@1 {
-+						label = "u-boot";
-+						reg = <0x1b0000 0x80000>;
-+					};
-+
-+					partition@2 {
-+						label = "u-boot-env";
-+						reg = <0x230000 0x40000>;
-+					};
-+
-+					partition@3 {
-+						label = "caldata";
-+						reg = <0x270000 0x40000>;
-+					};
-+
-+					partition@4 {
-+						label = "firmware";
-+						reg = <0x2b0000 0x1d50000>;
-+					};
-+				};
-+			};
-+		};
-+
-+		sata-phy@1b400000 {
-+			status = "ok";
-+		};
-+
-+		sata@29000000 {
-+			status = "ok";
-+		};
-+
-+		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";
-+		};
-+	};
-+};
diff --git a/target/linux/ipq806x/patches-3.18/023-ARM-dts-ipq806x-Disable-i2c-device-on-gsbi4.patch b/target/linux/ipq806x/patches-3.18/023-ARM-dts-ipq806x-Disable-i2c-device-on-gsbi4.patch
deleted file mode 100644
index 319859b109c05d936c88543c0e35093380325559..0000000000000000000000000000000000000000
--- a/target/linux/ipq806x/patches-3.18/023-ARM-dts-ipq806x-Disable-i2c-device-on-gsbi4.patch
+++ /dev/null
@@ -1,53 +0,0 @@
---- a/arch/arm/boot/dts/qcom-ipq8064-ap148.dts
-+++ b/arch/arm/boot/dts/qcom-ipq8064-ap148.dts
-@@ -46,15 +46,12 @@
- 			serial@16340000 {
- 				status = "ok";
- 			};
--
--			i2c4: i2c@16380000 {
--				status = "ok";
--
--				clock-frequency = <200000>;
--
--				pinctrl-0 = <&i2c4_pins>;
--				pinctrl-names = "default";
--			};
-+			/*
-+			 * The i2c device on gsbi4 should not be enabled.
-+			 * On ipq806x designs gsbi4 i2c is meant for exclusive
-+			 * RPM usage. Turning this on in kernel manifests as
-+			 * i2c failure for the RPM.
-+			 */
- 		};
- 
- 		gsbi5: gsbi@1a200000 {
---- a/drivers/clk/qcom/gcc-ipq806x.c
-+++ b/drivers/clk/qcom/gcc-ipq806x.c
-@@ -794,7 +794,7 @@ static struct clk_rcg gsbi7_qup_src = {
- 			.parent_names = gcc_pxo_pll8,
- 			.num_parents = 2,
- 			.ops = &clk_rcg_ops,
--			.flags = CLK_SET_PARENT_GATE,
-+			.flags = CLK_SET_PARENT_GATE | CLK_IGNORE_UNUSED,
- 		},
- 	},
- };
-@@ -810,7 +810,7 @@ static struct clk_branch gsbi7_qup_clk =
- 			.parent_names = (const char *[]){ "gsbi7_qup_src" },
- 			.num_parents = 1,
- 			.ops = &clk_branch_ops,
--			.flags = CLK_SET_RATE_PARENT,
-+			.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
- 		},
- 	},
- };
-@@ -858,7 +858,7 @@ static struct clk_branch gsbi4_h_clk = {
- 		.hw.init = &(struct clk_init_data){
- 			.name = "gsbi4_h_clk",
- 			.ops = &clk_branch_ops,
--			.flags = CLK_IS_ROOT,
-+			.flags = CLK_IS_ROOT | CLK_IGNORE_UNUSED,
- 		},
- 	},
- };
diff --git a/target/linux/ipq806x/patches-3.18/024-ap148-add-memory-node.patch b/target/linux/ipq806x/patches-3.18/024-ap148-add-memory-node.patch
deleted file mode 100644
index f026ed93941f4431aa51ad76d3ab68fcd453f69b..0000000000000000000000000000000000000000
--- a/target/linux/ipq806x/patches-3.18/024-ap148-add-memory-node.patch
+++ /dev/null
@@ -1,14 +0,0 @@
---- a/arch/arm/boot/dts/qcom-ipq8064-ap148.dts
-+++ b/arch/arm/boot/dts/qcom-ipq8064-ap148.dts
-@@ -4,6 +4,11 @@
- 	model = "Qualcomm IPQ8064/AP148";
- 	compatible = "qcom,ipq8064-ap148", "qcom,ipq8064";
- 
-+	memory@0 {
-+		reg = <0x42000000 0x1e000000>;
-+		device_type = "memory";
-+	};
-+
- 	reserved-memory {
- 		#address-cells = <1>;
- 		#size-cells = <1>;
diff --git a/target/linux/ipq806x/patches-3.18/030-hwspinlock-core-add-device-tree-support.patch b/target/linux/ipq806x/patches-3.18/030-hwspinlock-core-add-device-tree-support.patch
deleted file mode 100644
index 04f35b7ec759d00f4fdf2f39a96b6606fd95d9ab..0000000000000000000000000000000000000000
--- a/target/linux/ipq806x/patches-3.18/030-hwspinlock-core-add-device-tree-support.patch
+++ /dev/null
@@ -1,167 +0,0 @@
-From fb7737e949e31d8a71acee6bbb670f32dbd2a2c0 Mon Sep 17 00:00:00 2001
-From: Suman Anna <s-anna@ti.com>
-Date: Wed, 4 Mar 2015 20:01:14 -0600
-Subject: [PATCH] hwspinlock/core: add device tree support
-
-This patch adds a new OF-friendly API of_hwspin_lock_get_id()
-for hwspinlock clients to use/request locks from a hwspinlock
-device instantiated through a device-tree blob. This new API
-can be used by hwspinlock clients to get the id for a specific
-lock using the phandle + args specifier, so that it can be
-requested using the available hwspin_lock_request_specific()
-API.
-
-Signed-off-by: Suman Anna <s-anna@ti.com>
-Reviewed-by: Bjorn Andersson <bjorn.andersson@sonymobile.com>
-[small comment clarification]
-Signed-off-by: Ohad Ben-Cohen <ohad@wizery.com>
----
- Documentation/hwspinlock.txt         | 10 +++++
- drivers/hwspinlock/hwspinlock_core.c | 79 ++++++++++++++++++++++++++++++++++++
- include/linux/hwspinlock.h           |  7 ++++
- 3 files changed, 96 insertions(+)
-
---- a/Documentation/hwspinlock.txt
-+++ b/Documentation/hwspinlock.txt
-@@ -48,6 +48,16 @@ independent, drivers.
-      ids for predefined purposes.
-      Should be called from a process context (might sleep).
- 
-+  int of_hwspin_lock_get_id(struct device_node *np, int index);
-+   - retrieve the global lock id for an OF phandle-based specific lock.
-+     This function provides a means for DT users of a hwspinlock module
-+     to get the global lock id of a specific hwspinlock, so that it can
-+     be requested using the normal hwspin_lock_request_specific() API.
-+     The function returns a lock id number on success, -EPROBE_DEFER if
-+     the hwspinlock device is not yet registered with the core, or other
-+     error values.
-+     Should be called from a process context (might sleep).
-+
-   int hwspin_lock_free(struct hwspinlock *hwlock);
-    - free a previously-assigned hwspinlock; returns 0 on success, or an
-      appropriate error code on failure (e.g. -EINVAL if the hwspinlock
---- a/drivers/hwspinlock/hwspinlock_core.c
-+++ b/drivers/hwspinlock/hwspinlock_core.c
-@@ -27,6 +27,7 @@
- #include <linux/hwspinlock.h>
- #include <linux/pm_runtime.h>
- #include <linux/mutex.h>
-+#include <linux/of.h>
- 
- #include "hwspinlock_internal.h"
- 
-@@ -257,6 +258,84 @@ void __hwspin_unlock(struct hwspinlock *
- }
- EXPORT_SYMBOL_GPL(__hwspin_unlock);
- 
-+/**
-+ * of_hwspin_lock_simple_xlate - translate hwlock_spec to return a lock id
-+ * @bank: the hwspinlock device bank
-+ * @hwlock_spec: hwlock specifier as found in the device tree
-+ *
-+ * This is a simple translation function, suitable for hwspinlock platform
-+ * drivers that only has a lock specifier length of 1.
-+ *
-+ * Returns a relative index of the lock within a specified bank on success,
-+ * or -EINVAL on invalid specifier cell count.
-+ */
-+static inline int
-+of_hwspin_lock_simple_xlate(const struct of_phandle_args *hwlock_spec)
-+{
-+	if (WARN_ON(hwlock_spec->args_count != 1))
-+		return -EINVAL;
-+
-+	return hwlock_spec->args[0];
-+}
-+
-+/**
-+ * of_hwspin_lock_get_id() - get lock id for an OF phandle-based specific lock
-+ * @np: device node from which to request the specific hwlock
-+ * @index: index of the hwlock in the list of values
-+ *
-+ * This function provides a means for DT users of the hwspinlock module to
-+ * get the global lock id of a specific hwspinlock using the phandle of the
-+ * hwspinlock device, so that it can be requested using the normal
-+ * hwspin_lock_request_specific() API.
-+ *
-+ * Returns the global lock id number on success, -EPROBE_DEFER if the hwspinlock
-+ * device is not yet registered, -EINVAL on invalid args specifier value or an
-+ * appropriate error as returned from the OF parsing of the DT client node.
-+ */
-+int of_hwspin_lock_get_id(struct device_node *np, int index)
-+{
-+	struct of_phandle_args args;
-+	struct hwspinlock *hwlock;
-+	struct radix_tree_iter iter;
-+	void **slot;
-+	int id;
-+	int ret;
-+
-+	ret = of_parse_phandle_with_args(np, "hwlocks", "#hwlock-cells", index,
-+					 &args);
-+	if (ret)
-+		return ret;
-+
-+	/* Find the hwspinlock device: we need its base_id */
-+	ret = -EPROBE_DEFER;
-+	rcu_read_lock();
-+	radix_tree_for_each_slot(slot, &hwspinlock_tree, &iter, 0) {
-+		hwlock = radix_tree_deref_slot(slot);
-+		if (unlikely(!hwlock))
-+			continue;
-+
-+		if (hwlock->bank->dev->of_node == args.np) {
-+			ret = 0;
-+			break;
-+		}
-+	}
-+	rcu_read_unlock();
-+	if (ret < 0)
-+		goto out;
-+
-+	id = of_hwspin_lock_simple_xlate(&args);
-+	if (id < 0 || id >= hwlock->bank->num_locks) {
-+		ret = -EINVAL;
-+		goto out;
-+	}
-+	id += hwlock->bank->base_id;
-+
-+out:
-+	of_node_put(args.np);
-+	return ret ? ret : id;
-+}
-+EXPORT_SYMBOL_GPL(of_hwspin_lock_get_id);
-+
- static int hwspin_lock_register_single(struct hwspinlock *hwlock, int id)
- {
- 	struct hwspinlock *tmp;
---- a/include/linux/hwspinlock.h
-+++ b/include/linux/hwspinlock.h
-@@ -26,6 +26,7 @@
- #define HWLOCK_IRQ	0x02	/* Disable interrupts, don't save state */
- 
- struct device;
-+struct device_node;
- struct hwspinlock;
- struct hwspinlock_device;
- struct hwspinlock_ops;
-@@ -66,6 +67,7 @@ int hwspin_lock_unregister(struct hwspin
- struct hwspinlock *hwspin_lock_request(void);
- struct hwspinlock *hwspin_lock_request_specific(unsigned int id);
- int hwspin_lock_free(struct hwspinlock *hwlock);
-+int of_hwspin_lock_get_id(struct device_node *np, int index);
- int hwspin_lock_get_id(struct hwspinlock *hwlock);
- int __hwspin_lock_timeout(struct hwspinlock *, unsigned int, int,
- 							unsigned long *);
-@@ -120,6 +122,11 @@ void __hwspin_unlock(struct hwspinlock *
- {
- }
- 
-+static inline int of_hwspin_lock_get_id(struct device_node *np, int index)
-+{
-+	return 0;
-+}
-+
- static inline int hwspin_lock_get_id(struct hwspinlock *hwlock)
- {
- 	return 0;
diff --git a/target/linux/ipq806x/patches-3.18/031-hwspinlock-qcom-Add-support-for-Qualcomm-HW-Mutex-bl.patch b/target/linux/ipq806x/patches-3.18/031-hwspinlock-qcom-Add-support-for-Qualcomm-HW-Mutex-bl.patch
deleted file mode 100644
index 581b199d7ff87d89360974675b4138a1f8471637..0000000000000000000000000000000000000000
--- a/target/linux/ipq806x/patches-3.18/031-hwspinlock-qcom-Add-support-for-Qualcomm-HW-Mutex-bl.patch
+++ /dev/null
@@ -1,234 +0,0 @@
-From 19a0f61224d2d91860fa8291ab63cb104ee86bdd Mon Sep 17 00:00:00 2001
-From: Bjorn Andersson <bjorn.andersson@sonymobile.com>
-Date: Tue, 24 Mar 2015 10:11:05 -0700
-Subject: [PATCH] hwspinlock: qcom: Add support for Qualcomm HW Mutex block
-
-Add driver for Qualcomm Hardware Mutex block found in many Qualcomm
-SoCs.
-
-Based on initial effort by Kumar Gala <galak@codeaurora.org>
-
-Signed-off-by: Bjorn Andersson <bjorn.andersson@sonymobile.com>
-Reviewed-by: Andy Gross <agross@codeaurora.org>
-Reviewed-by: Jeffrey Hugo <jhugo@codeaurora.org>
-Signed-off-by: Ohad Ben-Cohen <ohad@wizery.com>
----
- drivers/hwspinlock/Kconfig           |  12 +++
- drivers/hwspinlock/Makefile          |   1 +
- drivers/hwspinlock/qcom_hwspinlock.c | 181 +++++++++++++++++++++++++++++++++++
- 3 files changed, 194 insertions(+)
- create mode 100644 drivers/hwspinlock/qcom_hwspinlock.c
-
---- a/drivers/hwspinlock/Kconfig
-+++ b/drivers/hwspinlock/Kconfig
-@@ -18,6 +18,18 @@ config HWSPINLOCK_OMAP
- 
- 	  If unsure, say N.
- 
-+config HWSPINLOCK_QCOM
-+	tristate "Qualcomm Hardware Spinlock device"
-+	depends on ARCH_QCOM
-+	select HWSPINLOCK
-+	select MFD_SYSCON
-+	help
-+	  Say y here to support the Qualcomm Hardware Mutex functionality, which
-+	  provides a synchronisation mechanism for the various processors on
-+	  the SoC.
-+
-+	  If unsure, say N.
-+
- config HSEM_U8500
- 	tristate "STE Hardware Semaphore functionality"
- 	depends on ARCH_U8500
---- a/drivers/hwspinlock/Makefile
-+++ b/drivers/hwspinlock/Makefile
-@@ -4,4 +4,5 @@
- 
- obj-$(CONFIG_HWSPINLOCK)		+= hwspinlock_core.o
- obj-$(CONFIG_HWSPINLOCK_OMAP)		+= omap_hwspinlock.o
-+obj-$(CONFIG_HWSPINLOCK_QCOM)		+= qcom_hwspinlock.o
- obj-$(CONFIG_HSEM_U8500)		+= u8500_hsem.o
---- /dev/null
-+++ b/drivers/hwspinlock/qcom_hwspinlock.c
-@@ -0,0 +1,181 @@
-+/*
-+ * Copyright (c) 2013, The Linux Foundation. All rights reserved.
-+ * Copyright (c) 2015, Sony Mobile Communications AB
-+ *
-+ * 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/hwspinlock.h>
-+#include <linux/io.h>
-+#include <linux/kernel.h>
-+#include <linux/mfd/syscon.h>
-+#include <linux/module.h>
-+#include <linux/of.h>
-+#include <linux/of_device.h>
-+#include <linux/platform_device.h>
-+#include <linux/pm_runtime.h>
-+#include <linux/regmap.h>
-+
-+#include "hwspinlock_internal.h"
-+
-+#define QCOM_MUTEX_APPS_PROC_ID	1
-+#define QCOM_MUTEX_NUM_LOCKS	32
-+
-+static int qcom_hwspinlock_trylock(struct hwspinlock *lock)
-+{
-+	struct regmap_field *field = lock->priv;
-+	u32 lock_owner;
-+	int ret;
-+
-+	ret = regmap_field_write(field, QCOM_MUTEX_APPS_PROC_ID);
-+	if (ret)
-+		return ret;
-+
-+	ret = regmap_field_read(field, &lock_owner);
-+	if (ret)
-+		return ret;
-+
-+	return lock_owner == QCOM_MUTEX_APPS_PROC_ID;
-+}
-+
-+static void qcom_hwspinlock_unlock(struct hwspinlock *lock)
-+{
-+	struct regmap_field *field = lock->priv;
-+	u32 lock_owner;
-+	int ret;
-+
-+	ret = regmap_field_read(field, &lock_owner);
-+	if (ret) {
-+		pr_err("%s: unable to query spinlock owner\n", __func__);
-+		return;
-+	}
-+
-+	if (lock_owner != QCOM_MUTEX_APPS_PROC_ID) {
-+		pr_err("%s: spinlock not owned by us (actual owner is %d)\n",
-+				__func__, lock_owner);
-+	}
-+
-+	ret = regmap_field_write(field, 0);
-+	if (ret)
-+		pr_err("%s: failed to unlock spinlock\n", __func__);
-+}
-+
-+static const struct hwspinlock_ops qcom_hwspinlock_ops = {
-+	.trylock	= qcom_hwspinlock_trylock,
-+	.unlock		= qcom_hwspinlock_unlock,
-+};
-+
-+static const struct of_device_id qcom_hwspinlock_of_match[] = {
-+	{ .compatible = "qcom,sfpb-mutex" },
-+	{ .compatible = "qcom,tcsr-mutex" },
-+	{ }
-+};
-+MODULE_DEVICE_TABLE(of, qcom_hwspinlock_of_match);
-+
-+static int qcom_hwspinlock_probe(struct platform_device *pdev)
-+{
-+	struct hwspinlock_device *bank;
-+	struct device_node *syscon;
-+	struct reg_field field;
-+	struct regmap *regmap;
-+	size_t array_size;
-+	u32 stride;
-+	u32 base;
-+	int ret;
-+	int i;
-+
-+	syscon = of_parse_phandle(pdev->dev.of_node, "syscon", 0);
-+	if (!syscon) {
-+		dev_err(&pdev->dev, "no syscon property\n");
-+		return -ENODEV;
-+	}
-+
-+	regmap = syscon_node_to_regmap(syscon);
-+	if (IS_ERR(regmap))
-+		return PTR_ERR(regmap);
-+
-+	ret = of_property_read_u32_index(pdev->dev.of_node, "syscon", 1, &base);
-+	if (ret < 0) {
-+		dev_err(&pdev->dev, "no offset in syscon\n");
-+		return -EINVAL;
-+	}
-+
-+	ret = of_property_read_u32_index(pdev->dev.of_node, "syscon", 2, &stride);
-+	if (ret < 0) {
-+		dev_err(&pdev->dev, "no stride syscon\n");
-+		return -EINVAL;
-+	}
-+
-+	array_size = QCOM_MUTEX_NUM_LOCKS * sizeof(struct hwspinlock);
-+	bank = devm_kzalloc(&pdev->dev, sizeof(*bank) + array_size, GFP_KERNEL);
-+	if (!bank)
-+		return -ENOMEM;
-+
-+	platform_set_drvdata(pdev, bank);
-+
-+	for (i = 0; i < QCOM_MUTEX_NUM_LOCKS; i++) {
-+		field.reg = base + i * stride;
-+		field.lsb = 0;
-+		field.msb = 32;
-+
-+		bank->lock[i].priv = devm_regmap_field_alloc(&pdev->dev,
-+							     regmap, field);
-+	}
-+
-+	pm_runtime_enable(&pdev->dev);
-+
-+	ret = hwspin_lock_register(bank, &pdev->dev, &qcom_hwspinlock_ops,
-+				   0, QCOM_MUTEX_NUM_LOCKS);
-+	if (ret)
-+		pm_runtime_disable(&pdev->dev);
-+
-+	return ret;
-+}
-+
-+static int qcom_hwspinlock_remove(struct platform_device *pdev)
-+{
-+	struct hwspinlock_device *bank = platform_get_drvdata(pdev);
-+	int ret;
-+
-+	ret = hwspin_lock_unregister(bank);
-+	if (ret) {
-+		dev_err(&pdev->dev, "%s failed: %d\n", __func__, ret);
-+		return ret;
-+	}
-+
-+	pm_runtime_disable(&pdev->dev);
-+
-+	return 0;
-+}
-+
-+static struct platform_driver qcom_hwspinlock_driver = {
-+	.probe		= qcom_hwspinlock_probe,
-+	.remove		= qcom_hwspinlock_remove,
-+	.driver		= {
-+		.name	= "qcom_hwspinlock",
-+		.of_match_table = qcom_hwspinlock_of_match,
-+	},
-+};
-+
-+static int __init qcom_hwspinlock_init(void)
-+{
-+	return platform_driver_register(&qcom_hwspinlock_driver);
-+}
-+/* board init code might need to reserve hwspinlocks for predefined purposes */
-+postcore_initcall(qcom_hwspinlock_init);
-+
-+static void __exit qcom_hwspinlock_exit(void)
-+{
-+	platform_driver_unregister(&qcom_hwspinlock_driver);
-+}
-+module_exit(qcom_hwspinlock_exit);
-+
-+MODULE_LICENSE("GPL v2");
-+MODULE_DESCRIPTION("Hardware spinlock driver for Qualcomm SoCs");
diff --git a/target/linux/ipq806x/patches-3.18/032-hwspinlock-qcom-Correct-msb-in-regmap_field.patch b/target/linux/ipq806x/patches-3.18/032-hwspinlock-qcom-Correct-msb-in-regmap_field.patch
deleted file mode 100644
index 70d5a58248d90e9f379a8a9683a45f1fd815b637..0000000000000000000000000000000000000000
--- a/target/linux/ipq806x/patches-3.18/032-hwspinlock-qcom-Correct-msb-in-regmap_field.patch
+++ /dev/null
@@ -1,26 +0,0 @@
-From bd5717a4632cdecafe82d03de7dcb3b1876e2828 Mon Sep 17 00:00:00 2001
-From: Bjorn Andersson <bjorn.andersson@sonymobile.com>
-Date: Fri, 26 Jun 2015 14:47:21 -0700
-Subject: [PATCH] hwspinlock: qcom: Correct msb in regmap_field
-
-msb of the regmap_field was mistakenly given the value 32, to set all bits
-in the regmap update mask; although incorrect this worked until 921cc294,
-where the mask calculation was corrected.
-
-Signed-off-by: Bjorn Andersson <bjorn.andersson@sonymobile.com>
-Signed-off-by: Ohad Ben-Cohen <ohad@wizery.com>
----
- drivers/hwspinlock/qcom_hwspinlock.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/drivers/hwspinlock/qcom_hwspinlock.c
-+++ b/drivers/hwspinlock/qcom_hwspinlock.c
-@@ -123,7 +123,7 @@ static int qcom_hwspinlock_probe(struct
- 	for (i = 0; i < QCOM_MUTEX_NUM_LOCKS; i++) {
- 		field.reg = base + i * stride;
- 		field.lsb = 0;
--		field.msb = 32;
-+		field.msb = 31;
- 
- 		bank->lock[i].priv = devm_regmap_field_alloc(&pdev->dev,
- 							     regmap, field);
diff --git a/target/linux/ipq806x/patches-3.18/033-ARM-qcom-add-SFPB-nodes-to-IPQ806x-dts.patch b/target/linux/ipq806x/patches-3.18/033-ARM-qcom-add-SFPB-nodes-to-IPQ806x-dts.patch
deleted file mode 100644
index 4a353254bfec700b7865271c28e69536954b0ca1..0000000000000000000000000000000000000000
--- a/target/linux/ipq806x/patches-3.18/033-ARM-qcom-add-SFPB-nodes-to-IPQ806x-dts.patch
+++ /dev/null
@@ -1,34 +0,0 @@
-From c7c482da19a5e4ba7101198c21c2434056b0b2da Mon Sep 17 00:00:00 2001
-From: Mathieu Olivari <mathieu@codeaurora.org>
-Date: Thu, 13 Aug 2015 09:45:26 -0700
-Subject: [PATCH 1/3] ARM: qcom: add SFPB nodes to IPQ806x dts
-
-Add one new node to the ipq806x.dtsi file to declare & register the
-hardware spinlock devices. This mechanism is required to be used by
-other drivers such as SMEM.
-
-Signed-off-by: Mathieu Olivari <mathieu@codeaurora.org>
----
- arch/arm/boot/dts/qcom-ipq8064.dtsi | 11 +++++++++++
- 1 file changed, 11 insertions(+)
-
---- a/arch/arm/boot/dts/qcom-ipq8064.dtsi
-+++ b/arch/arm/boot/dts/qcom-ipq8064.dtsi
-@@ -291,5 +291,17 @@
- 			#clock-cells = <1>;
- 			#reset-cells = <1>;
- 		};
-+
-+		sfpb_mutex_block: syscon@1200600 {
-+			compatible = "syscon";
-+			reg = <0x01200600 0x100>;
-+		};
- 	};
-+
-+	sfpb_mutex: sfpb-mutex {
-+		compatible = "qcom,sfpb-mutex";
-+		syscon = <&sfpb_mutex_block 4 4>;
-+
-+		#hwlock-cells = <1>;
-+ 	};
- };
diff --git a/target/linux/ipq806x/patches-3.18/034-soc-qcom-Add-device-tree-binding-for-SMEM.patch b/target/linux/ipq806x/patches-3.18/034-soc-qcom-Add-device-tree-binding-for-SMEM.patch
deleted file mode 100644
index d22db2226eda6961358e80b00ada8ae41ba83a4d..0000000000000000000000000000000000000000
--- a/target/linux/ipq806x/patches-3.18/034-soc-qcom-Add-device-tree-binding-for-SMEM.patch
+++ /dev/null
@@ -1,82 +0,0 @@
-Content-Type: text/plain; charset="utf-8"
-MIME-Version: 1.0
-Content-Transfer-Encoding: 7bit
-Subject: [v2,1/2] soc: qcom: Add device tree binding for SMEM
-From: Bjorn Andersson <bjorn.andersson@sonymobile.com>
-X-Patchwork-Id: 6202201
-Message-Id: <1428795178-24312-1-git-send-email-bjorn.andersson@sonymobile.com>
-To: Rob Herring <robh+dt@kernel.org>, Pawel Moll <pawel.moll@arm.com>,
-	Mark Rutland <mark.rutland@arm.com>,
-	Ian Campbell <ijc+devicetree@hellion.org.uk>,
-	Kumar Gala <galak@codeaurora.org>, Jeffrey Hugo <jhugo@codeaurora.org>, 
-	Andry Gross <agross@codeaurora.org>
-Cc: <devicetree@vger.kernel.org>,
-	linux-arm-msm <linux-arm-msm@vger.kernel.org>,
-	<linux-kernel@vger.kernel.org>
-Date: Sat, 11 Apr 2015 16:32:57 -0700
-
-Add device tree binding documentation for the Qualcom Shared Memory
-manager.
-
-Signed-off-by: Bjorn Andersson <bjorn.andersson@sonymobile.com>
-
----
-Changes since v1:
-- None
-
- .../devicetree/bindings/soc/qcom/qcom,smem.txt     | 49 ++++++++++++++++++++++
- 1 file changed, 49 insertions(+)
- create mode 100644 Documentation/devicetree/bindings/soc/qcom/qcom,smem.txt
-
---- /dev/null
-+++ b/Documentation/devicetree/bindings/soc/qcom/qcom,smem.txt
-@@ -0,0 +1,49 @@
-+Qualcomm Shared Memory binding
-+
-+This binding describes the Qualcomm Shared Memory, used to share data between
-+various subsystems and OSes in Qualcomm platforms.
-+
-+- compatible:
-+	Usage: required
-+	Value type: <stringlist>
-+	Definition: must be:
-+		    "qcom,smem"
-+
-+- memory-region:
-+	Usage: required
-+	Value type: <prop-encoded-array>
-+	Definition: handle to memory reservation for main smem memory region.
-+
-+- reg:
-+	Usage: optional
-+	Value type: <prop-encoded-array>
-+	Definition: base address and size pair for any additional memory areas
-+		    of the shared memory.
-+
-+- hwspinlocks:
-+	Usage: required
-+	Value type: <prop-encoded-array>
-+	Definition: reference to a hwspinlock used to protect allocations from
-+		    the shared memory
-+
-+= EXAMPLE
-+
-+	reserved-memory {
-+		#address-cells = <1>;
-+		#size-cells = <1>;
-+		ranges;
-+
-+		smem_region: smem@fa00000 {
-+			reg = <0xfa00000 0x200000>;
-+			no-map;
-+		};
-+	};
-+
-+	smem@fa00000 {
-+		compatible = "qcom,smem";
-+
-+		memory-region = <&smem_region>;
-+		reg = <0xfc428000 0x4000>;
-+
-+		hwlocks = <&tcsr_mutex 3>;
-+	};
diff --git a/target/linux/ipq806x/patches-3.18/035-soc-qcom-Add-Shared-Memory-Manager-driver.patch b/target/linux/ipq806x/patches-3.18/035-soc-qcom-Add-Shared-Memory-Manager-driver.patch
deleted file mode 100644
index c8cff1a2887e5dc05ea1bde8fccfd502d877e22b..0000000000000000000000000000000000000000
--- a/target/linux/ipq806x/patches-3.18/035-soc-qcom-Add-Shared-Memory-Manager-driver.patch
+++ /dev/null
@@ -1,841 +0,0 @@
-Content-Type: text/plain; charset="utf-8"
-MIME-Version: 1.0
-Content-Transfer-Encoding: 7bit
-Subject: [v2,2/2] soc: qcom: Add Shared Memory Manager driver
-From: Bjorn Andersson <bjorn.andersson@sonymobile.com>
-X-Patchwork-Id: 6202211
-Message-Id: <1428795178-24312-2-git-send-email-bjorn.andersson@sonymobile.com>
-To: Kumar Gala <galak@codeaurora.org>, Andy Gross <agross@codeaurora.org>,
-	David Brown <davidb@codeaurora.org>, Jeffrey Hugo <jhugo@codeaurora.org>
-Cc: <linux-kernel@vger.kernel.org>, <linux-arm-msm@vger.kernel.org>,
-	<linux-soc@vger.kernel.org>
-Date: Sat, 11 Apr 2015 16:32:58 -0700
-
-The Shared Memory Manager driver implements an interface for allocating
-and accessing items in the memory area shared among all of the
-processors in a Qualcomm platform.
-
-Signed-off-by: Bjorn Andersson <bjorn.andersson@sonymobile.com>
-Reviewed-by: Andy Gross <agross@codeaurora.org>
-Tested-by: Andy Gross <agross@codeaurora.org>
-
----
-Changes since v1:
-- ioremapping the regions nocache
-- improved documentation of the two regions of partitions
-- corrected free space check in private allocator
-
- drivers/soc/qcom/Kconfig      |   7 +
- drivers/soc/qcom/Makefile     |   1 +
- drivers/soc/qcom/smem.c       | 768 ++++++++++++++++++++++++++++++++++++++++++
- include/linux/soc/qcom/smem.h |  14 +
- 4 files changed, 790 insertions(+)
- create mode 100644 drivers/soc/qcom/smem.c
- create mode 100644 include/linux/soc/qcom/smem.h
-
---- a/drivers/soc/qcom/Kconfig
-+++ b/drivers/soc/qcom/Kconfig
-@@ -9,3 +9,10 @@ config QCOM_GSBI
-           functions for connecting the underlying serial UART, SPI, and I2C
-           devices to the output pins.
- 
-+config QCOM_SMEM
-+	tristate "Qualcomm Shared Memory Manager (SMEM)"
-+	depends on ARCH_QCOM
-+	help
-+	  Say y here to enable support for the Qualcomm Shared Memory Manager.
-+	  The driver provides an interface to items in a heap shared among all
-+	  processors in a Qualcomm platform.
---- a/drivers/soc/qcom/Makefile
-+++ b/drivers/soc/qcom/Makefile
-@@ -1 +1,2 @@
- obj-$(CONFIG_QCOM_GSBI)	+=	qcom_gsbi.o
-+obj-$(CONFIG_QCOM_SMEM) +=	smem.o
---- /dev/null
-+++ b/drivers/soc/qcom/smem.c
-@@ -0,0 +1,768 @@
-+/*
-+ * Copyright (c) 2015, Sony Mobile Communications AB.
-+ * 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/hwspinlock.h>
-+#include <linux/io.h>
-+#include <linux/module.h>
-+#include <linux/of.h>
-+#include <linux/of_address.h>
-+#include <linux/platform_device.h>
-+#include <linux/slab.h>
-+#include <linux/soc/qcom/smem.h>
-+
-+/*
-+ * The Qualcomm shared memory system is a allocate only heap structure that
-+ * consists of one of more memory areas that can be accessed by the processors
-+ * in the SoC.
-+ *
-+ * All systems contains a global heap, accessible by all processors in the SoC,
-+ * with a table of contents data structure (@smem_header) at the beginning of
-+ * the main shared memory block.
-+ *
-+ * The global header contains metadata for allocations as well as a fixed list
-+ * of 512 entries (@smem_global_entry) that can be initialized to reference
-+ * parts of the shared memory space.
-+ *
-+ *
-+ * In addition to this global heap a set of "private" heaps can be set up at
-+ * boot time with access restrictions so that only certain processor pairs can
-+ * access the data.
-+ *
-+ * These partitions are referenced from an optional partition table
-+ * (@smem_ptable), that is found 4kB from the end of the main smem region. The
-+ * partition table entries (@smem_ptable_entry) lists the involved processors
-+ * (or hosts) and their location in the main shared memory region.
-+ *
-+ * Each partition starts with a header (@smem_partition_header) that identifies
-+ * the partition and holds properties for the two internal memory regions. The
-+ * two regions are cached and non-cached memory respectively. Each region
-+ * contain a link list of allocation headers (@smem_private_entry) followed by
-+ * their data.
-+ *
-+ * Items in the non-cached region are allocated from the start of the partition
-+ * while items in the cached region are allocated from the end. The free area
-+ * is hence the region between the cached and non-cached offsets.
-+ *
-+ *
-+ * To synchronize allocations in the shared memory heaps a remote spinlock must
-+ * be held - currently lock number 3 of the sfpb or tcsr is used for this on all
-+ * platforms.
-+ *
-+ */
-+
-+/**
-+  * struct smem_proc_comm - proc_comm communication struct (legacy)
-+  * @command:	current command to be executed
-+  * @status:	status of the currently requested command
-+  * @params:	parameters to the command
-+  */
-+struct smem_proc_comm {
-+	u32 command;
-+	u32 status;
-+	u32 params[2];
-+};
-+
-+/**
-+ * struct smem_global_entry - entry to reference smem items on the heap
-+ * @allocated:	boolean to indicate if this entry is used
-+ * @offset:	offset to the allocated space
-+ * @size:	size of the allocated space, 8 byte aligned
-+ * @aux_base:	base address for the memory region used by this unit, or 0 for
-+ *		the default region. bits 0,1 are reserved
-+ */
-+struct smem_global_entry {
-+	u32 allocated;
-+	u32 offset;
-+	u32 size;
-+	u32 aux_base; /* bits 1:0 reserved */
-+};
-+#define AUX_BASE_MASK		0xfffffffc
-+
-+/**
-+ * struct smem_header - header found in beginning of primary smem region
-+ * @proc_comm:		proc_comm communication interface (legacy)
-+ * @version:		array of versions for the various subsystems
-+ * @initialized:	boolean to indicate that smem is initialized
-+ * @free_offset:	index of the first unallocated byte in smem
-+ * @available:		number of bytes available for allocation
-+ * @reserved:		reserved field, must be 0
-+ * toc:			array of references to items
-+ */
-+struct smem_header {
-+	struct smem_proc_comm proc_comm[4];
-+	u32 version[32];
-+	u32 initialized;
-+	u32 free_offset;
-+	u32 available;
-+	u32 reserved;
-+	struct smem_global_entry toc[];
-+};
-+
-+/**
-+ * struct smem_ptable_entry - one entry in the @smem_ptable list
-+ * @offset:	offset, within the main shared memory region, of the partition
-+ * @size:	size of the partition
-+ * @flags:	flags for the partition (currently unused)
-+ * @host0:	first processor/host with access to this partition
-+ * @host1:	second processor/host with access to this partition
-+ * @reserved:	reserved entries for later use
-+ */
-+struct smem_ptable_entry {
-+	u32 offset;
-+	u32 size;
-+	u32 flags;
-+	u16 host0;
-+	u16 host1;
-+	u32 reserved[8];
-+};
-+
-+/**
-+ * struct smem_ptable - partition table for the private partitions
-+ * @magic:	magic number, must be SMEM_PTABLE_MAGIC
-+ * @version:	version of the partition table
-+ * @num_entries: number of partitions in the table
-+ * @reserved:	for now reserved entries
-+ * @entry:	list of @smem_ptable_entry for the @num_entries partitions
-+ */
-+struct smem_ptable {
-+	u32 magic;
-+	u32 version;
-+	u32 num_entries;
-+	u32 reserved[5];
-+	struct smem_ptable_entry entry[];
-+};
-+#define SMEM_PTABLE_MAGIC	0x434f5424 /* "$TOC" */
-+
-+/**
-+ * struct smem_partition_header - header of the partitions
-+ * @magic:	magic number, must be SMEM_PART_MAGIC
-+ * @host0:	first processor/host with access to this partition
-+ * @host1:	second processor/host with access to this partition
-+ * @size:	size of the partition
-+ * @offset_free_uncached: offset to the first free byte of uncached memory in
-+ *		this partition
-+ * @offset_free_cached: offset to the first free byte of cached memory in this
-+ *		partition
-+ * @reserved:	for now reserved entries
-+ */
-+struct smem_partition_header {
-+	u32 magic;
-+	u16 host0;
-+	u16 host1;
-+	u32 size;
-+	u32 offset_free_uncached;
-+	u32 offset_free_cached;
-+	u32 reserved[3];
-+};
-+#define SMEM_PART_MAGIC		0x54525024 /* "$PRT" */
-+
-+/**
-+ * struct smem_private_entry - header of each item in the private partition
-+ * @canary:	magic number, must be SMEM_PRIVATE_CANARY
-+ * @item:	identifying number of the smem item
-+ * @size:	size of the data, including padding bytes
-+ * @padding_data: number of bytes of padding of data
-+ * @padding_hdr: number of bytes of padding between the header and the data
-+ * @reserved:	for now reserved entry
-+ */
-+struct smem_private_entry {
-+	u16 canary;
-+	u16 item;
-+	u32 size; /* includes padding bytes */
-+	u16 padding_data;
-+	u16 padding_hdr;
-+	u32 reserved;
-+};
-+#define SMEM_PRIVATE_CANARY	0xa5a5
-+
-+/*
-+ * Item 3 of the global heap contains an array of versions for the various
-+ * software components in the SoC. We verify that the boot loader version is
-+ * what the expected version (SMEM_EXPECTED_VERSION) as a sanity check.
-+ */
-+#define SMEM_ITEM_VERSION	3
-+#define  SMEM_MASTER_SBL_VERSION_INDEX	7
-+#define  SMEM_EXPECTED_VERSION		11
-+
-+/*
-+ * The first 8 items are only to be allocated by the boot loader while
-+ * initializing the heap.
-+ */
-+#define SMEM_ITEM_LAST_FIXED	8
-+
-+/* Highest accepted item number, for both global and private heaps */
-+#define SMEM_ITEM_LAST		512
-+
-+/* Processor/host identifier for the application processor */
-+#define SMEM_HOST_APPS		0
-+
-+/* Max number of processors/hosts in a system */
-+#define SMEM_HOST_COUNT		7
-+
-+/**
-+ * struct smem_region - representation of a chunk of memory used for smem
-+ * @aux_base:	identifier of aux_mem base
-+ * @virt_base:	virtual base address of memory with this aux_mem identifier
-+ * @size:	size of the memory region
-+ */
-+struct smem_region {
-+	u32 aux_base;
-+	void __iomem *virt_base;
-+	size_t size;
-+};
-+
-+/**
-+ * struct qcom_smem - device data for the smem device
-+ * @dev:	device pointer
-+ * @hwlock:	reference to a hwspinlock
-+ * @partitions:	list of pointers to partitions affecting the current
-+ *		processor/host
-+ * @num_regions: number of @regions
-+ * @regions:	list of the memory regions defining the shared memory
-+ */
-+struct qcom_smem {
-+	struct device *dev;
-+
-+	struct hwspinlock *hwlock;
-+
-+	struct smem_partition_header *partitions[SMEM_HOST_COUNT];
-+
-+	unsigned num_regions;
-+	struct smem_region regions[0];
-+};
-+
-+/* Pointer to the one and only smem handle */
-+static struct qcom_smem *__smem;
-+
-+/* Timeout (ms) for the trylock of remote spinlocks */
-+#define HWSPINLOCK_TIMEOUT	1000
-+
-+static int qcom_smem_alloc_private(struct qcom_smem *smem,
-+				   unsigned host,
-+				   unsigned item,
-+				   size_t size)
-+{
-+	struct smem_partition_header *phdr;
-+	struct smem_private_entry *hdr;
-+	size_t alloc_size;
-+	void *p;
-+
-+	/* We're not going to find it if there's no matching partition */
-+	if (host >= SMEM_HOST_COUNT || !smem->partitions[host])
-+		return -ENOENT;
-+
-+	phdr = smem->partitions[host];
-+
-+	p = (void *)phdr + sizeof(*phdr);
-+	while (p < (void *)phdr + phdr->offset_free_uncached) {
-+		hdr = p;
-+
-+		if (hdr->canary != SMEM_PRIVATE_CANARY) {
-+			dev_err(smem->dev,
-+				"Found invalid canary in host %d partition\n",
-+				host);
-+			return -EINVAL;
-+		}
-+
-+		if (hdr->item == item)
-+			return -EEXIST;
-+
-+		p += sizeof(*hdr) + hdr->padding_hdr + hdr->size;
-+	}
-+
-+	/* Check that we don't grow into the cached region */
-+	alloc_size = sizeof(*hdr) + ALIGN(size, 8);
-+	if (p + alloc_size >= (void *)phdr + phdr->offset_free_cached) {
-+		dev_err(smem->dev, "Out of memory\n");
-+		return -ENOSPC;
-+	}
-+
-+	hdr = p;
-+	hdr->canary = SMEM_PRIVATE_CANARY;
-+	hdr->item = item;
-+	hdr->size = ALIGN(size, 8);
-+	hdr->padding_data = hdr->size - size;
-+	hdr->padding_hdr = 0;
-+
-+	/*
-+	 * Ensure the header is written before we advance the free offset, so
-+	 * that remote processors that does not take the remote spinlock still
-+	 * gets a consistent view of the linked list.
-+	 */
-+	wmb();
-+	phdr->offset_free_uncached += alloc_size;
-+
-+	return 0;
-+}
-+
-+static int qcom_smem_alloc_global(struct qcom_smem *smem,
-+				  unsigned item,
-+				  size_t size)
-+{
-+	struct smem_header *header;
-+	struct smem_global_entry *entry;
-+
-+	if (WARN_ON(item >= SMEM_ITEM_LAST))
-+		return -EINVAL;
-+
-+	header = smem->regions[0].virt_base;
-+	entry = &header->toc[item];
-+	if (entry->allocated)
-+		return -EEXIST;
-+
-+	size = ALIGN(size, 8);
-+	if (WARN_ON(size > header->available))
-+		return -ENOMEM;
-+
-+	entry->offset = header->free_offset;
-+	entry->size = size;
-+
-+	/*
-+	 * Ensure the header is consistent before we mark the item allocated,
-+	 * so that remote processors will get a consistent view of the item
-+	 * even though they do not take the spinlock on read.
-+	 */
-+	wmb();
-+	entry->allocated = 1;
-+
-+	header->free_offset += size;
-+	header->available -= size;
-+
-+	return 0;
-+}
-+
-+/**
-+ * qcom_smem_alloc - allocate space for a smem item
-+ * @host:	remote processor id, or -1
-+ * @item:	smem item handle
-+ * @size:	number of bytes to be allocated
-+ *
-+ * Allocate space for a given smem item of size @size, given that the item is
-+ * not yet allocated.
-+ */
-+int qcom_smem_alloc(unsigned host, unsigned item, size_t size)
-+{
-+	unsigned long flags;
-+	int ret;
-+
-+	if (!__smem)
-+		return -EPROBE_DEFER;
-+
-+	if (item < SMEM_ITEM_LAST_FIXED) {
-+		dev_err(__smem->dev,
-+			"Rejecting allocation of static entry %d\n", item);
-+		return -EINVAL;
-+	}
-+
-+	ret = hwspin_lock_timeout_irqsave(__smem->hwlock,
-+					  HWSPINLOCK_TIMEOUT,
-+					  &flags);
-+	if (ret)
-+		return ret;
-+
-+	ret = qcom_smem_alloc_private(__smem, host, item, size);
-+	if (ret == -ENOENT)
-+		ret = qcom_smem_alloc_global(__smem, item, size);
-+
-+	hwspin_unlock_irqrestore(__smem->hwlock, &flags);
-+
-+	return ret;
-+}
-+EXPORT_SYMBOL(qcom_smem_alloc);
-+
-+static int qcom_smem_get_global(struct qcom_smem *smem,
-+				unsigned item,
-+				void **ptr,
-+				size_t *size)
-+{
-+	struct smem_header *header;
-+	struct smem_region *area;
-+	struct smem_global_entry *entry;
-+	u32 aux_base;
-+	unsigned i;
-+
-+	if (WARN_ON(item >= SMEM_ITEM_LAST))
-+		return -EINVAL;
-+
-+	header = smem->regions[0].virt_base;
-+	entry = &header->toc[item];
-+	if (!entry->allocated)
-+		return -ENXIO;
-+
-+	if (ptr != NULL) {
-+		aux_base = entry->aux_base & AUX_BASE_MASK;
-+
-+		for (i = 0; i < smem->num_regions; i++) {
-+			area = &smem->regions[i];
-+
-+			if (area->aux_base == aux_base || !aux_base) {
-+				*ptr = area->virt_base + entry->offset;
-+				break;
-+			}
-+		}
-+	}
-+	if (size != NULL)
-+		*size = entry->size;
-+
-+	return 0;
-+}
-+
-+static int qcom_smem_get_private(struct qcom_smem *smem,
-+				 unsigned host,
-+				 unsigned item,
-+				 void **ptr,
-+				 size_t *size)
-+{
-+	struct smem_partition_header *phdr;
-+	struct smem_private_entry *hdr;
-+	void *p;
-+
-+	/* We're not going to find it if there's no matching partition */
-+	if (host >= SMEM_HOST_COUNT || !smem->partitions[host])
-+		return -ENOENT;
-+
-+	phdr = smem->partitions[host];
-+
-+	p = (void *)phdr + sizeof(*phdr);
-+	while (p < (void *)phdr + phdr->offset_free_uncached) {
-+		hdr = p;
-+
-+		if (hdr->canary != SMEM_PRIVATE_CANARY) {
-+			dev_err(smem->dev,
-+				"Found invalid canary in host %d partition\n",
-+				host);
-+			return -EINVAL;
-+		}
-+
-+		if (hdr->item == item) {
-+			if (ptr != NULL)
-+				*ptr = p + sizeof(*hdr) + hdr->padding_hdr;
-+
-+			if (size != NULL)
-+				*size = hdr->size - hdr->padding_data;
-+
-+			return 0;
-+		}
-+
-+		p += sizeof(*hdr) + hdr->padding_hdr + hdr->size;
-+	}
-+
-+	return -ENOENT;
-+}
-+
-+/**
-+ * qcom_smem_get - resolve ptr of size of a smem item
-+ * @host:	the remote processor, or -1
-+ * @item:	smem item handle
-+ * @ptr:	pointer to be filled out with address of the item
-+ * @size:	pointer to be filled out with size of the item
-+ *
-+ * Looks up pointer and size of a smem item.
-+ */
-+int qcom_smem_get(unsigned host, unsigned item, void **ptr, size_t *size)
-+{
-+	unsigned long flags;
-+	int ret;
-+
-+	if (!__smem)
-+		return -EPROBE_DEFER;
-+
-+	ret = hwspin_lock_timeout_irqsave(__smem->hwlock,
-+					  HWSPINLOCK_TIMEOUT,
-+					  &flags);
-+	if (ret)
-+		return ret;
-+
-+	ret = qcom_smem_get_private(__smem, host, item, ptr, size);
-+	if (ret == -ENOENT)
-+		ret = qcom_smem_get_global(__smem, item, ptr, size);
-+
-+	hwspin_unlock_irqrestore(__smem->hwlock, &flags);
-+	return ret;
-+
-+}
-+EXPORT_SYMBOL(qcom_smem_get);
-+
-+/**
-+ * qcom_smem_get_free_space - retrieve amont of free space in a partition
-+ * @host:	the remote processor identifing a partition, or -1
-+ *
-+ * To be used by smem clients as a quick way to determine if any new
-+ * allocations has been made.
-+ */
-+int qcom_smem_get_free_space(unsigned host)
-+{
-+	struct smem_partition_header *phdr;
-+	struct smem_header *header;
-+	unsigned ret;
-+
-+	if (!__smem)
-+		return -EPROBE_DEFER;
-+
-+	if (host < SMEM_HOST_COUNT && __smem->partitions[host]) {
-+		phdr = __smem->partitions[host];
-+		ret = phdr->offset_free_uncached;
-+	} else {
-+		header = __smem->regions[0].virt_base;
-+		ret = header->available;
-+	}
-+
-+	return ret;
-+}
-+EXPORT_SYMBOL(qcom_smem_get_free_space);
-+
-+static int qcom_smem_get_sbl_version(struct qcom_smem *smem)
-+{
-+	unsigned *versions;
-+	size_t size;
-+	int ret;
-+
-+	ret = qcom_smem_get_global(smem, SMEM_ITEM_VERSION,
-+				   (void **)&versions, &size);
-+	if (ret < 0) {
-+		dev_err(smem->dev, "Unable to read the version item\n");
-+		return -ENOENT;
-+	}
-+
-+	if (size < sizeof(unsigned) * SMEM_MASTER_SBL_VERSION_INDEX) {
-+		dev_err(smem->dev, "Version item is too small\n");
-+		return -EINVAL;
-+	}
-+
-+	return versions[SMEM_MASTER_SBL_VERSION_INDEX];
-+}
-+
-+static int qcom_smem_enumerate_partitions(struct qcom_smem *smem,
-+					  unsigned local_host)
-+{
-+	struct smem_partition_header *header;
-+	struct smem_ptable_entry *entry;
-+	struct smem_ptable *ptable;
-+	unsigned remote_host;
-+	int i;
-+
-+	ptable = smem->regions[0].virt_base + smem->regions[0].size - 4 * 1024;
-+	if (ptable->magic != SMEM_PTABLE_MAGIC)
-+		return 0;
-+
-+	if (ptable->version != 1) {
-+		dev_err(smem->dev,
-+			"Unsupported partition header version %d\n",
-+			ptable->version);
-+		return -EINVAL;
-+	}
-+
-+	for (i = 0; i < ptable->num_entries; i++) {
-+		entry = &ptable->entry[i];
-+
-+		if (entry->host0 != local_host && entry->host1 != local_host)
-+			continue;
-+
-+		if (!entry->offset)
-+			continue;
-+
-+		if (!entry->size)
-+			continue;
-+
-+		if (entry->host0 == local_host)
-+			remote_host = entry->host1;
-+		else
-+			remote_host = entry->host0;
-+
-+		if (smem->partitions[remote_host]) {
-+			dev_err(smem->dev,
-+				"Already found a partition for host %d\n",
-+				remote_host);
-+			return -EINVAL;
-+		}
-+
-+		header = smem->regions[0].virt_base + entry->offset;
-+
-+		if (header->magic != SMEM_PART_MAGIC) {
-+			dev_err(smem->dev,
-+				"Partition %d has invalid magic\n", i);
-+			return -EINVAL;
-+		}
-+
-+		if (header->host0 != local_host && header->host1 != local_host) {
-+			dev_err(smem->dev,
-+				"Partition %d hosts are invalid\n", i);
-+			return -EINVAL;
-+		}
-+
-+		if (header->host0 != remote_host && header->host1 != remote_host) {
-+			dev_err(smem->dev,
-+				"Partition %d hosts are invalid\n", i);
-+			return -EINVAL;
-+		}
-+
-+		if (header->size != entry->size) {
-+			dev_err(smem->dev,
-+				"Partition %d has invalid size\n", i);
-+			return -EINVAL;
-+		}
-+
-+		if (header->offset_free_uncached > header->size) {
-+			dev_err(smem->dev,
-+				"Partition %d has invalid free pointer\n", i);
-+			return -EINVAL;
-+		}
-+
-+		smem->partitions[remote_host] = header;
-+	}
-+
-+	return 0;
-+}
-+
-+static int qcom_smem_count_mem_regions(struct platform_device *pdev)
-+{
-+	struct resource *res;
-+	int num_regions = 0;
-+	int i;
-+
-+	for (i = 0; i < pdev->num_resources; i++) {
-+		res = &pdev->resource[i];
-+
-+		if (resource_type(res) == IORESOURCE_MEM)
-+			num_regions++;
-+	}
-+
-+	return num_regions;
-+}
-+
-+static int qcom_smem_probe(struct platform_device *pdev)
-+{
-+	struct smem_header *header;
-+	struct device_node *np;
-+	struct qcom_smem *smem;
-+	struct resource *res;
-+	struct resource r;
-+	size_t array_size;
-+	int num_regions = 0;
-+	int hwlock_id;
-+	u32 version;
-+	int ret;
-+	int i;
-+
-+	num_regions = qcom_smem_count_mem_regions(pdev) + 1;
-+
-+	array_size = num_regions * sizeof(struct smem_region);
-+	smem = devm_kzalloc(&pdev->dev, sizeof(*smem) + array_size, GFP_KERNEL);
-+	if (!smem)
-+		return -ENOMEM;
-+
-+	smem->dev = &pdev->dev;
-+	smem->num_regions = num_regions;
-+
-+	np = of_parse_phandle(pdev->dev.of_node, "memory-region", 0);
-+	if (!np) {
-+		dev_err(&pdev->dev, "No memory-region specified\n");
-+		return -EINVAL;
-+	}
-+
-+	ret = of_address_to_resource(np, 0, &r);
-+	of_node_put(np);
-+	if (ret)
-+		return ret;
-+
-+	smem->regions[0].aux_base = (u32)r.start;
-+	smem->regions[0].size = resource_size(&r);
-+	smem->regions[0].virt_base = devm_ioremap_nocache(&pdev->dev,
-+							  r.start,
-+							  resource_size(&r));
-+	if (!smem->regions[0].virt_base)
-+		return -ENOMEM;
-+
-+	for (i = 1; i < num_regions; i++) {
-+		res = platform_get_resource(pdev, IORESOURCE_MEM, i - 1);
-+
-+		smem->regions[i].aux_base = (u32)res->start;
-+		smem->regions[i].size = resource_size(res);
-+		smem->regions[i].virt_base = devm_ioremap_nocache(&pdev->dev,
-+								  res->start,
-+								  resource_size(res));
-+		if (!smem->regions[i].virt_base)
-+			return -ENOMEM;
-+	}
-+
-+	header = smem->regions[0].virt_base;
-+	if (header->initialized != 1 || header->reserved) {
-+		dev_err(&pdev->dev, "SMEM is not initilized by SBL\n");
-+		return -EINVAL;
-+	}
-+
-+	version = qcom_smem_get_sbl_version(smem);
-+	if (version >> 16 != SMEM_EXPECTED_VERSION) {
-+		dev_err(&pdev->dev, "Unsupported smem version 0x%x\n", version);
-+		return -EINVAL;
-+	}
-+
-+	ret = qcom_smem_enumerate_partitions(smem, SMEM_HOST_APPS);
-+	if (ret < 0)
-+		return ret;
-+
-+	hwlock_id = of_hwspin_lock_get_id(pdev->dev.of_node, 0);
-+	if (hwlock_id < 0) {
-+		dev_err(&pdev->dev, "failed to retrieve hwlock\n");
-+		return hwlock_id;
-+	}
-+
-+	smem->hwlock = hwspin_lock_request_specific(hwlock_id);
-+	if (!smem->hwlock)
-+		return -ENXIO;
-+
-+	__smem = smem;
-+
-+	return 0;
-+}
-+
-+static int qcom_smem_remove(struct platform_device *pdev)
-+{
-+	hwspin_lock_free(__smem->hwlock);
-+	__smem = NULL;
-+
-+	return 0;
-+}
-+
-+static const struct of_device_id qcom_smem_of_match[] = {
-+	{ .compatible = "qcom,smem" },
-+	{}
-+};
-+MODULE_DEVICE_TABLE(of, qcom_smem_of_match);
-+
-+static struct platform_driver qcom_smem_driver = {
-+	.probe = qcom_smem_probe,
-+	.remove = qcom_smem_remove,
-+	.driver  = {
-+		.name = "qcom_smem",
-+		.of_match_table = qcom_smem_of_match,
-+		.suppress_bind_attrs = true,
-+	},
-+};
-+
-+static int __init qcom_smem_init(void)
-+{
-+	return platform_driver_register(&qcom_smem_driver);
-+}
-+arch_initcall(qcom_smem_init);
-+
-+static void __exit qcom_smem_exit(void)
-+{
-+	platform_driver_unregister(&qcom_smem_driver);
-+}
-+module_exit(qcom_smem_exit)
-+
-+MODULE_AUTHOR("Bjorn Andersson <bjorn.andersson@sonymobile.com>");
-+MODULE_DESCRIPTION("Qualcomm Shared Memory Manager");
-+MODULE_LICENSE("GPLv2");
---- /dev/null
-+++ b/include/linux/soc/qcom/smem.h
-@@ -0,0 +1,14 @@
-+#ifndef __QCOM_SMEM_H__
-+#define __QCOM_SMEM_H__
-+
-+struct device_node;
-+struct qcom_smem;
-+
-+#define QCOM_SMEM_HOST_ANY -1
-+
-+int qcom_smem_alloc(unsigned host, unsigned item, size_t size);
-+int qcom_smem_get(unsigned host, unsigned item, void **ptr, size_t *size);
-+
-+int qcom_smem_get_free_space(unsigned host);
-+
-+#endif
diff --git a/target/linux/ipq806x/patches-3.18/036-ARM-qcom-add-SMEM-device-node-to-IPQ806x-dts.patch b/target/linux/ipq806x/patches-3.18/036-ARM-qcom-add-SMEM-device-node-to-IPQ806x-dts.patch
deleted file mode 100644
index b2b9a749c34c3d7e0662f0da9a341dea69ecbd08..0000000000000000000000000000000000000000
--- a/target/linux/ipq806x/patches-3.18/036-ARM-qcom-add-SMEM-device-node-to-IPQ806x-dts.patch
+++ /dev/null
@@ -1,36 +0,0 @@
-From f212be3a6134db8dd7c5f6f0987536a669401fae Mon Sep 17 00:00:00 2001
-From: Mathieu Olivari <mathieu@codeaurora.org>
-Date: Fri, 14 Aug 2015 11:17:20 -0700
-Subject: [PATCH 2/3] ARM: qcom: add SMEM device node to IPQ806x dts
-
-SMEM is used on IPQ806x to store various board related information such
-as boot device and flash partition layout. We'll declare it as a device
-so we can make use of it thanks to the new SMEM soc driver.
-
-Signed-off-by: Mathieu Olivari <mathieu@codeaurora.org>
----
- arch/arm/boot/dts/qcom-ipq8064.dtsi | 8 +++++++-
- 1 file changed, 7 insertions(+), 1 deletion(-)
-
---- a/arch/arm/boot/dts/qcom-ipq8064.dtsi
-+++ b/arch/arm/boot/dts/qcom-ipq8064.dtsi
-@@ -54,7 +54,7 @@
- 			no-map;
- 		};
- 
--		smem@41000000 {
-+		smem: smem@41000000 {
- 			reg = <0x41000000 0x200000>;
- 			no-map;
- 		};
-@@ -304,4 +304,10 @@
- 
- 		#hwlock-cells = <1>;
-  	};
-+
-+	smem {
-+		compatible = "qcom,smem";
-+		memory-region = <&smem>;
-+		hwlocks = <&sfpb_mutex 3>;
-+	};
- };
diff --git a/target/linux/ipq806x/patches-3.18/037-mtd-add-SMEM-parser-for-QCOM-platforms.patch b/target/linux/ipq806x/patches-3.18/037-mtd-add-SMEM-parser-for-QCOM-platforms.patch
deleted file mode 100644
index b2c8cd5c53a3b1131a8537f18ad9d8ea14a54cda..0000000000000000000000000000000000000000
--- a/target/linux/ipq806x/patches-3.18/037-mtd-add-SMEM-parser-for-QCOM-platforms.patch
+++ /dev/null
@@ -1,277 +0,0 @@
-From 0501f76b138cf1dc11a313bb7a094da524b79337 Mon Sep 17 00:00:00 2001
-From: Mathieu Olivari <mathieu@codeaurora.org>
-Date: Thu, 13 Aug 2015 09:53:14 -0700
-Subject: [PATCH 3/3] mtd: add SMEM parser for QCOM platforms
-
-On QCOM platforms using MTD devices storage (such as IPQ806x), SMEM is
-used to store partition layout. This new parser can now be used to read
-SMEM and use it to register an MTD layout according to its content.
-
-Signed-off-by: Mathieu Olivari <mathieu@codeaurora.org>
----
- drivers/mtd/Kconfig          |   7 ++
- drivers/mtd/Makefile         |   1 +
- drivers/mtd/qcom_smem_part.c | 231 +++++++++++++++++++++++++++++++++++++++++++
- 3 files changed, 239 insertions(+)
- create mode 100644 drivers/mtd/qcom_smem_part.c
-
---- a/drivers/mtd/Kconfig
-+++ b/drivers/mtd/Kconfig
-@@ -200,6 +200,13 @@ config MTD_MYLOADER_PARTS
- 	  You will still need the parsing functions to be called by the driver
- 	  for your particular device. It won't happen automatically.
- 
-+config MTD_QCOM_SMEM_PARTS
-+	tristate "QCOM SMEM partitioning support"
-+	depends on QCOM_SMEM
-+	help
-+	  This provides partitions parser for QCOM devices using SMEM
-+	  such as IPQ806x.
-+
- comment "User Modules And Translation Layers"
- 
- #
---- /dev/null
-+++ b/drivers/mtd/qcom_smem_part.c
-@@ -0,0 +1,231 @@
-+/*
-+ * Copyright (c) 2015, 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/device.h>
-+#include <linux/slab.h>
-+
-+#include <linux/mtd/mtd.h>
-+#include <linux/mtd/partitions.h>
-+#include <linux/spi/spi.h>
-+#include <linux/module.h>
-+
-+#include <linux/soc/qcom/smem.h>
-+
-+/* Processor/host identifier for the application processor */
-+#define SMEM_HOST_APPS			0
-+
-+/* SMEM items index */
-+#define SMEM_AARM_PARTITION_TABLE	9
-+#define SMEM_BOOT_FLASH_TYPE		421
-+#define SMEM_BOOT_FLASH_BLOCK_SIZE	424
-+
-+/* SMEM Flash types */
-+#define SMEM_FLASH_NAND			2
-+#define SMEM_FLASH_SPI			6
-+
-+#define SMEM_PART_NAME_SZ		16
-+#define SMEM_PARTS_MAX			32
-+
-+struct smem_partition {
-+	char name[SMEM_PART_NAME_SZ];
-+	__le32 start;
-+	__le32 size;
-+	__le32 attr;
-+};
-+
-+struct smem_partition_table {
-+	u8 magic[8];
-+	__le32 version;
-+	__le32 len;
-+	struct smem_partition parts[SMEM_PARTS_MAX];
-+};
-+
-+/* SMEM Magic values in partition table */
-+static const u8 SMEM_PTABLE_MAGIC[] = {
-+	0xaa, 0x73, 0xee, 0x55,
-+	0xdb, 0xbd, 0x5e, 0xe3,
-+};
-+
-+static int qcom_smem_get_flash_blksz(u64 **smem_blksz)
-+{
-+	int ret;
-+	size_t size;
-+
-+	ret = qcom_smem_get(SMEM_HOST_APPS, SMEM_BOOT_FLASH_BLOCK_SIZE,
-+			    (void **) smem_blksz, &size);
-+
-+	if (ret < 0) {
-+		pr_err("Unable to read flash blksz from SMEM\n");
-+		return -ENOENT;
-+	}
-+
-+	if (size != sizeof(**smem_blksz)) {
-+		pr_err("Invalid flash blksz size in SMEM\n");
-+		return -EINVAL;
-+	}
-+
-+	return 0;
-+}
-+
-+static int qcom_smem_get_flash_type(u64 **smem_flash_type)
-+{
-+	int ret;
-+	size_t size;
-+
-+	ret = qcom_smem_get(SMEM_HOST_APPS, SMEM_BOOT_FLASH_TYPE,
-+			    (void **) smem_flash_type, &size);
-+
-+	if (ret < 0) {
-+		pr_err("Unable to read flash type from SMEM\n");
-+		return -ENOENT;
-+	}
-+
-+	if (size != sizeof(**smem_flash_type)) {
-+		pr_err("Invalid flash type size in SMEM\n");
-+		return -EINVAL;
-+	}
-+
-+	return 0;
-+}
-+
-+static int qcom_smem_get_flash_partitions(struct smem_partition_table **pparts)
-+{
-+	int ret;
-+	size_t size;
-+
-+	ret = qcom_smem_get(SMEM_HOST_APPS, SMEM_AARM_PARTITION_TABLE,
-+			    (void **) pparts, &size);
-+
-+	if (ret < 0) {
-+		pr_err("Unable to read partition table from SMEM\n");
-+		return -ENOENT;
-+	}
-+
-+	return 0;
-+}
-+
-+static int of_dev_node_match(struct device *dev, void *data)
-+{
-+	return dev->of_node == data;
-+}
-+
-+static bool is_spi_device(struct device_node *np)
-+{
-+	struct device *dev;
-+
-+	dev = bus_find_device(&spi_bus_type, NULL, np, of_dev_node_match);
-+	if (!dev)
-+		return false;
-+
-+	put_device(dev);
-+	return true;
-+}
-+
-+static int parse_qcom_smem_partitions(struct mtd_info *master,
-+				      struct mtd_partition **pparts,
-+				      struct mtd_part_parser_data *data)
-+{
-+	struct smem_partition_table *smem_parts;
-+	u64 *smem_flash_type, *smem_blksz;
-+	struct mtd_partition *mtd_parts;
-+	struct device_node *of_node = data->of_node;
-+	int i, ret;
-+
-+	/*
-+	 * SMEM will only store the partition table of the boot device.
-+	 * If this is not the boot device, do not return any partition.
-+	 */
-+	ret = qcom_smem_get_flash_type(&smem_flash_type);
-+	if (ret < 0)
-+		return ret;
-+
-+	if ((*smem_flash_type == SMEM_FLASH_NAND && !mtd_type_is_nand(master))
-+	    || (*smem_flash_type == SMEM_FLASH_SPI && !is_spi_device(of_node)))
-+		return 0;
-+
-+	/*
-+	 * Just for sanity purpose, make sure the block size in SMEM matches the
-+	 * block size of the MTD device
-+	 */
-+	ret = qcom_smem_get_flash_blksz(&smem_blksz);
-+	if (ret < 0)
-+		return ret;
-+
-+	if (*smem_blksz != master->erasesize) {
-+		pr_err("SMEM block size differs from MTD block size\n");
-+		return -EINVAL;
-+	}
-+
-+	/* Get partition pointer from SMEM */
-+	ret = qcom_smem_get_flash_partitions(&smem_parts);
-+	if (ret < 0)
-+		return ret;
-+
-+	if (memcmp(SMEM_PTABLE_MAGIC, smem_parts->magic,
-+		   sizeof(SMEM_PTABLE_MAGIC))) {
-+		pr_err("SMEM partition magic invalid\n");
-+		return -EINVAL;
-+	}
-+
-+	/* Allocate and populate the mtd structures */
-+	mtd_parts = kcalloc(le32_to_cpu(smem_parts->len), sizeof(*mtd_parts),
-+			    GFP_KERNEL);
-+	if (!mtd_parts)
-+		return -ENOMEM;
-+
-+	for (i = 0; i < smem_parts->len; i++) {
-+		struct smem_partition *s_part = &smem_parts->parts[i];
-+		struct mtd_partition *m_part = &mtd_parts[i];
-+
-+		m_part->name = s_part->name;
-+		m_part->size = le32_to_cpu(s_part->size) * (*smem_blksz);
-+		m_part->offset = le32_to_cpu(s_part->start) * (*smem_blksz);
-+
-+		/*
-+		 * The last SMEM partition may have its size marked as
-+		 * something like 0xffffffff, which means "until the end of the
-+		 * flash device". In this case, truncate it.
-+		 */
-+		if (m_part->offset + m_part->size > master->size)
-+			m_part->size = master->size - m_part->offset;
-+	}
-+
-+	*pparts = mtd_parts;
-+
-+	return smem_parts->len;
-+}
-+
-+static struct mtd_part_parser qcom_smem_parser = {
-+	.owner = THIS_MODULE,
-+	.parse_fn = parse_qcom_smem_partitions,
-+	.name = "qcom-smem",
-+};
-+
-+static int __init qcom_smem_parser_init(void)
-+{
-+	register_mtd_parser(&qcom_smem_parser);
-+	return 0;
-+}
-+
-+static void __exit qcom_smem_parser_exit(void)
-+{
-+	deregister_mtd_parser(&qcom_smem_parser);
-+}
-+
-+module_init(qcom_smem_parser_init);
-+module_exit(qcom_smem_parser_exit);
-+
-+MODULE_LICENSE("GPL");
-+MODULE_AUTHOR("Mathieu Olivari <mathieu@codeaurora.org>");
-+MODULE_DESCRIPTION("Parsing code for SMEM based partition tables");
---- a/drivers/mtd/Makefile
-+++ b/drivers/mtd/Makefile
-@@ -16,6 +16,7 @@ obj-$(CONFIG_MTD_AR7_PARTS)	+= ar7part.o
- obj-$(CONFIG_MTD_BCM63XX_PARTS)	+= bcm63xxpart.o
- obj-$(CONFIG_MTD_BCM47XX_PARTS)	+= bcm47xxpart.o
- obj-$(CONFIG_MTD_MYLOADER_PARTS) += myloader.o
-+obj-$(CONFIG_MTD_QCOM_SMEM_PARTS) += qcom_smem_part.o
- 
- # 'Users' - code which presents functionality to userspace.
- obj-$(CONFIG_MTD_BLKDEVS)	+= mtd_blkdevs.o
diff --git a/target/linux/ipq806x/patches-3.18/100-usb-phy-Add-Qualcomm-DWC3-HS-SS-PHY-drivers.patch b/target/linux/ipq806x/patches-3.18/100-usb-phy-Add-Qualcomm-DWC3-HS-SS-PHY-drivers.patch
deleted file mode 100644
index 25803b88ebee30f64af9b8c3f0f9d8676d48d9d8..0000000000000000000000000000000000000000
--- a/target/linux/ipq806x/patches-3.18/100-usb-phy-Add-Qualcomm-DWC3-HS-SS-PHY-drivers.patch
+++ /dev/null
@@ -1,511 +0,0 @@
---- a/drivers/phy/Kconfig
-+++ b/drivers/phy/Kconfig
-@@ -256,4 +256,15 @@ config PHY_STIH41X_USB
- 	  Enable this to support the USB transceiver that is part of
- 	  STMicroelectronics STiH41x SoC series.
- 
-+config PHY_QCOM_DWC3
-+	tristate "QCOM DWC3 USB PHY support"
-+	depends on ARCH_QCOM
-+	depends on HAS_IOMEM
-+	depends on OF
-+	select GENERIC_PHY
-+	help
-+	  This option enables support for the Synopsis PHYs present inside the
-+	  Qualcomm USB3.0 DWC3 controller.  This driver supports both HS and SS
-+	  PHY controllers.
-+
- endmenu
---- a/drivers/phy/Makefile
-+++ b/drivers/phy/Makefile
-@@ -31,3 +31,4 @@ obj-$(CONFIG_PHY_ST_SPEAR1340_MIPHY)	+=
- obj-$(CONFIG_PHY_XGENE)			+= phy-xgene.o
- obj-$(CONFIG_PHY_STIH407_USB)		+= phy-stih407-usb.o
- obj-$(CONFIG_PHY_STIH41X_USB)		+= phy-stih41x-usb.o
-+obj-$(CONFIG_PHY_QCOM_DWC3)		+= phy-qcom-dwc3.o
---- /dev/null
-+++ b/drivers/phy/phy-qcom-dwc3.c
-@@ -0,0 +1,483 @@
-+/* 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/phy/phy.h>
-+#include <linux/platform_device.h>
-+#include <linux/delay.h>
-+
-+/**
-+ *  USB QSCRATCH Hardware registers
-+ */
-+#define QSCRATCH_GENERAL_CFG		(0x08)
-+#define HSUSB_PHY_CTRL_REG		(0x10)
-+
-+/* PHY_CTRL_REG */
-+#define HSUSB_CTRL_DMSEHV_CLAMP			BIT(24)
-+#define HSUSB_CTRL_USB2_SUSPEND			BIT(23)
-+#define HSUSB_CTRL_UTMI_CLK_EN			BIT(21)
-+#define	HSUSB_CTRL_UTMI_OTG_VBUS_VALID		BIT(20)
-+#define HSUSB_CTRL_USE_CLKCORE			BIT(18)
-+#define HSUSB_CTRL_DPSEHV_CLAMP			BIT(17)
-+#define HSUSB_CTRL_COMMONONN			BIT(11)
-+#define HSUSB_CTRL_ID_HV_CLAMP			BIT(9)
-+#define HSUSB_CTRL_OTGSESSVLD_CLAMP		BIT(8)
-+#define HSUSB_CTRL_CLAMP_EN			BIT(7)
-+#define HSUSB_CTRL_RETENABLEN			BIT(1)
-+#define HSUSB_CTRL_POR				BIT(0)
-+
-+/* QSCRATCH_GENERAL_CFG */
-+#define HSUSB_GCFG_XHCI_REV		BIT(2)
-+
-+/**
-+ *  USB QSCRATCH Hardware registers
-+ */
-+#define SSUSB_PHY_CTRL_REG		(0x00)
-+#define SSUSB_PHY_PARAM_CTRL_1		(0x04)
-+#define SSUSB_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)
-+
-+/* PHY_CTRL_REG */
-+#define SSUSB_CTRL_REF_USE_PAD		BIT(28)
-+#define SSUSB_CTRL_TEST_POWERDOWN	BIT(27)
-+#define SSUSB_CTRL_LANE0_PWR_PRESENT	BIT(24)
-+#define SSUSB_CTRL_SS_PHY_EN		BIT(8)
-+#define SSUSB_CTRL_SS_PHY_RESET		BIT(7)
-+
-+/* SSPHY control registers */
-+#define SSPHY_CTRL_RX_OVRD_IN_HI(lane)	(0x1006 + 0x100 * lane)
-+#define SSPHY_CTRL_TX_OVRD_DRV_LO(lane)	(0x1002 + 0x100 * lane)
-+
-+/* RX OVRD IN HI bits */
-+#define RX_OVRD_IN_HI_RX_RESET_OVRD		BIT(13)
-+#define RX_OVRD_IN_HI_RX_RX_RESET		BIT(12)
-+#define RX_OVRD_IN_HI_RX_EQ_OVRD		BIT(11)
-+#define RX_OVRD_IN_HI_RX_EQ_MASK		0x0700
-+#define RX_OVRD_IN_HI_RX_EQ_SHIFT		8
-+#define RX_OVRD_IN_HI_RX_EQ_EN_OVRD		BIT(7)
-+#define RX_OVRD_IN_HI_RX_EQ_EN			BIT(6)
-+#define RX_OVRD_IN_HI_RX_LOS_FILTER_OVRD	BIT(5)
-+#define RX_OVRD_IN_HI_RX_LOS_FILTER_MASK	0x0018
-+#define RX_OVRD_IN_HI_RX_RATE_OVRD		BIT(2)
-+#define RX_OVRD_IN_HI_RX_RATE_MASK		0x0003
-+
-+/* TX OVRD DRV LO register bits */
-+#define TX_OVRD_DRV_LO_AMPLITUDE_MASK	0x007F
-+#define TX_OVRD_DRV_LO_PREEMPH_MASK	0x3F80
-+#define TX_OVRD_DRV_LO_PREEMPH_SHIFT	7
-+#define TX_OVRD_DRV_LO_EN		BIT(14)
-+
-+struct qcom_dwc3_usb_phy {
-+	void __iomem		*base;
-+	struct device		*dev;
-+	struct phy *phy;
-+
-+	int (*phy_init)(struct qcom_dwc3_usb_phy *phy_dwc3);
-+	int (*phy_exit)(struct qcom_dwc3_usb_phy *phy_dwc3);
-+
-+	struct clk		*xo_clk;
-+	struct clk		*ref_clk;
-+};
-+
-+/**
-+ * 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_phy_write_readback(
-+	struct qcom_dwc3_usb_phy *phy_dwc3, u32 offset,
-+	const u32 mask, u32 val)
-+{
-+	u32 write_val, tmp = readl(phy_dwc3->base + offset);
-+
-+	tmp &= ~mask;		/* retain other bits */
-+	write_val = tmp | val;
-+
-+	writel(write_val, phy_dwc3->base + offset);
-+
-+	/* Read back to see if val was written */
-+	tmp = readl(phy_dwc3->base + offset);
-+	tmp &= mask;		/* clear other bits */
-+
-+	if (tmp != val)
-+		dev_err(phy_dwc3->dev, "write: %x to QSCRATCH: %x FAILED\n",
-+			val, offset);
-+}
-+
-+static int wait_for_latch(void __iomem *addr)
-+{
-+	u32 retry = 10;
-+
-+	while (true) {
-+		if (!readl(addr))
-+			break;
-+
-+		if (--retry == 0)
-+			return -ETIMEDOUT;
-+
-+		usleep_range(10, 20);
-+	}
-+
-+	return 0;
-+}
-+
-+/**
-+ * Write SSPHY register
-+ *
-+ * @base - QCOM DWC3 PHY base virtual address.
-+ * @addr - SSPHY address to write.
-+ * @val - value to write.
-+ */
-+static int qcom_dwc3_ss_write_phycreg(void __iomem *base, u32 addr, u32 val)
-+{
-+	int ret;
-+
-+	writel(addr, base + CR_PROTOCOL_DATA_IN_REG);
-+	writel(0x1, base + CR_PROTOCOL_CAP_ADDR_REG);
-+
-+	ret = wait_for_latch(base + CR_PROTOCOL_CAP_ADDR_REG);
-+	if (ret)
-+		goto err_wait;
-+
-+	writel(val, base + CR_PROTOCOL_DATA_IN_REG);
-+	writel(0x1, base + CR_PROTOCOL_CAP_DATA_REG);
-+
-+	ret = wait_for_latch(base + CR_PROTOCOL_CAP_DATA_REG);
-+	if (ret)
-+		goto err_wait;
-+
-+	writel(0x1, base + CR_PROTOCOL_WRITE_REG);
-+
-+	ret = wait_for_latch(base + CR_PROTOCOL_WRITE_REG);
-+
-+err_wait:
-+	return ret;
-+}
-+
-+/**
-+ * Read SSPHY register.
-+ *
-+ * @base - QCOM DWC3 PHY base virtual address.
-+ * @addr - SSPHY address to read.
-+ */
-+static int qcom_dwc3_ss_read_phycreg(void __iomem *base, u32 addr, u32 *val)
-+{
-+	int ret;
-+	bool first_read = true;
-+
-+	writel(addr, base + CR_PROTOCOL_DATA_IN_REG);
-+	writel(0x1, base + CR_PROTOCOL_CAP_ADDR_REG);
-+
-+	ret = wait_for_latch(base + CR_PROTOCOL_CAP_ADDR_REG);
-+	if (ret)
-+		goto err_wait;
-+
-+	/*
-+	 * 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);
-+
-+	ret = wait_for_latch(base + CR_PROTOCOL_READ_REG);
-+	if (ret)
-+		goto err_wait;
-+
-+	if (first_read) {
-+		readl(base + CR_PROTOCOL_DATA_OUT_REG);
-+		first_read = false;
-+		goto retry;
-+	}
-+
-+	*val = readl(base + CR_PROTOCOL_DATA_OUT_REG);
-+
-+err_wait:
-+	return ret;
-+}
-+
-+static int qcom_dwc3_phy_power_on(struct phy *phy)
-+{
-+	int ret;
-+	struct qcom_dwc3_usb_phy *phy_dwc3 = phy_get_drvdata(phy);
-+
-+	ret = clk_prepare_enable(phy_dwc3->xo_clk);
-+	if (ret)
-+		return ret;
-+
-+	ret = clk_prepare_enable(phy_dwc3->ref_clk);
-+	if (ret)
-+		clk_disable_unprepare(phy_dwc3->xo_clk);
-+
-+	return ret;
-+}
-+
-+static int qcom_dwc3_phy_power_off(struct phy *phy)
-+{
-+	struct qcom_dwc3_usb_phy *phy_dwc3 = phy_get_drvdata(phy);
-+
-+	clk_disable_unprepare(phy_dwc3->ref_clk);
-+	clk_disable_unprepare(phy_dwc3->xo_clk);
-+
-+	return 0;
-+}
-+
-+static int qcom_dwc3_hs_phy_init(struct qcom_dwc3_usb_phy *phy_dwc3)
-+{
-+	u32 val;
-+
-+	/*
-+	 * HSPHY Initialization: Enable UTMI clock, select 19.2MHz fsel
-+	 * enable clamping, and disable RETENTION (power-on default is ENABLED)
-+	 */
-+	val = HSUSB_CTRL_DPSEHV_CLAMP | HSUSB_CTRL_DMSEHV_CLAMP |
-+		HSUSB_CTRL_RETENABLEN  | HSUSB_CTRL_COMMONONN |
-+		HSUSB_CTRL_OTGSESSVLD_CLAMP | HSUSB_CTRL_ID_HV_CLAMP |
-+		HSUSB_CTRL_DPSEHV_CLAMP | HSUSB_CTRL_UTMI_OTG_VBUS_VALID |
-+		HSUSB_CTRL_UTMI_CLK_EN | HSUSB_CTRL_CLAMP_EN | 0x70;
-+
-+	/* use core clock if external reference is not present */
-+	if (!phy_dwc3->xo_clk)
-+		val |= HSUSB_CTRL_USE_CLKCORE;
-+
-+	writel(val, phy_dwc3->base + HSUSB_PHY_CTRL_REG);
-+	usleep_range(2000, 2200);
-+
-+	/* Disable (bypass) VBUS and ID filters */
-+	writel(HSUSB_GCFG_XHCI_REV, phy_dwc3->base + QSCRATCH_GENERAL_CFG);
-+
-+	return 0;
-+}
-+
-+static int qcom_dwc3_ss_phy_init(struct qcom_dwc3_usb_phy *phy_dwc3)
-+{
-+	int ret;
-+	u32 data = 0;
-+
-+	/* reset phy */
-+	data = readl_relaxed(phy_dwc3->base + SSUSB_PHY_CTRL_REG);
-+	writel_relaxed(data | SSUSB_CTRL_SS_PHY_RESET,
-+		phy_dwc3->base + SSUSB_PHY_CTRL_REG);
-+	usleep_range(2000, 2200);
-+	writel_relaxed(data, phy_dwc3->base + SSUSB_PHY_CTRL_REG);
-+
-+	/* clear REF_PAD if we don't have XO clk */
-+	if (!phy_dwc3->xo_clk)
-+		data &= ~SSUSB_CTRL_REF_USE_PAD;
-+	else
-+		data |= SSUSB_CTRL_REF_USE_PAD;
-+
-+	writel_relaxed(data, phy_dwc3->base + SSUSB_PHY_CTRL_REG);
-+	msleep(30);
-+
-+	data |= SSUSB_CTRL_SS_PHY_EN | SSUSB_CTRL_LANE0_PWR_PRESENT;
-+	writel_relaxed(data, phy_dwc3->base + SSUSB_PHY_CTRL_REG);
-+
-+	/*
-+	 * 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
-+	 */
-+	ret = qcom_dwc3_ss_read_phycreg(phy_dwc3->base,
-+			SSPHY_CTRL_RX_OVRD_IN_HI(0), &data);
-+	if (ret)
-+		goto err_phy_trans;
-+
-+	data &= ~RX_OVRD_IN_HI_RX_EQ_EN;
-+	data |= RX_OVRD_IN_HI_RX_EQ_EN_OVRD;
-+	data &= ~RX_OVRD_IN_HI_RX_EQ_MASK;
-+	data |= 0x3 << RX_OVRD_IN_HI_RX_EQ_SHIFT;
-+	data |= RX_OVRD_IN_HI_RX_EQ_OVRD;
-+	ret = qcom_dwc3_ss_write_phycreg(phy_dwc3->base,
-+		SSPHY_CTRL_RX_OVRD_IN_HI(0), data);
-+	if (ret)
-+		goto err_phy_trans;
-+
-+	/*
-+	 * 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.
-+	 */
-+	ret = qcom_dwc3_ss_read_phycreg(phy_dwc3->base,
-+		SSPHY_CTRL_TX_OVRD_DRV_LO(0), &data);
-+	if (ret)
-+		goto err_phy_trans;
-+
-+	data &= ~TX_OVRD_DRV_LO_PREEMPH_MASK;
-+	data |= 0x16 << TX_OVRD_DRV_LO_PREEMPH_SHIFT;
-+	data &= ~TX_OVRD_DRV_LO_AMPLITUDE_MASK;
-+	data |= 0x7f;
-+	data |= TX_OVRD_DRV_LO_EN;
-+	ret = qcom_dwc3_ss_write_phycreg(phy_dwc3->base,
-+		SSPHY_CTRL_TX_OVRD_DRV_LO(0), data);
-+	if (ret)
-+		goto err_phy_trans;
-+
-+	/*
-+	 * 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_phy_write_readback(phy_dwc3, SSUSB_PHY_PARAM_CTRL_1,
-+				   0x07f03f07, 0x07f01605);
-+
-+err_phy_trans:
-+	return ret;
-+}
-+
-+static int qcom_dwc3_ss_phy_exit(struct qcom_dwc3_usb_phy *phy_dwc3)
-+{
-+	/* 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_phy_write_readback(phy_dwc3, SSUSB_PHY_CTRL_REG,
-+		SSUSB_CTRL_SS_PHY_EN, 0x0);
-+	qcom_dwc3_phy_write_readback(phy_dwc3, SSUSB_PHY_CTRL_REG,
-+		SSUSB_CTRL_REF_USE_PAD, 0x0);
-+	qcom_dwc3_phy_write_readback(phy_dwc3, SSUSB_PHY_CTRL_REG,
-+		0x0, SSUSB_CTRL_TEST_POWERDOWN);
-+
-+	return 0;
-+}
-+
-+static int qcom_dwc3_phy_init(struct phy *phy)
-+{
-+	struct qcom_dwc3_usb_phy *phy_dwc3 = phy_get_drvdata(phy);
-+
-+	if (phy_dwc3->phy_init)
-+		return phy_dwc3->phy_init(phy_dwc3);
-+
-+	return 0;
-+}
-+
-+static int qcom_dwc3_phy_exit(struct phy *phy)
-+{
-+	struct qcom_dwc3_usb_phy *phy_dwc3 = phy_get_drvdata(phy);
-+
-+	if (phy_dwc3->phy_exit)
-+		return qcom_dwc3_ss_phy_exit(phy_dwc3);
-+
-+	return 0;
-+}
-+
-+static struct phy_ops qcom_dwc3_phy_ops = {
-+	.init		= qcom_dwc3_phy_init,
-+	.exit		= qcom_dwc3_phy_exit,
-+	.power_on	= qcom_dwc3_phy_power_on,
-+	.power_off	= qcom_dwc3_phy_power_off,
-+	.owner		= THIS_MODULE,
-+};
-+
-+static const struct of_device_id qcom_dwc3_phy_table[] = {
-+	{ .compatible = "qcom,dwc3-hs-usb-phy", },
-+	{ .compatible = "qcom,dwc3-ss-usb-phy", },
-+	{ /* Sentinel */ }
-+};
-+MODULE_DEVICE_TABLE(of, qcom_dwc3_phy_table);
-+
-+static int qcom_dwc3_phy_probe(struct platform_device *pdev)
-+{
-+	struct qcom_dwc3_usb_phy	*phy_dwc3;
-+	struct phy_provider		*phy_provider;
-+	struct resource			*res;
-+
-+	phy_dwc3 = devm_kzalloc(&pdev->dev, sizeof(*phy_dwc3), GFP_KERNEL);
-+	if (!phy_dwc3)
-+		return -ENOMEM;
-+
-+	platform_set_drvdata(pdev, phy_dwc3);
-+
-+	phy_dwc3->dev = &pdev->dev;
-+
-+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-+	phy_dwc3->base = devm_ioremap_resource(phy_dwc3->dev, res);
-+	if (IS_ERR(phy_dwc3->base))
-+		return PTR_ERR(phy_dwc3->base);
-+
-+	phy_dwc3->ref_clk = devm_clk_get(phy_dwc3->dev, "ref");
-+	if (IS_ERR(phy_dwc3->ref_clk)) {
-+		dev_dbg(phy_dwc3->dev, "cannot get reference clock\n");
-+		return PTR_ERR(phy_dwc3->ref_clk);
-+	}
-+
-+	if (of_device_is_compatible(pdev->dev.of_node,
-+			"qcom,dwc3-hs-usb-phy")) {
-+		clk_set_rate(phy_dwc3->ref_clk, 60000000);
-+		phy_dwc3->phy_init = qcom_dwc3_hs_phy_init;
-+	} else if (of_device_is_compatible(pdev->dev.of_node,
-+			"qcom,dwc3-ss-usb-phy")) {
-+		phy_dwc3->phy_init = qcom_dwc3_ss_phy_init;
-+		phy_dwc3->phy_exit = qcom_dwc3_ss_phy_exit;
-+		clk_set_rate(phy_dwc3->ref_clk, 125000000);
-+	} else {
-+		dev_err(phy_dwc3->dev, "Unknown phy\n");
-+		return -EINVAL;
-+	}
-+
-+	phy_dwc3->xo_clk = devm_clk_get(phy_dwc3->dev, "xo");
-+	if (IS_ERR(phy_dwc3->xo_clk)) {
-+		dev_dbg(phy_dwc3->dev, "cannot get TCXO clock\n");
-+		phy_dwc3->xo_clk = NULL;
-+	}
-+
-+	phy_dwc3->phy = devm_phy_create(phy_dwc3->dev, NULL, &qcom_dwc3_phy_ops,
-+					NULL);
-+
-+	if (IS_ERR(phy_dwc3->phy))
-+		return PTR_ERR(phy_dwc3->phy);
-+
-+	phy_set_drvdata(phy_dwc3->phy, phy_dwc3);
-+
-+	phy_provider = devm_of_phy_provider_register(phy_dwc3->dev,
-+			of_phy_simple_xlate);
-+
-+	if (IS_ERR(phy_provider))
-+		return PTR_ERR(phy_provider);
-+
-+	return 0;
-+}
-+
-+static struct platform_driver qcom_dwc3_phy_driver = {
-+	.probe		= qcom_dwc3_phy_probe,
-+	.driver		= {
-+		.name	= "qcom-dwc3-usb-phy",
-+		.owner	= THIS_MODULE,
-+		.of_match_table = qcom_dwc3_phy_table,
-+	},
-+};
-+
-+module_platform_driver(qcom_dwc3_phy_driver);
-+
-+MODULE_ALIAS("platform:phy-qcom-dwc3");
-+MODULE_LICENSE("GPL v2");
-+MODULE_AUTHOR("Andy Gross <agross@codeaurora.org>");
-+MODULE_AUTHOR("Ivan T. Ivanov <iivanov@mm-sol.com>");
-+MODULE_DESCRIPTION("DesignWare USB3 QCOM PHY driver");
diff --git a/target/linux/ipq806x/patches-3.18/101-ARM-qcom-add-USB-nodes-to-ipq806x-ap148.patch b/target/linux/ipq806x/patches-3.18/101-ARM-qcom-add-USB-nodes-to-ipq806x-ap148.patch
deleted file mode 100644
index e2d03d4ffd26e88db033921116687785c3312c66..0000000000000000000000000000000000000000
--- a/target/linux/ipq806x/patches-3.18/101-ARM-qcom-add-USB-nodes-to-ipq806x-ap148.patch
+++ /dev/null
@@ -1,126 +0,0 @@
---- a/arch/arm/boot/dts/qcom-ipq8064-ap148.dts
-+++ b/arch/arm/boot/dts/qcom-ipq8064-ap148.dts
-@@ -91,5 +91,29 @@
- 		sata@29000000 {
- 			status = "ok";
- 		};
-+
-+		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
-@@ -296,6 +296,91 @@
- 			compatible = "syscon";
- 			reg = <0x01200600 0x100>;
- 		};
-+
-+		hs_phy_1: phy@100f8800 {
-+			compatible = "qcom,dwc3-hs-usb-phy";
-+			reg = <0x100f8800 0x30>;
-+			clocks = <&gcc USB30_1_UTMI_CLK>;
-+			clock-names = "ref";
-+			#phy-cells = <0>;
-+
-+			status = "disabled";
-+		};
-+
-+		ss_phy_1: phy@100f8830 {
-+			compatible = "qcom,dwc3-ss-usb-phy";
-+			reg = <0x100f8830 0x30>;
-+			clocks = <&gcc USB30_1_MASTER_CLK>;
-+			clock-names = "ref";
-+			#phy-cells = <0>;
-+
-+			status = "disabled";
-+		};
-+
-+		hs_phy_0: phy@110f8800 {
-+			compatible = "qcom,dwc3-hs-usb-phy";
-+			reg = <0x110f8800 0x30>;
-+			clocks = <&gcc USB30_0_UTMI_CLK>;
-+			clock-names = "ref";
-+			#phy-cells = <0>;
-+
-+			status = "disabled";
-+		};
-+
-+		ss_phy_0: phy@110f8830 {
-+			compatible = "qcom,dwc3-ss-usb-phy";
-+			reg = <0x110f8830 0x30>;
-+			clocks = <&gcc USB30_0_MASTER_CLK>;
-+			clock-names = "ref";
-+			#phy-cells = <0>;
-+
-+			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>;
-+				phys = <&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>;
-+				phys = <&hs_phy_1>, <&ss_phy_1>;
-+				phy-names = "usb2-phy", "usb3-phy";
-+				tx-fifo-resize;
-+				dr_mode = "host";
-+			};
-+		};
-+
- 	};
- 
- 	sfpb_mutex: sfpb-mutex {
diff --git a/target/linux/ipq806x/patches-3.18/102-soc-qcom-gsbi-Add-support-for-ADM-CRCI-muxing.patch b/target/linux/ipq806x/patches-3.18/102-soc-qcom-gsbi-Add-support-for-ADM-CRCI-muxing.patch
deleted file mode 100644
index 752f3f74d5a4880d667e7bc0152a7995104905cd..0000000000000000000000000000000000000000
--- a/target/linux/ipq806x/patches-3.18/102-soc-qcom-gsbi-Add-support-for-ADM-CRCI-muxing.patch
+++ /dev/null
@@ -1,249 +0,0 @@
---- a/Documentation/devicetree/bindings/soc/qcom/qcom,gsbi.txt
-+++ b/Documentation/devicetree/bindings/soc/qcom/qcom,gsbi.txt
-@@ -6,7 +6,8 @@ configuration settings.  The mode settin
- the 4 GSBI IOs.
- 
- Required properties:
--- compatible: must contain "qcom,gsbi-v1.0.0" for APQ8064/IPQ8064
-+- compatible:	Should contain "qcom,gsbi-v1.0.0"
-+- cell-index:	Should contain the GSBI index
- - reg: Address range for GSBI registers
- - clocks: required clock
- - clock-names: must contain "iface" entry
-@@ -16,6 +17,8 @@ Required properties:
- 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.
-+- syscon-tcsr: indicates phandle of TCSR syscon node.  Required if child uses
-+  dma.
- 
- Required properties if child node exists:
- - #address-cells: Must be 1
-@@ -39,6 +42,7 @@ Example for APQ8064:
- 
- 	gsbi4@16300000 {
- 		compatible = "qcom,gsbi-v1.0.0";
-+		cell-index = <4>;
- 		reg = <0x16300000 0x100>;
- 		clocks = <&gcc GSBI4_H_CLK>;
- 		clock-names = "iface";
-@@ -48,6 +52,8 @@ Example for APQ8064:
- 		qcom,mode = <GSBI_PROT_I2C_UART>;
- 		qcom,crci = <GSBI_CRCI_QUP>;
- 
-+		syscon-tcsr = <&tcsr>;
-+
- 		/* child nodes go under here */
- 
- 		i2c_qup4: i2c@16380000 {
-@@ -76,3 +82,9 @@ Example for APQ8064:
- 		};
- 	};
- 
-+	tcsr: syscon@1a400000 {
-+		compatible = "qcom,apq8064-tcsr", "syscon";
-+		reg = <0x1a400000 0x100>;
-+	};
-+
-+
---- a/drivers/soc/qcom/Kconfig
-+++ b/drivers/soc/qcom/Kconfig
-@@ -4,6 +4,7 @@
- config QCOM_GSBI
-         tristate "QCOM General Serial Bus Interface"
-         depends on ARCH_QCOM
-+        select MFD_SYSCON
-         help
-           Say y here to enable GSBI support.  The GSBI provides control
-           functions for connecting the underlying serial UART, SPI, and I2C
---- a/drivers/soc/qcom/qcom_gsbi.c
-+++ b/drivers/soc/qcom/qcom_gsbi.c
-@@ -18,22 +18,129 @@
- #include <linux/of.h>
- #include <linux/of_platform.h>
- #include <linux/platform_device.h>
-+#include <linux/regmap.h>
-+#include <linux/mfd/syscon.h>
-+#include <dt-bindings/soc/qcom,gsbi.h>
- 
- #define GSBI_CTRL_REG		0x0000
- #define GSBI_PROTOCOL_SHIFT	4
-+#define MAX_GSBI		12
-+
-+#define TCSR_ADM_CRCI_BASE	0x70
-+
-+struct crci_config {
-+	u32 num_rows;
-+	const u32 (*array)[MAX_GSBI];
-+};
-+
-+static const u32 crci_ipq8064[][MAX_GSBI] = {
-+	{
-+		0x000003, 0x00000c, 0x000030, 0x0000c0,
-+		0x000300, 0x000c00, 0x003000, 0x00c000,
-+		0x030000, 0x0c0000, 0x300000, 0xc00000
-+	},
-+	{
-+		0x000003, 0x00000c, 0x000030, 0x0000c0,
-+		0x000300, 0x000c00, 0x003000, 0x00c000,
-+		0x030000, 0x0c0000, 0x300000, 0xc00000
-+	},
-+};
-+
-+static const struct crci_config config_ipq8064 = {
-+	.num_rows = ARRAY_SIZE(crci_ipq8064),
-+	.array = crci_ipq8064,
-+};
-+
-+static const unsigned int crci_apq8064[][MAX_GSBI] = {
-+	{
-+		0x001800, 0x006000, 0x000030, 0x0000c0,
-+		0x000300, 0x000400, 0x000000, 0x000000,
-+		0x000000, 0x000000, 0x000000, 0x000000
-+	},
-+	{
-+		0x000000, 0x000000, 0x000000, 0x000000,
-+		0x000000, 0x000020, 0x0000c0, 0x000000,
-+		0x000000, 0x000000, 0x000000, 0x000000
-+	},
-+};
-+
-+static const struct crci_config config_apq8064 = {
-+	.num_rows = ARRAY_SIZE(crci_apq8064),
-+	.array = crci_apq8064,
-+};
-+
-+static const unsigned int crci_msm8960[][MAX_GSBI] = {
-+	{
-+		0x000003, 0x00000c, 0x000030, 0x0000c0,
-+		0x000300, 0x000400, 0x000000, 0x000000,
-+		0x000000, 0x000000, 0x000000, 0x000000
-+	},
-+	{
-+		0x000000, 0x000000, 0x000000, 0x000000,
-+		0x000000, 0x000020, 0x0000c0, 0x000300,
-+		0x001800, 0x006000, 0x000000, 0x000000
-+	},
-+};
-+
-+static const struct crci_config config_msm8960 = {
-+	.num_rows = ARRAY_SIZE(crci_msm8960),
-+	.array = crci_msm8960,
-+};
-+
-+static const unsigned int crci_msm8660[][MAX_GSBI] = {
-+	{	/* ADM 0 - B */
-+		0x000003, 0x00000c, 0x000030, 0x0000c0,
-+		0x000300, 0x000c00, 0x003000, 0x00c000,
-+		0x030000, 0x0c0000, 0x300000, 0xc00000
-+	},
-+	{	/* ADM 0 - B */
-+		0x000003, 0x00000c, 0x000030, 0x0000c0,
-+		0x000300, 0x000c00, 0x003000, 0x00c000,
-+		0x030000, 0x0c0000, 0x300000, 0xc00000
-+	},
-+	{	/* ADM 1 - A */
-+		0x000003, 0x00000c, 0x000030, 0x0000c0,
-+		0x000300, 0x000c00, 0x003000, 0x00c000,
-+		0x030000, 0x0c0000, 0x300000, 0xc00000
-+	},
-+	{	/* ADM 1 - B */
-+		0x000003, 0x00000c, 0x000030, 0x0000c0,
-+		0x000300, 0x000c00, 0x003000, 0x00c000,
-+		0x030000, 0x0c0000, 0x300000, 0xc00000
-+	},
-+};
-+
-+static const struct crci_config config_msm8660 = {
-+	.num_rows = ARRAY_SIZE(crci_msm8660),
-+	.array = crci_msm8660,
-+};
- 
- struct gsbi_info {
- 	struct clk *hclk;
- 	u32 mode;
- 	u32 crci;
-+	struct regmap *tcsr;
-+};
-+
-+static const struct of_device_id tcsr_dt_match[] = {
-+	{ .compatible = "qcom,tcsr-ipq8064", .data = &config_ipq8064},
-+	{ .compatible = "qcom,tcsr-apq8064", .data = &config_apq8064},
-+	{ .compatible = "qcom,tcsr-msm8960", .data = &config_msm8960},
-+	{ .compatible = "qcom,tcsr-msm8660", .data = &config_msm8660},
-+	{ },
- };
- 
- static int gsbi_probe(struct platform_device *pdev)
- {
- 	struct device_node *node = pdev->dev.of_node;
-+	struct device_node *tcsr_node;
-+	const struct of_device_id *match;
- 	struct resource *res;
- 	void __iomem *base;
- 	struct gsbi_info *gsbi;
-+	int i;
-+	u32 mask, gsbi_num;
-+	const struct crci_config *config = NULL;
- 
- 	gsbi = devm_kzalloc(&pdev->dev, sizeof(*gsbi), GFP_KERNEL);
- 
-@@ -45,6 +152,32 @@ static int gsbi_probe(struct platform_de
- 	if (IS_ERR(base))
- 		return PTR_ERR(base);
- 
-+	/* get the tcsr node and setup the config and regmap */
-+	gsbi->tcsr = syscon_regmap_lookup_by_phandle(node, "syscon-tcsr");
-+
-+	if (!IS_ERR(gsbi->tcsr)) {
-+		tcsr_node = of_parse_phandle(node, "syscon-tcsr", 0);
-+		if (tcsr_node) {
-+			match = of_match_node(tcsr_dt_match, tcsr_node);
-+			if (match)
-+				config = match->data;
-+			else
-+				dev_warn(&pdev->dev, "no matching TCSR\n");
-+
-+			of_node_put(tcsr_node);
-+		}
-+	}
-+
-+	if (of_property_read_u32(node, "cell-index", &gsbi_num)) {
-+		dev_err(&pdev->dev, "missing cell-index\n");
-+		return -EINVAL;
-+	}
-+
-+	if (gsbi_num < 1 || gsbi_num > MAX_GSBI) {
-+		dev_err(&pdev->dev, "invalid cell-index\n");
-+		return -EINVAL;
-+	}
-+
- 	if (of_property_read_u32(node, "qcom,mode", &gsbi->mode)) {
- 		dev_err(&pdev->dev, "missing mode configuration\n");
- 		return -EINVAL;
-@@ -64,6 +197,25 @@ static int gsbi_probe(struct platform_de
- 	writel_relaxed((gsbi->mode << GSBI_PROTOCOL_SHIFT) | gsbi->crci,
- 				base + GSBI_CTRL_REG);
- 
-+	/*
-+	 * modify tcsr to reflect mode and ADM CRCI mux
-+	 * Each gsbi contains a pair of bits, one for RX and one for TX
-+	 * SPI mode requires both bits cleared, otherwise they are set
-+	 */
-+	if (config) {
-+		for (i = 0; i < config->num_rows; i++) {
-+			mask = config->array[i][gsbi_num - 1];
-+
-+			if (gsbi->mode == GSBI_PROT_SPI)
-+				regmap_update_bits(gsbi->tcsr,
-+					TCSR_ADM_CRCI_BASE + 4 * i, mask, 0);
-+			else
-+				regmap_update_bits(gsbi->tcsr,
-+					TCSR_ADM_CRCI_BASE + 4 * i, mask, mask);
-+
-+		}
-+	}
-+
- 	/* make sure the gsbi control write is not reordered */
- 	wmb();
- 
diff --git a/target/linux/ipq806x/patches-3.18/103-ARM-DT-ipq8064-Add-TCSR-support.patch b/target/linux/ipq806x/patches-3.18/103-ARM-DT-ipq8064-Add-TCSR-support.patch
deleted file mode 100644
index 322e1d9237357070031cc7ffafee9a030f35ee82..0000000000000000000000000000000000000000
--- a/target/linux/ipq806x/patches-3.18/103-ARM-DT-ipq8064-Add-TCSR-support.patch
+++ /dev/null
@@ -1,65 +0,0 @@
---- a/arch/arm/boot/dts/qcom-ipq8064.dtsi
-+++ b/arch/arm/boot/dts/qcom-ipq8064.dtsi
-@@ -132,6 +132,7 @@
- 
- 		gsbi2: gsbi@12480000 {
- 			compatible = "qcom,gsbi-v1.0.0";
-+			cell-index = <2>;
- 			reg = <0x12480000 0x100>;
- 			clocks = <&gcc GSBI2_H_CLK>;
- 			clock-names = "iface";
-@@ -140,6 +141,8 @@
- 			ranges;
- 			status = "disabled";
- 
-+			syscon-tcsr = <&tcsr>;
-+
- 			uart2: serial@12490000 {
- 				compatible = "qcom,msm-uartdm-v1.3", "qcom,msm-uartdm";
- 				reg = <0x12490000 0x1000>,
-@@ -167,6 +170,7 @@
- 
- 		gsbi4: gsbi@16300000 {
- 			compatible = "qcom,gsbi-v1.0.0";
-+			cell-index = <4>;
- 			reg = <0x16300000 0x100>;
- 			clocks = <&gcc GSBI4_H_CLK>;
- 			clock-names = "iface";
-@@ -175,6 +179,8 @@
- 			ranges;
- 			status = "disabled";
- 
-+			syscon-tcsr = <&tcsr>;
-+
- 			uart4: serial@16340000 {
- 				compatible = "qcom,msm-uartdm-v1.3", "qcom,msm-uartdm";
- 				reg = <0x16340000 0x1000>,
-@@ -201,6 +207,7 @@
- 
- 		gsbi5: gsbi@1a200000 {
- 			compatible = "qcom,gsbi-v1.0.0";
-+			cell-index = <5>;
- 			reg = <0x1a200000 0x100>;
- 			clocks = <&gcc GSBI5_H_CLK>;
- 			clock-names = "iface";
-@@ -209,6 +216,8 @@
- 			ranges;
- 			status = "disabled";
- 
-+			syscon-tcsr = <&tcsr>;
-+
- 			uart5: serial@1a240000 {
- 				compatible = "qcom,msm-uartdm-v1.3", "qcom,msm-uartdm";
- 				reg = <0x1a240000 0x1000>,
-@@ -279,6 +288,11 @@
- 			status = "disabled";
- 		};
- 
-+		tcsr: syscon@1a400000 {
-+			compatible = "qcom,tcsr-ipq8064", "syscon";
-+			reg = <0x1a400000 0x100>;
-+		};
-+
- 		qcom,ssbi@500000 {
- 			compatible = "qcom,ssbi";
- 			reg = <0x00500000 0x1000>;
diff --git a/target/linux/ipq806x/patches-3.18/110-DT-PCI-qcom-Document-PCIe-devicetree-bindings.patch b/target/linux/ipq806x/patches-3.18/110-DT-PCI-qcom-Document-PCIe-devicetree-bindings.patch
deleted file mode 100644
index 41f91fae7c47b3a005819e1d97e0bfccb702883e..0000000000000000000000000000000000000000
--- a/target/linux/ipq806x/patches-3.18/110-DT-PCI-qcom-Document-PCIe-devicetree-bindings.patch
+++ /dev/null
@@ -1,263 +0,0 @@
-Content-Type: text/plain; charset="utf-8"
-MIME-Version: 1.0
-Content-Transfer-Encoding: 7bit
-Subject: [v2,3/5] DT: PCI: qcom: Document PCIe devicetree bindings
-From: Stanimir Varbanov <svarbanov@mm-sol.com>
-X-Patchwork-Id: 6326181
-Message-Id: <1430743338-10441-4-git-send-email-svarbanov@mm-sol.com>
-To: Rob Herring <robh+dt@kernel.org>, Kumar Gala <galak@codeaurora.org>,
-	Mark Rutland <mark.rutland@arm.com>,
-	Grant Likely <grant.likely@linaro.org>,
-	Bjorn Helgaas <bhelgaas@google.com>,
-	Kishon Vijay Abraham I <kishon@ti.com>,
-	Russell King <linux@arm.linux.org.uk>, Arnd Bergmann <arnd@arndb.de>
-Cc: linux-arm-msm@vger.kernel.org, linux-kernel@vger.kernel.org,
-	linux-arm-kernel@lists.infradead.org, devicetree@vger.kernel.org,
-	linux-pci@vger.kernel.org, Mathieu Olivari <mathieu@codeaurora.org>,
-	Srinivas Kandagatla <srinivas.kandagatla@linaro.org>,
-	Stanimir Varbanov <svarbanov@mm-sol.com>
-Date: Mon,  4 May 2015 15:42:16 +0300
-
-Document Qualcomm PCIe driver devicetree bindings.
-
-Signed-off-by: Stanimir Varbanov <svarbanov@mm-sol.com>
-
----
-.../devicetree/bindings/pci/qcom,pcie.txt          |  231 ++++++++++++++++++++
- 1 files changed, 231 insertions(+), 0 deletions(-)
- create mode 100644 Documentation/devicetree/bindings/pci/qcom,pcie.txt
-
---- /dev/null
-+++ b/Documentation/devicetree/bindings/pci/qcom,pcie.txt
-@@ -0,0 +1,231 @@
-+* Qualcomm PCI express root complex
-+
-+- compatible:
-+	Usage: required
-+	Value type: <stringlist>
-+	Definition: Value shall include
-+		    - "qcom,pcie-v0" for apq/ipq8064
-+		    - "qcom,pcie-v1" for apq8084
-+
-+- reg:
-+	Usage: required
-+	Value type: <prop-encoded-array>
-+	Definition: Register ranges as listed in the reg-names property
-+
-+- reg-names:
-+	Usage: required
-+	Value type: <stringlist>
-+	Definition: Must include the following entries
-+		    - "parf"   Qualcomm specific registers
-+		    - "dbi"    Designware PCIe registers
-+		    - "elbi"   External local bus interface registers
-+		    - "config" PCIe configuration space
-+
-+- device_type:
-+	Usage: required
-+	Value type: <string>
-+	Definition: Should be "pci". As specified in designware-pcie.txt
-+
-+- #address-cells:
-+	Usage: required
-+	Value type: <u32>
-+	Definition: Should be set to 3. As specified in designware-pcie.txt
-+
-+- #size-cells:
-+	Usage: required
-+	Value type: <u32>
-+	Definition: Should be set 2. As specified in designware-pcie.txt
-+
-+- ranges:
-+	Usage: required
-+	Value type: <prop-encoded-array>
-+	Definition: As specified in designware-pcie.txt
-+
-+- interrupts:
-+	Usage: required
-+	Value type: <prop-encoded-array>
-+	Definition: MSI interrupt
-+
-+- interrupt-names:
-+	Usage: required
-+	Value type: <stringlist>
-+	Definition: Should contain "msi"
-+
-+- #interrupt-cells:
-+	Usage: required
-+	Value type: <u32>
-+	Definition: Should be 1. As specified in designware-pcie.txt
-+
-+- interrupt-map-mask:
-+	Usage: required
-+	Value type: <prop-encoded-array>
-+	Definition: As specified in designware-pcie.txt
-+
-+- interrupt-map:
-+	Usage: required
-+	Value type: <prop-encoded-array>
-+	Definition: As specified in designware-pcie.txt
-+
-+- clocks:
-+	Usage: required
-+	Value type: <prop-encoded-array>
-+	Definition: List of phandle and clock specifier pairs as listed
-+		    in clock-names property
-+
-+- clock-names:
-+	Usage: required
-+	Value type: <stringlist>
-+	Definition: Should contain the following entries
-+		    * should be populated for v0 and v1
-+		    	- "iface"      Configuration AHB clock
-+
-+		    * should be populated for v0
-+		    	- "core"       Clocks the pcie hw block
-+		    	- "phy"        Clocks the pcie PHY block
-+
-+		    * should be populated for v1
-+			- "aux"        Auxiliary (AUX) clock
-+		    	- "bus_master" Master AXI clock
-+		    	- "bus_slave"  Slave AXI clock
-+
-+- resets:
-+	Usage: required
-+	Value type: <prop-encoded-array>
-+	Definition: List of phandle and reset specifier pairs as listed
-+		    in reset-names property
-+
-+- reset-names:
-+	Usage: required
-+	Value type: <stringlist>
-+	Definition: Should contain the following entries
-+		    * should be populated for v0
-+			- "axi"  AXI reset
-+			- "ahb"  AHB reset
-+			- "por"  POR reset
-+			- "pci"  PCI reset
-+			- "phy"  PHY reset
-+
-+		    * should be populated for v1
-+			- "core" Core reset
-+
-+- power-domains:
-+	Usage: required (for v1 only)
-+	Value type: <prop-encoded-array>
-+	Definition: A phandle and power domain specifier pair to the
-+		    power domain which is responsible for collapsing
-+		    and restoring power to the peripheral
-+
-+- <name>-supply:
-+	Usage: required
-+	Value type: <phandle>
-+	Definition: List of phandles to the power supply regulator(s)
-+		    * should be populated for v0 and v1
-+			- "vdda"        core analog power supply
-+
-+		    * should be populated for v0
-+			- "vdda_phy"    analog power supply for PHY
-+			- "vdda_refclk" analog power supply for IC which generate
-+					reference clock
-+
-+- phys:
-+	Usage: required (for v1 only)
-+	Value type: <phandle>
-+	Definition: List of phandle(s) as listed in phy-names property
-+
-+- phy-names:
-+	Usage: required (for v1 only)
-+	Value type: <stringlist>
-+	Definition: Should contain "pciephy"
-+
-+- <name>-gpio:
-+	Usage: optional
-+	Value type: <prop-encoded-array>
-+	Definition: List of phandle and gpio specifier pairs. Should contain
-+		    - "perst"  PCIe endpoint reset signal line
-+		    - "pewake" PCIe endpoint wake signal line
-+
-+- pinctrl-0:
-+	Usage: required
-+	Value type: <phandle>
-+	Definition: List of phandles pointing at a pin(s) configuration
-+
-+- pinctrl-names
-+	Usage: required
-+	Value type: <stringlist>
-+	Definition: List of names of pinctrl-0 state
-+
-+* Example for v0
-+	pcie0: pci@1b500000 {
-+		compatible = "qcom,pcie-v0";
-+		reg = <0x1b500000 0x1000
-+		       0x1b502000 0x80
-+		       0x1b600000 0x100
-+		       0x0ff00000 0x100000>;
-+		reg-names = "dbi", "elbi", "parf", "config";
-+		device_type = "pci";
-+		linux,pci-domain = <0>;
-+		bus-range = <0x00 0xff>;
-+		num-lanes = <1>;
-+		#address-cells = <3>;
-+		#size-cells = <2>;
-+		ranges = <0x81000000 0 0	  0x0fe00000 0 0x00100000   /* I/O */
-+			  0x82000000 0 0x00000000 0x08000000 0 0x07e00000>; /* memory */
-+		interrupts = <GIC_SPI 35 IRQ_TYPE_NONE>;
-+		interrupt-names = "msi";
-+		#interrupt-cells = <1>;
-+		interrupt-map-mask = <0 0 0 0x7>;
-+		interrupt-map = <0 0 0 1 &intc 0 36 IRQ_TYPE_LEVEL_HIGH>, /* int_a */
-+				<0 0 0 2 &intc 0 37 IRQ_TYPE_LEVEL_HIGH>, /* int_b */
-+				<0 0 0 3 &intc 0 38 IRQ_TYPE_LEVEL_HIGH>, /* int_c */
-+				<0 0 0 4 &intc 0 39 IRQ_TYPE_LEVEL_HIGH>; /* int_d */
-+		clocks = <&gcc PCIE_A_CLK>,
-+			 <&gcc PCIE_H_CLK>,
-+			 <&gcc PCIE_PHY_CLK>;
-+		clock-names = "core", "iface", "phy";
-+		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";
-+	};
-+
-+* Example for v1
-+	pcie0@fc520000 {
-+		compatible = "qcom,pcie-v1";
-+		reg = <0xfc520000 0x2000>,
-+		      <0xff000000 0x1000>,
-+		      <0xff001000 0x1000>,
-+		      <0xff002000 0x2000>;
-+		reg-names = "parf", "dbi", "elbi", "config";
-+		device_type = "pci";
-+		linux,pci-domain = <0>;
-+		bus-range = <0x00 0xff>;
-+		num-lanes = <1>;
-+		#address-cells = <3>;
-+		#size-cells = <2>;
-+		ranges = <0x81000000 0 0          0xff200000 0 0x00100000   /* I/O */
-+			  0x82000000 0 0x00300000 0xff300000 0 0x00d00000>; /* memory */
-+		interrupts = <GIC_SPI 243 IRQ_TYPE_NONE>;
-+		interrupt-names = "msi";
-+		#interrupt-cells = <1>;
-+		interrupt-map-mask = <0 0 0 0x7>;
-+		interrupt-map = <0 0 0 1 &intc 0 244 IRQ_TYPE_LEVEL_HIGH>, /* int_a */
-+				<0 0 0 2 &intc 0 245 IRQ_TYPE_LEVEL_HIGH>, /* int_b */
-+				<0 0 0 3 &intc 0 247 IRQ_TYPE_LEVEL_HIGH>, /* int_c */
-+				<0 0 0 4 &intc 0 248 IRQ_TYPE_LEVEL_HIGH>; /* int_d */
-+		clocks = <&gcc GCC_PCIE_0_CFG_AHB_CLK>,
-+			 <&gcc GCC_PCIE_0_MSTR_AXI_CLK>,
-+			 <&gcc GCC_PCIE_0_SLV_AXI_CLK>,
-+			 <&gcc GCC_PCIE_0_AUX_CLK>;
-+		clock-names = "iface", "master_bus", "slave_bus", "aux";
-+		resets = <&gcc GCC_PCIE_0_BCR>;
-+		reset-names = "core";
-+		power-domains = <&gcc PCIE0_GDSC>;
-+		vdda-supply = <&pma8084_l3>;
-+		phys = <&pciephy0>;
-+		phy-names = "pciephy";
-+		perst-gpio = <&tlmm 70 GPIO_ACTIVE_LOW>;
-+		pinctrl-0 = <&pcie0_pins_default>;
-+		pinctrl-names = "default";
-+	};
diff --git a/target/linux/ipq806x/patches-3.18/111-PCI-qcom-Add-Qualcomm-PCIe-controller-driver.patch b/target/linux/ipq806x/patches-3.18/111-PCI-qcom-Add-Qualcomm-PCIe-controller-driver.patch
deleted file mode 100644
index a0c9c7c36ed3fe6a52506ff6e5d636d7e9f3ed88..0000000000000000000000000000000000000000
--- a/target/linux/ipq806x/patches-3.18/111-PCI-qcom-Add-Qualcomm-PCIe-controller-driver.patch
+++ /dev/null
@@ -1,753 +0,0 @@
-Content-Type: text/plain; charset="utf-8"
-MIME-Version: 1.0
-Content-Transfer-Encoding: 7bit
-Subject: [v2,4/5] PCI: qcom: Add Qualcomm PCIe controller driver
-From: Stanimir Varbanov <svarbanov@mm-sol.com>
-X-Patchwork-Id: 6326161
-Message-Id: <1430743338-10441-5-git-send-email-svarbanov@mm-sol.com>
-To: Rob Herring <robh+dt@kernel.org>, Kumar Gala <galak@codeaurora.org>,
-	Mark Rutland <mark.rutland@arm.com>,
-	Grant Likely <grant.likely@linaro.org>,
-	Bjorn Helgaas <bhelgaas@google.com>,
-	Kishon Vijay Abraham I <kishon@ti.com>,
-	Russell King <linux@arm.linux.org.uk>, Arnd Bergmann <arnd@arndb.de>
-Cc: linux-arm-msm@vger.kernel.org, linux-kernel@vger.kernel.org,
-	linux-arm-kernel@lists.infradead.org, devicetree@vger.kernel.org,
-	linux-pci@vger.kernel.org, Mathieu Olivari <mathieu@codeaurora.org>,
-	Srinivas Kandagatla <srinivas.kandagatla@linaro.org>,
-	Stanimir Varbanov <svarbanov@mm-sol.com>
-Date: Mon,  4 May 2015 15:42:17 +0300
-
-The PCIe driver reuse the Designware common code for host
-and MSI initialization, and also program the Qualcomm
-application specific registers.
-
-Signed-off-by: Stanimir Varbanov <svarbanov@mm-sol.com>
-
----
-MAINTAINERS                  |    7 +
- drivers/pci/host/Kconfig     |    9 +
- drivers/pci/host/Makefile    |    1 +
- drivers/pci/host/pcie-qcom.c |  677 ++++++++++++++++++++++++++++++++++++++++++
- 4 files changed, 694 insertions(+), 0 deletions(-)
- create mode 100644 drivers/pci/host/pcie-qcom.c
-
---- a/MAINTAINERS
-+++ b/MAINTAINERS
-@@ -7127,6 +7127,13 @@ L:	linux-pci@vger.kernel.org
- S:	Maintained
- F:	drivers/pci/host/*spear*
- 
-+PCIE DRIVER FOR QUALCOMM MSM
-+M:	Stanimir Varbanov <svarbanov@mm-sol.com>
-+L:	linux-pci@vger.kernel.org
-+L:	linux-arm-msm@vger.kernel.org
-+S:	Maintained
-+F:	drivers/pci/host/*qcom*
-+
- PCMCIA SUBSYSTEM
- P:	Linux PCMCIA Team
- L:	linux-pcmcia@lists.infradead.org
---- a/drivers/pci/host/Kconfig
-+++ b/drivers/pci/host/Kconfig
-@@ -91,4 +91,13 @@ config PCI_XGENE
- 	  There are 5 internal PCIe ports available. Each port is GEN3 capable
- 	  and have varied lanes from x1 to x8.
- 
-+config PCIE_QCOM
-+	bool "Qualcomm PCIe controller"
-+	depends on ARCH_QCOM && OF || (ARM && COMPILE_TEST)
-+	select PCIE_DW
-+	select PCIEPORTBUS
-+	help
-+	  Say Y here to enable PCIe controller support on Qualcomm SoCs. The
-+	  PCIe controller use Designware core plus Qualcomm specific hardware
-+	  wrappers.
- endmenu
---- /dev/null
-+++ b/drivers/pci/host/pcie-qcom.c
-@@ -0,0 +1,677 @@
-+/*
-+ * 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/clk.h>
-+#include <linux/delay.h>
-+#include <linux/gpio.h>
-+#include <linux/interrupt.h>
-+#include <linux/io.h>
-+#include <linux/kernel.h>
-+#include <linux/module.h>
-+#include <linux/of_gpio.h>
-+#include <linux/pci.h>
-+#include <linux/platform_device.h>
-+#include <linux/phy/phy.h>
-+#include <linux/regulator/consumer.h>
-+#include <linux/reset.h>
-+#include <linux/slab.h>
-+#include <linux/types.h>
-+
-+#include "pcie-designware.h"
-+
-+#define PCIE20_PARF_PHY_CTRL			0x40
-+#define PCIE20_PARF_PHY_REFCLK			0x4C
-+#define PCIE20_PARF_DBI_BASE_ADDR		0x168
-+#define PCIE20_PARF_SLV_ADDR_SPACE_SIZE		0x16c
-+#define PCIE20_PARF_AXI_MSTR_WR_ADDR_HALT	0x178
-+
-+#define PCIE20_ELBI_SYS_CTRL			0x04
-+#define PCIE20_ELBI_SYS_STTS			0x08
-+#define XMLH_LINK_UP				BIT(10)
-+
-+#define PCIE20_CAP				0x70
-+#define PCIE20_CAP_LINKCTRLSTATUS		(PCIE20_CAP + 0x10)
-+
-+#define PERST_DELAY_MIN_US			1000
-+#define PERST_DELAY_MAX_US			1005
-+
-+#define LINKUP_DELAY_MIN_US			5000
-+#define LINKUP_DELAY_MAX_US			5100
-+#define LINKUP_RETRIES_COUNT			20
-+
-+#define PCIE_V0					0	/* apq8064 */
-+#define PCIE_V1					1	/* apq8084 */
-+
-+struct qcom_pcie_resources_v0 {
-+	struct clk *iface_clk;
-+	struct clk *core_clk;
-+	struct clk *phy_clk;
-+	struct reset_control *pci_reset;
-+	struct reset_control *axi_reset;
-+	struct reset_control *ahb_reset;
-+	struct reset_control *por_reset;
-+	struct reset_control *phy_reset;
-+	struct regulator *vdda;
-+	struct regulator *vdda_phy;
-+	struct regulator *vdda_refclk;
-+};
-+
-+struct qcom_pcie_resources_v1 {
-+	struct clk *iface;
-+	struct clk *aux;
-+	struct clk *master_bus;
-+	struct clk *slave_bus;
-+	struct reset_control *core;
-+	struct regulator *vdda;
-+};
-+
-+union pcie_resources {
-+	struct qcom_pcie_resources_v0 v0;
-+	struct qcom_pcie_resources_v1 v1;
-+};
-+
-+struct qcom_pcie {
-+	struct pcie_port pp;
-+	struct device *dev;
-+	union pcie_resources res;
-+	void __iomem *parf;
-+	void __iomem *dbi;
-+	void __iomem *elbi;
-+	struct phy *phy;
-+	struct gpio_desc *reset;
-+	unsigned int version;
-+};
-+
-+#define to_qcom_pcie(x)		container_of(x, struct qcom_pcie, pp)
-+
-+static inline void
-+writel_masked(void __iomem *addr, u32 clear_mask, u32 set_mask)
-+{
-+	u32 val = readl(addr);
-+
-+	val &= ~clear_mask;
-+	val |= set_mask;
-+	writel(val, addr);
-+}
-+
-+static void qcom_ep_reset_assert_deassert(struct qcom_pcie *pcie, int assert)
-+{
-+	int val, active_low;
-+
-+	if (IS_ERR_OR_NULL(pcie->reset))
-+		return;
-+
-+	active_low = gpiod_is_active_low(pcie->reset);
-+
-+	if (assert)
-+		val = !!active_low;
-+	else
-+		val = !active_low;
-+
-+	gpiod_set_value(pcie->reset, val);
-+
-+	usleep_range(PERST_DELAY_MIN_US, PERST_DELAY_MAX_US);
-+}
-+
-+static void qcom_ep_reset_assert(struct qcom_pcie *pcie)
-+{
-+	qcom_ep_reset_assert_deassert(pcie, 1);
-+}
-+
-+static void qcom_ep_reset_deassert(struct qcom_pcie *pcie)
-+{
-+	qcom_ep_reset_assert_deassert(pcie, 0);
-+}
-+
-+static irqreturn_t qcom_pcie_msi_irq_handler(int irq, void *arg)
-+{
-+	struct pcie_port *pp = arg;
-+
-+	return dw_handle_msi_irq(pp);
-+}
-+
-+static int qcom_pcie_link_up(struct pcie_port *pp)
-+{
-+	struct qcom_pcie *pcie = to_qcom_pcie(pp);
-+	u32 val = readl(pcie->dbi + PCIE20_CAP_LINKCTRLSTATUS);
-+
-+	return val & BIT(29) ? 1 : 0;
-+}
-+
-+static void qcom_pcie_disable_resources_v0(struct qcom_pcie *pcie)
-+{
-+	struct qcom_pcie_resources_v0 *res = &pcie->res.v0;
-+
-+	reset_control_assert(res->pci_reset);
-+	reset_control_assert(res->axi_reset);
-+	reset_control_assert(res->ahb_reset);
-+	reset_control_assert(res->por_reset);
-+	reset_control_assert(res->pci_reset);
-+	clk_disable_unprepare(res->iface_clk);
-+	clk_disable_unprepare(res->core_clk);
-+	clk_disable_unprepare(res->phy_clk);
-+	regulator_disable(res->vdda);
-+	regulator_disable(res->vdda_phy);
-+	regulator_disable(res->vdda_refclk);
-+}
-+
-+static void qcom_pcie_disable_resources_v1(struct qcom_pcie *pcie)
-+{
-+	struct qcom_pcie_resources_v1 *res = &pcie->res.v1;
-+
-+	reset_control_assert(res->core);
-+	clk_disable_unprepare(res->slave_bus);
-+	clk_disable_unprepare(res->master_bus);
-+	clk_disable_unprepare(res->iface);
-+	clk_disable_unprepare(res->aux);
-+	regulator_disable(res->vdda);
-+}
-+
-+static int qcom_pcie_enable_resources_v0(struct qcom_pcie *pcie)
-+{
-+	struct qcom_pcie_resources_v0 *res = &pcie->res.v0;
-+	struct device *dev = pcie->dev;
-+	int ret;
-+
-+	ret = regulator_enable(res->vdda);
-+	if (ret) {
-+		dev_err(dev, "cannot enable vdda regulator\n");
-+		return ret;
-+	}
-+
-+	ret = regulator_enable(res->vdda_refclk);
-+	if (ret) {
-+		dev_err(dev, "cannot enable vdda_refclk regulator\n");
-+		goto err_refclk;
-+	}
-+
-+	ret = regulator_enable(res->vdda_phy);
-+	if (ret) {
-+		dev_err(dev, "cannot enable vdda_phy regulator\n");
-+		goto err_vdda_phy;
-+	}
-+
-+	ret = clk_prepare_enable(res->iface_clk);
-+	if (ret) {
-+		dev_err(dev, "cannot prepare/enable iface clock\n");
-+		goto err_iface;
-+	}
-+
-+	ret = clk_prepare_enable(res->core_clk);
-+	if (ret) {
-+		dev_err(dev, "cannot prepare/enable core clock\n");
-+		goto err_clk_core;
-+	}
-+
-+	ret = clk_prepare_enable(res->phy_clk);
-+	if (ret) {
-+		dev_err(dev, "cannot prepare/enable phy clock\n");
-+		goto err_clk_phy;
-+	}
-+
-+	ret = reset_control_deassert(res->ahb_reset);
-+	if (ret) {
-+		dev_err(dev, "cannot deassert ahb reset\n");
-+		goto err_reset_ahb;
-+	}
-+
-+	return 0;
-+
-+err_reset_ahb:
-+	clk_disable_unprepare(res->phy_clk);
-+err_clk_phy:
-+	clk_disable_unprepare(res->core_clk);
-+err_clk_core:
-+	clk_disable_unprepare(res->iface_clk);
-+err_iface:
-+	regulator_disable(res->vdda_phy);
-+err_vdda_phy:
-+	regulator_disable(res->vdda_refclk);
-+err_refclk:
-+	regulator_disable(res->vdda);
-+	return ret;
-+}
-+
-+static int qcom_pcie_enable_resources_v1(struct qcom_pcie *pcie)
-+{
-+	struct qcom_pcie_resources_v1 *res = &pcie->res.v1;
-+	struct device *dev = pcie->dev;
-+	int ret;
-+
-+	ret = reset_control_deassert(res->core);
-+	if (ret) {
-+		dev_err(dev, "cannot deassert core reset\n");
-+		return ret;
-+	}
-+
-+	ret = clk_prepare_enable(res->aux);
-+	if (ret) {
-+		dev_err(dev, "cannot prepare/enable aux clock\n");
-+		goto err_res;
-+	}
-+
-+	ret = clk_prepare_enable(res->iface);
-+	if (ret) {
-+		dev_err(dev, "cannot prepare/enable iface clock\n");
-+		goto err_aux;
-+	}
-+
-+	ret = clk_prepare_enable(res->master_bus);
-+	if (ret) {
-+		dev_err(dev, "cannot prepare/enable master_bus clock\n");
-+		goto err_iface;
-+	}
-+
-+	ret = clk_prepare_enable(res->slave_bus);
-+	if (ret) {
-+		dev_err(dev, "cannot prepare/enable slave_bus clock\n");
-+		goto err_master;
-+	}
-+
-+	ret = regulator_enable(res->vdda);
-+	if (ret) {
-+		dev_err(dev, "cannot enable vdda regulator\n");
-+		goto err_slave;
-+	}
-+
-+	return 0;
-+
-+err_slave:
-+	clk_disable_unprepare(res->slave_bus);
-+err_master:
-+	clk_disable_unprepare(res->master_bus);
-+err_iface:
-+	clk_disable_unprepare(res->iface);
-+err_aux:
-+	clk_disable_unprepare(res->aux);
-+err_res:
-+	reset_control_assert(res->core);
-+
-+	return ret;
-+}
-+
-+static int qcom_pcie_get_resources_v0(struct qcom_pcie *pcie)
-+{
-+	struct qcom_pcie_resources_v0 *res = &pcie->res.v0;
-+	struct device *dev = pcie->dev;
-+
-+	res->vdda = devm_regulator_get(dev, "vdda");
-+	if (IS_ERR(res->vdda))
-+		return PTR_ERR(res->vdda);
-+
-+	res->vdda_phy = devm_regulator_get(dev, "vdda_phy");
-+	if (IS_ERR(res->vdda_phy))
-+		return PTR_ERR(res->vdda_phy);
-+
-+	res->vdda_refclk = devm_regulator_get(dev, "vdda_refclk");
-+	if (IS_ERR(res->vdda_refclk))
-+		return PTR_ERR(res->vdda_refclk);
-+
-+	res->iface_clk = devm_clk_get(dev, "iface");
-+	if (IS_ERR(res->iface_clk))
-+		return PTR_ERR(res->iface_clk);
-+
-+	res->core_clk = devm_clk_get(dev, "core");
-+	if (IS_ERR(res->core_clk))
-+		return PTR_ERR(res->core_clk);
-+
-+	res->phy_clk = devm_clk_get(dev, "phy");
-+	if (IS_ERR(res->phy_clk))
-+		return PTR_ERR(res->phy_clk);
-+
-+	res->pci_reset = devm_reset_control_get(dev, "pci");
-+	if (IS_ERR(res->pci_reset))
-+		return PTR_ERR(res->pci_reset);
-+
-+	res->axi_reset = devm_reset_control_get(dev, "axi");
-+	if (IS_ERR(res->axi_reset))
-+		return PTR_ERR(res->axi_reset);
-+
-+	res->ahb_reset = devm_reset_control_get(dev, "ahb");
-+	if (IS_ERR(res->ahb_reset))
-+		return PTR_ERR(res->ahb_reset);
-+
-+	res->por_reset = devm_reset_control_get(dev, "por");
-+	if (IS_ERR(res->por_reset))
-+		return PTR_ERR(res->por_reset);
-+
-+	res->phy_reset = devm_reset_control_get(dev, "phy");
-+	if (IS_ERR(res->phy_reset))
-+		return PTR_ERR(res->phy_reset);
-+
-+	return 0;
-+}
-+
-+static int qcom_pcie_get_resources_v1(struct qcom_pcie *pcie)
-+{
-+	struct qcom_pcie_resources_v1 *res = &pcie->res.v1;
-+	struct device *dev = pcie->dev;
-+
-+	res->vdda = devm_regulator_get(dev, "vdda");
-+	if (IS_ERR(res->vdda))
-+		return PTR_ERR(res->vdda);
-+
-+	res->iface = devm_clk_get(dev, "iface");
-+	if (IS_ERR(res->iface))
-+		return PTR_ERR(res->iface);
-+
-+	res->aux = devm_clk_get(dev, "aux");
-+	if (IS_ERR(res->aux) && PTR_ERR(res->aux) == -EPROBE_DEFER)
-+		return -EPROBE_DEFER;
-+	else if (IS_ERR(res->aux))
-+		res->aux = NULL;
-+
-+	res->master_bus = devm_clk_get(dev, "master_bus");
-+	if (IS_ERR(res->master_bus))
-+		return PTR_ERR(res->master_bus);
-+
-+	res->slave_bus = devm_clk_get(dev, "slave_bus");
-+	if (IS_ERR(res->slave_bus))
-+		return PTR_ERR(res->slave_bus);
-+
-+	res->core = devm_reset_control_get(dev, "core");
-+	if (IS_ERR(res->core))
-+		return PTR_ERR(res->core);
-+
-+	return 0;
-+}
-+
-+static int qcom_pcie_enable_link_training(struct pcie_port *pp)
-+{
-+	struct qcom_pcie *pcie = to_qcom_pcie(pp);
-+	struct device *dev = pp->dev;
-+	int retries;
-+	u32 val;
-+
-+	/* enable link training */
-+	writel_masked(pcie->elbi + PCIE20_ELBI_SYS_CTRL, 0, BIT(0));
-+
-+	/* wait for up to 100ms for the link to come up */
-+	retries = LINKUP_RETRIES_COUNT;
-+	do {
-+		val = readl(pcie->elbi + PCIE20_ELBI_SYS_STTS);
-+		if (val & XMLH_LINK_UP)
-+			break;
-+		usleep_range(LINKUP_DELAY_MIN_US, LINKUP_DELAY_MAX_US);
-+	} while (retries--);
-+
-+	if (retries < 0 || !dw_pcie_link_up(pp)) {
-+		dev_err(dev, "link initialization failed\n");
-+		return -ENXIO;
-+	}
-+
-+	return 0;
-+}
-+
-+static void qcom_pcie_host_init_v1(struct pcie_port *pp)
-+{
-+	struct qcom_pcie *pcie = to_qcom_pcie(pp);
-+	int ret;
-+
-+	qcom_ep_reset_assert(pcie);
-+
-+	ret = qcom_pcie_enable_resources_v1(pcie);
-+	if (ret)
-+		return;
-+
-+	/* change DBI base address */
-+	writel(0, pcie->parf + PCIE20_PARF_DBI_BASE_ADDR);
-+
-+	if (IS_ENABLED(CONFIG_PCI_MSI))
-+		writel_masked(pcie->parf + PCIE20_PARF_AXI_MSTR_WR_ADDR_HALT,
-+			      0, BIT(31));
-+
-+	ret = phy_init(pcie->phy);
-+	if (ret)
-+		goto err_res;
-+
-+	ret = phy_power_on(pcie->phy);
-+	if (ret)
-+		goto err_phy;
-+
-+	dw_pcie_setup_rc(pp);
-+
-+	if (IS_ENABLED(CONFIG_PCI_MSI))
-+		dw_pcie_msi_init(pp);
-+
-+	qcom_ep_reset_deassert(pcie);
-+
-+	ret = qcom_pcie_enable_link_training(pp);
-+	if (ret)
-+		goto err;
-+
-+	return;
-+
-+err:
-+	qcom_ep_reset_assert(pcie);
-+	phy_power_off(pcie->phy);
-+err_phy:
-+	phy_exit(pcie->phy);
-+err_res:
-+	qcom_pcie_disable_resources_v1(pcie);
-+}
-+
-+static void qcom_pcie_host_init_v0(struct pcie_port *pp)
-+{
-+	struct qcom_pcie *pcie = to_qcom_pcie(pp);
-+	struct qcom_pcie_resources_v0 *res = &pcie->res.v0;
-+	struct device *dev = pcie->dev;
-+	int ret;
-+
-+	qcom_ep_reset_assert(pcie);
-+
-+	ret = qcom_pcie_enable_resources_v0(pcie);
-+	if (ret)
-+		return;
-+
-+	writel_masked(pcie->parf + PCIE20_PARF_PHY_CTRL, BIT(0), 0);
-+
-+	/* enable external reference clock */
-+	writel_masked(pcie->parf + PCIE20_PARF_PHY_REFCLK, 0, BIT(16));
-+
-+	ret = reset_control_deassert(res->phy_reset);
-+	if (ret) {
-+		dev_err(dev, "cannot deassert phy reset\n");
-+		return;
-+	}
-+
-+	ret = reset_control_deassert(res->pci_reset);
-+	if (ret) {
-+		dev_err(dev, "cannot deassert pci reset\n");
-+		return;
-+	}
-+
-+	ret = reset_control_deassert(res->por_reset);
-+	if (ret) {
-+		dev_err(dev, "cannot deassert por reset\n");
-+		return;
-+	}
-+
-+	ret = reset_control_deassert(res->axi_reset);
-+	if (ret) {
-+		dev_err(dev, "cannot deassert axi reset\n");
-+		return;
-+	}
-+
-+	/* wait 150ms for clock acquisition */
-+	usleep_range(10000, 15000);
-+
-+	dw_pcie_setup_rc(pp);
-+
-+	if (IS_ENABLED(CONFIG_PCI_MSI))
-+		dw_pcie_msi_init(pp);
-+
-+	qcom_ep_reset_deassert(pcie);
-+
-+	ret = qcom_pcie_enable_link_training(pp);
-+	if (ret)
-+		goto err;
-+
-+	return;
-+err:
-+	qcom_ep_reset_assert(pcie);
-+	qcom_pcie_disable_resources_v0(pcie);
-+}
-+
-+static void qcom_pcie_host_init(struct pcie_port *pp)
-+{
-+	struct qcom_pcie *pcie = to_qcom_pcie(pp);
-+
-+	if (pcie->version == PCIE_V0)
-+		return qcom_pcie_host_init_v0(pp);
-+	else
-+		return qcom_pcie_host_init_v1(pp);
-+}
-+
-+static int
-+qcom_pcie_rd_own_conf(struct pcie_port *pp, int where, int size, u32 *val)
-+{
-+	/* the device class is not reported correctly from the register */
-+	if (where == PCI_CLASS_REVISION && size == 4) {
-+		*val = readl(pp->dbi_base + PCI_CLASS_REVISION);
-+		*val &= ~(0xffff << 16);
-+		*val |= PCI_CLASS_BRIDGE_PCI << 16;
-+		return PCIBIOS_SUCCESSFUL;
-+	}
-+
-+	return dw_pcie_cfg_read(pp->dbi_base + (where & ~0x3), where,
-+				size, val);
-+}
-+
-+static struct pcie_host_ops qcom_pcie_ops = {
-+	.link_up = qcom_pcie_link_up,
-+	.host_init = qcom_pcie_host_init,
-+	.rd_own_conf = qcom_pcie_rd_own_conf,
-+};
-+
-+static const struct of_device_id qcom_pcie_match[] = {
-+	{ .compatible = "qcom,pcie-v0", .data = (void *)PCIE_V0 },
-+	{ .compatible = "qcom,pcie-v1", .data = (void *)PCIE_V1 },
-+	{ }
-+};
-+
-+static int qcom_pcie_probe(struct platform_device *pdev)
-+{
-+	struct device *dev = &pdev->dev;
-+	const struct of_device_id *match;
-+	struct resource *res;
-+	struct qcom_pcie *pcie;
-+	struct pcie_port *pp;
-+	int ret;
-+
-+	match = of_match_node(qcom_pcie_match, dev->of_node);
-+	if (!match)
-+		return -ENXIO;
-+
-+	pcie = devm_kzalloc(dev, sizeof(*pcie), GFP_KERNEL);
-+	if (!pcie)
-+		return -ENOMEM;
-+
-+	pcie->version = (unsigned int)match->data;
-+
-+	pcie->reset = devm_gpiod_get_optional(dev, "perst");
-+	if (IS_ERR(pcie->reset) && PTR_ERR(pcie->reset) == -EPROBE_DEFER)
-+		return PTR_ERR(pcie->reset);
-+
-+	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "parf");
-+	pcie->parf = devm_ioremap_resource(dev, res);
-+	if (IS_ERR(pcie->parf))
-+		return PTR_ERR(pcie->parf);
-+
-+	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dbi");
-+	pcie->dbi = devm_ioremap_resource(dev, res);
-+	if (IS_ERR(pcie->dbi))
-+		return PTR_ERR(pcie->dbi);
-+
-+	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "elbi");
-+	pcie->elbi = devm_ioremap_resource(dev, res);
-+	if (IS_ERR(pcie->elbi))
-+		return PTR_ERR(pcie->elbi);
-+
-+	pcie->phy = devm_phy_optional_get(dev, "pciephy");
-+	if (IS_ERR(pcie->phy))
-+		return PTR_ERR(pcie->phy);
-+
-+	pcie->dev = dev;
-+
-+	if (pcie->version == PCIE_V0)
-+		ret = qcom_pcie_get_resources_v0(pcie);
-+	else
-+		ret = qcom_pcie_get_resources_v1(pcie);
-+
-+	if (ret)
-+		return ret;
-+
-+	pp = &pcie->pp;
-+	pp->dev = dev;
-+	pp->dbi_base = pcie->dbi;
-+	pp->root_bus_nr = -1;
-+	pp->ops = &qcom_pcie_ops;
-+
-+	if (IS_ENABLED(CONFIG_PCI_MSI)) {
-+		pp->msi_irq = platform_get_irq_byname(pdev, "msi");
-+		if (pp->msi_irq < 0) {
-+			dev_err(dev, "cannot get msi irq\n");
-+			return pp->msi_irq;
-+		}
-+
-+		ret = devm_request_irq(dev, pp->msi_irq,
-+				       qcom_pcie_msi_irq_handler,
-+				       IRQF_SHARED, "qcom-pcie-msi", pp);
-+		if (ret) {
-+			dev_err(dev, "cannot request msi irq\n");
-+			return ret;
-+		}
-+	}
-+
-+	ret = dw_pcie_host_init(pp);
-+	if (ret) {
-+		dev_err(dev, "cannot initialize host\n");
-+		return ret;
-+	}
-+
-+	platform_set_drvdata(pdev, pcie);
-+
-+	return 0;
-+}
-+
-+static int qcom_pcie_remove(struct platform_device *pdev)
-+{
-+	struct qcom_pcie *pcie = platform_get_drvdata(pdev);
-+
-+	qcom_ep_reset_assert(pcie);
-+	phy_power_off(pcie->phy);
-+	phy_exit(pcie->phy);
-+	if (pcie->version == PCIE_V0)
-+		qcom_pcie_disable_resources_v0(pcie);
-+	else
-+		qcom_pcie_disable_resources_v1(pcie);
-+
-+	return 0;
-+}
-+
-+static struct platform_driver qcom_pcie_driver = {
-+	.probe = qcom_pcie_probe,
-+	.remove = qcom_pcie_remove,
-+	.driver = {
-+		.name = "qcom-pcie",
-+		.of_match_table = qcom_pcie_match,
-+	},
-+};
-+
-+module_platform_driver(qcom_pcie_driver);
-+
-+MODULE_AUTHOR("Stanimir Varbanov <svarbanov@mm-sol.com>");
-+MODULE_DESCRIPTION("Qualcomm PCIe root complex driver");
-+MODULE_LICENSE("GPL v2");
-+MODULE_ALIAS("platform:qcom-pcie");
---- a/drivers/pci/host/Makefile
-+++ b/drivers/pci/host/Makefile
-@@ -11,3 +11,4 @@ obj-$(CONFIG_PCIE_SPEAR13XX) += pcie-spe
- obj-$(CONFIG_PCI_KEYSTONE) += pci-keystone-dw.o pci-keystone.o
- obj-$(CONFIG_PCIE_XILINX) += pcie-xilinx.o
- obj-$(CONFIG_PCI_XGENE) += pci-xgene.o
-+obj-$(CONFIG_PCIE_QCOM) += pcie-qcom.o
diff --git a/target/linux/ipq806x/patches-3.18/112-ARM-dts-qcom-add-pcie-nodes-to-ipq806x-platforms.patch b/target/linux/ipq806x/patches-3.18/112-ARM-dts-qcom-add-pcie-nodes-to-ipq806x-platforms.patch
deleted file mode 100644
index a57de6c4751e80083efee64a751477be56d0675f..0000000000000000000000000000000000000000
--- a/target/linux/ipq806x/patches-3.18/112-ARM-dts-qcom-add-pcie-nodes-to-ipq806x-platforms.patch
+++ /dev/null
@@ -1,244 +0,0 @@
-From 5b40516b2f5fb9b2a7d6d3e2e924f12ec9d183a8 Mon Sep 17 00:00:00 2001
-From: Mathieu Olivari <mathieu@codeaurora.org>
-Date: Tue, 21 Apr 2015 19:01:42 -0700
-Subject: [PATCH 8/9] ARM: dts: qcom: add pcie nodes to ipq806x platforms
-
-qcom-pcie driver now supports version 0 of the controller. This change
-adds the corresponding entries to the IPQ806x dtsi file and
-corresponding platform (AP148).
-
-Signed-off-by: Mathieu Olivari <mathieu@codeaurora.org>
----
- arch/arm/boot/dts/qcom-ipq8064-ap148.dts |  30 ++++++++
- arch/arm/boot/dts/qcom-ipq8064.dtsi      | 124 +++++++++++++++++++++++++++++++
- 2 files changed, 154 insertions(+)
-
---- a/arch/arm/boot/dts/qcom-ipq8064-ap148.dts
-+++ b/arch/arm/boot/dts/qcom-ipq8064-ap148.dts
-@@ -115,5 +115,15 @@
- 		usb30@1 {
- 			status = "ok";
- 		};
-+
-+		pcie0: pci@1b500000 {
-+			status = "ok";
-+			phy-tx0-term-offset = <7>;
-+		};
-+
-+		pcie1: pci@1b700000 {
-+			status = "ok";
-+			phy-tx0-term-offset = <7>;
-+		};
- 	};
- };
---- a/arch/arm/boot/dts/qcom-ipq8064-db149.dts
-+++ b/arch/arm/boot/dts/qcom-ipq8064-db149.dts
-@@ -128,5 +128,17 @@
- 		usb30@1 {
- 			status = "ok";
- 		};
-+
-+		pcie0: pci@1b500000 {
-+			status = "ok";
-+		};
-+
-+		pcie1: pci@1b700000 {
-+			status = "ok";
-+		};
-+
-+		pcie2: pci@1b900000 {
-+			status = "ok";
-+		};
- 	};
- };
---- a/arch/arm/boot/dts/qcom-ipq8064.dtsi
-+++ b/arch/arm/boot/dts/qcom-ipq8064.dtsi
-@@ -3,6 +3,9 @@
- #include "skeleton.dtsi"
- #include <dt-bindings/clock/qcom,gcc-ipq806x.h>
- #include <dt-bindings/soc/qcom,gsbi.h>
-+#include <dt-bindings/reset/qcom,gcc-ipq806x.h>
-+#include <dt-bindings/interrupt-controller/arm-gic.h>
-+#include <dt-bindings/gpio/gpio.h>
- 
- / {
- 	model = "Qualcomm IPQ8064";
-@@ -83,6 +86,33 @@
- 			interrupt-controller;
- 			#interrupt-cells = <2>;
- 			interrupts = <0 32 0x4>;
-+
-+			pcie0_pins: pcie0_pinmux {
-+				mux {
-+					pins = "gpio3";
-+					function = "pcie1_rst";
-+					drive-strength = <12>;
-+					bias-disable;
-+				};
-+			};
-+
-+			pcie1_pins: pcie1_pinmux {
-+				mux {
-+					pins = "gpio48";
-+					function = "pcie2_rst";
-+					drive-strength = <12>;
-+					bias-disable;
-+				};
-+			};
-+
-+			pcie2_pins: pcie2_pinmux {
-+				mux {
-+					pins = "gpio63";
-+					function = "pcie3_rst";
-+					drive-strength = <12>;
-+					bias-disable;
-+				};
-+			};
- 		};
- 
- 		intc: interrupt-controller@2000000 {
-@@ -311,6 +341,144 @@
- 			reg = <0x01200600 0x100>;
- 		};
- 
-+		pcie0: pci@1b500000 {
-+			compatible = "qcom,pcie-v0";
-+			reg = <0x1b500000 0x1000
-+			       0x1b502000 0x80
-+			       0x1b600000 0x100
-+			       0x0ff00000 0x100000>;
-+			reg-names = "dbi", "elbi", "parf", "config";
-+			device_type = "pci";
-+			linux,pci-domain = <0>;
-+			bus-range = <0x00 0xff>;
-+			num-lanes = <1>;
-+			#address-cells = <3>;
-+			#size-cells = <2>;
-+
-+			ranges = <0x81000000 0 0x0fe00000 0x0fe00000 0 0x00100000   /* downstream I/O */
-+				  0x82000000 0 0x08000000 0x08000000 0 0x07e00000>; /* non-prefetchable memory */
-+
-+			interrupts = <GIC_SPI 35 IRQ_TYPE_NONE>;
-+			interrupt-names = "msi";
-+			#interrupt-cells = <1>;
-+			interrupt-map-mask = <0 0 0 0x7>;
-+			interrupt-map = <0 0 0 1 &intc 0 36 IRQ_TYPE_LEVEL_HIGH>, /* int_a */
-+					<0 0 0 2 &intc 0 37 IRQ_TYPE_LEVEL_HIGH>, /* int_b */
-+					<0 0 0 3 &intc 0 38 IRQ_TYPE_LEVEL_HIGH>, /* int_c */
-+					<0 0 0 4 &intc 0 39 IRQ_TYPE_LEVEL_HIGH>; /* int_d */
-+
-+			clocks = <&gcc PCIE_A_CLK>,
-+				 <&gcc PCIE_H_CLK>,
-+				 <&gcc PCIE_PHY_CLK>;
-+			clock-names = "core", "iface", "phy";
-+
-+			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";
-+
-+			pinctrl-0 = <&pcie0_pins>;
-+			pinctrl-names = "default";
-+
-+			perst-gpio = <&qcom_pinmux 3 GPIO_ACTIVE_LOW>;
-+
-+			status = "disabled";
-+		};
-+
-+		pcie1: pci@1b700000 {
-+			compatible = "qcom,pcie-v0";
-+			reg = <0x1b700000 0x1000
-+			       0x1b702000 0x80
-+			       0x1b800000 0x100
-+			       0x31f00000 0x100000>;
-+			reg-names = "dbi", "elbi", "parf", "config";
-+			device_type = "pci";
-+			linux,pci-domain = <1>;
-+			bus-range = <0x00 0xff>;
-+			num-lanes = <1>;
-+			#address-cells = <3>;
-+			#size-cells = <2>;
-+
-+			ranges = <0x81000000 0 0x31e00000 0x31e00000 0 0x00100000   /* downstream I/O */
-+				  0x82000000 0 0x2e000000 0x2e000000 0 0x03e00000>; /* non-prefetchable memory */
-+
-+			interrupts = <GIC_SPI 57 IRQ_TYPE_NONE>;
-+			interrupt-names = "msi";
-+			#interrupt-cells = <1>;
-+			interrupt-map-mask = <0 0 0 0x7>;
-+			interrupt-map = <0 0 0 1 &intc 0 58 IRQ_TYPE_LEVEL_HIGH>, /* int_a */
-+					<0 0 0 2 &intc 0 59 IRQ_TYPE_LEVEL_HIGH>, /* int_b */
-+					<0 0 0 3 &intc 0 60 IRQ_TYPE_LEVEL_HIGH>, /* int_c */
-+					<0 0 0 4 &intc 0 61 IRQ_TYPE_LEVEL_HIGH>; /* int_d */
-+
-+			clocks = <&gcc PCIE_1_A_CLK>,
-+				 <&gcc PCIE_1_H_CLK>,
-+				 <&gcc PCIE_1_PHY_CLK>;
-+			clock-names = "core", "iface", "phy";
-+
-+			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";
-+
-+			pinctrl-0 = <&pcie1_pins>;
-+			pinctrl-names = "default";
-+
-+			perst-gpio = <&qcom_pinmux 48 GPIO_ACTIVE_LOW>;
-+
-+			status = "disabled";
-+		};
-+
-+		pcie2: pci@1b900000 {
-+			compatible = "qcom,pcie-v0";
-+			reg = <0x1b900000 0x1000
-+			       0x1b902000 0x80
-+			       0x1ba00000 0x100
-+			       0x35f00000 0x100000>;
-+			reg-names = "dbi", "elbi", "parf", "config";
-+			device_type = "pci";
-+			linux,pci-domain = <2>;
-+			bus-range = <0x00 0xff>;
-+			num-lanes = <1>;
-+			#address-cells = <3>;
-+			#size-cells = <2>;
-+
-+			ranges = <0x81000000 0 0x35e00000 0x35e00000 0 0x00100000   /* downstream I/O */
-+				  0x82000000 0 0x32000000 0x32000000 0 0x03e00000>; /* non-prefetchable memory */
-+
-+			interrupts = <GIC_SPI 71 IRQ_TYPE_NONE>;
-+			interrupt-names = "msi";
-+			#interrupt-cells = <1>;
-+			interrupt-map-mask = <0 0 0 0x7>;
-+			interrupt-map = <0 0 0 1 &intc 0 72 IRQ_TYPE_LEVEL_HIGH>, /* int_a */
-+					<0 0 0 2 &intc 0 73 IRQ_TYPE_LEVEL_HIGH>, /* int_b */
-+					<0 0 0 3 &intc 0 74 IRQ_TYPE_LEVEL_HIGH>, /* int_c */
-+					<0 0 0 4 &intc 0 75 IRQ_TYPE_LEVEL_HIGH>; /* int_d */
-+
-+			clocks = <&gcc PCIE_2_A_CLK>,
-+				 <&gcc PCIE_2_H_CLK>,
-+				 <&gcc PCIE_2_PHY_CLK>;
-+			clock-names = "core", "iface", "phy";
-+
-+			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";
-+
-+			pinctrl-0 = <&pcie2_pins>;
-+			pinctrl-names = "default";
-+
-+			perst-gpio = <&qcom_pinmux 63 GPIO_ACTIVE_LOW>;
-+
-+			status = "disabled";
-+		};
-+
- 		hs_phy_1: phy@100f8800 {
- 			compatible = "qcom,dwc3-hs-usb-phy";
- 			reg = <0x100f8800 0x30>;
diff --git a/target/linux/ipq806x/patches-3.18/113-ARM-qcom-automatically-select-PCI_DOMAINS-if-PCI-is-.patch b/target/linux/ipq806x/patches-3.18/113-ARM-qcom-automatically-select-PCI_DOMAINS-if-PCI-is-.patch
deleted file mode 100644
index 4f0e45f656d1942aa4aeff935b5f54b0e16a111c..0000000000000000000000000000000000000000
--- a/target/linux/ipq806x/patches-3.18/113-ARM-qcom-automatically-select-PCI_DOMAINS-if-PCI-is-.patch
+++ /dev/null
@@ -1,29 +0,0 @@
-From f004aa1dec6e2e206be025de15b115d60f2b21e3 Mon Sep 17 00:00:00 2001
-From: Mathieu Olivari <mathieu@codeaurora.org>
-Date: Tue, 21 Apr 2015 19:09:07 -0700
-Subject: [PATCH 9/9] ARM: qcom: automatically select PCI_DOMAINS if PCI is
- enabled
-
-If multiple PCIe devices are present in the system, the kernel will
-panic at boot time when trying to scan the PCI buses. This happens on
-IPQ806x based platforms, which has 3 PCIe ports.
-
-Enabling this option allows the kernel to assign the pci-domains
-according to the device-tree content. This allows multiple PCIe
-controllers to coexist in the system.
-
-Signed-off-by: Mathieu Olivari <mathieu@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
-@@ -6,6 +6,7 @@ menuconfig ARCH_QCOM
- 	select CLKSRC_OF
- 	select PINCTRL
- 	select QCOM_SCM if SMP
-+	select PCI_DOMAINS if PCI
- 	help
- 	  Support for Qualcomm's devicetree based systems.
- 
diff --git a/target/linux/ipq806x/patches-3.18/114-pcie-add-ctlr-init.patch b/target/linux/ipq806x/patches-3.18/114-pcie-add-ctlr-init.patch
deleted file mode 100644
index c00abca75377d7cb29cd8ec6416affe5bb748234..0000000000000000000000000000000000000000
--- a/target/linux/ipq806x/patches-3.18/114-pcie-add-ctlr-init.patch
+++ /dev/null
@@ -1,311 +0,0 @@
---- a/drivers/pci/host/pcie-qcom.c
-+++ b/drivers/pci/host/pcie-qcom.c
-@@ -29,8 +29,53 @@
- 
- #include "pcie-designware.h"
- 
-+/* DBI registers */
-+#define PCIE20_CAP				0x70
-+#define PCIE20_CAP_LINKCTRLSTATUS		(PCIE20_CAP + 0x10)
-+
-+#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_REGION_OUTBOUND		(0x0 << 31)
-+#define PCIE20_PLR_IATU_REGION_INDEX(x)		(x << 0)
-+
-+#define PCIE20_PLR_IATU_CTRL1			0x904
-+#define PCIE20_PLR_IATU_TYPE_CFG0		(0x4 << 0)
-+#define PCIE20_PLR_IATU_TYPE_MEM		(0x0 << 0)
-+
-+#define PCIE20_PLR_IATU_CTRL2			0x908
-+#define PCIE20_PLR_IATU_ENABLE			BIT(31)
-+
-+#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
-+
-+/* PARF registers */
-+#define PCIE20_PARF_PCS_DEEMPH			0x34
-+#define PCS_DEEMPH_TX_DEEMPH_GEN1(x)		(x << 16)
-+#define PCS_DEEMPH_TX_DEEMPH_GEN2_3_5DB(x)	(x << 8)
-+#define PCS_DEEMPH_TX_DEEMPH_GEN2_6DB(x)	(x << 0)
-+
-+#define PCIE20_PARF_PCS_SWING			0x38
-+#define PCS_SWING_TX_SWING_FULL(x)		(x << 8)
-+#define PCS_SWING_TX_SWING_LOW(x)		(x << 0)
-+
- #define PCIE20_PARF_PHY_CTRL			0x40
-+#define PHY_CTRL_PHY_TX0_TERM_OFFSET_MASK	(0x1f << 16)
-+#define PHY_CTRL_PHY_TX0_TERM_OFFSET(x)		(x << 16)
-+
- #define PCIE20_PARF_PHY_REFCLK			0x4C
-+#define REF_SSP_EN				BIT(16)
-+#define REF_USE_PAD				BIT(12)
-+
-+#define PCIE20_PARF_CONFIG_BITS			0x50
-+#define PHY_RX0_EQ(x)				(x << 24)
-+
- #define PCIE20_PARF_DBI_BASE_ADDR		0x168
- #define PCIE20_PARF_SLV_ADDR_SPACE_SIZE		0x16c
- #define PCIE20_PARF_AXI_MSTR_WR_ADDR_HALT	0x178
-@@ -39,9 +84,6 @@
- #define PCIE20_ELBI_SYS_STTS			0x08
- #define XMLH_LINK_UP				BIT(10)
- 
--#define PCIE20_CAP				0x70
--#define PCIE20_CAP_LINKCTRLSTATUS		(PCIE20_CAP + 0x10)
--
- #define PERST_DELAY_MIN_US			1000
- #define PERST_DELAY_MAX_US			1005
- 
-@@ -56,14 +98,18 @@ struct qcom_pcie_resources_v0 {
- 	struct clk *iface_clk;
- 	struct clk *core_clk;
- 	struct clk *phy_clk;
-+	struct clk *aux_clk;
-+	struct clk *ref_clk;
- 	struct reset_control *pci_reset;
- 	struct reset_control *axi_reset;
- 	struct reset_control *ahb_reset;
- 	struct reset_control *por_reset;
- 	struct reset_control *phy_reset;
-+	struct reset_control *ext_reset;
- 	struct regulator *vdda;
- 	struct regulator *vdda_phy;
- 	struct regulator *vdda_refclk;
-+	uint8_t phy_tx0_term_offset;
- };
- 
- struct qcom_pcie_resources_v1 {
-@@ -106,20 +152,10 @@ writel_masked(void __iomem *addr, u32 cl
- 
- static void qcom_ep_reset_assert_deassert(struct qcom_pcie *pcie, int assert)
- {
--	int val, active_low;
--
- 	if (IS_ERR_OR_NULL(pcie->reset))
- 		return;
- 
--	active_low = gpiod_is_active_low(pcie->reset);
--
--	if (assert)
--		val = !!active_low;
--	else
--		val = !active_low;
--
--	gpiod_set_value(pcie->reset, val);
--
-+	gpiod_set_value(pcie->reset, assert);
- 	usleep_range(PERST_DELAY_MIN_US, PERST_DELAY_MAX_US);
- }
- 
-@@ -156,10 +192,13 @@ static void qcom_pcie_disable_resources_
- 	reset_control_assert(res->axi_reset);
- 	reset_control_assert(res->ahb_reset);
- 	reset_control_assert(res->por_reset);
--	reset_control_assert(res->pci_reset);
-+	reset_control_assert(res->phy_reset);
-+	reset_control_assert(res->ext_reset);
- 	clk_disable_unprepare(res->iface_clk);
- 	clk_disable_unprepare(res->core_clk);
- 	clk_disable_unprepare(res->phy_clk);
-+	clk_disable_unprepare(res->aux_clk);
-+	clk_disable_unprepare(res->ref_clk);
- 	regulator_disable(res->vdda);
- 	regulator_disable(res->vdda_phy);
- 	regulator_disable(res->vdda_refclk);
-@@ -201,6 +240,12 @@ static int qcom_pcie_enable_resources_v0
- 		goto err_vdda_phy;
- 	}
- 
-+	ret = reset_control_deassert(res->ext_reset);
-+	if (ret) {
-+		dev_err(dev, "cannot assert ext reset\n");
-+		goto err_reset_ext;
-+	}
-+
- 	ret = clk_prepare_enable(res->iface_clk);
- 	if (ret) {
- 		dev_err(dev, "cannot prepare/enable iface clock\n");
-@@ -219,21 +264,40 @@ static int qcom_pcie_enable_resources_v0
- 		goto err_clk_phy;
- 	}
- 
-+	ret = clk_prepare_enable(res->aux_clk);
-+	if (ret) {
-+		dev_err(dev, "cannot prepare/enable aux clock\n");
-+		goto err_clk_aux;
-+	}
-+
-+	ret = clk_prepare_enable(res->ref_clk);
-+	if (ret) {
-+		dev_err(dev, "cannot prepare/enable ref clock\n");
-+		goto err_clk_ref;
-+	}
-+
- 	ret = reset_control_deassert(res->ahb_reset);
- 	if (ret) {
- 		dev_err(dev, "cannot deassert ahb reset\n");
- 		goto err_reset_ahb;
- 	}
-+	udelay(1);
- 
- 	return 0;
- 
- err_reset_ahb:
-+	clk_disable_unprepare(res->ref_clk);
-+err_clk_ref:
-+	clk_disable_unprepare(res->aux_clk);
-+err_clk_aux:
- 	clk_disable_unprepare(res->phy_clk);
- err_clk_phy:
- 	clk_disable_unprepare(res->core_clk);
- err_clk_core:
- 	clk_disable_unprepare(res->iface_clk);
- err_iface:
-+	reset_control_assert(res->ext_reset);
-+err_reset_ext:
- 	regulator_disable(res->vdda_phy);
- err_vdda_phy:
- 	regulator_disable(res->vdda_refclk);
-@@ -329,6 +393,14 @@ static int qcom_pcie_get_resources_v0(st
- 	if (IS_ERR(res->phy_clk))
- 		return PTR_ERR(res->phy_clk);
- 
-+	res->aux_clk = devm_clk_get(dev, "aux");
-+	if (IS_ERR(res->aux_clk))
-+		return PTR_ERR(res->aux_clk);
-+
-+	res->ref_clk = devm_clk_get(dev, "ref");
-+	if (IS_ERR(res->ref_clk))
-+		return PTR_ERR(res->ref_clk);
-+
- 	res->pci_reset = devm_reset_control_get(dev, "pci");
- 	if (IS_ERR(res->pci_reset))
- 		return PTR_ERR(res->pci_reset);
-@@ -349,6 +421,14 @@ static int qcom_pcie_get_resources_v0(st
- 	if (IS_ERR(res->phy_reset))
- 		return PTR_ERR(res->phy_reset);
- 
-+	res->ext_reset = devm_reset_control_get(dev, "ext");
-+	if (IS_ERR(res->ext_reset))
-+		return PTR_ERR(res->ext_reset);
-+
-+	if (of_property_read_u8(dev->of_node, "phy-tx0-term-offset",
-+				&res->phy_tx0_term_offset))
-+		res->phy_tx0_term_offset = 0;
-+
- 	return 0;
- }
- 
-@@ -461,6 +541,57 @@ err_res:
- 	qcom_pcie_disable_resources_v1(pcie);
- }
- 
-+static void qcom_pcie_prog_viewport_cfg0(struct qcom_pcie *pcie, u32 busdev)
-+{
-+	struct pcie_port *pp = &pcie->pp;
-+
-+	/*
-+	 * program and enable address translation region 0 (device config
-+	 * address space); region type config;
-+	 * axi config address range to device config address range
-+	 */
-+	writel(PCIE20_PLR_IATU_REGION_OUTBOUND |
-+	       PCIE20_PLR_IATU_REGION_INDEX(0),
-+	       pcie->dbi + PCIE20_PLR_IATU_VIEWPORT);
-+
-+	writel(PCIE20_PLR_IATU_TYPE_CFG0, pcie->dbi + PCIE20_PLR_IATU_CTRL1);
-+	writel(PCIE20_PLR_IATU_ENABLE, pcie->dbi + PCIE20_PLR_IATU_CTRL2);
-+	writel(pp->cfg0_mod_base, pcie->dbi + PCIE20_PLR_IATU_LBAR);
-+	writel((pp->cfg0_mod_base >> 32), pcie->dbi + PCIE20_PLR_IATU_UBAR);
-+	writel((pp->cfg0_mod_base + pp->cfg0_size - 1),
-+	       pcie->dbi + PCIE20_PLR_IATU_LAR);
-+	writel(busdev, pcie->dbi + PCIE20_PLR_IATU_LTAR);
-+	writel(0, pcie->dbi + PCIE20_PLR_IATU_UTAR);
-+}
-+
-+static void qcom_pcie_prog_viewport_mem2_outbound(struct qcom_pcie *pcie)
-+{
-+	struct pcie_port *pp = &pcie->pp;
-+
-+	/*
-+	 * 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(PCIE20_PLR_IATU_REGION_OUTBOUND |
-+	       PCIE20_PLR_IATU_REGION_INDEX(2),
-+	       pcie->dbi + PCIE20_PLR_IATU_VIEWPORT);
-+
-+	writel(PCIE20_PLR_IATU_TYPE_MEM, pcie->dbi + PCIE20_PLR_IATU_CTRL1);
-+	writel(PCIE20_PLR_IATU_ENABLE, pcie->dbi + PCIE20_PLR_IATU_CTRL2);
-+	writel(pp->mem_mod_base, pcie->dbi + PCIE20_PLR_IATU_LBAR);
-+	writel((pp->mem_mod_base >> 32), pcie->dbi + PCIE20_PLR_IATU_UBAR);
-+	writel(pp->mem_mod_base + pp->mem_size - 1,
-+	       pcie->dbi + PCIE20_PLR_IATU_LAR);
-+	writel(pp->mem_bus_addr, pcie->dbi + PCIE20_PLR_IATU_LTAR);
-+	writel(upper_32_bits(pp->mem_bus_addr),
-+	       pcie->dbi + PCIE20_PLR_IATU_UTAR);
-+
-+	/* 256B PCIE buffer setting */
-+	writel(0x1, pcie->dbi + PCIE20_AXI_MSTR_RESP_COMP_CTRL0);
-+	writel(0x1, pcie->dbi + PCIE20_AXI_MSTR_RESP_COMP_CTRL1);
-+}
-+
- static void qcom_pcie_host_init_v0(struct pcie_port *pp)
- {
- 	struct qcom_pcie *pcie = to_qcom_pcie(pp);
-@@ -470,15 +601,34 @@ static void qcom_pcie_host_init_v0(struc
- 
- 	qcom_ep_reset_assert(pcie);
- 
-+	reset_control_assert(res->ahb_reset);
-+
- 	ret = qcom_pcie_enable_resources_v0(pcie);
- 	if (ret)
- 		return;
- 
- 	writel_masked(pcie->parf + PCIE20_PARF_PHY_CTRL, BIT(0), 0);
- 
--	/* enable external reference clock */
--	writel_masked(pcie->parf + PCIE20_PARF_PHY_REFCLK, 0, BIT(16));
-+	/* Set Tx termination offset */
-+	writel_masked(pcie->parf + PCIE20_PARF_PHY_CTRL,
-+		      PHY_CTRL_PHY_TX0_TERM_OFFSET_MASK,
-+		      PHY_CTRL_PHY_TX0_TERM_OFFSET(res->phy_tx0_term_offset));
-+
-+	/* PARF programming */
-+	writel(PCS_DEEMPH_TX_DEEMPH_GEN1(0x18) |
-+	       PCS_DEEMPH_TX_DEEMPH_GEN2_3_5DB(0x18) |
-+	       PCS_DEEMPH_TX_DEEMPH_GEN2_6DB(0x22),
-+	       pcie->parf + PCIE20_PARF_PCS_DEEMPH);
-+	writel(PCS_SWING_TX_SWING_FULL(0x78) |
-+	       PCS_SWING_TX_SWING_LOW(0x78),
-+	       pcie->parf + PCIE20_PARF_PCS_SWING);
-+	writel(PHY_RX0_EQ(0x4), pcie->parf + PCIE20_PARF_CONFIG_BITS);
-+
-+	/* Enable reference clock */
-+	writel_masked(pcie->parf + PCIE20_PARF_PHY_REFCLK,
-+		      REF_USE_PAD, REF_SSP_EN);
- 
-+	/* De-assert PHY, PCIe, POR and AXI resets */
- 	ret = reset_control_deassert(res->phy_reset);
- 	if (ret) {
- 		dev_err(dev, "cannot deassert phy reset\n");
-@@ -517,6 +667,9 @@ static void qcom_pcie_host_init_v0(struc
- 	if (ret)
- 		goto err;
- 
-+	qcom_pcie_prog_viewport_cfg0(pcie, MSM_PCIE_DEV_CFG_ADDR);
-+	qcom_pcie_prog_viewport_mem2_outbound(pcie);
-+
- 	return;
- err:
- 	qcom_ep_reset_assert(pcie);
diff --git a/target/linux/ipq806x/patches-3.18/115-add-pcie-aux-clk-dts.patch b/target/linux/ipq806x/patches-3.18/115-add-pcie-aux-clk-dts.patch
deleted file mode 100644
index 9f32e8fbc2175306ca7aa31d8a8feb4ad23b8160..0000000000000000000000000000000000000000
--- a/target/linux/ipq806x/patches-3.18/115-add-pcie-aux-clk-dts.patch
+++ /dev/null
@@ -1,80 +0,0 @@
---- a/arch/arm/boot/dts/qcom-ipq8064.dtsi
-+++ b/arch/arm/boot/dts/qcom-ipq8064.dtsi
-@@ -369,15 +369,21 @@
- 
- 			clocks = <&gcc PCIE_A_CLK>,
- 				 <&gcc PCIE_H_CLK>,
--				 <&gcc PCIE_PHY_CLK>;
--			clock-names = "core", "iface", "phy";
-+				 <&gcc PCIE_PHY_CLK>,
-+				 <&gcc PCIE_AUX_CLK>,
-+				 <&gcc PCIE_ALT_REF_CLK>;
-+			clock-names = "core", "iface", "phy", "aux", "ref";
-+
-+			assigned-clocks = <&gcc PCIE_ALT_REF_CLK>;
-+			assigned-clock-rates = <100000000>;
- 
- 			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";
-+				 <&gcc PCIE_PHY_RESET>,
-+				 <&gcc PCIE_EXT_RESET>;
-+			reset-names = "axi", "ahb", "por", "pci", "phy", "ext";
- 
- 			pinctrl-0 = <&pcie0_pins>;
- 			pinctrl-names = "default";
-@@ -415,15 +421,21 @@
- 
- 			clocks = <&gcc PCIE_1_A_CLK>,
- 				 <&gcc PCIE_1_H_CLK>,
--				 <&gcc PCIE_1_PHY_CLK>;
--			clock-names = "core", "iface", "phy";
-+				 <&gcc PCIE_1_PHY_CLK>,
-+				 <&gcc PCIE_1_AUX_CLK>,
-+				 <&gcc PCIE_1_ALT_REF_CLK>;
-+			clock-names = "core", "iface", "phy", "aux", "ref";
-+
-+			assigned-clocks = <&gcc PCIE_1_ALT_REF_CLK>;
-+			assigned-clock-rates = <100000000>;
- 
- 			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";
-+				 <&gcc PCIE_1_PHY_RESET>,
-+				 <&gcc PCIE_1_EXT_RESET>;
-+			reset-names = "axi", "ahb", "por", "pci", "phy", "ext";
- 
- 			pinctrl-0 = <&pcie1_pins>;
- 			pinctrl-names = "default";
-@@ -461,15 +473,21 @@
- 
- 			clocks = <&gcc PCIE_2_A_CLK>,
- 				 <&gcc PCIE_2_H_CLK>,
--				 <&gcc PCIE_2_PHY_CLK>;
--			clock-names = "core", "iface", "phy";
-+				 <&gcc PCIE_2_PHY_CLK>,
-+				 <&gcc PCIE_2_AUX_CLK>,
-+				 <&gcc PCIE_2_ALT_REF_CLK>;
-+			clock-names = "core", "iface", "phy", "aux", "ref";
-+
-+			assigned-clocks = <&gcc PCIE_2_ALT_REF_CLK>;
-+			assigned-clock-rates = <100000000>;
- 
- 			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";
-+				 <&gcc PCIE_2_PHY_RESET>,
-+				 <&gcc PCIE_2_EXT_RESET>;
-+			reset-names = "axi", "ahb", "por", "pci", "phy", "ext";
- 
- 			pinctrl-0 = <&pcie2_pins>;
- 			pinctrl-names = "default";
diff --git a/target/linux/ipq806x/patches-3.18/120-mfd-qcom-rpm-Driver-for-the-Qualcomm-RPM.patch b/target/linux/ipq806x/patches-3.18/120-mfd-qcom-rpm-Driver-for-the-Qualcomm-RPM.patch
deleted file mode 100644
index d8191422c4f1618c2cbed3faebc1d62c611495ed..0000000000000000000000000000000000000000
--- a/target/linux/ipq806x/patches-3.18/120-mfd-qcom-rpm-Driver-for-the-Qualcomm-RPM.patch
+++ /dev/null
@@ -1,654 +0,0 @@
-From 58e214382bdd1eb48c5a3519182bddcb26edabad Mon Sep 17 00:00:00 2001
-From: Bjorn Andersson <bjorn.andersson@sonymobile.com>
-Date: Wed, 26 Nov 2014 13:51:00 -0800
-Subject: [PATCH] mfd: qcom-rpm: Driver for the Qualcomm RPM
-
-Driver for the Resource Power Manager (RPM) found in Qualcomm 8660, 8960
-and 8064 based devices. The driver exposes resources that child drivers
-can operate on; to implementing regulator, clock and bus frequency
-drivers.
-
-Signed-off-by: Bjorn Andersson <bjorn.andersson@sonymobile.com>
-Signed-off-by: Lee Jones <lee.jones@linaro.org>
----
- drivers/mfd/Kconfig          |  14 ++
- drivers/mfd/Makefile         |   1 +
- drivers/mfd/qcom_rpm.c       | 581 +++++++++++++++++++++++++++++++++++++++++++
- include/linux/mfd/qcom_rpm.h |  13 +
- 4 files changed, 609 insertions(+)
- create mode 100644 drivers/mfd/qcom_rpm.c
- create mode 100644 include/linux/mfd/qcom_rpm.h
-
---- a/drivers/mfd/Kconfig
-+++ b/drivers/mfd/Kconfig
-@@ -567,6 +567,20 @@ config MFD_PM8921_CORE
- 	  Say M here if you want to include support for PM8921 chip as a module.
- 	  This will build a module called "pm8921-core".
- 
-+config MFD_QCOM_RPM
-+	tristate "Qualcomm Resource Power Manager (RPM)"
-+	depends on ARCH_QCOM && OF
-+	help
-+	  If you say yes to this option, support will be included for the
-+	  Resource Power Manager system found in the Qualcomm 8660, 8960 and
-+	  8064 based devices.
-+
-+	  This is required to access many regulators, clocks and bus
-+	  frequencies controlled by the RPM on these devices.
-+
-+	  Say M here if you want to include support for the Qualcomm RPM as a
-+	  module. This will build a module called "qcom_rpm".
-+
- config MFD_SPMI_PMIC
- 	tristate "Qualcomm SPMI PMICs"
- 	depends on ARCH_QCOM || COMPILE_TEST
---- a/drivers/mfd/Makefile
-+++ b/drivers/mfd/Makefile
-@@ -153,6 +153,7 @@ obj-$(CONFIG_MFD_SI476X_CORE)	+= si476x-
- obj-$(CONFIG_MFD_CS5535)	+= cs5535-mfd.o
- obj-$(CONFIG_MFD_OMAP_USB_HOST)	+= omap-usb-host.o omap-usb-tll.o
- obj-$(CONFIG_MFD_PM8921_CORE) 	+= pm8921-core.o ssbi.o
-+obj-$(CONFIG_MFD_QCOM_RPM)	+= qcom_rpm.o
- obj-$(CONFIG_MFD_SPMI_PMIC)	+= qcom-spmi-pmic.o
- obj-$(CONFIG_TPS65911_COMPARATOR)	+= tps65911-comparator.o
- obj-$(CONFIG_MFD_TPS65090)	+= tps65090.o
---- /dev/null
-+++ b/drivers/mfd/qcom_rpm.c
-@@ -0,0 +1,581 @@
-+/*
-+ * Copyright (c) 2014, Sony Mobile Communications AB.
-+ * Copyright (c) 2013, The Linux Foundation. All rights reserved.
-+ * Author: Bjorn Andersson <bjorn.andersson@sonymobile.com>
-+ *
-+ * 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/platform_device.h>
-+#include <linux/of_platform.h>
-+#include <linux/io.h>
-+#include <linux/interrupt.h>
-+#include <linux/mfd/qcom_rpm.h>
-+#include <linux/mfd/syscon.h>
-+#include <linux/regmap.h>
-+
-+#include <dt-bindings/mfd/qcom-rpm.h>
-+
-+struct qcom_rpm_resource {
-+	unsigned target_id;
-+	unsigned status_id;
-+	unsigned select_id;
-+	unsigned size;
-+};
-+
-+struct qcom_rpm_data {
-+	u32 version;
-+	const struct qcom_rpm_resource *resource_table;
-+	unsigned n_resources;
-+};
-+
-+struct qcom_rpm {
-+	struct device *dev;
-+	struct regmap *ipc_regmap;
-+	unsigned ipc_offset;
-+	unsigned ipc_bit;
-+
-+	struct completion ack;
-+	struct mutex lock;
-+
-+	void __iomem *status_regs;
-+	void __iomem *ctrl_regs;
-+	void __iomem *req_regs;
-+
-+	u32 ack_status;
-+
-+	const struct qcom_rpm_data *data;
-+};
-+
-+#define RPM_STATUS_REG(rpm, i)	((rpm)->status_regs + (i) * 4)
-+#define RPM_CTRL_REG(rpm, i)	((rpm)->ctrl_regs + (i) * 4)
-+#define RPM_REQ_REG(rpm, i)	((rpm)->req_regs + (i) * 4)
-+
-+#define RPM_REQUEST_TIMEOUT	(5 * HZ)
-+
-+#define RPM_REQUEST_CONTEXT	3
-+#define RPM_REQ_SELECT		11
-+#define RPM_ACK_CONTEXT		15
-+#define RPM_ACK_SELECTOR	23
-+#define RPM_SELECT_SIZE		7
-+
-+#define RPM_NOTIFICATION	BIT(30)
-+#define RPM_REJECTED		BIT(31)
-+
-+#define RPM_SIGNAL		BIT(2)
-+
-+static const struct qcom_rpm_resource apq8064_rpm_resource_table[] = {
-+	[QCOM_RPM_CXO_CLK] =			{ 25, 9, 5, 1 },
-+	[QCOM_RPM_PXO_CLK] =			{ 26, 10, 6, 1 },
-+	[QCOM_RPM_APPS_FABRIC_CLK] =		{ 27, 11, 8, 1 },
-+	[QCOM_RPM_SYS_FABRIC_CLK] =		{ 28, 12, 9, 1 },
-+	[QCOM_RPM_MM_FABRIC_CLK] =		{ 29, 13, 10, 1 },
-+	[QCOM_RPM_DAYTONA_FABRIC_CLK] =		{ 30, 14, 11, 1 },
-+	[QCOM_RPM_SFPB_CLK] =			{ 31, 15, 12, 1 },
-+	[QCOM_RPM_CFPB_CLK] =			{ 32, 16, 13, 1 },
-+	[QCOM_RPM_MMFPB_CLK] =			{ 33, 17, 14, 1 },
-+	[QCOM_RPM_EBI1_CLK] =			{ 34, 18, 16, 1 },
-+	[QCOM_RPM_APPS_FABRIC_HALT] =		{ 35, 19, 18, 1 },
-+	[QCOM_RPM_APPS_FABRIC_MODE] =		{ 37, 20, 19, 1 },
-+	[QCOM_RPM_APPS_FABRIC_IOCTL] =		{ 40, 21, 20, 1 },
-+	[QCOM_RPM_APPS_FABRIC_ARB] =		{ 41, 22, 21, 12 },
-+	[QCOM_RPM_SYS_FABRIC_HALT] =		{ 53, 23, 22, 1 },
-+	[QCOM_RPM_SYS_FABRIC_MODE] =		{ 55, 24, 23, 1 },
-+	[QCOM_RPM_SYS_FABRIC_IOCTL] =		{ 58, 25, 24, 1 },
-+	[QCOM_RPM_SYS_FABRIC_ARB] =		{ 59, 26, 25, 30 },
-+	[QCOM_RPM_MM_FABRIC_HALT] =		{ 89, 27, 26, 1 },
-+	[QCOM_RPM_MM_FABRIC_MODE] =		{ 91, 28, 27, 1 },
-+	[QCOM_RPM_MM_FABRIC_IOCTL] =		{ 94, 29, 28, 1 },
-+	[QCOM_RPM_MM_FABRIC_ARB] =		{ 95, 30, 29, 21 },
-+	[QCOM_RPM_PM8921_SMPS1] =		{ 116, 31, 30, 2 },
-+	[QCOM_RPM_PM8921_SMPS2] =		{ 118, 33, 31, 2 },
-+	[QCOM_RPM_PM8921_SMPS3] =		{ 120, 35, 32, 2 },
-+	[QCOM_RPM_PM8921_SMPS4] =		{ 122, 37, 33, 2 },
-+	[QCOM_RPM_PM8921_SMPS5] =		{ 124, 39, 34, 2 },
-+	[QCOM_RPM_PM8921_SMPS6] =		{ 126, 41, 35, 2 },
-+	[QCOM_RPM_PM8921_SMPS7] =		{ 128, 43, 36, 2 },
-+	[QCOM_RPM_PM8921_SMPS8] =		{ 130, 45, 37, 2 },
-+	[QCOM_RPM_PM8921_LDO1] =		{ 132, 47, 38, 2 },
-+	[QCOM_RPM_PM8921_LDO2] =		{ 134, 49, 39, 2 },
-+	[QCOM_RPM_PM8921_LDO3] =		{ 136, 51, 40, 2 },
-+	[QCOM_RPM_PM8921_LDO4] =		{ 138, 53, 41, 2 },
-+	[QCOM_RPM_PM8921_LDO5] =		{ 140, 55, 42, 2 },
-+	[QCOM_RPM_PM8921_LDO6] =		{ 142, 57, 43, 2 },
-+	[QCOM_RPM_PM8921_LDO7] =		{ 144, 59, 44, 2 },
-+	[QCOM_RPM_PM8921_LDO8] =		{ 146, 61, 45, 2 },
-+	[QCOM_RPM_PM8921_LDO9] =		{ 148, 63, 46, 2 },
-+	[QCOM_RPM_PM8921_LDO10] =		{ 150, 65, 47, 2 },
-+	[QCOM_RPM_PM8921_LDO11] =		{ 152, 67, 48, 2 },
-+	[QCOM_RPM_PM8921_LDO12] =		{ 154, 69, 49, 2 },
-+	[QCOM_RPM_PM8921_LDO13] =		{ 156, 71, 50, 2 },
-+	[QCOM_RPM_PM8921_LDO14] =		{ 158, 73, 51, 2 },
-+	[QCOM_RPM_PM8921_LDO15] =		{ 160, 75, 52, 2 },
-+	[QCOM_RPM_PM8921_LDO16] =		{ 162, 77, 53, 2 },
-+	[QCOM_RPM_PM8921_LDO17] =		{ 164, 79, 54, 2 },
-+	[QCOM_RPM_PM8921_LDO18] =		{ 166, 81, 55, 2 },
-+	[QCOM_RPM_PM8921_LDO19] =		{ 168, 83, 56, 2 },
-+	[QCOM_RPM_PM8921_LDO20] =		{ 170, 85, 57, 2 },
-+	[QCOM_RPM_PM8921_LDO21] =		{ 172, 87, 58, 2 },
-+	[QCOM_RPM_PM8921_LDO22] =		{ 174, 89, 59, 2 },
-+	[QCOM_RPM_PM8921_LDO23] =		{ 176, 91, 60, 2 },
-+	[QCOM_RPM_PM8921_LDO24] =		{ 178, 93, 61, 2 },
-+	[QCOM_RPM_PM8921_LDO25] =		{ 180, 95, 62, 2 },
-+	[QCOM_RPM_PM8921_LDO26] =		{ 182, 97, 63, 2 },
-+	[QCOM_RPM_PM8921_LDO27] =		{ 184, 99, 64, 2 },
-+	[QCOM_RPM_PM8921_LDO28] =		{ 186, 101, 65, 2 },
-+	[QCOM_RPM_PM8921_LDO29] =		{ 188, 103, 66, 2 },
-+	[QCOM_RPM_PM8921_CLK1] =		{ 190, 105, 67, 2 },
-+	[QCOM_RPM_PM8921_CLK2] =		{ 192, 107, 68, 2 },
-+	[QCOM_RPM_PM8921_LVS1] =		{ 194, 109, 69, 1 },
-+	[QCOM_RPM_PM8921_LVS2] =		{ 195, 110, 70, 1 },
-+	[QCOM_RPM_PM8921_LVS3] =		{ 196, 111, 71, 1 },
-+	[QCOM_RPM_PM8921_LVS4] =		{ 197, 112, 72, 1 },
-+	[QCOM_RPM_PM8921_LVS5] =		{ 198, 113, 73, 1 },
-+	[QCOM_RPM_PM8921_LVS6] =		{ 199, 114, 74, 1 },
-+	[QCOM_RPM_PM8921_LVS7] =		{ 200, 115, 75, 1 },
-+	[QCOM_RPM_PM8821_SMPS1] =		{ 201, 116, 76, 2 },
-+	[QCOM_RPM_PM8821_SMPS2] =		{ 203, 118, 77, 2 },
-+	[QCOM_RPM_PM8821_LDO1] =		{ 205, 120, 78, 2 },
-+	[QCOM_RPM_PM8921_NCP] =			{ 207, 122, 80, 2 },
-+	[QCOM_RPM_CXO_BUFFERS] =		{ 209, 124, 81, 1 },
-+	[QCOM_RPM_USB_OTG_SWITCH] =		{ 210, 125, 82, 1 },
-+	[QCOM_RPM_HDMI_SWITCH] =		{ 211, 126, 83, 1 },
-+	[QCOM_RPM_DDR_DMM] =			{ 212, 127, 84, 2 },
-+	[QCOM_RPM_VDDMIN_GPIO] =		{ 215, 131, 89, 1 },
-+};
-+
-+static const struct qcom_rpm_data apq8064_template = {
-+	.version = 3,
-+	.resource_table = apq8064_rpm_resource_table,
-+	.n_resources = ARRAY_SIZE(apq8064_rpm_resource_table),
-+};
-+
-+static const struct qcom_rpm_resource msm8660_rpm_resource_table[] = {
-+	[QCOM_RPM_CXO_CLK] =			{ 32, 12, 5, 1 },
-+	[QCOM_RPM_PXO_CLK] =			{ 33, 13, 6, 1 },
-+	[QCOM_RPM_PLL_4] =			{ 34, 14, 7, 1 },
-+	[QCOM_RPM_APPS_FABRIC_CLK] =		{ 35, 15, 8, 1 },
-+	[QCOM_RPM_SYS_FABRIC_CLK] =		{ 36, 16, 9, 1 },
-+	[QCOM_RPM_MM_FABRIC_CLK] =		{ 37, 17, 10, 1 },
-+	[QCOM_RPM_DAYTONA_FABRIC_CLK] =		{ 38, 18, 11, 1 },
-+	[QCOM_RPM_SFPB_CLK] =			{ 39, 19, 12, 1 },
-+	[QCOM_RPM_CFPB_CLK] =			{ 40, 20, 13, 1 },
-+	[QCOM_RPM_MMFPB_CLK] =			{ 41, 21, 14, 1 },
-+	[QCOM_RPM_SMI_CLK] =			{ 42, 22, 15, 1 },
-+	[QCOM_RPM_EBI1_CLK] =			{ 43, 23, 16, 1 },
-+	[QCOM_RPM_APPS_L2_CACHE_CTL] =		{ 44, 24, 17, 1 },
-+	[QCOM_RPM_APPS_FABRIC_HALT] =		{ 45, 25, 18, 2 },
-+	[QCOM_RPM_APPS_FABRIC_MODE] =		{ 47, 26, 19, 3 },
-+	[QCOM_RPM_APPS_FABRIC_ARB] =		{ 51, 28, 21, 6 },
-+	[QCOM_RPM_SYS_FABRIC_HALT] =		{ 63, 29, 22, 2 },
-+	[QCOM_RPM_SYS_FABRIC_MODE] =		{ 65, 30, 23, 3 },
-+	[QCOM_RPM_SYS_FABRIC_ARB] =		{ 69, 32, 25, 22 },
-+	[QCOM_RPM_MM_FABRIC_HALT] =		{ 105, 33, 26, 2 },
-+	[QCOM_RPM_MM_FABRIC_MODE] =		{ 107, 34, 27, 3 },
-+	[QCOM_RPM_MM_FABRIC_ARB] =		{ 111, 36, 29, 23 },
-+	[QCOM_RPM_PM8901_SMPS0] =		{ 134, 37, 30, 2 },
-+	[QCOM_RPM_PM8901_SMPS1] =		{ 136, 39, 31, 2 },
-+	[QCOM_RPM_PM8901_SMPS2] =		{ 138, 41, 32, 2 },
-+	[QCOM_RPM_PM8901_SMPS3] =		{ 140, 43, 33, 2 },
-+	[QCOM_RPM_PM8901_SMPS4] =		{ 142, 45, 34, 2 },
-+	[QCOM_RPM_PM8901_LDO0] =		{ 144, 47, 35, 2 },
-+	[QCOM_RPM_PM8901_LDO1] =		{ 146, 49, 36, 2 },
-+	[QCOM_RPM_PM8901_LDO2] =		{ 148, 51, 37, 2 },
-+	[QCOM_RPM_PM8901_LDO3] =		{ 150, 53, 38, 2 },
-+	[QCOM_RPM_PM8901_LDO4] =		{ 152, 55, 39, 2 },
-+	[QCOM_RPM_PM8901_LDO5] =		{ 154, 57, 40, 2 },
-+	[QCOM_RPM_PM8901_LDO6] =		{ 156, 59, 41, 2 },
-+	[QCOM_RPM_PM8901_LVS0] =		{ 158, 61, 42, 1 },
-+	[QCOM_RPM_PM8901_LVS1] =		{ 159, 62, 43, 1 },
-+	[QCOM_RPM_PM8901_LVS2] =		{ 160, 63, 44, 1 },
-+	[QCOM_RPM_PM8901_LVS3] =		{ 161, 64, 45, 1 },
-+	[QCOM_RPM_PM8901_MVS] =			{ 162, 65, 46, 1 },
-+	[QCOM_RPM_PM8058_SMPS0] =		{ 163, 66, 47, 2 },
-+	[QCOM_RPM_PM8058_SMPS1] =		{ 165, 68, 48, 2 },
-+	[QCOM_RPM_PM8058_SMPS2] =		{ 167, 70, 49, 2 },
-+	[QCOM_RPM_PM8058_SMPS3] =		{ 169, 72, 50, 2 },
-+	[QCOM_RPM_PM8058_SMPS4] =		{ 171, 74, 51, 2 },
-+	[QCOM_RPM_PM8058_LDO0] =		{ 173, 76, 52, 2 },
-+	[QCOM_RPM_PM8058_LDO1] =		{ 175, 78, 53, 2 },
-+	[QCOM_RPM_PM8058_LDO2] =		{ 177, 80, 54, 2 },
-+	[QCOM_RPM_PM8058_LDO3] =		{ 179, 82, 55, 2 },
-+	[QCOM_RPM_PM8058_LDO4] =		{ 181, 84, 56, 2 },
-+	[QCOM_RPM_PM8058_LDO5] =		{ 183, 86, 57, 2 },
-+	[QCOM_RPM_PM8058_LDO6] =		{ 185, 88, 58, 2 },
-+	[QCOM_RPM_PM8058_LDO7] =		{ 187, 90, 59, 2 },
-+	[QCOM_RPM_PM8058_LDO8] =		{ 189, 92, 60, 2 },
-+	[QCOM_RPM_PM8058_LDO9] =		{ 191, 94, 61, 2 },
-+	[QCOM_RPM_PM8058_LDO10] =		{ 193, 96, 62, 2 },
-+	[QCOM_RPM_PM8058_LDO11] =		{ 195, 98, 63, 2 },
-+	[QCOM_RPM_PM8058_LDO12] =		{ 197, 100, 64, 2 },
-+	[QCOM_RPM_PM8058_LDO13] =		{ 199, 102, 65, 2 },
-+	[QCOM_RPM_PM8058_LDO14] =		{ 201, 104, 66, 2 },
-+	[QCOM_RPM_PM8058_LDO15] =		{ 203, 106, 67, 2 },
-+	[QCOM_RPM_PM8058_LDO16] =		{ 205, 108, 68, 2 },
-+	[QCOM_RPM_PM8058_LDO17] =		{ 207, 110, 69, 2 },
-+	[QCOM_RPM_PM8058_LDO18] =		{ 209, 112, 70, 2 },
-+	[QCOM_RPM_PM8058_LDO19] =		{ 211, 114, 71, 2 },
-+	[QCOM_RPM_PM8058_LDO20] =		{ 213, 116, 72, 2 },
-+	[QCOM_RPM_PM8058_LDO21] =		{ 215, 118, 73, 2 },
-+	[QCOM_RPM_PM8058_LDO22] =		{ 217, 120, 74, 2 },
-+	[QCOM_RPM_PM8058_LDO23] =		{ 219, 122, 75, 2 },
-+	[QCOM_RPM_PM8058_LDO24] =		{ 221, 124, 76, 2 },
-+	[QCOM_RPM_PM8058_LDO25] =		{ 223, 126, 77, 2 },
-+	[QCOM_RPM_PM8058_LVS0] =		{ 225, 128, 78, 1 },
-+	[QCOM_RPM_PM8058_LVS1] =		{ 226, 129, 79, 1 },
-+	[QCOM_RPM_PM8058_NCP] =			{ 227, 130, 80, 2 },
-+	[QCOM_RPM_CXO_BUFFERS] =		{ 229, 132, 81, 1 },
-+};
-+
-+static const struct qcom_rpm_data msm8660_template = {
-+	.version = 2,
-+	.resource_table = msm8660_rpm_resource_table,
-+	.n_resources = ARRAY_SIZE(msm8660_rpm_resource_table),
-+};
-+
-+static const struct qcom_rpm_resource msm8960_rpm_resource_table[] = {
-+	[QCOM_RPM_CXO_CLK] =			{ 25, 9, 5, 1 },
-+	[QCOM_RPM_PXO_CLK] =			{ 26, 10, 6, 1 },
-+	[QCOM_RPM_APPS_FABRIC_CLK] =		{ 27, 11, 8, 1 },
-+	[QCOM_RPM_SYS_FABRIC_CLK] =		{ 28, 12, 9, 1 },
-+	[QCOM_RPM_MM_FABRIC_CLK] =		{ 29, 13, 10, 1 },
-+	[QCOM_RPM_DAYTONA_FABRIC_CLK] =		{ 30, 14, 11, 1 },
-+	[QCOM_RPM_SFPB_CLK] =			{ 31, 15, 12, 1 },
-+	[QCOM_RPM_CFPB_CLK] =			{ 32, 16, 13, 1 },
-+	[QCOM_RPM_MMFPB_CLK] =			{ 33, 17, 14, 1 },
-+	[QCOM_RPM_EBI1_CLK] =			{ 34, 18, 16, 1 },
-+	[QCOM_RPM_APPS_FABRIC_HALT] =		{ 35, 19, 18, 1 },
-+	[QCOM_RPM_APPS_FABRIC_MODE] =		{ 37, 20, 19, 1 },
-+	[QCOM_RPM_APPS_FABRIC_IOCTL] =		{ 40, 21, 20, 1 },
-+	[QCOM_RPM_APPS_FABRIC_ARB] =		{ 41, 22, 21, 12 },
-+	[QCOM_RPM_SYS_FABRIC_HALT] =		{ 53, 23, 22, 1 },
-+	[QCOM_RPM_SYS_FABRIC_MODE] =		{ 55, 24, 23, 1 },
-+	[QCOM_RPM_SYS_FABRIC_IOCTL] =		{ 58, 25, 24, 1 },
-+	[QCOM_RPM_SYS_FABRIC_ARB] =		{ 59, 26, 25, 29 },
-+	[QCOM_RPM_MM_FABRIC_HALT] =		{ 88, 27, 26, 1 },
-+	[QCOM_RPM_MM_FABRIC_MODE] =		{ 90, 28, 27, 1 },
-+	[QCOM_RPM_MM_FABRIC_IOCTL] =		{ 93, 29, 28, 1 },
-+	[QCOM_RPM_MM_FABRIC_ARB] =		{ 94, 30, 29, 23 },
-+	[QCOM_RPM_PM8921_SMPS1] =		{ 117, 31, 30, 2 },
-+	[QCOM_RPM_PM8921_SMPS2] =		{ 119, 33, 31, 2 },
-+	[QCOM_RPM_PM8921_SMPS3] =		{ 121, 35, 32, 2 },
-+	[QCOM_RPM_PM8921_SMPS4] =		{ 123, 37, 33, 2 },
-+	[QCOM_RPM_PM8921_SMPS5] =		{ 125, 39, 34, 2 },
-+	[QCOM_RPM_PM8921_SMPS6] =		{ 127, 41, 35, 2 },
-+	[QCOM_RPM_PM8921_SMPS7] =		{ 129, 43, 36, 2 },
-+	[QCOM_RPM_PM8921_SMPS8] =		{ 131, 45, 37, 2 },
-+	[QCOM_RPM_PM8921_LDO1] =		{ 133, 47, 38, 2 },
-+	[QCOM_RPM_PM8921_LDO2] =		{ 135, 49, 39, 2 },
-+	[QCOM_RPM_PM8921_LDO3] =		{ 137, 51, 40, 2 },
-+	[QCOM_RPM_PM8921_LDO4] =		{ 139, 53, 41, 2 },
-+	[QCOM_RPM_PM8921_LDO5] =		{ 141, 55, 42, 2 },
-+	[QCOM_RPM_PM8921_LDO6] =		{ 143, 57, 43, 2 },
-+	[QCOM_RPM_PM8921_LDO7] =		{ 145, 59, 44, 2 },
-+	[QCOM_RPM_PM8921_LDO8] =		{ 147, 61, 45, 2 },
-+	[QCOM_RPM_PM8921_LDO9] =		{ 149, 63, 46, 2 },
-+	[QCOM_RPM_PM8921_LDO10] =		{ 151, 65, 47, 2 },
-+	[QCOM_RPM_PM8921_LDO11] =		{ 153, 67, 48, 2 },
-+	[QCOM_RPM_PM8921_LDO12] =		{ 155, 69, 49, 2 },
-+	[QCOM_RPM_PM8921_LDO13] =		{ 157, 71, 50, 2 },
-+	[QCOM_RPM_PM8921_LDO14] =		{ 159, 73, 51, 2 },
-+	[QCOM_RPM_PM8921_LDO15] =		{ 161, 75, 52, 2 },
-+	[QCOM_RPM_PM8921_LDO16] =		{ 163, 77, 53, 2 },
-+	[QCOM_RPM_PM8921_LDO17] =		{ 165, 79, 54, 2 },
-+	[QCOM_RPM_PM8921_LDO18] =		{ 167, 81, 55, 2 },
-+	[QCOM_RPM_PM8921_LDO19] =		{ 169, 83, 56, 2 },
-+	[QCOM_RPM_PM8921_LDO20] =		{ 171, 85, 57, 2 },
-+	[QCOM_RPM_PM8921_LDO21] =		{ 173, 87, 58, 2 },
-+	[QCOM_RPM_PM8921_LDO22] =		{ 175, 89, 59, 2 },
-+	[QCOM_RPM_PM8921_LDO23] =		{ 177, 91, 60, 2 },
-+	[QCOM_RPM_PM8921_LDO24] =		{ 179, 93, 61, 2 },
-+	[QCOM_RPM_PM8921_LDO25] =		{ 181, 95, 62, 2 },
-+	[QCOM_RPM_PM8921_LDO26] =		{ 183, 97, 63, 2 },
-+	[QCOM_RPM_PM8921_LDO27] =		{ 185, 99, 64, 2 },
-+	[QCOM_RPM_PM8921_LDO28] =		{ 187, 101, 65, 2 },
-+	[QCOM_RPM_PM8921_LDO29] =		{ 189, 103, 66, 2 },
-+	[QCOM_RPM_PM8921_CLK1] =		{ 191, 105, 67, 2 },
-+	[QCOM_RPM_PM8921_CLK2] =		{ 193, 107, 68, 2 },
-+	[QCOM_RPM_PM8921_LVS1] =		{ 195, 109, 69, 1 },
-+	[QCOM_RPM_PM8921_LVS2] =		{ 196, 110, 70, 1 },
-+	[QCOM_RPM_PM8921_LVS3] =		{ 197, 111, 71, 1 },
-+	[QCOM_RPM_PM8921_LVS4] =		{ 198, 112, 72, 1 },
-+	[QCOM_RPM_PM8921_LVS5] =		{ 199, 113, 73, 1 },
-+	[QCOM_RPM_PM8921_LVS6] =		{ 200, 114, 74, 1 },
-+	[QCOM_RPM_PM8921_LVS7] =		{ 201, 115, 75, 1 },
-+	[QCOM_RPM_PM8921_NCP] =			{ 202, 116, 80, 2 },
-+	[QCOM_RPM_CXO_BUFFERS] =		{ 204, 118, 81, 1 },
-+	[QCOM_RPM_USB_OTG_SWITCH] =		{ 205, 119, 82, 1 },
-+	[QCOM_RPM_HDMI_SWITCH] =		{ 206, 120, 83, 1 },
-+	[QCOM_RPM_DDR_DMM] =			{ 207, 121, 84, 2 },
-+};
-+
-+static const struct qcom_rpm_data msm8960_template = {
-+	.version = 3,
-+	.resource_table = msm8960_rpm_resource_table,
-+	.n_resources = ARRAY_SIZE(msm8960_rpm_resource_table),
-+};
-+
-+static const struct of_device_id qcom_rpm_of_match[] = {
-+	{ .compatible = "qcom,rpm-apq8064", .data = &apq8064_template },
-+	{ .compatible = "qcom,rpm-msm8660", .data = &msm8660_template },
-+	{ .compatible = "qcom,rpm-msm8960", .data = &msm8960_template },
-+	{ }
-+};
-+MODULE_DEVICE_TABLE(of, qcom_rpm_of_match);
-+
-+int qcom_rpm_write(struct qcom_rpm *rpm,
-+		   int state,
-+		   int resource,
-+		   u32 *buf, size_t count)
-+{
-+	const struct qcom_rpm_resource *res;
-+	const struct qcom_rpm_data *data = rpm->data;
-+	u32 sel_mask[RPM_SELECT_SIZE] = { 0 };
-+	int left;
-+	int ret = 0;
-+	int i;
-+
-+	if (WARN_ON(resource < 0 || resource >= data->n_resources))
-+		return -EINVAL;
-+
-+	res = &data->resource_table[resource];
-+	if (WARN_ON(res->size != count))
-+		return -EINVAL;
-+
-+	mutex_lock(&rpm->lock);
-+
-+	for (i = 0; i < res->size; i++)
-+		writel_relaxed(buf[i], RPM_REQ_REG(rpm, res->target_id + i));
-+
-+	bitmap_set((unsigned long *)sel_mask, res->select_id, 1);
-+	for (i = 0; i < ARRAY_SIZE(sel_mask); i++) {
-+		writel_relaxed(sel_mask[i],
-+			       RPM_CTRL_REG(rpm, RPM_REQ_SELECT + i));
-+	}
-+
-+	writel_relaxed(BIT(state), RPM_CTRL_REG(rpm, RPM_REQUEST_CONTEXT));
-+
-+	reinit_completion(&rpm->ack);
-+	regmap_write(rpm->ipc_regmap, rpm->ipc_offset, BIT(rpm->ipc_bit));
-+
-+	left = wait_for_completion_timeout(&rpm->ack, RPM_REQUEST_TIMEOUT);
-+	if (!left)
-+		ret = -ETIMEDOUT;
-+	else if (rpm->ack_status & RPM_REJECTED)
-+		ret = -EIO;
-+
-+	mutex_unlock(&rpm->lock);
-+
-+	return ret;
-+}
-+EXPORT_SYMBOL(qcom_rpm_write);
-+
-+static irqreturn_t qcom_rpm_ack_interrupt(int irq, void *dev)
-+{
-+	struct qcom_rpm *rpm = dev;
-+	u32 ack;
-+	int i;
-+
-+	ack = readl_relaxed(RPM_CTRL_REG(rpm, RPM_ACK_CONTEXT));
-+	for (i = 0; i < RPM_SELECT_SIZE; i++)
-+		writel_relaxed(0, RPM_CTRL_REG(rpm, RPM_ACK_SELECTOR + i));
-+	writel(0, RPM_CTRL_REG(rpm, RPM_ACK_CONTEXT));
-+
-+	if (ack & RPM_NOTIFICATION) {
-+		dev_warn(rpm->dev, "ignoring notification!\n");
-+	} else {
-+		rpm->ack_status = ack;
-+		complete(&rpm->ack);
-+	}
-+
-+	return IRQ_HANDLED;
-+}
-+
-+static irqreturn_t qcom_rpm_err_interrupt(int irq, void *dev)
-+{
-+	struct qcom_rpm *rpm = dev;
-+
-+	regmap_write(rpm->ipc_regmap, rpm->ipc_offset, BIT(rpm->ipc_bit));
-+	dev_err(rpm->dev, "RPM triggered fatal error\n");
-+
-+	return IRQ_HANDLED;
-+}
-+
-+static irqreturn_t qcom_rpm_wakeup_interrupt(int irq, void *dev)
-+{
-+	return IRQ_HANDLED;
-+}
-+
-+static int qcom_rpm_probe(struct platform_device *pdev)
-+{
-+	const struct of_device_id *match;
-+	struct device_node *syscon_np;
-+	struct resource *res;
-+	struct qcom_rpm *rpm;
-+	u32 fw_version[3];
-+	int irq_wakeup;
-+	int irq_ack;
-+	int irq_err;
-+	int ret;
-+
-+	rpm = devm_kzalloc(&pdev->dev, sizeof(*rpm), GFP_KERNEL);
-+	if (!rpm)
-+		return -ENOMEM;
-+
-+	rpm->dev = &pdev->dev;
-+	mutex_init(&rpm->lock);
-+	init_completion(&rpm->ack);
-+
-+	irq_ack = platform_get_irq_byname(pdev, "ack");
-+	if (irq_ack < 0) {
-+		dev_err(&pdev->dev, "required ack interrupt missing\n");
-+		return irq_ack;
-+	}
-+
-+	irq_err = platform_get_irq_byname(pdev, "err");
-+	if (irq_err < 0) {
-+		dev_err(&pdev->dev, "required err interrupt missing\n");
-+		return irq_err;
-+	}
-+
-+	irq_wakeup = platform_get_irq_byname(pdev, "wakeup");
-+	if (irq_wakeup < 0) {
-+		dev_err(&pdev->dev, "required wakeup interrupt missing\n");
-+		return irq_wakeup;
-+	}
-+
-+	match = of_match_device(qcom_rpm_of_match, &pdev->dev);
-+	rpm->data = match->data;
-+
-+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-+	rpm->status_regs = devm_ioremap_resource(&pdev->dev, res);
-+	if (IS_ERR(rpm->status_regs))
-+		return PTR_ERR(rpm->status_regs);
-+	rpm->ctrl_regs = rpm->status_regs + 0x400;
-+	rpm->req_regs = rpm->status_regs + 0x600;
-+
-+	syscon_np = of_parse_phandle(pdev->dev.of_node, "qcom,ipc", 0);
-+	if (!syscon_np) {
-+		dev_err(&pdev->dev, "no qcom,ipc node\n");
-+		return -ENODEV;
-+	}
-+
-+	rpm->ipc_regmap = syscon_node_to_regmap(syscon_np);
-+	if (IS_ERR(rpm->ipc_regmap))
-+		return PTR_ERR(rpm->ipc_regmap);
-+
-+	ret = of_property_read_u32_index(pdev->dev.of_node, "qcom,ipc", 1,
-+					 &rpm->ipc_offset);
-+	if (ret < 0) {
-+		dev_err(&pdev->dev, "no offset in qcom,ipc\n");
-+		return -EINVAL;
-+	}
-+
-+	ret = of_property_read_u32_index(pdev->dev.of_node, "qcom,ipc", 2,
-+					 &rpm->ipc_bit);
-+	if (ret < 0) {
-+		dev_err(&pdev->dev, "no bit in qcom,ipc\n");
-+		return -EINVAL;
-+	}
-+
-+	dev_set_drvdata(&pdev->dev, rpm);
-+
-+	fw_version[0] = readl(RPM_STATUS_REG(rpm, 0));
-+	fw_version[1] = readl(RPM_STATUS_REG(rpm, 1));
-+	fw_version[2] = readl(RPM_STATUS_REG(rpm, 2));
-+	if (fw_version[0] != rpm->data->version) {
-+		dev_err(&pdev->dev,
-+			"RPM version %u.%u.%u incompatible with driver version %u",
-+			fw_version[0],
-+			fw_version[1],
-+			fw_version[2],
-+			rpm->data->version);
-+		return -EFAULT;
-+	}
-+
-+	dev_info(&pdev->dev, "RPM firmware %u.%u.%u\n", fw_version[0],
-+							fw_version[1],
-+							fw_version[2]);
-+
-+	ret = devm_request_irq(&pdev->dev,
-+			       irq_ack,
-+			       qcom_rpm_ack_interrupt,
-+			       IRQF_TRIGGER_RISING | IRQF_NO_SUSPEND,
-+			       "qcom_rpm_ack",
-+			       rpm);
-+	if (ret) {
-+		dev_err(&pdev->dev, "failed to request ack interrupt\n");
-+		return ret;
-+	}
-+
-+	ret = irq_set_irq_wake(irq_ack, 1);
-+	if (ret)
-+		dev_warn(&pdev->dev, "failed to mark ack irq as wakeup\n");
-+
-+	ret = devm_request_irq(&pdev->dev,
-+			       irq_err,
-+			       qcom_rpm_err_interrupt,
-+			       IRQF_TRIGGER_RISING,
-+			       "qcom_rpm_err",
-+			       rpm);
-+	if (ret) {
-+		dev_err(&pdev->dev, "failed to request err interrupt\n");
-+		return ret;
-+	}
-+
-+	ret = devm_request_irq(&pdev->dev,
-+			       irq_wakeup,
-+			       qcom_rpm_wakeup_interrupt,
-+			       IRQF_TRIGGER_RISING,
-+			       "qcom_rpm_wakeup",
-+			       rpm);
-+	if (ret) {
-+		dev_err(&pdev->dev, "failed to request wakeup interrupt\n");
-+		return ret;
-+	}
-+
-+	ret = irq_set_irq_wake(irq_wakeup, 1);
-+	if (ret)
-+		dev_warn(&pdev->dev, "failed to mark wakeup irq as wakeup\n");
-+
-+	return of_platform_populate(pdev->dev.of_node, NULL, NULL, &pdev->dev);
-+}
-+
-+static int qcom_rpm_remove(struct platform_device *pdev)
-+{
-+	of_platform_depopulate(&pdev->dev);
-+	return 0;
-+}
-+
-+static struct platform_driver qcom_rpm_driver = {
-+	.probe = qcom_rpm_probe,
-+	.remove = qcom_rpm_remove,
-+	.driver  = {
-+		.name  = "qcom_rpm",
-+		.of_match_table = qcom_rpm_of_match,
-+	},
-+};
-+
-+static int __init qcom_rpm_init(void)
-+{
-+	return platform_driver_register(&qcom_rpm_driver);
-+}
-+arch_initcall(qcom_rpm_init);
-+
-+static void __exit qcom_rpm_exit(void)
-+{
-+	platform_driver_unregister(&qcom_rpm_driver);
-+}
-+module_exit(qcom_rpm_exit)
-+
-+MODULE_DESCRIPTION("Qualcomm Resource Power Manager driver");
-+MODULE_LICENSE("GPL v2");
-+MODULE_AUTHOR("Bjorn Andersson <bjorn.andersson@sonymobile.com>");
---- /dev/null
-+++ b/include/linux/mfd/qcom_rpm.h
-@@ -0,0 +1,13 @@
-+#ifndef __QCOM_RPM_H__
-+#define __QCOM_RPM_H__
-+
-+#include <linux/types.h>
-+
-+struct qcom_rpm;
-+
-+#define QCOM_RPM_ACTIVE_STATE	0
-+#define QCOM_RPM_SLEEP_STATE	1
-+
-+int qcom_rpm_write(struct qcom_rpm *rpm, int state, int resource, u32 *buf, size_t count);
-+
-+#endif
diff --git a/target/linux/ipq806x/patches-3.18/121-mfd-qcom_rpm-Add-support-for-IPQ8064.patch b/target/linux/ipq806x/patches-3.18/121-mfd-qcom_rpm-Add-support-for-IPQ8064.patch
deleted file mode 100644
index e5e9e4e6cceef264a6e4414ff7547196caedfa40..0000000000000000000000000000000000000000
--- a/target/linux/ipq806x/patches-3.18/121-mfd-qcom_rpm-Add-support-for-IPQ8064.patch
+++ /dev/null
@@ -1,71 +0,0 @@
-From 4d54b0adfa67476e6509bc8646b9dbac642e8a29 Mon Sep 17 00:00:00 2001
-From: Josh Cartwright <joshc@codeaurora.org>
-Date: Thu, 26 Mar 2015 11:29:26 -0700
-Subject: [PATCH] mfd: qcom_rpm: Add support for IPQ8064
-
-The IPQ8064 also includes an RPM following the same message structure as
-other chips.  In addition, it supports a few new resource types to
-support the NSS fabric clocks and the SMB208/SMB209 regulators found on
-the reference boards.
-
-Signed-off-by: Josh Cartwright <joshc@codeaurora.org>
-Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
-Signed-off-by: Lee Jones <lee.jones@linaro.org>
----
- drivers/mfd/qcom_rpm.c | 41 +++++++++++++++++++++++++++++++++++++++++
- 1 file changed, 41 insertions(+)
-
---- a/drivers/mfd/qcom_rpm.c
-+++ b/drivers/mfd/qcom_rpm.c
-@@ -323,10 +323,51 @@ static const struct qcom_rpm_data msm896
- 	.n_resources = ARRAY_SIZE(msm8960_rpm_resource_table),
- };
- 
-+static const struct qcom_rpm_resource ipq806x_rpm_resource_table[] = {
-+	[QCOM_RPM_CXO_CLK] =			{ 25, 9, 5, 1 },
-+	[QCOM_RPM_PXO_CLK] =			{ 26, 10, 6, 1 },
-+	[QCOM_RPM_APPS_FABRIC_CLK] =		{ 27, 11, 8, 1 },
-+	[QCOM_RPM_SYS_FABRIC_CLK] =		{ 28, 12, 9, 1 },
-+	[QCOM_RPM_NSS_FABRIC_0_CLK] =		{ 29, 13, 10, 1 },
-+	[QCOM_RPM_DAYTONA_FABRIC_CLK] =		{ 30, 14, 11, 1 },
-+	[QCOM_RPM_SFPB_CLK] =			{ 31, 15, 12, 1 },
-+	[QCOM_RPM_CFPB_CLK] =			{ 32, 16, 13, 1 },
-+	[QCOM_RPM_NSS_FABRIC_1_CLK] =		{ 33, 17, 14, 1 },
-+	[QCOM_RPM_EBI1_CLK] =			{ 34, 18, 16, 1 },
-+	[QCOM_RPM_APPS_FABRIC_HALT] =		{ 35, 19, 18, 2 },
-+	[QCOM_RPM_APPS_FABRIC_MODE] =		{ 37, 20, 19, 3 },
-+	[QCOM_RPM_APPS_FABRIC_IOCTL] =		{ 40, 21, 20, 1 },
-+	[QCOM_RPM_APPS_FABRIC_ARB] =		{ 41, 22, 21, 12 },
-+	[QCOM_RPM_SYS_FABRIC_HALT] =		{ 53, 23, 22, 2 },
-+	[QCOM_RPM_SYS_FABRIC_MODE] =		{ 55, 24, 23, 3 },
-+	[QCOM_RPM_SYS_FABRIC_IOCTL] =		{ 58, 25, 24, 1 },
-+	[QCOM_RPM_SYS_FABRIC_ARB] =		{ 59, 26, 25, 30 },
-+	[QCOM_RPM_MM_FABRIC_HALT] =		{ 89, 27, 26, 2 },
-+	[QCOM_RPM_MM_FABRIC_MODE] =		{ 91, 28, 27, 3 },
-+	[QCOM_RPM_MM_FABRIC_IOCTL] =		{ 94, 29, 28, 1 },
-+	[QCOM_RPM_MM_FABRIC_ARB] =		{ 95, 30, 29, 2 },
-+	[QCOM_RPM_CXO_BUFFERS] =		{ 209, 33, 31, 1 },
-+	[QCOM_RPM_USB_OTG_SWITCH] =		{ 210, 34, 32, 1 },
-+	[QCOM_RPM_HDMI_SWITCH] =		{ 211, 35, 33, 1 },
-+	[QCOM_RPM_DDR_DMM] =			{ 212, 36, 34, 2 },
-+	[QCOM_RPM_VDDMIN_GPIO] =		{ 215, 40, 39, 1 },
-+	[QCOM_RPM_SMB208_S1a] =			{ 216, 41, 90, 2 },
-+	[QCOM_RPM_SMB208_S1b] =			{ 218, 43, 91, 2 },
-+	[QCOM_RPM_SMB208_S2a] =			{ 220, 45, 92, 2 },
-+	[QCOM_RPM_SMB208_S2b] =			{ 222, 47, 93, 2 },
-+};
-+
-+static const struct qcom_rpm_data ipq806x_template = {
-+	.version = 3,
-+	.resource_table = ipq806x_rpm_resource_table,
-+	.n_resources = ARRAY_SIZE(ipq806x_rpm_resource_table),
-+};
-+
- static const struct of_device_id qcom_rpm_of_match[] = {
- 	{ .compatible = "qcom,rpm-apq8064", .data = &apq8064_template },
- 	{ .compatible = "qcom,rpm-msm8660", .data = &msm8660_template },
- 	{ .compatible = "qcom,rpm-msm8960", .data = &msm8960_template },
-+	{ .compatible = "qcom,rpm-ipq8064", .data = &ipq806x_template },
- 	{ }
- };
- MODULE_DEVICE_TABLE(of, qcom_rpm_of_match);
diff --git a/target/linux/ipq806x/patches-3.18/122-mfd-devicetree-bindings-Add-Qualcomm-RPM-DT-binding.patch b/target/linux/ipq806x/patches-3.18/122-mfd-devicetree-bindings-Add-Qualcomm-RPM-DT-binding.patch
deleted file mode 100644
index a65d2c51318c916a647309483a273223dbb73d6e..0000000000000000000000000000000000000000
--- a/target/linux/ipq806x/patches-3.18/122-mfd-devicetree-bindings-Add-Qualcomm-RPM-DT-binding.patch
+++ /dev/null
@@ -1,247 +0,0 @@
-From aa0c4b815045420ea54d5ae5362f5a0190609d46 Mon Sep 17 00:00:00 2001
-From: Bjorn Andersson <bjorn.andersson@sonymobile.com>
-Date: Wed, 26 Nov 2014 13:50:59 -0800
-Subject: [PATCH] mfd: devicetree: bindings: Add Qualcomm RPM DT binding
-
-Add binding for the Qualcomm Resource Power Manager (RPM) found in 8660,
-8960 and 8064 based devices.
-
-Signed-off-by: Bjorn Andersson <bjorn.andersson@sonymobile.com>
-Signed-off-by: Lee Jones <lee.jones@linaro.org>
----
- Documentation/devicetree/bindings/mfd/qcom-rpm.txt |  70 ++++++++++
- include/dt-bindings/mfd/qcom-rpm.h                 | 154 +++++++++++++++++++++
- 2 files changed, 224 insertions(+)
- create mode 100644 Documentation/devicetree/bindings/mfd/qcom-rpm.txt
- create mode 100644 include/dt-bindings/mfd/qcom-rpm.h
-
---- /dev/null
-+++ b/Documentation/devicetree/bindings/mfd/qcom-rpm.txt
-@@ -0,0 +1,70 @@
-+Qualcomm Resource Power Manager (RPM)
-+
-+This driver is used to interface with the Resource Power Manager (RPM) found in
-+various Qualcomm platforms. The RPM allows each component in the system to vote
-+for state of the system resources, such as clocks, regulators and bus
-+frequencies.
-+
-+- compatible:
-+	Usage: required
-+	Value type: <string>
-+	Definition: must be one of:
-+		    "qcom,rpm-apq8064"
-+		    "qcom,rpm-msm8660"
-+		    "qcom,rpm-msm8960"
-+
-+- reg:
-+	Usage: required
-+	Value type: <prop-encoded-array>
-+	Definition: base address and size of the RPM's message ram
-+
-+- interrupts:
-+	Usage: required
-+	Value type: <prop-encoded-array>
-+	Definition: three entries specifying the RPM's:
-+		    1. acknowledgement interrupt
-+		    2. error interrupt
-+		    3. wakeup interrupt
-+
-+- interrupt-names:
-+	Usage: required
-+	Value type: <string-array>
-+	Definition: must be the three strings "ack", "err" and "wakeup", in order
-+
-+- #address-cells:
-+	Usage: required
-+	Value type: <u32>
-+	Definition: must be 1
-+
-+- #size-cells:
-+	Usage: required
-+	Value type: <u32>
-+	Definition: must be 0
-+
-+- qcom,ipc:
-+	Usage: required
-+	Value type: <prop-encoded-array>
-+
-+	Definition: three entries specifying the outgoing ipc bit used for
-+		    signaling the RPM:
-+		    - phandle to a syscon node representing the apcs registers
-+		    - u32 representing offset to the register within the syscon
-+		    - u32 representing the ipc bit within the register
-+
-+
-+= EXAMPLE
-+
-+	#include <dt-bindings/mfd/qcom-rpm.h>
-+
-+	rpm@108000 {
-+		compatible = "qcom,rpm-msm8960";
-+		reg = <0x108000 0x1000>;
-+		qcom,ipc = <&apcs 0x8 2>;
-+
-+		interrupts = <0 19 0>, <0 21 0>, <0 22 0>;
-+		interrupt-names = "ack", "err", "wakeup";
-+
-+		#address-cells = <1>;
-+		#size-cells = <0>;
-+	};
-+
---- /dev/null
-+++ b/include/dt-bindings/mfd/qcom-rpm.h
-@@ -0,0 +1,154 @@
-+/*
-+ * This header provides constants for the Qualcomm RPM bindings.
-+ */
-+
-+#ifndef _DT_BINDINGS_MFD_QCOM_RPM_H
-+#define _DT_BINDINGS_MFD_QCOM_RPM_H
-+
-+/*
-+ * Constants use to identify individual resources in the RPM.
-+ */
-+#define QCOM_RPM_APPS_FABRIC_ARB		1
-+#define QCOM_RPM_APPS_FABRIC_CLK		2
-+#define QCOM_RPM_APPS_FABRIC_HALT		3
-+#define QCOM_RPM_APPS_FABRIC_IOCTL		4
-+#define QCOM_RPM_APPS_FABRIC_MODE		5
-+#define QCOM_RPM_APPS_L2_CACHE_CTL		6
-+#define QCOM_RPM_CFPB_CLK			7
-+#define QCOM_RPM_CXO_BUFFERS			8
-+#define QCOM_RPM_CXO_CLK			9
-+#define QCOM_RPM_DAYTONA_FABRIC_CLK		10
-+#define QCOM_RPM_DDR_DMM			11
-+#define QCOM_RPM_EBI1_CLK			12
-+#define QCOM_RPM_HDMI_SWITCH			13
-+#define QCOM_RPM_MMFPB_CLK			14
-+#define QCOM_RPM_MM_FABRIC_ARB			15
-+#define QCOM_RPM_MM_FABRIC_CLK			16
-+#define QCOM_RPM_MM_FABRIC_HALT			17
-+#define QCOM_RPM_MM_FABRIC_IOCTL		18
-+#define QCOM_RPM_MM_FABRIC_MODE			19
-+#define QCOM_RPM_PLL_4				20
-+#define QCOM_RPM_PM8058_LDO0			21
-+#define QCOM_RPM_PM8058_LDO1			22
-+#define QCOM_RPM_PM8058_LDO2			23
-+#define QCOM_RPM_PM8058_LDO3			24
-+#define QCOM_RPM_PM8058_LDO4			25
-+#define QCOM_RPM_PM8058_LDO5			26
-+#define QCOM_RPM_PM8058_LDO6			27
-+#define QCOM_RPM_PM8058_LDO7			28
-+#define QCOM_RPM_PM8058_LDO8			29
-+#define QCOM_RPM_PM8058_LDO9			30
-+#define QCOM_RPM_PM8058_LDO10			31
-+#define QCOM_RPM_PM8058_LDO11			32
-+#define QCOM_RPM_PM8058_LDO12			33
-+#define QCOM_RPM_PM8058_LDO13			34
-+#define QCOM_RPM_PM8058_LDO14			35
-+#define QCOM_RPM_PM8058_LDO15			36
-+#define QCOM_RPM_PM8058_LDO16			37
-+#define QCOM_RPM_PM8058_LDO17			38
-+#define QCOM_RPM_PM8058_LDO18			39
-+#define QCOM_RPM_PM8058_LDO19			40
-+#define QCOM_RPM_PM8058_LDO20			41
-+#define QCOM_RPM_PM8058_LDO21			42
-+#define QCOM_RPM_PM8058_LDO22			43
-+#define QCOM_RPM_PM8058_LDO23			44
-+#define QCOM_RPM_PM8058_LDO24			45
-+#define QCOM_RPM_PM8058_LDO25			46
-+#define QCOM_RPM_PM8058_LVS0			47
-+#define QCOM_RPM_PM8058_LVS1			48
-+#define QCOM_RPM_PM8058_NCP			49
-+#define QCOM_RPM_PM8058_SMPS0			50
-+#define QCOM_RPM_PM8058_SMPS1			51
-+#define QCOM_RPM_PM8058_SMPS2			52
-+#define QCOM_RPM_PM8058_SMPS3			53
-+#define QCOM_RPM_PM8058_SMPS4			54
-+#define QCOM_RPM_PM8821_LDO1			55
-+#define QCOM_RPM_PM8821_SMPS1			56
-+#define QCOM_RPM_PM8821_SMPS2			57
-+#define QCOM_RPM_PM8901_LDO0			58
-+#define QCOM_RPM_PM8901_LDO1			59
-+#define QCOM_RPM_PM8901_LDO2			60
-+#define QCOM_RPM_PM8901_LDO3			61
-+#define QCOM_RPM_PM8901_LDO4			62
-+#define QCOM_RPM_PM8901_LDO5			63
-+#define QCOM_RPM_PM8901_LDO6			64
-+#define QCOM_RPM_PM8901_LVS0			65
-+#define QCOM_RPM_PM8901_LVS1			66
-+#define QCOM_RPM_PM8901_LVS2			67
-+#define QCOM_RPM_PM8901_LVS3			68
-+#define QCOM_RPM_PM8901_MVS			69
-+#define QCOM_RPM_PM8901_SMPS0			70
-+#define QCOM_RPM_PM8901_SMPS1			71
-+#define QCOM_RPM_PM8901_SMPS2			72
-+#define QCOM_RPM_PM8901_SMPS3			73
-+#define QCOM_RPM_PM8901_SMPS4			74
-+#define QCOM_RPM_PM8921_CLK1			75
-+#define QCOM_RPM_PM8921_CLK2			76
-+#define QCOM_RPM_PM8921_LDO1			77
-+#define QCOM_RPM_PM8921_LDO2			78
-+#define QCOM_RPM_PM8921_LDO3			79
-+#define QCOM_RPM_PM8921_LDO4			80
-+#define QCOM_RPM_PM8921_LDO5			81
-+#define QCOM_RPM_PM8921_LDO6			82
-+#define QCOM_RPM_PM8921_LDO7			83
-+#define QCOM_RPM_PM8921_LDO8			84
-+#define QCOM_RPM_PM8921_LDO9			85
-+#define QCOM_RPM_PM8921_LDO10			86
-+#define QCOM_RPM_PM8921_LDO11			87
-+#define QCOM_RPM_PM8921_LDO12			88
-+#define QCOM_RPM_PM8921_LDO13			89
-+#define QCOM_RPM_PM8921_LDO14			90
-+#define QCOM_RPM_PM8921_LDO15			91
-+#define QCOM_RPM_PM8921_LDO16			92
-+#define QCOM_RPM_PM8921_LDO17			93
-+#define QCOM_RPM_PM8921_LDO18			94
-+#define QCOM_RPM_PM8921_LDO19			95
-+#define QCOM_RPM_PM8921_LDO20			96
-+#define QCOM_RPM_PM8921_LDO21			97
-+#define QCOM_RPM_PM8921_LDO22			98
-+#define QCOM_RPM_PM8921_LDO23			99
-+#define QCOM_RPM_PM8921_LDO24			100
-+#define QCOM_RPM_PM8921_LDO25			101
-+#define QCOM_RPM_PM8921_LDO26			102
-+#define QCOM_RPM_PM8921_LDO27			103
-+#define QCOM_RPM_PM8921_LDO28			104
-+#define QCOM_RPM_PM8921_LDO29			105
-+#define QCOM_RPM_PM8921_LVS1			106
-+#define QCOM_RPM_PM8921_LVS2			107
-+#define QCOM_RPM_PM8921_LVS3			108
-+#define QCOM_RPM_PM8921_LVS4			109
-+#define QCOM_RPM_PM8921_LVS5			110
-+#define QCOM_RPM_PM8921_LVS6			111
-+#define QCOM_RPM_PM8921_LVS7			112
-+#define QCOM_RPM_PM8921_MVS			113
-+#define QCOM_RPM_PM8921_NCP			114
-+#define QCOM_RPM_PM8921_SMPS1			115
-+#define QCOM_RPM_PM8921_SMPS2			116
-+#define QCOM_RPM_PM8921_SMPS3			117
-+#define QCOM_RPM_PM8921_SMPS4			118
-+#define QCOM_RPM_PM8921_SMPS5			119
-+#define QCOM_RPM_PM8921_SMPS6			120
-+#define QCOM_RPM_PM8921_SMPS7			121
-+#define QCOM_RPM_PM8921_SMPS8			122
-+#define QCOM_RPM_PXO_CLK			123
-+#define QCOM_RPM_QDSS_CLK			124
-+#define QCOM_RPM_SFPB_CLK			125
-+#define QCOM_RPM_SMI_CLK			126
-+#define QCOM_RPM_SYS_FABRIC_ARB			127
-+#define QCOM_RPM_SYS_FABRIC_CLK			128
-+#define QCOM_RPM_SYS_FABRIC_HALT		129
-+#define QCOM_RPM_SYS_FABRIC_IOCTL		130
-+#define QCOM_RPM_SYS_FABRIC_MODE		131
-+#define QCOM_RPM_USB_OTG_SWITCH			132
-+#define QCOM_RPM_VDDMIN_GPIO			133
-+
-+/*
-+ * Constants used to select force mode for regulators.
-+ */
-+#define QCOM_RPM_FORCE_MODE_NONE		0
-+#define QCOM_RPM_FORCE_MODE_LPM			1
-+#define QCOM_RPM_FORCE_MODE_HPM			2
-+#define QCOM_RPM_FORCE_MODE_AUTO		3
-+#define QCOM_RPM_FORCE_MODE_BYPASS		4
-+
-+#endif
diff --git a/target/linux/ipq806x/patches-3.18/123-mfd-devicetree-qcom_rpm-Document-IPQ8064-resources.patch b/target/linux/ipq806x/patches-3.18/123-mfd-devicetree-qcom_rpm-Document-IPQ8064-resources.patch
deleted file mode 100644
index c8a9f3f5d0850348f5e39ed5f6aa4137599f94fd..0000000000000000000000000000000000000000
--- a/target/linux/ipq806x/patches-3.18/123-mfd-devicetree-qcom_rpm-Document-IPQ8064-resources.patch
+++ /dev/null
@@ -1,42 +0,0 @@
-From 30bc3aa5c4ed3072bdff7d915772df1b91307ed4 Mon Sep 17 00:00:00 2001
-From: Josh Cartwright <joshc@codeaurora.org>
-Date: Thu, 26 Mar 2015 11:29:25 -0700
-Subject: [PATCH] mfd: devicetree: qcom_rpm: Document IPQ8064 resources
-
-The IPQ8064 SoC has several RPM-controlled resources, an NSS fabrick
-clock and four regulator resources.  Provide definitions for them.
-
-Signed-off-by: Josh Cartwright <joshc@codeaurora.org>
-[sboyd@codeaurora.org: Drop regulator part of binding]
-Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
-Signed-off-by: Lee Jones <lee.jones@linaro.org>
----
- Documentation/devicetree/bindings/mfd/qcom-rpm.txt | 1 +
- include/dt-bindings/mfd/qcom-rpm.h                 | 6 ++++++
- 2 files changed, 7 insertions(+)
-
---- a/Documentation/devicetree/bindings/mfd/qcom-rpm.txt
-+++ b/Documentation/devicetree/bindings/mfd/qcom-rpm.txt
-@@ -12,6 +12,7 @@ frequencies.
- 		    "qcom,rpm-apq8064"
- 		    "qcom,rpm-msm8660"
- 		    "qcom,rpm-msm8960"
-+		    "qcom,rpm-ipq8064"
- 
- - reg:
- 	Usage: required
---- a/include/dt-bindings/mfd/qcom-rpm.h
-+++ b/include/dt-bindings/mfd/qcom-rpm.h
-@@ -141,6 +141,12 @@
- #define QCOM_RPM_SYS_FABRIC_MODE		131
- #define QCOM_RPM_USB_OTG_SWITCH			132
- #define QCOM_RPM_VDDMIN_GPIO			133
-+#define QCOM_RPM_NSS_FABRIC_0_CLK		134
-+#define QCOM_RPM_NSS_FABRIC_1_CLK		135
-+#define QCOM_RPM_SMB208_S1a			136
-+#define QCOM_RPM_SMB208_S1b			137
-+#define QCOM_RPM_SMB208_S2a			138
-+#define QCOM_RPM_SMB208_S2b			139
- 
- /*
-  * Constants used to select force mode for regulators.
diff --git a/target/linux/ipq806x/patches-3.18/124-regulator-rpm-add-support-for-RPM-controller-SMB208.patch b/target/linux/ipq806x/patches-3.18/124-regulator-rpm-add-support-for-RPM-controller-SMB208.patch
deleted file mode 100644
index e4f094c2132cc9eca8611d7796dc8e3044768ec6..0000000000000000000000000000000000000000
--- a/target/linux/ipq806x/patches-3.18/124-regulator-rpm-add-support-for-RPM-controller-SMB208.patch
+++ /dev/null
@@ -1,58 +0,0 @@
-From 0f5bb5b5de3b18877373f746bdb85d8ea0efeedf Mon Sep 17 00:00:00 2001
-From: Josh Cartwright <joshc@codeaurora.org>
-Date: Thu, 20 Nov 2014 13:41:25 -0600
-Subject: [PATCH] regulator: rpm: add support for RPM-controller SMB208
-
-The IPQ8064 reference boards make use of SMB208 regulators which are
-controlled by RPM.  Implement support for these regulators in the RPM
-regulator driver.
-
-Signed-off-by: Josh Cartwright <joshc@codeaurora.org>
-Acked-by: Bjorn Andersson <bjorn.andersson@sonymobile.com>
-Signed-off-by: Mark Brown <broonie@kernel.org>
----
- drivers/regulator/qcom_rpm-regulator.c | 19 +++++++++++++++++++
- 1 file changed, 19 insertions(+)
-
---- a/drivers/regulator/qcom_rpm-regulator.c
-+++ b/drivers/regulator/qcom_rpm-regulator.c
-@@ -183,6 +183,13 @@ static const struct regulator_linear_ran
- 	REGULATOR_LINEAR_RANGE(1500000,  64, 100, 50000),
- };
- 
-+static const struct regulator_linear_range smb208_ranges[] = {
-+	REGULATOR_LINEAR_RANGE( 375000,   0,  29, 12500),
-+	REGULATOR_LINEAR_RANGE( 750000,  30,  89, 12500),
-+	REGULATOR_LINEAR_RANGE(1500000,  90, 153, 25000),
-+	REGULATOR_LINEAR_RANGE(3100000, 154, 234, 25000),
-+};
-+
- static const struct regulator_linear_range ncp_ranges[] = {
- 	REGULATOR_LINEAR_RANGE(1500000,   0,  31, 50000),
- };
-@@ -559,6 +566,16 @@ static const struct qcom_rpm_reg pm8921_
- 	.parts = &rpm8960_switch_parts,
- };
- 
-+static const struct qcom_rpm_reg smb208_smps = {
-+	.desc.linear_ranges = smb208_ranges,
-+	.desc.n_linear_ranges = ARRAY_SIZE(smb208_ranges),
-+	.desc.n_voltages = 235,
-+	.desc.ops = &uV_ops,
-+	.parts = &rpm8960_smps_parts,
-+	.supports_force_mode_auto = false,
-+	.supports_force_mode_bypass = false,
-+};
-+
- static const struct of_device_id rpm_of_match[] = {
- 	{ .compatible = "qcom,rpm-pm8058-pldo",     .data = &pm8058_pldo },
- 	{ .compatible = "qcom,rpm-pm8058-nldo",     .data = &pm8058_nldo },
-@@ -578,6 +595,8 @@ static const struct of_device_id rpm_of_
- 	{ .compatible = "qcom,rpm-pm8921-ftsmps",   .data = &pm8921_ftsmps },
- 	{ .compatible = "qcom,rpm-pm8921-ncp",      .data = &pm8921_ncp },
- 	{ .compatible = "qcom,rpm-pm8921-switch",   .data = &pm8921_switch },
-+
-+	{ .compatible = "qcom,rpm-smb208", .data = &smb208_smps },
- 	{ }
- };
- MODULE_DEVICE_TABLE(of, rpm_of_match);
diff --git a/target/linux/ipq806x/patches-3.18/125-regulator-qcom-rpm-Add-missing-state-flag-in-call-to.patch b/target/linux/ipq806x/patches-3.18/125-regulator-qcom-rpm-Add-missing-state-flag-in-call-to.patch
deleted file mode 100644
index 48921a842912ade0971cbd1c0ce042e6f9ed4384..0000000000000000000000000000000000000000
--- a/target/linux/ipq806x/patches-3.18/125-regulator-qcom-rpm-Add-missing-state-flag-in-call-to.patch
+++ /dev/null
@@ -1,25 +0,0 @@
-From 803926825fa4db007437f76654e3e63bafb9b906 Mon Sep 17 00:00:00 2001
-From: Bjorn Andersson <bjorn.andersson@sonymobile.com>
-Date: Wed, 26 Nov 2014 13:51:01 -0800
-Subject: [PATCH] regulator: qcom-rpm: Add missing state flag in call to RPM
-
-This adds the missing state parameter to the call down to the RPM. This
-is currently hard coded to the active state, as that's all we're
-supporting at this moment.
-
-Signed-off-by: Bjorn Andersson <bjorn.andersson@sonymobile.com>
-Signed-off-by: Lee Jones <lee.jones@linaro.org>
----
- drivers/regulator/qcom_rpm-regulator.c | 1 +
- 1 file changed, 1 insertion(+)
-
---- a/drivers/regulator/qcom_rpm-regulator.c
-+++ b/drivers/regulator/qcom_rpm-regulator.c
-@@ -205,6 +205,7 @@ static int rpm_reg_write(struct qcom_rpm
- 	vreg->val[req->word] |= value << req->shift;
- 
- 	return qcom_rpm_write(vreg->rpm,
-+			      QCOM_RPM_ACTIVE_STATE,
- 			      vreg->resource,
- 			      vreg->val,
- 			      vreg->parts->request_len);
diff --git a/target/linux/ipq806x/patches-3.18/126-add-rpm-to-ipq8064-dts.patch b/target/linux/ipq806x/patches-3.18/126-add-rpm-to-ipq8064-dts.patch
deleted file mode 100644
index a40738edb1f026fb1a1c3669c49382f33e964652..0000000000000000000000000000000000000000
--- a/target/linux/ipq806x/patches-3.18/126-add-rpm-to-ipq8064-dts.patch
+++ /dev/null
@@ -1,87 +0,0 @@
---- 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/mfd/qcom-rpm.h>
- #include <dt-bindings/soc/qcom,gsbi.h>
- #include <dt-bindings/reset/qcom,gcc-ipq806x.h>
- #include <dt-bindings/interrupt-controller/arm-gic.h>
-@@ -77,6 +78,63 @@
- 		ranges;
- 		compatible = "simple-bus";
- 
-+		rpm@108000 {
-+			compatible = "qcom,rpm-ipq8064";
-+			reg = <0x108000 0x1000>;
-+			qcom,ipc = <&l2cc 0x8 2>;
-+
-+			interrupts = <0 19 0>,
-+				     <0 21 0>,
-+				     <0 22 0>;
-+			interrupt-names = "ack",
-+					  "err",
-+					  "wakeup";
-+
-+			#address-cells = <1>;
-+			#size-cells = <0>;
-+
-+			smb208_s1a: smb208-s1a {
-+				compatible = "qcom,rpm-smb208";
-+				reg = <QCOM_RPM_SMB208_S1a>;
-+
-+				regulator-min-microvolt = <1050000>;
-+				regulator-max-microvolt = <1150000>;
-+
-+				qcom,switch-mode-frequency = <1200000>;
-+
-+			};
-+
-+			smb208_s1b: smb208-s1b {
-+				compatible = "qcom,rpm-smb208";
-+				reg = <QCOM_RPM_SMB208_S1b>;
-+
-+				regulator-min-microvolt = <1050000>;
-+				regulator-max-microvolt = <1150000>;
-+
-+				qcom,switch-mode-frequency = <1200000>;
-+			};
-+
-+			smb208_s2a: smb208-s2a {
-+				compatible = "qcom,rpm-smb208";
-+				reg = <QCOM_RPM_SMB208_S2a>;
-+
-+				regulator-min-microvolt = < 800000>;
-+				regulator-max-microvolt = <1250000>;
-+
-+				qcom,switch-mode-frequency = <1200000>;
-+			};
-+
-+			smb208_s2b: smb208-s2b {
-+				compatible = "qcom,rpm-smb208";
-+				reg = <QCOM_RPM_SMB208_S2b>;
-+
-+				regulator-min-microvolt = < 800000>;
-+				regulator-max-microvolt = <1250000>;
-+
-+				qcom,switch-mode-frequency = <1200000>;
-+			};
-+		};
-+
- 		qcom_pinmux: pinmux@800000 {
- 			compatible = "qcom,ipq8064-pinctrl";
- 			reg = <0x800000 0x4000>;
-@@ -148,6 +206,12 @@
- 			reg = <0x02098000 0x1000>, <0x02008000 0x1000>;
- 		};
- 
-+		l2cc: clock-controller@2011000 {
-+			compatible = "qcom,kpss-gcc", "syscon";
-+			reg = <0x2011000 0x1000>;
-+			clock-output-names = "acpu_l2_aux";
-+ 		};
-+ 
- 		saw0: regulator@2089000 {
- 			compatible = "qcom,saw2";
- 			reg = <0x02089000 0x1000>, <0x02009000 0x1000>;
diff --git a/target/linux/ipq806x/patches-3.18/130-clk_mux-Fix-set_parent-doing-the-wrong-thing-when-IN.patch b/target/linux/ipq806x/patches-3.18/130-clk_mux-Fix-set_parent-doing-the-wrong-thing-when-IN.patch
deleted file mode 100644
index 29f74b760d358e4b2581ad9df8f7ad0520965e10..0000000000000000000000000000000000000000
--- a/target/linux/ipq806x/patches-3.18/130-clk_mux-Fix-set_parent-doing-the-wrong-thing-when-IN.patch
+++ /dev/null
@@ -1,55 +0,0 @@
-From 6793b3cd5da817c4be218bd8632f07cf4d2b0d26 Mon Sep 17 00:00:00 2001
-From: Hans de Goede <hdegoede@redhat.com>
-Date: Wed, 19 Nov 2014 14:48:59 +0100
-Subject: [PATCH] clk_mux: Fix set_parent doing the wrong thing when INDEX_BIT
- && index >= 3
-
-If CLK_MUX_INDEX_BIT is set, then each bit turns on / off a single parent,
-so theoretically multiple parents could be enabled at the same time, but in
-practice only one bit should ever be 1. So to select parent 0, set
-the register (*) to 0x01, to select parent 1 set it 0x02, parent 2, 0x04,
-parent 3, 0x08, etc.
-
-But the current code does:
-
-                if (mux->flags & CLK_MUX_INDEX_BIT)
-                        index = (1 << ffs(index));
-
-Which means that:
-
-For an input index of 0, ffs returns 0, so we set the register
-to 0x01, ok.
-
-For an input index of 1, ffs returns 1, so we set the register
-to 0x02, ok.
-
-For an input index of 2, ffs returns 2, so we set the register
-to 0x04, ok.
-
-For an input index of 3, ffs returns 1, so we set the register
-to 0x02, not good!
-
-The code should simply be:
-
-                if (mux->flags & CLK_MUX_INDEX_BIT)
-                        index = 1 << index;
-
-Which always does the right thing, this commit fixes this.
-
-Signed-off-by: Hans de Goede <hdegoede@redhat.com>
-Signed-off-by: Michael Turquette <mturquette@linaro.org>
----
- drivers/clk/clk-mux.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/drivers/clk/clk-mux.c
-+++ b/drivers/clk/clk-mux.c
-@@ -77,7 +77,7 @@ static int clk_mux_set_parent(struct clk
- 
- 	else {
- 		if (mux->flags & CLK_MUX_INDEX_BIT)
--			index = (1 << ffs(index));
-+			index = 1 << index;
- 
- 		if (mux->flags & CLK_MUX_INDEX_ONE)
- 			index++;
diff --git a/target/linux/ipq806x/patches-3.18/131-clk-Add-__clk_mux_determine_rate_closest.patch b/target/linux/ipq806x/patches-3.18/131-clk-Add-__clk_mux_determine_rate_closest.patch
deleted file mode 100644
index 18972f353791fb7c381a620a76016422f3442a6a..0000000000000000000000000000000000000000
--- a/target/linux/ipq806x/patches-3.18/131-clk-Add-__clk_mux_determine_rate_closest.patch
+++ /dev/null
@@ -1,120 +0,0 @@
-From 15a02c1f6dd7c2bb150c61d00ffb33f584ff2288 Mon Sep 17 00:00:00 2001
-From: Stephen Boyd <sboyd@codeaurora.org>
-Date: Mon, 19 Jan 2015 18:05:28 -0800
-Subject: [PATCH] clk: Add __clk_mux_determine_rate_closest
-
-Some clock drivers want to find the closest rate on the input of
-a mux instead of a rate that's less than or equal to the desired
-rate. Add a generic mux function to support this.
-
-Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
-Tested-by: Kenneth Westfield <kwestfie@codeaurora.org>
-Signed-off-by: Michael Turquette <mturquette@linaro.org>
----
- drivers/clk/clk.c            | 47 +++++++++++++++++++++++++++++++++++---------
- include/linux/clk-provider.h |  8 +++++++-
- 2 files changed, 45 insertions(+), 10 deletions(-)
-
---- a/drivers/clk/clk.c
-+++ b/drivers/clk/clk.c
-@@ -695,14 +695,20 @@ struct clk *__clk_lookup(const char *nam
- 	return NULL;
- }
- 
--/*
-- * Helper for finding best parent to provide a given frequency. This can be used
-- * directly as a determine_rate callback (e.g. for a mux), or from a more
-- * complex clock that may combine a mux with other operations.
-- */
--long __clk_mux_determine_rate(struct clk_hw *hw, unsigned long rate,
--			      unsigned long *best_parent_rate,
--			      struct clk **best_parent_p)
-+static bool mux_is_better_rate(unsigned long rate, unsigned long now,
-+			   unsigned long best, unsigned long flags)
-+{
-+	if (flags & CLK_MUX_ROUND_CLOSEST)
-+		return abs(now - rate) < abs(best - rate);
-+
-+	return now <= rate && now > best;
-+}
-+
-+static long
-+clk_mux_determine_rate_flags(struct clk_hw *hw, unsigned long rate,
-+			     unsigned long *best_parent_rate,
-+			     struct clk **best_parent_p,
-+			     unsigned long flags)
- {
- 	struct clk *clk = hw->clk, *parent, *best_parent = NULL;
- 	int i, num_parents;
-@@ -730,7 +736,7 @@ long __clk_mux_determine_rate(struct clk
- 			parent_rate = __clk_round_rate(parent, rate);
- 		else
- 			parent_rate = __clk_get_rate(parent);
--		if (parent_rate <= rate && parent_rate > best) {
-+		if (mux_is_better_rate(rate, parent_rate, best, flags)) {
- 			best_parent = parent;
- 			best = parent_rate;
- 		}
-@@ -743,8 +749,31 @@ out:
- 
- 	return best;
- }
-+
-+/*
-+ * Helper for finding best parent to provide a given frequency. This can be used
-+ * directly as a determine_rate callback (e.g. for a mux), or from a more
-+ * complex clock that may combine a mux with other operations.
-+ */
-+long __clk_mux_determine_rate(struct clk_hw *hw, unsigned long rate,
-+			      unsigned long *best_parent_rate,
-+			      struct clk **best_parent_p)
-+{
-+	return clk_mux_determine_rate_flags(hw, rate, best_parent_rate,
-+					    best_parent_p, 0);
-+}
- EXPORT_SYMBOL_GPL(__clk_mux_determine_rate);
- 
-+long __clk_mux_determine_rate_closest(struct clk_hw *hw, unsigned long rate,
-+			      unsigned long *best_parent_rate,
-+			      struct clk **best_parent_p)
-+{
-+	return clk_mux_determine_rate_flags(hw, rate, best_parent_rate,
-+					    best_parent_p,
-+					    CLK_MUX_ROUND_CLOSEST);
-+}
-+EXPORT_SYMBOL_GPL(__clk_mux_determine_rate_closest);
-+
- /***        clk api        ***/
- 
- void __clk_unprepare(struct clk *clk)
---- a/include/linux/clk-provider.h
-+++ b/include/linux/clk-provider.h
-@@ -382,6 +382,8 @@ struct clk *clk_register_divider_table(s
-  *	register, and mask of mux bits are in higher 16-bit of this register.
-  *	While setting the mux bits, higher 16-bit should also be updated to
-  *	indicate changing mux bits.
-+ * CLK_MUX_ROUND_CLOSEST - Use the parent rate that is closest to the desired
-+ *	frequency.
-  */
- struct clk_mux {
- 	struct clk_hw	hw;
-@@ -396,7 +398,8 @@ struct clk_mux {
- #define CLK_MUX_INDEX_ONE		BIT(0)
- #define CLK_MUX_INDEX_BIT		BIT(1)
- #define CLK_MUX_HIWORD_MASK		BIT(2)
--#define CLK_MUX_READ_ONLY	BIT(3) /* mux setting cannot be changed */
-+#define CLK_MUX_READ_ONLY		BIT(3) /* mux can't be changed */
-+#define CLK_MUX_ROUND_CLOSEST		BIT(4)
- 
- extern const struct clk_ops clk_mux_ops;
- extern const struct clk_ops clk_mux_ro_ops;
-@@ -554,6 +557,9 @@ struct clk *__clk_lookup(const char *nam
- long __clk_mux_determine_rate(struct clk_hw *hw, unsigned long rate,
- 			      unsigned long *best_parent_rate,
- 			      struct clk **best_parent_p);
-+long __clk_mux_determine_rate_closest(struct clk_hw *hw, unsigned long rate,
-+			      unsigned long *best_parent_rate,
-+			      struct clk **best_parent_p);
- 
- /*
-  * FIXME clock api without lock protection
diff --git a/target/linux/ipq806x/patches-3.18/132-clk-Add-clk_unregister_-divider-gate-mux-to-close-me.patch b/target/linux/ipq806x/patches-3.18/132-clk-Add-clk_unregister_-divider-gate-mux-to-close-me.patch
deleted file mode 100644
index 790f25d28db2704a892f2b509765b2492b67eb69..0000000000000000000000000000000000000000
--- a/target/linux/ipq806x/patches-3.18/132-clk-Add-clk_unregister_-divider-gate-mux-to-close-me.patch
+++ /dev/null
@@ -1,115 +0,0 @@
-From 4e3c021fb995bcbb5d1f814d00584cb80eb904a8 Mon Sep 17 00:00:00 2001
-From: Krzysztof Kozlowski <k.kozlowski@samsung.com>
-Date: Mon, 5 Jan 2015 10:52:40 +0100
-Subject: [PATCH] clk: Add clk_unregister_{divider, gate, mux} to close memory
- leak
-
-The common clk_register_{divider,gate,mux} functions allocated memory
-for internal data which wasn't freed anywhere. Drivers using these
-helpers could only unregister clocks but the memory would still leak.
-
-Add corresponding unregister functions which will release all resources.
-
-Signed-off-by: Krzysztof Kozlowski <k.kozlowski@samsung.com>
-Reviewed-by: Stephen Boyd <sboyd@codeaurora.org>
-Signed-off-by: Michael Turquette <mturquette@linaro.org>
----
- drivers/clk/clk-divider.c    | 16 ++++++++++++++++
- drivers/clk/clk-gate.c       | 16 ++++++++++++++++
- drivers/clk/clk-mux.c        | 16 ++++++++++++++++
- include/linux/clk-provider.h |  4 ++++
- 4 files changed, 52 insertions(+)
-
---- a/drivers/clk/clk-divider.c
-+++ b/drivers/clk/clk-divider.c
-@@ -461,3 +461,19 @@ struct clk *clk_register_divider_table(s
- 			width, clk_divider_flags, table, lock);
- }
- EXPORT_SYMBOL_GPL(clk_register_divider_table);
-+
-+void clk_unregister_divider(struct clk *clk)
-+{
-+	struct clk_divider *div;
-+	struct clk_hw *hw;
-+
-+	hw = __clk_get_hw(clk);
-+	if (!hw)
-+		return;
-+
-+	div = to_clk_divider(hw);
-+
-+	clk_unregister(clk);
-+	kfree(div);
-+}
-+EXPORT_SYMBOL_GPL(clk_unregister_divider);
---- a/drivers/clk/clk-gate.c
-+++ b/drivers/clk/clk-gate.c
-@@ -162,3 +162,19 @@ struct clk *clk_register_gate(struct dev
- 	return clk;
- }
- EXPORT_SYMBOL_GPL(clk_register_gate);
-+
-+void clk_unregister_gate(struct clk *clk)
-+{
-+	struct clk_gate *gate;
-+	struct clk_hw *hw;
-+
-+	hw = __clk_get_hw(clk);
-+	if (!hw)
-+		return;
-+
-+	gate = to_clk_gate(hw);
-+
-+	clk_unregister(clk);
-+	kfree(gate);
-+}
-+EXPORT_SYMBOL_GPL(clk_unregister_gate);
---- a/drivers/clk/clk-mux.c
-+++ b/drivers/clk/clk-mux.c
-@@ -177,3 +177,19 @@ struct clk *clk_register_mux(struct devi
- 				      NULL, lock);
- }
- EXPORT_SYMBOL_GPL(clk_register_mux);
-+
-+void clk_unregister_mux(struct clk *clk)
-+{
-+	struct clk_mux *mux;
-+	struct clk_hw *hw;
-+
-+	hw = __clk_get_hw(clk);
-+	if (!hw)
-+		return;
-+
-+	mux = to_clk_mux(hw);
-+
-+	clk_unregister(clk);
-+	kfree(mux);
-+}
-+EXPORT_SYMBOL_GPL(clk_unregister_mux);
---- a/include/linux/clk-provider.h
-+++ b/include/linux/clk-provider.h
-@@ -294,6 +294,7 @@ struct clk *clk_register_gate(struct dev
- 		const char *parent_name, unsigned long flags,
- 		void __iomem *reg, u8 bit_idx,
- 		u8 clk_gate_flags, spinlock_t *lock);
-+void clk_unregister_gate(struct clk *clk);
- 
- struct clk_div_table {
- 	unsigned int	val;
-@@ -361,6 +362,7 @@ struct clk *clk_register_divider_table(s
- 		void __iomem *reg, u8 shift, u8 width,
- 		u8 clk_divider_flags, const struct clk_div_table *table,
- 		spinlock_t *lock);
-+void clk_unregister_divider(struct clk *clk);
- 
- /**
-  * struct clk_mux - multiplexer clock
-@@ -414,6 +416,8 @@ struct clk *clk_register_mux_table(struc
- 		void __iomem *reg, u8 shift, u32 mask,
- 		u8 clk_mux_flags, u32 *table, spinlock_t *lock);
- 
-+void clk_unregister_mux(struct clk *clk);
-+
- void of_fixed_factor_clk_setup(struct device_node *node);
- 
- /**
diff --git a/target/linux/ipq806x/patches-3.18/133-ARM-Add-Krait-L2-register-accessor-functions.patch b/target/linux/ipq806x/patches-3.18/133-ARM-Add-Krait-L2-register-accessor-functions.patch
deleted file mode 100644
index 36a92c858aeb669bd84e202c59ef715686ef65ba..0000000000000000000000000000000000000000
--- a/target/linux/ipq806x/patches-3.18/133-ARM-Add-Krait-L2-register-accessor-functions.patch
+++ /dev/null
@@ -1,144 +0,0 @@
-Content-Type: text/plain; charset="utf-8"
-MIME-Version: 1.0
-Content-Transfer-Encoding: 7bit
-Subject: [v3,01/13] ARM: Add Krait L2 register accessor functions
-From: Stephen Boyd <sboyd@codeaurora.org>
-X-Patchwork-Id: 6063051
-Message-Id: <1426920332-9340-2-git-send-email-sboyd@codeaurora.org>
-To: Mike Turquette <mturquette@linaro.org>, Stephen Boyd <sboyd@codeaurora.org>
-Cc: linux-kernel@vger.kernel.org, linux-arm-msm@vger.kernel.org,
-	linux-pm@vger.kernel.org, linux-arm-kernel@lists.infradead.org,
-	Viresh Kumar <viresh.kumar@linaro.org>,
-	Mark Rutland <mark.rutland@arm.com>, Russell King <linux@arm.linux.org.uk>,
-	Courtney Cavin <courtney.cavin@sonymobile.com>
-Date: Fri, 20 Mar 2015 23:45:20 -0700
-
-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-3.18/134-clk-mux-Split-out-register-accessors-for-reuse.patch b/target/linux/ipq806x/patches-3.18/134-clk-mux-Split-out-register-accessors-for-reuse.patch
deleted file mode 100644
index 50022e6107dbf9207d65d2f12ef8cd836f113bb8..0000000000000000000000000000000000000000
--- a/target/linux/ipq806x/patches-3.18/134-clk-mux-Split-out-register-accessors-for-reuse.patch
+++ /dev/null
@@ -1,192 +0,0 @@
-Content-Type: text/plain; charset="utf-8"
-MIME-Version: 1.0
-Content-Transfer-Encoding: 7bit
-Subject: [v3,02/13] clk: mux: Split out register accessors for reuse
-From: Stephen Boyd <sboyd@codeaurora.org>
-X-Patchwork-Id: 6063111
-Message-Id: <1426920332-9340-3-git-send-email-sboyd@codeaurora.org>
-To: Mike Turquette <mturquette@linaro.org>, Stephen Boyd <sboyd@codeaurora.org>
-Cc: linux-kernel@vger.kernel.org, linux-arm-msm@vger.kernel.org,
-	linux-pm@vger.kernel.org, linux-arm-kernel@lists.infradead.org,
-	Viresh Kumar <viresh.kumar@linaro.org>
-Date: Fri, 20 Mar 2015 23:45:21 -0700
-
-We want to reuse the logic in clk-mux.c for other clock drivers
-that don't use readl as register accessors. Fortunately, there
-really isn't much to the mux code besides the table indirection
-and quirk flags if you assume any bit shifting and masking has
-been done already. Pull that logic out into reusable functions
-that operate on an optional table and some flags so that other
-drivers can use the same logic.
-
-Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
-
----
-drivers/clk/clk-mux.c        | 76 +++++++++++++++++++++++++++-----------------
- include/linux/clk-provider.h |  9 ++++--
- 2 files changed, 54 insertions(+), 31 deletions(-)
-
---- a/drivers/clk/clk-mux.c
-+++ b/drivers/clk/clk-mux.c
-@@ -29,35 +29,24 @@
- 
- #define to_clk_mux(_hw) container_of(_hw, struct clk_mux, hw)
- 
--static u8 clk_mux_get_parent(struct clk_hw *hw)
-+unsigned int clk_mux_get_parent(struct clk_hw *hw, unsigned int val,
-+				unsigned int *table, unsigned long flags)
- {
--	struct clk_mux *mux = to_clk_mux(hw);
- 	int num_parents = __clk_get_num_parents(hw->clk);
--	u32 val;
- 
--	/*
--	 * FIXME need a mux-specific flag to determine if val is bitwise or numeric
--	 * e.g. sys_clkin_ck's clksel field is 3 bits wide, but ranges from 0x1
--	 * to 0x7 (index starts at one)
--	 * OTOH, pmd_trace_clk_mux_ck uses a separate bit for each clock, so
--	 * val = 0x4 really means "bit 2, index starts at bit 0"
--	 */
--	val = clk_readl(mux->reg) >> mux->shift;
--	val &= mux->mask;
--
--	if (mux->table) {
-+	if (table) {
- 		int i;
- 
- 		for (i = 0; i < num_parents; i++)
--			if (mux->table[i] == val)
-+			if (table[i] == val)
- 				return i;
- 		return -EINVAL;
- 	}
- 
--	if (val && (mux->flags & CLK_MUX_INDEX_BIT))
-+	if (val && (flags & CLK_MUX_INDEX_BIT))
- 		val = ffs(val) - 1;
- 
--	if (val && (mux->flags & CLK_MUX_INDEX_ONE))
-+	if (val && (flags & CLK_MUX_INDEX_ONE))
- 		val--;
- 
- 	if (val >= num_parents)
-@@ -65,24 +54,53 @@ static u8 clk_mux_get_parent(struct clk_
- 
- 	return val;
- }
-+EXPORT_SYMBOL_GPL(clk_mux_get_parent);
- 
--static int clk_mux_set_parent(struct clk_hw *hw, u8 index)
-+static u8 _clk_mux_get_parent(struct clk_hw *hw)
- {
- 	struct clk_mux *mux = to_clk_mux(hw);
- 	u32 val;
--	unsigned long flags = 0;
- 
--	if (mux->table)
--		index = mux->table[index];
-+	/*
-+	 * FIXME need a mux-specific flag to determine if val is bitwise or numeric
-+	 * e.g. sys_clkin_ck's clksel field is 3 bits wide, but ranges from 0x1
-+	 * to 0x7 (index starts at one)
-+	 * OTOH, pmd_trace_clk_mux_ck uses a separate bit for each clock, so
-+	 * val = 0x4 really means "bit 2, index starts at bit 0"
-+	 */
-+	val = clk_readl(mux->reg) >> mux->shift;
-+	val &= mux->mask;
-+
-+	return clk_mux_get_parent(hw, val, mux->table, mux->flags);
-+}
- 
--	else {
--		if (mux->flags & CLK_MUX_INDEX_BIT)
--			index = 1 << index;
-+unsigned int clk_mux_reindex(u8 index, unsigned int *table,
-+			     unsigned long flags)
-+{
-+	unsigned int val = index;
- 
--		if (mux->flags & CLK_MUX_INDEX_ONE)
--			index++;
-+	if (table) {
-+		val = table[val];
-+	} else {
-+		if (flags & CLK_MUX_INDEX_BIT)
-+			val = 1 << index;
-+
-+		if (flags & CLK_MUX_INDEX_ONE)
-+			val++;
- 	}
- 
-+	return val;
-+}
-+EXPORT_SYMBOL_GPL(clk_mux_reindex);
-+
-+static int clk_mux_set_parent(struct clk_hw *hw, u8 index)
-+{
-+	struct clk_mux *mux = to_clk_mux(hw);
-+	u32 val;
-+	unsigned long flags = 0;
-+
-+	index = clk_mux_reindex(index, mux->table, mux->flags);
-+
- 	if (mux->lock)
- 		spin_lock_irqsave(mux->lock, flags);
- 
-@@ -102,21 +120,21 @@ static int clk_mux_set_parent(struct clk
- }
- 
- const struct clk_ops clk_mux_ops = {
--	.get_parent = clk_mux_get_parent,
-+	.get_parent = _clk_mux_get_parent,
- 	.set_parent = clk_mux_set_parent,
- 	.determine_rate = __clk_mux_determine_rate,
- };
- EXPORT_SYMBOL_GPL(clk_mux_ops);
- 
- const struct clk_ops clk_mux_ro_ops = {
--	.get_parent = clk_mux_get_parent,
-+	.get_parent = _clk_mux_get_parent,
- };
- EXPORT_SYMBOL_GPL(clk_mux_ro_ops);
- 
- struct clk *clk_register_mux_table(struct device *dev, const char *name,
- 		const char **parent_names, u8 num_parents, unsigned long flags,
- 		void __iomem *reg, u8 shift, u32 mask,
--		u8 clk_mux_flags, u32 *table, spinlock_t *lock)
-+		u8 clk_mux_flags, unsigned int *table, spinlock_t *lock)
- {
- 	struct clk_mux *mux;
- 	struct clk *clk;
---- a/include/linux/clk-provider.h
-+++ b/include/linux/clk-provider.h
-@@ -390,7 +390,7 @@ void clk_unregister_divider(struct clk *
- struct clk_mux {
- 	struct clk_hw	hw;
- 	void __iomem	*reg;
--	u32		*table;
-+	unsigned int	*table;
- 	u32		mask;
- 	u8		shift;
- 	u8		flags;
-@@ -406,6 +406,11 @@ struct clk_mux {
- extern const struct clk_ops clk_mux_ops;
- extern const struct clk_ops clk_mux_ro_ops;
- 
-+unsigned int clk_mux_get_parent(struct clk_hw *hw, unsigned int val,
-+				unsigned int *table, unsigned long flags);
-+unsigned int clk_mux_reindex(u8 index, unsigned int *table,
-+			     unsigned long flags);
-+
- struct clk *clk_register_mux(struct device *dev, const char *name,
- 		const char **parent_names, u8 num_parents, unsigned long flags,
- 		void __iomem *reg, u8 shift, u8 width,
-@@ -414,7 +419,7 @@ struct clk *clk_register_mux(struct devi
- struct clk *clk_register_mux_table(struct device *dev, const char *name,
- 		const char **parent_names, u8 num_parents, unsigned long flags,
- 		void __iomem *reg, u8 shift, u32 mask,
--		u8 clk_mux_flags, u32 *table, spinlock_t *lock);
-+		u8 clk_mux_flags, unsigned int *table, spinlock_t *lock);
- 
- void clk_unregister_mux(struct clk *clk);
- 
diff --git a/target/linux/ipq806x/patches-3.18/135-clk-Avoid-sending-high-rates-to-downstream-clocks-during-set_rate.patch b/target/linux/ipq806x/patches-3.18/135-clk-Avoid-sending-high-rates-to-downstream-clocks-during-set_rate.patch
deleted file mode 100644
index 02d96ad08af3b6488c54ec039372071a1f840bcc..0000000000000000000000000000000000000000
--- a/target/linux/ipq806x/patches-3.18/135-clk-Avoid-sending-high-rates-to-downstream-clocks-during-set_rate.patch
+++ /dev/null
@@ -1,129 +0,0 @@
-Content-Type: text/plain; charset="utf-8"
-MIME-Version: 1.0
-Content-Transfer-Encoding: 7bit
-Subject: [v3, 03/13] clk: Avoid sending high rates to downstream clocks during
-	set_rate
-From: Stephen Boyd <sboyd@codeaurora.org>
-X-Patchwork-Id: 6063271
-Message-Id: <1426920332-9340-4-git-send-email-sboyd@codeaurora.org>
-To: Mike Turquette <mturquette@linaro.org>, Stephen Boyd <sboyd@codeaurora.org>
-Cc: linux-kernel@vger.kernel.org, linux-arm-msm@vger.kernel.org,
-	linux-pm@vger.kernel.org, linux-arm-kernel@lists.infradead.org,
-	Viresh Kumar <viresh.kumar@linaro.org>
-Date: Fri, 20 Mar 2015 23:45:22 -0700
-
-If a clock is on and we call clk_set_rate() on it we may get into
-a situation where the clock temporarily increases in rate
-dramatically while we walk the tree and call .set_rate() ops. For
-example, consider a case where a PLL feeds into a divider.
-Initially the divider is set to divide by 1 and the PLL is
-running fairly slow (100MHz). The downstream consumer of the
-divider output can only handle rates =< 400 MHz, but the divider
-can only choose between divisors of 1 and 4.
-
- +-----+   +----------------+
- | PLL |-->| div 1 or div 4 |---> consumer device
- +-----+   +----------------+
-
-To achieve a rate of 400MHz on the output of the divider, we
-would have to set the rate of the PLL to 1.6 GHz and then divide
-it by 4. The current code would set the PLL to 1.6GHz first while
-the divider is still set to 1, thus causing the downstream
-consumer of the clock to receive a few clock cycles of 1.6GHz
-clock (far beyond it's maximum acceptable rate). We should be
-changing the divider first before increasing the PLL rate to
-avoid this problem.
-
-Therefore, set the rate of any child clocks that are increasing
-in rate from their current rate so that they can increase their
-dividers if necessary. We assume that there isn't such a thing as
-minimum rate requirements.
-
-Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
-
----
-drivers/clk/clk.c | 34 ++++++++++++++++++++++------------
- 1 file changed, 22 insertions(+), 12 deletions(-)
-
---- a/drivers/clk/clk.c
-+++ b/drivers/clk/clk.c
-@@ -1476,21 +1476,23 @@ static struct clk *clk_propagate_rate_ch
-  * walk down a subtree and set the new rates notifying the rate
-  * change on the way
-  */
--static void clk_change_rate(struct clk *clk)
-+static void clk_change_rate(struct clk *clk, unsigned long best_parent_rate)
- {
- 	struct clk *child;
- 	struct hlist_node *tmp;
- 	unsigned long old_rate;
--	unsigned long best_parent_rate = 0;
- 	bool skip_set_rate = false;
- 	struct clk *old_parent;
- 
--	old_rate = clk->rate;
-+	hlist_for_each_entry(child, &clk->children, child_node) {
-+		/* Skip children who will be reparented to another clock */
-+		if (child->new_parent && child->new_parent != clk)
-+			continue;
-+		if (child->new_rate > child->rate)
-+			clk_change_rate(child, clk->new_rate);
-+	}
- 
--	if (clk->new_parent)
--		best_parent_rate = clk->new_parent->rate;
--	else if (clk->parent)
--		best_parent_rate = clk->parent->rate;
-+	old_rate = clk->rate;
- 
- 	if (clk->new_parent && clk->new_parent != clk->parent) {
- 		old_parent = __clk_set_parent_before(clk, clk->new_parent);
-@@ -1510,7 +1512,7 @@ static void clk_change_rate(struct clk *
- 	if (!skip_set_rate && clk->ops->set_rate)
- 		clk->ops->set_rate(clk->hw, clk->new_rate, best_parent_rate);
- 
--	clk->rate = clk_recalc(clk, best_parent_rate);
-+	clk->rate = clk->new_rate;
- 
- 	if (clk->notifier_count && old_rate != clk->rate)
- 		__clk_notify(clk, POST_RATE_CHANGE, old_rate, clk->rate);
-@@ -1523,12 +1525,13 @@ static void clk_change_rate(struct clk *
- 		/* Skip children who will be reparented to another clock */
- 		if (child->new_parent && child->new_parent != clk)
- 			continue;
--		clk_change_rate(child);
-+		if (child->new_rate != child->rate)
-+			clk_change_rate(child, clk->new_rate);
- 	}
- 
- 	/* handle the new child who might not be in clk->children yet */
--	if (clk->new_child)
--		clk_change_rate(clk->new_child);
-+	if (clk->new_child && clk->new_child->new_rate != clk->new_child->rate)
-+		clk_change_rate(clk->new_child, clk->new_rate);
- }
- 
- /**
-@@ -1556,6 +1559,7 @@ int clk_set_rate(struct clk *clk, unsign
- {
- 	struct clk *top, *fail_clk;
- 	int ret = 0;
-+	unsigned long parent_rate;
- 
- 	if (!clk)
- 		return 0;
-@@ -1589,8 +1593,13 @@ int clk_set_rate(struct clk *clk, unsign
- 		goto out;
- 	}
- 
-+	if (top->parent)
-+		parent_rate = top->parent->rate;
-+	else
-+		parent_rate = 0;
-+
- 	/* change the rates */
--	clk_change_rate(top);
-+	clk_change_rate(top, parent_rate);
- 
- out:
- 	clk_prepare_unlock();
diff --git a/target/linux/ipq806x/patches-3.18/136-clk-Add-safe-switch-hook.patch b/target/linux/ipq806x/patches-3.18/136-clk-Add-safe-switch-hook.patch
deleted file mode 100644
index 227f8cea05c1f3a0fe97a3bd1ac1f84c6aa0ea99..0000000000000000000000000000000000000000
--- a/target/linux/ipq806x/patches-3.18/136-clk-Add-safe-switch-hook.patch
+++ /dev/null
@@ -1,170 +0,0 @@
-Content-Type: text/plain; charset="utf-8"
-MIME-Version: 1.0
-Content-Transfer-Encoding: 7bit
-Subject: [v3,04/13] clk: Add safe switch hook
-From: Stephen Boyd <sboyd@codeaurora.org>
-X-Patchwork-Id: 6063211
-Message-Id: <1426920332-9340-5-git-send-email-sboyd@codeaurora.org>
-To: Mike Turquette <mturquette@linaro.org>, Stephen Boyd <sboyd@codeaurora.org>
-Cc: linux-kernel@vger.kernel.org, linux-arm-msm@vger.kernel.org,
-	linux-pm@vger.kernel.org, linux-arm-kernel@lists.infradead.org,
-	Viresh Kumar <viresh.kumar@linaro.org>
-Date: Fri, 20 Mar 2015 23:45:23 -0700
-
-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>
-
----
-This patch is good enough for Krait, but soon I'll need to 
-support a "safe rate" where we ask a clock what rate it needs to be running
-at to be sure it's within voltage constraints. Right now safe parent
-handles that problem on Krait, but on other platforms it won't work.
-
- drivers/clk/clk.c            | 61 ++++++++++++++++++++++++++++++++++++++------
- include/linux/clk-provider.h |  1 +
- 2 files changed, 54 insertions(+), 8 deletions(-)
-
---- a/drivers/clk/clk.c
-+++ b/drivers/clk/clk.c
-@@ -1350,7 +1350,8 @@ out:
- static void clk_calc_subtree(struct clk *clk, unsigned long new_rate,
- 			     struct clk *new_parent, u8 p_index)
- {
--	struct clk *child;
-+	struct clk *child, *parent;
-+	struct clk_hw *parent_hw;
- 
- 	clk->new_rate = new_rate;
- 	clk->new_parent = new_parent;
-@@ -1360,6 +1361,18 @@ 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_hw = clk->ops->get_safe_parent(clk->hw);
-+		if (parent_hw) {
-+			parent = parent_hw->clk;
-+			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) {
- 		child->new_rate = clk_recalc(child, new_rate);
- 		clk_calc_subtree(child, child->new_rate, NULL, 0);
-@@ -1439,17 +1452,47 @@ out:
-  * so that in case of an error we can walk down the whole tree again and
-  * abort the change.
-  */
--static struct clk *clk_propagate_rate_change(struct clk *clk, unsigned long event)
-+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);
-+		clk->old_rate = clk->rate;
-+		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 || clk->old_rate != clk->rate)
-+			ret = __clk_notify(clk, event, clk->old_rate,
-+					   clk->new_rate);
-+		if (ret & NOTIFY_STOP_MASK && event != POST_RATE_CHANGE)
- 			fail_clk = clk;
- 	}
- 
-@@ -1494,7 +1537,8 @@ static void clk_change_rate(struct clk *
- 
- 	old_rate = clk->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) {
-@@ -1514,9 +1558,6 @@ static void clk_change_rate(struct clk *
- 
- 	clk->rate = clk->new_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.
-@@ -1601,6 +1642,8 @@ int clk_set_rate(struct clk *clk, unsign
- 	/* change the rates */
- 	clk_change_rate(top, parent_rate);
- 
-+	clk_propagate_rate_change(top, POST_RATE_CHANGE);
-+
- out:
- 	clk_prepare_unlock();
- 
---- a/include/linux/clk-provider.h
-+++ b/include/linux/clk-provider.h
-@@ -179,6 +179,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_hw	*(*get_safe_parent)(struct clk_hw *hw);
- 	int		(*set_rate)(struct clk_hw *hw, unsigned long rate,
- 				    unsigned long parent_rate);
- 	int		(*set_rate_and_parent)(struct clk_hw *hw,
---- a/include/linux/clk-private.h
-+++ b/include/linux/clk-private.h
-@@ -38,8 +38,11 @@ struct clk {
- 	struct clk		**parents;
- 	u8			num_parents;
- 	u8			new_parent_index;
-+	u8			safe_parent_index;
- 	unsigned long		rate;
-+	unsigned long		old_rate;
- 	unsigned long		new_rate;
-+	struct clk		*safe_parent;
- 	struct clk		*new_parent;
- 	struct clk		*new_child;
- 	unsigned long		flags;
diff --git a/target/linux/ipq806x/patches-3.18/137-clk-qcom-Add-support-for-High-Frequency-PLLs-HFPLLs.patch b/target/linux/ipq806x/patches-3.18/137-clk-qcom-Add-support-for-High-Frequency-PLLs-HFPLLs.patch
deleted file mode 100644
index 701d5e70460926cf879c02444bfe53ad48816e31..0000000000000000000000000000000000000000
--- a/target/linux/ipq806x/patches-3.18/137-clk-qcom-Add-support-for-High-Frequency-PLLs-HFPLLs.patch
+++ /dev/null
@@ -1,351 +0,0 @@
-Content-Type: text/plain; charset="utf-8"
-MIME-Version: 1.0
-Content-Transfer-Encoding: 7bit
-Subject: [v3,05/13] clk: qcom: Add support for High-Frequency PLLs (HFPLLs)
-From: Stephen Boyd <sboyd@codeaurora.org>
-X-Patchwork-Id: 6063261
-Message-Id: <1426920332-9340-6-git-send-email-sboyd@codeaurora.org>
-To: Mike Turquette <mturquette@linaro.org>, Stephen Boyd <sboyd@codeaurora.org>
-Cc: linux-kernel@vger.kernel.org, linux-arm-msm@vger.kernel.org,
-	linux-pm@vger.kernel.org, linux-arm-kernel@lists.infradead.org,
-	Viresh Kumar <viresh.kumar@linaro.org>
-Date: Fri, 20 Mar 2015 23:45:24 -0700
-
-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>
-
----
-I'd really like to get rid of __clk_hfpll_init_once() if possible...
-
- drivers/clk/qcom/Makefile    |   1 +
- drivers/clk/qcom/clk-hfpll.c | 253 +++++++++++++++++++++++++++++++++++++++++++
- drivers/clk/qcom/clk-hfpll.h |  54 +++++++++
- 3 files changed, 308 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
-@@ -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-hfpll.o
- clk-qcom-y += reset.o
- 
- obj-$(CONFIG_APQ_GCC_8084) += gcc-apq8084.o
---- /dev/null
-+++ b/drivers/clk/qcom/clk-hfpll.c
-@@ -0,0 +1,253 @@
-+/*
-+ * 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/export.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.
-+	 */
-+	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 {
-+		udelay(60);
-+	}
-+
-+	/* Enable PLL output. */
-+	regmap_update_bits(regmap, hd->mode_reg, PLL_OUTCTRL, PLL_OUTCTRL);
-+}
-+
-+/* 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_hfpll *h)
-+{
-+	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(h);
-+	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(h);
-+
-+	/* 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-3.18/138-clk-qcom-Add-HFPLL-driver.patch b/target/linux/ipq806x/patches-3.18/138-clk-qcom-Add-HFPLL-driver.patch
deleted file mode 100644
index a0b1d64dc6130cade3102f19cf6178ba79386013..0000000000000000000000000000000000000000
--- a/target/linux/ipq806x/patches-3.18/138-clk-qcom-Add-HFPLL-driver.patch
+++ /dev/null
@@ -1,206 +0,0 @@
-Content-Type: text/plain; charset="utf-8"
-MIME-Version: 1.0
-Content-Transfer-Encoding: 7bit
-Subject: [v3,06/13] clk: qcom: Add HFPLL driver
-From: Stephen Boyd <sboyd@codeaurora.org>
-X-Patchwork-Id: 6063231
-Message-Id: <1426920332-9340-7-git-send-email-sboyd@codeaurora.org>
-To: Mike Turquette <mturquette@linaro.org>, Stephen Boyd <sboyd@codeaurora.org>
-Cc: linux-kernel@vger.kernel.org, linux-arm-msm@vger.kernel.org,
-	linux-pm@vger.kernel.org, linux-arm-kernel@lists.infradead.org,
-	Viresh Kumar <viresh.kumar@linaro.org>, <devicetree@vger.kernel.org>
-Date: Fri, 20 Mar 2015 23:45:25 -0700
-
-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.
-
-Cc: <devicetree@vger.kernel.org>
-Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
-
----
-.../devicetree/bindings/clock/qcom,hfpll.txt       |  40 ++++++++
- drivers/clk/qcom/Kconfig                           |   8 ++
- drivers/clk/qcom/Makefile                          |   1 +
- drivers/clk/qcom/hfpll.c                           | 109 +++++++++++++++++++++
- 4 files changed, 158 insertions(+)
- create mode 100644 Documentation/devicetree/bindings/clock/qcom,hfpll.txt
- create mode 100644 drivers/clk/qcom/hfpll.c
-
---- /dev/null
-+++ b/Documentation/devicetree/bindings/clock/qcom,hfpll.txt
-@@ -0,0 +1,40 @@
-+High-Frequency PLL (HFPLL)
-+
-+PROPERTIES
-+
-+- compatible:
-+	Usage: required
-+	Value type: <string>
-+	Definition: must be "qcom,hfpll"
-+
-+- reg:
-+	Usage: required
-+	Value type: <prop-encoded-array>
-+	Definition: address and size of HPLL registers. An optional second
-+		    element specifies the address and size of the alias
-+		    register region.
-+
-+- clock-output-names:
-+	Usage: required
-+	Value type: <string>
-+	Definition: Name of the PLL. Typically hfpllX where X is a CPU number
-+		    starting at 0. Otherwise hfpll_Y where Y is more specific
-+		    such as "l2".
-+
-+Example:
-+
-+1) An HFPLL for the L2 cache.
-+
-+	clock-controller@f9016000 {
-+		compatible = "qcom,hfpll";
-+		reg = <0xf9016000 0x30>;
-+		clock-output-names = "hfpll_l2";
-+	};
-+
-+2) An HFPLL for CPU0. This HFPLL has the alias register region.
-+
-+	clock-controller@f908a000 {
-+		compatible = "qcom,hfpll";
-+		reg = <0xf908a000 0x30>, <0xf900a000 0x30>;
-+		clock-output-names = "hfpll0";
-+	};
---- a/drivers/clk/qcom/Kconfig
-+++ b/drivers/clk/qcom/Kconfig
-@@ -70,3 +70,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
-@@ -17,3 +17,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,109 @@
-+/*
-+ * 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 const 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",
-+		.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-3.18/139-clk-qcom-Add-IPQ806X-s-HFPLLs.patch b/target/linux/ipq806x/patches-3.18/139-clk-qcom-Add-IPQ806X-s-HFPLLs.patch
deleted file mode 100644
index 7fd53d1d9c184242b7ede8f8ee38b11aa162f9e4..0000000000000000000000000000000000000000
--- a/target/linux/ipq806x/patches-3.18/139-clk-qcom-Add-IPQ806X-s-HFPLLs.patch
+++ /dev/null
@@ -1,127 +0,0 @@
-Content-Type: text/plain; charset="utf-8"
-MIME-Version: 1.0
-Content-Transfer-Encoding: 7bit
-Subject: [v3,08/13] clk: qcom: Add IPQ806X's HFPLLs
-From: Stephen Boyd <sboyd@codeaurora.org>
-X-Patchwork-Id: 6063241
-Message-Id: <1426920332-9340-9-git-send-email-sboyd@codeaurora.org>
-To: Mike Turquette <mturquette@linaro.org>, Stephen Boyd <sboyd@codeaurora.org>
-Cc: linux-kernel@vger.kernel.org, linux-arm-msm@vger.kernel.org,
-	linux-pm@vger.kernel.org, linux-arm-kernel@lists.infradead.org,
-	Viresh Kumar <viresh.kumar@linaro.org>
-Date: Fri, 20 Mar 2015 23:45:27 -0700
-
-Describe the HFPLLs present on IPQ806X devices.
-
-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,
-@@ -2261,6 +2341,9 @@ 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,
-+	[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-3.18/140-clk-qcom-Add-support-for-Krait-clocks.patch b/target/linux/ipq806x/patches-3.18/140-clk-qcom-Add-support-for-Krait-clocks.patch
deleted file mode 100644
index 63292e86114c4668263e46119724493630ee323e..0000000000000000000000000000000000000000
--- a/target/linux/ipq806x/patches-3.18/140-clk-qcom-Add-support-for-Krait-clocks.patch
+++ /dev/null
@@ -1,271 +0,0 @@
-Content-Type: text/plain; charset="utf-8"
-MIME-Version: 1.0
-Content-Transfer-Encoding: 7bit
-Subject: [v3,09/13] clk: qcom: Add support for Krait clocks
-From: Stephen Boyd <sboyd@codeaurora.org>
-X-Patchwork-Id: 6063251
-Message-Id: <1426920332-9340-10-git-send-email-sboyd@codeaurora.org>
-To: Mike Turquette <mturquette@linaro.org>, Stephen Boyd <sboyd@codeaurora.org>
-Cc: linux-kernel@vger.kernel.org, linux-arm-msm@vger.kernel.org,
-	linux-pm@vger.kernel.org, linux-arm-kernel@lists.infradead.org,
-	Viresh Kumar <viresh.kumar@linaro.org>
-Date: Fri, 20 Mar 2015 23:45:28 -0700
-
-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 | 166 +++++++++++++++++++++++++++++++++++++++++++
- drivers/clk/qcom/clk-krait.h |  49 +++++++++++++
- 4 files changed, 220 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
-@@ -78,3 +78,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
-@@ -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-$(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,166 @@
-+/*
-+ * 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(krait_clock_reg_lock);
-+
-+#define LPL_SHIFT	8
-+static void __krait_mux_set_sel(struct krait_mux_clk *mux, int sel)
-+{
-+	unsigned long flags;
-+	u32 regval;
-+
-+	spin_lock_irqsave(&krait_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->lpl) {
-+		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(&krait_clock_reg_lock, flags);
-+
-+	/* Wait for switch to complete. */
-+	mb();
-+	udelay(1);
-+}
-+
-+static int krait_mux_set_parent(struct clk_hw *hw, u8 index)
-+{
-+	struct krait_mux_clk *mux = to_krait_mux_clk(hw);
-+	u32 sel;
-+
-+	sel = clk_mux_reindex(index, mux->parent_map, 0);
-+	mux->en_mask = sel;
-+	/* Don't touch mux if CPU is off as it won't work */
-+	if (__clk_is_enabled(hw->clk))
-+		__krait_mux_set_sel(mux, sel);
-+	return 0;
-+}
-+
-+static u8 krait_mux_get_parent(struct clk_hw *hw)
-+{
-+	struct krait_mux_clk *mux = to_krait_mux_clk(hw);
-+	u32 sel;
-+
-+	sel = krait_get_l2_indirect_reg(mux->offset);
-+	sel >>= mux->shift;
-+	sel &= mux->mask;
-+	mux->en_mask = sel;
-+
-+	return clk_mux_get_parent(hw, sel, mux->parent_map, 0);
-+}
-+
-+static struct clk_hw *krait_mux_get_safe_parent(struct clk_hw *hw)
-+{
-+	int i;
-+	struct krait_mux_clk *mux = to_krait_mux_clk(hw);
-+	int num_parents = __clk_get_num_parents(hw->clk);
-+
-+	i = mux->safe_sel;
-+	for (i = 0; i < num_parents; i++)
-+		if (mux->safe_sel == mux->parent_map[i])
-+			break;
-+
-+	return __clk_get_hw(clk_get_parent_by_index(hw->clk, i));
-+}
-+
-+static int krait_mux_enable(struct clk_hw *hw)
-+{
-+	struct krait_mux_clk *mux = to_krait_mux_clk(hw);
-+
-+	__krait_mux_set_sel(mux, mux->en_mask);
-+
-+	return 0;
-+}
-+
-+static void krait_mux_disable(struct clk_hw *hw)
-+{
-+	struct krait_mux_clk *mux = to_krait_mux_clk(hw);
-+
-+	__krait_mux_set_sel(mux, mux->safe_sel);
-+}
-+
-+const struct clk_ops krait_mux_clk_ops = {
-+	.enable = krait_mux_enable,
-+	.disable = krait_mux_disable,
-+	.set_parent = krait_mux_set_parent,
-+	.get_parent = krait_mux_get_parent,
-+	.determine_rate = __clk_mux_determine_rate_closest,
-+	.get_safe_parent = krait_mux_get_safe_parent,
-+};
-+EXPORT_SYMBOL_GPL(krait_mux_clk_ops);
-+
-+/* The divider can divide by 2, 4, 6 and 8. But we only really need div-2. */
-+static long krait_div2_round_rate(struct clk_hw *hw, unsigned long rate,
-+				  unsigned long *parent_rate)
-+{
-+	*parent_rate = __clk_round_rate(__clk_get_parent(hw->clk), rate * 2);
-+	return DIV_ROUND_UP(*parent_rate, 2);
-+}
-+
-+static int krait_div2_set_rate(struct clk_hw *hw, unsigned long rate,
-+			unsigned long parent_rate)
-+{
-+	struct krait_div2_clk *d = to_krait_div2_clk(hw);
-+	unsigned long flags;
-+	u32 val;
-+	u32 mask = BIT(d->width) - 1;
-+
-+	if (d->lpl)
-+		mask = mask << (d->shift + LPL_SHIFT) | mask << d->shift;
-+
-+	spin_lock_irqsave(&krait_clock_reg_lock, flags);
-+	val = krait_get_l2_indirect_reg(d->offset);
-+	val &= ~mask;
-+	krait_set_l2_indirect_reg(d->offset, val);
-+	spin_unlock_irqrestore(&krait_clock_reg_lock, flags);
-+
-+	return 0;
-+}
-+
-+static unsigned long
-+krait_div2_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)
-+{
-+	struct krait_div2_clk *d = to_krait_div2_clk(hw);
-+	u32 mask = BIT(d->width) - 1;
-+	u32 div;
-+
-+	div = krait_get_l2_indirect_reg(d->offset);
-+	div >>= d->shift;
-+	div &= mask;
-+	div = (div + 1) * 2;
-+
-+	return DIV_ROUND_UP(parent_rate, div);
-+}
-+
-+const struct clk_ops krait_div2_clk_ops = {
-+	.round_rate = krait_div2_round_rate,
-+	.set_rate = krait_div2_set_rate,
-+	.recalc_rate = krait_div2_recalc_rate,
-+};
-+EXPORT_SYMBOL_GPL(krait_div2_clk_ops);
---- /dev/null
-+++ b/drivers/clk/qcom/clk-krait.h
-@@ -0,0 +1,49 @@
-+/*
-+ * 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 __QCOM_CLK_KRAIT_H
-+#define __QCOM_CLK_KRAIT_H
-+
-+#include <linux/clk-provider.h>
-+
-+struct krait_mux_clk {
-+	unsigned int	*parent_map;
-+	bool		has_safe_parent;
-+	u8		safe_sel;
-+	u32		offset;
-+	u32		mask;
-+	u32		shift;
-+	u32		en_mask;
-+	bool		lpl;
-+
-+	struct clk_hw	hw;
-+};
-+
-+#define to_krait_mux_clk(_hw) container_of(_hw, struct krait_mux_clk, hw)
-+
-+extern const struct clk_ops krait_mux_clk_ops;
-+
-+struct krait_div2_clk {
-+	u32		offset;
-+	u8		width;
-+	u32		shift;
-+	bool		lpl;
-+
-+	struct clk_hw	hw;
-+};
-+
-+#define to_krait_div2_clk(_hw) container_of(_hw, struct krait_div2_clk, hw)
-+
-+extern const struct clk_ops krait_div2_clk_ops;
-+
-+#endif
diff --git a/target/linux/ipq806x/patches-3.18/141-clk-qcom-Add-KPSS-ACC-GCC-driver.patch b/target/linux/ipq806x/patches-3.18/141-clk-qcom-Add-KPSS-ACC-GCC-driver.patch
deleted file mode 100644
index 06b14d8b5332bb2a92f00463fc1d1c0bddb0c607..0000000000000000000000000000000000000000
--- a/target/linux/ipq806x/patches-3.18/141-clk-qcom-Add-KPSS-ACC-GCC-driver.patch
+++ /dev/null
@@ -1,205 +0,0 @@
-Content-Type: text/plain; charset="utf-8"
-MIME-Version: 1.0
-Content-Transfer-Encoding: 7bit
-Subject: [v3,10/13] clk: qcom: Add KPSS ACC/GCC driver
-From: Stephen Boyd <sboyd@codeaurora.org>
-X-Patchwork-Id: 6063201
-Message-Id: <1426920332-9340-11-git-send-email-sboyd@codeaurora.org>
-To: Mike Turquette <mturquette@linaro.org>, Stephen Boyd <sboyd@codeaurora.org>
-Cc: linux-kernel@vger.kernel.org, linux-arm-msm@vger.kernel.org,
-	linux-pm@vger.kernel.org, linux-arm-kernel@lists.infradead.org,
-	Viresh Kumar <viresh.kumar@linaro.org>, <devicetree@vger.kernel.org>
-Date: Fri, 20 Mar 2015 23:45:29 -0700
-
-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.
-
-Cc: <devicetree@vger.kernel.org>
-Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
-
----
-.../devicetree/bindings/arm/msm/qcom,kpss-acc.txt  |  7 ++
- .../devicetree/bindings/arm/msm/qcom,kpss-gcc.txt  | 28 +++++++
- drivers/clk/qcom/Kconfig                           |  8 ++
- drivers/clk/qcom/Makefile                          |  1 +
- drivers/clk/qcom/kpss-xcc.c                        | 95 ++++++++++++++++++++++
- 5 files changed, 139 insertions(+)
- create mode 100644 Documentation/devicetree/bindings/arm/msm/qcom,kpss-gcc.txt
- create mode 100644 drivers/clk/qcom/kpss-xcc.c
-
---- a/Documentation/devicetree/bindings/arm/msm/qcom,kpss-acc.txt
-+++ b/Documentation/devicetree/bindings/arm/msm/qcom,kpss-acc.txt
-@@ -21,10 +21,17 @@ PROPERTIES
- 		    the register region. An optional second element specifies
- 		    the base address and size of the alias register region.
- 
-+- clock-output-names:
-+	Usage: optional
-+	Value type: <string>
-+	Definition: Name of the output clock. Typically acpuX_aux where X is a
-+		    CPU number starting at 0.
-+
- Example:
- 
- 	clock-controller@2088000 {
- 		compatible = "qcom,kpss-acc-v2";
- 		reg = <0x02088000 0x1000>,
- 		      <0x02008000 0x1000>;
-+		clock-output-names = "acpu0_aux";
- 	};
---- /dev/null
-+++ b/Documentation/devicetree/bindings/arm/msm/qcom,kpss-gcc.txt
-@@ -0,0 +1,28 @@
-+Krait Processor Sub-system (KPSS) Global Clock Controller (GCC)
-+
-+PROPERTIES
-+
-+- compatible:
-+	Usage: required
-+	Value type: <string>
-+	Definition: should be one of:
-+			"qcom,kpss-gcc"
-+
-+- reg:
-+	Usage: required
-+	Value type: <prop-encoded-array>
-+	Definition: base address and size of the register region
-+
-+- clock-output-names:
-+	Usage: required
-+	Value type: <string>
-+	Definition: Name of the output clock. Typically acpu_l2_aux indicating
-+		    an L2 cache auxiliary clock.
-+
-+Example:
-+
-+	l2cc: clock-controller@2011000 {
-+		compatible = "qcom,kpss-gcc";
-+		reg = <0x2011000 0x1000>;
-+		clock-output-names = "acpu_l2_aux";
-+	};
---- a/drivers/clk/qcom/Kconfig
-+++ b/drivers/clk/qcom/Kconfig
-@@ -79,6 +79,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
-@@ -18,4 +18,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,95 @@
-+/* Copyright (c) 2014-2015, 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>
-+
-+static const char *aux_parents[] = {
-+	"pll8_vote",
-+	"pxo",
-+};
-+
-+static unsigned int 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;
-+	const char *name;
-+
-+	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);
-+
-+	if (id->data) {
-+		if (of_property_read_string_index(pdev->dev.of_node,
-+					"clock-output-names", 0, &name))
-+			return -ENODEV;
-+		base += 0x14;
-+	} else {
-+		name = "acpu_l2_aux";
-+		base += 0x28;
-+	}
-+
-+	clk = clk_register_mux_table(&pdev->dev, name, aux_parents,
-+				     ARRAY_SIZE(aux_parents), 0, base, 0, 0x3,
-+				     0, aux_parent_map, NULL);
-+
-+	platform_set_drvdata(pdev, clk);
-+
-+	return PTR_ERR_OR_ZERO(clk);
-+}
-+
-+static int kpss_xcc_driver_remove(struct platform_device *pdev)
-+{
-+	clk_unregister_mux(platform_get_drvdata(pdev));
-+	return 0;
-+}
-+
-+static struct platform_driver kpss_xcc_driver = {
-+	.probe = kpss_xcc_driver_probe,
-+	.remove = kpss_xcc_driver_remove,
-+	.driver = {
-+		.name = "kpss-xcc",
-+		.of_match_table = kpss_xcc_match_table,
-+	},
-+};
-+module_platform_driver(kpss_xcc_driver);
-+
-+MODULE_DESCRIPTION("Krait Processor Sub System (KPSS) Clock Driver");
-+MODULE_LICENSE("GPL v2");
-+MODULE_ALIAS("platform:kpss-xcc");
diff --git a/target/linux/ipq806x/patches-3.18/142-clk-qcom-Add-Krait-clock-controller-driver.patch b/target/linux/ipq806x/patches-3.18/142-clk-qcom-Add-Krait-clock-controller-driver.patch
deleted file mode 100644
index 98a09ac08e45c34642bc43b6688ae8e0734f62a6..0000000000000000000000000000000000000000
--- a/target/linux/ipq806x/patches-3.18/142-clk-qcom-Add-Krait-clock-controller-driver.patch
+++ /dev/null
@@ -1,435 +0,0 @@
-Content-Type: text/plain; charset="utf-8"
-MIME-Version: 1.0
-Content-Transfer-Encoding: 7bit
-Subject: [v3,11/13] clk: qcom: Add Krait clock controller driver
-From: Stephen Boyd <sboyd@codeaurora.org>
-X-Patchwork-Id: 6063121
-Message-Id: <1426920332-9340-12-git-send-email-sboyd@codeaurora.org>
-To: Mike Turquette <mturquette@linaro.org>, Stephen Boyd <sboyd@codeaurora.org>
-Cc: linux-kernel@vger.kernel.org, linux-arm-msm@vger.kernel.org,
-	linux-pm@vger.kernel.org, linux-arm-kernel@lists.infradead.org,
-	Viresh Kumar <viresh.kumar@linaro.org>, <devicetree@vger.kernel.org>
-Date: Fri, 20 Mar 2015 23:45:30 -0700
-
-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.
-
-Cc: <devicetree@vger.kernel.org>
-Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
-
----
-.../devicetree/bindings/clock/qcom,krait-cc.txt    |  22 ++
- drivers/clk/qcom/Kconfig                           |   8 +
- drivers/clk/qcom/Makefile                          |   1 +
- drivers/clk/qcom/krait-cc.c                        | 352 +++++++++++++++++++++
- 4 files changed, 383 insertions(+)
- create mode 100644 Documentation/devicetree/bindings/clock/qcom,krait-cc.txt
- create mode 100644 drivers/clk/qcom/krait-cc.c
-
---- /dev/null
-+++ b/Documentation/devicetree/bindings/clock/qcom,krait-cc.txt
-@@ -0,0 +1,22 @@
-+Krait Clock Controller
-+
-+PROPERTIES
-+
-+- compatible:
-+	Usage: required
-+	Value type: <string>
-+	Definition: must be one of:
-+			"qcom,krait-cc-v1"
-+			"qcom,krait-cc-v2"
-+
-+- #clock-cells:
-+	Usage: required
-+	Value type: <u32>
-+	Definition: must be 1
-+
-+Example:
-+
-+	kraitcc: clock-controller {
-+		compatible = "qcom,krait-cc-v1";
-+		#clock-cells = <1>;
-+	};
---- a/drivers/clk/qcom/Kconfig
-+++ b/drivers/clk/qcom/Kconfig
-@@ -87,6 +87,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
-@@ -20,3 +20,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,352 @@
-+/* Copyright (c) 2013-2015, 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 "clk-krait.h"
-+
-+static unsigned int sec_mux_map[] = {
-+	2,
-+	0,
-+};
-+
-+static unsigned int pri_mux_map[] = {
-+	1,
-+	2,
-+	0,
-+};
-+
-+static int
-+krait_add_div(struct device *dev, int id, const char *s, unsigned offset)
-+{
-+	struct krait_div2_clk *div;
-+	struct clk_init_data init = {
-+		.num_parents = 1,
-+		.ops = &krait_div2_clk_ops,
-+		.flags = CLK_SET_RATE_PARENT,
-+	};
-+	const char *p_names[1];
-+	struct clk *clk;
-+
-+	div = devm_kzalloc(dev, sizeof(*div), GFP_KERNEL);
-+	if (!div)
-+		return -ENOMEM;
-+
-+	div->width = 2;
-+	div->shift = 6;
-+	div->lpl = 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 krait_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 = &krait_mux_clk_ops,
-+		.flags = CLK_SET_RATE_PARENT,
-+	};
-+	struct clk *clk;
-+
-+	mux = devm_kzalloc(dev, sizeof(*mux), GFP_KERNEL);
-+	if (!mux)
-+		return -ENOMEM;
-+
-+	mux->offset = offset;
-+	mux->lpl = id >= 0;
-+	mux->has_safe_parent = true;
-+	mux->safe_sel = 2;
-+	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 krait_mux_clk *mux;
-+	const char *p_names[3];
-+	struct clk_init_data init = {
-+		.parent_names = p_names,
-+		.num_parents = ARRAY_SIZE(p_names),
-+		.ops = &krait_mux_clk_ops,
-+		.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->mask = 0x3;
-+	mux->shift = 0;
-+	mux->offset = offset;
-+	mux->lpl = 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 cpu;
-+	struct clk *clk;
-+	struct clk **clks;
-+	struct clk *l2_pri_mux_clk;
-+
-+	id = of_match_device(krait_cc_match_table, 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 = clk_register_fixed_factor(dev, "acpu_aux",
-+						"gpll0_vote", 0, 1, 2);
-+		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(cpu) {
-+		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(cpu) {
-+		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(cpu) {
-+		clk = clks[cpu];
-+		cur_rate = clk_get_rate(clk);
-+		if (cur_rate == 1) {
-+			pr_info("CPU%d @ QSB rate. Forcing new rate.\n", cpu);
-+			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", cpu, 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 = "krait-cc",
-+		.of_match_table = krait_cc_match_table,
-+	},
-+};
-+module_platform_driver(krait_cc_driver);
-+
-+MODULE_DESCRIPTION("Krait CPU Clock Driver");
-+MODULE_LICENSE("GPL v2");
-+MODULE_ALIAS("platform:krait-cc");
diff --git a/target/linux/ipq806x/patches-3.18/143-cpufreq-Add-module-to-register-cpufreq-on-Krait-CPUs.patch b/target/linux/ipq806x/patches-3.18/143-cpufreq-Add-module-to-register-cpufreq-on-Krait-CPUs.patch
deleted file mode 100644
index c3ca9b5f7049937814d407c0816d99abb8f3e03e..0000000000000000000000000000000000000000
--- a/target/linux/ipq806x/patches-3.18/143-cpufreq-Add-module-to-register-cpufreq-on-Krait-CPUs.patch
+++ /dev/null
@@ -1,304 +0,0 @@
-Content-Type: text/plain; charset="utf-8"
-MIME-Version: 1.0
-Content-Transfer-Encoding: 7bit
-Subject: [v3,12/13] cpufreq: Add module to register cpufreq on Krait CPUs
-From: Stephen Boyd <sboyd@codeaurora.org>
-X-Patchwork-Id: 6063191
-Message-Id: <1426920332-9340-13-git-send-email-sboyd@codeaurora.org>
-To: Mike Turquette <mturquette@linaro.org>, Stephen Boyd <sboyd@codeaurora.org>
-Cc: linux-kernel@vger.kernel.org, linux-arm-msm@vger.kernel.org,
-	linux-pm@vger.kernel.org, linux-arm-kernel@lists.infradead.org,
-	Viresh Kumar <viresh.kumar@linaro.org>, <devicetree@vger.kernel.org>
-Date: Fri, 20 Mar 2015 23:45:31 -0700
-
-Register a cpufreq-generic device whenever we detect that a
-"qcom,krait" compatible CPU is present in DT.
-
-Cc: <devicetree@vger.kernel.org>
-Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
-
----
-.../devicetree/bindings/arm/msm/qcom,pvs.txt       |  38 ++++
- drivers/cpufreq/Kconfig.arm                        |   9 +
- drivers/cpufreq/Makefile                           |   1 +
- drivers/cpufreq/qcom-cpufreq.c                     | 204 +++++++++++++++++++++
- 4 files changed, 252 insertions(+)
- create mode 100644 Documentation/devicetree/bindings/arm/msm/qcom,pvs.txt
- create mode 100644 drivers/cpufreq/qcom-cpufreq.c
-
---- /dev/null
-+++ b/Documentation/devicetree/bindings/arm/msm/qcom,pvs.txt
-@@ -0,0 +1,38 @@
-+Qualcomm Process Voltage Scaling Tables
-+
-+The node name is required to be "qcom,pvs". There shall only be one
-+such node present in the root of the tree.
-+
-+PROPERTIES
-+
-+- qcom,pvs-format-a or qcom,pvs-format-b:
-+	Usage: required
-+	Value type: <empty>
-+	Definition: Indicates the format of qcom,speedX-pvsY-bin-vZ properties.
-+		    If qcom,pvs-format-a is used the table is two columns
-+		    (frequency and voltage in that order). If qcom,pvs-format-b 		    is used the table is three columns (frequency, voltage,
-+		    and current in that order).
-+
-+- qcom,speedX-pvsY-bin-vZ:
-+	Usage: required
-+	Value type: <prop-encoded-array>
-+	Definition: The PVS table corresponding to the speed bin X, pvs bin Y,
-+		    and version Z.
-+Example:
-+
-+	qcom,pvs {
-+		qcom,pvs-format-a;
-+		qcom,speed0-pvs0-bin-v0 =
-+			<  384000000  950000 >,
-+			<  486000000  975000 >,
-+			<  594000000 1000000 >,
-+			<  702000000 1025000 >,
-+			<  810000000 1075000 >,
-+			<  918000000 1100000 >,
-+			< 1026000000 1125000 >,
-+			< 1134000000 1175000 >,
-+			< 1242000000 1200000 >,
-+			< 1350000000 1225000 >,
-+			< 1458000000 1237500 >,
-+			< 1512000000 1250000 >;
-+	};
---- a/drivers/cpufreq/Kconfig.arm
-+++ b/drivers/cpufreq/Kconfig.arm
-@@ -129,6 +129,15 @@ config ARM_OMAP2PLUS_CPUFREQ
- 	depends on ARCH_OMAP2PLUS
- 	default ARCH_OMAP2PLUS
- 
-+config ARM_QCOM_CPUFREQ
-+	tristate "Qualcomm based"
-+	depends on ARCH_QCOM
-+	select PM_OPP
-+	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
-@@ -64,6 +64,7 @@ obj-$(CONFIG_ARM_OMAP2PLUS_CPUFREQ)	+= o
- obj-$(CONFIG_PXA25x)			+= pxa2xx-cpufreq.o
- obj-$(CONFIG_PXA27x)			+= pxa2xx-cpufreq.o
- obj-$(CONFIG_PXA3xx)			+= pxa3xx-cpufreq.o
-+obj-$(CONFIG_ARM_QCOM_CPUFREQ)		+= qcom-cpufreq.o
- obj-$(CONFIG_ARM_S3C24XX_CPUFREQ)	+= s3c24xx-cpufreq.o
- obj-$(CONFIG_ARM_S3C24XX_CPUFREQ_DEBUGFS) += s3c24xx-cpufreq-debugfs.o
- obj-$(CONFIG_ARM_S3C2410_CPUFREQ)	+= s3c2410-cpufreq.o
---- /dev/null
-+++ b/drivers/cpufreq/qcom-cpufreq.c
-@@ -0,0 +1,204 @@
-+/* 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/cpu.h>
-+#include <linux/err.h>
-+#include <linux/init.h>
-+#include <linux/io.h>
-+#include <linux/kernel.h>
-+#include <linux/module.h>
-+#include <linux/of.h>
-+#include <linux/platform_device.h>
-+#include <linux/pm_opp.h>
-+#include <linux/slab.h>
-+#include <linux/cpufreq-dt.h>
-+
-+static void __init get_krait_bin_format_a(int *speed, int *pvs, int *pvs_ver)
-+{
-+	void __iomem *base;
-+	u32 pte_efuse;
-+
-+	*speed = *pvs = *pvs_ver = 0;
-+
-+	base = ioremap(0x007000c0, 4);
-+	if (!base) {
-+		pr_warn("Unable to read efuse data. Defaulting to 0!\n");
-+		return;
-+	}
-+
-+	pte_efuse = readl_relaxed(base);
-+	iounmap(base);
-+
-+	*speed = pte_efuse & 0xf;
-+	if (*speed == 0xf)
-+		*speed = (pte_efuse >> 4) & 0xf;
-+
-+	if (*speed == 0xf) {
-+		*speed = 0;
-+		pr_warn("Speed bin: Defaulting to %d\n", *speed);
-+	} else {
-+		pr_info("Speed bin: %d\n", *speed);
-+	}
-+
-+	*pvs = (pte_efuse >> 10) & 0x7;
-+	if (*pvs == 0x7)
-+		*pvs = (pte_efuse >> 13) & 0x7;
-+
-+	if (*pvs == 0x7) {
-+		*pvs = 0;
-+		pr_warn("PVS bin: Defaulting to %d\n", *pvs);
-+	} else {
-+		pr_info("PVS bin: %d\n", *pvs);
-+	}
-+}
-+
-+static void __init get_krait_bin_format_b(int *speed, int *pvs, int *pvs_ver)
-+{
-+	u32 pte_efuse, redundant_sel;
-+	void __iomem *base;
-+
-+	*speed = 0;
-+	*pvs = 0;
-+	*pvs_ver = 0;
-+
-+	base = ioremap(0xfc4b80b0, 8);
-+	if (!base) {
-+		pr_warn("Unable to read efuse data. Defaulting to 0!\n");
-+		return;
-+	}
-+
-+	pte_efuse = readl_relaxed(base);
-+	redundant_sel = (pte_efuse >> 24) & 0x7;
-+	*speed = pte_efuse & 0x7;
-+	/* 4 bits of PVS are in efuse register bits 31, 8-6. */
-+	*pvs = ((pte_efuse >> 28) & 0x8) | ((pte_efuse >> 6) & 0x7);
-+	*pvs_ver = (pte_efuse >> 4) & 0x3;
-+
-+	switch (redundant_sel) {
-+	case 1:
-+		*speed = (pte_efuse >> 27) & 0xf;
-+		break;
-+	case 2:
-+		*pvs = (pte_efuse >> 27) & 0xf;
-+		break;
-+	}
-+
-+	/* Check SPEED_BIN_BLOW_STATUS */
-+	if (pte_efuse & BIT(3)) {
-+		pr_info("Speed bin: %d\n", *speed);
-+	} else {
-+		pr_warn("Speed bin not set. Defaulting to 0!\n");
-+		*speed = 0;
-+	}
-+
-+	/* Check PVS_BLOW_STATUS */
-+	pte_efuse = readl_relaxed(base + 0x4) & BIT(21);
-+	if (pte_efuse) {
-+		pr_info("PVS bin: %d\n", *pvs);
-+	} else {
-+		pr_warn("PVS bin not set. Defaulting to 0!\n");
-+		*pvs = 0;
-+	}
-+
-+	pr_info("PVS version: %d\n", *pvs_ver);
-+	iounmap(base);
-+}
-+
-+static int __init qcom_cpufreq_populate_opps(void)
-+{
-+	int len, rows, cols, i, k, speed, pvs, pvs_ver;
-+	char table_name[] = "qcom,speedXX-pvsXX-bin-vXX";
-+	struct device_node *np;
-+	struct device *dev;
-+	int cpu = 0;
-+
-+	np = of_find_node_by_name(NULL, "qcom,pvs");
-+	if (!np)
-+		return -ENODEV;
-+
-+	if (of_property_read_bool(np, "qcom,pvs-format-a")) {
-+		get_krait_bin_format_a(&speed, &pvs, &pvs_ver);
-+		cols = 2;
-+	} else if (of_property_read_bool(np, "qcom,pvs-format-b")) {
-+		get_krait_bin_format_b(&speed, &pvs, &pvs_ver);
-+		cols = 3;
-+	} else {
-+		return -ENODEV;
-+	}
-+
-+	snprintf(table_name, sizeof(table_name),
-+			"qcom,speed%d-pvs%d-bin-v%d", speed, pvs, pvs_ver);
-+
-+	if (!of_find_property(np, table_name, &len))
-+		return -EINVAL;
-+
-+	len /= sizeof(u32);
-+	if (len % cols || len == 0)
-+		return -EINVAL;
-+
-+	rows = len / cols;
-+
-+	for (i = 0, k = 0; i < rows; i++) {
-+		u32 freq, volt;
-+
-+		of_property_read_u32_index(np, table_name, k++, &freq);
-+		of_property_read_u32_index(np, table_name, k++, &volt);
-+		while (k % cols)
-+			k++; /* Skip uA entries if present */
-+		for (cpu = 0; cpu < num_possible_cpus(); cpu++) {
-+			dev = get_cpu_device(cpu);
-+			if (!dev)
-+				return -ENODEV;
-+			if (dev_pm_opp_add(dev, freq, volt))
-+				pr_warn("failed to add OPP %u\n", freq);
-+		}
-+	}
-+
-+	return 0;
-+}
-+
-+static int __init qcom_cpufreq_driver_init(void)
-+{
-+	struct cpufreq_dt_platform_data pdata = { .independent_clocks = true };
-+	struct platform_device_info devinfo = {
-+		.name = "cpufreq-dt",
-+		.data = &pdata,
-+		.size_data = sizeof(pdata),
-+	};
-+	struct device *cpu_dev;
-+	struct device_node *np;
-+	int ret;
-+
-+	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);
-+
-+	ret = qcom_cpufreq_populate_opps();
-+	if (ret)
-+		return ret;
-+
-+	return PTR_ERR_OR_ZERO(platform_device_register_full(&devinfo));
-+}
-+module_init(qcom_cpufreq_driver_init);
-+
-+MODULE_DESCRIPTION("Qualcomm CPUfreq driver");
-+MODULE_LICENSE("GPL v2");
diff --git a/target/linux/ipq806x/patches-3.18/144-ARM-dts-qcom-Add-necessary-DT-data-for-Krait-cpufreq.patch b/target/linux/ipq806x/patches-3.18/144-ARM-dts-qcom-Add-necessary-DT-data-for-Krait-cpufreq.patch
deleted file mode 100644
index c398487ae599f3556b9ee20f009f94ecab9a6b88..0000000000000000000000000000000000000000
--- a/target/linux/ipq806x/patches-3.18/144-ARM-dts-qcom-Add-necessary-DT-data-for-Krait-cpufreq.patch
+++ /dev/null
@@ -1,100 +0,0 @@
---- a/arch/arm/boot/dts/qcom-ipq8064.dtsi
-+++ b/arch/arm/boot/dts/qcom-ipq8064.dtsi
-@@ -25,6 +25,11 @@
- 			next-level-cache = <&L2>;
- 			qcom,acc = <&acc0>;
- 			qcom,saw = <&saw0>;
-+			clocks = <&kraitcc 0>;
-+			clock-names = "cpu";
-+			clock-latency = <100000>;
-+			core-supply = <&smb208_s2a>;
-+			voltage-tolerance = <5>;
- 		};
- 
- 		cpu@1 {
-@@ -35,11 +40,24 @@
- 			next-level-cache = <&L2>;
- 			qcom,acc = <&acc1>;
- 			qcom,saw = <&saw1>;
-+			clocks = <&kraitcc 1>;
-+			clock-names = "cpu";
-+			clock-latency = <100000>;
-+			core-supply = <&smb208_s2b>;
- 		};
- 
- 		L2: l2-cache {
- 			compatible = "cache";
- 			cache-level = <2>;
-+			clocks = <&kraitcc 4>;
-+			clock-names = "cache";
-+			cache-points-kHz = <
-+				/* kHz    uV    CPU kHz */
-+				1200000 1150000 1200000
-+				1000000 1100000  600000
-+				 384000 1100000  384000
-+			>;
-+			vdd_dig-supply = <&smb208_s1a>;
- 		};
- 	};
- 
-@@ -72,6 +90,46 @@
- 		};
- 	};
- 
-+	kraitcc: clock-controller {
-+		compatible = "qcom,krait-cc-v1";
-+		#clock-cells = <1>;
-+	};
-+
-+	qcom,pvs {
-+		qcom,pvs-format-a;
-+		qcom,speed0-pvs0-bin-v0 =
-+			< 1400000000 1250000 >,
-+			< 1200000000 1200000 >,
-+			< 1000000000 1150000 >,
-+			 < 800000000 1100000 >,
-+			 < 600000000 1050000 >,
-+			 < 384000000 1000000 >;
-+
-+		qcom,speed0-pvs1-bin-v0 =
-+			< 1400000000 1175000 >,
-+			< 1200000000 1125000 >,
-+			< 1000000000 1075000 >,
-+			 < 800000000 1025000 >,
-+			 < 600000000  975000 >,
-+			 < 384000000  925000 >;
-+
-+		qcom,speed0-pvs2-bin-v0 =
-+			< 1400000000 1125000 >,
-+			< 1200000000 1075000 >,
-+			< 1000000000 1025000 >,
-+			 < 800000000  995000 >,
-+			 < 600000000  925000 >,
-+			 < 384000000  875000 >;
-+
-+		qcom,speed0-pvs3-bin-v0 =
-+			< 1400000000 1050000 >,
-+			< 1200000000 1000000 >,
-+			< 1000000000  950000 >,
-+			 < 800000000  900000 >,
-+			 < 600000000  850000 >,
-+			 < 384000000  800000 >;
-+	};
-+
- 	soc: soc {
- 		#address-cells = <1>;
- 		#size-cells = <1>;
-@@ -199,11 +257,13 @@
- 		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 {
diff --git a/target/linux/ipq806x/patches-3.18/145-cpufreq-Add-a-cpufreq-krait-based-on-cpufre.patch b/target/linux/ipq806x/patches-3.18/145-cpufreq-Add-a-cpufreq-krait-based-on-cpufre.patch
deleted file mode 100644
index 6052b417ac7af6570b03c20663c4f09a9b91ee4e..0000000000000000000000000000000000000000
--- a/target/linux/ipq806x/patches-3.18/145-cpufreq-Add-a-cpufreq-krait-based-on-cpufre.patch
+++ /dev/null
@@ -1,461 +0,0 @@
-From dd77db4143290689d3a5e1ec61627233d0711b66 Mon Sep 17 00:00:00 2001
-From: Stephen Boyd <sboyd@codeaurora.org>
-Date: Fri, 30 May 2014 16:36:11 -0700
-Subject: [PATCH] FROMLIST: 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
-@@ -196,6 +196,19 @@ config CPUFREQ_DT
- 
- 	  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
-@@ -14,6 +14,7 @@ obj-$(CONFIG_CPU_FREQ_GOV_CONSERVATIVE)
- obj-$(CONFIG_CPU_FREQ_GOV_COMMON)		+= cpufreq_governor.o
- 
- obj-$(CONFIG_CPUFREQ_DT)		+= cpufreq-dt.o
-+obj-$(CONFIG_GENERIC_CPUFREQ_KRAIT)	+= cpufreq-krait.o
- 
- ##################################################################################
- # x86 drivers.
---- /dev/null
-+++ b/drivers/cpufreq/cpufreq-krait.c
-@@ -0,0 +1,390 @@
-+/*
-+ * 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/regulator/consumer.h>
-+#include <linux/slab.h>
-+#include <linux/thermal.h>
-+
-+static unsigned int transition_latency;
-+static unsigned int voltage_tolerance; /* in percentage */
-+
-+static struct device *cpu_dev;
-+static DEFINE_PER_CPU(struct clk *, krait_cpu_clks);
-+static DEFINE_PER_CPU(struct regulator *, krait_supply_core);
-+static struct cpufreq_frequency_table *freq_table;
-+static struct thermal_cooling_device *cdev;
-+
-+struct cache_points {
-+	unsigned long cache_freq;
-+	unsigned int cache_volt;
-+	unsigned long cpu_freq;
-+};
-+
-+static struct regulator *krait_l2_reg;
-+static struct clk *krait_l2_clk;
-+static struct cache_points *krait_l2_points;
-+static int nr_krait_l2_points;
-+
-+static int krait_parse_cache_points(struct device *dev,
-+		struct device_node *of_node)
-+{
-+	const struct property *prop;
-+	const __be32 *val;
-+	int nr, i;
-+
-+	prop = of_find_property(of_node, "cache-points-kHz", NULL);
-+	if (!prop)
-+		return -ENODEV;
-+	if (!prop->value)
-+		return -ENODATA;
-+
-+	/*
-+	 * Each OPP is a set of tuples consisting of frequency and
-+	 * cpu-frequency like <freq-kHz volt-uV freq-kHz>.
-+	 */
-+	nr = prop->length / sizeof(u32);
-+	if (nr % 3) {
-+		dev_err(dev, "%s: Invalid cache points\n", __func__);
-+		return -EINVAL;
-+	}
-+	nr /= 3;
-+
-+	krait_l2_points = devm_kcalloc(dev, nr, sizeof(*krait_l2_points),
-+				       GFP_KERNEL);
-+	if (!krait_l2_points)
-+		return -ENOMEM;
-+	nr_krait_l2_points = nr;
-+
-+	for (i = 0, val = prop->value; i < nr; i++) {
-+		unsigned long cache_freq = be32_to_cpup(val++) * 1000;
-+		unsigned int cache_volt = be32_to_cpup(val++);
-+		unsigned long cpu_freq = be32_to_cpup(val++) * 1000;
-+
-+		krait_l2_points[i].cache_freq = cache_freq;
-+		krait_l2_points[i].cache_volt = cache_volt;
-+		krait_l2_points[i].cpu_freq = cpu_freq;
-+	}
-+
-+	return 0;
-+}
-+
-+static int krait_set_target(struct cpufreq_policy *policy, unsigned int index)
-+{
-+	struct dev_pm_opp *opp;
-+	unsigned long volt = 0, volt_old = 0, tol = 0;
-+	unsigned long freq, max_cpu_freq = 0;
-+	unsigned int old_freq, new_freq;
-+	long freq_Hz, freq_exact;
-+	int ret, i;
-+	struct clk *cpu_clk;
-+	struct regulator *core;
-+	unsigned int cpu;
-+
-+	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;
-+
-+	core = per_cpu(krait_supply_core, policy->cpu);
-+
-+	rcu_read_lock();
-+	opp = dev_pm_opp_find_freq_ceil(cpu_dev, &freq_Hz);
-+	if (IS_ERR(opp)) {
-+		rcu_read_unlock();
-+		pr_err("failed to find OPP for %ld\n", freq_Hz);
-+		return PTR_ERR(opp);
-+	}
-+	volt = dev_pm_opp_get_voltage(opp);
-+	rcu_read_unlock();
-+	tol = volt * voltage_tolerance / 100;
-+	volt_old = regulator_get_voltage(core);
-+
-+	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);
-+
-+	/* scaling up?  scale voltage before frequency */
-+	if (new_freq > old_freq) {
-+		ret = regulator_set_voltage_tol(core, volt, tol);
-+		if (ret) {
-+			pr_err("failed to scale voltage up: %d\n", ret);
-+			return ret;
-+		}
-+	}
-+
-+	ret = clk_set_rate(cpu_clk, freq_exact);
-+	if (ret) {
-+		pr_err("failed to set clock rate: %d\n", ret);
-+		return ret;
-+	}
-+
-+	/* scaling down?  scale voltage after frequency */
-+	if (new_freq < old_freq) {
-+		ret = regulator_set_voltage_tol(core, volt, tol);
-+		if (ret) {
-+			pr_err("failed to scale voltage down: %d\n", ret);
-+			clk_set_rate(cpu_clk, old_freq * 1000);
-+		}
-+	}
-+
-+	for_each_possible_cpu(cpu) {
-+		freq = clk_get_rate(per_cpu(krait_cpu_clks, cpu));
-+		max_cpu_freq = max(max_cpu_freq, freq);
-+	}
-+
-+	for (i = 0; i < nr_krait_l2_points; i++) {
-+		if (max_cpu_freq >= krait_l2_points[i].cpu_freq) {
-+			if (krait_l2_reg) {
-+				ret = regulator_set_voltage_tol(krait_l2_reg,
-+						krait_l2_points[i].cache_volt,
-+						tol);
-+				if (ret) {
-+					pr_err("failed to scale l2 voltage: %d\n",
-+						ret);
-+				}
-+			}
-+			ret = clk_set_rate(krait_l2_clk,
-+					krait_l2_points[i].cache_freq);
-+			if (ret)
-+				pr_err("failed to scale l2 clk: %d\n", ret);
-+			break;
-+		}
-+
-+	}
-+
-+	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, *cache;
-+	int ret, i;
-+	unsigned int cpu;
-+	struct device *dev;
-+	struct clk *clk;
-+	struct regulator *core;
-+	unsigned long freq_Hz, freq, max_cpu_freq = 0;
-+	struct dev_pm_opp *opp;
-+	unsigned long volt, tol;
-+
-+	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;
-+	}
-+
-+	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;
-+	}
-+
-+	of_property_read_u32(np, "voltage-tolerance", &voltage_tolerance);
-+
-+	if (of_property_read_u32(np, "clock-latency", &transition_latency))
-+		transition_latency = CPUFREQ_ETERNAL;
-+
-+	cache = of_find_next_cache_node(np);
-+	if (cache) {
-+		struct device_node *vdd;
-+
-+		vdd = of_parse_phandle(cache, "vdd_dig-supply", 0);
-+		if (vdd) {
-+			krait_l2_reg = regulator_get(NULL, vdd->name);
-+			if (IS_ERR(krait_l2_reg)) {
-+				pr_warn("failed to get l2 vdd_dig supply\n");
-+				krait_l2_reg = NULL;
-+			}
-+			of_node_put(vdd);
-+		}
-+
-+		krait_l2_clk = of_clk_get(cache, 0);
-+		if (!IS_ERR(krait_l2_clk)) {
-+			ret = krait_parse_cache_points(&pdev->dev, cache);
-+			if (ret)
-+				clk_put(krait_l2_clk);
-+		}
-+		if (IS_ERR(krait_l2_clk) || ret)
-+			krait_l2_clk = NULL;
-+	}
-+
-+	for_each_possible_cpu(cpu) {
-+		dev = get_cpu_device(cpu);
-+		if (!dev) {
-+			pr_err("failed to get krait device\n");
-+			ret = -ENOENT;
-+			goto out_free_table;
-+		}
-+		per_cpu(krait_cpu_clks, cpu) = clk = devm_clk_get(dev, NULL);
-+		if (IS_ERR(clk)) {
-+			ret = PTR_ERR(clk);
-+			goto out_free_table;
-+		}
-+		core = devm_regulator_get(dev, "core");
-+		if (IS_ERR(core)) {
-+			pr_debug("failed to get core regulator\n");
-+			ret = PTR_ERR(core);
-+			goto out_free_table;
-+		}
-+		per_cpu(krait_supply_core, cpu) = core;
-+
-+		freq = freq_Hz = clk_get_rate(clk);
-+
-+		rcu_read_lock();
-+		opp = dev_pm_opp_find_freq_ceil(cpu_dev, &freq_Hz);
-+		if (IS_ERR(opp)) {
-+			rcu_read_unlock();
-+			pr_err("failed to find OPP for %ld\n", freq_Hz);
-+			ret = PTR_ERR(opp);
-+			goto out_free_table;
-+		}
-+		volt = dev_pm_opp_get_voltage(opp);
-+		rcu_read_unlock();
-+
-+		tol = volt * voltage_tolerance / 100;
-+		ret = regulator_set_voltage_tol(core, volt, tol);
-+		if (ret) {
-+			pr_err("failed to scale voltage up: %d\n", ret);
-+			goto out_free_table;
-+		}
-+		ret = regulator_enable(core);
-+		if (ret) {
-+			pr_err("failed to enable regulator: %d\n", ret);
-+			goto out_free_table;
-+		}
-+		max_cpu_freq = max(max_cpu_freq, freq);
-+	}
-+
-+	for (i = 0; i < nr_krait_l2_points; i++) {
-+		if (max_cpu_freq >= krait_l2_points[i].cpu_freq) {
-+			if (krait_l2_reg) {
-+				ret = regulator_set_voltage_tol(krait_l2_reg,
-+						krait_l2_points[i].cache_volt,
-+						tol);
-+				if (ret)
-+					pr_err("failed to scale l2 voltage: %d\n",
-+							ret);
-+				ret = regulator_enable(krait_l2_reg);
-+				if (ret)
-+					pr_err("failed to enable l2 voltage: %d\n",
-+							ret);
-+			}
-+			break;
-+		}
-+
-+	}
-+
-+	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:
-+	regulator_put(krait_l2_reg);
-+	clk_put(krait_l2_clk);
-+	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);
-+	clk_put(krait_l2_clk);
-+	regulator_put(krait_l2_reg);
-+
-+	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");
---- a/drivers/cpufreq/qcom-cpufreq.c
-+++ b/drivers/cpufreq/qcom-cpufreq.c
-@@ -168,11 +168,8 @@ static int __init qcom_cpufreq_populate_
- 
- static int __init qcom_cpufreq_driver_init(void)
- {
--	struct cpufreq_dt_platform_data pdata = { .independent_clocks = true };
- 	struct platform_device_info devinfo = {
--		.name = "cpufreq-dt",
--		.data = &pdata,
--		.size_data = sizeof(pdata),
-+		.name = "cpufreq-krait",
- 	};
- 	struct device *cpu_dev;
- 	struct device_node *np;
diff --git a/target/linux/ipq806x/patches-3.18/150-dmaengine-Rework-dma_chan_get.patch b/target/linux/ipq806x/patches-3.18/150-dmaengine-Rework-dma_chan_get.patch
deleted file mode 100644
index 880e67c46bf71afac0fc72c7122fcfbbd11aecb7..0000000000000000000000000000000000000000
--- a/target/linux/ipq806x/patches-3.18/150-dmaengine-Rework-dma_chan_get.patch
+++ /dev/null
@@ -1,70 +0,0 @@
-From d2f4f99db3e9ec8b063cf2e45704e2bb95428317 Mon Sep 17 00:00:00 2001
-From: Maxime Ripard <maxime.ripard@free-electrons.com>
-Date: Mon, 17 Nov 2014 14:41:58 +0100
-Subject: [PATCH] dmaengine: Rework dma_chan_get
-
-dma_chan_get uses a rather interesting error handling and code path.
-
-Change it to something more usual in the kernel.
-
-Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
-Acked-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
-Signed-off-by: Vinod Koul <vinod.koul@intel.com>
----
- drivers/dma/dmaengine.c | 36 +++++++++++++++++++-----------------
- 1 file changed, 19 insertions(+), 17 deletions(-)
-
---- a/drivers/dma/dmaengine.c
-+++ b/drivers/dma/dmaengine.c
-@@ -222,31 +222,33 @@ static void balance_ref_count(struct dma
-  */
- static int dma_chan_get(struct dma_chan *chan)
- {
--	int err = -ENODEV;
- 	struct module *owner = dma_chan_to_owner(chan);
-+	int ret;
- 
-+	/* The channel is already in use, update client count */
- 	if (chan->client_count) {
- 		__module_get(owner);
--		err = 0;
--	} else if (try_module_get(owner))
--		err = 0;
-+		goto out;
-+	}
- 
--	if (err == 0)
--		chan->client_count++;
-+	if (!try_module_get(owner))
-+		return -ENODEV;
- 
- 	/* allocate upon first client reference */
--	if (chan->client_count == 1 && err == 0) {
--		int desc_cnt = chan->device->device_alloc_chan_resources(chan);
--
--		if (desc_cnt < 0) {
--			err = desc_cnt;
--			chan->client_count = 0;
--			module_put(owner);
--		} else if (!dma_has_cap(DMA_PRIVATE, chan->device->cap_mask))
--			balance_ref_count(chan);
--	}
--
--	return err;
-+	ret = chan->device->device_alloc_chan_resources(chan);
-+	if (ret < 0)
-+		goto err_out;
-+
-+	if (!dma_has_cap(DMA_PRIVATE, chan->device->cap_mask))
-+		balance_ref_count(chan);
-+
-+out:
-+	chan->client_count++;
-+	return 0;
-+
-+err_out:
-+	module_put(owner);
-+	return ret;
- }
- 
- /**
diff --git a/target/linux/ipq806x/patches-3.18/151-dmaengine-Remove-the-need-to-declare-device_control.patch b/target/linux/ipq806x/patches-3.18/151-dmaengine-Remove-the-need-to-declare-device_control.patch
deleted file mode 100644
index b24a10b9110fcd640ac62eb9cb6963a10fd440b5..0000000000000000000000000000000000000000
--- a/target/linux/ipq806x/patches-3.18/151-dmaengine-Remove-the-need-to-declare-device_control.patch
+++ /dev/null
@@ -1,27 +0,0 @@
-From 4f8ef9f4140cc286d7d1cf9237da7a7439e4fc0b Mon Sep 17 00:00:00 2001
-From: Maxime Ripard <maxime.ripard@free-electrons.com>
-Date: Mon, 17 Nov 2014 14:42:03 +0100
-Subject: [PATCH] dmaengine: Remove the need to declare device_control
-
-In order to migrate the drivers without triggering a BUG_ON for the converted
-drivers, which would cause bisectability issues, we need to remove that check
-before removing the device_control function entirely.
-
-Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
-Acked-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
-Signed-off-by: Vinod Koul <vinod.koul@intel.com>
----
- drivers/dma/dmaengine.c | 2 --
- 1 file changed, 2 deletions(-)
-
---- a/drivers/dma/dmaengine.c
-+++ b/drivers/dma/dmaengine.c
-@@ -814,8 +814,6 @@ int dma_async_device_register(struct dma
- 		!device->device_prep_dma_sg);
- 	BUG_ON(dma_has_cap(DMA_CYCLIC, device->cap_mask) &&
- 		!device->device_prep_dma_cyclic);
--	BUG_ON(dma_has_cap(DMA_SLAVE, device->cap_mask) &&
--		!device->device_control);
- 	BUG_ON(dma_has_cap(DMA_INTERLEAVE, device->cap_mask) &&
- 		!device->device_prep_interleaved_dma);
- 
diff --git a/target/linux/ipq806x/patches-3.18/152-dmaengine-Make-channel-allocation-callbacks-optional.patch b/target/linux/ipq806x/patches-3.18/152-dmaengine-Make-channel-allocation-callbacks-optional.patch
deleted file mode 100644
index 63372594d8f97a1eaaae12c2bf248bce243b2b4d..0000000000000000000000000000000000000000
--- a/target/linux/ipq806x/patches-3.18/152-dmaengine-Make-channel-allocation-callbacks-optional.patch
+++ /dev/null
@@ -1,62 +0,0 @@
-From c4b54a648e682f678c338619df848233a6babc46 Mon Sep 17 00:00:00 2001
-From: Maxime Ripard <maxime.ripard@free-electrons.com>
-Date: Mon, 17 Nov 2014 14:41:59 +0100
-Subject: [PATCH] dmaengine: Make channel allocation callbacks optional
-
-Nowadays, some drivers don't have anything in there channel allocation
-callbacks anymore.
-
-Remove the BUG_ON if those callbacks aren't implemented, in order to allow
-drivers to not implement them.
-
-Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
-Acked-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
-Signed-off-by: Vinod Koul <vinod.koul@intel.com>
----
- drivers/dma/dmaengine.c | 18 +++++++++++-------
- 1 file changed, 11 insertions(+), 7 deletions(-)
-
---- a/drivers/dma/dmaengine.c
-+++ b/drivers/dma/dmaengine.c
-@@ -235,9 +235,11 @@ static int dma_chan_get(struct dma_chan
- 		return -ENODEV;
- 
- 	/* allocate upon first client reference */
--	ret = chan->device->device_alloc_chan_resources(chan);
--	if (ret < 0)
--		goto err_out;
-+	if (chan->device->device_alloc_chan_resources) {
-+		ret = chan->device->device_alloc_chan_resources(chan);
-+		if (ret < 0)
-+			goto err_out;
-+	}
- 
- 	if (!dma_has_cap(DMA_PRIVATE, chan->device->cap_mask))
- 		balance_ref_count(chan);
-@@ -259,11 +261,15 @@ err_out:
-  */
- static void dma_chan_put(struct dma_chan *chan)
- {
-+	/* This channel is not in use, bail out */
- 	if (!chan->client_count)
--		return; /* this channel failed alloc_chan_resources */
-+		return;
-+
- 	chan->client_count--;
- 	module_put(dma_chan_to_owner(chan));
--	if (chan->client_count == 0)
-+
-+	/* This channel is not in use anymore, free it */
-+	if (!chan->client_count && chan->device->device_free_chan_resources)
- 		chan->device->device_free_chan_resources(chan);
- }
- 
-@@ -817,8 +823,6 @@ int dma_async_device_register(struct dma
- 	BUG_ON(dma_has_cap(DMA_INTERLEAVE, device->cap_mask) &&
- 		!device->device_prep_interleaved_dma);
- 
--	BUG_ON(!device->device_alloc_chan_resources);
--	BUG_ON(!device->device_free_chan_resources);
- 	BUG_ON(!device->device_tx_status);
- 	BUG_ON(!device->device_issue_pending);
- 	BUG_ON(!device->dev);
diff --git a/target/linux/ipq806x/patches-3.18/153-dmaengine-Introduce-a-device_config-callback.patch b/target/linux/ipq806x/patches-3.18/153-dmaengine-Introduce-a-device_config-callback.patch
deleted file mode 100644
index ced452f8a075c1122fcdb3c3442d9162476a6458..0000000000000000000000000000000000000000
--- a/target/linux/ipq806x/patches-3.18/153-dmaengine-Introduce-a-device_config-callback.patch
+++ /dev/null
@@ -1,51 +0,0 @@
-From 94a73e30dfe6722e9f4ef19f7892901d7d00eab1 Mon Sep 17 00:00:00 2001
-From: Maxime Ripard <maxime.ripard@free-electrons.com>
-Date: Mon, 17 Nov 2014 14:42:00 +0100
-Subject: [PATCH] dmaengine: Introduce a device_config callback
-
-The fact that the channel configuration is done in device_control is rather
-misleading, since it's not really advertised as such, plus, the fact that the
-framework exposes a function of its own makes it not really intuitive, while
-we're losing the type checking whenever we pass that unsigned long argument.
-
-Add a device_config callback to dma_device, with a fallback on the old
-behaviour for now for existing drivers to opt in.
-
-Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
-Acked-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
-Signed-off-by: Vinod Koul <vinod.koul@intel.com>
----
- include/linux/dmaengine.h | 8 ++++++++
- 1 file changed, 8 insertions(+)
-
---- a/include/linux/dmaengine.h
-+++ b/include/linux/dmaengine.h
-@@ -607,6 +607,8 @@ struct dma_tx_state {
-  *	The function takes a buffer of size buf_len. The callback function will
-  *	be called after period_len bytes have been transferred.
-  * @device_prep_interleaved_dma: Transfer expression in a generic way.
-+ * @device_config: Pushes a new configuration to a channel, return 0 or an error
-+ *	code
-  * @device_control: manipulate all pending operations on a channel, returns
-  *	zero or error code
-  * @device_tx_status: poll for transaction completion, the optional
-@@ -673,6 +675,9 @@ struct dma_device {
- 	struct dma_async_tx_descriptor *(*device_prep_interleaved_dma)(
- 		struct dma_chan *chan, struct dma_interleaved_template *xt,
- 		unsigned long flags);
-+
-+	int (*device_config)(struct dma_chan *chan,
-+			     struct dma_slave_config *config);
- 	int (*device_control)(struct dma_chan *chan, enum dma_ctrl_cmd cmd,
- 		unsigned long arg);
- 
-@@ -696,6 +701,9 @@ static inline int dmaengine_device_contr
- static inline int dmaengine_slave_config(struct dma_chan *chan,
- 					  struct dma_slave_config *config)
- {
-+	if (chan->device->device_config)
-+		return chan->device->device_config(chan, config);
-+
- 	return dmaengine_device_control(chan, DMA_SLAVE_CONFIG,
- 			(unsigned long)config);
- }
diff --git a/target/linux/ipq806x/patches-3.18/154-dmaengine-Add-device_terminate_all-callback.patch b/target/linux/ipq806x/patches-3.18/154-dmaengine-Add-device_terminate_all-callback.patch
deleted file mode 100644
index 422f7fbe42410e3e525eaf0a044329982d3f906b..0000000000000000000000000000000000000000
--- a/target/linux/ipq806x/patches-3.18/154-dmaengine-Add-device_terminate_all-callback.patch
+++ /dev/null
@@ -1,47 +0,0 @@
-From 7fa0cf462daa6f6121b332b87833d7f5bdb515c0 Mon Sep 17 00:00:00 2001
-From: Maxime Ripard <maxime.ripard@free-electrons.com>
-Date: Mon, 17 Nov 2014 14:42:02 +0100
-Subject: [PATCH] dmaengine: Add device_terminate_all callback
-
-Split out the terminate_all command from device_control to a dma_device
-callback. In order to preserve backward capability, still rely on
-device_control if no such callback has been implemented.
-
-Eventually, this will allow to create a generic dma_slave_caps callback.
-
-Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
-Acked-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
-Signed-off-by: Vinod Koul <vinod.koul@intel.com>
----
- include/linux/dmaengine.h | 6 ++++++
- 1 file changed, 6 insertions(+)
-
---- a/include/linux/dmaengine.h
-+++ b/include/linux/dmaengine.h
-@@ -611,6 +611,8 @@ struct dma_tx_state {
-  *	code
-  * @device_control: manipulate all pending operations on a channel, returns
-  *	zero or error code
-+ * @device_terminate_all: Aborts all transfers on a channel. Returns 0
-+ *	or an error code
-  * @device_tx_status: poll for transaction completion, the optional
-  *	txstate parameter can be supplied with a pointer to get a
-  *	struct with auxiliary transfer status information, otherwise the call
-@@ -680,6 +682,7 @@ struct dma_device {
- 			     struct dma_slave_config *config);
- 	int (*device_control)(struct dma_chan *chan, enum dma_ctrl_cmd cmd,
- 		unsigned long arg);
-+	int (*device_terminate_all)(struct dma_chan *chan);
- 
- 	enum dma_status (*device_tx_status)(struct dma_chan *chan,
- 					    dma_cookie_t cookie,
-@@ -789,6 +792,9 @@ static inline int dma_get_slave_caps(str
- 
- static inline int dmaengine_terminate_all(struct dma_chan *chan)
- {
-+	if (chan->device->device_terminate_all)
-+		return chan->device->device_terminate_all(chan);
-+
- 	return dmaengine_device_control(chan, DMA_TERMINATE_ALL, 0);
- }
- 
diff --git a/target/linux/ipq806x/patches-3.18/155-dt-bindings-qcom_adm-Fix-channel-specifiers.patch b/target/linux/ipq806x/patches-3.18/155-dt-bindings-qcom_adm-Fix-channel-specifiers.patch
deleted file mode 100644
index 4f5c0efb7b0596c0e20471d996180597748c3336..0000000000000000000000000000000000000000
--- a/target/linux/ipq806x/patches-3.18/155-dt-bindings-qcom_adm-Fix-channel-specifiers.patch
+++ /dev/null
@@ -1,76 +0,0 @@
-Content-Type: text/plain; charset="utf-8"
-MIME-Version: 1.0
-Content-Transfer-Encoding: 7bit
-Subject: [v6,1/2] dt/bindings: qcom_adm: Fix channel specifiers
-From: Andy Gross <agross@codeaurora.org>
-X-Patchwork-Id: 6027361
-Message-Id: <1426571172-9711-2-git-send-email-agross@codeaurora.org>
-To: Vinod Koul <vinod.koul@intel.com>
-Cc: devicetree@vger.kernel.org, dmaengine@vger.kernel.org,
-	linux-arm-msm@vger.kernel.org, linux-kernel@vger.kernel.org,
-	linux-arm-kernel@lists.infradead.org, Kumar Gala <galak@codeaurora.org>,
-	Bjorn Andersson <bjorn.andersson@sonymobile.com>,
-	Andy Gross <agross@codeaurora.org>
-Date: Tue, 17 Mar 2015 00:46:11 -0500
-
-This patch removes the crci information from the dma channel property.  At least
-one client device requires using more than one CRCI value for a channel.  This
-does not match the current binding and the crci information needs to be removed.
-
-Instead, the client device will provide this information via other means.
-
-Signed-off-by: Andy Gross <agross@codeaurora.org>
-
----
-Documentation/devicetree/bindings/dma/qcom_adm.txt |   16 ++++++----------
- 1 file changed, 6 insertions(+), 10 deletions(-)
-
---- a/Documentation/devicetree/bindings/dma/qcom_adm.txt
-+++ b/Documentation/devicetree/bindings/dma/qcom_adm.txt
-@@ -4,8 +4,7 @@ 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.
-+- #dma-cells: must be <1>.  First cell denotes the channel number.
- - clocks: Should contain the core clock and interface clock.
- - clock-names: Must contain "core" for the core clock and "iface" for the
-   interface clock.
-@@ -22,7 +21,7 @@ Example:
- 			compatible = "qcom,adm";
- 			reg = <0x18300000 0x100000>;
- 			interrupts = <0 170 0>;
--			#dma-cells = <2>;
-+			#dma-cells = <1>;
- 
- 			clocks = <&gcc ADM0_CLK>, <&gcc ADM0_PBUS_CLK>;
- 			clock-names = "core", "iface";
-@@ -35,15 +34,12 @@ Example:
- 			qcom,ee = <0>;
- 		};
- 
--DMA clients must use the format descripted in the dma.txt file, using a three
-+DMA clients must use the format descripted in the dma.txt file, using a two
- cell specifier for each channel.
- 
--Each dmas request consists of 3 cells:
-+Each dmas request consists of two 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.
--    The CRCI is used for flow control.  It identifies the peripheral device that
--    is the source/destination for the transferred data.
- 
- Example:
- 
-@@ -56,7 +52,7 @@ Example:
- 
- 		cs-gpios = <&qcom_pinmux 20 0>;
- 
--		dmas = <&adm_dma 6 9>,
--			<&adm_dma 5 10>;
-+		dmas = <&adm_dma 6>,
-+			<&adm_dma 5>;
- 		dma-names = "rx", "tx";
- 	};
diff --git a/target/linux/ipq806x/patches-3.18/156-dmaengine-Add-ADM-driver.patch b/target/linux/ipq806x/patches-3.18/156-dmaengine-Add-ADM-driver.patch
deleted file mode 100644
index 16d000e8a5bea25af7859f6fffc13a075640cef2..0000000000000000000000000000000000000000
--- a/target/linux/ipq806x/patches-3.18/156-dmaengine-Add-ADM-driver.patch
+++ /dev/null
@@ -1,958 +0,0 @@
-Content-Type: text/plain; charset="utf-8"
-MIME-Version: 1.0
-Content-Transfer-Encoding: 7bit
-Subject: [v6,2/2] dmaengine: Add ADM driver
-From: Andy Gross <agross@codeaurora.org>
-X-Patchwork-Id: 6027351
-Message-Id: <1426571172-9711-3-git-send-email-agross@codeaurora.org>
-To: Vinod Koul <vinod.koul@intel.com>
-Cc: devicetree@vger.kernel.org, dmaengine@vger.kernel.org,
-	linux-arm-msm@vger.kernel.org, linux-kernel@vger.kernel.org,
-	linux-arm-kernel@lists.infradead.org, Kumar Gala <galak@codeaurora.org>,
-	Bjorn Andersson <bjorn.andersson@sonymobile.com>,
-	Andy Gross <agross@codeaurora.org>
-Date: Tue, 17 Mar 2015 00:46:12 -0500
-
-Add the DMA engine driver for the QCOM Application Data Mover (ADM) DMA
-controller found in the MSM8x60 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>
-Reviewed-by: sricharan <sricharan@codeaurora.org>
-
----
-drivers/dma/Kconfig    |   10 +
- drivers/dma/Makefile   |    1 +
- drivers/dma/qcom_adm.c |  900 ++++++++++++++++++++++++++++++++++++++++++++++++
- 3 files changed, 911 insertions(+)
- create mode 100644 drivers/dma/qcom_adm.c
-
---- a/drivers/dma/Kconfig
-+++ b/drivers/dma/Kconfig
-@@ -457,4 +457,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
---- /dev/null
-+++ b/drivers/dma/qcom_adm.c
-@@ -0,0 +1,896 @@
-+/*
-+ * Copyright (c) 2013-2015, 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 ADM_CHAN_MULTI			0x4
-+#define ADM_CI_MULTI			0x4
-+#define ADM_CRCI_MULTI			0x4
-+#define ADM_EE_MULTI			0x800
-+#define ADM_CHAN_OFFS(chan)		(ADM_CHAN_MULTI * chan)
-+#define ADM_EE_OFFS(ee)			(ADM_EE_MULTI * ee)
-+#define ADM_CHAN_EE_OFFS(chan, ee)	(ADM_CHAN_OFFS(chan) + ADM_EE_OFFS(ee))
-+#define ADM_CHAN_OFFS(chan)		(ADM_CHAN_MULTI * chan)
-+#define ADM_CI_OFFS(ci)			(ADM_CHAN_OFF(ci))
-+#define ADM_CH_CMD_PTR(chan, ee)	(ADM_CHAN_EE_OFFS(chan, ee))
-+#define ADM_CH_RSLT(chan, ee)		(0x40 + ADM_CHAN_EE_OFFS(chan, ee))
-+#define ADM_CH_FLUSH_STATE0(chan, ee)	(0x80 + ADM_CHAN_EE_OFFS(chan, ee))
-+#define ADM_CH_STATUS_SD(chan, ee)	(0x200 + ADM_CHAN_EE_OFFS(chan, ee))
-+#define ADM_CH_CONF(chan)		(0x240 + ADM_CHAN_OFFS(chan))
-+#define ADM_CH_RSLT_CONF(chan, ee)	(0x300 + ADM_CHAN_EE_OFFS(chan, ee))
-+#define ADM_SEC_DOMAIN_IRQ_STATUS(ee)	(0x380 + ADM_EE_OFFS(ee))
-+#define ADM_CI_CONF(ci)			(0x390 + ci * ADM_CI_MULTI)
-+#define ADM_GP_CTL			0x3d8
-+#define ADM_CRCI_CTL(crci, ee)		(0x400 + crci * ADM_CRCI_MULTI + \
-+						ADM_EE_OFFS(ee))
-+
-+/* channel status */
-+#define ADM_CH_STATUS_VALID	BIT(1)
-+
-+/* channel result */
-+#define ADM_CH_RSLT_VALID	BIT(31)
-+#define ADM_CH_RSLT_ERR		BIT(3)
-+#define ADM_CH_RSLT_FLUSH	BIT(2)
-+#define ADM_CH_RSLT_TPD		BIT(1)
-+
-+/* channel conf */
-+#define ADM_CH_CONF_SHADOW_EN		BIT(12)
-+#define ADM_CH_CONF_MPU_DISABLE		BIT(11)
-+#define ADM_CH_CONF_PERM_MPU_CONF	BIT(9)
-+#define ADM_CH_CONF_FORCE_RSLT_EN	BIT(7)
-+#define ADM_CH_CONF_SEC_DOMAIN(ee)	(((ee & 0x3) << 4) | ((ee & 0x4) << 11))
-+
-+/* channel result conf */
-+#define ADM_CH_RSLT_CONF_FLUSH_EN	BIT(1)
-+#define ADM_CH_RSLT_CONF_IRQ_EN		BIT(0)
-+
-+/* CRCI CTL */
-+#define ADM_CRCI_CTL_MUX_SEL	BIT(18)
-+#define ADM_CRCI_CTL_RST	BIT(17)
-+
-+/* CI configuration */
-+#define ADM_CI_RANGE_END(x)	(x << 24)
-+#define ADM_CI_RANGE_START(x)	(x << 16)
-+#define ADM_CI_BURST_4_WORDS	BIT(2)
-+#define ADM_CI_BURST_8_WORDS	BIT(3)
-+
-+/* GP CTL */
-+#define ADM_GP_CTL_LP_EN	BIT(12)
-+#define ADM_GP_CTL_LP_CNT(x)	(x << 8)
-+
-+/* Command pointer list entry */
-+#define ADM_CPLE_LP		BIT(31)
-+#define ADM_CPLE_CMD_PTR_LIST	BIT(29)
-+
-+/* Command list entry */
-+#define ADM_CMD_LC		BIT(31)
-+#define ADM_CMD_DST_CRCI(n)	(((n) & 0xf) << 7)
-+#define ADM_CMD_SRC_CRCI(n)	(((n) & 0xf) << 3)
-+
-+#define ADM_CMD_TYPE_SINGLE	0x0
-+#define ADM_CMD_TYPE_BOX	0x3
-+
-+#define ADM_CRCI_MUX_SEL	BIT(4)
-+#define ADM_DESC_ALIGN		8
-+#define ADM_MAX_XFER		(SZ_64K-1)
-+#define ADM_MAX_ROWS		(SZ_64K-1)
-+#define ADM_MAX_CHANNELS	16
-+
-+struct adm_desc_hw_box {
-+	u32 cmd;
-+	u32 src_addr;
-+	u32 dst_addr;
-+	u32 row_len;
-+	u32 num_rows;
-+	u32 row_offset;
-+};
-+
-+struct adm_desc_hw_single {
-+	u32 cmd;
-+	u32 src_addr;
-+	u32 dst_addr;
-+	u32 len;
-+};
-+
-+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;
-+
-+	void *cpl;
-+	dma_addr_t cp_addr;
-+	u32 crci;
-+	u32 mux;
-+	u32 blk_size;
-+};
-+
-+struct adm_chan {
-+	struct virt_dma_chan vc;
-+	struct adm_device *adev;
-+
-+	/* parsed from DT */
-+	u32 id;			/* channel id */
-+
-+	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 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_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_get_blksize - Get block size from burst value
-+ *
-+ */
-+static int adm_get_blksize(unsigned int burst)
-+{
-+	int ret;
-+
-+	switch (burst) {
-+	case 16:
-+	case 32:
-+	case 64:
-+	case 128:
-+		ret = ffs(burst>>4) - 1;
-+		break;
-+	case 192:
-+		ret = 4;
-+		break;
-+	case 256:
-+		ret = 5;
-+		break;
-+	default:
-+		ret = -EINVAL;
-+		break;
-+	}
-+
-+	return ret;
-+}
-+
-+/**
-+ * adm_process_fc_descriptors - Process descriptors for flow controlled xfers
-+ *
-+ * @achan: ADM channel
-+ * @desc: Descriptor memory pointer
-+ * @sg: Scatterlist entry
-+ * @crci: CRCI value
-+ * @burst: Burst size of transaction
-+ * @direction: DMA transfer direction
-+ */
-+static void *adm_process_fc_descriptors(struct adm_chan *achan,
-+	void *desc, struct scatterlist *sg, u32 crci, u32 burst,
-+	enum dma_transfer_direction direction)
-+{
-+	struct adm_desc_hw_box *box_desc = NULL;
-+	struct adm_desc_hw_single *single_desc;
-+	u32 remainder = sg_dma_len(sg);
-+	u32 rows, row_offset, crci_cmd;
-+	u32 mem_addr = sg_dma_address(sg);
-+	u32 *incr_addr = &mem_addr;
-+	u32 *src, *dst;
-+
-+	if (direction == DMA_DEV_TO_MEM) {
-+		crci_cmd = ADM_CMD_SRC_CRCI(crci);
-+		row_offset = burst;
-+		src = &achan->slave.src_addr;
-+		dst = &mem_addr;
-+	} else {
-+		crci_cmd = ADM_CMD_DST_CRCI(crci);
-+		row_offset = burst << 16;
-+		src = &mem_addr;
-+		dst = &achan->slave.dst_addr;
-+	}
-+
-+	while (remainder >= burst) {
-+		box_desc = desc;
-+		box_desc->cmd = ADM_CMD_TYPE_BOX | crci_cmd;
-+		box_desc->row_offset = row_offset;
-+		box_desc->src_addr = *src;
-+		box_desc->dst_addr = *dst;
-+
-+		rows = remainder / burst;
-+		rows = min_t(u32, rows, ADM_MAX_ROWS);
-+		box_desc->num_rows = rows << 16 | rows;
-+		box_desc->row_len = burst << 16 | burst;
-+
-+		*incr_addr += burst * rows;
-+		remainder -= burst * rows;
-+		desc += sizeof(*box_desc);
-+	}
-+
-+	/* if leftover bytes, do one single descriptor */
-+	if (remainder) {
-+		single_desc = desc;
-+		single_desc->cmd = ADM_CMD_TYPE_SINGLE | crci_cmd;
-+		single_desc->len = remainder;
-+		single_desc->src_addr = *src;
-+		single_desc->dst_addr = *dst;
-+		desc += sizeof(*single_desc);
-+
-+		if (sg_is_last(sg))
-+			single_desc->cmd |= ADM_CMD_LC;
-+	} else {
-+		if (box_desc && sg_is_last(sg))
-+			box_desc->cmd |= ADM_CMD_LC;
-+	}
-+
-+	return desc;
-+}
-+
-+/**
-+ * adm_process_non_fc_descriptors - Process descriptors for non-fc xfers
-+ *
-+ * @achan: ADM channel
-+ * @desc: Descriptor memory pointer
-+ * @sg: Scatterlist entry
-+ * @direction: DMA transfer direction
-+ */
-+static void *adm_process_non_fc_descriptors(struct adm_chan *achan,
-+	void *desc, struct scatterlist *sg,
-+	enum dma_transfer_direction direction)
-+{
-+	struct adm_desc_hw_single *single_desc;
-+	u32 remainder = sg_dma_len(sg);
-+	u32 mem_addr = sg_dma_address(sg);
-+	u32 *incr_addr = &mem_addr;
-+	u32 *src, *dst;
-+
-+	if (direction == DMA_DEV_TO_MEM) {
-+		src = &achan->slave.src_addr;
-+		dst = &mem_addr;
-+	} else {
-+		src = &mem_addr;
-+		dst = &achan->slave.dst_addr;
-+	}
-+
-+	do {
-+		single_desc = desc;
-+		single_desc->cmd = ADM_CMD_TYPE_SINGLE;
-+		single_desc->src_addr = *src;
-+		single_desc->dst_addr = *dst;
-+		single_desc->len = (remainder > ADM_MAX_XFER) ?
-+				ADM_MAX_XFER : remainder;
-+
-+		remainder -= single_desc->len;
-+		*incr_addr += single_desc->len;
-+		desc += sizeof(*single_desc);
-+	} while (remainder);
-+
-+	/* set last command if this is the end of the whole transaction */
-+	if (sg_is_last(sg))
-+		single_desc->cmd |= ADM_CMD_LC;
-+
-+	return desc;
-+}
-+
-+/**
-+ * 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, burst;
-+	u32 single_count = 0, box_count = 0, crci = 0;
-+	void *desc;
-+	u32 *cple;
-+	int blk_size = 0;
-+
-+	if (!is_slave_direction(direction)) {
-+		dev_err(adev->dev, "invalid dma direction\n");
-+		return NULL;
-+	}
-+
-+	/*
-+	 * get burst value from slave configuration
-+	 */
-+	burst = (direction == DMA_MEM_TO_DEV) ?
-+		achan->slave.dst_maxburst :
-+		achan->slave.src_maxburst;
-+
-+	/* if using flow control, validate burst and crci values */
-+	if (achan->slave.device_fc) {
-+
-+		blk_size = adm_get_blksize(burst);
-+		if (blk_size < 0) {
-+			dev_err(adev->dev, "invalid burst value: %d\n",
-+				burst);
-+			return ERR_PTR(-EINVAL);
-+		}
-+
-+		crci = achan->slave.slave_id & 0xf;
-+		if (!crci || achan->slave.slave_id > 0x1f) {
-+			dev_err(adev->dev, "invalid crci value\n");
-+			return ERR_PTR(-EINVAL);
-+		}
-+	}
-+
-+	/* iterate through sgs and compute allocation size of structures */
-+	for_each_sg(sgl, sg, sg_len, i) {
-+		if (achan->slave.device_fc) {
-+			box_count += DIV_ROUND_UP(sg_dma_len(sg) / burst,
-+						  ADM_MAX_ROWS);
-+			if (sg_dma_len(sg) % burst)
-+				single_count++;
-+		} else {
-+			single_count += DIV_ROUND_UP(sg_dma_len(sg),
-+						     ADM_MAX_XFER);
-+		}
-+	}
-+
-+	async_desc = kzalloc(sizeof(*async_desc), GFP_NOWAIT);
-+	if (!async_desc)
-+		return ERR_PTR(-ENOMEM);
-+
-+	if (crci)
-+		async_desc->mux = achan->slave.slave_id & ADM_CRCI_MUX_SEL ?
-+					ADM_CRCI_CTL_MUX_SEL : 0;
-+	async_desc->crci = crci;
-+	async_desc->blk_size = blk_size;
-+	async_desc->dma_len = single_count * sizeof(struct adm_desc_hw_single) +
-+				box_count * sizeof(struct adm_desc_hw_box) +
-+				sizeof(*cple) + 2 * 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->adev = adev;
-+
-+	/* both command list entry and descriptors must be 8 byte aligned */
-+	cple = PTR_ALIGN(async_desc->cpl, ADM_DESC_ALIGN);
-+	desc = PTR_ALIGN(cple + 1, ADM_DESC_ALIGN);
-+
-+	/* init cmd list */
-+	*cple = ADM_CPLE_LP;
-+	*cple |= (desc - async_desc->cpl + async_desc->dma_addr) >> 3;
-+
-+	for_each_sg(sgl, sg, sg_len, i) {
-+		async_desc->length += sg_dma_len(sg);
-+
-+		if (achan->slave.device_fc)
-+			desc = adm_process_fc_descriptors(achan, desc, sg, crci,
-+							burst, direction);
-+		else
-+			desc = adm_process_non_fc_descriptors(achan, desc, sg,
-+							   direction);
-+	}
-+
-+	return vchan_tx_prep(&achan->vc, &async_desc->vd, flags);
-+}
-+
-+/**
-+ * 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 int adm_terminate_all(struct dma_chan *chan)
-+{
-+	struct adm_chan *achan = to_adm_chan(chan);
-+	struct adm_device *adev = achan->adev;
-+	unsigned long flags;
-+	LIST_HEAD(head);
-+
-+	spin_lock_irqsave(&achan->vc.lock, flags);
-+	vchan_get_all_descriptors(&achan->vc, &head);
-+
-+	/* send flush command to terminate current transaction */
-+	writel_relaxed(0x0,
-+		adev->regs + ADM_CH_FLUSH_STATE0(achan->id, adev->ee));
-+
-+	spin_unlock_irqrestore(&achan->vc.lock, flags);
-+
-+	vchan_dma_desc_free_list(&achan->vc, &head);
-+
-+	return 0;
-+}
-+
-+static int adm_slave_config(struct dma_chan *chan, struct dma_slave_config *cfg)
-+{
-+	struct adm_chan *achan = to_adm_chan(chan);
-+	unsigned long flag;
-+
-+	spin_lock_irqsave(&achan->vc.lock, flag);
-+	memcpy(&achan->slave, cfg, sizeof(struct dma_slave_config));
-+	spin_unlock_irqrestore(&achan->vc.lock, flag);
-+
-+	return 0;
-+}
-+
-+/**
-+ * 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;
-+
-+	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;
-+
-+	/* reset channel error */
-+	achan->error = 0;
-+
-+	if (!achan->initialized) {
-+		/* enable interrupts */
-+		writel(ADM_CH_CONF_SHADOW_EN |
-+		       ADM_CH_CONF_PERM_MPU_CONF |
-+		       ADM_CH_CONF_MPU_DISABLE |
-+		       ADM_CH_CONF_SEC_DOMAIN(adev->ee),
-+		       adev->regs + ADM_CH_CONF(achan->id));
-+
-+		writel(ADM_CH_RSLT_CONF_IRQ_EN | ADM_CH_RSLT_CONF_FLUSH_EN,
-+			adev->regs + ADM_CH_RSLT_CONF(achan->id, adev->ee));
-+
-+		achan->initialized = 1;
-+	}
-+
-+	/* set the crci block size if this transaction requires CRCI */
-+	if (async_desc->crci) {
-+		writel(async_desc->mux | async_desc->blk_size,
-+			adev->regs + ADM_CRCI_CTL(async_desc->crci, adev->ee));
-+	}
-+
-+	/* make sure IRQ enable doesn't get reordered */
-+	wmb();
-+
-+	/* write next command list out to the CMD FIFO */
-+	writel(ALIGN(async_desc->dma_addr, ADM_DESC_ALIGN) >> 3,
-+		adev->regs + ADM_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 +
-+			ADM_SEC_DOMAIN_IRQ_STATUS(adev->ee));
-+
-+	for (i = 0; i < ADM_MAX_CHANNELS; i++) {
-+		struct adm_chan *achan = &adev->channels[i];
-+		u32 status, result;
-+
-+		if (srcs & BIT(i)) {
-+			status = readl_relaxed(adev->regs +
-+				ADM_CH_STATUS_SD(i, adev->ee));
-+
-+			/* if no result present, skip */
-+			if (!(status & ADM_CH_STATUS_VALID))
-+				continue;
-+
-+			result = readl_relaxed(adev->regs +
-+				ADM_CH_RSLT(i, adev->ee));
-+
-+			/* no valid results, skip */
-+			if (!(result & ADM_CH_RSLT_VALID))
-+				continue;
-+
-+			/* flag error if transaction was flushed or failed */
-+			if (result & (ADM_CH_RSLT_ERR | ADM_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);
-+	if (ret == DMA_COMPLETE || !txstate)
-+		return ret;
-+
-+	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;
-+
-+	spin_unlock_irqrestore(&achan->vc.lock, flags);
-+
-+	/*
-+	 * residue is either the full length if it is in the issued list, or 0
-+	 * if it is in progress.  We have no reliable way of determining
-+	 * anything inbetween
-+	*/
-+	dma_set_residue(txstate, residue);
-+
-+	if (achan->error)
-+		return DMA_ERROR;
-+
-+	return ret;
-+}
-+
-+/**
-+ * 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)) {
-+		ret = PTR_ERR(adev->iface_clk);
-+		goto err_disable_core_clk;
-+	}
-+
-+	ret = clk_prepare_enable(adev->iface_clk);
-+	if (ret) {
-+		dev_err(adev->dev, "failed to prepare/enable iface clock\n");
-+		goto err_disable_core_clk;
-+	}
-+
-+	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");
-+		ret = PTR_ERR(adev->clk_reset);
-+		goto err_disable_clks;
-+	}
-+
-+	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");
-+		ret = PTR_ERR(adev->c0_reset);
-+		goto err_disable_clks;
-+	}
-+
-+	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");
-+		ret = PTR_ERR(adev->c1_reset);
-+		goto err_disable_clks;
-+	}
-+
-+	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");
-+		ret = PTR_ERR(adev->c2_reset);
-+		goto err_disable_clks;
-+	}
-+
-+	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->channels = devm_kcalloc(adev->dev, ADM_MAX_CHANNELS,
-+				sizeof(*adev->channels), GFP_KERNEL);
-+
-+	if (!adev->channels) {
-+		ret = -ENOMEM;
-+		goto err_disable_clks;
-+	}
-+
-+	/* allocate and initialize channels */
-+	INIT_LIST_HEAD(&adev->common.channels);
-+
-+	for (i = 0; i < ADM_MAX_CHANNELS; i++)
-+		adm_channel_init(adev, &adev->channels[i], i);
-+
-+	/* reset CRCIs */
-+	for (i = 0; i < 16; i++)
-+		writel(ADM_CRCI_CTL_RST, adev->regs +
-+			ADM_CRCI_CTL(i, adev->ee));
-+
-+	/* configure client interfaces */
-+	writel(ADM_CI_RANGE_START(0x40) | ADM_CI_RANGE_END(0xb0) |
-+		ADM_CI_BURST_8_WORDS, adev->regs + ADM_CI_CONF(0));
-+	writel(ADM_CI_RANGE_START(0x2a) | ADM_CI_RANGE_END(0x2c) |
-+		ADM_CI_BURST_8_WORDS, adev->regs + ADM_CI_CONF(1));
-+	writel(ADM_CI_RANGE_START(0x12) | ADM_CI_RANGE_END(0x28) |
-+		ADM_CI_BURST_8_WORDS, adev->regs + ADM_CI_CONF(2));
-+	writel(ADM_GP_CTL_LP_EN | ADM_GP_CTL_LP_CNT(0xf),
-+		adev->regs + ADM_GP_CTL);
-+
-+	ret = devm_request_irq(adev->dev, adev->irq, adm_dma_irq,
-+			0, "adm_dma", adev);
-+	if (ret)
-+		goto err_disable_clks;
-+
-+	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_free_chan_resources = adm_free_chan;
-+	adev->common.device_prep_slave_sg = adm_prep_slave_sg;
-+	adev->common.device_issue_pending = adm_issue_pending;
-+	adev->common.device_tx_status = adm_tx_status;
-+	adev->common.device_terminate_all = adm_terminate_all;
-+	adev->common.device_config = adm_slave_config;
-+
-+	ret = dma_async_device_register(&adev->common);
-+	if (ret) {
-+		dev_err(adev->dev, "failed to register dma async device\n");
-+		goto err_disable_clks;
-+	}
-+
-+	ret = of_dma_controller_register(pdev->dev.of_node,
-+					 of_dma_xlate_by_chan_id,
-+					 &adev->common);
-+	if (ret)
-+		goto err_unregister_dma;
-+
-+	return 0;
-+
-+err_unregister_dma:
-+	dma_async_device_unregister(&adev->common);
-+err_disable_clks:
-+	clk_disable_unprepare(adev->iface_clk);
-+err_disable_core_clk:
-+	clk_disable_unprepare(adev->core_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);
-+
-+	for (i = 0; i < ADM_MAX_CHANNELS; i++) {
-+		achan = &adev->channels[i];
-+
-+		/* mask IRQs for this channel/EE pair */
-+		writel(0, adev->regs + ADM_CH_RSLT_CONF(achan->id, adev->ee));
-+
-+		adm_terminate_all(&adev->channels[i].vc.chan);
-+	}
-+
-+	devm_free_irq(adev->dev, adev->irq, adev);
-+
-+	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",
-+		.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");
---- a/drivers/dma/Makefile
-+++ b/drivers/dma/Makefile
-@@ -49,3 +49,4 @@ obj-y += xilinx/
- obj-$(CONFIG_INTEL_MIC_X100_DMA) += mic_x100_dma.o
- obj-$(CONFIG_NBPFAXI_DMA) += nbpfaxi.o
- obj-$(CONFIG_DMA_SUN6I) += sun6i-dma.o
-+obj-$(CONFIG_QCOM_ADM) += qcom_adm.o
diff --git a/target/linux/ipq806x/patches-3.18/157-ARM-DT-ipq8064-Add-ADM-device-node.patch b/target/linux/ipq806x/patches-3.18/157-ARM-DT-ipq8064-Add-ADM-device-node.patch
deleted file mode 100644
index a6dc89764cd6fc62f85dd77ceba9ae5aed6f068a..0000000000000000000000000000000000000000
--- a/target/linux/ipq806x/patches-3.18/157-ARM-DT-ipq8064-Add-ADM-device-node.patch
+++ /dev/null
@@ -1,42 +0,0 @@
-From 1fb18acab2d71e7e4efd9c10492edb1baf84dcc0 Mon Sep 17 00:00:00 2001
-From: Andy Gross <agross@codeaurora.org>
-Date: Wed, 20 May 2015 15:41:07 +0530
-Subject: [PATCH] ARM: DT: ipq8064: Add ADM device node
-
-This patch adds support for the ADM DMA on the IPQ8064 SOC
-
-Signed-off-by: Andy Gross <agross@codeaurora.org>
----
- arch/arm/boot/dts/qcom-ipq8064-ap148.dts |  4 ++++
- arch/arm/boot/dts/qcom-ipq8064.dtsi      | 21 +++++++++++++++++++++
- 2 files changed, 25 insertions(+)
-
---- a/arch/arm/boot/dts/qcom-ipq8064.dtsi
-+++ b/arch/arm/boot/dts/qcom-ipq8064.dtsi
-@@ -705,6 +705,26 @@
- 			};
- 		};
- 
-+		adm_dma: dma@18300000 {
-+			compatible = "qcom,adm";
-+			reg = <0x18300000 0x100000>;
-+			interrupts = <0 170 0>;
-+			#dma-cells = <1>;
-+
-+			clocks = <&gcc ADM0_CLK>, <&gcc ADM0_PBUS_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 = "clk", "pbus", "c0", "c1", "c2";
-+			qcom,ee = <0>;
-+
-+			status = "disabled";
-+		};
-+
- 	};
- 
- 	sfpb_mutex: sfpb-mutex {
diff --git a/target/linux/ipq806x/patches-3.18/160-clk-qcom-Add-EBI2-clocks-for-IPQ806x.patch b/target/linux/ipq806x/patches-3.18/160-clk-qcom-Add-EBI2-clocks-for-IPQ806x.patch
deleted file mode 100644
index 77d29d8ac43bf6a915a85081b7d345c5561658ee..0000000000000000000000000000000000000000
--- a/target/linux/ipq806x/patches-3.18/160-clk-qcom-Add-EBI2-clocks-for-IPQ806x.patch
+++ /dev/null
@@ -1,74 +0,0 @@
-From 4c385b25fab119144bffb255ad77712fe586ac10 Mon Sep 17 00:00:00 2001
-From: Archit Taneja <architt@codeaurora.org>
-Date: Thu, 2 Apr 2015 11:20:41 +0530
-Subject: [PATCH] clk: qcom: Add EBI2 clocks for IPQ806x
-
-The NAND controller within EBI2 requires EBI2_CLK and
-EBI2_ALWAYS_ON_CLK clocks.  Create structs for these clocks so
-that they can be used by the NAND controller driver. Add an entry
-for EBI2_AON_CLK in the gcc-ipq806x DT binding document.
-
-Signed-off-by: Archit Taneja <architt@codeaurora.org>
-Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
----
- drivers/clk/qcom/gcc-ipq806x.c               | 32 ++++++++++++++++++++++++++++
- include/dt-bindings/clock/qcom,gcc-ipq806x.h |  1 +
- 2 files changed, 33 insertions(+)
-
---- a/drivers/clk/qcom/gcc-ipq806x.c
-+++ b/drivers/clk/qcom/gcc-ipq806x.c
-@@ -2239,6 +2239,36 @@ static struct clk_branch usb_fs1_h_clk =
- 	},
- };
- 
-+static struct clk_branch ebi2_clk = {
-+	.hwcg_reg = 0x3b00,
-+	.hwcg_bit = 6,
-+	.halt_reg = 0x2fcc,
-+	.halt_bit = 1,
-+	.clkr = {
-+		.enable_reg = 0x3b00,
-+		.enable_mask = BIT(4),
-+		.hw.init = &(struct clk_init_data){
-+			.name = "ebi2_clk",
-+			.ops = &clk_branch_ops,
-+			.flags = CLK_IS_ROOT,
-+		},
-+	},
-+};
-+
-+static struct clk_branch ebi2_aon_clk = {
-+	.halt_reg = 0x2fcc,
-+	.halt_bit = 0,
-+	.clkr = {
-+		.enable_reg = 0x3b00,
-+		.enable_mask = BIT(8),
-+		.hw.init = &(struct clk_init_data){
-+			.name = "ebi2_always_on_clk",
-+			.ops = &clk_branch_ops,
-+			.flags = CLK_IS_ROOT,
-+		},
-+	},
-+};
-+
- static struct clk_regmap *gcc_ipq806x_clks[] = {
- 	[PLL0] = &pll0.clkr,
- 	[PLL0_VOTE] = &pll0_vote,
-@@ -2341,6 +2371,8 @@ 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,
-+	[EBI2_CLK] = &ebi2_clk.clkr,
-+	[EBI2_AON_CLK] = &ebi2_aon_clk.clkr,
- 	[PLL9] = &hfpll0.clkr,
- 	[PLL10] = &hfpll1.clkr,
- 	[PLL12] = &hfpll_l2.clkr,
---- a/include/dt-bindings/clock/qcom,gcc-ipq806x.h
-+++ b/include/dt-bindings/clock/qcom,gcc-ipq806x.h
-@@ -289,5 +289,6 @@
- #define UBI32_CORE2_CLK_SRC			278
- #define UBI32_CORE1_CLK				279
- #define UBI32_CORE2_CLK				280
-+#define EBI2_AON_CLK				281
- 
- #endif
diff --git a/target/linux/ipq806x/patches-3.18/161-mtd-nand-Create-a-BBT-flag-to-access-bad-block-markers-in-raw-mode.patch b/target/linux/ipq806x/patches-3.18/161-mtd-nand-Create-a-BBT-flag-to-access-bad-block-markers-in-raw-mode.patch
deleted file mode 100644
index 3fb47850fc48070e7619d4e93ded8c46e4119442..0000000000000000000000000000000000000000
--- a/target/linux/ipq806x/patches-3.18/161-mtd-nand-Create-a-BBT-flag-to-access-bad-block-markers-in-raw-mode.patch
+++ /dev/null
@@ -1,84 +0,0 @@
-Content-Type: text/plain; charset="utf-8"
-MIME-Version: 1.0
-Content-Transfer-Encoding: 7bit
-Subject: [v3,
-	1/5] mtd: nand: Create a BBT flag to access bad block markers in raw
-	mode
-From: Archit Taneja <architt@codeaurora.org>
-X-Patchwork-Id: 6927081
-Message-Id: <1438578498-32254-2-git-send-email-architt@codeaurora.org>
-To: linux-mtd@lists.infradead.org, dehrenberg@google.com,
-	cernekee@gmail.com, computersforpeace@gmail.com
-Cc: linux-arm-msm@vger.kernel.org, agross@codeaurora.org,
-	sboyd@codeaurora.org, linux-kernel@vger.kernel.org,
-	Archit Taneja <architt@codeaurora.org>
-Date: Mon,  3 Aug 2015 10:38:14 +0530
-
-Some controllers can access the factory bad block marker from OOB only
-when they read it in raw mode. When ECC is enabled, these controllers
-discard reading/writing bad block markers, preventing access to them
-altogether.
-
-The bbt driver assumes MTD_OPS_PLACE_OOB when scanning for bad blocks.
-This results in the nand driver's ecc->read_oob() op to be called, which
-works with ECC enabled.
-
-Create a new BBT option flag that tells nand_bbt to force the mode to
-MTD_OPS_RAW. This would result in the correct op being called for the
-underlying nand controller driver.
-
-Reviewed-by: Andy Gross <agross@codeaurora.org>
-Signed-off-by: Archit Taneja <architt@codeaurora.org>
-
----
-drivers/mtd/nand/nand_base.c | 6 +++++-
- drivers/mtd/nand/nand_bbt.c  | 6 +++++-
- include/linux/mtd/bbm.h      | 7 +++++++
- 3 files changed, 17 insertions(+), 2 deletions(-)
-
---- a/drivers/mtd/nand/nand_base.c
-+++ b/drivers/mtd/nand/nand_base.c
-@@ -396,7 +396,11 @@ static int nand_default_block_markbad(st
- 	} else {
- 		ops.len = ops.ooblen = 1;
- 	}
--	ops.mode = MTD_OPS_PLACE_OOB;
-+
-+	if (unlikely(chip->bbt_options & NAND_BBT_ACCESS_BBM_RAW))
-+		ops.mode = MTD_OPS_RAW;
-+	else
-+		ops.mode = MTD_OPS_PLACE_OOB;
- 
- 	/* Write to first/last page(s) if necessary */
- 	if (chip->bbt_options & NAND_BBT_SCANLASTPAGE)
---- a/drivers/mtd/nand/nand_bbt.c
-+++ b/drivers/mtd/nand/nand_bbt.c
-@@ -423,7 +423,11 @@ static int scan_block_fast(struct mtd_in
- 	ops.oobbuf = buf;
- 	ops.ooboffs = 0;
- 	ops.datbuf = NULL;
--	ops.mode = MTD_OPS_PLACE_OOB;
-+
-+	if (unlikely(bd->options & NAND_BBT_ACCESS_BBM_RAW))
-+		ops.mode = MTD_OPS_RAW;
-+	else
-+		ops.mode = MTD_OPS_PLACE_OOB;
- 
- 	for (j = 0; j < numpages; j++) {
- 		/*
---- a/include/linux/mtd/bbm.h
-+++ b/include/linux/mtd/bbm.h
-@@ -116,6 +116,13 @@ struct nand_bbt_descr {
- #define NAND_BBT_NO_OOB_BBM	0x00080000
- 
- /*
-+ * Force MTD_OPS_RAW mode when trying to access bad block markes from OOB. To
-+ * be used by controllers which can access BBM only when ECC is disabled, i.e,
-+ * when in RAW access mode
-+ */
-+#define NAND_BBT_ACCESS_BBM_RAW	0x00100000
-+
-+/*
-  * Flag set by nand_create_default_bbt_descr(), marking that the nand_bbt_descr
-  * was allocated dynamicaly and must be freed in nand_release(). Has no meaning
-  * in nand_chip.bbt_options.
diff --git a/target/linux/ipq806x/patches-3.18/162-mtd-nand-Qualcomm-NAND-controller-driver.patch b/target/linux/ipq806x/patches-3.18/162-mtd-nand-Qualcomm-NAND-controller-driver.patch
deleted file mode 100644
index 6172f7dec8bead8e5a3d6855e3c2b407b1d1e534..0000000000000000000000000000000000000000
--- a/target/linux/ipq806x/patches-3.18/162-mtd-nand-Qualcomm-NAND-controller-driver.patch
+++ /dev/null
@@ -1,2024 +0,0 @@
-Content-Type: text/plain; charset="utf-8"
-MIME-Version: 1.0
-Content-Transfer-Encoding: 7bit
-Subject: [v3,2/5] mtd: nand: Qualcomm NAND controller driver
-From: Archit Taneja <architt@codeaurora.org>
-X-Patchwork-Id: 6927101
-Message-Id: <1438578498-32254-3-git-send-email-architt@codeaurora.org>
-To: linux-mtd@lists.infradead.org, dehrenberg@google.com,
-	cernekee@gmail.com, computersforpeace@gmail.com
-Cc: linux-arm-msm@vger.kernel.org, agross@codeaurora.org,
-	sboyd@codeaurora.org, linux-kernel@vger.kernel.org,
-	Archit Taneja <architt@codeaurora.org>
-Date: Mon,  3 Aug 2015 10:38:15 +0530
-
-The Qualcomm NAND controller is found in SoCs like IPQ806x, MSM7xx,
-MDM9x15 series.
-
-It exists as a sub block inside the IPs EBI2 (External Bus Interface 2)
-and QPIC (Qualcomm Parallel Interface Controller). These IPs provide a
-broader interface for external slow peripheral devices such as LCD and
-NAND/NOR flash memory or SRAM like interfaces.
-
-We add support for the NAND controller found within EBI2. For the SoCs
-of our interest, we only use the NAND controller within EBI2. Therefore,
-it's safe for us to assume that the NAND controller is a standalone block
-within the SoC.
-
-The controller supports 512B, 2kB, 4kB and 8kB page 8-bit and 16-bit NAND
-flash devices. It contains a HW ECC block that supports BCH ECC (4, 8 and
-16 bit correction/step) and RS ECC(4 bit correction/step) that covers main
-and spare data. The controller contains an internal 512 byte page buffer
-to which we read/write via DMA. The EBI2 type NAND controller uses ADM DMA
-for register read/write and data transfers. The controller performs page
-reads and writes at a codeword/step level of 512 bytes. It can support up
-to 2 external chips of different configurations.
-
-The driver prepares register read and write configuration descriptors for
-each codeword, followed by data descriptors to read or write data from the
-controller's internal buffer. It uses a single ADM DMA channel that we get
-via dmaengine API. The controller requires 2 ADM CRCIs for command and
-data flow control. These are passed via DT.
-
-The ecc layout used by the controller is syndrome like, but we can't use
-the standard syndrome ecc ops because of several reasons. First, the amount
-of data bytes covered by ecc isn't same in each step. Second, writing to
-free oob space requires us writing to the entire step in which the oob
-lies. This forces us to create our own ecc ops.
-
-One more difference is how the controller accesses the bad block marker.
-The controller ignores reading the marker when ECC is enabled. ECC needs
-to be explicity disabled to read or write to the bad block marker. For
-this reason, we use the newly created flag NAND_BBT_ACCESS_BBM_RAW to
-read the factory provided bad block markers.
-
-v3:
-- Refactor dma functions for maximum reuse
-- Use dma_slave_confing on stack
-- optimize and clean upempty_page_fixup using memchr_inv
-- ensure portability with dma register reads using le32_* funcs
-- use NAND_USE_BOUNCE_BUFFER instead of doing it ourselves
-- fix handling of return values of dmaengine funcs
-- constify wherever possible
-- Remove dependency on ADM DMA in Kconfig
-- Misc fixes and clean ups
-
-v2:
-- Use new BBT flag that allows us to read BBM in raw mode
-- reduce memcpy-s in the driver
-- some refactor and clean ups because of above changes
-
-Reviewed-by: Andy Gross <agross@codeaurora.org>
-Signed-off-by: Archit Taneja <architt@codeaurora.org>
-
----
-drivers/mtd/nand/Kconfig      |    7 +
- drivers/mtd/nand/Makefile     |    1 +
- drivers/mtd/nand/qcom_nandc.c | 1913 +++++++++++++++++++++++++++++++++++++++++
- 3 files changed, 1921 insertions(+)
- create mode 100644 drivers/mtd/nand/qcom_nandc.c
-
---- a/drivers/mtd/nand/Kconfig
-+++ b/drivers/mtd/nand/Kconfig
-@@ -516,4 +516,11 @@ 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_NAND_QCOM
-+	tristate "Support for NAND on QCOM SoCs"
-+	depends on ARCH_QCOM
-+	help
-+	  Enables support for NAND flash chips on SoCs containing the EBI2 NAND
-+	  controller. This controller is found on IPQ806x SoC.
-+
- endif # MTD_NAND
---- /dev/null
-+++ b/drivers/mtd/nand/qcom_nandc.c
-@@ -0,0 +1,1918 @@
-+/*
-+ * Copyright (c) 2015, 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/slab.h>
-+#include <linux/bitops.h>
-+#include <linux/dma-mapping.h>
-+#include <linux/dmaengine.h>
-+#include <linux/module.h>
-+#include <linux/mtd/nand.h>
-+#include <linux/mtd/partitions.h>
-+#include <linux/of.h>
-+#include <linux/of_device.h>
-+#include <linux/of_mtd.h>
-+#include <linux/delay.h>
-+
-+/* NANDc reg offsets */
-+#define NAND_FLASH_CMD			0x00
-+#define NAND_ADDR0			0x04
-+#define NAND_ADDR1			0x08
-+#define NAND_FLASH_CHIP_SELECT		0x0c
-+#define NAND_EXEC_CMD			0x10
-+#define NAND_FLASH_STATUS		0x14
-+#define NAND_BUFFER_STATUS		0x18
-+#define NAND_DEV0_CFG0			0x20
-+#define NAND_DEV0_CFG1			0x24
-+#define NAND_DEV0_ECC_CFG		0x28
-+#define NAND_DEV1_ECC_CFG		0x2c
-+#define NAND_DEV1_CFG0			0x30
-+#define NAND_DEV1_CFG1			0x34
-+#define NAND_READ_ID			0x40
-+#define NAND_READ_STATUS		0x44
-+#define NAND_DEV_CMD0			0xa0
-+#define NAND_DEV_CMD1			0xa4
-+#define NAND_DEV_CMD2			0xa8
-+#define NAND_DEV_CMD_VLD		0xac
-+#define SFLASHC_BURST_CFG		0xe0
-+#define NAND_ERASED_CW_DETECT_CFG	0xe8
-+#define NAND_ERASED_CW_DETECT_STATUS	0xec
-+#define NAND_EBI2_ECC_BUF_CFG		0xf0
-+#define FLASH_BUF_ACC			0x100
-+
-+#define NAND_CTRL			0xf00
-+#define NAND_VERSION			0xf08
-+#define NAND_READ_LOCATION_0		0xf20
-+#define NAND_READ_LOCATION_1		0xf24
-+
-+/* dummy register offsets, used by write_reg_dma */
-+#define NAND_DEV_CMD1_RESTORE		0xdead
-+#define NAND_DEV_CMD_VLD_RESTORE	0xbeef
-+
-+/* NAND_FLASH_CMD bits */
-+#define PAGE_ACC			BIT(4)
-+#define LAST_PAGE			BIT(5)
-+
-+/* NAND_FLASH_CHIP_SELECT bits */
-+#define NAND_DEV_SEL			0
-+#define DM_EN				BIT(2)
-+
-+/* NAND_FLASH_STATUS bits */
-+#define FS_OP_ERR			BIT(4)
-+#define FS_READY_BSY_N			BIT(5)
-+#define FS_MPU_ERR			BIT(8)
-+#define FS_DEVICE_STS_ERR		BIT(16)
-+#define FS_DEVICE_WP			BIT(23)
-+
-+/* NAND_BUFFER_STATUS bits */
-+#define BS_UNCORRECTABLE_BIT		BIT(8)
-+#define BS_CORRECTABLE_ERR_MSK		0x1f
-+
-+/* NAND_DEVn_CFG0 bits */
-+#define DISABLE_STATUS_AFTER_WRITE	4
-+#define CW_PER_PAGE			6
-+#define UD_SIZE_BYTES			9
-+#define ECC_PARITY_SIZE_BYTES_RS	19
-+#define SPARE_SIZE_BYTES		23
-+#define NUM_ADDR_CYCLES			27
-+#define STATUS_BFR_READ			30
-+#define SET_RD_MODE_AFTER_STATUS	31
-+
-+/* NAND_DEVn_CFG0 bits */
-+#define DEV0_CFG1_ECC_DISABLE		0
-+#define WIDE_FLASH			1
-+#define NAND_RECOVERY_CYCLES		2
-+#define CS_ACTIVE_BSY			5
-+#define BAD_BLOCK_BYTE_NUM		6
-+#define BAD_BLOCK_IN_SPARE_AREA		16
-+#define WR_RD_BSY_GAP			17
-+#define ENABLE_BCH_ECC			27
-+
-+/* NAND_DEV0_ECC_CFG bits */
-+#define ECC_CFG_ECC_DISABLE		0
-+#define ECC_SW_RESET			1
-+#define ECC_MODE			4
-+#define ECC_PARITY_SIZE_BYTES_BCH	8
-+#define ECC_NUM_DATA_BYTES		16
-+#define ECC_FORCE_CLK_OPEN		30
-+
-+/* NAND_DEV_CMD1 bits */
-+#define READ_ADDR			0
-+
-+/* NAND_DEV_CMD_VLD bits */
-+#define READ_START_VLD			0
-+
-+/* NAND_EBI2_ECC_BUF_CFG bits */
-+#define NUM_STEPS			0
-+
-+/* NAND_ERASED_CW_DETECT_CFG bits */
-+#define ERASED_CW_ECC_MASK		1
-+#define AUTO_DETECT_RES			0
-+#define MASK_ECC			(1 << ERASED_CW_ECC_MASK)
-+#define RESET_ERASED_DET		(1 << AUTO_DETECT_RES)
-+#define ACTIVE_ERASED_DET		(0 << AUTO_DETECT_RES)
-+#define CLR_ERASED_PAGE_DET		(RESET_ERASED_DET | MASK_ECC)
-+#define SET_ERASED_PAGE_DET		(ACTIVE_ERASED_DET | MASK_ECC)
-+
-+/* NAND_ERASED_CW_DETECT_STATUS bits */
-+#define PAGE_ALL_ERASED			BIT(7)
-+#define CODEWORD_ALL_ERASED		BIT(6)
-+#define PAGE_ERASED			BIT(5)
-+#define CODEWORD_ERASED			BIT(4)
-+#define ERASED_PAGE			(PAGE_ALL_ERASED | PAGE_ERASED)
-+#define ERASED_CW			(CODEWORD_ALL_ERASED | CODEWORD_ERASED)
-+
-+/* Version Mask */
-+#define NAND_VERSION_MAJOR_MASK		0xf0000000
-+#define NAND_VERSION_MAJOR_SHIFT	28
-+#define NAND_VERSION_MINOR_MASK		0x0fff0000
-+#define NAND_VERSION_MINOR_SHIFT	16
-+
-+/* NAND OP_CMDs */
-+#define PAGE_READ			0x2
-+#define PAGE_READ_WITH_ECC		0x3
-+#define PAGE_READ_WITH_ECC_SPARE	0x4
-+#define PROGRAM_PAGE			0x6
-+#define PAGE_PROGRAM_WITH_ECC		0x7
-+#define PROGRAM_PAGE_SPARE		0x9
-+#define BLOCK_ERASE			0xa
-+#define FETCH_ID			0xb
-+#define RESET_DEVICE			0xd
-+
-+/*
-+ * the NAND controller performs reads/writes with ECC in 516 byte chunks.
-+ * the driver calls the chunks 'step' or 'codeword' interchangeably
-+ */
-+#define NANDC_STEP_SIZE			512
-+
-+/*
-+ * the largest page size we support is 8K, this will have 16 steps/codewords
-+ * of 512 bytes each
-+ */
-+#define	MAX_NUM_STEPS			(SZ_8K / NANDC_STEP_SIZE)
-+
-+/* we read at most 3 registers per codeword scan */
-+#define MAX_REG_RD			(3 * MAX_NUM_STEPS)
-+
-+/* ECC modes */
-+#define ECC_NONE	BIT(0)
-+#define ECC_RS_4BIT	BIT(1)
-+#define	ECC_BCH_4BIT	BIT(2)
-+#define	ECC_BCH_8BIT	BIT(3)
-+
-+struct desc_info {
-+	struct list_head list;
-+
-+	enum dma_transfer_direction dir;
-+	struct scatterlist sgl;
-+	struct dma_async_tx_descriptor *dma_desc;
-+};
-+
-+/*
-+ * holds the current register values that we want to write. acts as a contiguous
-+ * chunk of memory which we use to write the controller registers through DMA.
-+ */
-+struct nandc_regs {
-+	u32 cmd;
-+	u32 addr0;
-+	u32 addr1;
-+	u32 chip_sel;
-+	u32 exec;
-+
-+	u32 cfg0;
-+	u32 cfg1;
-+	u32 ecc_bch_cfg;
-+
-+	u32 clrflashstatus;
-+	u32 clrreadstatus;
-+
-+	u32 cmd1;
-+	u32 vld;
-+
-+	u32 orig_cmd1;
-+	u32 orig_vld;
-+
-+	u32 ecc_buf_cfg;
-+};
-+
-+/*
-+ * @cmd_crci:			ADM DMA CRCI for command flow control
-+ * @data_crci:			ADM DMA CRCI for data flow control
-+ * @list:			DMA descriptor list (list of desc_infos)
-+ * @dma_done:			completion param to denote end of last
-+ *				descriptor in the list
-+ * @data_buffer:		our local DMA buffer for page read/writes,
-+ *				used when we can't use the buffer provided
-+ *				by upper layers directly
-+ * @buf_size/count/start:	markers for chip->read_buf/write_buf functions
-+ * @reg_read_buf:		buffer for reading register data via DMA
-+ * @reg_read_pos:		marker for data read in reg_read_buf
-+ * @cfg0, cfg1, cfg0_raw..:	NANDc register configurations needed for
-+ *				ecc/non-ecc mode for the current nand flash
-+ *				device
-+ * @regs:			a contiguous chunk of memory for DMA register
-+ *				writes
-+ * @ecc_strength:		4 bit or 8 bit ecc, received via DT
-+ * @bus_width:			8 bit or 16 bit NAND bus width, received via DT
-+ * @ecc_modes:			supported ECC modes by the current controller,
-+ *				initialized via DT match data
-+ * @cw_size:			the number of bytes in a single step/codeword
-+ *				of a page, consisting of all data, ecc, spare
-+ *				and reserved bytes
-+ * @cw_data:			the number of bytes within a codeword protected
-+ *				by ECC
-+ * @bch_enabled:		flag to tell whether BCH or RS ECC mode is used
-+ * @status:			value to be returned if NAND_CMD_STATUS command
-+ *				is executed
-+ */
-+struct qcom_nandc_data {
-+	struct platform_device *pdev;
-+	struct device *dev;
-+
-+	void __iomem *base;
-+	struct resource *res;
-+
-+	struct clk *core_clk;
-+	struct clk *aon_clk;
-+
-+	/* DMA stuff */
-+	struct dma_chan *chan;
-+	struct dma_slave_config	slave_conf;
-+	unsigned int cmd_crci;
-+	unsigned int data_crci;
-+	struct list_head list;
-+	struct completion dma_done;
-+
-+	/* MTD stuff */
-+	struct nand_chip chip;
-+	struct mtd_info mtd;
-+
-+	/* local data buffer and markers */
-+	u8		*data_buffer;
-+	int		buf_size;
-+	int		buf_count;
-+	int		buf_start;
-+
-+	/* local buffer to read back registers */
-+	u32 *reg_read_buf;
-+	int reg_read_pos;
-+
-+	/* required configs */
-+	u32 cfg0, cfg1;
-+	u32 cfg0_raw, cfg1_raw;
-+	u32 ecc_buf_cfg;
-+	u32 ecc_bch_cfg;
-+	u32 clrflashstatus;
-+	u32 clrreadstatus;
-+	u32 sflashc_burst_cfg;
-+	u32 cmd1, vld;
-+
-+	/* register state */
-+	struct nandc_regs *regs;
-+
-+	/* things we get from DT */
-+	int ecc_strength;
-+	int bus_width;
-+
-+	u32 ecc_modes;
-+
-+	/* misc params */
-+	int cw_size;
-+	int cw_data;
-+	bool use_ecc;
-+	bool bch_enabled;
-+	u8 status;
-+	int last_command;
-+};
-+
-+static inline u32 nandc_read(struct qcom_nandc_data *this, int offset)
-+{
-+	return ioread32(this->base + offset);
-+}
-+
-+static inline void nandc_write(struct qcom_nandc_data *this, int offset,
-+			       u32 val)
-+{
-+	iowrite32(val, this->base + offset);
-+}
-+
-+/* helper to configure address register values */
-+static void set_address(struct qcom_nandc_data *this, u16 column, int page)
-+{
-+	struct nand_chip *chip = &this->chip;
-+	struct nandc_regs *regs = this->regs;
-+
-+	if (chip->options & NAND_BUSWIDTH_16)
-+		column >>= 1;
-+
-+	regs->addr0 = page << 16 | column;
-+	regs->addr1 = page >> 16 & 0xff;
-+}
-+
-+/*
-+ * update_rw_regs:	set up read/write register values, these will be
-+ *			written to the NAND controller registers via DMA
-+ *
-+ * @num_cw:		number of steps for the read/write operation
-+ * @read:		read or write operation
-+ */
-+static void update_rw_regs(struct qcom_nandc_data *this, int num_cw, bool read)
-+{
-+	struct nandc_regs *regs = this->regs;
-+
-+	if (read) {
-+		if (this->use_ecc)
-+			regs->cmd = PAGE_READ_WITH_ECC | PAGE_ACC | LAST_PAGE;
-+		else
-+			regs->cmd = PAGE_READ | PAGE_ACC | LAST_PAGE;
-+	} else {
-+			regs->cmd = PROGRAM_PAGE | PAGE_ACC | LAST_PAGE;
-+	}
-+
-+	if (this->use_ecc) {
-+		regs->cfg0 = (this->cfg0 & ~(7U << CW_PER_PAGE)) |
-+				(num_cw - 1) << CW_PER_PAGE;
-+
-+		regs->cfg1 = this->cfg1;
-+		regs->ecc_bch_cfg = this->ecc_bch_cfg;
-+	} else {
-+		regs->cfg0 = (this->cfg0_raw & ~(7U << CW_PER_PAGE)) |
-+				(num_cw - 1) << CW_PER_PAGE;
-+
-+		regs->cfg1 = this->cfg1_raw;
-+		regs->ecc_bch_cfg = 1 << ECC_CFG_ECC_DISABLE;
-+	}
-+
-+	regs->ecc_buf_cfg = this->ecc_buf_cfg;
-+	regs->clrflashstatus = this->clrflashstatus;
-+	regs->clrreadstatus = this->clrreadstatus;
-+	regs->exec = 1;
-+}
-+
-+static int prep_dma_desc(struct qcom_nandc_data *this, bool read, int reg_off,
-+			 const void *vaddr, int size, bool flow_control)
-+{
-+	struct desc_info *desc;
-+	struct dma_async_tx_descriptor *dma_desc;
-+	struct scatterlist *sgl;
-+	struct dma_slave_config slave_conf;
-+	int r;
-+
-+	desc = kzalloc(sizeof(*desc), GFP_KERNEL);
-+	if (!desc)
-+		return -ENOMEM;
-+
-+	list_add_tail(&desc->list, &this->list);
-+
-+	sgl = &desc->sgl;
-+
-+	sg_init_one(sgl, vaddr, size);
-+
-+	desc->dir = read ? DMA_DEV_TO_MEM : DMA_MEM_TO_DEV;
-+
-+	r = dma_map_sg(this->dev, sgl, 1, desc->dir);
-+	if (r == 0) {
-+		r = -ENOMEM;
-+		goto err;
-+	}
-+
-+	memset(&slave_conf, 0x00, sizeof(slave_conf));
-+
-+	slave_conf.device_fc = flow_control;
-+	if (read) {
-+		slave_conf.src_maxburst = 16;
-+		slave_conf.src_addr = this->res->start + reg_off;
-+		slave_conf.slave_id = this->data_crci;
-+	} else {
-+		slave_conf.dst_maxburst = 16;
-+		slave_conf.dst_addr = this->res->start + reg_off;
-+		slave_conf.slave_id = this->cmd_crci;
-+	}
-+
-+	r = dmaengine_slave_config(this->chan, &slave_conf);
-+	if (r) {
-+		dev_err(this->dev, "failed to configure dma channel\n");
-+		goto err;
-+	}
-+
-+	dma_desc = dmaengine_prep_slave_sg(this->chan, sgl, 1, desc->dir, 0);
-+	if (!dma_desc) {
-+		dev_err(this->dev, "failed to prepare desc\n");
-+		r = -EINVAL;
-+		goto err;
-+	}
-+
-+	desc->dma_desc = dma_desc;
-+
-+	return 0;
-+err:
-+	kfree(desc);
-+
-+	return r;
-+}
-+
-+/*
-+ * read_reg_dma:	prepares a descriptor to read a given number of
-+ *			contiguous registers to the reg_read_buf pointer
-+ *
-+ * @first:		offset of the first register in the contiguous block
-+ * @num_regs:		number of registers to read
-+ */
-+static int read_reg_dma(struct qcom_nandc_data *this, int first, int num_regs)
-+{
-+	bool flow_control = false;
-+	void *vaddr;
-+	int size;
-+
-+	if (first == NAND_READ_ID || first == NAND_FLASH_STATUS)
-+		flow_control = true;
-+
-+	size = num_regs * sizeof(u32);
-+	vaddr = this->reg_read_buf + this->reg_read_pos;
-+	this->reg_read_pos += num_regs;
-+
-+	return prep_dma_desc(this, true, first, vaddr, size, flow_control);
-+}
-+
-+/*
-+ * write_reg_dma:	prepares a descriptor to write a given number of
-+ *			contiguous registers
-+ *
-+ * @first:		offset of the first register in the contiguous block
-+ * @num_regs:		number of registers to write
-+ */
-+static int write_reg_dma(struct qcom_nandc_data *this, int first, int num_regs)
-+{
-+	bool flow_control = false;
-+	struct nandc_regs *regs = this->regs;
-+	void *vaddr;
-+	int size;
-+
-+	switch (first) {
-+	case NAND_FLASH_CMD:
-+		vaddr = &regs->cmd;
-+		flow_control = true;
-+		break;
-+	case NAND_EXEC_CMD:
-+		vaddr = &regs->exec;
-+		break;
-+	case NAND_FLASH_STATUS:
-+		vaddr = &regs->clrflashstatus;
-+		break;
-+	case NAND_DEV0_CFG0:
-+		vaddr = &regs->cfg0;
-+		break;
-+	case NAND_READ_STATUS:
-+		vaddr = &regs->clrreadstatus;
-+		break;
-+	case NAND_DEV_CMD1:
-+		vaddr = &regs->cmd1;
-+		break;
-+	case NAND_DEV_CMD1_RESTORE:
-+		first = NAND_DEV_CMD1;
-+		vaddr = &regs->orig_cmd1;
-+		break;
-+	case NAND_DEV_CMD_VLD:
-+		vaddr = &regs->vld;
-+		break;
-+	case NAND_DEV_CMD_VLD_RESTORE:
-+		first = NAND_DEV_CMD_VLD;
-+		vaddr = &regs->orig_vld;
-+		break;
-+	case NAND_EBI2_ECC_BUF_CFG:
-+		vaddr = &regs->ecc_buf_cfg;
-+		break;
-+	default:
-+		dev_err(this->dev, "invalid starting register\n");
-+		return -EINVAL;
-+	}
-+
-+	size = num_regs * sizeof(u32);
-+
-+	return prep_dma_desc(this, false, first, vaddr, size, flow_control);
-+}
-+
-+/*
-+ * read_data_dma:	prepares a DMA descriptor to transfer data from the
-+ *			controller's internal buffer to the buffer 'vaddr'
-+ *
-+ * @reg_off:		offset within the controller's data buffer
-+ * @vaddr:		virtual address of the buffer we want to write to
-+ * @size:		DMA transaction size in bytes
-+ */
-+static int read_data_dma(struct qcom_nandc_data *this, int reg_off,
-+			 const u8 *vaddr, int size)
-+{
-+	return prep_dma_desc(this, true, reg_off, vaddr, size, false);
-+}
-+
-+/*
-+ * write_data_dma:	prepares a DMA descriptor to transfer data from
-+ *			'vaddr' to the controller's internal buffer
-+ *
-+ * @reg_off:		offset within the controller's data buffer
-+ * @vaddr:		virtual address of the buffer we want to read from
-+ * @size:		DMA transaction size in bytes
-+ */
-+static int write_data_dma(struct qcom_nandc_data *this, int reg_off,
-+			  const u8 *vaddr, int size)
-+{
-+	return prep_dma_desc(this, false, reg_off, vaddr, size, false);
-+}
-+
-+/*
-+ * helper to prepare dma descriptors to configure registers needed for reading a
-+ * codeword/step in a page
-+ */
-+static void config_cw_read(struct qcom_nandc_data *this)
-+{
-+	write_reg_dma(this, NAND_FLASH_CMD, 3);
-+	write_reg_dma(this, NAND_DEV0_CFG0, 3);
-+	write_reg_dma(this, NAND_EBI2_ECC_BUF_CFG, 1);
-+
-+	write_reg_dma(this, NAND_EXEC_CMD, 1);
-+
-+	read_reg_dma(this, NAND_FLASH_STATUS, 2);
-+	read_reg_dma(this, NAND_ERASED_CW_DETECT_STATUS, 1);
-+}
-+
-+/*
-+ * helpers to prepare dma descriptors used to configure registers needed for
-+ * writing a codeword/step in a page
-+ */
-+static void config_cw_write_pre(struct qcom_nandc_data *this)
-+{
-+	write_reg_dma(this, NAND_FLASH_CMD, 3);
-+	write_reg_dma(this, NAND_DEV0_CFG0, 3);
-+	write_reg_dma(this, NAND_EBI2_ECC_BUF_CFG, 1);
-+}
-+
-+static void config_cw_write_post(struct qcom_nandc_data *this)
-+{
-+	write_reg_dma(this, NAND_EXEC_CMD, 1);
-+
-+	read_reg_dma(this, NAND_FLASH_STATUS, 1);
-+
-+	write_reg_dma(this, NAND_FLASH_STATUS, 1);
-+	write_reg_dma(this, NAND_READ_STATUS, 1);
-+}
-+
-+/*
-+ * the following functions are used within chip->cmdfunc() to perform different
-+ * NAND_CMD_* commands
-+ */
-+
-+/* sets up descriptors for NAND_CMD_PARAM */
-+static int nandc_param(struct qcom_nandc_data *this)
-+{
-+	struct nandc_regs *regs = this->regs;
-+
-+	/*
-+	 * NAND_CMD_PARAM is called before we know much about the FLASH chip
-+	 * in use. we configure the controller to perform a raw read of 512
-+	 * bytes to read onfi params
-+	 */
-+	regs->cmd = PAGE_READ | PAGE_ACC | LAST_PAGE;
-+	regs->addr0 = 0;
-+	regs->addr1 = 0;
-+	regs->cfg0 =  0 << CW_PER_PAGE
-+			| 512 << UD_SIZE_BYTES
-+			| 5 << NUM_ADDR_CYCLES
-+			| 0 << SPARE_SIZE_BYTES;
-+
-+	regs->cfg1 =  7 << NAND_RECOVERY_CYCLES
-+			| 0 << CS_ACTIVE_BSY
-+			| 17 << BAD_BLOCK_BYTE_NUM
-+			| 1 << BAD_BLOCK_IN_SPARE_AREA
-+			| 2 << WR_RD_BSY_GAP
-+			| 0 << WIDE_FLASH
-+			| 1 << DEV0_CFG1_ECC_DISABLE;
-+
-+	regs->ecc_bch_cfg = 1 << ECC_CFG_ECC_DISABLE;
-+
-+	/* configure CMD1 and VLD for ONFI param probing */
-+	regs->vld = (this->vld & ~(1 << READ_START_VLD))
-+			| 0 << READ_START_VLD;
-+
-+	regs->cmd1 = (this->cmd1 & ~(0xFF << READ_ADDR))
-+			| NAND_CMD_PARAM << READ_ADDR;
-+
-+	regs->exec = 1;
-+
-+	regs->orig_cmd1 = this->cmd1;
-+	regs->orig_vld = this->vld;
-+
-+	write_reg_dma(this, NAND_DEV_CMD_VLD, 1);
-+	write_reg_dma(this, NAND_DEV_CMD1, 1);
-+
-+	this->buf_count = 512;
-+	memset(this->data_buffer, 0xff, this->buf_count);
-+
-+	config_cw_read(this);
-+
-+	read_data_dma(this, FLASH_BUF_ACC, this->data_buffer, this->buf_count);
-+
-+	/* restore CMD1 and VLD regs */
-+	write_reg_dma(this, NAND_DEV_CMD1_RESTORE, 1);
-+	write_reg_dma(this, NAND_DEV_CMD_VLD_RESTORE, 1);
-+
-+	return 0;
-+}
-+
-+/* sets up descriptors for NAND_CMD_ERASE1 */
-+static int erase_block(struct qcom_nandc_data *this, int page_addr)
-+{
-+	struct nandc_regs *regs = this->regs;
-+
-+	regs->cmd = BLOCK_ERASE | PAGE_ACC | LAST_PAGE;
-+	regs->addr0 = page_addr;
-+	regs->addr1 = 0;
-+	regs->cfg0 = this->cfg0_raw & ~(7 << CW_PER_PAGE);
-+	regs->cfg1 = this->cfg1_raw;
-+	regs->exec = 1;
-+	regs->clrflashstatus = this->clrflashstatus;
-+	regs->clrreadstatus = this->clrreadstatus;
-+
-+	write_reg_dma(this, NAND_FLASH_CMD, 3);
-+	write_reg_dma(this, NAND_DEV0_CFG0, 2);
-+	write_reg_dma(this, NAND_EXEC_CMD, 1);
-+
-+	read_reg_dma(this, NAND_FLASH_STATUS, 1);
-+
-+	write_reg_dma(this, NAND_FLASH_STATUS, 1);
-+	write_reg_dma(this, NAND_READ_STATUS, 1);
-+
-+	return 0;
-+}
-+
-+/* sets up descriptors for NAND_CMD_READID */
-+static int read_id(struct qcom_nandc_data *this, int column)
-+{
-+	struct nandc_regs *regs = this->regs;
-+
-+	if (column == -1)
-+		return 0;
-+
-+	regs->cmd = FETCH_ID;
-+	regs->addr0 = column;
-+	regs->addr1 = 0;
-+	regs->chip_sel = DM_EN;
-+	regs->exec = 1;
-+
-+	write_reg_dma(this, NAND_FLASH_CMD, 4);
-+	write_reg_dma(this, NAND_EXEC_CMD, 1);
-+
-+	read_reg_dma(this, NAND_READ_ID, 1);
-+
-+	return 0;
-+}
-+
-+/* sets up descriptors for NAND_CMD_RESET */
-+static int reset(struct qcom_nandc_data *this)
-+{
-+	struct nandc_regs *regs = this->regs;
-+
-+	regs->cmd = RESET_DEVICE;
-+	regs->exec = 1;
-+
-+	write_reg_dma(this, NAND_FLASH_CMD, 1);
-+	write_reg_dma(this, NAND_EXEC_CMD, 1);
-+
-+	read_reg_dma(this, NAND_FLASH_STATUS, 1);
-+
-+	return 0;
-+}
-+
-+/* helpers to submit/free our list of dma descriptors */
-+static void dma_callback(void *param)
-+{
-+	struct qcom_nandc_data *this = param;
-+	struct completion *c = &this->dma_done;
-+
-+	complete(c);
-+}
-+
-+static int submit_descs(struct qcom_nandc_data *this)
-+{
-+	struct completion *c = &this->dma_done;
-+	struct desc_info *desc;
-+	int r;
-+
-+	init_completion(c);
-+
-+	list_for_each_entry(desc, &this->list, list) {
-+		/*
-+		 * we add a callback to the last descriptor in our list to
-+		 * notify completion of command
-+		 */
-+		if (list_is_last(&desc->list, &this->list)) {
-+			desc->dma_desc->callback = dma_callback;
-+			desc->dma_desc->callback_param = this;
-+		}
-+
-+		dmaengine_submit(desc->dma_desc);
-+	}
-+
-+	dma_async_issue_pending(this->chan);
-+
-+	r = wait_for_completion_timeout(c, msecs_to_jiffies(500));
-+	if (!r)
-+		return -ETIMEDOUT;
-+
-+	return 0;
-+}
-+
-+static void free_descs(struct qcom_nandc_data *this)
-+{
-+	struct desc_info *desc, *n;
-+
-+	list_for_each_entry_safe(desc, n, &this->list, list) {
-+		list_del(&desc->list);
-+		dma_unmap_sg(this->dev, &desc->sgl, 1, desc->dir);
-+		kfree(desc);
-+	}
-+}
-+
-+/* reset the register read buffer for next NAND operation */
-+static void clear_read_regs(struct qcom_nandc_data *this)
-+{
-+	this->reg_read_pos = 0;
-+	memset(this->reg_read_buf, 0, MAX_REG_RD * sizeof(*this->reg_read_buf));
-+}
-+
-+static void pre_command(struct qcom_nandc_data *this, int command)
-+{
-+	this->buf_count = 0;
-+	this->buf_start = 0;
-+	this->use_ecc = false;
-+	this->last_command = command;
-+
-+	clear_read_regs(this);
-+}
-+
-+/*
-+ * this is called after NAND_CMD_PAGEPROG and NAND_CMD_ERASE1 to set our
-+ * privately maintained status byte, this status byte can be read after
-+ * NAND_CMD_STATUS is called
-+ */
-+static void parse_erase_write_errors(struct qcom_nandc_data *this, int command)
-+{
-+	struct nand_chip *chip = &this->chip;
-+	struct nand_ecc_ctrl *ecc = &chip->ecc;
-+	int num_cw;
-+	int i;
-+
-+	num_cw = command == NAND_CMD_PAGEPROG ? ecc->steps : 1;
-+
-+	for (i = 0; i < num_cw; i++) {
-+		__le32 flash_status = le32_to_cpu(this->reg_read_buf[i]);
-+
-+		if (flash_status & FS_MPU_ERR)
-+			this->status &= ~NAND_STATUS_WP;
-+
-+		if (flash_status & FS_OP_ERR || (i == (num_cw - 1) &&
-+				(flash_status & FS_DEVICE_STS_ERR)))
-+			this->status |= NAND_STATUS_FAIL;
-+	}
-+}
-+
-+static void post_command(struct qcom_nandc_data *this, int command)
-+{
-+	switch (command) {
-+	case NAND_CMD_READID:
-+		memcpy(this->data_buffer, this->reg_read_buf, this->buf_count);
-+		break;
-+	case NAND_CMD_PAGEPROG:
-+	case NAND_CMD_ERASE1:
-+		parse_erase_write_errors(this, command);
-+		break;
-+	default:
-+		break;
-+	}
-+}
-+
-+/*
-+ * Implements chip->cmdfunc. It's  only used for a limited set of commands.
-+ * The rest of the commands wouldn't be called by upper layers. For example,
-+ * NAND_CMD_READOOB would never be called because we have our own versions
-+ * of read_oob ops for nand_ecc_ctrl.
-+ */
-+static void qcom_nandc_command(struct mtd_info *mtd, unsigned int command,
-+			 int column, int page_addr)
-+{
-+	struct nand_chip *chip = mtd->priv;
-+	struct nand_ecc_ctrl *ecc = &chip->ecc;
-+	struct qcom_nandc_data *this = chip->priv;
-+	bool wait = false;
-+	int r = 0;
-+
-+	pre_command(this, command);
-+
-+	switch (command) {
-+	case NAND_CMD_RESET:
-+		r = reset(this);
-+		wait = true;
-+		break;
-+
-+	case NAND_CMD_READID:
-+		this->buf_count = 4;
-+		r = read_id(this, column);
-+		wait = true;
-+		break;
-+
-+	case NAND_CMD_PARAM:
-+		r = nandc_param(this);
-+		wait = true;
-+		break;
-+
-+	case NAND_CMD_ERASE1:
-+		r = erase_block(this, page_addr);
-+		wait = true;
-+		break;
-+
-+	case NAND_CMD_READ0:
-+		/* we read the entire page for now */
-+		WARN_ON(column != 0);
-+
-+		this->use_ecc = true;
-+		set_address(this, 0, page_addr);
-+		update_rw_regs(this, ecc->steps, true);
-+		break;
-+
-+	case NAND_CMD_SEQIN:
-+		WARN_ON(column != 0);
-+		set_address(this, 0, page_addr);
-+		break;
-+
-+	case NAND_CMD_PAGEPROG:
-+	case NAND_CMD_STATUS:
-+	case NAND_CMD_NONE:
-+	default:
-+		break;
-+	}
-+
-+	if (r) {
-+		dev_err(this->dev, "failure executing command %d\n",
-+			command);
-+		free_descs(this);
-+		return;
-+	}
-+
-+	if (wait) {
-+		r = submit_descs(this);
-+		if (r)
-+			dev_err(this->dev,
-+				"failure submitting descs for command %d\n",
-+				command);
-+	}
-+
-+	free_descs(this);
-+
-+	post_command(this, command);
-+}
-+
-+/*
-+ * when using RS ECC, the NAND controller flags an error when reading an
-+ * erased page. however, there are special characters at certain offsets when
-+ * we read the erased page. we check here if the page is really empty. if so,
-+ * we replace the magic characters with 0xffs
-+ */
-+static bool empty_page_fixup(struct qcom_nandc_data *this, u8 *data_buf)
-+{
-+	struct mtd_info *mtd = &this->mtd;
-+	struct nand_chip *chip = &this->chip;
-+	struct nand_ecc_ctrl *ecc = &chip->ecc;
-+	int cwperpage = ecc->steps;
-+	u8 orig1[MAX_NUM_STEPS], orig2[MAX_NUM_STEPS];
-+	int i, j;
-+
-+	/* if BCH is enabled, HW will take care of detecting erased pages */
-+	if (this->bch_enabled || !this->use_ecc)
-+		return false;
-+
-+	for (i = 0; i < cwperpage; i++) {
-+		u8 *empty1, *empty2;
-+		__le32 flash_status = le32_to_cpu(this->reg_read_buf[3 * i]);
-+
-+		/*
-+		 * an erased page flags an error in NAND_FLASH_STATUS, check if
-+		 * the page is erased by looking for 0x54s at offsets 3 and 175
-+		 * from the beginning of each codeword
-+		 */
-+		if (!(flash_status & FS_OP_ERR))
-+			break;
-+
-+		empty1 = &data_buf[3 + i * this->cw_data];
-+		empty2 = &data_buf[175 + i * this->cw_data];
-+
-+		/*
-+		 * if the error wasn't because of an erased page, bail out and
-+		 * and let someone else do the error checking
-+		 */
-+		if ((*empty1 == 0x54 && *empty2 == 0xff) ||
-+				(*empty1 == 0xff && *empty2 == 0x54)) {
-+			orig1[i] = *empty1;
-+			orig2[i] = *empty2;
-+
-+			*empty1 = 0xff;
-+			*empty2 = 0xff;
-+		} else {
-+			break;
-+		}
-+	}
-+
-+	if (i < cwperpage || memchr_inv(data_buf, 0xff, mtd->writesize))
-+		goto not_empty;
-+
-+	/*
-+	 * tell the caller that the page was empty and is fixed up, so that
-+	 * parse_read_errors() doesn't think it's an error
-+	 */
-+	return true;
-+
-+not_empty:
-+	/* restore original values if not empty*/
-+	for (j = 0; j < i; j++) {
-+		data_buf[3 + j * this->cw_data] = orig1[j];
-+		data_buf[175 + j * this->cw_data] = orig2[j];
-+	}
-+
-+	return false;
-+}
-+
-+struct read_stats {
-+	__le32 flash;
-+	__le32 buffer;
-+	__le32 erased_cw;
-+};
-+
-+/*
-+ * reads back status registers set by the controller to notify page read
-+ * errors. this is equivalent to what 'ecc->correct()' would do.
-+ */
-+static int parse_read_errors(struct qcom_nandc_data *this, bool erased_page)
-+{
-+	struct mtd_info *mtd = &this->mtd;
-+	struct nand_chip *chip = &this->chip;
-+	struct nand_ecc_ctrl *ecc = &chip->ecc;
-+	int cwperpage = ecc->steps;
-+	unsigned int max_bitflips = 0;
-+	int i;
-+
-+	for (i = 0; i < cwperpage; i++) {
-+		int stat;
-+		struct read_stats *buf;
-+
-+		buf = (struct read_stats *) (this->reg_read_buf + 3 * i);
-+
-+		buf->flash = le32_to_cpu(buf->flash);
-+		buf->buffer = le32_to_cpu(buf->buffer);
-+		buf->erased_cw = le32_to_cpu(buf->erased_cw);
-+
-+		if (buf->flash & (FS_OP_ERR | FS_MPU_ERR)) {
-+
-+			/* ignore erased codeword errors */
-+			if (this->bch_enabled) {
-+				if ((buf->erased_cw & ERASED_CW) == ERASED_CW)
-+					continue;
-+			} else if (erased_page) {
-+				continue;
-+			}
-+
-+			if (buf->buffer & BS_UNCORRECTABLE_BIT) {
-+				mtd->ecc_stats.failed++;
-+				continue;
-+			}
-+		}
-+
-+		stat = buf->buffer & BS_CORRECTABLE_ERR_MSK;
-+		mtd->ecc_stats.corrected += stat;
-+
-+		max_bitflips = max_t(unsigned int, max_bitflips, stat);
-+	}
-+
-+	return max_bitflips;
-+}
-+
-+/*
-+ * helper to perform the actual page read operation, used by ecc->read_page()
-+ * and ecc->read_oob()
-+ */
-+static int read_page_low(struct qcom_nandc_data *this, u8 *data_buf,
-+			 u8 *oob_buf)
-+{
-+	struct nand_chip *chip = &this->chip;
-+	struct nand_ecc_ctrl *ecc = &chip->ecc;
-+	int i, r;
-+
-+	/* queue cmd descs for each codeword */
-+	for (i = 0; i < ecc->steps; i++) {
-+		int data_size, oob_size;
-+
-+		if (i == (ecc->steps - 1)) {
-+			data_size = ecc->size - ((ecc->steps - 1) << 2);
-+			oob_size = (ecc->steps << 2) + ecc->bytes;
-+		} else {
-+			data_size = this->cw_data;
-+			oob_size = ecc->bytes;
-+		}
-+
-+		config_cw_read(this);
-+
-+		if (data_buf)
-+			read_data_dma(this, FLASH_BUF_ACC, data_buf, data_size);
-+
-+		if (oob_buf)
-+			read_data_dma(this, FLASH_BUF_ACC + data_size, oob_buf,
-+					oob_size);
-+
-+		if (data_buf)
-+			data_buf += data_size;
-+		if (oob_buf)
-+			oob_buf += oob_size;
-+	}
-+
-+	r = submit_descs(this);
-+	if (r)
-+		dev_err(this->dev, "failure to read page/oob\n");
-+
-+	free_descs(this);
-+
-+	return r;
-+}
-+
-+/*
-+ * a helper that copies the last step/codeword of a page (containing free oob)
-+ * into our local buffer
-+ */
-+static int copy_last_cw(struct qcom_nandc_data *this, bool use_ecc, int page)
-+{
-+	struct nand_chip *chip = &this->chip;
-+	struct nand_ecc_ctrl *ecc = &chip->ecc;
-+	int size;
-+	int r;
-+
-+	clear_read_regs(this);
-+
-+	size = use_ecc ? this->cw_data : this->cw_size;
-+
-+	/* prepare a clean read buffer */
-+	memset(this->data_buffer, 0xff, size);
-+
-+	this->use_ecc = use_ecc;
-+	set_address(this, this->cw_size * (ecc->steps - 1), page);
-+	update_rw_regs(this, 1, true);
-+
-+	config_cw_read(this);
-+
-+	read_data_dma(this, FLASH_BUF_ACC, this->data_buffer, size);
-+
-+	r = submit_descs(this);
-+	if (r)
-+		dev_err(this->dev, "failed to copy last codeword\n");
-+
-+	free_descs(this);
-+
-+	return r;
-+}
-+
-+/* implements ecc->read_page() */
-+static int qcom_nandc_read_page(struct mtd_info *mtd, struct nand_chip *chip,
-+				uint8_t *buf, int oob_required, int page)
-+{
-+	struct qcom_nandc_data *this = chip->priv;
-+	u8 *data_buf, *oob_buf = NULL;
-+	bool erased_page;
-+	int r;
-+
-+	data_buf = buf;
-+	oob_buf = oob_required ? chip->oob_poi : NULL;
-+
-+	r = read_page_low(this, data_buf, oob_buf);
-+	if (r) {
-+		dev_err(this->dev, "failure to read page\n");
-+		return r;
-+	}
-+
-+	erased_page = empty_page_fixup(this, data_buf);
-+
-+	return parse_read_errors(this, erased_page);
-+}
-+
-+/* implements ecc->read_oob() */
-+static int qcom_nandc_read_oob(struct mtd_info *mtd, struct nand_chip *chip,
-+			       int page)
-+{
-+	struct qcom_nandc_data *this = chip->priv;
-+	struct nand_ecc_ctrl *ecc = &chip->ecc;
-+	int r;
-+
-+	clear_read_regs(this);
-+
-+	this->use_ecc = true;
-+	set_address(this, 0, page);
-+	update_rw_regs(this, ecc->steps, true);
-+
-+	r = read_page_low(this, NULL, chip->oob_poi);
-+	if (r)
-+		dev_err(this->dev, "failure to read oob\n");
-+
-+	return r;
-+}
-+
-+/* implements ecc->read_oob_raw(), used to read the bad block marker flag */
-+static int qcom_nandc_read_oob_raw(struct mtd_info *mtd, struct nand_chip *chip,
-+				   int page)
-+{
-+	struct qcom_nandc_data *this = chip->priv;
-+	struct nand_ecc_ctrl *ecc = &chip->ecc;
-+	uint8_t *oob = chip->oob_poi;
-+	int start, length;
-+	int r;
-+
-+	/*
-+	 * configure registers for a raw page read, the address is set to the
-+	 * beginning of the last codeword, we don't care about reading ecc
-+	 * portion of oob, just the free stuff
-+	 */
-+	r = copy_last_cw(this, false, page);
-+	if (r)
-+		return r;
-+
-+	/*
-+	 * reading raw oob has 2 parts, first the bad block byte, then the
-+	 * actual free oob region. perform a memcpy in two steps
-+	 */
-+	start = mtd->writesize - (this->cw_size * (ecc->steps - 1));
-+	length = chip->options & NAND_BUSWIDTH_16 ? 2 : 1;
-+
-+	memcpy(oob, this->data_buffer + start, length);
-+
-+	oob += length;
-+
-+	start = this->cw_data - (ecc->steps << 2) + 1;
-+	length = ecc->steps << 2;
-+
-+	memcpy(oob, this->data_buffer + start, length);
-+
-+	return 0;
-+}
-+
-+/* implements ecc->write_page() */
-+static int qcom_nandc_write_page(struct mtd_info *mtd, struct nand_chip *chip,
-+				 const uint8_t *buf, int oob_required)
-+{
-+	struct qcom_nandc_data *this = chip->priv;
-+	struct nand_ecc_ctrl *ecc = &chip->ecc;
-+	u8 *data_buf, *oob_buf;
-+	int i, r = 0;
-+
-+	clear_read_regs(this);
-+
-+	data_buf = (u8 *) buf;
-+	oob_buf = chip->oob_poi;
-+
-+	this->use_ecc = true;
-+	update_rw_regs(this, ecc->steps, false);
-+
-+	for (i = 0; i < ecc->steps; i++) {
-+		int data_size, oob_size;
-+
-+		if (i == (ecc->steps - 1)) {
-+			data_size = ecc->size - ((ecc->steps - 1) << 2);
-+			oob_size = (ecc->steps << 2) + ecc->bytes;
-+		} else {
-+			data_size = this->cw_data;
-+			oob_size = ecc->bytes;
-+		}
-+
-+		config_cw_write_pre(this);
-+		write_data_dma(this, FLASH_BUF_ACC, data_buf, data_size);
-+
-+		/*
-+		 * we don't really need to write anything to oob for the
-+		 * first n - 1 codewords since these oob regions just
-+		 * contain ecc that's written by the controller itself
-+		 */
-+		if (i == (ecc->steps - 1))
-+			write_data_dma(this, FLASH_BUF_ACC + data_size,
-+					oob_buf, oob_size);
-+		config_cw_write_post(this);
-+
-+		data_buf += data_size;
-+		oob_buf += oob_size;
-+	}
-+
-+	r = submit_descs(this);
-+	if (r)
-+		dev_err(this->dev, "failure to write page\n");
-+
-+	free_descs(this);
-+
-+	return r;
-+}
-+
-+/*
-+ * implements ecc->write_oob()
-+ *
-+ * the NAND controller cannot write only data or only oob within a codeword,
-+ * since ecc is calculated for the combined codeword. we first copy the
-+ * entire contents for the last codeword(data + oob), replace the old oob
-+ * with the new one in chip->oob_poi, and then write the entire codeword.
-+ * this read-copy-write operation results in a slight perormance loss.
-+ */
-+static int qcom_nandc_write_oob(struct mtd_info *mtd, struct nand_chip *chip,
-+				int page)
-+{
-+	struct qcom_nandc_data *this = chip->priv;
-+	struct nand_ecc_ctrl *ecc = &chip->ecc;
-+	uint8_t *oob = chip->oob_poi;
-+	int free_boff;
-+	int data_size, oob_size;
-+	int r, status = 0;
-+
-+	r = copy_last_cw(this, true, page);
-+	if (r)
-+		return r;
-+
-+	clear_read_regs(this);
-+
-+	/* calculate the data and oob size for the last codeword/step */
-+	data_size = ecc->size - ((ecc->steps - 1) << 2);
-+	oob_size = (ecc->steps << 2) + ecc->bytes;
-+
-+	/*
-+	 * the location of spare data in the oob buffer, we could also use
-+	 * ecc->layout.oobfree here
-+	 */
-+	free_boff = ecc->bytes * (ecc->steps - 1);
-+
-+	/* override new oob content to last codeword */
-+	memcpy(this->data_buffer + data_size, oob + free_boff, oob_size);
-+
-+	this->use_ecc = true;
-+	set_address(this, this->cw_size * (ecc->steps - 1), page);
-+	update_rw_regs(this, 1, false);
-+
-+	config_cw_write_pre(this);
-+	write_data_dma(this, FLASH_BUF_ACC, this->data_buffer,
-+		data_size + oob_size);
-+	config_cw_write_post(this);
-+
-+	r = submit_descs(this);
-+
-+	free_descs(this);
-+
-+	if (r) {
-+		dev_err(this->dev, "failure to write oob\n");
-+		return -EIO;
-+	}
-+
-+	chip->cmdfunc(mtd, NAND_CMD_PAGEPROG, -1, -1);
-+
-+	status = chip->waitfunc(mtd, chip);
-+
-+	return status & NAND_STATUS_FAIL ? -EIO : 0;
-+}
-+
-+/* implements ecc->write_oob_raw(), used to write bad block marker flag */
-+static int qcom_nandc_write_oob_raw(struct mtd_info *mtd,
-+				    struct nand_chip *chip, int page)
-+{
-+	struct qcom_nandc_data *this = chip->priv;
-+	struct nand_ecc_ctrl *ecc = &chip->ecc;
-+	uint8_t *oob = chip->oob_poi;
-+	int start, length;
-+	int r, status = 0;
-+
-+	r = copy_last_cw(this, false, page);
-+	if (r)
-+		return r;
-+
-+	clear_read_regs(this);
-+
-+	/*
-+	 * writing raw oob has 2 parts, first the bad block region, then the
-+	 * actual free region
-+	 */
-+	start = mtd->writesize - (this->cw_size * (ecc->steps - 1));
-+	length = chip->options & NAND_BUSWIDTH_16 ? 2 : 1;
-+
-+	memcpy(this->data_buffer + start, oob, length);
-+
-+	oob += length;
-+
-+	start = this->cw_data - (ecc->steps << 2) + 1;
-+	length = ecc->steps << 2;
-+
-+	memcpy(this->data_buffer + start, oob, length);
-+
-+	/* prepare write */
-+	this->use_ecc = false;
-+	set_address(this, this->cw_size * (ecc->steps - 1), page);
-+	update_rw_regs(this, 1, false);
-+
-+	config_cw_write_pre(this);
-+	write_data_dma(this, FLASH_BUF_ACC, this->data_buffer, this->cw_size);
-+	config_cw_write_post(this);
-+
-+	r = submit_descs(this);
-+
-+	free_descs(this);
-+
-+	if (r) {
-+		dev_err(this->dev, "failure to write updated oob\n");
-+		return -EIO;
-+	}
-+
-+	chip->cmdfunc(mtd, NAND_CMD_PAGEPROG, -1, -1);
-+
-+	status = chip->waitfunc(mtd, chip);
-+
-+	return status & NAND_STATUS_FAIL ? -EIO : 0;
-+}
-+
-+/*
-+ * the three functions below implement chip->read_byte(), chip->read_buf()
-+ * and chip->write_buf() respectively. these aren't used for
-+ * reading/writing page data, they are used for smaller data like reading
-+ * id, status etc
-+ */
-+static uint8_t qcom_nandc_read_byte(struct mtd_info *mtd)
-+{
-+	struct nand_chip *chip = mtd->priv;
-+	struct qcom_nandc_data *this = chip->priv;
-+	uint8_t *buf = this->data_buffer;
-+	uint8_t ret = 0x0;
-+
-+	if (this->last_command == NAND_CMD_STATUS) {
-+		ret = this->status;
-+
-+		this->status = NAND_STATUS_READY | NAND_STATUS_WP;
-+
-+		return ret;
-+	}
-+
-+	if (this->buf_start < this->buf_count)
-+		ret = buf[this->buf_start++];
-+
-+	return ret;
-+}
-+
-+static void qcom_nandc_read_buf(struct mtd_info *mtd, uint8_t *buf, int len)
-+{
-+	struct nand_chip *chip = mtd->priv;
-+	struct qcom_nandc_data *this = chip->priv;
-+	int real_len = min_t(size_t, len, this->buf_count - this->buf_start);
-+
-+	memcpy(buf, this->data_buffer + this->buf_start, real_len);
-+	this->buf_start += real_len;
-+}
-+
-+static void qcom_nandc_write_buf(struct mtd_info *mtd, const uint8_t *buf,
-+		int len)
-+{
-+	struct nand_chip *chip = mtd->priv;
-+	struct qcom_nandc_data *this = chip->priv;
-+	int real_len = min_t(size_t, len, this->buf_count - this->buf_start);
-+
-+	memcpy(this->data_buffer + this->buf_start, buf, real_len);
-+
-+	this->buf_start += real_len;
-+}
-+
-+/* we support only one external chip for now */
-+static void qcom_nandc_select_chip(struct mtd_info *mtd, int chipnr)
-+{
-+	struct nand_chip *chip = mtd->priv;
-+	struct qcom_nandc_data *this = chip->priv;
-+
-+	if (chipnr <= 0)
-+		return;
-+
-+	dev_warn(this->dev, "invalid chip select\n");
-+}
-+
-+/*
-+ * NAND controller page layout info
-+ *
-+ * |-----------------------|	  |---------------------------------|
-+ * |		xx.......xx|	  |		*********xx.......xx|
-+ * |	DATA	xx..ECC..xx|	  |	DATA	**SPARE**xx..ECC..xx|
-+ * |   (516)	xx.......xx|	  |  (516-n*4)	**(n*4)**xx.......xx|
-+ * |		xx.......xx|	  |		*********xx.......xx|
-+ * |-----------------------|	  |---------------------------------|
-+ *     codeword 1,2..n-1			codeword n
-+ *  <---(528/532 Bytes)---->	   <-------(528/532 Bytes)---------->
-+ *
-+ * n = number of codewords in the page
-+ * . = ECC bytes
-+ * * = spare bytes
-+ * x = unused/reserved bytes
-+ *
-+ * 2K page: n = 4, spare = 16 bytes
-+ * 4K page: n = 8, spare = 32 bytes
-+ * 8K page: n = 16, spare = 64 bytes
-+ *
-+ * the qcom nand controller operates at a sub page/codeword level. each
-+ * codeword is 528 and 532 bytes for 4 bit and 8 bit ECC modes respectively.
-+ * the number of ECC bytes vary based on the ECC strength and the bus width.
-+ *
-+ * the first n - 1 codewords contains 516 bytes of user data, the remaining
-+ * 12/16 bytes consist of ECC and reserved data. The nth codeword contains
-+ * both user data and spare(oobavail) bytes that sum up to 516 bytes.
-+ *
-+ * the layout described above is used by the controller when the ECC block is
-+ * enabled. When we read a page with ECC enabled, the unused/reserved bytes are
-+ * skipped and not copied to our internal buffer. therefore, the nand_ecclayout
-+ * layouts defined below doesn't consider the positions occupied by the reserved
-+ * bytes
-+ *
-+ * when the ECC block is disabled, one unused byte (or two for 16 bit bus width)
-+ * in the last codeword is the position of bad block marker. the bad block
-+ * marker cannot be accessed when ECC is enabled.
-+ *
-+ */
-+
-+/*
-+ * Layouts for different page sizes and ecc modes. We skip the eccpos field
-+ * since it isn't needed for this driver
-+ */
-+
-+/* 2K page, 4 bit ECC */
-+static struct nand_ecclayout layout_oob_64 = {
-+	.eccbytes	= 40,
-+	.oobfree	= {
-+				{ 30, 16 },
-+			  },
-+};
-+
-+/* 4K page, 4 bit ECC, 8/16 bit bus width */
-+static struct nand_ecclayout layout_oob_128 = {
-+	.eccbytes	= 80,
-+	.oobfree	= {
-+				{ 70, 32 },
-+			  },
-+};
-+
-+/* 4K page, 8 bit ECC, 8 bit bus width */
-+static struct nand_ecclayout layout_oob_224_x8 = {
-+	.eccbytes	= 104,
-+	.oobfree	= {
-+				{ 91, 32 },
-+			  },
-+};
-+
-+/* 4K page, 8 bit ECC, 16 bit bus width */
-+static struct nand_ecclayout layout_oob_224_x16 = {
-+	.eccbytes	= 112,
-+	.oobfree	= {
-+				{ 98, 32 },
-+			  },
-+};
-+
-+/* 8K page, 4 bit ECC, 8/16 bit bus width */
-+static struct nand_ecclayout layout_oob_256 = {
-+	.eccbytes	= 160,
-+	.oobfree	= {
-+				{ 151, 64 },
-+			  },
-+};
-+
-+/*
-+ * this is called before scan_ident, we do some minimal configurations so
-+ * that reading ID and ONFI params work
-+ */
-+static void qcom_nandc_pre_init(struct qcom_nandc_data *this)
-+{
-+	/* kill onenand */
-+	nandc_write(this, SFLASHC_BURST_CFG, 0);
-+
-+	/* enable ADM DMA */
-+	nandc_write(this, NAND_FLASH_CHIP_SELECT, DM_EN);
-+
-+	/* save the original values of these registers */
-+	this->cmd1 = nandc_read(this, NAND_DEV_CMD1);
-+	this->vld = nandc_read(this, NAND_DEV_CMD_VLD);
-+
-+	/* initial status value */
-+	this->status = NAND_STATUS_READY | NAND_STATUS_WP;
-+}
-+
-+static int qcom_nandc_ecc_init(struct qcom_nandc_data *this)
-+{
-+	struct mtd_info *mtd = &this->mtd;
-+	struct nand_chip *chip = &this->chip;
-+	struct nand_ecc_ctrl *ecc = &chip->ecc;
-+	int cwperpage;
-+	bool wide_bus;
-+
-+	/* the nand controller fetches codewords/chunks of 512 bytes */
-+	cwperpage = mtd->writesize >> 9;
-+
-+	ecc->strength = this->ecc_strength;
-+
-+	wide_bus = chip->options & NAND_BUSWIDTH_16 ? true : false;
-+
-+	if (ecc->strength >= 8) {
-+		/* 8 bit ECC defaults to BCH ECC on all platforms */
-+		ecc->bytes = wide_bus ? 14 : 13;
-+	} else {
-+		/*
-+		 * if the controller supports BCH for 4 bit ECC, the controller
-+		 * uses lesser bytes for ECC. If RS is used, the ECC bytes is
-+		 * always 10 bytes
-+		 */
-+		if (this->ecc_modes & ECC_BCH_4BIT)
-+			ecc->bytes = wide_bus ? 8 : 7;
-+		else
-+			ecc->bytes = 10;
-+	}
-+
-+	/* each step consists of 512 bytes of data */
-+	ecc->size = NANDC_STEP_SIZE;
-+
-+	ecc->read_page		= qcom_nandc_read_page;
-+	ecc->read_oob		= qcom_nandc_read_oob;
-+	ecc->write_page		= qcom_nandc_write_page;
-+	ecc->write_oob		= qcom_nandc_write_oob;
-+
-+	/*
-+	 * the bad block marker is readable only when we read the page with ECC
-+	 * disabled. all the ops above run with ECC enabled. We need raw read
-+	 * and write function for oob in order to access bad block marker.
-+	 */
-+	ecc->read_oob_raw	= qcom_nandc_read_oob_raw;
-+	ecc->write_oob_raw	= qcom_nandc_write_oob_raw;
-+
-+	switch (mtd->oobsize) {
-+	case 64:
-+		ecc->layout = &layout_oob_64;
-+		break;
-+	case 128:
-+		ecc->layout = &layout_oob_128;
-+		break;
-+	case 224:
-+		if (wide_bus)
-+			ecc->layout = &layout_oob_224_x16;
-+		else
-+			ecc->layout = &layout_oob_224_x8;
-+		break;
-+	case 256:
-+		ecc->layout = &layout_oob_256;
-+		break;
-+	default:
-+		dev_err(this->dev, "unsupported NAND device, oobsize %d\n",
-+			mtd->oobsize);
-+		return -ENODEV;
-+	}
-+
-+	ecc->mode = NAND_ECC_HW;
-+
-+	/* enable ecc by default */
-+	this->use_ecc = true;
-+
-+	return 0;
-+}
-+
-+static void qcom_nandc_hw_post_init(struct qcom_nandc_data *this)
-+{
-+	struct mtd_info *mtd = &this->mtd;
-+	struct nand_chip *chip = &this->chip;
-+	struct nand_ecc_ctrl *ecc = &chip->ecc;
-+	int cwperpage = mtd->writesize / ecc->size;
-+	int spare_bytes, bad_block_byte;
-+	bool wide_bus;
-+	int ecc_mode = 0;
-+
-+	wide_bus = chip->options & NAND_BUSWIDTH_16 ? true : false;
-+
-+	if (ecc->strength >= 8) {
-+		this->cw_size = 532;
-+
-+		spare_bytes = wide_bus ? 0 : 2;
-+
-+		this->bch_enabled = true;
-+		ecc_mode = 1;
-+	} else {
-+		this->cw_size = 528;
-+
-+		if (this->ecc_modes & ECC_BCH_4BIT) {
-+			spare_bytes = wide_bus ? 2 : 4;
-+
-+			this->bch_enabled = true;
-+			ecc_mode = 0;
-+		} else {
-+			spare_bytes = wide_bus ? 0 : 1;
-+		}
-+	}
-+
-+	/*
-+	 * DATA_UD_BYTES varies based on whether the read/write command protects
-+	 * spare data with ECC too. We protect spare data by default, so we set
-+	 * it to main + spare data, which are 512 and 4 bytes respectively.
-+	 */
-+	this->cw_data = 516;
-+
-+	bad_block_byte = mtd->writesize - this->cw_size * (cwperpage - 1) + 1;
-+
-+	this->cfg0 = (cwperpage - 1) << CW_PER_PAGE
-+				| this->cw_data << UD_SIZE_BYTES
-+				| 0 << DISABLE_STATUS_AFTER_WRITE
-+				| 5 << NUM_ADDR_CYCLES
-+				| ecc->bytes << ECC_PARITY_SIZE_BYTES_RS
-+				| 0 << STATUS_BFR_READ
-+				| 1 << SET_RD_MODE_AFTER_STATUS
-+				| spare_bytes << SPARE_SIZE_BYTES;
-+
-+	this->cfg1 = 7 << NAND_RECOVERY_CYCLES
-+				| 0 <<  CS_ACTIVE_BSY
-+				| bad_block_byte << BAD_BLOCK_BYTE_NUM
-+				| 0 << BAD_BLOCK_IN_SPARE_AREA
-+				| 2 << WR_RD_BSY_GAP
-+				| wide_bus << WIDE_FLASH
-+				| this->bch_enabled << ENABLE_BCH_ECC;
-+
-+	this->cfg0_raw = (cwperpage - 1) << CW_PER_PAGE
-+				| this->cw_size << UD_SIZE_BYTES
-+				| 5 << NUM_ADDR_CYCLES
-+				| 0 << SPARE_SIZE_BYTES;
-+
-+	this->cfg1_raw = 7 << NAND_RECOVERY_CYCLES
-+				| 0 << CS_ACTIVE_BSY
-+				| 17 << BAD_BLOCK_BYTE_NUM
-+				| 1 << BAD_BLOCK_IN_SPARE_AREA
-+				| 2 << WR_RD_BSY_GAP
-+				| wide_bus << WIDE_FLASH
-+				| 1 << DEV0_CFG1_ECC_DISABLE;
-+
-+	this->ecc_bch_cfg = this->bch_enabled << ECC_CFG_ECC_DISABLE
-+				| 0 << ECC_SW_RESET
-+				| this->cw_data << ECC_NUM_DATA_BYTES
-+				| 1 << ECC_FORCE_CLK_OPEN
-+				| ecc_mode << ECC_MODE
-+				| ecc->bytes << ECC_PARITY_SIZE_BYTES_BCH;
-+
-+	this->ecc_buf_cfg = 0x203 << NUM_STEPS;
-+
-+	this->clrflashstatus = FS_READY_BSY_N;
-+	this->clrreadstatus = 0xc0;
-+
-+	dev_dbg(this->dev,
-+		"cfg0 %x cfg1 %x ecc_buf_cfg %x ecc_bch cfg %x cw_size %d cw_data %d strength %d parity_bytes %d steps %d\n",
-+		this->cfg0, this->cfg1, this->ecc_buf_cfg,
-+		this->ecc_bch_cfg, this->cw_size, this->cw_data,
-+		ecc->strength, ecc->bytes, cwperpage);
-+}
-+
-+static int qcom_nandc_alloc(struct qcom_nandc_data *this)
-+{
-+	int r;
-+
-+	r = dma_set_coherent_mask(this->dev, DMA_BIT_MASK(32));
-+	if (r) {
-+		dev_err(this->dev, "failed to set DMA mask\n");
-+		return r;
-+	}
-+
-+	/*
-+	 * we use the internal buffer for reading ONFI params, reading small
-+	 * data like ID and status, and preforming read-copy-write operations
-+	 * when writing to a codeword partially. 532 is the maximum possible
-+	 * size of a codeword for our nand controller
-+	 */
-+	this->buf_size = 532;
-+
-+	this->data_buffer = devm_kzalloc(this->dev, this->buf_size, GFP_KERNEL);
-+	if (!this->data_buffer)
-+		return -ENOMEM;
-+
-+	this->regs = devm_kzalloc(this->dev, sizeof(*this->regs), GFP_KERNEL);
-+	if (!this->regs)
-+		return -ENOMEM;
-+
-+	this->reg_read_buf = devm_kzalloc(this->dev,
-+				MAX_REG_RD * sizeof(*this->reg_read_buf),
-+				GFP_KERNEL);
-+	if (!this->reg_read_buf)
-+		return -ENOMEM;
-+
-+	INIT_LIST_HEAD(&this->list);
-+
-+	this->chan = dma_request_slave_channel(this->dev, "rxtx");
-+	if (!this->chan) {
-+		dev_err(this->dev, "failed to request slave channel\n");
-+		return -ENODEV;
-+	}
-+
-+	return 0;
-+}
-+
-+static void qcom_nandc_unalloc(struct qcom_nandc_data *this)
-+{
-+	dma_release_channel(this->chan);
-+}
-+
-+static int qcom_nandc_init(struct qcom_nandc_data *this)
-+{
-+	struct mtd_info *mtd = &this->mtd;
-+	struct nand_chip *chip = &this->chip;
-+	struct device_node *np = this->dev->of_node;
-+	struct mtd_part_parser_data ppdata = { .of_node = np };
-+	int r;
-+
-+	mtd->priv = chip;
-+	mtd->name = "qcom-nandc";
-+	mtd->owner = THIS_MODULE;
-+
-+	chip->priv = this;
-+
-+	chip->cmdfunc		= qcom_nandc_command;
-+	chip->select_chip	= qcom_nandc_select_chip;
-+	chip->read_byte		= qcom_nandc_read_byte;
-+	chip->read_buf		= qcom_nandc_read_buf;
-+	chip->write_buf		= qcom_nandc_write_buf;
-+
-+	chip->options |= NAND_NO_SUBPAGE_WRITE | NAND_USE_BOUNCE_BUFFER;
-+	if (this->bus_width == 16)
-+		chip->options |= NAND_BUSWIDTH_16;
-+
-+	chip->bbt_options = NAND_BBT_ACCESS_BBM_RAW;
-+	if (of_get_nand_on_flash_bbt(np))
-+		chip->bbt_options = NAND_BBT_USE_FLASH | NAND_BBT_NO_OOB;
-+
-+	qcom_nandc_pre_init(this);
-+
-+	r = nand_scan_ident(mtd, 1, NULL);
-+	if (r)
-+		return r;
-+
-+	r = qcom_nandc_ecc_init(this);
-+	if (r)
-+		return r;
-+
-+	qcom_nandc_hw_post_init(this);
-+
-+	r = nand_scan_tail(mtd);
-+	if (r)
-+		return r;
-+
-+	return mtd_device_parse_register(mtd, NULL, &ppdata, NULL, 0);
-+}
-+
-+static int qcom_nandc_parse_dt(struct platform_device *pdev)
-+{
-+	struct qcom_nandc_data *this = platform_get_drvdata(pdev);
-+	struct device_node *np = this->dev->of_node;
-+	int r;
-+
-+	this->ecc_strength = of_get_nand_ecc_strength(np);
-+	if (this->ecc_strength < 0) {
-+		dev_warn(this->dev,
-+			"incorrect ecc strength, setting to 4 bits/step\n");
-+		this->ecc_strength = 4;
-+	}
-+
-+	this->bus_width = of_get_nand_bus_width(np);
-+	if (this->bus_width < 0) {
-+		dev_warn(this->dev, "incorrect bus width, setting to 8\n");
-+		this->bus_width = 8;
-+	}
-+
-+	r = of_property_read_u32(np, "qcom,cmd-crci", &this->cmd_crci);
-+	if (r) {
-+		dev_err(this->dev, "command CRCI unspecified\n");
-+		return r;
-+	}
-+
-+	r = of_property_read_u32(np, "qcom,data-crci", &this->data_crci);
-+	if (r) {
-+		dev_err(this->dev, "data CRCI unspecified\n");
-+		return r;
-+	}
-+
-+	return 0;
-+}
-+
-+static int qcom_nandc_probe(struct platform_device *pdev)
-+{
-+	struct qcom_nandc_data *this;
-+	const struct of_device_id *match;
-+	int r;
-+
-+	this = devm_kzalloc(&pdev->dev, sizeof(*this), GFP_KERNEL);
-+	if (!this)
-+		return -ENOMEM;
-+
-+	platform_set_drvdata(pdev, this);
-+
-+	this->pdev = pdev;
-+	this->dev  = &pdev->dev;
-+
-+	match = of_match_device(pdev->dev.driver->of_match_table, &pdev->dev);
-+	if (!match) {
-+		dev_err(&pdev->dev, "failed to match device\n");
-+		return -ENODEV;
-+	}
-+
-+	if (!match->data) {
-+		dev_err(&pdev->dev, "failed to get device data\n");
-+		return -ENODEV;
-+	}
-+
-+	this->ecc_modes = (u32) match->data;
-+
-+	this->res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-+	this->base = devm_ioremap_resource(&pdev->dev, this->res);
-+	if (IS_ERR(this->base))
-+		return PTR_ERR(this->base);
-+
-+	this->core_clk = devm_clk_get(&pdev->dev, "core");
-+	if (IS_ERR(this->core_clk))
-+		return PTR_ERR(this->core_clk);
-+
-+	this->aon_clk = devm_clk_get(&pdev->dev, "aon");
-+	if (IS_ERR(this->aon_clk))
-+		return PTR_ERR(this->aon_clk);
-+
-+	r = qcom_nandc_parse_dt(pdev);
-+	if (r)
-+		return r;
-+
-+	r = qcom_nandc_alloc(this);
-+	if (r)
-+		return r;
-+
-+	r = clk_prepare_enable(this->core_clk);
-+	if (r)
-+		goto err_core_clk;
-+
-+	r = clk_prepare_enable(this->aon_clk);
-+	if (r)
-+		goto err_aon_clk;
-+
-+	r = qcom_nandc_init(this);
-+	if (r)
-+		goto err_init;
-+
-+	return 0;
-+
-+err_init:
-+	clk_disable_unprepare(this->aon_clk);
-+err_aon_clk:
-+	clk_disable_unprepare(this->core_clk);
-+err_core_clk:
-+	qcom_nandc_unalloc(this);
-+
-+	return r;
-+}
-+
-+static int qcom_nandc_remove(struct platform_device *pdev)
-+{
-+	struct qcom_nandc_data *this = platform_get_drvdata(pdev);
-+
-+	qcom_nandc_unalloc(this);
-+
-+	clk_disable_unprepare(this->aon_clk);
-+	clk_disable_unprepare(this->core_clk);
-+
-+	return 0;
-+}
-+
-+#define EBI2_NANDC_ECC_MODES	(ECC_RS_4BIT | ECC_BCH_8BIT)
-+
-+/*
-+ * data will hold a struct pointer containing more differences once we support
-+ * more IPs
-+ */
-+static const struct of_device_id qcom_nandc_of_match[] = {
-+	{	.compatible = "qcom,ebi2-nandc",
-+		.data = (void *) EBI2_NANDC_ECC_MODES,
-+	},
-+	{}
-+};
-+MODULE_DEVICE_TABLE(of, qcom_nandc_of_match);
-+
-+static struct platform_driver qcom_nandc_driver = {
-+	.driver = {
-+		.name = "qcom-nandc",
-+		.of_match_table = qcom_nandc_of_match,
-+	},
-+	.probe   = qcom_nandc_probe,
-+	.remove  = qcom_nandc_remove,
-+};
-+module_platform_driver(qcom_nandc_driver);
-+
-+MODULE_AUTHOR("Archit Taneja <architt@codeaurora.org>");
-+MODULE_DESCRIPTION("Qualcomm NAND Controller driver");
-+MODULE_LICENSE("GPL v2");
---- a/drivers/mtd/nand/Makefile
-+++ b/drivers/mtd/nand/Makefile
-@@ -50,5 +50,6 @@ 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_NAND_QCOM)		+= qcom_nandc.o
- 
- nand-objs := nand_base.o nand_bbt.o nand_timings.o
diff --git a/target/linux/ipq806x/patches-3.18/163-dt-bindings-qcom_nandc-Add-DT-bindings.patch b/target/linux/ipq806x/patches-3.18/163-dt-bindings-qcom_nandc-Add-DT-bindings.patch
deleted file mode 100644
index 6530eb1c86b2f708c1031e7a7f221e10c228a403..0000000000000000000000000000000000000000
--- a/target/linux/ipq806x/patches-3.18/163-dt-bindings-qcom_nandc-Add-DT-bindings.patch
+++ /dev/null
@@ -1,82 +0,0 @@
-Content-Type: text/plain; charset="utf-8"
-MIME-Version: 1.0
-Content-Transfer-Encoding: 7bit
-Subject: [v3,3/5] dt/bindings: qcom_nandc: Add DT bindings
-From: Archit Taneja <architt@codeaurora.org>
-X-Patchwork-Id: 6927141
-Message-Id: <1438578498-32254-4-git-send-email-architt@codeaurora.org>
-To: linux-mtd@lists.infradead.org, dehrenberg@google.com,
-	cernekee@gmail.com, computersforpeace@gmail.com
-Cc: linux-arm-msm@vger.kernel.org, agross@codeaurora.org,
-	sboyd@codeaurora.org, linux-kernel@vger.kernel.org,
-	Archit Taneja <architt@codeaurora.org>, devicetree@vger.kernel.org
-Date: Mon,  3 Aug 2015 10:38:16 +0530
-
-Add DT bindings document for the Qualcomm NAND controller driver.
-
-Cc: devicetree@vger.kernel.org
-
-v3:
-- Don't use '0x' when specifying nand controller address space
-- Add optional property for on-flash bbt usage
-
-Acked-by: Andy Gross <agross@codeaurora.org>
-Signed-off-by: Archit Taneja <architt@codeaurora.org>
-
----
-.../devicetree/bindings/mtd/qcom_nandc.txt         | 49 ++++++++++++++++++++++
- 1 file changed, 49 insertions(+)
- create mode 100644 Documentation/devicetree/bindings/mtd/qcom_nandc.txt
-
---- /dev/null
-+++ b/Documentation/devicetree/bindings/mtd/qcom_nandc.txt
-@@ -0,0 +1,49 @@
-+* Qualcomm NAND controller
-+
-+Required properties:
-+- compatible:		should be "qcom,ebi2-nand" for IPQ806x
-+- reg:			MMIO address range
-+- clocks:		must contain core clock and always on clock
-+- clock-names:		must contain "core" for the core clock and "aon" for the
-+			always on clock
-+- dmas:			DMA specifier, consisting of a phandle to the ADM DMA
-+			controller node and the channel number to be used for
-+			NAND. Refer to dma.txt and qcom_adm.txt for more details
-+- dma-names:		must be "rxtx"
-+- qcom,cmd-crci:	must contain the ADM command type CRCI block instance
-+			number specified for the NAND controller on the given
-+			platform
-+- qcom,data-crci:	must contain the ADM data type CRCI block instance
-+			number specified for the NAND controller on the given
-+			platform
-+
-+Optional properties:
-+- nand-bus-width:	bus width. Must be 8 or 16. If not present, 8 is chosen
-+			as default
-+
-+- nand-ecc-strength:	number of bits to correct per ECC step. Must be 4 or 8
-+			bits. If not present, 4 is chosen as default
-+- nand-on-flash-bbt:	Create/use on-flash bad block table
-+
-+The device tree may optionally contain sub-nodes describing partitions of the
-+address space. See partition.txt for more detail.
-+
-+Example:
-+
-+nand@1ac00000 {
-+	compatible = "qcom,ebi2-nandc";
-+	reg = <0x1ac00000 0x800>;
-+
-+	clocks = <&gcc EBI2_CLK>,
-+		 <&gcc EBI2_AON_CLK>;
-+	clock-names = "core", "aon";
-+
-+	dmas = <&adm_dma 3>;
-+	dma-names = "rxtx";
-+	qcom,cmd-crci = <15>;
-+	qcom,data-crci = <3>;
-+
-+	partition@0 {
-+	...
-+	};
-+};
diff --git a/target/linux/ipq806x/patches-3.18/164-arm-qcom-dts-Add-NAND-controller-node-for-ipq806x.patch b/target/linux/ipq806x/patches-3.18/164-arm-qcom-dts-Add-NAND-controller-node-for-ipq806x.patch
deleted file mode 100644
index 6a8ec4ac4b62e6f9df0b0625a848befd92cb10c6..0000000000000000000000000000000000000000
--- a/target/linux/ipq806x/patches-3.18/164-arm-qcom-dts-Add-NAND-controller-node-for-ipq806x.patch
+++ /dev/null
@@ -1,51 +0,0 @@
-Content-Type: text/plain; charset="utf-8"
-MIME-Version: 1.0
-Content-Transfer-Encoding: 7bit
-Subject: [v3,4/5] arm: qcom: dts: Add NAND controller node for ipq806x
-From: Archit Taneja <architt@codeaurora.org>
-X-Patchwork-Id: 6927121
-Message-Id: <1438578498-32254-5-git-send-email-architt@codeaurora.org>
-To: linux-mtd@lists.infradead.org, dehrenberg@google.com,
-	cernekee@gmail.com, computersforpeace@gmail.com
-Cc: linux-arm-msm@vger.kernel.org, agross@codeaurora.org,
-	sboyd@codeaurora.org, linux-kernel@vger.kernel.org,
-	Archit Taneja <architt@codeaurora.org>, devicetree@vger.kernel.org
-Date: Mon,  3 Aug 2015 10:38:17 +0530
-
-The nand controller in IPQ806x is of the 'EBI2 type'. Use the corresponding
-compatible string.
-
-Cc: devicetree@vger.kernel.org
-
-Reviewed-by: Andy Gross <agross@codeaurora.org>
-Signed-off-by: Archit Taneja <architt@codeaurora.org>
-
----
-arch/arm/boot/dts/qcom-ipq8064.dtsi | 15 +++++++++++++++
- 1 file changed, 15 insertions(+)
-
---- a/arch/arm/boot/dts/qcom-ipq8064.dtsi
-+++ b/arch/arm/boot/dts/qcom-ipq8064.dtsi
-@@ -725,6 +725,22 @@
- 			status = "disabled";
- 		};
- 
-+		nand@1ac00000 {
-+			compatible = "qcom,ebi2-nandc";
-+			reg = <0x1ac00000 0x800>;
-+
-+			clocks = <&gcc EBI2_CLK>,
-+				 <&gcc EBI2_AON_CLK>;
-+			clock-names = "core", "aon";
-+
-+			dmas = <&adm_dma 3>;
-+			dma-names = "rxtx";
-+			qcom,cmd-crci = <15>;
-+			qcom,data-crci = <3>;
-+
-+			status = "disabled";
-+		};
-+
- 	};
- 
- 	sfpb_mutex: sfpb-mutex {
diff --git a/target/linux/ipq806x/patches-3.18/165-arm-qcom-dts-Enable-NAND-node-on-IPQ8064-AP148-platform.patch b/target/linux/ipq806x/patches-3.18/165-arm-qcom-dts-Enable-NAND-node-on-IPQ8064-AP148-platform.patch
deleted file mode 100644
index 9c7c3a3af0169ffaf4d8f0da7210d985f8241c69..0000000000000000000000000000000000000000
--- a/target/linux/ipq806x/patches-3.18/165-arm-qcom-dts-Enable-NAND-node-on-IPQ8064-AP148-platform.patch
+++ /dev/null
@@ -1,79 +0,0 @@
-Content-Type: text/plain; charset="utf-8"
-MIME-Version: 1.0
-Content-Transfer-Encoding: 7bit
-Subject: [v3,5/5] arm: qcom: dts: Enable NAND node on IPQ8064 AP148 platform
-From: Archit Taneja <architt@codeaurora.org>
-X-Patchwork-Id: 6927091
-Message-Id: <1438578498-32254-6-git-send-email-architt@codeaurora.org>
-To: linux-mtd@lists.infradead.org, dehrenberg@google.com,
-	cernekee@gmail.com, computersforpeace@gmail.com
-Cc: linux-arm-msm@vger.kernel.org, agross@codeaurora.org,
-	sboyd@codeaurora.org, linux-kernel@vger.kernel.org,
-	Archit Taneja <architt@codeaurora.org>, devicetree@vger.kernel.org
-Date: Mon,  3 Aug 2015 10:38:18 +0530
-
-Enable the NAND controller node on the AP148 platform. Provide pinmux
-information.
-
-Cc: devicetree@vger.kernel.org
-
-Signed-off-by: Archit Taneja <architt@codeaurora.org>
-
----
-arch/arm/boot/dts/qcom-ipq8064-ap148.dts | 36 ++++++++++++++++++++++++++++++++
- 1 file changed, 36 insertions(+)
-
---- a/arch/arm/boot/dts/qcom-ipq8064-ap148.dts
-+++ b/arch/arm/boot/dts/qcom-ipq8064-ap148.dts
-@@ -43,6 +43,31 @@
- 					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 {
-@@ -125,5 +150,19 @@
- 			status = "ok";
- 			phy-tx0-term-offset = <7>;
- 		};
-+
-+		nand@1ac00000 {
-+			status = "ok";
-+
-+			pinctrl-0 = <&nand_pins>;
-+			pinctrl-names = "default";
-+
-+			nand-ecc-strength = <4>;
-+			nand-bus-width = <8>;
-+		};
- 	};
- };
-+
-+&adm_dma {
-+	status = "ok";
-+};
diff --git a/target/linux/ipq806x/patches-3.18/166-arch-qcom-dts-enable-qcom-smem-on-AP148-NAND.patch b/target/linux/ipq806x/patches-3.18/166-arch-qcom-dts-enable-qcom-smem-on-AP148-NAND.patch
deleted file mode 100644
index 1db21e4edcb1e6426f4b269655c7934e6a87ce98..0000000000000000000000000000000000000000
--- a/target/linux/ipq806x/patches-3.18/166-arch-qcom-dts-enable-qcom-smem-on-AP148-NAND.patch
+++ /dev/null
@@ -1,11 +0,0 @@
---- a/arch/arm/boot/dts/qcom-ipq8064-ap148.dts
-+++ b/arch/arm/boot/dts/qcom-ipq8064-ap148.dts
-@@ -159,6 +159,8 @@
- 
- 			nand-ecc-strength = <4>;
- 			nand-bus-width = <8>;
-+
-+			linux,part-probe = "qcom-smem";
- 		};
- 	};
- };
diff --git a/target/linux/ipq806x/patches-3.18/300-arch-arm-force-ZRELADDR-on-arch-qcom.patch b/target/linux/ipq806x/patches-3.18/300-arch-arm-force-ZRELADDR-on-arch-qcom.patch
deleted file mode 100644
index 8669b0257ca6e3053a2a5cba245458cebae415ea..0000000000000000000000000000000000000000
--- a/target/linux/ipq806x/patches-3.18/300-arch-arm-force-ZRELADDR-on-arch-qcom.patch
+++ /dev/null
@@ -1,62 +0,0 @@
-From b12e230f09d4481424e6a5d7e2ae566b6954e83f Mon Sep 17 00:00:00 2001
-From: Mathieu Olivari <mathieu@codeaurora.org>
-Date: Wed, 29 Apr 2015 15:21:46 -0700
-Subject: [PATCH] HACK: arch: arm: force ZRELADDR on arch-qcom
-
-ARCH_QCOM is using the ARCH_MULTIPLATFORM option, as now recommended
-on most ARM architectures. This automatically calculate ZRELADDR by
-masking PHYS_OFFSET with 0xf8000000.
-
-However, on IPQ806x, the first ~20MB of RAM is reserved for the hardware
-network accelerators, and the bootloader removes this section from the
-layout passed from the ATAGS (when used).
-
-For newer bootloader, when DT is used, this is not a problem, we just
-reserve this memory in the device tree. But if the bootloader doesn't
-have DT support, then ATAGS have to be used. In this case, the ARM
-decompressor will position the kernel in this low mem, which will not be
-in the RAM section mapped by the bootloader, which means the kernel will
-freeze in the middle of the boot process trying to map the memory.
-
-As a work around, this patch allows disabling AUTO_ZRELADDR when
-ARCH_QCOM is selected. It makes the zImage usage possible on bootloaders
-which don't support device-tree, which is the case on certain early
-IPQ806x based designs.
-
-Signed-off-by: Mathieu Olivari <mathieu@codeaurora.org>
----
- arch/arm/Kconfig                 | 2 +-
- arch/arm/Makefile                | 2 ++
- arch/arm/mach-qcom/Makefile.boot | 1 +
- 3 files changed, 4 insertions(+), 1 deletion(-)
- create mode 100644 arch/arm/mach-qcom/Makefile.boot
-
---- a/arch/arm/Kconfig
-+++ b/arch/arm/Kconfig
-@@ -311,7 +311,7 @@ config ARCH_MULTIPLATFORM
- 	select ARCH_WANT_OPTIONAL_GPIOLIB
- 	select ARM_HAS_SG_CHAIN
- 	select ARM_PATCH_PHYS_VIRT
--	select AUTO_ZRELADDR
-+	select AUTO_ZRELADDR if !ARCH_QCOM
- 	select CLKSRC_OF
- 	select COMMON_CLK
- 	select GENERIC_CLOCKEVENTS
---- a/arch/arm/Makefile
-+++ b/arch/arm/Makefile
-@@ -248,9 +248,11 @@ MACHINE  := arch/arm/mach-$(word 1,$(mac
- else
- MACHINE  :=
- endif
-+ifeq ($(CONFIG_ARCH_QCOM),)
- ifeq ($(CONFIG_ARCH_MULTIPLATFORM),y)
- MACHINE  :=
- endif
-+endif
- 
- machdirs := $(patsubst %,arch/arm/mach-%/,$(machine-y))
- platdirs := $(patsubst %,arch/arm/plat-%/,$(sort $(plat-y)))
---- /dev/null
-+++ b/arch/arm/mach-qcom/Makefile.boot
-@@ -0,0 +1 @@
-+zreladdr-y+= 0x42208000
diff --git a/target/linux/ipq806x/patches-3.18/301-ARM-qcom-add-Netgear-Nighthawk-X4-R7500-device-tree.patch b/target/linux/ipq806x/patches-3.18/301-ARM-qcom-add-Netgear-Nighthawk-X4-R7500-device-tree.patch
deleted file mode 100644
index abd7cf631de5c432fc2d8bec52945b994632a19d..0000000000000000000000000000000000000000
--- a/target/linux/ipq806x/patches-3.18/301-ARM-qcom-add-Netgear-Nighthawk-X4-R7500-device-tree.patch
+++ /dev/null
@@ -1,367 +0,0 @@
-From 7e77aa188a7a7c4391856a9e5ef5ef58f769e679 Mon Sep 17 00:00:00 2001
-From: Jonas Gorski <jogo@openwrt.org>
-Date: Sun, 9 Aug 2015 13:02:38 +0200
-Subject: [PATCH] ARM: qcom: add Netgear Nighthawk X4 R7500 device tree
-
-Signed-off-by: Jonas Gorski <jogo@openwrt.org>
----
- arch/arm/boot/dts/Makefile               |   1 +
- arch/arm/boot/dts/qcom-ipq8064-r7500.dts | 370 +++++++++++++++++++++++++++++++
- 2 files changed, 371 insertions(+)
- create mode 100644 arch/arm/boot/dts/qcom-ipq8064-r7500.dts
-
---- a/arch/arm/boot/dts/Makefile
-+++ b/arch/arm/boot/dts/Makefile
-@@ -361,6 +361,7 @@ dtb-$(CONFIG_ARCH_QCOM) += \
- 	qcom-apq8084-mtp.dtb \
- 	qcom-ipq8064-ap148.dtb \
- 	qcom-ipq8064-db149.dtb \
-+	qcom-ipq8064-r7500.dtb \
- 	qcom-msm8660-surf.dtb \
- 	qcom-msm8960-cdp.dtb \
- 	qcom-msm8974-sony-xperia-honami.dtb
---- /dev/null
-+++ b/arch/arm/boot/dts/qcom-ipq8064-r7500.dts
-@@ -0,0 +1,342 @@
-+#include "qcom-ipq8064-v1.0.dtsi"
-+
-+#include <dt-bindings/input/input.h>
-+
-+/ {
-+	model = "Netgear Nighthawk X4 R7500";
-+	compatible = "netgear,r7500", "qcom,ipq8064";
-+
-+	memory@0 {
-+		reg = <0x42000000 0xe000000>;
-+		device_type = "memory";
-+	};
-+
-+	reserved-memory {
-+		#address-cells = <1>;
-+		#size-cells = <1>;
-+		ranges;
-+		rsvd@41200000 {
-+			reg = <0x41200000 0x300000>;
-+			no-map;
-+		};
-+	};
-+
-+	aliases {
-+		serial0 = &uart4;
-+		mdio-gpio0 = &mdio0;
-+	};
-+
-+	chosen {
-+		bootargs = "rootfstype=squashfs noinitrd";
-+		linux,stdout-path = "serial0:115200n8";
-+	};
-+
-+	soc {
-+		pinmux@800000 {
-+			i2c4_pins: i2c4_pinmux {
-+				pins = "gpio12", "gpio13";
-+				function = "gsbi4";
-+				bias-disable;
-+			};
-+
-+			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;
-+				};
-+			};
-+
-+			mdio0_pins: mdio0_pins {
-+				mux {
-+					pins = "gpio0", "gpio1";
-+					function = "gpio";
-+					drive-strength = <8>;
-+					bias-disable;
-+				};
-+			};
-+
-+			rgmii2_pins: rgmii2_pins {
-+				mux {
-+					pins = "gpio27", "gpio28", "gpio29", "gpio30", "gpio31", "gpio32",
-+					       "gpio51", "gpio52", "gpio59", "gpio60", "gpio61", "gpio62" ;
-+					function = "rgmii2";
-+					drive-strength = <8>;
-+					bias-disable;
-+				};
-+			};
-+		};
-+
-+		gsbi@16300000 {
-+			qcom,mode = <GSBI_PROT_I2C_UART>;
-+			status = "ok";
-+			serial@16340000 {
-+				status = "ok";
-+			};
-+			/*
-+			 * The i2c device on gsbi4 should not be enabled.
-+			 * On ipq806x designs gsbi4 i2c is meant for exclusive
-+			 * RPM usage. Turning this on in kernel manifests as
-+			 * i2c failure for the RPM.
-+			 */
-+		};
-+
-+		sata-phy@1b400000 {
-+			status = "ok";
-+		};
-+
-+		sata@29000000 {
-+			status = "ok";
-+		};
-+
-+		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";
-+		};
-+
-+		pcie0: pci@1b500000 {
-+			status = "ok";
-+		};
-+
-+		pcie1: pci@1b700000 {
-+			status = "ok";
-+		};
-+
-+		nand@1ac00000 {
-+			status = "ok";
-+
-+			pinctrl-0 = <&nand_pins>;
-+			pinctrl-names = "default";
-+
-+			nand-ecc-strength = <4>;
-+			nand-bus-width = <8>;
-+
-+			#address-cells = <1>;
-+			#size-cells = <1>;
-+
-+			qcadata@0 {
-+				label = "qcadata";
-+				reg = <0x0000000 0x0c80000>;
-+				read-only;
-+			};
-+
-+			APPSBL@c80000 {
-+				label = "APPSBL";
-+				reg = <0x0c80000 0x0500000>;
-+				read-only;
-+			};
-+
-+			APPSBLENV@1180000 {
-+				label = "APPSBLENV";
-+				reg = <0x1180000 0x0080000>;
-+				read-only;
-+			};
-+
-+			art: art@1200000 {
-+				label = "art";
-+				reg = <0x1200000 0x0140000>;
-+				read-only;
-+			};
-+
-+			kernel@1340000 {
-+				label = "kernel";
-+				reg = <0x1340000 0x0200000>;
-+			};
-+
-+			ubi@1540000 {
-+				label = "ubi";
-+				reg = <0x1540000 0x1800000>;
-+			};
-+
-+			netgear@2d40000 {
-+				label = "netgear";
-+				reg = <0x2d40000 0x0c00000>;
-+				read-only;
-+			};
-+
-+			reserve@3940000 {
-+				label = "reserve";
-+				reg = <0x3940000 0x46c0000>;
-+				read-only;
-+			};
-+
-+			firmware@1340000 {
-+				label = "firmware";
-+				reg = <0x1340000 0x1a00000>;
-+			};
-+
-+		};
-+
-+		mdio0: mdio {
-+			compatible = "virtual,mdio-gpio";
-+			#address-cells = <1>;
-+			#size-cells = <0>;
-+			gpios = <&qcom_pinmux 1 0 &qcom_pinmux 0 0>;
-+			pinctrl-0 = <&mdio0_pins>;
-+			pinctrl-names = "default";
-+
-+			phy0: ethernet-phy@0 {
-+				device_type = "ethernet-phy";
-+				reg = <0>;
-+				qca,ar8327-initvals = <
-+					0x00004 0x7600000   /* PAD0_MODE */
-+					0x00008 0x1000000   /* PAD5_MODE */
-+					0x0000c 0x80        /* PAD6_MODE */
-+					0x000e4 0xaa545     /* MAC_POWER_SEL */
-+					0x000e0 0xc74164de  /* SGMII_CTRL */
-+					0x0007c 0x4e        /* PORT0_STATUS */
-+					0x00094 0x4e        /* PORT6_STATUS */
-+					>;
-+			};
-+
-+			phy4: ethernet-phy@4 {
-+				device_type = "ethernet-phy";
-+				reg = <4>;
-+			};
-+		};
-+
-+		gmac1: ethernet@37200000 {
-+			status = "ok";
-+			phy-mode = "rgmii";
-+			qcom,id = <1>;
-+
-+			pinctrl-0 = <&rgmii2_pins>;
-+			pinctrl-names = "default";
-+
-+			mtd-mac-address = <&art 6>;
-+
-+			fixed-link {
-+				speed = <1000>;
-+				full-duplex;
-+			};
-+		};
-+
-+		gmac2: ethernet@37400000 {
-+			status = "ok";
-+			phy-mode = "sgmii";
-+			qcom,id = <2>;
-+
-+			mtd-mac-address = <&art 0>;
-+
-+			fixed-link {
-+				speed = <1000>;
-+				full-duplex;
-+			};
-+		};
-+	};
-+
-+	gpio-keys {
-+		compatible = "gpio-keys";
-+
-+		wifi {
-+			label = "wifi";
-+			gpios = <&qcom_pinmux 6 1>;
-+			linux,code = <KEY_WLAN>;
-+		};
-+
-+		reset {
-+			label = "reset";
-+			gpios = <&qcom_pinmux 54 1>;
-+			linux,code = <KEY_RESTART>;
-+		};
-+
-+		wps {
-+			label = "wps";
-+			gpios = <&qcom_pinmux 65 1>;
-+			linux,code = <KEY_WPS_BUTTON>;
-+		};
-+	};
-+
-+	gpio-leds {
-+		compatible = "gpio-leds";
-+
-+		usb1 {
-+			label = "r7500:amber:usb1";
-+			gpios = <&qcom_pinmux 7 0>;
-+		};
-+
-+		usb3 {
-+			label = "r7500:amber:usb3";
-+			gpios = <&qcom_pinmux 8 0>;
-+		};
-+
-+		status {
-+			label = "r7500:amber:status";
-+			gpios = <&qcom_pinmux 9 0>;
-+		};
-+
-+		internet {
-+			label = "r7500:white:internet";
-+			gpios = <&qcom_pinmux 22 0>;
-+		};
-+
-+		wan {
-+			label = "r7500:white:wan";
-+			gpios = <&qcom_pinmux 23 0>;
-+		};
-+
-+		wps {
-+			label = "r7500:white:wps";
-+			gpios = <&qcom_pinmux 24 0>;
-+		};
-+
-+		esata {
-+			label = "r7500:white:esata";
-+			gpios = <&qcom_pinmux 26 0>;
-+		};
-+
-+		power {
-+			label = "r7500:white:power";
-+			gpios = <&qcom_pinmux 53 0>;
-+			default-state = "on";
-+		};
-+
-+		rfkill {
-+			label = "r7500:white:rfkill";
-+			gpios = <&qcom_pinmux 64 0>;
-+		};
-+
-+		wifi5g {
-+			label = "r7500:white:wifi5g";
-+			gpios = <&qcom_pinmux 67 0>;
-+		};
-+	};
-+};
-+
-+&adm_dma {
-+	status = "ok";
-+};
diff --git a/target/linux/ipq806x/patches-3.18/302-mtd-qcom-smem-rename-rootfs-ubi.patch b/target/linux/ipq806x/patches-3.18/302-mtd-qcom-smem-rename-rootfs-ubi.patch
deleted file mode 100644
index 471a87ba680671d54818f63f827b8e94a0553ac8..0000000000000000000000000000000000000000
--- a/target/linux/ipq806x/patches-3.18/302-mtd-qcom-smem-rename-rootfs-ubi.patch
+++ /dev/null
@@ -1,13 +0,0 @@
---- a/drivers/mtd/qcom_smem_part.c
-+++ b/drivers/mtd/qcom_smem_part.c
-@@ -192,6 +192,10 @@ static int parse_qcom_smem_partitions(st
- 		m_part->size = le32_to_cpu(s_part->size) * (*smem_blksz);
- 		m_part->offset = le32_to_cpu(s_part->start) * (*smem_blksz);
- 
-+		/* "rootfs" conflicts with OpenWrt auto mounting */
-+		if (mtd_type_is_nand(master) && !strcmp(m_part->name, "rootfs"))
-+			m_part->name = "ubi";
-+
- 		/*
- 		 * The last SMEM partition may have its size marked as
- 		 * something like 0xffffffff, which means "until the end of the
diff --git a/target/linux/ipq806x/patches-3.18/700-clk-qcom-Add-support-for-NSS-GMAC-clocks-and-resets.patch b/target/linux/ipq806x/patches-3.18/700-clk-qcom-Add-support-for-NSS-GMAC-clocks-and-resets.patch
deleted file mode 100644
index 22d28ac638348c37471b2965e3457067b2ad7927..0000000000000000000000000000000000000000
--- a/target/linux/ipq806x/patches-3.18/700-clk-qcom-Add-support-for-NSS-GMAC-clocks-and-resets.patch
+++ /dev/null
@@ -1,733 +0,0 @@
-From 2fbb18f85826a9ba308fedb2cf90d3a661a39fd7 Mon Sep 17 00:00:00 2001
-From: Stephen Boyd <sboyd@codeaurora.org>
-Date: Fri, 27 Mar 2015 00:16:14 -0700
-Subject: [PATCH] clk: qcom: Add support for NSS/GMAC clocks and resets
-
-Add the NSS/GMAC clocks and the TCM clock and NSS resets.
-
-Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
----
- drivers/clk/qcom/gcc-ipq806x.c               | 594 ++++++++++++++++++++++++++-
- drivers/clk/qcom/gcc-ipq806x.c.rej           |  50 +++
- include/dt-bindings/clock/qcom,gcc-ipq806x.h |   2 +
- include/dt-bindings/reset/qcom,gcc-ipq806x.h |  43 ++
- 4 files changed, 688 insertions(+), 1 deletion(-)
- create mode 100644 drivers/clk/qcom/gcc-ipq806x.c.rej
-
---- a/drivers/clk/qcom/gcc-ipq806x.c
-+++ b/drivers/clk/qcom/gcc-ipq806x.c
-@@ -209,11 +209,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,
-@@ -264,6 +299,22 @@ static const char *gcc_pxo_pll8_pll0_map
- 	"pll0_vote",
- };
- 
-+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 },
-@@ -2269,6 +2320,472 @@ static struct clk_branch ebi2_aon_clk =
- 	},
- };
- 
-+static const struct freq_tbl clk_tbl_gmac[] = {
-+	{ 133000000, P_PLL0, 1,  50, 301 },
-+	{ 266000000, P_PLL0, 1, 127, 382 },
-+	{ }
-+};
-+
-+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 struct clk_regmap *gcc_ipq806x_clks[] = {
- 	[PLL0] = &pll0.clkr,
- 	[PLL0_VOTE] = &pll0_vote,
-@@ -2277,6 +2794,7 @@ static struct clk_regmap *gcc_ipq806x_cl
- 	[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,
-@@ -2376,6 +2894,18 @@ static struct clk_regmap *gcc_ipq806x_cl
- 	[PLL9] = &hfpll0.clkr,
- 	[PLL10] = &hfpll1.clkr,
- 	[PLL12] = &hfpll_l2.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,
- };
- 
- static const struct qcom_reset_map gcc_ipq806x_resets[] = {
-@@ -2494,6 +3024,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 = {
-@@ -2522,6 +3094,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);
-@@ -2532,7 +3106,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
-@@ -290,5 +290,7 @@
- #define UBI32_CORE1_CLK				279
- #define UBI32_CORE2_CLK				280
- #define EBI2_AON_CLK				281
-+#define NSSTCM_CLK_SRC				282
-+#define NSSTCM_CLK				283
- 
- #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-3.18/701-stmmac_update_to_4.3.patch b/target/linux/ipq806x/patches-3.18/701-stmmac_update_to_4.3.patch
deleted file mode 100644
index 539d1a1c445328e954d090ac5af3d2aa5bb661eb..0000000000000000000000000000000000000000
--- a/target/linux/ipq806x/patches-3.18/701-stmmac_update_to_4.3.patch
+++ /dev/null
@@ -1,4258 +0,0 @@
---- a/include/linux/stmmac.h
-+++ b/include/linux/stmmac.h
-@@ -99,6 +99,7 @@ struct plat_stmmacenet_data {
- 	int phy_addr;
- 	int interface;
- 	struct stmmac_mdio_bus_data *mdio_bus_data;
-+	struct device_node *phy_node;
- 	struct stmmac_dma_cfg *dma_cfg;
- 	int clk_csr;
- 	int has_gmac;
-@@ -114,32 +115,12 @@ struct plat_stmmacenet_data {
- 	int maxmtu;
- 	int multicast_filter_bins;
- 	int unicast_filter_entries;
-+	int tx_fifo_size;
-+	int rx_fifo_size;
- 	void (*fix_mac_speed)(void *priv, unsigned int speed);
- 	void (*bus_setup)(void __iomem *ioaddr);
--	void *(*setup)(struct platform_device *pdev);
--	void (*free)(struct platform_device *pdev, void *priv);
- 	int (*init)(struct platform_device *pdev, void *priv);
- 	void (*exit)(struct platform_device *pdev, void *priv);
--	void *custom_cfg;
--	void *custom_data;
- 	void *bsp_priv;
- };
--
--/* of_data for SoC glue layer device tree bindings */
--
--struct stmmac_of_data {
--	int has_gmac;
--	int enh_desc;
--	int tx_coe;
--	int rx_coe;
--	int bugged_jumbo;
--	int pmt;
--	int riwt_off;
--	void (*fix_mac_speed)(void *priv, unsigned int speed);
--	void (*bus_setup)(void __iomem *ioaddr);
--	void *(*setup)(struct platform_device *pdev);
--	void (*free)(struct platform_device *pdev, void *priv);
--	int (*init)(struct platform_device *pdev, void *priv);
--	void (*exit)(struct platform_device *pdev, void *priv);
--};
- #endif
---- a/drivers/net/ethernet/stmicro/Kconfig
-+++ b/drivers/net/ethernet/stmicro/Kconfig
-@@ -7,9 +7,7 @@ config NET_VENDOR_STMICRO
- 	default y
- 	depends on HAS_IOMEM
- 	---help---
--	  If you have a network (Ethernet) card belonging to this class, say Y
--	  and read the Ethernet-HOWTO, available from
--	  <http://www.tldp.org/docs.html#howto>.
-+	  If you have a network (Ethernet) card belonging to this class, say Y.
- 
- 	  Note that the answer to this question doesn't directly affect the
- 	  kernel: saying N will just cause the configurator to skip all
---- a/drivers/net/ethernet/stmicro/stmmac/Kconfig
-+++ b/drivers/net/ethernet/stmicro/stmmac/Kconfig
-@@ -14,21 +14,54 @@ config STMMAC_ETH
- if STMMAC_ETH
- 
- config STMMAC_PLATFORM
--	bool "STMMAC Platform bus support"
-+	tristate "STMMAC Platform bus support"
- 	depends on STMMAC_ETH
-+	select MFD_SYSCON
- 	default y
- 	---help---
--	  This selects the platform specific bus support for
--	  the stmmac device driver. This is the driver used
--	  on many embedded STM platforms based on ARM and SuperH
--	  processors.
-+	  This selects the platform specific bus support for the stmmac driver.
-+	  This is the driver used on several SoCs:
-+	  STi, Allwinner, Amlogic Meson, Altera SOCFPGA.
-+
- 	  If you have a controller with this interface, say Y or M here.
- 
- 	  If unsure, say N.
- 
-+if STMMAC_PLATFORM
-+
-+config DWMAC_GENERIC
-+	tristate "Generic driver for DWMAC"
-+	default STMMAC_PLATFORM
-+	---help---
-+	  Generic DWMAC driver for platforms that don't require any
-+	  platform specific code to function or is using platform
-+	  data for setup.
-+
-+config DWMAC_IPQ806X
-+	tristate "QCA IPQ806x DWMAC support"
-+	default ARCH_QCOM
-+	depends on OF
-+	select MFD_SYSCON
-+	help
-+	  Support for QCA IPQ806X DWMAC Ethernet.
-+
-+	  This selects the IPQ806x SoC glue layer support for the stmmac
-+	  device driver. This driver does not use any of the hardware
-+	  acceleration features available on this SoC. Network devices
-+	  will behave like standard non-accelerated ethernet interfaces.
-+
-+config DWMAC_LPC18XX
-+	tristate "NXP LPC18xx/43xx DWMAC support"
-+	default ARCH_LPC18XX
-+	depends on OF
-+	select MFD_SYSCON
-+	---help---
-+	  Support for NXP LPC18xx/43xx DWMAC Ethernet.
-+
- config DWMAC_MESON
--	bool "Amlogic Meson dwmac support"
--	depends on STMMAC_PLATFORM && ARCH_MESON
-+	tristate "Amlogic Meson dwmac support"
-+	default ARCH_MESON
-+	depends on OF
- 	help
- 	  Support for Ethernet controller on Amlogic Meson SoCs.
- 
-@@ -36,9 +69,22 @@ config DWMAC_MESON
- 	  the stmmac device driver. This driver is used for Meson6 and
- 	  Meson8 SoCs.
- 
-+config DWMAC_ROCKCHIP
-+	tristate "Rockchip dwmac support"
-+	default ARCH_ROCKCHIP
-+	depends on OF
-+	select MFD_SYSCON
-+	help
-+	  Support for Ethernet controller on Rockchip RK3288 SoC.
-+
-+	  This selects the Rockchip RK3288 SoC glue layer support for
-+	  the stmmac device driver.
-+
- config DWMAC_SOCFPGA
--	bool "SOCFPGA dwmac support"
--	depends on STMMAC_PLATFORM && MFD_SYSCON && (ARCH_SOCFPGA || COMPILE_TEST)
-+	tristate "SOCFPGA dwmac support"
-+	default ARCH_SOCFPGA
-+	depends on OF
-+	select MFD_SYSCON
- 	help
- 	  Support for ethernet controller on Altera SOCFPGA
- 
-@@ -46,21 +92,11 @@ config DWMAC_SOCFPGA
- 	  for the stmmac device driver. This driver is used for
- 	  arria5 and cyclone5 FPGA SoCs.
- 
--config DWMAC_SUNXI
--	bool "Allwinner GMAC support"
--	depends on STMMAC_PLATFORM && ARCH_SUNXI
--	default y
--	---help---
--	  Support for Allwinner A20/A31 GMAC ethernet controllers.
--
--	  This selects Allwinner SoC glue layer support for the
--	  stmmac device driver. This driver is used for A20/A31
--	  GMAC 	  ethernet controller.
--
- config DWMAC_STI
--	bool "STi GMAC support"
--	depends on STMMAC_PLATFORM && ARCH_STI
--	default y
-+	tristate "STi GMAC support"
-+	default ARCH_STI
-+	depends on OF
-+	select MFD_SYSCON
- 	---help---
- 	  Support for ethernet controller on STi SOCs.
- 
-@@ -68,8 +104,20 @@ config DWMAC_STI
- 	  device driver. This driver is used on for the STi series
- 	  SOCs GMAC ethernet controller.
- 
-+config DWMAC_SUNXI
-+	tristate "Allwinner GMAC support"
-+	default ARCH_SUNXI
-+	depends on OF
-+	---help---
-+	  Support for Allwinner A20/A31 GMAC ethernet controllers.
-+
-+	  This selects Allwinner SoC glue layer support for the
-+	  stmmac device driver. This driver is used for A20/A31
-+	  GMAC ethernet controller.
-+endif
-+
- config STMMAC_PCI
--	bool "STMMAC PCI bus support"
-+	tristate "STMMAC PCI bus support"
- 	depends on STMMAC_ETH && PCI
- 	---help---
- 	  This is to select the Synopsys DWMAC available on PCI devices,
-@@ -79,22 +127,4 @@ config STMMAC_PCI
- 	  D1215994A VIRTEX FPGA board.
- 
- 	  If unsure, say N.
--
--config STMMAC_DEBUG_FS
--	bool "Enable monitoring via sysFS "
--	default n
--	depends on STMMAC_ETH && DEBUG_FS
--	---help---
--	  The stmmac entry in /sys reports DMA TX/RX rings
--	  or (if supported) the HW cap register.
--
--config STMMAC_DA
--	bool "STMMAC DMA arbitration scheme"
--	default n
--	---help---
--	  Selecting this option, rx has priority over Tx (only for Giga
--	  Ethernet device).
--	  By default, the DMA arbitration scheme is based on Round-robin
--	  (rx:tx priority is 1:1).
--
- endif
---- a/drivers/net/ethernet/stmicro/stmmac/Makefile
-+++ b/drivers/net/ethernet/stmicro/stmmac/Makefile
-@@ -1,11 +1,20 @@
- obj-$(CONFIG_STMMAC_ETH) += stmmac.o
--stmmac-$(CONFIG_STMMAC_PLATFORM) += stmmac_platform.o
--stmmac-$(CONFIG_STMMAC_PCI) += stmmac_pci.o
--stmmac-$(CONFIG_DWMAC_MESON) += dwmac-meson.o
--stmmac-$(CONFIG_DWMAC_SUNXI) += dwmac-sunxi.o
--stmmac-$(CONFIG_DWMAC_STI) += dwmac-sti.o
--stmmac-$(CONFIG_DWMAC_SOCFPGA) += dwmac-socfpga.o
- stmmac-objs:= stmmac_main.o stmmac_ethtool.o stmmac_mdio.o ring_mode.o	\
--	      chain_mode.o dwmac_lib.o dwmac1000_core.o  dwmac1000_dma.o \
--	      dwmac100_core.o dwmac100_dma.o enh_desc.o  norm_desc.o \
-+	      chain_mode.o dwmac_lib.o dwmac1000_core.o dwmac1000_dma.o	\
-+	      dwmac100_core.o dwmac100_dma.o enh_desc.o norm_desc.o	\
- 	      mmc_core.o stmmac_hwtstamp.o stmmac_ptp.o $(stmmac-y)
-+
-+# Ordering matters. Generic driver must be last.
-+obj-$(CONFIG_STMMAC_PLATFORM)	+= stmmac-platform.o
-+obj-$(CONFIG_DWMAC_IPQ806X)	+= dwmac-ipq806x.o
-+obj-$(CONFIG_DWMAC_LPC18XX)	+= dwmac-lpc18xx.o
-+obj-$(CONFIG_DWMAC_MESON)	+= dwmac-meson.o
-+obj-$(CONFIG_DWMAC_ROCKCHIP)	+= dwmac-rk.o
-+obj-$(CONFIG_DWMAC_SOCFPGA)	+= dwmac-socfpga.o
-+obj-$(CONFIG_DWMAC_STI)		+= dwmac-sti.o
-+obj-$(CONFIG_DWMAC_SUNXI)	+= dwmac-sunxi.o
-+obj-$(CONFIG_DWMAC_GENERIC)	+= dwmac-generic.o
-+stmmac-platform-objs:= stmmac_platform.o
-+
-+obj-$(CONFIG_STMMAC_PCI) += stmmac-pci.o
-+stmmac-pci-objs:= stmmac_pci.o
---- a/drivers/net/ethernet/stmicro/stmmac/common.h
-+++ b/drivers/net/ethernet/stmicro/stmmac/common.h
-@@ -44,6 +44,7 @@
- #undef FRAME_FILTER_DEBUG
- /* #define FRAME_FILTER_DEBUG */
- 
-+/* Extra statistic and debug information exposed by ethtool */
- struct stmmac_extra_stats {
- 	/* Transmit errors */
- 	unsigned long tx_underflow ____cacheline_aligned;
-@@ -149,7 +150,7 @@ struct stmmac_extra_stats {
- #define	MAC_CSR_H_FRQ_MASK	0x20
- 
- #define HASH_TABLE_SIZE 64
--#define PAUSE_TIME 0x200
-+#define PAUSE_TIME 0xffff
- 
- /* Flow Control defines */
- #define FLOW_OFF	0
-@@ -220,6 +221,7 @@ enum dma_irq_status {
- 	handle_tx = 0x8,
- };
- 
-+/* EEE and LPI defines */
- #define	CORE_IRQ_TX_PATH_IN_LPI_MODE	(1 << 0)
- #define	CORE_IRQ_TX_PATH_EXIT_LPI_MODE	(1 << 1)
- #define	CORE_IRQ_RX_PATH_IN_LPI_MODE	(1 << 2)
-@@ -229,6 +231,7 @@ enum dma_irq_status {
- #define	CORE_PCS_LINK_STATUS		(1 << 6)
- #define	CORE_RGMII_IRQ			(1 << 7)
- 
-+/* Physical Coding Sublayer */
- struct rgmii_adv {
- 	unsigned int pause;
- 	unsigned int duplex;
-@@ -294,6 +297,7 @@ struct dma_features {
- 
- #define JUMBO_LEN		9000
- 
-+/* Descriptors helpers */
- struct stmmac_desc_ops {
- 	/* DMA RX descriptor ring initialization */
- 	void (*init_rx_desc) (struct dma_desc *p, int disable_rx_ic, int mode,
-@@ -341,6 +345,10 @@ struct stmmac_desc_ops {
- 	int (*get_rx_timestamp_status) (void *desc, u32 ats);
- };
- 
-+extern const struct stmmac_desc_ops enh_desc_ops;
-+extern const struct stmmac_desc_ops ndesc_ops;
-+
-+/* Specific DMA helpers */
- struct stmmac_dma_ops {
- 	/* DMA core initialization */
- 	int (*init) (void __iomem *ioaddr, int pbl, int fb, int mb,
-@@ -349,7 +357,8 @@ struct stmmac_dma_ops {
- 	void (*dump_regs) (void __iomem *ioaddr);
- 	/* Set tx/rx threshold in the csr6 register
- 	 * An invalid value enables the store-and-forward mode */
--	void (*dma_mode) (void __iomem *ioaddr, int txmode, int rxmode);
-+	void (*dma_mode)(void __iomem *ioaddr, int txmode, int rxmode,
-+			 int rxfifosz);
- 	/* To track extra statistic (if supported) */
- 	void (*dma_diagnostic_fr) (void *data, struct stmmac_extra_stats *x,
- 				   void __iomem *ioaddr);
-@@ -370,6 +379,7 @@ struct stmmac_dma_ops {
- 
- struct mac_device_info;
- 
-+/* Helpers to program the MAC core */
- struct stmmac_ops {
- 	/* MAC core initialization */
- 	void (*core_init)(struct mac_device_info *hw, int mtu);
-@@ -400,6 +410,7 @@ struct stmmac_ops {
- 	void (*get_adv)(struct mac_device_info *hw, struct rgmii_adv *adv);
- };
- 
-+/* PTP and HW Timer helpers */
- struct stmmac_hwtimestamp {
- 	void (*config_hw_tstamping) (void __iomem *ioaddr, u32 data);
- 	void (*config_sub_second_increment) (void __iomem *ioaddr);
-@@ -410,6 +421,8 @@ struct stmmac_hwtimestamp {
- 	 u64(*get_systime) (void __iomem *ioaddr);
- };
- 
-+extern const struct stmmac_hwtimestamp stmmac_ptp;
-+
- struct mac_link {
- 	int port;
- 	int duplex;
-@@ -421,6 +434,7 @@ struct mii_regs {
- 	unsigned int data;	/* MII Data */
- };
- 
-+/* Helpers to manage the descriptors for chain and ring modes */
- struct stmmac_mode_ops {
- 	void (*init) (void *des, dma_addr_t phy_addr, unsigned int size,
- 		      unsigned int extend_desc);
---- /dev/null
-+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-generic.c
-@@ -0,0 +1,81 @@
-+/*
-+ * Generic DWMAC platform driver
-+ *
-+ * Copyright (C) 2007-2011  STMicroelectronics Ltd
-+ * Copyright (C) 2015 Joachim Eastwood <manabian@gmail.com>
-+ *
-+ * This file is licensed under the terms of the GNU General Public
-+ * License version 2. This program is licensed "as is" without any
-+ * warranty of any kind, whether express or implied.
-+ */
-+
-+#include <linux/module.h>
-+#include <linux/of.h>
-+#include <linux/platform_device.h>
-+
-+#include "stmmac.h"
-+#include "stmmac_platform.h"
-+
-+static int dwmac_generic_probe(struct platform_device *pdev)
-+{
-+	struct plat_stmmacenet_data *plat_dat;
-+	struct stmmac_resources stmmac_res;
-+	int ret;
-+
-+	ret = stmmac_get_platform_resources(pdev, &stmmac_res);
-+	if (ret)
-+		return ret;
-+
-+	if (pdev->dev.of_node) {
-+		plat_dat = stmmac_probe_config_dt(pdev, &stmmac_res.mac);
-+		if (IS_ERR(plat_dat)) {
-+			dev_err(&pdev->dev, "dt configuration failed\n");
-+			return PTR_ERR(plat_dat);
-+		}
-+	} else {
-+		plat_dat = dev_get_platdata(&pdev->dev);
-+		if (!plat_dat) {
-+			dev_err(&pdev->dev, "no platform data provided\n");
-+			return  -EINVAL;
-+		}
-+
-+		/* Set default value for multicast hash bins */
-+		plat_dat->multicast_filter_bins = HASH_TABLE_SIZE;
-+
-+		/* Set default value for unicast filter entries */
-+		plat_dat->unicast_filter_entries = 1;
-+	}
-+
-+	/* Custom initialisation (if needed) */
-+	if (plat_dat->init) {
-+		ret = plat_dat->init(pdev, plat_dat->bsp_priv);
-+		if (ret)
-+			return ret;
-+	}
-+
-+	return stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res);
-+}
-+
-+static const struct of_device_id dwmac_generic_match[] = {
-+	{ .compatible = "st,spear600-gmac"},
-+	{ .compatible = "snps,dwmac-3.610"},
-+	{ .compatible = "snps,dwmac-3.70a"},
-+	{ .compatible = "snps,dwmac-3.710"},
-+	{ .compatible = "snps,dwmac"},
-+	{ }
-+};
-+MODULE_DEVICE_TABLE(of, dwmac_generic_match);
-+
-+static struct platform_driver dwmac_generic_driver = {
-+	.probe  = dwmac_generic_probe,
-+	.remove = stmmac_pltfr_remove,
-+	.driver = {
-+		.name           = STMMAC_RESOURCE_NAME,
-+		.pm		= &stmmac_pltfr_pm_ops,
-+		.of_match_table = of_match_ptr(dwmac_generic_match),
-+	},
-+};
-+module_platform_driver(dwmac_generic_driver);
-+
-+MODULE_DESCRIPTION("Generic dwmac driver");
-+MODULE_LICENSE("GPL v2");
---- /dev/null
-+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-ipq806x.c
-@@ -0,0 +1,373 @@
-+/*
-+ * Qualcomm Atheros IPQ806x GMAC glue layer
-+ *
-+ * Copyright (C) 2015 The Linux Foundation
-+ *
-+ * Permission to use, copy, modify, and/or distribute this software for any
-+ * purpose with or without fee is hereby granted, provided that the above
-+ * copyright notice and this permission notice appear in all copies.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
-+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
-+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-+ */
-+
-+#include <linux/device.h>
-+#include <linux/platform_device.h>
-+#include <linux/phy.h>
-+#include <linux/regmap.h>
-+#include <linux/clk.h>
-+#include <linux/reset.h>
-+#include <linux/of_net.h>
-+#include <linux/mfd/syscon.h>
-+#include <linux/stmmac.h>
-+#include <linux/of_mdio.h>
-+#include <linux/module.h>
-+
-+#include "stmmac_platform.h"
-+
-+#define NSS_COMMON_CLK_GATE			0x8
-+#define NSS_COMMON_CLK_GATE_PTP_EN(x)		BIT(0x10 + x)
-+#define NSS_COMMON_CLK_GATE_RGMII_RX_EN(x)	BIT(0x9 + (x * 2))
-+#define NSS_COMMON_CLK_GATE_RGMII_TX_EN(x)	BIT(0x8 + (x * 2))
-+#define NSS_COMMON_CLK_GATE_GMII_RX_EN(x)	BIT(0x4 + x)
-+#define NSS_COMMON_CLK_GATE_GMII_TX_EN(x)	BIT(0x0 + x)
-+
-+#define NSS_COMMON_CLK_DIV0			0xC
-+#define NSS_COMMON_CLK_DIV_OFFSET(x)		(x * 8)
-+#define NSS_COMMON_CLK_DIV_MASK			0x7f
-+
-+#define NSS_COMMON_CLK_SRC_CTRL			0x14
-+#define NSS_COMMON_CLK_SRC_CTRL_OFFSET(x)	(x)
-+/* Mode is coded on 1 bit but is different depending on the MAC ID:
-+ * MAC0: QSGMII=0 RGMII=1
-+ * MAC1: QSGMII=0 SGMII=0 RGMII=1
-+ * MAC2 & MAC3: QSGMII=0 SGMII=1
-+ */
-+#define NSS_COMMON_CLK_SRC_CTRL_RGMII(x)	1
-+#define NSS_COMMON_CLK_SRC_CTRL_SGMII(x)	((x >= 2) ? 1 : 0)
-+
-+#define NSS_COMMON_MACSEC_CTL			0x28
-+#define NSS_COMMON_MACSEC_CTL_EXT_BYPASS_EN(x)	(1 << x)
-+
-+#define NSS_COMMON_GMAC_CTL(x)			(0x30 + (x * 4))
-+#define NSS_COMMON_GMAC_CTL_CSYS_REQ		BIT(19)
-+#define NSS_COMMON_GMAC_CTL_PHY_IFACE_SEL	BIT(16)
-+#define NSS_COMMON_GMAC_CTL_IFG_LIMIT_OFFSET	8
-+#define NSS_COMMON_GMAC_CTL_IFG_OFFSET		0
-+#define NSS_COMMON_GMAC_CTL_IFG_MASK		0x3f
-+
-+#define NSS_COMMON_CLK_DIV_RGMII_1000		1
-+#define NSS_COMMON_CLK_DIV_RGMII_100		9
-+#define NSS_COMMON_CLK_DIV_RGMII_10		99
-+#define NSS_COMMON_CLK_DIV_SGMII_1000		0
-+#define NSS_COMMON_CLK_DIV_SGMII_100		4
-+#define NSS_COMMON_CLK_DIV_SGMII_10		49
-+
-+#define QSGMII_PCS_MODE_CTL			0x68
-+#define QSGMII_PCS_MODE_CTL_AUTONEG_EN(x)	BIT((x * 8) + 7)
-+
-+#define QSGMII_PCS_CAL_LCKDT_CTL		0x120
-+#define QSGMII_PCS_CAL_LCKDT_CTL_RST		BIT(19)
-+
-+/* Only GMAC1/2/3 support SGMII and their CTL register are not contiguous */
-+#define QSGMII_PHY_SGMII_CTL(x)			((x == 1) ? 0x134 : \
-+						 (0x13c + (4 * (x - 2))))
-+#define QSGMII_PHY_CDR_EN			BIT(0)
-+#define QSGMII_PHY_RX_FRONT_EN			BIT(1)
-+#define QSGMII_PHY_RX_SIGNAL_DETECT_EN		BIT(2)
-+#define QSGMII_PHY_TX_DRIVER_EN			BIT(3)
-+#define QSGMII_PHY_QSGMII_EN			BIT(7)
-+#define QSGMII_PHY_PHASE_LOOP_GAIN_OFFSET	12
-+#define QSGMII_PHY_PHASE_LOOP_GAIN_MASK		0x7
-+#define QSGMII_PHY_RX_DC_BIAS_OFFSET		18
-+#define QSGMII_PHY_RX_DC_BIAS_MASK		0x3
-+#define QSGMII_PHY_RX_INPUT_EQU_OFFSET		20
-+#define QSGMII_PHY_RX_INPUT_EQU_MASK		0x3
-+#define QSGMII_PHY_CDR_PI_SLEW_OFFSET		22
-+#define QSGMII_PHY_CDR_PI_SLEW_MASK		0x3
-+#define QSGMII_PHY_TX_DRV_AMP_OFFSET		28
-+#define QSGMII_PHY_TX_DRV_AMP_MASK		0xf
-+
-+struct ipq806x_gmac {
-+	struct platform_device *pdev;
-+	struct regmap *nss_common;
-+	struct regmap *qsgmii_csr;
-+	uint32_t id;
-+	struct clk *core_clk;
-+	phy_interface_t phy_mode;
-+};
-+
-+static int get_clk_div_sgmii(struct ipq806x_gmac *gmac, unsigned int speed)
-+{
-+	struct device *dev = &gmac->pdev->dev;
-+	int div;
-+
-+	switch (speed) {
-+	case SPEED_1000:
-+		div = NSS_COMMON_CLK_DIV_SGMII_1000;
-+		break;
-+
-+	case SPEED_100:
-+		div = NSS_COMMON_CLK_DIV_SGMII_100;
-+		break;
-+
-+	case SPEED_10:
-+		div = NSS_COMMON_CLK_DIV_SGMII_10;
-+		break;
-+
-+	default:
-+		dev_err(dev, "Speed %dMbps not supported in SGMII\n", speed);
-+		return -EINVAL;
-+	}
-+
-+	return div;
-+}
-+
-+static int get_clk_div_rgmii(struct ipq806x_gmac *gmac, unsigned int speed)
-+{
-+	struct device *dev = &gmac->pdev->dev;
-+	int div;
-+
-+	switch (speed) {
-+	case SPEED_1000:
-+		div = NSS_COMMON_CLK_DIV_RGMII_1000;
-+		break;
-+
-+	case SPEED_100:
-+		div = NSS_COMMON_CLK_DIV_RGMII_100;
-+		break;
-+
-+	case SPEED_10:
-+		div = NSS_COMMON_CLK_DIV_RGMII_10;
-+		break;
-+
-+	default:
-+		dev_err(dev, "Speed %dMbps not supported in RGMII\n", speed);
-+		return -EINVAL;
-+	}
-+
-+	return div;
-+}
-+
-+static int ipq806x_gmac_set_speed(struct ipq806x_gmac *gmac, unsigned int speed)
-+{
-+	uint32_t clk_bits, val;
-+	int div;
-+
-+	switch (gmac->phy_mode) {
-+	case PHY_INTERFACE_MODE_RGMII:
-+		div = get_clk_div_rgmii(gmac, speed);
-+		clk_bits = NSS_COMMON_CLK_GATE_RGMII_RX_EN(gmac->id) |
-+			   NSS_COMMON_CLK_GATE_RGMII_TX_EN(gmac->id);
-+		break;
-+
-+	case PHY_INTERFACE_MODE_SGMII:
-+		div = get_clk_div_sgmii(gmac, speed);
-+		clk_bits = NSS_COMMON_CLK_GATE_GMII_RX_EN(gmac->id) |
-+			   NSS_COMMON_CLK_GATE_GMII_TX_EN(gmac->id);
-+		break;
-+
-+	default:
-+		dev_err(&gmac->pdev->dev, "Unsupported PHY mode: \"%s\"\n",
-+			phy_modes(gmac->phy_mode));
-+		return -EINVAL;
-+	}
-+
-+	/* Disable the clocks */
-+	regmap_read(gmac->nss_common, NSS_COMMON_CLK_GATE, &val);
-+	val &= ~clk_bits;
-+	regmap_write(gmac->nss_common, NSS_COMMON_CLK_GATE, val);
-+
-+	/* Set the divider */
-+	regmap_read(gmac->nss_common, NSS_COMMON_CLK_DIV0, &val);
-+	val &= ~(NSS_COMMON_CLK_DIV_MASK
-+		 << NSS_COMMON_CLK_DIV_OFFSET(gmac->id));
-+	val |= div << NSS_COMMON_CLK_DIV_OFFSET(gmac->id);
-+	regmap_write(gmac->nss_common, NSS_COMMON_CLK_DIV0, val);
-+
-+	/* Enable the clock back */
-+	regmap_read(gmac->nss_common, NSS_COMMON_CLK_GATE, &val);
-+	val |= clk_bits;
-+	regmap_write(gmac->nss_common, NSS_COMMON_CLK_GATE, val);
-+
-+	return 0;
-+}
-+
-+static void *ipq806x_gmac_of_parse(struct ipq806x_gmac *gmac)
-+{
-+	struct device *dev = &gmac->pdev->dev;
-+
-+	gmac->phy_mode = of_get_phy_mode(dev->of_node);
-+	if (gmac->phy_mode < 0) {
-+		dev_err(dev, "missing phy mode property\n");
-+		return ERR_PTR(-EINVAL);
-+	}
-+
-+	if (of_property_read_u32(dev->of_node, "qcom,id", &gmac->id) < 0) {
-+		dev_err(dev, "missing qcom id property\n");
-+		return ERR_PTR(-EINVAL);
-+	}
-+
-+	/* The GMACs are called 1 to 4 in the documentation, but to simplify the
-+	 * code and keep it consistent with the Linux convention, we'll number
-+	 * them from 0 to 3 here.
-+	 */
-+	if (gmac->id < 0 || gmac->id > 3) {
-+		dev_err(dev, "invalid gmac id\n");
-+		return ERR_PTR(-EINVAL);
-+	}
-+
-+	gmac->core_clk = devm_clk_get(dev, "stmmaceth");
-+	if (IS_ERR(gmac->core_clk)) {
-+		dev_err(dev, "missing stmmaceth clk property\n");
-+		return gmac->core_clk;
-+	}
-+	clk_set_rate(gmac->core_clk, 266000000);
-+
-+	/* Setup the register map for the nss common registers */
-+	gmac->nss_common = syscon_regmap_lookup_by_phandle(dev->of_node,
-+							   "qcom,nss-common");
-+	if (IS_ERR(gmac->nss_common)) {
-+		dev_err(dev, "missing nss-common node\n");
-+		return gmac->nss_common;
-+	}
-+
-+	/* Setup the register map for the qsgmii csr registers */
-+	gmac->qsgmii_csr = syscon_regmap_lookup_by_phandle(dev->of_node,
-+							   "qcom,qsgmii-csr");
-+	if (IS_ERR(gmac->qsgmii_csr)) {
-+		dev_err(dev, "missing qsgmii-csr node\n");
-+		return gmac->qsgmii_csr;
-+	}
-+
-+	return NULL;
-+}
-+
-+static void ipq806x_gmac_fix_mac_speed(void *priv, unsigned int speed)
-+{
-+	struct ipq806x_gmac *gmac = priv;
-+
-+	ipq806x_gmac_set_speed(gmac, speed);
-+}
-+
-+static int ipq806x_gmac_probe(struct platform_device *pdev)
-+{
-+	struct plat_stmmacenet_data *plat_dat;
-+	struct stmmac_resources stmmac_res;
-+	struct device *dev = &pdev->dev;
-+	struct ipq806x_gmac *gmac;
-+	int val;
-+	void *err;
-+
-+	val = stmmac_get_platform_resources(pdev, &stmmac_res);
-+	if (val)
-+		return val;
-+
-+	plat_dat = stmmac_probe_config_dt(pdev, &stmmac_res.mac);
-+	if (IS_ERR(plat_dat))
-+		return PTR_ERR(plat_dat);
-+
-+	gmac = devm_kzalloc(dev, sizeof(*gmac), GFP_KERNEL);
-+	if (!gmac)
-+		return -ENOMEM;
-+
-+	gmac->pdev = pdev;
-+
-+	err = ipq806x_gmac_of_parse(gmac);
-+	if (IS_ERR(err)) {
-+		dev_err(dev, "device tree parsing error\n");
-+		return PTR_ERR(err);
-+	}
-+
-+	regmap_write(gmac->qsgmii_csr, QSGMII_PCS_CAL_LCKDT_CTL,
-+		     QSGMII_PCS_CAL_LCKDT_CTL_RST);
-+
-+	/* Inter frame gap is set to 12 */
-+	val = 12 << NSS_COMMON_GMAC_CTL_IFG_OFFSET |
-+	      12 << NSS_COMMON_GMAC_CTL_IFG_LIMIT_OFFSET;
-+	/* We also initiate an AXI low power exit request */
-+	val |= NSS_COMMON_GMAC_CTL_CSYS_REQ;
-+	switch (gmac->phy_mode) {
-+	case PHY_INTERFACE_MODE_RGMII:
-+		val |= NSS_COMMON_GMAC_CTL_PHY_IFACE_SEL;
-+		break;
-+	case PHY_INTERFACE_MODE_SGMII:
-+		val &= ~NSS_COMMON_GMAC_CTL_PHY_IFACE_SEL;
-+		break;
-+	default:
-+		dev_err(&pdev->dev, "Unsupported PHY mode: \"%s\"\n",
-+			phy_modes(gmac->phy_mode));
-+		return -EINVAL;
-+	}
-+	regmap_write(gmac->nss_common, NSS_COMMON_GMAC_CTL(gmac->id), val);
-+
-+	/* Configure the clock src according to the mode */
-+	regmap_read(gmac->nss_common, NSS_COMMON_CLK_SRC_CTRL, &val);
-+	val &= ~(1 << NSS_COMMON_CLK_SRC_CTRL_OFFSET(gmac->id));
-+	switch (gmac->phy_mode) {
-+	case PHY_INTERFACE_MODE_RGMII:
-+		val |= NSS_COMMON_CLK_SRC_CTRL_RGMII(gmac->id) <<
-+			NSS_COMMON_CLK_SRC_CTRL_OFFSET(gmac->id);
-+		break;
-+	case PHY_INTERFACE_MODE_SGMII:
-+		val |= NSS_COMMON_CLK_SRC_CTRL_SGMII(gmac->id) <<
-+			NSS_COMMON_CLK_SRC_CTRL_OFFSET(gmac->id);
-+		break;
-+	default:
-+		dev_err(&pdev->dev, "Unsupported PHY mode: \"%s\"\n",
-+			phy_modes(gmac->phy_mode));
-+		return -EINVAL;
-+	}
-+	regmap_write(gmac->nss_common, NSS_COMMON_CLK_SRC_CTRL, val);
-+
-+	/* Enable PTP clock */
-+	regmap_read(gmac->nss_common, NSS_COMMON_CLK_GATE, &val);
-+	val |= NSS_COMMON_CLK_GATE_PTP_EN(gmac->id);
-+	regmap_write(gmac->nss_common, NSS_COMMON_CLK_GATE, val);
-+
-+	if (gmac->phy_mode == PHY_INTERFACE_MODE_SGMII) {
-+		regmap_write(gmac->qsgmii_csr, QSGMII_PHY_SGMII_CTL(gmac->id),
-+			     QSGMII_PHY_CDR_EN |
-+			     QSGMII_PHY_RX_FRONT_EN |
-+			     QSGMII_PHY_RX_SIGNAL_DETECT_EN |
-+			     QSGMII_PHY_TX_DRIVER_EN |
-+			     QSGMII_PHY_QSGMII_EN |
-+			     0x4 << QSGMII_PHY_PHASE_LOOP_GAIN_OFFSET |
-+			     0x3 << QSGMII_PHY_RX_DC_BIAS_OFFSET |
-+			     0x1 << QSGMII_PHY_RX_INPUT_EQU_OFFSET |
-+			     0x2 << QSGMII_PHY_CDR_PI_SLEW_OFFSET |
-+			     0xC << QSGMII_PHY_TX_DRV_AMP_OFFSET);
-+	}
-+
-+	plat_dat->has_gmac = true;
-+	plat_dat->bsp_priv = gmac;
-+	plat_dat->fix_mac_speed = ipq806x_gmac_fix_mac_speed;
-+
-+	return stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res);
-+}
-+
-+static const struct of_device_id ipq806x_gmac_dwmac_match[] = {
-+	{ .compatible = "qcom,ipq806x-gmac" },
-+	{ }
-+};
-+MODULE_DEVICE_TABLE(of, ipq806x_gmac_dwmac_match);
-+
-+static struct platform_driver ipq806x_gmac_dwmac_driver = {
-+	.probe = ipq806x_gmac_probe,
-+	.remove = stmmac_pltfr_remove,
-+	.driver = {
-+		.name		= "ipq806x-gmac-dwmac",
-+		.pm		= &stmmac_pltfr_pm_ops,
-+		.of_match_table	= ipq806x_gmac_dwmac_match,
-+	},
-+};
-+module_platform_driver(ipq806x_gmac_dwmac_driver);
-+
-+MODULE_AUTHOR("Mathieu Olivari <mathieu@codeaurora.org>");
-+MODULE_DESCRIPTION("Qualcomm Atheros IPQ806x DWMAC specific glue layer");
-+MODULE_LICENSE("Dual BSD/GPL");
---- /dev/null
-+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-lpc18xx.c
-@@ -0,0 +1,86 @@
-+/*
-+ * DWMAC glue for NXP LPC18xx/LPC43xx Ethernet
-+ *
-+ * Copyright (C) 2015 Joachim Eastwood <manabian@gmail.com>
-+ *
-+ * This file is licensed under the terms of the GNU General Public
-+ * License version 2. This program is licensed "as is" without any
-+ * warranty of any kind, whether express or implied.
-+ */
-+
-+#include <linux/mfd/syscon.h>
-+#include <linux/module.h>
-+#include <linux/of.h>
-+#include <linux/of_net.h>
-+#include <linux/phy.h>
-+#include <linux/platform_device.h>
-+#include <linux/regmap.h>
-+#include <linux/stmmac.h>
-+
-+#include "stmmac_platform.h"
-+
-+/* Register defines for CREG syscon */
-+#define LPC18XX_CREG_CREG6			0x12c
-+# define LPC18XX_CREG_CREG6_ETHMODE_MASK	0x7
-+# define LPC18XX_CREG_CREG6_ETHMODE_MII		0x0
-+# define LPC18XX_CREG_CREG6_ETHMODE_RMII	0x4
-+
-+static int lpc18xx_dwmac_probe(struct platform_device *pdev)
-+{
-+	struct plat_stmmacenet_data *plat_dat;
-+	struct stmmac_resources stmmac_res;
-+	struct regmap *reg;
-+	u8 ethmode;
-+	int ret;
-+
-+	ret = stmmac_get_platform_resources(pdev, &stmmac_res);
-+	if (ret)
-+		return ret;
-+
-+	plat_dat = stmmac_probe_config_dt(pdev, &stmmac_res.mac);
-+	if (IS_ERR(plat_dat))
-+		return PTR_ERR(plat_dat);
-+
-+	plat_dat->has_gmac = true;
-+
-+	reg = syscon_regmap_lookup_by_compatible("nxp,lpc1850-creg");
-+	if (IS_ERR(reg)) {
-+		dev_err(&pdev->dev, "syscon lookup failed\n");
-+		return PTR_ERR(reg);
-+	}
-+
-+	if (plat_dat->interface == PHY_INTERFACE_MODE_MII) {
-+		ethmode = LPC18XX_CREG_CREG6_ETHMODE_MII;
-+	} else if (plat_dat->interface == PHY_INTERFACE_MODE_RMII) {
-+		ethmode = LPC18XX_CREG_CREG6_ETHMODE_RMII;
-+	} else {
-+		dev_err(&pdev->dev, "Only MII and RMII mode supported\n");
-+		return -EINVAL;
-+	}
-+
-+	regmap_update_bits(reg, LPC18XX_CREG_CREG6,
-+			   LPC18XX_CREG_CREG6_ETHMODE_MASK, ethmode);
-+
-+	return stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res);
-+}
-+
-+static const struct of_device_id lpc18xx_dwmac_match[] = {
-+	{ .compatible = "nxp,lpc1850-dwmac" },
-+	{ }
-+};
-+MODULE_DEVICE_TABLE(of, lpc18xx_dwmac_match);
-+
-+static struct platform_driver lpc18xx_dwmac_driver = {
-+	.probe  = lpc18xx_dwmac_probe,
-+	.remove = stmmac_pltfr_remove,
-+	.driver = {
-+		.name           = "lpc18xx-dwmac",
-+		.pm		= &stmmac_pltfr_pm_ops,
-+		.of_match_table = lpc18xx_dwmac_match,
-+	},
-+};
-+module_platform_driver(lpc18xx_dwmac_driver);
-+
-+MODULE_AUTHOR("Joachim Eastwood <manabian@gmail.com>");
-+MODULE_DESCRIPTION("DWMAC glue for LPC18xx/43xx Ethernet");
-+MODULE_LICENSE("GPL v2");
---- a/drivers/net/ethernet/stmicro/stmmac/dwmac-meson.c
-+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-meson.c
-@@ -15,9 +15,12 @@
- #include <linux/ethtool.h>
- #include <linux/io.h>
- #include <linux/ioport.h>
-+#include <linux/module.h>
- #include <linux/platform_device.h>
- #include <linux/stmmac.h>
- 
-+#include "stmmac_platform.h"
-+
- #define ETHMAC_SPEED_100	BIT(1)
- 
- struct meson_dwmac {
-@@ -44,24 +47,54 @@ static void meson6_dwmac_fix_mac_speed(v
- 	writel(val, dwmac->reg);
- }
- 
--static void *meson6_dwmac_setup(struct platform_device *pdev)
-+static int meson6_dwmac_probe(struct platform_device *pdev)
- {
-+	struct plat_stmmacenet_data *plat_dat;
-+	struct stmmac_resources stmmac_res;
- 	struct meson_dwmac *dwmac;
- 	struct resource *res;
-+	int ret;
-+
-+	ret = stmmac_get_platform_resources(pdev, &stmmac_res);
-+	if (ret)
-+		return ret;
-+
-+	plat_dat = stmmac_probe_config_dt(pdev, &stmmac_res.mac);
-+	if (IS_ERR(plat_dat))
-+		return PTR_ERR(plat_dat);
- 
- 	dwmac = devm_kzalloc(&pdev->dev, sizeof(*dwmac), GFP_KERNEL);
- 	if (!dwmac)
--		return ERR_PTR(-ENOMEM);
-+		return -ENOMEM;
- 
- 	res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
- 	dwmac->reg = devm_ioremap_resource(&pdev->dev, res);
- 	if (IS_ERR(dwmac->reg))
--		return dwmac->reg;
-+		return PTR_ERR(dwmac->reg);
-+
-+	plat_dat->bsp_priv = dwmac;
-+	plat_dat->fix_mac_speed = meson6_dwmac_fix_mac_speed;
- 
--	return dwmac;
-+	return stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res);
- }
- 
--const struct stmmac_of_data meson6_dwmac_data = {
--	.setup		= meson6_dwmac_setup,
--	.fix_mac_speed	= meson6_dwmac_fix_mac_speed,
-+static const struct of_device_id meson6_dwmac_match[] = {
-+	{ .compatible = "amlogic,meson6-dwmac" },
-+	{ }
- };
-+MODULE_DEVICE_TABLE(of, meson6_dwmac_match);
-+
-+static struct platform_driver meson6_dwmac_driver = {
-+	.probe  = meson6_dwmac_probe,
-+	.remove = stmmac_pltfr_remove,
-+	.driver = {
-+		.name           = "meson6-dwmac",
-+		.pm		= &stmmac_pltfr_pm_ops,
-+		.of_match_table = meson6_dwmac_match,
-+	},
-+};
-+module_platform_driver(meson6_dwmac_driver);
-+
-+MODULE_AUTHOR("Beniamino Galvani <b.galvani@gmail.com>");
-+MODULE_DESCRIPTION("Amlogic Meson DWMAC glue layer");
-+MODULE_LICENSE("GPL v2");
---- /dev/null
-+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
-@@ -0,0 +1,626 @@
-+/**
-+ * dwmac-rk.c - Rockchip RK3288 DWMAC specific glue layer
-+ *
-+ * Copyright (C) 2014 Chen-Zhi (Roger Chen)
-+ *
-+ * Chen-Zhi (Roger Chen)  <roger.chen@rock-chips.com>
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-+ * GNU General Public License for more details.
-+ */
-+
-+#include <linux/stmmac.h>
-+#include <linux/bitops.h>
-+#include <linux/clk.h>
-+#include <linux/phy.h>
-+#include <linux/of_net.h>
-+#include <linux/gpio.h>
-+#include <linux/module.h>
-+#include <linux/of_gpio.h>
-+#include <linux/of_device.h>
-+#include <linux/platform_device.h>
-+#include <linux/regulator/consumer.h>
-+#include <linux/delay.h>
-+#include <linux/mfd/syscon.h>
-+#include <linux/regmap.h>
-+
-+#include "stmmac_platform.h"
-+
-+struct rk_priv_data;
-+struct rk_gmac_ops {
-+	void (*set_to_rgmii)(struct rk_priv_data *bsp_priv,
-+			     int tx_delay, int rx_delay);
-+	void (*set_to_rmii)(struct rk_priv_data *bsp_priv);
-+	void (*set_rgmii_speed)(struct rk_priv_data *bsp_priv, int speed);
-+	void (*set_rmii_speed)(struct rk_priv_data *bsp_priv, int speed);
-+};
-+
-+struct rk_priv_data {
-+	struct platform_device *pdev;
-+	int phy_iface;
-+	struct regulator *regulator;
-+	const struct rk_gmac_ops *ops;
-+
-+	bool clk_enabled;
-+	bool clock_input;
-+
-+	struct clk *clk_mac;
-+	struct clk *gmac_clkin;
-+	struct clk *mac_clk_rx;
-+	struct clk *mac_clk_tx;
-+	struct clk *clk_mac_ref;
-+	struct clk *clk_mac_refout;
-+	struct clk *aclk_mac;
-+	struct clk *pclk_mac;
-+
-+	int tx_delay;
-+	int rx_delay;
-+
-+	struct regmap *grf;
-+};
-+
-+#define HIWORD_UPDATE(val, mask, shift) \
-+		((val) << (shift) | (mask) << ((shift) + 16))
-+
-+#define GRF_BIT(nr)	(BIT(nr) | BIT(nr+16))
-+#define GRF_CLR_BIT(nr)	(BIT(nr+16))
-+
-+#define RK3288_GRF_SOC_CON1	0x0248
-+#define RK3288_GRF_SOC_CON3	0x0250
-+
-+/*RK3288_GRF_SOC_CON1*/
-+#define RK3288_GMAC_PHY_INTF_SEL_RGMII	(GRF_BIT(6) | GRF_CLR_BIT(7) | \
-+					 GRF_CLR_BIT(8))
-+#define RK3288_GMAC_PHY_INTF_SEL_RMII	(GRF_CLR_BIT(6) | GRF_CLR_BIT(7) | \
-+					 GRF_BIT(8))
-+#define RK3288_GMAC_FLOW_CTRL		GRF_BIT(9)
-+#define RK3288_GMAC_FLOW_CTRL_CLR	GRF_CLR_BIT(9)
-+#define RK3288_GMAC_SPEED_10M		GRF_CLR_BIT(10)
-+#define RK3288_GMAC_SPEED_100M		GRF_BIT(10)
-+#define RK3288_GMAC_RMII_CLK_25M	GRF_BIT(11)
-+#define RK3288_GMAC_RMII_CLK_2_5M	GRF_CLR_BIT(11)
-+#define RK3288_GMAC_CLK_125M		(GRF_CLR_BIT(12) | GRF_CLR_BIT(13))
-+#define RK3288_GMAC_CLK_25M		(GRF_BIT(12) | GRF_BIT(13))
-+#define RK3288_GMAC_CLK_2_5M		(GRF_CLR_BIT(12) | GRF_BIT(13))
-+#define RK3288_GMAC_RMII_MODE		GRF_BIT(14)
-+#define RK3288_GMAC_RMII_MODE_CLR	GRF_CLR_BIT(14)
-+
-+/*RK3288_GRF_SOC_CON3*/
-+#define RK3288_GMAC_TXCLK_DLY_ENABLE	GRF_BIT(14)
-+#define RK3288_GMAC_TXCLK_DLY_DISABLE	GRF_CLR_BIT(14)
-+#define RK3288_GMAC_RXCLK_DLY_ENABLE	GRF_BIT(15)
-+#define RK3288_GMAC_RXCLK_DLY_DISABLE	GRF_CLR_BIT(15)
-+#define RK3288_GMAC_CLK_RX_DL_CFG(val)	HIWORD_UPDATE(val, 0x7F, 7)
-+#define RK3288_GMAC_CLK_TX_DL_CFG(val)	HIWORD_UPDATE(val, 0x7F, 0)
-+
-+static void rk3288_set_to_rgmii(struct rk_priv_data *bsp_priv,
-+				int tx_delay, int rx_delay)
-+{
-+	struct device *dev = &bsp_priv->pdev->dev;
-+
-+	if (IS_ERR(bsp_priv->grf)) {
-+		dev_err(dev, "Missing rockchip,grf property\n");
-+		return;
-+	}
-+
-+	regmap_write(bsp_priv->grf, RK3288_GRF_SOC_CON1,
-+		     RK3288_GMAC_PHY_INTF_SEL_RGMII |
-+		     RK3288_GMAC_RMII_MODE_CLR);
-+	regmap_write(bsp_priv->grf, RK3288_GRF_SOC_CON3,
-+		     RK3288_GMAC_RXCLK_DLY_ENABLE |
-+		     RK3288_GMAC_TXCLK_DLY_ENABLE |
-+		     RK3288_GMAC_CLK_RX_DL_CFG(rx_delay) |
-+		     RK3288_GMAC_CLK_TX_DL_CFG(tx_delay));
-+}
-+
-+static void rk3288_set_to_rmii(struct rk_priv_data *bsp_priv)
-+{
-+	struct device *dev = &bsp_priv->pdev->dev;
-+
-+	if (IS_ERR(bsp_priv->grf)) {
-+		dev_err(dev, "Missing rockchip,grf property\n");
-+		return;
-+	}
-+
-+	regmap_write(bsp_priv->grf, RK3288_GRF_SOC_CON1,
-+		     RK3288_GMAC_PHY_INTF_SEL_RMII | RK3288_GMAC_RMII_MODE);
-+}
-+
-+static void rk3288_set_rgmii_speed(struct rk_priv_data *bsp_priv, int speed)
-+{
-+	struct device *dev = &bsp_priv->pdev->dev;
-+
-+	if (IS_ERR(bsp_priv->grf)) {
-+		dev_err(dev, "Missing rockchip,grf property\n");
-+		return;
-+	}
-+
-+	if (speed == 10)
-+		regmap_write(bsp_priv->grf, RK3288_GRF_SOC_CON1,
-+			     RK3288_GMAC_CLK_2_5M);
-+	else if (speed == 100)
-+		regmap_write(bsp_priv->grf, RK3288_GRF_SOC_CON1,
-+			     RK3288_GMAC_CLK_25M);
-+	else if (speed == 1000)
-+		regmap_write(bsp_priv->grf, RK3288_GRF_SOC_CON1,
-+			     RK3288_GMAC_CLK_125M);
-+	else
-+		dev_err(dev, "unknown speed value for RGMII! speed=%d", speed);
-+}
-+
-+static void rk3288_set_rmii_speed(struct rk_priv_data *bsp_priv, int speed)
-+{
-+	struct device *dev = &bsp_priv->pdev->dev;
-+
-+	if (IS_ERR(bsp_priv->grf)) {
-+		dev_err(dev, "Missing rockchip,grf property\n");
-+		return;
-+	}
-+
-+	if (speed == 10) {
-+		regmap_write(bsp_priv->grf, RK3288_GRF_SOC_CON1,
-+			     RK3288_GMAC_RMII_CLK_2_5M |
-+			     RK3288_GMAC_SPEED_10M);
-+	} else if (speed == 100) {
-+		regmap_write(bsp_priv->grf, RK3288_GRF_SOC_CON1,
-+			     RK3288_GMAC_RMII_CLK_25M |
-+			     RK3288_GMAC_SPEED_100M);
-+	} else {
-+		dev_err(dev, "unknown speed value for RMII! speed=%d", speed);
-+	}
-+}
-+
-+static const struct rk_gmac_ops rk3288_ops = {
-+	.set_to_rgmii = rk3288_set_to_rgmii,
-+	.set_to_rmii = rk3288_set_to_rmii,
-+	.set_rgmii_speed = rk3288_set_rgmii_speed,
-+	.set_rmii_speed = rk3288_set_rmii_speed,
-+};
-+
-+#define RK3368_GRF_SOC_CON15	0x043c
-+#define RK3368_GRF_SOC_CON16	0x0440
-+
-+/* RK3368_GRF_SOC_CON15 */
-+#define RK3368_GMAC_PHY_INTF_SEL_RGMII	(GRF_BIT(9) | GRF_CLR_BIT(10) | \
-+					 GRF_CLR_BIT(11))
-+#define RK3368_GMAC_PHY_INTF_SEL_RMII	(GRF_CLR_BIT(9) | GRF_CLR_BIT(10) | \
-+					 GRF_BIT(11))
-+#define RK3368_GMAC_FLOW_CTRL		GRF_BIT(8)
-+#define RK3368_GMAC_FLOW_CTRL_CLR	GRF_CLR_BIT(8)
-+#define RK3368_GMAC_SPEED_10M		GRF_CLR_BIT(7)
-+#define RK3368_GMAC_SPEED_100M		GRF_BIT(7)
-+#define RK3368_GMAC_RMII_CLK_25M	GRF_BIT(3)
-+#define RK3368_GMAC_RMII_CLK_2_5M	GRF_CLR_BIT(3)
-+#define RK3368_GMAC_CLK_125M		(GRF_CLR_BIT(4) | GRF_CLR_BIT(5))
-+#define RK3368_GMAC_CLK_25M		(GRF_BIT(4) | GRF_BIT(5))
-+#define RK3368_GMAC_CLK_2_5M		(GRF_CLR_BIT(4) | GRF_BIT(5))
-+#define RK3368_GMAC_RMII_MODE		GRF_BIT(6)
-+#define RK3368_GMAC_RMII_MODE_CLR	GRF_CLR_BIT(6)
-+
-+/* RK3368_GRF_SOC_CON16 */
-+#define RK3368_GMAC_TXCLK_DLY_ENABLE	GRF_BIT(7)
-+#define RK3368_GMAC_TXCLK_DLY_DISABLE	GRF_CLR_BIT(7)
-+#define RK3368_GMAC_RXCLK_DLY_ENABLE	GRF_BIT(15)
-+#define RK3368_GMAC_RXCLK_DLY_DISABLE	GRF_CLR_BIT(15)
-+#define RK3368_GMAC_CLK_RX_DL_CFG(val)	HIWORD_UPDATE(val, 0x7F, 8)
-+#define RK3368_GMAC_CLK_TX_DL_CFG(val)	HIWORD_UPDATE(val, 0x7F, 0)
-+
-+static void rk3368_set_to_rgmii(struct rk_priv_data *bsp_priv,
-+				int tx_delay, int rx_delay)
-+{
-+	struct device *dev = &bsp_priv->pdev->dev;
-+
-+	if (IS_ERR(bsp_priv->grf)) {
-+		dev_err(dev, "%s: Missing rockchip,grf property\n", __func__);
-+		return;
-+	}
-+
-+	regmap_write(bsp_priv->grf, RK3368_GRF_SOC_CON15,
-+		     RK3368_GMAC_PHY_INTF_SEL_RGMII |
-+		     RK3368_GMAC_RMII_MODE_CLR);
-+	regmap_write(bsp_priv->grf, RK3368_GRF_SOC_CON16,
-+		     RK3368_GMAC_RXCLK_DLY_ENABLE |
-+		     RK3368_GMAC_TXCLK_DLY_ENABLE |
-+		     RK3368_GMAC_CLK_RX_DL_CFG(rx_delay) |
-+		     RK3368_GMAC_CLK_TX_DL_CFG(tx_delay));
-+}
-+
-+static void rk3368_set_to_rmii(struct rk_priv_data *bsp_priv)
-+{
-+	struct device *dev = &bsp_priv->pdev->dev;
-+
-+	if (IS_ERR(bsp_priv->grf)) {
-+		dev_err(dev, "%s: Missing rockchip,grf property\n", __func__);
-+		return;
-+	}
-+
-+	regmap_write(bsp_priv->grf, RK3368_GRF_SOC_CON15,
-+		     RK3368_GMAC_PHY_INTF_SEL_RMII | RK3368_GMAC_RMII_MODE);
-+}
-+
-+static void rk3368_set_rgmii_speed(struct rk_priv_data *bsp_priv, int speed)
-+{
-+	struct device *dev = &bsp_priv->pdev->dev;
-+
-+	if (IS_ERR(bsp_priv->grf)) {
-+		dev_err(dev, "%s: Missing rockchip,grf property\n", __func__);
-+		return;
-+	}
-+
-+	if (speed == 10)
-+		regmap_write(bsp_priv->grf, RK3368_GRF_SOC_CON15,
-+			     RK3368_GMAC_CLK_2_5M);
-+	else if (speed == 100)
-+		regmap_write(bsp_priv->grf, RK3368_GRF_SOC_CON15,
-+			     RK3368_GMAC_CLK_25M);
-+	else if (speed == 1000)
-+		regmap_write(bsp_priv->grf, RK3368_GRF_SOC_CON15,
-+			     RK3368_GMAC_CLK_125M);
-+	else
-+		dev_err(dev, "unknown speed value for RGMII! speed=%d", speed);
-+}
-+
-+static void rk3368_set_rmii_speed(struct rk_priv_data *bsp_priv, int speed)
-+{
-+	struct device *dev = &bsp_priv->pdev->dev;
-+
-+	if (IS_ERR(bsp_priv->grf)) {
-+		dev_err(dev, "%s: Missing rockchip,grf property\n", __func__);
-+		return;
-+	}
-+
-+	if (speed == 10) {
-+		regmap_write(bsp_priv->grf, RK3368_GRF_SOC_CON15,
-+			     RK3368_GMAC_RMII_CLK_2_5M |
-+			     RK3368_GMAC_SPEED_10M);
-+	} else if (speed == 100) {
-+		regmap_write(bsp_priv->grf, RK3368_GRF_SOC_CON15,
-+			     RK3368_GMAC_RMII_CLK_25M |
-+			     RK3368_GMAC_SPEED_100M);
-+	} else {
-+		dev_err(dev, "unknown speed value for RMII! speed=%d", speed);
-+	}
-+}
-+
-+static const struct rk_gmac_ops rk3368_ops = {
-+	.set_to_rgmii = rk3368_set_to_rgmii,
-+	.set_to_rmii = rk3368_set_to_rmii,
-+	.set_rgmii_speed = rk3368_set_rgmii_speed,
-+	.set_rmii_speed = rk3368_set_rmii_speed,
-+};
-+
-+static int gmac_clk_init(struct rk_priv_data *bsp_priv)
-+{
-+	struct device *dev = &bsp_priv->pdev->dev;
-+
-+	bsp_priv->clk_enabled = false;
-+
-+	bsp_priv->mac_clk_rx = devm_clk_get(dev, "mac_clk_rx");
-+	if (IS_ERR(bsp_priv->mac_clk_rx))
-+		dev_err(dev, "cannot get clock %s\n",
-+			"mac_clk_rx");
-+
-+	bsp_priv->mac_clk_tx = devm_clk_get(dev, "mac_clk_tx");
-+	if (IS_ERR(bsp_priv->mac_clk_tx))
-+		dev_err(dev, "cannot get clock %s\n",
-+			"mac_clk_tx");
-+
-+	bsp_priv->aclk_mac = devm_clk_get(dev, "aclk_mac");
-+	if (IS_ERR(bsp_priv->aclk_mac))
-+		dev_err(dev, "cannot get clock %s\n",
-+			"aclk_mac");
-+
-+	bsp_priv->pclk_mac = devm_clk_get(dev, "pclk_mac");
-+	if (IS_ERR(bsp_priv->pclk_mac))
-+		dev_err(dev, "cannot get clock %s\n",
-+			"pclk_mac");
-+
-+	bsp_priv->clk_mac = devm_clk_get(dev, "stmmaceth");
-+	if (IS_ERR(bsp_priv->clk_mac))
-+		dev_err(dev, "cannot get clock %s\n",
-+			"stmmaceth");
-+
-+	if (bsp_priv->phy_iface == PHY_INTERFACE_MODE_RMII) {
-+		bsp_priv->clk_mac_ref = devm_clk_get(dev, "clk_mac_ref");
-+		if (IS_ERR(bsp_priv->clk_mac_ref))
-+			dev_err(dev, "cannot get clock %s\n",
-+				"clk_mac_ref");
-+
-+		if (!bsp_priv->clock_input) {
-+			bsp_priv->clk_mac_refout =
-+				devm_clk_get(dev, "clk_mac_refout");
-+			if (IS_ERR(bsp_priv->clk_mac_refout))
-+				dev_err(dev, "cannot get clock %s\n",
-+					"clk_mac_refout");
-+		}
-+	}
-+
-+	if (bsp_priv->clock_input) {
-+		dev_info(dev, "clock input from PHY\n");
-+	} else {
-+		if (bsp_priv->phy_iface == PHY_INTERFACE_MODE_RMII)
-+			clk_set_rate(bsp_priv->clk_mac, 50000000);
-+	}
-+
-+	return 0;
-+}
-+
-+static int gmac_clk_enable(struct rk_priv_data *bsp_priv, bool enable)
-+{
-+	int phy_iface = phy_iface = bsp_priv->phy_iface;
-+
-+	if (enable) {
-+		if (!bsp_priv->clk_enabled) {
-+			if (phy_iface == PHY_INTERFACE_MODE_RMII) {
-+				if (!IS_ERR(bsp_priv->mac_clk_rx))
-+					clk_prepare_enable(
-+						bsp_priv->mac_clk_rx);
-+
-+				if (!IS_ERR(bsp_priv->clk_mac_ref))
-+					clk_prepare_enable(
-+						bsp_priv->clk_mac_ref);
-+
-+				if (!IS_ERR(bsp_priv->clk_mac_refout))
-+					clk_prepare_enable(
-+						bsp_priv->clk_mac_refout);
-+			}
-+
-+			if (!IS_ERR(bsp_priv->aclk_mac))
-+				clk_prepare_enable(bsp_priv->aclk_mac);
-+
-+			if (!IS_ERR(bsp_priv->pclk_mac))
-+				clk_prepare_enable(bsp_priv->pclk_mac);
-+
-+			if (!IS_ERR(bsp_priv->mac_clk_tx))
-+				clk_prepare_enable(bsp_priv->mac_clk_tx);
-+
-+			/**
-+			 * if (!IS_ERR(bsp_priv->clk_mac))
-+			 *	clk_prepare_enable(bsp_priv->clk_mac);
-+			 */
-+			mdelay(5);
-+			bsp_priv->clk_enabled = true;
-+		}
-+	} else {
-+		if (bsp_priv->clk_enabled) {
-+			if (phy_iface == PHY_INTERFACE_MODE_RMII) {
-+				if (!IS_ERR(bsp_priv->mac_clk_rx))
-+					clk_disable_unprepare(
-+						bsp_priv->mac_clk_rx);
-+
-+				if (!IS_ERR(bsp_priv->clk_mac_ref))
-+					clk_disable_unprepare(
-+						bsp_priv->clk_mac_ref);
-+
-+				if (!IS_ERR(bsp_priv->clk_mac_refout))
-+					clk_disable_unprepare(
-+						bsp_priv->clk_mac_refout);
-+			}
-+
-+			if (!IS_ERR(bsp_priv->aclk_mac))
-+				clk_disable_unprepare(bsp_priv->aclk_mac);
-+
-+			if (!IS_ERR(bsp_priv->pclk_mac))
-+				clk_disable_unprepare(bsp_priv->pclk_mac);
-+
-+			if (!IS_ERR(bsp_priv->mac_clk_tx))
-+				clk_disable_unprepare(bsp_priv->mac_clk_tx);
-+			/**
-+			 * if (!IS_ERR(bsp_priv->clk_mac))
-+			 *	clk_disable_unprepare(bsp_priv->clk_mac);
-+			 */
-+			bsp_priv->clk_enabled = false;
-+		}
-+	}
-+
-+	return 0;
-+}
-+
-+static int phy_power_on(struct rk_priv_data *bsp_priv, bool enable)
-+{
-+	struct regulator *ldo = bsp_priv->regulator;
-+	int ret;
-+	struct device *dev = &bsp_priv->pdev->dev;
-+
-+	if (!ldo) {
-+		dev_err(dev, "no regulator found\n");
-+		return -1;
-+	}
-+
-+	if (enable) {
-+		ret = regulator_enable(ldo);
-+		if (ret)
-+			dev_err(dev, "fail to enable phy-supply\n");
-+	} else {
-+		ret = regulator_disable(ldo);
-+		if (ret)
-+			dev_err(dev, "fail to disable phy-supply\n");
-+	}
-+
-+	return 0;
-+}
-+
-+static struct rk_priv_data *rk_gmac_setup(struct platform_device *pdev,
-+					  const struct rk_gmac_ops *ops)
-+{
-+	struct rk_priv_data *bsp_priv;
-+	struct device *dev = &pdev->dev;
-+	int ret;
-+	const char *strings = NULL;
-+	int value;
-+
-+	bsp_priv = devm_kzalloc(dev, sizeof(*bsp_priv), GFP_KERNEL);
-+	if (!bsp_priv)
-+		return ERR_PTR(-ENOMEM);
-+
-+	bsp_priv->phy_iface = of_get_phy_mode(dev->of_node);
-+	bsp_priv->ops = ops;
-+
-+	bsp_priv->regulator = devm_regulator_get_optional(dev, "phy");
-+	if (IS_ERR(bsp_priv->regulator)) {
-+		if (PTR_ERR(bsp_priv->regulator) == -EPROBE_DEFER) {
-+			dev_err(dev, "phy regulator is not available yet, deferred probing\n");
-+			return ERR_PTR(-EPROBE_DEFER);
-+		}
-+		dev_err(dev, "no regulator found\n");
-+		bsp_priv->regulator = NULL;
-+	}
-+
-+	ret = of_property_read_string(dev->of_node, "clock_in_out", &strings);
-+	if (ret) {
-+		dev_err(dev, "Can not read property: clock_in_out.\n");
-+		bsp_priv->clock_input = true;
-+	} else {
-+		dev_info(dev, "clock input or output? (%s).\n",
-+			 strings);
-+		if (!strcmp(strings, "input"))
-+			bsp_priv->clock_input = true;
-+		else
-+			bsp_priv->clock_input = false;
-+	}
-+
-+	ret = of_property_read_u32(dev->of_node, "tx_delay", &value);
-+	if (ret) {
-+		bsp_priv->tx_delay = 0x30;
-+		dev_err(dev, "Can not read property: tx_delay.");
-+		dev_err(dev, "set tx_delay to 0x%x\n",
-+			bsp_priv->tx_delay);
-+	} else {
-+		dev_info(dev, "TX delay(0x%x).\n", value);
-+		bsp_priv->tx_delay = value;
-+	}
-+
-+	ret = of_property_read_u32(dev->of_node, "rx_delay", &value);
-+	if (ret) {
-+		bsp_priv->rx_delay = 0x10;
-+		dev_err(dev, "Can not read property: rx_delay.");
-+		dev_err(dev, "set rx_delay to 0x%x\n",
-+			bsp_priv->rx_delay);
-+	} else {
-+		dev_info(dev, "RX delay(0x%x).\n", value);
-+		bsp_priv->rx_delay = value;
-+	}
-+
-+	bsp_priv->grf = syscon_regmap_lookup_by_phandle(dev->of_node,
-+							"rockchip,grf");
-+	bsp_priv->pdev = pdev;
-+
-+	/*rmii or rgmii*/
-+	if (bsp_priv->phy_iface == PHY_INTERFACE_MODE_RGMII) {
-+		dev_info(dev, "init for RGMII\n");
-+		bsp_priv->ops->set_to_rgmii(bsp_priv, bsp_priv->tx_delay,
-+					    bsp_priv->rx_delay);
-+	} else if (bsp_priv->phy_iface == PHY_INTERFACE_MODE_RMII) {
-+		dev_info(dev, "init for RMII\n");
-+		bsp_priv->ops->set_to_rmii(bsp_priv);
-+	} else {
-+		dev_err(dev, "NO interface defined!\n");
-+	}
-+
-+	gmac_clk_init(bsp_priv);
-+
-+	return bsp_priv;
-+}
-+
-+static int rk_gmac_init(struct platform_device *pdev, void *priv)
-+{
-+	struct rk_priv_data *bsp_priv = priv;
-+	int ret;
-+
-+	ret = phy_power_on(bsp_priv, true);
-+	if (ret)
-+		return ret;
-+
-+	ret = gmac_clk_enable(bsp_priv, true);
-+	if (ret)
-+		return ret;
-+
-+	return 0;
-+}
-+
-+static void rk_gmac_exit(struct platform_device *pdev, void *priv)
-+{
-+	struct rk_priv_data *gmac = priv;
-+
-+	phy_power_on(gmac, false);
-+	gmac_clk_enable(gmac, false);
-+}
-+
-+static void rk_fix_speed(void *priv, unsigned int speed)
-+{
-+	struct rk_priv_data *bsp_priv = priv;
-+	struct device *dev = &bsp_priv->pdev->dev;
-+
-+	if (bsp_priv->phy_iface == PHY_INTERFACE_MODE_RGMII)
-+		bsp_priv->ops->set_rgmii_speed(bsp_priv, speed);
-+	else if (bsp_priv->phy_iface == PHY_INTERFACE_MODE_RMII)
-+		bsp_priv->ops->set_rmii_speed(bsp_priv, speed);
-+	else
-+		dev_err(dev, "unsupported interface %d", bsp_priv->phy_iface);
-+}
-+
-+static int rk_gmac_probe(struct platform_device *pdev)
-+{
-+	struct plat_stmmacenet_data *plat_dat;
-+	struct stmmac_resources stmmac_res;
-+	const struct rk_gmac_ops *data;
-+	int ret;
-+
-+	data = of_device_get_match_data(&pdev->dev);
-+	if (!data) {
-+		dev_err(&pdev->dev, "no of match data provided\n");
-+		return -EINVAL;
-+	}
-+
-+	ret = stmmac_get_platform_resources(pdev, &stmmac_res);
-+	if (ret)
-+		return ret;
-+
-+	plat_dat = stmmac_probe_config_dt(pdev, &stmmac_res.mac);
-+	if (IS_ERR(plat_dat))
-+		return PTR_ERR(plat_dat);
-+
-+	plat_dat->has_gmac = true;
-+	plat_dat->init = rk_gmac_init;
-+	plat_dat->exit = rk_gmac_exit;
-+	plat_dat->fix_mac_speed = rk_fix_speed;
-+
-+	plat_dat->bsp_priv = rk_gmac_setup(pdev, data);
-+	if (IS_ERR(plat_dat->bsp_priv))
-+		return PTR_ERR(plat_dat->bsp_priv);
-+
-+	ret = rk_gmac_init(pdev, plat_dat->bsp_priv);
-+	if (ret)
-+		return ret;
-+
-+	return stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res);
-+}
-+
-+static const struct of_device_id rk_gmac_dwmac_match[] = {
-+	{ .compatible = "rockchip,rk3288-gmac", .data = &rk3288_ops },
-+	{ .compatible = "rockchip,rk3368-gmac", .data = &rk3368_ops },
-+	{ }
-+};
-+MODULE_DEVICE_TABLE(of, rk_gmac_dwmac_match);
-+
-+static struct platform_driver rk_gmac_dwmac_driver = {
-+	.probe  = rk_gmac_probe,
-+	.remove = stmmac_pltfr_remove,
-+	.driver = {
-+		.name           = "rk_gmac-dwmac",
-+		.pm		= &stmmac_pltfr_pm_ops,
-+		.of_match_table = rk_gmac_dwmac_match,
-+	},
-+};
-+module_platform_driver(rk_gmac_dwmac_driver);
-+
-+MODULE_AUTHOR("Chen-Zhi (Roger Chen) <roger.chen@rock-chips.com>");
-+MODULE_DESCRIPTION("Rockchip RK3288 DWMAC specific glue layer");
-+MODULE_LICENSE("GPL");
---- a/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c
-+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c
-@@ -23,7 +23,9 @@
- #include <linux/regmap.h>
- #include <linux/reset.h>
- #include <linux/stmmac.h>
-+
- #include "stmmac.h"
-+#include "stmmac_platform.h"
- 
- #define SYSMGR_EMACGRP_CTRL_PHYSEL_ENUM_GMII_MII 0x0
- #define SYSMGR_EMACGRP_CTRL_PHYSEL_ENUM_RGMII 0x1
-@@ -89,7 +91,9 @@ static int socfpga_dwmac_parse_data(stru
- 						  STMMAC_RESOURCE_NAME);
- 	if (IS_ERR(dwmac->stmmac_rst)) {
- 		dev_info(dev, "Could not get reset control!\n");
--		return -EINVAL;
-+		if (PTR_ERR(dwmac->stmmac_rst) == -EPROBE_DEFER)
-+			return -EPROBE_DEFER;
-+		dwmac->stmmac_rst = NULL;
- 	}
- 
- 	dwmac->interface = of_get_phy_mode(np);
-@@ -171,31 +175,6 @@ static int socfpga_dwmac_setup(struct so
- 	return 0;
- }
- 
--static void *socfpga_dwmac_probe(struct platform_device *pdev)
--{
--	struct device		*dev = &pdev->dev;
--	int			ret;
--	struct socfpga_dwmac	*dwmac;
--
--	dwmac = devm_kzalloc(dev, sizeof(*dwmac), GFP_KERNEL);
--	if (!dwmac)
--		return ERR_PTR(-ENOMEM);
--
--	ret = socfpga_dwmac_parse_data(dwmac, dev);
--	if (ret) {
--		dev_err(dev, "Unable to parse OF data\n");
--		return ERR_PTR(ret);
--	}
--
--	ret = socfpga_dwmac_setup(dwmac);
--	if (ret) {
--		dev_err(dev, "couldn't setup SoC glue (%d)\n", ret);
--		return ERR_PTR(ret);
--	}
--
--	return dwmac;
--}
--
- static void socfpga_dwmac_exit(struct platform_device *pdev, void *priv)
- {
- 	struct socfpga_dwmac	*dwmac = priv;
-@@ -253,9 +232,65 @@ static int socfpga_dwmac_init(struct pla
- 	return ret;
- }
- 
--const struct stmmac_of_data socfpga_gmac_data = {
--	.setup = socfpga_dwmac_probe,
--	.init = socfpga_dwmac_init,
--	.exit = socfpga_dwmac_exit,
--	.fix_mac_speed = socfpga_dwmac_fix_mac_speed,
-+static int socfpga_dwmac_probe(struct platform_device *pdev)
-+{
-+	struct plat_stmmacenet_data *plat_dat;
-+	struct stmmac_resources stmmac_res;
-+	struct device		*dev = &pdev->dev;
-+	int			ret;
-+	struct socfpga_dwmac	*dwmac;
-+
-+	ret = stmmac_get_platform_resources(pdev, &stmmac_res);
-+	if (ret)
-+		return ret;
-+
-+	plat_dat = stmmac_probe_config_dt(pdev, &stmmac_res.mac);
-+	if (IS_ERR(plat_dat))
-+		return PTR_ERR(plat_dat);
-+
-+	dwmac = devm_kzalloc(dev, sizeof(*dwmac), GFP_KERNEL);
-+	if (!dwmac)
-+		return -ENOMEM;
-+
-+	ret = socfpga_dwmac_parse_data(dwmac, dev);
-+	if (ret) {
-+		dev_err(dev, "Unable to parse OF data\n");
-+		return ret;
-+	}
-+
-+	ret = socfpga_dwmac_setup(dwmac);
-+	if (ret) {
-+		dev_err(dev, "couldn't setup SoC glue (%d)\n", ret);
-+		return ret;
-+	}
-+
-+	plat_dat->bsp_priv = dwmac;
-+	plat_dat->init = socfpga_dwmac_init;
-+	plat_dat->exit = socfpga_dwmac_exit;
-+	plat_dat->fix_mac_speed = socfpga_dwmac_fix_mac_speed;
-+
-+	ret = socfpga_dwmac_init(pdev, plat_dat->bsp_priv);
-+	if (ret)
-+		return ret;
-+
-+	return stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res);
-+}
-+
-+static const struct of_device_id socfpga_dwmac_match[] = {
-+	{ .compatible = "altr,socfpga-stmmac" },
-+	{ }
- };
-+MODULE_DEVICE_TABLE(of, socfpga_dwmac_match);
-+
-+static struct platform_driver socfpga_dwmac_driver = {
-+	.probe  = socfpga_dwmac_probe,
-+	.remove = stmmac_pltfr_remove,
-+	.driver = {
-+		.name           = "socfpga-dwmac",
-+		.pm		= &stmmac_pltfr_pm_ops,
-+		.of_match_table = socfpga_dwmac_match,
-+	},
-+};
-+module_platform_driver(socfpga_dwmac_driver);
-+
-+MODULE_LICENSE("GPL v2");
---- a/drivers/net/ethernet/stmicro/stmmac/dwmac-sti.c
-+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-sti.c
-@@ -1,4 +1,4 @@
--/**
-+/*
-  * dwmac-sti.c - STMicroelectronics DWMAC Specific Glue layer
-  *
-  * Copyright (C) 2003-2014 STMicroelectronics (R&D) Limited
-@@ -17,11 +17,15 @@
- #include <linux/stmmac.h>
- #include <linux/phy.h>
- #include <linux/mfd/syscon.h>
-+#include <linux/module.h>
- #include <linux/regmap.h>
- #include <linux/clk.h>
- #include <linux/of.h>
-+#include <linux/of_device.h>
- #include <linux/of_net.h>
- 
-+#include "stmmac_platform.h"
-+
- #define DWMAC_125MHZ	125000000
- #define DWMAC_50MHZ	50000000
- #define DWMAC_25MHZ	25000000
-@@ -35,9 +39,8 @@
- #define IS_PHY_IF_MODE_GBIT(iface)	(IS_PHY_IF_MODE_RGMII(iface) || \
- 					 iface == PHY_INTERFACE_MODE_GMII)
- 
--/* STiH4xx register definitions (STiH415/STiH416/STiH407/STiH410 families) */
--
--/**
-+/* STiH4xx register definitions (STiH415/STiH416/STiH407/STiH410 families)
-+ *
-  * Below table summarizes the clock requirement and clock sources for
-  * supported phy interface modes with link speeds.
-  * ________________________________________________
-@@ -76,9 +79,7 @@
- #define STIH4XX_ETH_SEL_INTERNAL_NOTEXT_PHYCLK	BIT(7)
- #define STIH4XX_ETH_SEL_TXCLK_NOT_CLK125	BIT(6)
- 
--/* STiD127 register definitions */
--
--/**
-+/* STiD127 register definitions
-  *-----------------------
-  * src	 |BIT(6)| BIT(7)|
-  *-----------------------
-@@ -104,13 +105,13 @@
- #define EN_MASK		GENMASK(1, 1)
- #define EN		BIT(1)
- 
--/**
-+/*
-  * 3 bits [4:2]
-  *	000-GMII/MII
-  *	001-RGMII
-  *	010-SGMII
-  *	100-RMII
--*/
-+ */
- #define MII_PHY_SEL_MASK	GENMASK(4, 2)
- #define ETH_PHY_SEL_RMII	BIT(4)
- #define ETH_PHY_SEL_SGMII	BIT(3)
-@@ -123,11 +124,16 @@ struct sti_dwmac {
- 	bool ext_phyclk;	/* Clock from external PHY */
- 	u32 tx_retime_src;	/* TXCLK Retiming*/
- 	struct clk *clk;	/* PHY clock */
--	int ctrl_reg;		/* GMAC glue-logic control register */
-+	u32 ctrl_reg;		/* GMAC glue-logic control register */
- 	int clk_sel_reg;	/* GMAC ext clk selection register */
- 	struct device *dev;
- 	struct regmap *regmap;
- 	u32 speed;
-+	void (*fix_retime_src)(void *priv, unsigned int speed);
-+};
-+
-+struct sti_dwmac_of_data {
-+	void (*fix_retime_src)(void *priv, unsigned int speed);
- };
- 
- static u32 phy_intf_sels[] = {
-@@ -222,8 +228,9 @@ static void stid127_fix_retime_src(void
- 	regmap_update_bits(dwmac->regmap, reg, STID127_RETIME_SRC_MASK, val);
- }
- 
--static void sti_dwmac_ctrl_init(struct sti_dwmac *dwmac)
-+static int sti_dwmac_init(struct platform_device *pdev, void *priv)
- {
-+	struct sti_dwmac *dwmac = priv;
- 	struct regmap *regmap = dwmac->regmap;
- 	int iface = dwmac->interface;
- 	struct device *dev = dwmac->dev;
-@@ -241,28 +248,8 @@ static void sti_dwmac_ctrl_init(struct s
- 
- 	val = (iface == PHY_INTERFACE_MODE_REVMII) ? 0 : ENMII;
- 	regmap_update_bits(regmap, reg, ENMII_MASK, val);
--}
- 
--static int stix4xx_init(struct platform_device *pdev, void *priv)
--{
--	struct sti_dwmac *dwmac = priv;
--	u32 spd = dwmac->speed;
--
--	sti_dwmac_ctrl_init(dwmac);
--
--	stih4xx_fix_retime_src(priv, spd);
--
--	return 0;
--}
--
--static int stid127_init(struct platform_device *pdev, void *priv)
--{
--	struct sti_dwmac *dwmac = priv;
--	u32 spd = dwmac->speed;
--
--	sti_dwmac_ctrl_init(dwmac);
--
--	stid127_fix_retime_src(priv, spd);
-+	dwmac->fix_retime_src(priv, dwmac->speed);
- 
- 	return 0;
- }
-@@ -286,11 +273,6 @@ static int sti_dwmac_parse_data(struct s
- 	if (!np)
- 		return -EINVAL;
- 
--	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "sti-ethconf");
--	if (!res)
--		return -ENODATA;
--	dwmac->ctrl_reg = res->start;
--
- 	/* clk selection from extra syscfg register */
- 	dwmac->clk_sel_reg = -ENXIO;
- 	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "sti-clkconf");
-@@ -301,6 +283,12 @@ static int sti_dwmac_parse_data(struct s
- 	if (IS_ERR(regmap))
- 		return PTR_ERR(regmap);
- 
-+	err = of_property_read_u32_index(np, "st,syscon", 1, &dwmac->ctrl_reg);
-+	if (err) {
-+		dev_err(dev, "Can't get sysconfig ctrl offset (%d)\n", err);
-+		return err;
-+	}
-+
- 	dwmac->dev = dev;
- 	dwmac->interface = of_get_phy_mode(np);
- 	dwmac->regmap = regmap;
-@@ -310,16 +298,16 @@ static int sti_dwmac_parse_data(struct s
- 
- 	if (IS_PHY_IF_MODE_GBIT(dwmac->interface)) {
- 		const char *rs;
--		dwmac->tx_retime_src = TX_RETIME_SRC_CLKGEN;
- 
- 		err = of_property_read_string(np, "st,tx-retime-src", &rs);
--		if (err < 0)
-+		if (err < 0) {
- 			dev_warn(dev, "Use internal clock source\n");
--
--		if (!strcasecmp(rs, "clk_125"))
-+			dwmac->tx_retime_src = TX_RETIME_SRC_CLKGEN;
-+		} else if (!strcasecmp(rs, "clk_125")) {
- 			dwmac->tx_retime_src = TX_RETIME_SRC_CLK_125;
--		else if (!strcasecmp(rs, "txclk"))
-+		} else if (!strcasecmp(rs, "txclk")) {
- 			dwmac->tx_retime_src = TX_RETIME_SRC_TXCLK;
-+		}
- 
- 		dwmac->speed = SPEED_1000;
- 	}
-@@ -333,34 +321,80 @@ static int sti_dwmac_parse_data(struct s
- 	return 0;
- }
- 
--static void *sti_dwmac_setup(struct platform_device *pdev)
-+static int sti_dwmac_probe(struct platform_device *pdev)
- {
-+	struct plat_stmmacenet_data *plat_dat;
-+	const struct sti_dwmac_of_data *data;
-+	struct stmmac_resources stmmac_res;
- 	struct sti_dwmac *dwmac;
- 	int ret;
- 
-+	data = of_device_get_match_data(&pdev->dev);
-+	if (!data) {
-+		dev_err(&pdev->dev, "No OF match data provided\n");
-+		return -EINVAL;
-+	}
-+
-+	ret = stmmac_get_platform_resources(pdev, &stmmac_res);
-+	if (ret)
-+		return ret;
-+
-+	plat_dat = stmmac_probe_config_dt(pdev, &stmmac_res.mac);
-+	if (IS_ERR(plat_dat))
-+		return PTR_ERR(plat_dat);
-+
- 	dwmac = devm_kzalloc(&pdev->dev, sizeof(*dwmac), GFP_KERNEL);
- 	if (!dwmac)
--		return ERR_PTR(-ENOMEM);
-+		return -ENOMEM;
- 
- 	ret = sti_dwmac_parse_data(dwmac, pdev);
- 	if (ret) {
- 		dev_err(&pdev->dev, "Unable to parse OF data\n");
--		return ERR_PTR(ret);
-+		return ret;
- 	}
- 
--	return dwmac;
-+	dwmac->fix_retime_src = data->fix_retime_src;
-+
-+	plat_dat->bsp_priv = dwmac;
-+	plat_dat->init = sti_dwmac_init;
-+	plat_dat->exit = sti_dwmac_exit;
-+	plat_dat->fix_mac_speed = data->fix_retime_src;
-+
-+	ret = sti_dwmac_init(pdev, plat_dat->bsp_priv);
-+	if (ret)
-+		return ret;
-+
-+	return stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res);
- }
- 
--const struct stmmac_of_data stih4xx_dwmac_data = {
--	.fix_mac_speed = stih4xx_fix_retime_src,
--	.setup = sti_dwmac_setup,
--	.init = stix4xx_init,
--	.exit = sti_dwmac_exit,
-+static const struct sti_dwmac_of_data stih4xx_dwmac_data = {
-+	.fix_retime_src = stih4xx_fix_retime_src,
- };
- 
--const struct stmmac_of_data stid127_dwmac_data = {
--	.fix_mac_speed = stid127_fix_retime_src,
--	.setup = sti_dwmac_setup,
--	.init = stid127_init,
--	.exit = sti_dwmac_exit,
-+static const struct sti_dwmac_of_data stid127_dwmac_data = {
-+	.fix_retime_src = stid127_fix_retime_src,
- };
-+
-+static const struct of_device_id sti_dwmac_match[] = {
-+	{ .compatible = "st,stih415-dwmac", .data = &stih4xx_dwmac_data},
-+	{ .compatible = "st,stih416-dwmac", .data = &stih4xx_dwmac_data},
-+	{ .compatible = "st,stid127-dwmac", .data = &stid127_dwmac_data},
-+	{ .compatible = "st,stih407-dwmac", .data = &stih4xx_dwmac_data},
-+	{ }
-+};
-+MODULE_DEVICE_TABLE(of, sti_dwmac_match);
-+
-+static struct platform_driver sti_dwmac_driver = {
-+	.probe  = sti_dwmac_probe,
-+	.remove = stmmac_pltfr_remove,
-+	.driver = {
-+		.name           = "sti-dwmac",
-+		.pm		= &stmmac_pltfr_pm_ops,
-+		.of_match_table = sti_dwmac_match,
-+	},
-+};
-+module_platform_driver(sti_dwmac_driver);
-+
-+MODULE_AUTHOR("Srinivas Kandagatla <srinivas.kandagatla@st.com>");
-+MODULE_DESCRIPTION("STMicroelectronics DWMAC Specific Glue layer");
-+MODULE_LICENSE("GPL");
---- a/drivers/net/ethernet/stmicro/stmmac/dwmac-sunxi.c
-+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-sunxi.c
-@@ -1,4 +1,4 @@
--/**
-+/*
-  * dwmac-sunxi.c - Allwinner sunxi DWMAC specific glue layer
-  *
-  * Copyright (C) 2013 Chen-Yu Tsai
-@@ -18,10 +18,14 @@
- 
- #include <linux/stmmac.h>
- #include <linux/clk.h>
-+#include <linux/module.h>
- #include <linux/phy.h>
-+#include <linux/platform_device.h>
- #include <linux/of_net.h>
- #include <linux/regulator/consumer.h>
- 
-+#include "stmmac_platform.h"
-+
- struct sunxi_priv_data {
- 	int interface;
- 	int clk_enabled;
-@@ -29,35 +33,6 @@ struct sunxi_priv_data {
- 	struct regulator *regulator;
- };
- 
--static void *sun7i_gmac_setup(struct platform_device *pdev)
--{
--	struct sunxi_priv_data *gmac;
--	struct device *dev = &pdev->dev;
--
--	gmac = devm_kzalloc(dev, sizeof(*gmac), GFP_KERNEL);
--	if (!gmac)
--		return ERR_PTR(-ENOMEM);
--
--	gmac->interface = of_get_phy_mode(dev->of_node);
--
--	gmac->tx_clk = devm_clk_get(dev, "allwinner_gmac_tx");
--	if (IS_ERR(gmac->tx_clk)) {
--		dev_err(dev, "could not get tx clock\n");
--		return gmac->tx_clk;
--	}
--
--	/* Optional regulator for PHY */
--	gmac->regulator = devm_regulator_get_optional(dev, "phy");
--	if (IS_ERR(gmac->regulator)) {
--		if (PTR_ERR(gmac->regulator) == -EPROBE_DEFER)
--			return ERR_PTR(-EPROBE_DEFER);
--		dev_info(dev, "no regulator found\n");
--		gmac->regulator = NULL;
--	}
--
--	return gmac;
--}
--
- #define SUN7I_GMAC_GMII_RGMII_RATE	125000000
- #define SUN7I_GMAC_MII_RATE		25000000
- 
-@@ -128,13 +103,76 @@ static void sun7i_fix_speed(void *priv,
- 	}
- }
- 
--/* of_data specifying hardware features and callbacks.
-- * hardware features were copied from Allwinner drivers. */
--const struct stmmac_of_data sun7i_gmac_data = {
--	.has_gmac = 1,
--	.tx_coe = 1,
--	.fix_mac_speed = sun7i_fix_speed,
--	.setup = sun7i_gmac_setup,
--	.init = sun7i_gmac_init,
--	.exit = sun7i_gmac_exit,
-+static int sun7i_gmac_probe(struct platform_device *pdev)
-+{
-+	struct plat_stmmacenet_data *plat_dat;
-+	struct stmmac_resources stmmac_res;
-+	struct sunxi_priv_data *gmac;
-+	struct device *dev = &pdev->dev;
-+	int ret;
-+
-+	ret = stmmac_get_platform_resources(pdev, &stmmac_res);
-+	if (ret)
-+		return ret;
-+
-+	plat_dat = stmmac_probe_config_dt(pdev, &stmmac_res.mac);
-+	if (IS_ERR(plat_dat))
-+		return PTR_ERR(plat_dat);
-+
-+	gmac = devm_kzalloc(dev, sizeof(*gmac), GFP_KERNEL);
-+	if (!gmac)
-+		return -ENOMEM;
-+
-+	gmac->interface = of_get_phy_mode(dev->of_node);
-+
-+	gmac->tx_clk = devm_clk_get(dev, "allwinner_gmac_tx");
-+	if (IS_ERR(gmac->tx_clk)) {
-+		dev_err(dev, "could not get tx clock\n");
-+		return PTR_ERR(gmac->tx_clk);
-+	}
-+
-+	/* Optional regulator for PHY */
-+	gmac->regulator = devm_regulator_get_optional(dev, "phy");
-+	if (IS_ERR(gmac->regulator)) {
-+		if (PTR_ERR(gmac->regulator) == -EPROBE_DEFER)
-+			return -EPROBE_DEFER;
-+		dev_info(dev, "no regulator found\n");
-+		gmac->regulator = NULL;
-+	}
-+
-+	/* platform data specifying hardware features and callbacks.
-+	 * hardware features were copied from Allwinner drivers. */
-+	plat_dat->tx_coe = 1;
-+	plat_dat->has_gmac = true;
-+	plat_dat->bsp_priv = gmac;
-+	plat_dat->init = sun7i_gmac_init;
-+	plat_dat->exit = sun7i_gmac_exit;
-+	plat_dat->fix_mac_speed = sun7i_fix_speed;
-+
-+	ret = sun7i_gmac_init(pdev, plat_dat->bsp_priv);
-+	if (ret)
-+		return ret;
-+
-+	return stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res);
-+}
-+
-+static const struct of_device_id sun7i_dwmac_match[] = {
-+	{ .compatible = "allwinner,sun7i-a20-gmac" },
-+	{ }
- };
-+MODULE_DEVICE_TABLE(of, sun7i_dwmac_match);
-+
-+static struct platform_driver sun7i_dwmac_driver = {
-+	.probe  = sun7i_gmac_probe,
-+	.remove = stmmac_pltfr_remove,
-+	.driver = {
-+		.name           = "sun7i-dwmac",
-+		.pm		= &stmmac_pltfr_pm_ops,
-+		.of_match_table = sun7i_dwmac_match,
-+	},
-+};
-+module_platform_driver(sun7i_dwmac_driver);
-+
-+MODULE_AUTHOR("Chen-Yu Tsai <wens@csie.org>");
-+MODULE_DESCRIPTION("Allwinner sunxi DWMAC specific glue layer");
-+MODULE_LICENSE("GPL");
---- a/drivers/net/ethernet/stmicro/stmmac/dwmac1000.h
-+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac1000.h
-@@ -172,6 +172,7 @@ enum inter_frame_gap {
- /* GMAC FLOW CTRL defines */
- #define GMAC_FLOW_CTRL_PT_MASK	0xffff0000	/* Pause Time Mask */
- #define GMAC_FLOW_CTRL_PT_SHIFT	16
-+#define GMAC_FLOW_CTRL_UP	0x00000008	/* Unicast pause frame enable */
- #define GMAC_FLOW_CTRL_RFE	0x00000004	/* Rx Flow Control Enable */
- #define GMAC_FLOW_CTRL_TFE	0x00000002	/* Tx Flow Control Enable */
- #define GMAC_FLOW_CTRL_FCB_BPA	0x00000001	/* Flow Control Busy ... */
-@@ -246,6 +247,56 @@ enum ttc_control {
- #define DMA_CONTROL_FEF		0x00000080
- #define DMA_CONTROL_FUF		0x00000040
- 
-+/* Receive flow control activation field
-+ * RFA field in DMA control register, bits 23,10:9
-+ */
-+#define DMA_CONTROL_RFA_MASK	0x00800600
-+
-+/* Receive flow control deactivation field
-+ * RFD field in DMA control register, bits 22,12:11
-+ */
-+#define DMA_CONTROL_RFD_MASK	0x00401800
-+
-+/* RFD and RFA fields are encoded as follows
-+ *
-+ *   Bit Field
-+ *   0,00 - Full minus 1KB (only valid when rxfifo >= 4KB and EFC enabled)
-+ *   0,01 - Full minus 2KB (only valid when rxfifo >= 4KB and EFC enabled)
-+ *   0,10 - Full minus 3KB (only valid when rxfifo >= 4KB and EFC enabled)
-+ *   0,11 - Full minus 4KB (only valid when rxfifo > 4KB and EFC enabled)
-+ *   1,00 - Full minus 5KB (only valid when rxfifo > 8KB and EFC enabled)
-+ *   1,01 - Full minus 6KB (only valid when rxfifo > 8KB and EFC enabled)
-+ *   1,10 - Full minus 7KB (only valid when rxfifo > 8KB and EFC enabled)
-+ *   1,11 - Reserved
-+ *
-+ * RFD should always be > RFA for a given FIFO size. RFD == RFA may work,
-+ * but packet throughput performance may not be as expected.
-+ *
-+ * Be sure that bit 3 in GMAC Register 6 is set for Unicast Pause frame
-+ * detection (IEEE Specification Requirement, Annex 31B, 31B.1, Pause
-+ * Description).
-+ *
-+ * Be sure that DZPA (bit 7 in Flow Control Register, GMAC Register 6),
-+ * is set to 0. This allows pause frames with a quanta of 0 to be sent
-+ * as an XOFF message to the link peer.
-+ */
-+
-+#define RFA_FULL_MINUS_1K	0x00000000
-+#define RFA_FULL_MINUS_2K	0x00000200
-+#define RFA_FULL_MINUS_3K	0x00000400
-+#define RFA_FULL_MINUS_4K	0x00000600
-+#define RFA_FULL_MINUS_5K	0x00800000
-+#define RFA_FULL_MINUS_6K	0x00800200
-+#define RFA_FULL_MINUS_7K	0x00800400
-+
-+#define RFD_FULL_MINUS_1K	0x00000000
-+#define RFD_FULL_MINUS_2K	0x00000800
-+#define RFD_FULL_MINUS_3K	0x00001000
-+#define RFD_FULL_MINUS_4K	0x00001800
-+#define RFD_FULL_MINUS_5K	0x00400000
-+#define RFD_FULL_MINUS_6K	0x00400800
-+#define RFD_FULL_MINUS_7K	0x00401000
-+
- enum rtc_control {
- 	DMA_CONTROL_RTC_64 = 0x00000000,
- 	DMA_CONTROL_RTC_32 = 0x00000008,
---- a/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c
-+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c
-@@ -201,7 +201,10 @@ static void dwmac1000_flow_ctrl(struct m
- 				unsigned int fc, unsigned int pause_time)
- {
- 	void __iomem *ioaddr = hw->pcsr;
--	unsigned int flow = 0;
-+	/* Set flow such that DZPQ in Mac Register 6 is 0,
-+	 * and unicast pause detect is enabled.
-+	 */
-+	unsigned int flow = GMAC_FLOW_CTRL_UP;
- 
- 	pr_debug("GMAC Flow-Control:\n");
- 	if (fc & FLOW_RX) {
---- a/drivers/net/ethernet/stmicro/stmmac/dwmac1000_dma.c
-+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac1000_dma.c
-@@ -70,10 +70,6 @@ static int dwmac1000_dma_init(void __iom
- 	if (mb)
- 		value |= DMA_BUS_MODE_MB;
- 
--#ifdef CONFIG_STMMAC_DA
--	value |= DMA_BUS_MODE_DA;	/* Rx has priority over tx */
--#endif
--
- 	if (atds)
- 		value |= DMA_BUS_MODE_ATDS;
- 
-@@ -110,8 +106,29 @@ static int dwmac1000_dma_init(void __iom
- 	return 0;
- }
- 
-+static u32 dwmac1000_configure_fc(u32 csr6, int rxfifosz)
-+{
-+	csr6 &= ~DMA_CONTROL_RFA_MASK;
-+	csr6 &= ~DMA_CONTROL_RFD_MASK;
-+
-+	/* Leave flow control disabled if receive fifo size is less than
-+	 * 4K or 0. Otherwise, send XOFF when fifo is 1K less than full,
-+	 * and send XON when 2K less than full.
-+	 */
-+	if (rxfifosz < 4096) {
-+		csr6 &= ~DMA_CONTROL_EFC;
-+		pr_debug("GMAC: disabling flow control, rxfifo too small(%d)\n",
-+			 rxfifosz);
-+	} else {
-+		csr6 |= DMA_CONTROL_EFC;
-+		csr6 |= RFA_FULL_MINUS_1K;
-+		csr6 |= RFD_FULL_MINUS_2K;
-+	}
-+	return csr6;
-+}
-+
- static void dwmac1000_dma_operation_mode(void __iomem *ioaddr, int txmode,
--					 int rxmode)
-+					 int rxmode, int rxfifosz)
- {
- 	u32 csr6 = readl(ioaddr + DMA_CONTROL);
- 
-@@ -157,6 +174,9 @@ static void dwmac1000_dma_operation_mode
- 			csr6 |= DMA_CONTROL_RTC_128;
- 	}
- 
-+	/* Configure flow control based on rx fifo size */
-+	csr6 = dwmac1000_configure_fc(csr6, rxfifosz);
-+
- 	writel(csr6, ioaddr + DMA_CONTROL);
- }
- 
---- a/drivers/net/ethernet/stmicro/stmmac/dwmac100_dma.c
-+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac100_dma.c
-@@ -72,7 +72,7 @@ static int dwmac100_dma_init(void __iome
-  * control register.
-  */
- static void dwmac100_dma_operation_mode(void __iomem *ioaddr, int txmode,
--					int rxmode)
-+					int rxmode, int rxfifosz)
- {
- 	u32 csr6 = readl(ioaddr + DMA_CONTROL);
- 
---- a/drivers/net/ethernet/stmicro/stmmac/mmc_core.c
-+++ b/drivers/net/ethernet/stmicro/stmmac/mmc_core.c
-@@ -73,7 +73,7 @@
- #define MMC_RX_OCTETCOUNT_G		0x00000188
- #define MMC_RX_BROADCASTFRAME_G		0x0000018c
- #define MMC_RX_MULTICASTFRAME_G		0x00000190
--#define MMC_RX_CRC_ERRROR		0x00000194
-+#define MMC_RX_CRC_ERROR		0x00000194
- #define MMC_RX_ALIGN_ERROR		0x00000198
- #define MMC_RX_RUN_ERROR		0x0000019C
- #define MMC_RX_JABBER_ERROR		0x000001A0
-@@ -196,7 +196,7 @@ void dwmac_mmc_read(void __iomem *ioaddr
- 	mmc->mmc_rx_octetcount_g += readl(ioaddr + MMC_RX_OCTETCOUNT_G);
- 	mmc->mmc_rx_broadcastframe_g += readl(ioaddr + MMC_RX_BROADCASTFRAME_G);
- 	mmc->mmc_rx_multicastframe_g += readl(ioaddr + MMC_RX_MULTICASTFRAME_G);
--	mmc->mmc_rx_crc_error += readl(ioaddr + MMC_RX_CRC_ERRROR);
-+	mmc->mmc_rx_crc_error += readl(ioaddr + MMC_RX_CRC_ERROR);
- 	mmc->mmc_rx_align_error += readl(ioaddr + MMC_RX_ALIGN_ERROR);
- 	mmc->mmc_rx_run_error += readl(ioaddr + MMC_RX_RUN_ERROR);
- 	mmc->mmc_rx_jabber_error += readl(ioaddr + MMC_RX_JABBER_ERROR);
---- a/drivers/net/ethernet/stmicro/stmmac/stmmac.h
-+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac.h
-@@ -34,6 +34,14 @@
- #include <linux/ptp_clock_kernel.h>
- #include <linux/reset.h>
- 
-+struct stmmac_resources {
-+	void __iomem *addr;
-+	const char *mac;
-+	int wol_irq;
-+	int lpi_irq;
-+	int irq;
-+};
-+
- struct stmmac_tx_info {
- 	dma_addr_t buf;
- 	bool map_as_page;
-@@ -97,6 +105,7 @@ struct stmmac_priv {
- 	int wolopts;
- 	int wol_irq;
- 	struct clk *stmmac_clk;
-+	struct clk *pclk;
- 	struct reset_control *stmmac_rst;
- 	int clk_csr;
- 	struct timer_list eee_ctrl_timer;
-@@ -116,97 +125,28 @@ struct stmmac_priv {
- 	int use_riwt;
- 	int irq_wake;
- 	spinlock_t ptp_lock;
-+
-+#ifdef CONFIG_DEBUG_FS
-+	struct dentry *dbgfs_dir;
-+	struct dentry *dbgfs_rings_status;
-+	struct dentry *dbgfs_dma_cap;
-+#endif
- };
- 
- int stmmac_mdio_unregister(struct net_device *ndev);
- int stmmac_mdio_register(struct net_device *ndev);
- int stmmac_mdio_reset(struct mii_bus *mii);
- void stmmac_set_ethtool_ops(struct net_device *netdev);
--extern const struct stmmac_desc_ops enh_desc_ops;
--extern const struct stmmac_desc_ops ndesc_ops;
--extern const struct stmmac_hwtimestamp stmmac_ptp;
-+
- int stmmac_ptp_register(struct stmmac_priv *priv);
- void stmmac_ptp_unregister(struct stmmac_priv *priv);
- int stmmac_resume(struct net_device *ndev);
- int stmmac_suspend(struct net_device *ndev);
- int stmmac_dvr_remove(struct net_device *ndev);
--struct stmmac_priv *stmmac_dvr_probe(struct device *device,
--				     struct plat_stmmacenet_data *plat_dat,
--				     void __iomem *addr);
-+int stmmac_dvr_probe(struct device *device,
-+		     struct plat_stmmacenet_data *plat_dat,
-+		     struct stmmac_resources *res);
- void stmmac_disable_eee_mode(struct stmmac_priv *priv);
- bool stmmac_eee_init(struct stmmac_priv *priv);
- 
--#ifdef CONFIG_STMMAC_PLATFORM
--#ifdef CONFIG_DWMAC_MESON
--extern const struct stmmac_of_data meson6_dwmac_data;
--#endif
--#ifdef CONFIG_DWMAC_SUNXI
--extern const struct stmmac_of_data sun7i_gmac_data;
--#endif
--#ifdef CONFIG_DWMAC_STI
--extern const struct stmmac_of_data stih4xx_dwmac_data;
--extern const struct stmmac_of_data stid127_dwmac_data;
--#endif
--#ifdef CONFIG_DWMAC_SOCFPGA
--extern const struct stmmac_of_data socfpga_gmac_data;
--#endif
--extern struct platform_driver stmmac_pltfr_driver;
--static inline int stmmac_register_platform(void)
--{
--	int err;
--
--	err = platform_driver_register(&stmmac_pltfr_driver);
--	if (err)
--		pr_err("stmmac: failed to register the platform driver\n");
--
--	return err;
--}
--
--static inline void stmmac_unregister_platform(void)
--{
--	platform_driver_unregister(&stmmac_pltfr_driver);
--}
--#else
--static inline int stmmac_register_platform(void)
--{
--	pr_debug("stmmac: do not register the platf driver\n");
--
--	return 0;
--}
--
--static inline void stmmac_unregister_platform(void)
--{
--}
--#endif /* CONFIG_STMMAC_PLATFORM */
--
--#ifdef CONFIG_STMMAC_PCI
--extern struct pci_driver stmmac_pci_driver;
--static inline int stmmac_register_pci(void)
--{
--	int err;
--
--	err = pci_register_driver(&stmmac_pci_driver);
--	if (err)
--		pr_err("stmmac: failed to register the PCI driver\n");
--
--	return err;
--}
--
--static inline void stmmac_unregister_pci(void)
--{
--	pci_unregister_driver(&stmmac_pci_driver);
--}
--#else
--static inline int stmmac_register_pci(void)
--{
--	pr_debug("stmmac: do not register the PCI driver\n");
--
--	return 0;
--}
--
--static inline void stmmac_unregister_pci(void)
--{
--}
--#endif /* CONFIG_STMMAC_PCI */
--
- #endif /* __STMMAC_H__ */
---- a/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
-+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
-@@ -696,7 +696,7 @@ static int stmmac_set_coalesce(struct ne
- 	    (ec->tx_max_coalesced_frames == 0))
- 		return -EINVAL;
- 
--	if ((ec->tx_coalesce_usecs > STMMAC_COAL_TX_TIMER) ||
-+	if ((ec->tx_coalesce_usecs > STMMAC_MAX_COAL_TX_TICK) ||
- 	    (ec->tx_max_coalesced_frames > STMMAC_TX_MAX_FRAMES))
- 		return -EINVAL;
- 
---- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
-+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
-@@ -44,14 +44,15 @@
- #include <linux/slab.h>
- #include <linux/prefetch.h>
- #include <linux/pinctrl/consumer.h>
--#ifdef CONFIG_STMMAC_DEBUG_FS
-+#ifdef CONFIG_DEBUG_FS
- #include <linux/debugfs.h>
- #include <linux/seq_file.h>
--#endif /* CONFIG_STMMAC_DEBUG_FS */
-+#endif /* CONFIG_DEBUG_FS */
- #include <linux/net_tstamp.h>
- #include "stmmac_ptp.h"
- #include "stmmac.h"
- #include <linux/reset.h>
-+#include <linux/of_mdio.h>
- 
- #define STMMAC_ALIGN(x)	L1_CACHE_ALIGN(x)
- 
-@@ -116,17 +117,17 @@ MODULE_PARM_DESC(chain_mode, "To use cha
- 
- static irqreturn_t stmmac_interrupt(int irq, void *dev_id);
- 
--#ifdef CONFIG_STMMAC_DEBUG_FS
-+#ifdef CONFIG_DEBUG_FS
- static int stmmac_init_fs(struct net_device *dev);
--static void stmmac_exit_fs(void);
-+static void stmmac_exit_fs(struct net_device *dev);
- #endif
- 
- #define STMMAC_COAL_TIMER(x) (jiffies + usecs_to_jiffies(x))
- 
- /**
-  * stmmac_verify_args - verify the driver parameters.
-- * Description: it verifies if some wrong parameter is passed to the driver.
-- * Note that wrong parameters are replaced with the default values.
-+ * Description: it checks the driver parameters and set a default in case of
-+ * errors.
-  */
- static void stmmac_verify_args(void)
- {
-@@ -191,14 +192,8 @@ static void stmmac_clk_csr_set(struct st
- 
- static void print_pkt(unsigned char *buf, int len)
- {
--	int j;
--	pr_debug("len = %d byte, buf addr: 0x%p", len, buf);
--	for (j = 0; j < len; j++) {
--		if ((j % 16) == 0)
--			pr_debug("\n %03x:", j);
--		pr_debug(" %02x", buf[j]);
--	}
--	pr_debug("\n");
-+	pr_debug("len = %d byte, buf addr: 0x%p\n", len, buf);
-+	print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, buf, len);
- }
- 
- /* minimum number of free TX descriptors required to wake up TX process */
-@@ -210,7 +205,7 @@ static inline u32 stmmac_tx_avail(struct
- }
- 
- /**
-- * stmmac_hw_fix_mac_speed: callback for speed selection
-+ * stmmac_hw_fix_mac_speed - callback for speed selection
-  * @priv: driver private structure
-  * Description: on some platforms (e.g. ST), some HW system configuraton
-  * registers have to be set according to the link speed negotiated.
-@@ -224,9 +219,10 @@ static inline void stmmac_hw_fix_mac_spe
- }
- 
- /**
-- * stmmac_enable_eee_mode: Check and enter in LPI mode
-+ * stmmac_enable_eee_mode - check and enter in LPI mode
-  * @priv: driver private structure
-- * Description: this function is to verify and enter in LPI mode for EEE.
-+ * Description: this function is to verify and enter in LPI mode in case of
-+ * EEE.
-  */
- static void stmmac_enable_eee_mode(struct stmmac_priv *priv)
- {
-@@ -237,7 +233,7 @@ static void stmmac_enable_eee_mode(struc
- }
- 
- /**
-- * stmmac_disable_eee_mode: disable/exit from EEE
-+ * stmmac_disable_eee_mode - disable and exit from LPI mode
-  * @priv: driver private structure
-  * Description: this function is to exit and disable EEE in case of
-  * LPI state is true. This is called by the xmit.
-@@ -250,7 +246,7 @@ void stmmac_disable_eee_mode(struct stmm
- }
- 
- /**
-- * stmmac_eee_ctrl_timer: EEE TX SW timer.
-+ * stmmac_eee_ctrl_timer - EEE TX SW timer.
-  * @arg : data hook
-  * Description:
-  *  if there is no data transfer and if we are not in LPI state,
-@@ -265,13 +261,12 @@ static void stmmac_eee_ctrl_timer(unsign
- }
- 
- /**
-- * stmmac_eee_init: init EEE
-+ * stmmac_eee_init - init EEE
-  * @priv: driver private structure
-  * Description:
-- *  If the EEE support has been enabled while configuring the driver,
-- *  if the GMAC actually supports the EEE (from the HW cap reg) and the
-- *  phy can also manage EEE, so enable the LPI state and start the timer
-- *  to verify if the tx path can enter in LPI state.
-+ *  if the GMAC supports the EEE (from the HW cap reg) and the phy device
-+ *  can also manage EEE, this function enable the LPI state and start related
-+ *  timer.
-  */
- bool stmmac_eee_init(struct stmmac_priv *priv)
- {
-@@ -316,11 +311,11 @@ bool stmmac_eee_init(struct stmmac_priv
- 		spin_lock_irqsave(&priv->lock, flags);
- 		if (!priv->eee_active) {
- 			priv->eee_active = 1;
--			init_timer(&priv->eee_ctrl_timer);
--			priv->eee_ctrl_timer.function = stmmac_eee_ctrl_timer;
--			priv->eee_ctrl_timer.data = (unsigned long)priv;
--			priv->eee_ctrl_timer.expires = STMMAC_LPI_T(eee_timer);
--			add_timer(&priv->eee_ctrl_timer);
-+			setup_timer(&priv->eee_ctrl_timer,
-+				    stmmac_eee_ctrl_timer,
-+				    (unsigned long)priv);
-+			mod_timer(&priv->eee_ctrl_timer,
-+				  STMMAC_LPI_T(eee_timer));
- 
- 			priv->hw->mac->set_eee_timer(priv->hw,
- 						     STMMAC_DEFAULT_LIT_LS,
-@@ -338,7 +333,7 @@ out:
- 	return ret;
- }
- 
--/* stmmac_get_tx_hwtstamp: get HW TX timestamps
-+/* stmmac_get_tx_hwtstamp - get HW TX timestamps
-  * @priv: driver private structure
-  * @entry : descriptor index to be used.
-  * @skb : the socket buffer
-@@ -380,7 +375,7 @@ static void stmmac_get_tx_hwtstamp(struc
- 	return;
- }
- 
--/* stmmac_get_rx_hwtstamp: get HW RX timestamps
-+/* stmmac_get_rx_hwtstamp - get HW RX timestamps
-  * @priv: driver private structure
-  * @entry : descriptor index to be used.
-  * @skb : the socket buffer
-@@ -615,7 +610,7 @@ static int stmmac_hwtstamp_ioctl(struct
- 		 * where, freq_div_ratio = clk_ptp_ref_i/50MHz
- 		 * hence, addend = ((2^32) * 50MHz)/clk_ptp_ref_i;
- 		 * NOTE: clk_ptp_ref_i should be >= 50MHz to
--		 *       achive 20ns accuracy.
-+		 *       achieve 20ns accuracy.
- 		 *
- 		 * 2^x * y == (y << x), hence
- 		 * 2^32 * 50000000 ==> (50000000 << 32)
-@@ -636,11 +631,11 @@ static int stmmac_hwtstamp_ioctl(struct
- }
- 
- /**
-- * stmmac_init_ptp: init PTP
-+ * stmmac_init_ptp - init PTP
-  * @priv: driver private structure
-- * Description: this is to verify if the HW supports the PTPv1 or v2.
-+ * Description: this is to verify if the HW supports the PTPv1 or PTPv2.
-  * This is done by looking at the HW cap. register.
-- * Also it registers the ptp driver.
-+ * This function also registers the ptp driver.
-  */
- static int stmmac_init_ptp(struct stmmac_priv *priv)
- {
-@@ -682,9 +677,13 @@ static void stmmac_release_ptp(struct st
- }
- 
- /**
-- * stmmac_adjust_link
-+ * stmmac_adjust_link - adjusts the link parameters
-  * @dev: net device structure
-- * Description: it adjusts the link parameters.
-+ * Description: this is the helper called by the physical abstraction layer
-+ * drivers to communicate the phy link status. According the speed and duplex
-+ * this driver can invoke registered glue-logic as well.
-+ * It also invoke the eee initialization because it could happen when switch
-+ * on different networks (that are eee capable).
-  */
- static void stmmac_adjust_link(struct net_device *dev)
- {
-@@ -774,7 +773,7 @@ static void stmmac_adjust_link(struct ne
- }
- 
- /**
-- * stmmac_check_pcs_mode: verify if RGMII/SGMII is supported
-+ * stmmac_check_pcs_mode - verify if RGMII/SGMII is supported
-  * @priv: driver private structure
-  * Description: this is to verify if the HW supports the PCS.
-  * Physical Coding Sublayer (PCS) interface that can be used when the MAC is
-@@ -818,21 +817,31 @@ static int stmmac_init_phy(struct net_de
- 	priv->speed = 0;
- 	priv->oldduplex = -1;
- 
--	if (priv->plat->phy_bus_name)
--		snprintf(bus_id, MII_BUS_ID_SIZE, "%s-%x",
--			 priv->plat->phy_bus_name, priv->plat->bus_id);
--	else
--		snprintf(bus_id, MII_BUS_ID_SIZE, "stmmac-%x",
--			 priv->plat->bus_id);
-+	if (priv->plat->phy_node) {
-+		phydev = of_phy_connect(dev, priv->plat->phy_node,
-+					&stmmac_adjust_link, 0, interface);
-+	} else {
-+		if (priv->plat->phy_bus_name)
-+			snprintf(bus_id, MII_BUS_ID_SIZE, "%s-%x",
-+				 priv->plat->phy_bus_name, priv->plat->bus_id);
-+		else
-+			snprintf(bus_id, MII_BUS_ID_SIZE, "stmmac-%x",
-+				 priv->plat->bus_id);
- 
--	snprintf(phy_id_fmt, MII_BUS_ID_SIZE + 3, PHY_ID_FMT, bus_id,
--		 priv->plat->phy_addr);
--	pr_debug("stmmac_init_phy:  trying to attach to %s\n", phy_id_fmt);
-+		snprintf(phy_id_fmt, MII_BUS_ID_SIZE + 3, PHY_ID_FMT, bus_id,
-+			 priv->plat->phy_addr);
-+		pr_debug("stmmac_init_phy:  trying to attach to %s\n",
-+			 phy_id_fmt);
- 
--	phydev = phy_connect(dev, phy_id_fmt, &stmmac_adjust_link, interface);
-+		phydev = phy_connect(dev, phy_id_fmt, &stmmac_adjust_link,
-+				     interface);
-+	}
- 
--	if (IS_ERR(phydev)) {
-+	if (IS_ERR_OR_NULL(phydev)) {
- 		pr_err("%s: Could not attach to PHY\n", dev->name);
-+		if (!phydev)
-+			return -ENODEV;
-+
- 		return PTR_ERR(phydev);
- 	}
- 
-@@ -850,7 +859,7 @@ static int stmmac_init_phy(struct net_de
- 	 * device as well.
- 	 * Note: phydev->phy_id is the result of reading the UID PHY registers.
- 	 */
--	if (phydev->phy_id == 0) {
-+	if (!priv->plat->phy_node && phydev->phy_id == 0) {
- 		phy_disconnect(phydev);
- 		return -ENODEV;
- 	}
-@@ -863,7 +872,7 @@ static int stmmac_init_phy(struct net_de
- }
- 
- /**
-- * stmmac_display_ring: display ring
-+ * stmmac_display_ring - display ring
-  * @head: pointer to the head of the ring passed.
-  * @size: size of the ring.
-  * @extend_desc: to verify if extended descriptors are used.
-@@ -931,7 +940,7 @@ static int stmmac_set_bfsize(int mtu, in
- }
- 
- /**
-- * stmmac_clear_descriptors: clear descriptors
-+ * stmmac_clear_descriptors - clear descriptors
-  * @priv: driver private structure
-  * Description: this function is called to clear the tx and rx descriptors
-  * in case of both basic and extended descriptors are used.
-@@ -963,18 +972,25 @@ static void stmmac_clear_descriptors(str
- 						     (i == txsize - 1));
- }
- 
-+/**
-+ * stmmac_init_rx_buffers - init the RX descriptor buffer.
-+ * @priv: driver private structure
-+ * @p: descriptor pointer
-+ * @i: descriptor index
-+ * @flags: gfp flag.
-+ * Description: this function is called to allocate a receive buffer, perform
-+ * the DMA mapping and init the descriptor.
-+ */
- static int stmmac_init_rx_buffers(struct stmmac_priv *priv, struct dma_desc *p,
- 				  int i, gfp_t flags)
- {
- 	struct sk_buff *skb;
- 
--	skb = __netdev_alloc_skb(priv->dev, priv->dma_buf_sz + NET_IP_ALIGN,
--				 flags);
-+	skb = __netdev_alloc_skb_ip_align(priv->dev, priv->dma_buf_sz, flags);
- 	if (!skb) {
- 		pr_err("%s: Rx init fails; skb is NULL\n", __func__);
- 		return -ENOMEM;
- 	}
--	skb_reserve(skb, NET_IP_ALIGN);
- 	priv->rx_skbuff[i] = skb;
- 	priv->rx_skbuff_dma[i] = dma_map_single(priv->device, skb->data,
- 						priv->dma_buf_sz,
-@@ -1007,7 +1023,8 @@ static void stmmac_free_rx_buffers(struc
- /**
-  * init_dma_desc_rings - init the RX/TX descriptor rings
-  * @dev: net device structure
-- * Description:  this function initializes the DMA RX/TX descriptors
-+ * @flags: gfp flag.
-+ * Description: this function initializes the DMA RX/TX descriptors
-  * and allocates the socket buffers. It suppors the chained and ring
-  * modes.
-  */
-@@ -1089,6 +1106,7 @@ static int init_dma_desc_rings(struct ne
- 
- 	priv->dirty_tx = 0;
- 	priv->cur_tx = 0;
-+	netdev_reset_queue(priv->dev);
- 
- 	stmmac_clear_descriptors(priv);
- 
-@@ -1144,6 +1162,14 @@ static void dma_free_tx_skbufs(struct st
- 	}
- }
- 
-+/**
-+ * alloc_dma_desc_resources - alloc TX/RX resources.
-+ * @priv: private structure
-+ * Description: according to which descriptor can be used (extend or basic)
-+ * this function allocates the resources for TX and RX paths. In case of
-+ * reception, for example, it pre-allocated the RX socket buffer in order to
-+ * allow zero-copy mechanism.
-+ */
- static int alloc_dma_desc_resources(struct stmmac_priv *priv)
- {
- 	unsigned int txsize = priv->dma_tx_size;
-@@ -1255,13 +1281,15 @@ static void free_dma_desc_resources(stru
- /**
-  *  stmmac_dma_operation_mode - HW DMA operation mode
-  *  @priv: driver private structure
-- *  Description: it sets the DMA operation mode: tx/rx DMA thresholds
-- *  or Store-And-Forward capability.
-+ *  Description: it is used for configuring the DMA operation mode register in
-+ *  order to program the tx/rx DMA thresholds or Store-And-Forward mode.
-  */
- static void stmmac_dma_operation_mode(struct stmmac_priv *priv)
- {
-+	int rxfifosz = priv->plat->rx_fifo_size;
-+
- 	if (priv->plat->force_thresh_dma_mode)
--		priv->hw->dma->dma_mode(priv->ioaddr, tc, tc);
-+		priv->hw->dma->dma_mode(priv->ioaddr, tc, tc, rxfifosz);
- 	else if (priv->plat->force_sf_dma_mode || priv->plat->tx_coe) {
- 		/*
- 		 * In case of GMAC, SF mode can be enabled
-@@ -1270,20 +1298,23 @@ static void stmmac_dma_operation_mode(st
- 		 * 2) There is no bugged Jumbo frame support
- 		 *    that needs to not insert csum in the TDES.
- 		 */
--		priv->hw->dma->dma_mode(priv->ioaddr, SF_DMA_MODE, SF_DMA_MODE);
--		tc = SF_DMA_MODE;
-+		priv->hw->dma->dma_mode(priv->ioaddr, SF_DMA_MODE, SF_DMA_MODE,
-+					rxfifosz);
-+		priv->xstats.threshold = SF_DMA_MODE;
- 	} else
--		priv->hw->dma->dma_mode(priv->ioaddr, tc, SF_DMA_MODE);
-+		priv->hw->dma->dma_mode(priv->ioaddr, tc, SF_DMA_MODE,
-+					rxfifosz);
- }
- 
- /**
-- * stmmac_tx_clean:
-+ * stmmac_tx_clean - to manage the transmission completion
-  * @priv: driver private structure
-- * Description: it reclaims resources after transmission completes.
-+ * Description: it reclaims the transmit resources after transmission completes.
-  */
- static void stmmac_tx_clean(struct stmmac_priv *priv)
- {
- 	unsigned int txsize = priv->dma_tx_size;
-+	unsigned int bytes_compl = 0, pkts_compl = 0;
- 
- 	spin_lock(&priv->tx_lock);
- 
-@@ -1340,6 +1371,8 @@ static void stmmac_tx_clean(struct stmma
- 		priv->hw->mode->clean_desc3(priv, p);
- 
- 		if (likely(skb != NULL)) {
-+			pkts_compl++;
-+			bytes_compl += skb->len;
- 			dev_consume_skb_any(skb);
- 			priv->tx_skbuff[entry] = NULL;
- 		}
-@@ -1348,6 +1381,9 @@ static void stmmac_tx_clean(struct stmma
- 
- 		priv->dirty_tx++;
- 	}
-+
-+	netdev_completed_queue(priv->dev, pkts_compl, bytes_compl);
-+
- 	if (unlikely(netif_queue_stopped(priv->dev) &&
- 		     stmmac_tx_avail(priv) > STMMAC_TX_THRESH(priv))) {
- 		netif_tx_lock(priv->dev);
-@@ -1378,10 +1414,10 @@ static inline void stmmac_disable_dma_ir
- }
- 
- /**
-- * stmmac_tx_err: irq tx error mng function
-+ * stmmac_tx_err - to manage the tx error
-  * @priv: driver private structure
-  * Description: it cleans the descriptors and restarts the transmission
-- * in case of errors.
-+ * in case of transmission errors.
-  */
- static void stmmac_tx_err(struct stmmac_priv *priv)
- {
-@@ -1402,6 +1438,7 @@ static void stmmac_tx_err(struct stmmac_
- 						     (i == txsize - 1));
- 	priv->dirty_tx = 0;
- 	priv->cur_tx = 0;
-+	netdev_reset_queue(priv->dev);
- 	priv->hw->dma->start_tx(priv->ioaddr);
- 
- 	priv->dev->stats.tx_errors++;
-@@ -1409,16 +1446,16 @@ static void stmmac_tx_err(struct stmmac_
- }
- 
- /**
-- * stmmac_dma_interrupt: DMA ISR
-+ * stmmac_dma_interrupt - DMA ISR
-  * @priv: driver private structure
-  * Description: this is the DMA ISR. It is called by the main ISR.
-- * It calls the dwmac dma routine to understand which type of interrupt
-- * happened. In case of there is a Normal interrupt and either TX or RX
-- * interrupt happened so the NAPI is scheduled.
-+ * It calls the dwmac dma routine and schedule poll method in case of some
-+ * work can be done.
-  */
- static void stmmac_dma_interrupt(struct stmmac_priv *priv)
- {
- 	int status;
-+	int rxfifosz = priv->plat->rx_fifo_size;
- 
- 	status = priv->hw->dma->dma_interrupt(priv->ioaddr, &priv->xstats);
- 	if (likely((status & handle_rx)) || (status & handle_tx)) {
-@@ -1429,9 +1466,15 @@ static void stmmac_dma_interrupt(struct
- 	}
- 	if (unlikely(status & tx_hard_error_bump_tc)) {
- 		/* Try to bump up the dma threshold on this failure */
--		if (unlikely(tc != SF_DMA_MODE) && (tc <= 256)) {
-+		if (unlikely(priv->xstats.threshold != SF_DMA_MODE) &&
-+		    (tc <= 256)) {
- 			tc += 64;
--			priv->hw->dma->dma_mode(priv->ioaddr, tc, SF_DMA_MODE);
-+			if (priv->plat->force_thresh_dma_mode)
-+				priv->hw->dma->dma_mode(priv->ioaddr, tc, tc,
-+							rxfifosz);
-+			else
-+				priv->hw->dma->dma_mode(priv->ioaddr, tc,
-+							SF_DMA_MODE, rxfifosz);
- 			priv->xstats.threshold = tc;
- 		}
- 	} else if (unlikely(status == tx_hard_error))
-@@ -1457,6 +1500,12 @@ static void stmmac_mmc_setup(struct stmm
- 		pr_info(" No MAC Management Counters available\n");
- }
- 
-+/**
-+ * stmmac_get_synopsys_id - return the SYINID.
-+ * @priv: driver private structure
-+ * Description: this simple function is to decode and return the SYINID
-+ * starting from the HW core register.
-+ */
- static u32 stmmac_get_synopsys_id(struct stmmac_priv *priv)
- {
- 	u32 hwid = priv->hw->synopsys_uid;
-@@ -1475,11 +1524,11 @@ static u32 stmmac_get_synopsys_id(struct
- }
- 
- /**
-- * stmmac_selec_desc_mode: to select among: normal/alternate/extend descriptors
-+ * stmmac_selec_desc_mode - to select among: normal/alternate/extend descriptors
-  * @priv: driver private structure
-  * Description: select the Enhanced/Alternate or Normal descriptors.
-- * In case of Enhanced/Alternate, it looks at the extended descriptors are
-- * supported by the HW cap. register.
-+ * In case of Enhanced/Alternate, it checks if the extended descriptors are
-+ * supported by the HW capability register.
-  */
- static void stmmac_selec_desc_mode(struct stmmac_priv *priv)
- {
-@@ -1501,7 +1550,7 @@ static void stmmac_selec_desc_mode(struc
- }
- 
- /**
-- * stmmac_get_hw_features: get MAC capabilities from the HW cap. register.
-+ * stmmac_get_hw_features - get MAC capabilities from the HW cap. register.
-  * @priv: driver private structure
-  * Description:
-  *  new GMAC chip generations have a new register to indicate the
-@@ -1559,7 +1608,7 @@ static int stmmac_get_hw_features(struct
- }
- 
- /**
-- * stmmac_check_ether_addr: check if the MAC addr is valid
-+ * stmmac_check_ether_addr - check if the MAC addr is valid
-  * @priv: driver private structure
-  * Description:
-  * it is to verify if the MAC address is valid, in case of failures it
-@@ -1578,7 +1627,7 @@ static void stmmac_check_ether_addr(stru
- }
- 
- /**
-- * stmmac_init_dma_engine: DMA init.
-+ * stmmac_init_dma_engine - DMA init.
-  * @priv: driver private structure
-  * Description:
-  * It inits the DMA invoking the specific MAC/GMAC callback.
-@@ -1607,7 +1656,7 @@ static int stmmac_init_dma_engine(struct
- }
- 
- /**
-- * stmmac_tx_timer: mitigation sw timer for tx.
-+ * stmmac_tx_timer - mitigation sw timer for tx.
-  * @data: data pointer
-  * Description:
-  * This is the timer handler to directly invoke the stmmac_tx_clean.
-@@ -1620,7 +1669,7 @@ static void stmmac_tx_timer(unsigned lon
- }
- 
- /**
-- * stmmac_init_tx_coalesce: init tx mitigation options.
-+ * stmmac_init_tx_coalesce - init tx mitigation options.
-  * @priv: driver private structure
-  * Description:
-  * This inits the transmit coalesce parameters: i.e. timer rate,
-@@ -1639,15 +1688,18 @@ static void stmmac_init_tx_coalesce(stru
- }
- 
- /**
-- * stmmac_hw_setup: setup mac in a usable state.
-+ * stmmac_hw_setup - setup mac in a usable state.
-  *  @dev : pointer to the device structure.
-  *  Description:
-- *  This function sets up the ip in a usable state.
-+ *  this is the main function to setup the HW in a usable state because the
-+ *  dma engine is reset, the core registers are configured (e.g. AXI,
-+ *  Checksum features, timers). The DMA is ready to start receiving and
-+ *  transmitting.
-  *  Return value:
-  *  0 on success and an appropriate (-)ve integer as defined in errno.h
-  *  file on failure.
-  */
--static int stmmac_hw_setup(struct net_device *dev)
-+static int stmmac_hw_setup(struct net_device *dev, bool init_ptp)
- {
- 	struct stmmac_priv *priv = netdev_priv(dev);
- 	int ret;
-@@ -1684,11 +1736,13 @@ static int stmmac_hw_setup(struct net_de
- 
- 	stmmac_mmc_setup(priv);
- 
--	ret = stmmac_init_ptp(priv);
--	if (ret && ret != -EOPNOTSUPP)
--		pr_warn("%s: failed PTP initialisation\n", __func__);
-+	if (init_ptp) {
-+		ret = stmmac_init_ptp(priv);
-+		if (ret && ret != -EOPNOTSUPP)
-+			pr_warn("%s: failed PTP initialisation\n", __func__);
-+	}
- 
--#ifdef CONFIG_STMMAC_DEBUG_FS
-+#ifdef CONFIG_DEBUG_FS
- 	ret = stmmac_init_fs(dev);
- 	if (ret < 0)
- 		pr_warn("%s: failed debugFS registration\n", __func__);
-@@ -1763,7 +1817,7 @@ static int stmmac_open(struct net_device
- 		goto init_error;
- 	}
- 
--	ret = stmmac_hw_setup(dev);
-+	ret = stmmac_hw_setup(dev, true);
- 	if (ret < 0) {
- 		pr_err("%s: Hw setup failed\n", __func__);
- 		goto init_error;
-@@ -1870,8 +1924,8 @@ static int stmmac_release(struct net_dev
- 
- 	netif_carrier_off(dev);
- 
--#ifdef CONFIG_STMMAC_DEBUG_FS
--	stmmac_exit_fs();
-+#ifdef CONFIG_DEBUG_FS
-+	stmmac_exit_fs(dev);
- #endif
- 
- 	stmmac_release_ptp(priv);
-@@ -1880,7 +1934,7 @@ static int stmmac_release(struct net_dev
- }
- 
- /**
-- *  stmmac_xmit: Tx entry point of the driver
-+ *  stmmac_xmit - Tx entry point of the driver
-  *  @skb : the socket buffer
-  *  @dev : device pointer
-  *  Description : this is the tx entry point of the driver.
-@@ -2024,6 +2078,7 @@ static netdev_tx_t stmmac_xmit(struct sk
- 	if (!priv->hwts_tx_en)
- 		skb_tx_timestamp(skb);
- 
-+	netdev_sent_queue(dev, skb->len);
- 	priv->hw->dma->enable_dma_transmission(priv->ioaddr);
- 
- 	spin_unlock(&priv->tx_lock);
-@@ -2055,7 +2110,7 @@ static void stmmac_rx_vlan(struct net_de
- 
- 
- /**
-- * stmmac_rx_refill: refill used skb preallocated buffers
-+ * stmmac_rx_refill - refill used skb preallocated buffers
-  * @priv: driver private structure
-  * Description : this is to reallocate the skb for the reception process
-  * that is based on zero-copy.
-@@ -2106,7 +2161,7 @@ static inline void stmmac_rx_refill(stru
- }
- 
- /**
-- * stmmac_rx_refill: refill used skb preallocated buffers
-+ * stmmac_rx - manage the receive process
-  * @priv: driver private structure
-  * @limit: napi bugget.
-  * Description :  this the function called by the napi poll method.
-@@ -2375,8 +2430,11 @@ static int stmmac_set_features(struct ne
-  *  @irq: interrupt number.
-  *  @dev_id: to pass the net device pointer.
-  *  Description: this is the main driver interrupt service routine.
-- *  It calls the DMA ISR and also the core ISR to manage PMT, MMC, LPI
-- *  interrupts.
-+ *  It can call:
-+ *  o DMA service routine (to manage incoming frame reception and transmission
-+ *    status)
-+ *  o Core interrupts to manage: remote wake-up, management counter, LPI
-+ *    interrupts.
-  */
- static irqreturn_t stmmac_interrupt(int irq, void *dev_id)
- {
-@@ -2457,10 +2515,8 @@ static int stmmac_ioctl(struct net_devic
- 	return ret;
- }
- 
--#ifdef CONFIG_STMMAC_DEBUG_FS
-+#ifdef CONFIG_DEBUG_FS
- static struct dentry *stmmac_fs_dir;
--static struct dentry *stmmac_rings_status;
--static struct dentry *stmmac_dma_cap;
- 
- static void sysfs_display_ring(void *head, int size, int extend_desc,
- 			       struct seq_file *seq)
-@@ -2599,36 +2655,39 @@ static const struct file_operations stmm
- 
- static int stmmac_init_fs(struct net_device *dev)
- {
--	/* Create debugfs entries */
--	stmmac_fs_dir = debugfs_create_dir(STMMAC_RESOURCE_NAME, NULL);
-+	struct stmmac_priv *priv = netdev_priv(dev);
- 
--	if (!stmmac_fs_dir || IS_ERR(stmmac_fs_dir)) {
--		pr_err("ERROR %s, debugfs create directory failed\n",
--		       STMMAC_RESOURCE_NAME);
-+	/* Create per netdev entries */
-+	priv->dbgfs_dir = debugfs_create_dir(dev->name, stmmac_fs_dir);
-+
-+	if (!priv->dbgfs_dir || IS_ERR(priv->dbgfs_dir)) {
-+		pr_err("ERROR %s/%s, debugfs create directory failed\n",
-+		       STMMAC_RESOURCE_NAME, dev->name);
- 
- 		return -ENOMEM;
- 	}
- 
- 	/* Entry to report DMA RX/TX rings */
--	stmmac_rings_status = debugfs_create_file("descriptors_status",
--						  S_IRUGO, stmmac_fs_dir, dev,
--						  &stmmac_rings_status_fops);
-+	priv->dbgfs_rings_status =
-+		debugfs_create_file("descriptors_status", S_IRUGO,
-+				    priv->dbgfs_dir, dev,
-+				    &stmmac_rings_status_fops);
- 
--	if (!stmmac_rings_status || IS_ERR(stmmac_rings_status)) {
-+	if (!priv->dbgfs_rings_status || IS_ERR(priv->dbgfs_rings_status)) {
- 		pr_info("ERROR creating stmmac ring debugfs file\n");
--		debugfs_remove(stmmac_fs_dir);
-+		debugfs_remove_recursive(priv->dbgfs_dir);
- 
- 		return -ENOMEM;
- 	}
- 
- 	/* Entry to report the DMA HW features */
--	stmmac_dma_cap = debugfs_create_file("dma_cap", S_IRUGO, stmmac_fs_dir,
--					     dev, &stmmac_dma_cap_fops);
-+	priv->dbgfs_dma_cap = debugfs_create_file("dma_cap", S_IRUGO,
-+					    priv->dbgfs_dir,
-+					    dev, &stmmac_dma_cap_fops);
- 
--	if (!stmmac_dma_cap || IS_ERR(stmmac_dma_cap)) {
-+	if (!priv->dbgfs_dma_cap || IS_ERR(priv->dbgfs_dma_cap)) {
- 		pr_info("ERROR creating stmmac MMC debugfs file\n");
--		debugfs_remove(stmmac_rings_status);
--		debugfs_remove(stmmac_fs_dir);
-+		debugfs_remove_recursive(priv->dbgfs_dir);
- 
- 		return -ENOMEM;
- 	}
-@@ -2636,13 +2695,13 @@ static int stmmac_init_fs(struct net_dev
- 	return 0;
- }
- 
--static void stmmac_exit_fs(void)
-+static void stmmac_exit_fs(struct net_device *dev)
- {
--	debugfs_remove(stmmac_rings_status);
--	debugfs_remove(stmmac_dma_cap);
--	debugfs_remove(stmmac_fs_dir);
-+	struct stmmac_priv *priv = netdev_priv(dev);
-+
-+	debugfs_remove_recursive(priv->dbgfs_dir);
- }
--#endif /* CONFIG_STMMAC_DEBUG_FS */
-+#endif /* CONFIG_DEBUG_FS */
- 
- static const struct net_device_ops stmmac_netdev_ops = {
- 	.ndo_open = stmmac_open,
-@@ -2663,11 +2722,10 @@ static const struct net_device_ops stmma
- /**
-  *  stmmac_hw_init - Init the MAC device
-  *  @priv: driver private structure
-- *  Description: this function detects which MAC device
-- *  (GMAC/MAC10-100) has to attached, checks the HW capability
-- *  (if supported) and sets the driver's features (for example
-- *  to use the ring or chaine mode or support the normal/enh
-- *  descriptor structure).
-+ *  Description: this function is to configure the MAC device according to
-+ *  some platform parameters or the HW capability register. It prepares the
-+ *  driver to use either ring or chain modes and to setup either enhanced or
-+ *  normal descriptors.
-  */
- static int stmmac_hw_init(struct stmmac_priv *priv)
- {
-@@ -2714,7 +2772,11 @@ static int stmmac_hw_init(struct stmmac_
- 		priv->plat->enh_desc = priv->dma_cap.enh_desc;
- 		priv->plat->pmt = priv->dma_cap.pmt_remote_wake_up;
- 
--		priv->plat->tx_coe = priv->dma_cap.tx_coe;
-+		/* TXCOE doesn't work in thresh DMA mode */
-+		if (priv->plat->force_thresh_dma_mode)
-+			priv->plat->tx_coe = 0;
-+		else
-+			priv->plat->tx_coe = priv->dma_cap.tx_coe;
- 
- 		if (priv->dma_cap.rx_coe_type2)
- 			priv->plat->rx_coe = STMMAC_RX_COE_TYPE2;
-@@ -2747,13 +2809,15 @@ static int stmmac_hw_init(struct stmmac_
-  * stmmac_dvr_probe
-  * @device: device pointer
-  * @plat_dat: platform data pointer
-- * @addr: iobase memory address
-+ * @res: stmmac resource pointer
-  * Description: this is the main probe function used to
-  * call the alloc_etherdev, allocate the priv structure.
-+ * Return:
-+ * returns 0 on success, otherwise errno.
-  */
--struct stmmac_priv *stmmac_dvr_probe(struct device *device,
--				     struct plat_stmmacenet_data *plat_dat,
--				     void __iomem *addr)
-+int stmmac_dvr_probe(struct device *device,
-+		     struct plat_stmmacenet_data *plat_dat,
-+		     struct stmmac_resources *res)
- {
- 	int ret = 0;
- 	struct net_device *ndev = NULL;
-@@ -2761,7 +2825,7 @@ struct stmmac_priv *stmmac_dvr_probe(str
- 
- 	ndev = alloc_etherdev(sizeof(struct stmmac_priv));
- 	if (!ndev)
--		return NULL;
-+		return -ENOMEM;
- 
- 	SET_NETDEV_DEV(ndev, device);
- 
-@@ -2772,8 +2836,17 @@ struct stmmac_priv *stmmac_dvr_probe(str
- 	stmmac_set_ethtool_ops(ndev);
- 	priv->pause = pause;
- 	priv->plat = plat_dat;
--	priv->ioaddr = addr;
--	priv->dev->base_addr = (unsigned long)addr;
-+	priv->ioaddr = res->addr;
-+	priv->dev->base_addr = (unsigned long)res->addr;
-+
-+	priv->dev->irq = res->irq;
-+	priv->wol_irq = res->wol_irq;
-+	priv->lpi_irq = res->lpi_irq;
-+
-+	if (res->mac)
-+		memcpy(priv->dev->dev_addr, res->mac, ETH_ALEN);
-+
-+	dev_set_drvdata(device, priv->dev);
- 
- 	/* Verify driver arguments */
- 	stmmac_verify_args();
-@@ -2800,6 +2873,16 @@ struct stmmac_priv *stmmac_dvr_probe(str
- 	}
- 	clk_prepare_enable(priv->stmmac_clk);
- 
-+	priv->pclk = devm_clk_get(priv->device, "pclk");
-+	if (IS_ERR(priv->pclk)) {
-+		if (PTR_ERR(priv->pclk) == -EPROBE_DEFER) {
-+			ret = -EPROBE_DEFER;
-+			goto error_pclk_get;
-+		}
-+		priv->pclk = NULL;
-+	}
-+	clk_prepare_enable(priv->pclk);
-+
- 	priv->stmmac_rst = devm_reset_control_get(priv->device,
- 						  STMMAC_RESOURCE_NAME);
- 	if (IS_ERR(priv->stmmac_rst)) {
-@@ -2878,19 +2961,22 @@ struct stmmac_priv *stmmac_dvr_probe(str
- 		}
- 	}
- 
--	return priv;
-+	return 0;
- 
- error_mdio_register:
- 	unregister_netdev(ndev);
- error_netdev_register:
- 	netif_napi_del(&priv->napi);
- error_hw_init:
-+	clk_disable_unprepare(priv->pclk);
-+error_pclk_get:
- 	clk_disable_unprepare(priv->stmmac_clk);
- error_clk_get:
- 	free_netdev(ndev);
- 
--	return ERR_PTR(ret);
-+	return ret;
- }
-+EXPORT_SYMBOL_GPL(stmmac_dvr_probe);
- 
- /**
-  * stmmac_dvr_remove
-@@ -2908,20 +2994,28 @@ int stmmac_dvr_remove(struct net_device
- 	priv->hw->dma->stop_tx(priv->ioaddr);
- 
- 	stmmac_set_mac(priv->ioaddr, false);
--	if (priv->pcs != STMMAC_PCS_RGMII && priv->pcs != STMMAC_PCS_TBI &&
--	    priv->pcs != STMMAC_PCS_RTBI)
--		stmmac_mdio_unregister(ndev);
- 	netif_carrier_off(ndev);
- 	unregister_netdev(ndev);
- 	if (priv->stmmac_rst)
- 		reset_control_assert(priv->stmmac_rst);
-+	clk_disable_unprepare(priv->pclk);
- 	clk_disable_unprepare(priv->stmmac_clk);
-+	if (priv->pcs != STMMAC_PCS_RGMII && priv->pcs != STMMAC_PCS_TBI &&
-+	    priv->pcs != STMMAC_PCS_RTBI)
-+		stmmac_mdio_unregister(ndev);
- 	free_netdev(ndev);
- 
- 	return 0;
- }
-+EXPORT_SYMBOL_GPL(stmmac_dvr_remove);
- 
--#ifdef CONFIG_PM
-+/**
-+ * stmmac_suspend - suspend callback
-+ * @ndev: net device pointer
-+ * Description: this is the function to suspend the device and it is called
-+ * by the platform driver to stop the network queue, release the resources,
-+ * program the PMT register (for WoL), clean and release driver resources.
-+ */
- int stmmac_suspend(struct net_device *ndev)
- {
- 	struct stmmac_priv *priv = netdev_priv(ndev);
-@@ -2954,6 +3048,7 @@ int stmmac_suspend(struct net_device *nd
- 		stmmac_set_mac(priv->ioaddr, false);
- 		pinctrl_pm_select_sleep_state(priv->device);
- 		/* Disable clock in case of PWM is off */
-+		clk_disable(priv->pclk);
- 		clk_disable(priv->stmmac_clk);
- 	}
- 	spin_unlock_irqrestore(&priv->lock, flags);
-@@ -2963,7 +3058,14 @@ int stmmac_suspend(struct net_device *nd
- 	priv->oldduplex = -1;
- 	return 0;
- }
-+EXPORT_SYMBOL_GPL(stmmac_suspend);
- 
-+/**
-+ * stmmac_resume - resume callback
-+ * @ndev: net device pointer
-+ * Description: when resume this function is invoked to setup the DMA and CORE
-+ * in a usable state.
-+ */
- int stmmac_resume(struct net_device *ndev)
- {
- 	struct stmmac_priv *priv = netdev_priv(ndev);
-@@ -2987,6 +3089,7 @@ int stmmac_resume(struct net_device *nde
- 		pinctrl_pm_select_default_state(priv->device);
- 		/* enable the clk prevously disabled */
- 		clk_enable(priv->stmmac_clk);
-+		clk_enable(priv->pclk);
- 		/* reset the phy so that it's ready */
- 		if (priv->mii)
- 			stmmac_mdio_reset(priv->mii);
-@@ -2995,7 +3098,7 @@ int stmmac_resume(struct net_device *nde
- 	netif_device_attach(ndev);
- 
- 	init_dma_desc_rings(ndev, GFP_ATOMIC);
--	stmmac_hw_setup(ndev);
-+	stmmac_hw_setup(ndev, false);
- 	stmmac_init_tx_coalesce(priv);
- 
- 	napi_enable(&priv->napi);
-@@ -3009,37 +3112,7 @@ int stmmac_resume(struct net_device *nde
- 
- 	return 0;
- }
--#endif /* CONFIG_PM */
--
--/* Driver can be configured w/ and w/ both PCI and Platf drivers
-- * depending on the configuration selected.
-- */
--static int __init stmmac_init(void)
--{
--	int ret;
--
--	ret = stmmac_register_platform();
--	if (ret)
--		goto err;
--	ret = stmmac_register_pci();
--	if (ret)
--		goto err_pci;
--	return 0;
--err_pci:
--	stmmac_unregister_platform();
--err:
--	pr_err("stmmac: driver registration failed\n");
--	return ret;
--}
--
--static void __exit stmmac_exit(void)
--{
--	stmmac_unregister_platform();
--	stmmac_unregister_pci();
--}
--
--module_init(stmmac_init);
--module_exit(stmmac_exit);
-+EXPORT_SYMBOL_GPL(stmmac_resume);
- 
- #ifndef MODULE
- static int __init stmmac_cmdline_opt(char *str)
-@@ -3094,6 +3167,35 @@ err:
- __setup("stmmaceth=", stmmac_cmdline_opt);
- #endif /* MODULE */
- 
-+static int __init stmmac_init(void)
-+{
-+#ifdef CONFIG_DEBUG_FS
-+	/* Create debugfs main directory if it doesn't exist yet */
-+	if (!stmmac_fs_dir) {
-+		stmmac_fs_dir = debugfs_create_dir(STMMAC_RESOURCE_NAME, NULL);
-+
-+		if (!stmmac_fs_dir || IS_ERR(stmmac_fs_dir)) {
-+			pr_err("ERROR %s, debugfs create directory failed\n",
-+			       STMMAC_RESOURCE_NAME);
-+
-+			return -ENOMEM;
-+		}
-+	}
-+#endif
-+
-+	return 0;
-+}
-+
-+static void __exit stmmac_exit(void)
-+{
-+#ifdef CONFIG_DEBUG_FS
-+	debugfs_remove_recursive(stmmac_fs_dir);
-+#endif
-+}
-+
-+module_init(stmmac_init)
-+module_exit(stmmac_exit)
-+
- MODULE_DESCRIPTION("STMMAC 10/100/1000 Ethernet device driver");
- MODULE_AUTHOR("Giuseppe Cavallaro <peppe.cavallaro@st.com>");
- MODULE_LICENSE("GPL");
---- a/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c
-+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c
-@@ -161,11 +161,16 @@ int stmmac_mdio_reset(struct mii_bus *bu
- 
- 		if (!gpio_request(reset_gpio, "mdio-reset")) {
- 			gpio_direction_output(reset_gpio, active_low ? 1 : 0);
--			udelay(data->delays[0]);
-+			if (data->delays[0])
-+				msleep(DIV_ROUND_UP(data->delays[0], 1000));
-+
- 			gpio_set_value(reset_gpio, active_low ? 0 : 1);
--			udelay(data->delays[1]);
-+			if (data->delays[1])
-+				msleep(DIV_ROUND_UP(data->delays[1], 1000));
-+
- 			gpio_set_value(reset_gpio, active_low ? 1 : 0);
--			udelay(data->delays[2]);
-+			if (data->delays[2])
-+				msleep(DIV_ROUND_UP(data->delays[2], 1000));
- 		}
- 	}
- #endif
---- a/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c
-+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c
-@@ -24,38 +24,128 @@
- *******************************************************************************/
- 
- #include <linux/pci.h>
-+#include <linux/dmi.h>
-+
- #include "stmmac.h"
- 
--static struct plat_stmmacenet_data plat_dat;
--static struct stmmac_mdio_bus_data mdio_data;
--static struct stmmac_dma_cfg dma_cfg;
--
--static void stmmac_default_data(void)
--{
--	memset(&plat_dat, 0, sizeof(struct plat_stmmacenet_data));
--
--	plat_dat.bus_id = 1;
--	plat_dat.phy_addr = 0;
--	plat_dat.interface = PHY_INTERFACE_MODE_GMII;
--	plat_dat.clk_csr = 2;	/* clk_csr_i = 20-35MHz & MDC = clk_csr_i/16 */
--	plat_dat.has_gmac = 1;
--	plat_dat.force_sf_dma_mode = 1;
--
--	mdio_data.phy_reset = NULL;
--	mdio_data.phy_mask = 0;
--	plat_dat.mdio_bus_data = &mdio_data;
--
--	dma_cfg.pbl = 32;
--	dma_cfg.burst_len = DMA_AXI_BLEN_256;
--	plat_dat.dma_cfg = &dma_cfg;
-+/*
-+ * This struct is used to associate PCI Function of MAC controller on a board,
-+ * discovered via DMI, with the address of PHY connected to the MAC. The
-+ * negative value of the address means that MAC controller is not connected
-+ * with PHY.
-+ */
-+struct stmmac_pci_dmi_data {
-+	const char *name;
-+	unsigned int func;
-+	int phy_addr;
-+};
-+
-+struct stmmac_pci_info {
-+	struct pci_dev *pdev;
-+	int (*setup)(struct plat_stmmacenet_data *plat,
-+		     struct stmmac_pci_info *info);
-+	struct stmmac_pci_dmi_data *dmi;
-+};
-+
-+static int stmmac_pci_find_phy_addr(struct stmmac_pci_info *info)
-+{
-+	const char *name = dmi_get_system_info(DMI_BOARD_NAME);
-+	unsigned int func = PCI_FUNC(info->pdev->devfn);
-+	struct stmmac_pci_dmi_data *dmi;
-+
-+	/*
-+	 * Galileo boards with old firmware don't support DMI. We always return
-+	 * 1 here, so at least first found MAC controller would be probed.
-+	 */
-+	if (!name)
-+		return 1;
-+
-+	for (dmi = info->dmi; dmi->name && *dmi->name; dmi++) {
-+		if (!strcmp(dmi->name, name) && dmi->func == func)
-+			return dmi->phy_addr;
-+	}
-+
-+	return -ENODEV;
-+}
-+
-+static void stmmac_default_data(struct plat_stmmacenet_data *plat)
-+{
-+	plat->bus_id = 1;
-+	plat->phy_addr = 0;
-+	plat->interface = PHY_INTERFACE_MODE_GMII;
-+	plat->clk_csr = 2;	/* clk_csr_i = 20-35MHz & MDC = clk_csr_i/16 */
-+	plat->has_gmac = 1;
-+	plat->force_sf_dma_mode = 1;
-+
-+	plat->mdio_bus_data->phy_reset = NULL;
-+	plat->mdio_bus_data->phy_mask = 0;
-+
-+	plat->dma_cfg->pbl = 32;
-+	plat->dma_cfg->burst_len = DMA_AXI_BLEN_256;
-+
-+	/* Set default value for multicast hash bins */
-+	plat->multicast_filter_bins = HASH_TABLE_SIZE;
-+
-+	/* Set default value for unicast filter entries */
-+	plat->unicast_filter_entries = 1;
-+}
-+
-+static int quark_default_data(struct plat_stmmacenet_data *plat,
-+			      struct stmmac_pci_info *info)
-+{
-+	struct pci_dev *pdev = info->pdev;
-+	int ret;
-+
-+	/*
-+	 * Refuse to load the driver and register net device if MAC controller
-+	 * does not connect to any PHY interface.
-+	 */
-+	ret = stmmac_pci_find_phy_addr(info);
-+	if (ret < 0)
-+		return ret;
-+
-+	plat->bus_id = PCI_DEVID(pdev->bus->number, pdev->devfn);
-+	plat->phy_addr = ret;
-+	plat->interface = PHY_INTERFACE_MODE_RMII;
-+	plat->clk_csr = 2;
-+	plat->has_gmac = 1;
-+	plat->force_sf_dma_mode = 1;
-+
-+	plat->mdio_bus_data->phy_reset = NULL;
-+	plat->mdio_bus_data->phy_mask = 0;
-+
-+	plat->dma_cfg->pbl = 16;
-+	plat->dma_cfg->burst_len = DMA_AXI_BLEN_256;
-+	plat->dma_cfg->fixed_burst = 1;
- 
- 	/* Set default value for multicast hash bins */
--	plat_dat.multicast_filter_bins = HASH_TABLE_SIZE;
-+	plat->multicast_filter_bins = HASH_TABLE_SIZE;
- 
- 	/* Set default value for unicast filter entries */
--	plat_dat.unicast_filter_entries = 1;
-+	plat->unicast_filter_entries = 1;
-+
-+	return 0;
- }
- 
-+static struct stmmac_pci_dmi_data quark_pci_dmi_data[] = {
-+	{
-+		.name = "Galileo",
-+		.func = 6,
-+		.phy_addr = 1,
-+	},
-+	{
-+		.name = "GalileoGen2",
-+		.func = 6,
-+		.phy_addr = 1,
-+	},
-+	{}
-+};
-+
-+static struct stmmac_pci_info quark_pci_info = {
-+	.setup = quark_default_data,
-+	.dmi = quark_pci_dmi_data,
-+};
-+
- /**
-  * stmmac_pci_probe
-  *
-@@ -71,64 +161,65 @@ static void stmmac_default_data(void)
- static int stmmac_pci_probe(struct pci_dev *pdev,
- 			    const struct pci_device_id *id)
- {
--	int ret = 0;
--	void __iomem *addr = NULL;
--	struct stmmac_priv *priv = NULL;
-+	struct stmmac_pci_info *info = (struct stmmac_pci_info *)id->driver_data;
-+	struct plat_stmmacenet_data *plat;
-+	struct stmmac_resources res;
- 	int i;
-+	int ret;
-+
-+	plat = devm_kzalloc(&pdev->dev, sizeof(*plat), GFP_KERNEL);
-+	if (!plat)
-+		return -ENOMEM;
-+
-+	plat->mdio_bus_data = devm_kzalloc(&pdev->dev,
-+					   sizeof(*plat->mdio_bus_data),
-+					   GFP_KERNEL);
-+	if (!plat->mdio_bus_data)
-+		return -ENOMEM;
-+
-+	plat->dma_cfg = devm_kzalloc(&pdev->dev, sizeof(*plat->dma_cfg),
-+				     GFP_KERNEL);
-+	if (!plat->dma_cfg)
-+		return -ENOMEM;
- 
- 	/* Enable pci device */
--	ret = pci_enable_device(pdev);
-+	ret = pcim_enable_device(pdev);
- 	if (ret) {
--		pr_err("%s : ERROR: failed to enable %s device\n", __func__,
--		       pci_name(pdev));
-+		dev_err(&pdev->dev, "%s: ERROR: failed to enable device\n",
-+			__func__);
- 		return ret;
- 	}
--	if (pci_request_regions(pdev, STMMAC_RESOURCE_NAME)) {
--		pr_err("%s: ERROR: failed to get PCI region\n", __func__);
--		ret = -ENODEV;
--		goto err_out_req_reg_failed;
--	}
- 
- 	/* Get the base address of device */
--	for (i = 0; i <= 5; i++) {
-+	for (i = 0; i <= PCI_STD_RESOURCE_END; i++) {
- 		if (pci_resource_len(pdev, i) == 0)
- 			continue;
--		addr = pci_iomap(pdev, i, 0);
--		if (addr == NULL) {
--			pr_err("%s: ERROR: cannot map register memory aborting",
--			       __func__);
--			ret = -EIO;
--			goto err_out_map_failed;
--		}
-+		ret = pcim_iomap_regions(pdev, BIT(i), pci_name(pdev));
-+		if (ret)
-+			return ret;
- 		break;
- 	}
--	pci_set_master(pdev);
--
--	stmmac_default_data();
- 
--	priv = stmmac_dvr_probe(&(pdev->dev), &plat_dat, addr);
--	if (IS_ERR(priv)) {
--		pr_err("%s: main driver probe failed", __func__);
--		ret = PTR_ERR(priv);
--		goto err_out;
--	}
--	priv->dev->irq = pdev->irq;
--	priv->wol_irq = pdev->irq;
--
--	pci_set_drvdata(pdev, priv->dev);
-+	pci_set_master(pdev);
- 
--	pr_debug("STMMAC platform driver registration completed");
-+	if (info) {
-+		info->pdev = pdev;
-+		if (info->setup) {
-+			ret = info->setup(plat, info);
-+			if (ret)
-+				return ret;
-+		}
-+	} else
-+		stmmac_default_data(plat);
- 
--	return 0;
-+	pci_enable_msi(pdev);
- 
--err_out:
--	pci_clear_master(pdev);
--err_out_map_failed:
--	pci_release_regions(pdev);
--err_out_req_reg_failed:
--	pci_disable_device(pdev);
-+	memset(&res, 0, sizeof(res));
-+	res.addr = pcim_iomap_table(pdev)[i];
-+	res.wol_irq = pdev->irq;
-+	res.irq = pdev->irq;
- 
--	return ret;
-+	return stmmac_dvr_probe(&pdev->dev, plat, &res);
- }
- 
- /**
-@@ -141,61 +232,55 @@ err_out_req_reg_failed:
- static void stmmac_pci_remove(struct pci_dev *pdev)
- {
- 	struct net_device *ndev = pci_get_drvdata(pdev);
--	struct stmmac_priv *priv = netdev_priv(ndev);
- 
- 	stmmac_dvr_remove(ndev);
--
--	pci_iounmap(pdev, priv->ioaddr);
--	pci_release_regions(pdev);
--	pci_disable_device(pdev);
- }
- 
--#ifdef CONFIG_PM
--static int stmmac_pci_suspend(struct pci_dev *pdev, pm_message_t state)
-+#ifdef CONFIG_PM_SLEEP
-+static int stmmac_pci_suspend(struct device *dev)
- {
-+	struct pci_dev *pdev = to_pci_dev(dev);
- 	struct net_device *ndev = pci_get_drvdata(pdev);
--	int ret;
--
--	ret = stmmac_suspend(ndev);
--	pci_save_state(pdev);
--	pci_set_power_state(pdev, pci_choose_state(pdev, state));
- 
--	return ret;
-+	return stmmac_suspend(ndev);
- }
- 
--static int stmmac_pci_resume(struct pci_dev *pdev)
-+static int stmmac_pci_resume(struct device *dev)
- {
-+	struct pci_dev *pdev = to_pci_dev(dev);
- 	struct net_device *ndev = pci_get_drvdata(pdev);
- 
--	pci_set_power_state(pdev, PCI_D0);
--	pci_restore_state(pdev);
--
- 	return stmmac_resume(ndev);
- }
- #endif
- 
-+static SIMPLE_DEV_PM_OPS(stmmac_pm_ops, stmmac_pci_suspend, stmmac_pci_resume);
-+
- #define STMMAC_VENDOR_ID 0x700
-+#define STMMAC_QUARK_ID  0x0937
- #define STMMAC_DEVICE_ID 0x1108
- 
- static const struct pci_device_id stmmac_id_table[] = {
- 	{PCI_DEVICE(STMMAC_VENDOR_ID, STMMAC_DEVICE_ID)},
- 	{PCI_DEVICE(PCI_VENDOR_ID_STMICRO, PCI_DEVICE_ID_STMICRO_MAC)},
-+	{PCI_VDEVICE(INTEL, STMMAC_QUARK_ID), (kernel_ulong_t)&quark_pci_info},
- 	{}
- };
- 
- MODULE_DEVICE_TABLE(pci, stmmac_id_table);
- 
--struct pci_driver stmmac_pci_driver = {
-+static struct pci_driver stmmac_pci_driver = {
- 	.name = STMMAC_RESOURCE_NAME,
- 	.id_table = stmmac_id_table,
- 	.probe = stmmac_pci_probe,
- 	.remove = stmmac_pci_remove,
--#ifdef CONFIG_PM
--	.suspend = stmmac_pci_suspend,
--	.resume = stmmac_pci_resume,
--#endif
-+	.driver         = {
-+		.pm     = &stmmac_pm_ops,
-+	},
- };
- 
-+module_pci_driver(stmmac_pci_driver);
-+
- MODULE_DESCRIPTION("STMMAC 10/100/1000 Ethernet PCI driver");
- MODULE_AUTHOR("Rayagond Kokatanur <rayagond.kokatanur@vayavyalabs.com>");
- MODULE_AUTHOR("Giuseppe Cavallaro <peppe.cavallaro@st.com>");
---- a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
-+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
-@@ -23,41 +23,23 @@
- *******************************************************************************/
- 
- #include <linux/platform_device.h>
-+#include <linux/module.h>
- #include <linux/io.h>
- #include <linux/of.h>
- #include <linux/of_net.h>
- #include <linux/of_device.h>
--#include "stmmac.h"
-+#include <linux/of_mdio.h>
- 
--static const struct of_device_id stmmac_dt_ids[] = {
--#ifdef CONFIG_DWMAC_MESON
--	{ .compatible = "amlogic,meson6-dwmac", .data = &meson6_dwmac_data},
--#endif
--#ifdef CONFIG_DWMAC_SUNXI
--	{ .compatible = "allwinner,sun7i-a20-gmac", .data = &sun7i_gmac_data},
--#endif
--#ifdef CONFIG_DWMAC_STI
--	{ .compatible = "st,stih415-dwmac", .data = &stih4xx_dwmac_data},
--	{ .compatible = "st,stih416-dwmac", .data = &stih4xx_dwmac_data},
--	{ .compatible = "st,stid127-dwmac", .data = &stid127_dwmac_data},
--	{ .compatible = "st,stih407-dwmac", .data = &stih4xx_dwmac_data},
--#endif
--#ifdef CONFIG_DWMAC_SOCFPGA
--	{ .compatible = "altr,socfpga-stmmac", .data = &socfpga_gmac_data },
--#endif
--	/* SoC specific glue layers should come before generic bindings */
--	{ .compatible = "st,spear600-gmac"},
--	{ .compatible = "snps,dwmac-3.610"},
--	{ .compatible = "snps,dwmac-3.70a"},
--	{ .compatible = "snps,dwmac-3.710"},
--	{ .compatible = "snps,dwmac"},
--	{ /* sentinel */ }
--};
--MODULE_DEVICE_TABLE(of, stmmac_dt_ids);
-+#include "stmmac.h"
-+#include "stmmac_platform.h"
- 
- #ifdef CONFIG_OF
- 
--/* This function validates the number of Multicast filtering bins specified
-+/**
-+ * dwmac1000_validate_mcast_bins - validates the number of Multicast filter bins
-+ * @mcast_bins: Multicast filtering bins
-+ * Description:
-+ * this function validates the number of Multicast filtering bins specified
-  * by the configuration through the device tree. The Synopsys GMAC supports
-  * 64 bins, 128 bins, or 256 bins. "bins" refer to the division of CRC
-  * number space. 64 bins correspond to 6 bits of the CRC, 128 corresponds
-@@ -83,7 +65,11 @@ static int dwmac1000_validate_mcast_bins
- 	return x;
- }
- 
--/* This function validates the number of Unicast address entries supported
-+/**
-+ * dwmac1000_validate_ucast_entries - validate the Unicast address entries
-+ * @ucast_entries: number of Unicast address entries
-+ * Description:
-+ * This function validates the number of Unicast address entries supported
-  * by a particular Synopsys 10/100/1000 controller. The Synopsys controller
-  * supports 1, 32, 64, or 128 Unicast filter entries for it's Unicast filter
-  * logic. This function validates a valid, supported configuration is
-@@ -109,37 +95,25 @@ static int dwmac1000_validate_ucast_entr
- 	return x;
- }
- 
--static int stmmac_probe_config_dt(struct platform_device *pdev,
--				  struct plat_stmmacenet_data *plat,
--				  const char **mac)
-+/**
-+ * stmmac_probe_config_dt - parse device-tree driver parameters
-+ * @pdev: platform_device structure
-+ * @plat: driver data platform structure
-+ * @mac: MAC address to use
-+ * Description:
-+ * this function is to read the driver parameters from device-tree and
-+ * set some private fields that will be used by the main at runtime.
-+ */
-+struct plat_stmmacenet_data *
-+stmmac_probe_config_dt(struct platform_device *pdev, const char **mac)
- {
- 	struct device_node *np = pdev->dev.of_node;
-+	struct plat_stmmacenet_data *plat;
- 	struct stmmac_dma_cfg *dma_cfg;
--	const struct of_device_id *device;
- 
--	if (!np)
--		return -ENODEV;
--
--	device = of_match_device(stmmac_dt_ids, &pdev->dev);
--	if (!device)
--		return -ENODEV;
--
--	if (device->data) {
--		const struct stmmac_of_data *data = device->data;
--		plat->has_gmac = data->has_gmac;
--		plat->enh_desc = data->enh_desc;
--		plat->tx_coe = data->tx_coe;
--		plat->rx_coe = data->rx_coe;
--		plat->bugged_jumbo = data->bugged_jumbo;
--		plat->pmt = data->pmt;
--		plat->riwt_off = data->riwt_off;
--		plat->fix_mac_speed = data->fix_mac_speed;
--		plat->bus_setup = data->bus_setup;
--		plat->setup = data->setup;
--		plat->free = data->free;
--		plat->init = data->init;
--		plat->exit = data->exit;
--	}
-+	plat = devm_kzalloc(&pdev->dev, sizeof(*plat), GFP_KERNEL);
-+	if (!plat)
-+		return ERR_PTR(-ENOMEM);
- 
- 	*mac = of_get_mac_address(np);
- 	plat->interface = of_get_phy_mode(np);
-@@ -155,13 +129,24 @@ static int stmmac_probe_config_dt(struct
- 	/* Default to phy auto-detection */
- 	plat->phy_addr = -1;
- 
-+	/* If we find a phy-handle property, use it as the PHY */
-+	plat->phy_node = of_parse_phandle(np, "phy-handle", 0);
-+
-+	/* If phy-handle is not specified, check if we have a fixed-phy */
-+	if (!plat->phy_node && of_phy_is_fixed_link(np)) {
-+		if ((of_phy_register_fixed_link(np) < 0))
-+			return ERR_PTR(-ENODEV);
-+
-+		plat->phy_node = of_node_get(np);
-+	}
-+
- 	/* "snps,phy-addr" is not a standard property. Mark it as deprecated
- 	 * and warn of its use. Remove this when phy node support is added.
- 	 */
- 	if (of_property_read_u32(np, "snps,phy-addr", &plat->phy_addr) == 0)
- 		dev_warn(&pdev->dev, "snps,phy-addr property is deprecated\n");
- 
--	if (plat->phy_bus_name)
-+	if (plat->phy_node || plat->phy_bus_name)
- 		plat->mdio_bus_data = NULL;
- 	else
- 		plat->mdio_bus_data =
-@@ -169,6 +154,10 @@ static int stmmac_probe_config_dt(struct
- 				     sizeof(struct stmmac_mdio_bus_data),
- 				     GFP_KERNEL);
- 
-+	of_property_read_u32(np, "tx-fifo-depth", &plat->tx_fifo_size);
-+
-+	of_property_read_u32(np, "rx-fifo-depth", &plat->rx_fifo_size);
-+
- 	plat->force_sf_dma_mode =
- 		of_property_read_bool(np, "snps,force_sf_dma_mode");
- 
-@@ -177,6 +166,12 @@ static int stmmac_probe_config_dt(struct
- 	 */
- 	plat->maxmtu = JUMBO_LEN;
- 
-+	/* Set default value for multicast hash bins */
-+	plat->multicast_filter_bins = HASH_TABLE_SIZE;
-+
-+	/* Set default value for unicast filter entries */
-+	plat->unicast_filter_entries = 1;
-+
- 	/*
- 	 * Currently only the properties needed on SPEAr600
- 	 * are provided. All other properties should be added
-@@ -215,14 +210,19 @@ static int stmmac_probe_config_dt(struct
- 	if (of_find_property(np, "snps,pbl", NULL)) {
- 		dma_cfg = devm_kzalloc(&pdev->dev, sizeof(*dma_cfg),
- 				       GFP_KERNEL);
--		if (!dma_cfg)
--			return -ENOMEM;
-+		if (!dma_cfg) {
-+			of_node_put(np);
-+			return ERR_PTR(-ENOMEM);
-+		}
- 		plat->dma_cfg = dma_cfg;
- 		of_property_read_u32(np, "snps,pbl", &dma_cfg->pbl);
- 		dma_cfg->fixed_burst =
- 			of_property_read_bool(np, "snps,fixed-burst");
- 		dma_cfg->mixed_burst =
- 			of_property_read_bool(np, "snps,mixed-burst");
-+		of_property_read_u32(np, "snps,burst_len", &dma_cfg->burst_len);
-+		if (dma_cfg->burst_len < 0 || dma_cfg->burst_len > 256)
-+			dma_cfg->burst_len = 0;
- 	}
- 	plat->force_thresh_dma_mode = of_property_read_bool(np, "snps,force_thresh_dma_mode");
- 	if (plat->force_thresh_dma_mode) {
-@@ -230,123 +230,60 @@ static int stmmac_probe_config_dt(struct
- 		pr_warn("force_sf_dma_mode is ignored if force_thresh_dma_mode is set.");
- 	}
- 
--	return 0;
-+	return plat;
- }
- #else
--static int stmmac_probe_config_dt(struct platform_device *pdev,
--				  struct plat_stmmacenet_data *plat,
--				  const char **mac)
-+struct plat_stmmacenet_data *
-+stmmac_probe_config_dt(struct platform_device *pdev, const char **mac)
- {
--	return -ENOSYS;
-+	return ERR_PTR(-ENOSYS);
- }
- #endif /* CONFIG_OF */
-+EXPORT_SYMBOL_GPL(stmmac_probe_config_dt);
- 
--/**
-- * stmmac_pltfr_probe
-- * @pdev: platform device pointer
-- * Description: platform_device probe function. It allocates
-- * the necessary resources and invokes the main to init
-- * the net device, register the mdio bus etc.
-- */
--static int stmmac_pltfr_probe(struct platform_device *pdev)
-+int stmmac_get_platform_resources(struct platform_device *pdev,
-+				  struct stmmac_resources *stmmac_res)
- {
--	int ret = 0;
- 	struct resource *res;
--	struct device *dev = &pdev->dev;
--	void __iomem *addr = NULL;
--	struct stmmac_priv *priv = NULL;
--	struct plat_stmmacenet_data *plat_dat = NULL;
--	const char *mac = NULL;
--
--	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
--	addr = devm_ioremap_resource(dev, res);
--	if (IS_ERR(addr))
--		return PTR_ERR(addr);
--
--	plat_dat = dev_get_platdata(&pdev->dev);
--
--	if (!plat_dat)
--		plat_dat = devm_kzalloc(&pdev->dev,
--					sizeof(struct plat_stmmacenet_data),
--					GFP_KERNEL);
--	if (!plat_dat) {
--		pr_err("%s: ERROR: no memory", __func__);
--		return  -ENOMEM;
--	}
--
--	/* Set default value for multicast hash bins */
--	plat_dat->multicast_filter_bins = HASH_TABLE_SIZE;
--
--	/* Set default value for unicast filter entries */
--	plat_dat->unicast_filter_entries = 1;
--
--	if (pdev->dev.of_node) {
--		ret = stmmac_probe_config_dt(pdev, plat_dat, &mac);
--		if (ret) {
--			pr_err("%s: main dt probe failed", __func__);
--			return ret;
--		}
--	}
--
--	/* Custom setup (if needed) */
--	if (plat_dat->setup) {
--		plat_dat->bsp_priv = plat_dat->setup(pdev);
--		if (IS_ERR(plat_dat->bsp_priv))
--			return PTR_ERR(plat_dat->bsp_priv);
--	}
--
--	/* Custom initialisation (if needed)*/
--	if (plat_dat->init) {
--		ret = plat_dat->init(pdev, plat_dat->bsp_priv);
--		if (unlikely(ret))
--			return ret;
--	}
- 
--	priv = stmmac_dvr_probe(&(pdev->dev), plat_dat, addr);
--	if (IS_ERR(priv)) {
--		pr_err("%s: main driver probe failed", __func__);
--		return PTR_ERR(priv);
--	}
-+	memset(stmmac_res, 0, sizeof(*stmmac_res));
- 
--	/* Get MAC address if available (DT) */
--	if (mac)
--		memcpy(priv->dev->dev_addr, mac, ETH_ALEN);
--
--	/* Get the MAC information */
--	priv->dev->irq = platform_get_irq_byname(pdev, "macirq");
--	if (priv->dev->irq < 0) {
--		if (priv->dev->irq != -EPROBE_DEFER) {
--			netdev_err(priv->dev,
--				   "MAC IRQ configuration information not found\n");
-+	/* Get IRQ information early to have an ability to ask for deferred
-+	 * probe if needed before we went too far with resource allocation.
-+	 */
-+	stmmac_res->irq = platform_get_irq_byname(pdev, "macirq");
-+	if (stmmac_res->irq < 0) {
-+		if (stmmac_res->irq != -EPROBE_DEFER) {
-+			dev_err(&pdev->dev,
-+				"MAC IRQ configuration information not found\n");
- 		}
--		return priv->dev->irq;
-+		return stmmac_res->irq;
- 	}
- 
--	/*
--	 * On some platforms e.g. SPEAr the wake up irq differs from the mac irq
-+	/* On some platforms e.g. SPEAr the wake up irq differs from the mac irq
- 	 * The external wake up irq can be passed through the platform code
- 	 * named as "eth_wake_irq"
- 	 *
- 	 * In case the wake up interrupt is not passed from the platform
- 	 * so the driver will continue to use the mac irq (ndev->irq)
- 	 */
--	priv->wol_irq = platform_get_irq_byname(pdev, "eth_wake_irq");
--	if (priv->wol_irq < 0) {
--		if (priv->wol_irq == -EPROBE_DEFER)
-+	stmmac_res->wol_irq = platform_get_irq_byname(pdev, "eth_wake_irq");
-+	if (stmmac_res->wol_irq < 0) {
-+		if (stmmac_res->wol_irq == -EPROBE_DEFER)
- 			return -EPROBE_DEFER;
--		priv->wol_irq = priv->dev->irq;
-+		stmmac_res->wol_irq = stmmac_res->irq;
- 	}
- 
--	priv->lpi_irq = platform_get_irq_byname(pdev, "eth_lpi");
--	if (priv->lpi_irq == -EPROBE_DEFER)
-+	stmmac_res->lpi_irq = platform_get_irq_byname(pdev, "eth_lpi");
-+	if (stmmac_res->lpi_irq == -EPROBE_DEFER)
- 		return -EPROBE_DEFER;
- 
--	platform_set_drvdata(pdev, priv->dev);
--
--	pr_debug("STMMAC platform driver registration completed");
-+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-+	stmmac_res->addr = devm_ioremap_resource(&pdev->dev, res);
- 
--	return 0;
-+	return PTR_ERR_OR_ZERO(stmmac_res->addr);
- }
-+EXPORT_SYMBOL_GPL(stmmac_get_platform_resources);
- 
- /**
-  * stmmac_pltfr_remove
-@@ -354,7 +291,7 @@ static int stmmac_pltfr_probe(struct pla
-  * Description: this function calls the main to free the net resources
-  * and calls the platforms hook and release the resources (e.g. mem).
-  */
--static int stmmac_pltfr_remove(struct platform_device *pdev)
-+int stmmac_pltfr_remove(struct platform_device *pdev)
- {
- 	struct net_device *ndev = platform_get_drvdata(pdev);
- 	struct stmmac_priv *priv = netdev_priv(ndev);
-@@ -363,13 +300,18 @@ static int stmmac_pltfr_remove(struct pl
- 	if (priv->plat->exit)
- 		priv->plat->exit(pdev, priv->plat->bsp_priv);
- 
--	if (priv->plat->free)
--		priv->plat->free(pdev, priv->plat->bsp_priv);
--
- 	return ret;
- }
-+EXPORT_SYMBOL_GPL(stmmac_pltfr_remove);
- 
--#ifdef CONFIG_PM
-+#ifdef CONFIG_PM_SLEEP
-+/**
-+ * stmmac_pltfr_suspend
-+ * @dev: device pointer
-+ * Description: this function is invoked when suspend the driver and it direcly
-+ * call the main suspend function and then, if required, on some platform, it
-+ * can call an exit helper.
-+ */
- static int stmmac_pltfr_suspend(struct device *dev)
- {
- 	int ret;
-@@ -384,6 +326,13 @@ static int stmmac_pltfr_suspend(struct d
- 	return ret;
- }
- 
-+/**
-+ * stmmac_pltfr_resume
-+ * @dev: device pointer
-+ * Description: this function is invoked when resume the driver before calling
-+ * the main resume function, on some platforms, it can call own init helper
-+ * if required.
-+ */
- static int stmmac_pltfr_resume(struct device *dev)
- {
- 	struct net_device *ndev = dev_get_drvdata(dev);
-@@ -395,23 +344,12 @@ static int stmmac_pltfr_resume(struct de
- 
- 	return stmmac_resume(ndev);
- }
-+#endif /* CONFIG_PM_SLEEP */
- 
--#endif /* CONFIG_PM */
--
--static SIMPLE_DEV_PM_OPS(stmmac_pltfr_pm_ops,
--			stmmac_pltfr_suspend, stmmac_pltfr_resume);
--
--struct platform_driver stmmac_pltfr_driver = {
--	.probe = stmmac_pltfr_probe,
--	.remove = stmmac_pltfr_remove,
--	.driver = {
--		   .name = STMMAC_RESOURCE_NAME,
--		   .owner = THIS_MODULE,
--		   .pm = &stmmac_pltfr_pm_ops,
--		   .of_match_table = of_match_ptr(stmmac_dt_ids),
--		   },
--};
-+SIMPLE_DEV_PM_OPS(stmmac_pltfr_pm_ops, stmmac_pltfr_suspend,
-+				       stmmac_pltfr_resume);
-+EXPORT_SYMBOL_GPL(stmmac_pltfr_pm_ops);
- 
--MODULE_DESCRIPTION("STMMAC 10/100/1000 Ethernet PLATFORM driver");
-+MODULE_DESCRIPTION("STMMAC 10/100/1000 Ethernet platform support");
- MODULE_AUTHOR("Giuseppe Cavallaro <peppe.cavallaro@st.com>");
- MODULE_LICENSE("GPL");
---- /dev/null
-+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.h
-@@ -0,0 +1,33 @@
-+/*******************************************************************************
-+  Copyright (C) 2007-2009  STMicroelectronics Ltd
-+
-+  This program is free software; you can redistribute it and/or modify it
-+  under the terms and conditions of the GNU General Public License,
-+  version 2, as published by the Free Software Foundation.
-+
-+  This program is distributed in the hope it will be useful, but WITHOUT
-+  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
-+  more details.
-+
-+  The full GNU General Public License is included in this distribution in
-+  the file called "COPYING".
-+
-+  Author: Giuseppe Cavallaro <peppe.cavallaro@st.com>
-+*******************************************************************************/
-+
-+#ifndef __STMMAC_PLATFORM_H__
-+#define __STMMAC_PLATFORM_H__
-+
-+#include "stmmac.h"
-+
-+struct plat_stmmacenet_data *
-+stmmac_probe_config_dt(struct platform_device *pdev, const char **mac);
-+
-+int stmmac_get_platform_resources(struct platform_device *pdev,
-+				  struct stmmac_resources *stmmac_res);
-+
-+int stmmac_pltfr_remove(struct platform_device *pdev);
-+extern const struct dev_pm_ops stmmac_pltfr_pm_ops;
-+
-+#endif /* __STMMAC_PLATFORM_H__ */
diff --git a/target/linux/ipq806x/patches-3.18/707-ARM-dts-qcom-add-mdio-nodes-to-ap148-db149.patch b/target/linux/ipq806x/patches-3.18/707-ARM-dts-qcom-add-mdio-nodes-to-ap148-db149.patch
deleted file mode 100644
index 0f2aebe5d4ca762632f05b56ecf2ea53715d90b7..0000000000000000000000000000000000000000
--- a/target/linux/ipq806x/patches-3.18/707-ARM-dts-qcom-add-mdio-nodes-to-ap148-db149.patch
+++ /dev/null
@@ -1,146 +0,0 @@
-From e81de9d28bd0421c236df322872e64edf4ee1852 Mon Sep 17 00:00:00 2001
-From: Mathieu Olivari <mathieu@codeaurora.org>
-Date: Mon, 11 May 2015 16:32:09 -0700
-Subject: [PATCH 7/8] ARM: dts: qcom: add mdio nodes to ap148 & db149
-
-Signed-off-by: Mathieu Olivari <mathieu@codeaurora.org>
----
- arch/arm/boot/dts/qcom-ipq8064-ap148.dts | 40 ++++++++++++++++++++++++++-
- arch/arm/boot/dts/qcom-ipq8064-db149.dts | 46 ++++++++++++++++++++++++++++++++
- 2 files changed, 85 insertions(+), 1 deletion(-)
-
---- a/arch/arm/boot/dts/qcom-ipq8064-ap148.dts
-+++ b/arch/arm/boot/dts/qcom-ipq8064-ap148.dts
-@@ -19,8 +19,9 @@
- 		};
- 	};
- 
--	alias {
-+	aliases {
- 		serial0 = &uart4;
-+		mdio-gpio0 = &mdio0;
- 	};
- 
- 	chosen {
-@@ -68,6 +69,15 @@
- 					bias-bus-hold;
- 				};
- 			};
-+
-+			mdio0_pins: mdio0_pins {
-+				mux {
-+					pins = "gpio0", "gpio1";
-+					function = "gpio";
-+					drive-strength = <8>;
-+					bias-disable;
-+				};
-+			};
- 		};
- 
- 		gsbi@16300000 {
-@@ -162,6 +172,34 @@
- 
- 			linux,part-probe = "qcom-smem";
- 		};
-+
-+		mdio0: mdio {
-+			compatible = "virtual,mdio-gpio";
-+			#address-cells = <1>;
-+			#size-cells = <0>;
-+			gpios = <&qcom_pinmux 1 0 &qcom_pinmux 0 0>;
-+			pinctrl-0 = <&mdio0_pins>;
-+			pinctrl-names = "default";
-+
-+			phy0: ethernet-phy@0 {
-+				device_type = "ethernet-phy";
-+				reg = <0>;
-+				qca,ar8327-initvals = <
-+					0x00004 0x7600000   /* PAD0_MODE */
-+					0x00008 0x1000000   /* PAD5_MODE */
-+					0x0000c 0x80        /* PAD6_MODE */
-+					0x000e4 0xaa545     /* MAC_POWER_SEL */
-+					0x000e0 0xc74164de  /* SGMII_CTRL */
-+					0x0007c 0x4e        /* PORT0_STATUS */
-+					0x00094 0x4e        /* PORT6_STATUS */
-+					>;
-+			};
-+
-+			phy4: ethernet-phy@4 {
-+				device_type = "ethernet-phy";
-+				reg = <4>;
-+			};
-+		};
- 	};
- };
- 
---- a/arch/arm/boot/dts/qcom-ipq8064-db149.dts
-+++ b/arch/arm/boot/dts/qcom-ipq8064-db149.dts
-@@ -16,6 +16,7 @@
- 
- 	alias {
- 		serial0 = &uart2;
-+		mdio-gpio0 = &mdio0;
- 	};
- 
- 	chosen {
-@@ -38,6 +39,15 @@
- 					bias-none;
- 				};
- 			};
-+
-+			mdio0_pins: mdio0_pins {
-+				mux {
-+					pins = "gpio0", "gpio1";
-+					function = "gpio";
-+					drive-strength = <8>;
-+					bias-disable;
-+				};
-+			};
- 		};
- 
- 		gsbi2: gsbi@12480000 {
-@@ -140,5 +150,44 @@
- 		pcie2: pci@1b900000 {
- 			status = "ok";
- 		};
-+
-+		mdio0: mdio {
-+			compatible = "virtual,mdio-gpio";
-+			#address-cells = <1>;
-+			#size-cells = <0>;
-+			gpios = <&qcom_pinmux 1 0 &qcom_pinmux 0 0>;
-+
-+			pinctrl-0 = <&mdio0_pins>;
-+			pinctrl-names = "default";
-+
-+			phy0: ethernet-phy@0 {
-+				device_type = "ethernet-phy";
-+				reg = <0>;
-+				qca,ar8327-initvals = <
-+					0x00004 0x7600000   /* PAD0_MODE */
-+					0x00008 0x1000000   /* PAD5_MODE */
-+					0x0000c 0x80        /* PAD6_MODE */
-+					0x000e4 0xaa545     /* MAC_POWER_SEL */
-+					0x000e0 0xc74164de  /* SGMII_CTRL */
-+					0x0007c 0x4e        /* PORT0_STATUS */
-+					0x00094 0x4e        /* PORT6_STATUS */
-+				>;
-+			};
-+
-+			phy4: ethernet-phy@4 {
-+				device_type = "ethernet-phy";
-+				reg = <4>;
-+			};
-+
-+			phy6: ethernet-phy@6 {
-+				device_type = "ethernet-phy";
-+				reg = <6>;
-+			};
-+
-+			phy7: ethernet-phy@7 {
-+				device_type = "ethernet-phy";
-+				reg = <7>;
-+			};
-+		};
- 	};
- };
diff --git a/target/linux/ipq806x/patches-3.18/708-ARM-dts-qcom-add-gmac-nodes-to-ipq806x-platforms.patch b/target/linux/ipq806x/patches-3.18/708-ARM-dts-qcom-add-gmac-nodes-to-ipq806x-platforms.patch
deleted file mode 100644
index 49203f1cea09a9d86588bd5ab5e828ffd2ad7d33..0000000000000000000000000000000000000000
--- a/target/linux/ipq806x/patches-3.18/708-ARM-dts-qcom-add-gmac-nodes-to-ipq806x-platforms.patch
+++ /dev/null
@@ -1,216 +0,0 @@
-From cab1f4720e82f2e17eaeed9a9ad9e4f07c742977 Mon Sep 17 00:00:00 2001
-From: Mathieu Olivari <mathieu@codeaurora.org>
-Date: Mon, 11 May 2015 12:29:18 -0700
-Subject: [PATCH 8/8] ARM: dts: qcom: add gmac nodes to ipq806x platforms
-
-Signed-off-by: Mathieu Olivari <mathieu@codeaurora.org>
----
- arch/arm/boot/dts/qcom-ipq8064-ap148.dts | 31 ++++++++++++
- arch/arm/boot/dts/qcom-ipq8064-db149.dts | 43 ++++++++++++++++
- arch/arm/boot/dts/qcom-ipq8064.dtsi      | 86 ++++++++++++++++++++++++++++++++
- 3 files changed, 160 insertions(+)
-
---- a/arch/arm/boot/dts/qcom-ipq8064-ap148.dts
-+++ b/arch/arm/boot/dts/qcom-ipq8064-ap148.dts
-@@ -78,6 +78,16 @@
- 					bias-disable;
- 				};
- 			};
-+
-+			rgmii2_pins: rgmii2_pins {
-+				mux {
-+					pins = "gpio27", "gpio28", "gpio29", "gpio30", "gpio31", "gpio32",
-+					       "gpio51", "gpio52", "gpio59", "gpio60", "gpio61", "gpio62" ;
-+					function = "rgmii2";
-+					drive-strength = <8>;
-+					bias-disable;
-+				};
-+			};
- 		};
- 
- 		gsbi@16300000 {
-@@ -200,6 +210,31 @@
- 				reg = <4>;
- 			};
- 		};
-+
-+		gmac1: ethernet@37200000 {
-+			status = "ok";
-+			phy-mode = "rgmii";
-+			qcom,id = <1>;
-+
-+			pinctrl-0 = <&rgmii2_pins>;
-+			pinctrl-names = "default";
-+
-+			fixed-link {
-+				speed = <1000>;
-+				full-duplex;
-+			};
-+		};
-+
-+		gmac2: ethernet@37400000 {
-+			status = "ok";
-+			phy-mode = "sgmii";
-+			qcom,id = <2>;
-+
-+			fixed-link {
-+				speed = <1000>;
-+				full-duplex;
-+			};
-+		};
- 	};
- };
- 
---- a/arch/arm/boot/dts/qcom-ipq8064-db149.dts
-+++ b/arch/arm/boot/dts/qcom-ipq8064-db149.dts
-@@ -48,6 +48,14 @@
- 					bias-disable;
- 				};
- 			};
-+
-+			rgmii0_pins: rgmii0_pins {
-+				mux {
-+					pins = "gpio2", "gpio66";
-+					drive-strength = <8>;
-+					bias-disable;
-+				};
-+			};
- 		};
- 
- 		gsbi2: gsbi@12480000 {
-@@ -189,5 +197,40 @@
- 				reg = <7>;
- 			};
- 		};
-+
-+		gmac0: ethernet@37000000 {
-+			status = "ok";
-+			phy-mode = "rgmii";
-+			qcom,id = <0>;
-+			phy-handle = <&phy4>;
-+
-+			pinctrl-0 = <&rgmii0_pins>;
-+			pinctrl-names = "default";
-+		};
-+
-+		gmac1: ethernet@37200000 {
-+			status = "ok";
-+			phy-mode = "sgmii";
-+			qcom,id = <1>;
-+
-+			fixed-link {
-+				speed = <1000>;
-+				full-duplex;
-+			};
-+		};
-+
-+		gmac2: ethernet@37400000 {
-+			status = "ok";
-+			phy-mode = "sgmii";
-+			qcom,id = <2>;
-+			phy-handle = <&phy6>;
-+		};
-+
-+		gmac3: ethernet@37600000 {
-+			status = "ok";
-+			phy-mode = "sgmii";
-+			qcom,id = <3>;
-+			phy-handle = <&phy7>;
-+		};
- 	};
- };
---- a/arch/arm/boot/dts/qcom-ipq8064.dtsi
-+++ b/arch/arm/boot/dts/qcom-ipq8064.dtsi
-@@ -741,6 +741,92 @@
- 			status = "disabled";
- 		};
- 
-+		nss_common: syscon@03000000 {
-+			compatible = "syscon";
-+			reg = <0x03000000 0x0000FFFF>;
-+		};
-+
-+		qsgmii_csr: syscon@1bb00000 {
-+			compatible = "syscon";
-+			reg = <0x1bb00000 0x000001FF>;
-+		};
-+
-+		gmac0: ethernet@37000000 {
-+			device_type = "network";
-+			compatible = "qcom,ipq806x-gmac";
-+			reg = <0x37000000 0x200000>;
-+			interrupts = <GIC_SPI 220 IRQ_TYPE_LEVEL_HIGH>;
-+			interrupt-names = "macirq";
-+
-+			qcom,nss-common = <&nss_common>;
-+			qcom,qsgmii-csr = <&qsgmii_csr>;
-+
-+			clocks = <&gcc GMAC_CORE1_CLK>;
-+			clock-names = "stmmaceth";
-+
-+			resets = <&gcc GMAC_CORE1_RESET>;
-+			reset-names = "stmmaceth";
-+
-+			status = "disabled";
-+		};
-+
-+		gmac1: ethernet@37200000 {
-+			device_type = "network";
-+			compatible = "qcom,ipq806x-gmac";
-+			reg = <0x37200000 0x200000>;
-+			interrupts = <GIC_SPI 223 IRQ_TYPE_LEVEL_HIGH>;
-+			interrupt-names = "macirq";
-+
-+			qcom,nss-common = <&nss_common>;
-+			qcom,qsgmii-csr = <&qsgmii_csr>;
-+
-+			clocks = <&gcc GMAC_CORE2_CLK>;
-+			clock-names = "stmmaceth";
-+
-+			resets = <&gcc GMAC_CORE2_RESET>;
-+			reset-names = "stmmaceth";
-+
-+			status = "disabled";
-+		};
-+
-+		gmac2: ethernet@37400000 {
-+			device_type = "network";
-+			compatible = "qcom,ipq806x-gmac";
-+			reg = <0x37400000 0x200000>;
-+			interrupts = <GIC_SPI 226 IRQ_TYPE_LEVEL_HIGH>;
-+			interrupt-names = "macirq";
-+
-+			qcom,nss-common = <&nss_common>;
-+			qcom,qsgmii-csr = <&qsgmii_csr>;
-+
-+			clocks = <&gcc GMAC_CORE3_CLK>;
-+			clock-names = "stmmaceth";
-+
-+			resets = <&gcc GMAC_CORE3_RESET>;
-+			reset-names = "stmmaceth";
-+
-+			status = "disabled";
-+		};
-+
-+		gmac3: ethernet@37600000 {
-+			device_type = "network";
-+			compatible = "qcom,ipq806x-gmac";
-+			reg = <0x37600000 0x200000>;
-+			interrupts = <GIC_SPI 229 IRQ_TYPE_LEVEL_HIGH>;
-+			interrupt-names = "macirq";
-+
-+			qcom,nss-common = <&nss_common>;
-+			qcom,qsgmii-csr = <&qsgmii_csr>;
-+
-+			clocks = <&gcc GMAC_CORE4_CLK>;
-+			clock-names = "stmmaceth";
-+
-+			resets = <&gcc GMAC_CORE4_RESET>;
-+			reset-names = "stmmaceth";
-+
-+			status = "disabled";
-+		};
-+
- 	};
- 
- 	sfpb_mutex: sfpb-mutex {
diff --git a/target/linux/ipq806x/patches-3.18/709-stmac-platform-add-support-for-retreiving-mac-from-m.patch b/target/linux/ipq806x/patches-3.18/709-stmac-platform-add-support-for-retreiving-mac-from-m.patch
deleted file mode 100644
index d385c9a36cc40538b9c054faa93ff8de74eec335..0000000000000000000000000000000000000000
--- a/target/linux/ipq806x/patches-3.18/709-stmac-platform-add-support-for-retreiving-mac-from-m.patch
+++ /dev/null
@@ -1,31 +0,0 @@
-From 5bf2dabde1fa3af0c9082b42b6847ef3fd198b13 Mon Sep 17 00:00:00 2001
-From: Jonas Gorski <jogo@openwrt.org>
-Date: Sun, 9 Aug 2015 12:53:55 +0200
-Subject: [PATCH] stmac: platform: add support for retreiving mac from mtd
-
----
- drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c | 10 ++++++++++
- 1 file changed, 10 insertions(+)
-
---- a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
-+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
-@@ -116,6 +116,19 @@ stmmac_probe_config_dt(struct platform_d
- 		return ERR_PTR(-ENOMEM);
- 
- 	*mac = of_get_mac_address(np);
-+	if (!*mac) {
-+		u8 mtd_mac[ETH_ALEN];
-+		int ret;
-+
-+		ret = of_get_mac_address_mtd(np, mtd_mac);
-+		if (ret == -EPROBE_DEFER)
-+			return ERR_PTR(ret);
-+
-+		if (is_valid_ether_addr(mtd_mac))
-+			*mac = devm_kmemdup(&pdev->dev, mtd_mac, ETH_ALEN,
-+					    GFP_KERNEL);
-+	}
-+
- 	plat->interface = of_get_phy_mode(np);
- 
- 	/* Get max speed of operation from device tree */
diff --git a/target/linux/ipq806x/patches-3.18/710-stmmac-fix-ipq806x-DMA-configuration.patch b/target/linux/ipq806x/patches-3.18/710-stmmac-fix-ipq806x-DMA-configuration.patch
deleted file mode 100644
index c99f60768f2814ec4466dde736c3c45715c5b6f4..0000000000000000000000000000000000000000
--- a/target/linux/ipq806x/patches-3.18/710-stmmac-fix-ipq806x-DMA-configuration.patch
+++ /dev/null
@@ -1,117 +0,0 @@
---- a/drivers/net/ethernet/stmicro/stmmac/dwmac-ipq806x.c
-+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-ipq806x.c
-@@ -259,6 +259,7 @@ static int ipq806x_gmac_probe(struct pla
- {
- 	struct plat_stmmacenet_data *plat_dat;
- 	struct stmmac_resources stmmac_res;
-+	struct stmmac_dma_cfg *dma_cfg;
- 	struct device *dev = &pdev->dev;
- 	struct ipq806x_gmac *gmac;
- 	int val;
-@@ -348,6 +349,17 @@ static int ipq806x_gmac_probe(struct pla
- 	plat_dat->bsp_priv = gmac;
- 	plat_dat->fix_mac_speed = ipq806x_gmac_fix_mac_speed;
- 
-+	dma_cfg = devm_kzalloc(&pdev->dev, sizeof(*dma_cfg),
-+			       GFP_KERNEL);
-+
-+	dma_cfg->pbl = 32;
-+	dma_cfg->aal = 1;
-+	dma_cfg->burst_len = DMA_AXI_BLEN_16 |
-+		(7 << DMA_AXI_RD_OSR_LMT_SHIFT) |
-+		(7 << DMA_AXI_WR_OSR_LMT_SHIFT);
-+
-+	plat_dat->dma_cfg = dma_cfg;
-+
- 	return stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res);
- }
- 
---- a/include/linux/stmmac.h
-+++ b/include/linux/stmmac.h
-@@ -73,6 +73,9 @@
- 			| DMA_AXI_BLEN_32 | DMA_AXI_BLEN_64 \
- 			| DMA_AXI_BLEN_128 | DMA_AXI_BLEN_256)
- 
-+#define DMA_AXI_RD_OSR_LMT_SHIFT	16
-+#define DMA_AXI_WR_OSR_LMT_SHIFT	20
-+
- /* Platfrom data for platform device structure's platform_data field */
- 
- struct stmmac_mdio_bus_data {
-@@ -88,6 +91,7 @@ struct stmmac_mdio_bus_data {
- 
- struct stmmac_dma_cfg {
- 	int pbl;
-+	int aal;
- 	int fixed_burst;
- 	int mixed_burst;
- 	int burst_len;
---- a/drivers/net/ethernet/stmicro/stmmac/dwmac1000_dma.c
-+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac1000_dma.c
-@@ -31,7 +31,8 @@
- #include "dwmac_dma.h"
- 
- static int dwmac1000_dma_init(void __iomem *ioaddr, int pbl, int fb, int mb,
--			      int burst_len, u32 dma_tx, u32 dma_rx, int atds)
-+			      int burst_len, u32 dma_tx, u32 dma_rx, int atds,
-+			      int aal)
- {
- 	u32 value = readl(ioaddr + DMA_BUS_MODE);
- 	int limit;
-@@ -62,6 +63,10 @@ static int dwmac1000_dma_init(void __iom
- 	value = DMA_BUS_MODE_PBL | ((pbl << DMA_BUS_MODE_PBL_SHIFT) |
- 				    (pbl << DMA_BUS_MODE_RPBL_SHIFT));
- 
-+	/* Address Aligned Beats */
-+	if (aal)
-+		value |= DMA_BUS_MODE_AAL;
-+
- 	/* Set the Fixed burst mode */
- 	if (fb)
- 		value |= DMA_BUS_MODE_FB;
---- a/drivers/net/ethernet/stmicro/stmmac/common.h
-+++ b/drivers/net/ethernet/stmicro/stmmac/common.h
-@@ -352,7 +352,7 @@ extern const struct stmmac_desc_ops ndes
- struct stmmac_dma_ops {
- 	/* DMA core initialization */
- 	int (*init) (void __iomem *ioaddr, int pbl, int fb, int mb,
--		     int burst_len, u32 dma_tx, u32 dma_rx, int atds);
-+		     int burst_len, u32 dma_tx, u32 dma_rx, int atds, int aal);
- 	/* Dump DMA registers */
- 	void (*dump_regs) (void __iomem *ioaddr);
- 	/* Set tx/rx threshold in the csr6 register
---- a/drivers/net/ethernet/stmicro/stmmac/dwmac100_dma.c
-+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac100_dma.c
-@@ -33,7 +33,8 @@
- #include "dwmac_dma.h"
- 
- static int dwmac100_dma_init(void __iomem *ioaddr, int pbl, int fb, int mb,
--			     int burst_len, u32 dma_tx, u32 dma_rx, int atds)
-+			     int burst_len, u32 dma_tx, u32 dma_rx, int atds,
-+			     int aal)
- {
- 	u32 value = readl(ioaddr + DMA_BUS_MODE);
- 	int limit;
---- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
-+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
-@@ -1639,9 +1639,11 @@ static int stmmac_init_dma_engine(struct
- 	int pbl = DEFAULT_DMA_PBL, fixed_burst = 0, burst_len = 0;
- 	int mixed_burst = 0;
- 	int atds = 0;
-+	int aal = 0;
- 
- 	if (priv->plat->dma_cfg) {
- 		pbl = priv->plat->dma_cfg->pbl;
-+		aal = priv->plat->dma_cfg->aal;
- 		fixed_burst = priv->plat->dma_cfg->fixed_burst;
- 		mixed_burst = priv->plat->dma_cfg->mixed_burst;
- 		burst_len = priv->plat->dma_cfg->burst_len;
-@@ -1652,7 +1654,7 @@ static int stmmac_init_dma_engine(struct
- 
- 	return priv->hw->dma->init(priv->ioaddr, pbl, fixed_burst, mixed_burst,
- 				   burst_len, priv->dma_tx_phy,
--				   priv->dma_rx_phy, atds);
-+				   priv->dma_rx_phy, atds, aal);
- }
- 
- /**
diff --git a/target/linux/ipq806x/patches-3.18/801-ARM-qcom-add-Netgear-Nighthawk-X4-D7800-device-tree.patch b/target/linux/ipq806x/patches-3.18/801-ARM-qcom-add-Netgear-Nighthawk-X4-D7800-device-tree.patch
deleted file mode 100644
index eaf037f57e787c60d874cf19ac7325aa617ab994..0000000000000000000000000000000000000000
--- a/target/linux/ipq806x/patches-3.18/801-ARM-qcom-add-Netgear-Nighthawk-X4-D7800-device-tree.patch
+++ /dev/null
@@ -1,381 +0,0 @@
---- a/arch/arm/boot/dts/Makefile
-+++ b/arch/arm/boot/dts/Makefile
-@@ -362,6 +362,7 @@ dtb-$(CONFIG_ARCH_QCOM) += \
- 	qcom-ipq8064-ap148.dtb \
- 	qcom-ipq8064-db149.dtb \
- 	qcom-ipq8064-r7500.dtb \
-+	qcom-ipq8064-d7800.dtb \
- 	qcom-msm8660-surf.dtb \
- 	qcom-msm8960-cdp.dtb \
- 	qcom-msm8974-sony-xperia-honami.dtb
---- /dev/null
-+++ b/arch/arm/boot/dts/qcom-ipq8064-d7800.dts
-@@ -0,0 +1,368 @@
-+#include "qcom-ipq8064-v1.0.dtsi"
-+
-+#include <dt-bindings/input/input.h>
-+
-+/ {
-+	model = "Netgear Nighthawk X4 D7800";
-+	compatible = "netgear,d7800", "qcom,ipq8064";
-+
-+	memory@0 {
-+		reg = <0x42000000 0xe000000>;
-+		device_type = "memory";
-+	};
-+
-+	reserved-memory {
-+		#address-cells = <1>;
-+		#size-cells = <1>;
-+		ranges;
-+		rsvd@41200000 {
-+			reg = <0x41200000 0x300000>;
-+			no-map;
-+		};
-+	};
-+
-+	aliases {
-+		serial0 = &uart4;
-+		mdio-gpio0 = &mdio0;
-+	};
-+
-+	chosen {
-+		bootargs = "rootfstype=squashfs noinitrd";
-+		linux,stdout-path = "serial0:115200n8";
-+	};
-+
-+	soc {
-+		pinmux@800000 {
-+			i2c4_pins: i2c4_pinmux {
-+				pins = "gpio12", "gpio13";
-+				function = "gsbi4";
-+				bias-disable;
-+			};
-+
-+			pcie0_pins: pcie0_pinmux {
-+				mux {
-+					pins = "gpio3";
-+					function = "pcie1_rst";
-+					drive-strength = <12>;
-+					bias-disable;
-+				};
-+			};
-+
-+			pcie1_pins: pcie1_pinmux {
-+				mux {
-+					pins = "gpio48";
-+					function = "pcie2_rst";
-+					drive-strength = <12>;
-+					bias-disable;
-+				};
-+			};
-+
-+			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;
-+				};
-+			};
-+
-+			mdio0_pins: mdio0_pins {
-+				mux {
-+					pins = "gpio0", "gpio1";
-+					function = "gpio";
-+					drive-strength = <8>;
-+					bias-disable;
-+				};
-+			};
-+
-+			rgmii2_pins: rgmii2_pins {
-+				mux {
-+					pins = "gpio27", "gpio28", "gpio29", "gpio30", "gpio31", "gpio32",
-+					       "gpio51", "gpio52", "gpio59", "gpio60", "gpio61", "gpio62" ;
-+					function = "rgmii2";
-+					drive-strength = <8>;
-+					bias-disable;
-+				};
-+			};
-+		};
-+
-+		gsbi@16300000 {
-+			qcom,mode = <GSBI_PROT_I2C_UART>;
-+			status = "ok";
-+			serial@16340000 {
-+				status = "ok";
-+			};
-+			/*
-+			 * The i2c device on gsbi4 should not be enabled.
-+			 * On ipq806x designs gsbi4 i2c is meant for exclusive
-+			 * RPM usage. Turning this on in kernel manifests as
-+			 * i2c failure for the RPM.
-+			 */
-+		};
-+
-+		sata-phy@1b400000 {
-+			status = "ok";
-+		};
-+
-+		sata@29000000 {
-+			status = "ok";
-+		};
-+
-+		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";
-+		};
-+
-+		pcie0: pci@1b500000 {
-+			status = "ok";
-+			reset-gpio = <&qcom_pinmux 3 0>;
-+			pinctrl-0 = <&pcie0_pins>;
-+			pinctrl-names = "default";
-+		};
-+
-+		pcie1: pci@1b700000 {
-+			status = "ok";
-+			reset-gpio = <&qcom_pinmux 48 0>;
-+			pinctrl-0 = <&pcie1_pins>;
-+			pinctrl-names = "default";
-+		};
-+
-+		nand@1ac00000 {
-+			status = "ok";
-+
-+			pinctrl-0 = <&nand_pins>;
-+			pinctrl-names = "default";
-+
-+			nand-ecc-strength = <4>;
-+			nand-bus-width = <8>;
-+
-+			#address-cells = <1>;
-+			#size-cells = <1>;
-+
-+			qcadata@0 {
-+				label = "qcadata";
-+				reg = <0x0000000 0x0c80000>;
-+				read-only;
-+			};
-+
-+			APPSBL@c80000 {
-+				label = "APPSBL";
-+				reg = <0x0c80000 0x0500000>;
-+				read-only;
-+			};
-+
-+			APPSBLENV@1180000 {
-+				label = "APPSBLENV";
-+				reg = <0x1180000 0x0080000>;
-+				read-only;
-+			};
-+
-+			art: art@1200000 {
-+				label = "art";
-+				reg = <0x1200000 0x0140000>;
-+				read-only;
-+			};
-+
-+			artbak: art@1340000 {
-+				label = "artbak";
-+				reg = <0x1340000 0x0140000>;
-+				read-only;
-+			};
-+
-+			kernel@1480000 {
-+				label = "kernel";
-+				reg = <0x1480000 0x0200000>;
-+			};
-+
-+			ubi@1680000 {
-+				label = "ubi";
-+				reg = <0x1680000 0x1E00000>;
-+			};
-+
-+			netgear@3480000 {
-+				label = "netgear";
-+				reg = <0x3480000 0x4480000>;
-+				read-only;
-+			};
-+
-+			reserve@7900000 {
-+				label = "reserve";
-+				reg = <0x7900000 0x0700000>;
-+				read-only;
-+			};
-+
-+			firmware@1480000 {
-+				label = "firmware";
-+				reg = <0x1480000 0x2000000>;
-+			};
-+
-+		};
-+
-+		mdio0: mdio {
-+			compatible = "virtual,mdio-gpio";
-+			#address-cells = <1>;
-+			#size-cells = <0>;
-+			gpios = <&qcom_pinmux 1 0 &qcom_pinmux 0 0>;
-+			pinctrl-0 = <&mdio0_pins>;
-+			pinctrl-names = "default";
-+
-+			phy0: ethernet-phy@0 {
-+				device_type = "ethernet-phy";
-+				reg = <0>;
-+				qca,ar8327-initvals = <
-+					0x00004 0x7600000   /* PAD0_MODE */
-+					0x00008 0x1000000   /* PAD5_MODE */
-+					0x0000c 0x80        /* PAD6_MODE */
-+					0x000e4 0xaa545     /* MAC_POWER_SEL */
-+					0x000e0 0xc74164de  /* SGMII_CTRL */
-+					0x0007c 0x4e        /* PORT0_STATUS */
-+					0x00094 0x4e        /* PORT6_STATUS */
-+					>;
-+			};
-+
-+			phy4: ethernet-phy@4 {
-+				device_type = "ethernet-phy";
-+				reg = <4>;
-+			};
-+		};
-+
-+		gmac1: ethernet@37200000 {
-+			status = "ok";
-+			phy-mode = "rgmii";
-+			phy-handle = <&phy4>;
-+			qcom,id = <1>;
-+
-+			pinctrl-0 = <&rgmii2_pins>;
-+			pinctrl-names = "default";
-+
-+			mtd-mac-address = <&art 6>;
-+		};
-+
-+		gmac2: ethernet@37400000 {
-+			status = "ok";
-+			phy-mode = "sgmii";
-+			qcom,id = <2>;
-+
-+			mtd-mac-address = <&art 0>;
-+
-+			fixed-link {
-+				speed = <1000>;
-+				full-duplex;
-+			};
-+		};
-+	};
-+
-+	gpio-keys {
-+		compatible = "gpio-keys";
-+
-+		wifi {
-+			label = "wifi";
-+			gpios = <&qcom_pinmux 6 1>;
-+			linux,code = <KEY_WLAN>;
-+		};
-+
-+		reset {
-+			label = "reset";
-+			gpios = <&qcom_pinmux 54 1>;
-+			linux,code = <KEY_RESTART>;
-+		};
-+
-+		wps {
-+			label = "wps";
-+			gpios = <&qcom_pinmux 65 1>;
-+			linux,code = <KEY_WPS_BUTTON>;
-+		};
-+	};
-+
-+	gpio-leds {
-+		compatible = "gpio-leds";
-+
-+		usb1 {
-+			label = "d7800:amber:usb1";
-+			gpios = <&qcom_pinmux 7 0>;
-+		};
-+
-+		usb3 {
-+			label = "d7800:amber:usb3";
-+			gpios = <&qcom_pinmux 8 0>;
-+		};
-+
-+		status {
-+			label = "d7800:amber:status";
-+			gpios = <&qcom_pinmux 9 0>;
-+		};
-+
-+		internet {
-+			label = "d7800:white:internet";
-+			gpios = <&qcom_pinmux 22 0>;
-+		};
-+
-+		wan {
-+			label = "d7800:white:wan";
-+			gpios = <&qcom_pinmux 23 0>;
-+		};
-+
-+		wps {
-+			label = "d7800:white:wps";
-+			gpios = <&qcom_pinmux 24 0>;
-+		};
-+
-+		esata {
-+			label = "d7800:white:esata";
-+			gpios = <&qcom_pinmux 26 0>;
-+		};
-+
-+		power {
-+			label = "d7800:white:power";
-+			gpios = <&qcom_pinmux 53 0>;
-+			default-state = "on";
-+		};
-+
-+		rfkill {
-+			label = "d7800:white:rfkill";
-+			gpios = <&qcom_pinmux 64 0>;
-+		};
-+
-+		wifi5g {
-+			label = "d7800:white:wifi5g";
-+			gpios = <&qcom_pinmux 67 0>;
-+		};
-+	};
-+};
-+
-+&adm_dma {
-+	status = "ok";
-+};
diff --git a/target/linux/ipq806x/patches-3.18/802-ARM-qcom-add-TPLink-C2600-device-tree.patch b/target/linux/ipq806x/patches-3.18/802-ARM-qcom-add-TPLink-C2600-device-tree.patch
deleted file mode 100644
index 8952f3339d9c0d4ee169a187fe511a524fa53018..0000000000000000000000000000000000000000
--- a/target/linux/ipq806x/patches-3.18/802-ARM-qcom-add-TPLink-C2600-device-tree.patch
+++ /dev/null
@@ -1,425 +0,0 @@
---- a/arch/arm/boot/dts/Makefile
-+++ b/arch/arm/boot/dts/Makefile
-@@ -506,6 +506,7 @@
- 	qcom-apq8084-ifc6540.dtb \
- 	qcom-apq8084-mtp.dtb \
- 	qcom-ipq8064-ap148.dtb \
-+	qcom-ipq8064-c2600.dtb \
- 	qcom-ipq8064-db149.dtb \
- 	qcom-ipq8064-r7500.dtb \
- 	qcom-ipq8064-d7800.dtb \
---- /dev/null
-+++ b/arch/arm/boot/dts/qcom-ipq8064-c2600.dts
-@@ -0,0 +1,412 @@
-+#include "qcom-ipq8064-v1.0.dtsi"
-+#include <dt-bindings/input/input.h>
-+
-+/ {
-+	model = "TP-Link Archer C2600";
-+	compatible = "tplink,c2600", "qcom,ipq8064";
-+
-+	memory@0 {
-+		reg = <0x42000000 0x1e000000>;
-+		device_type = "memory";
-+	};
-+
-+	reserved-memory {
-+		#address-cells = <1>;
-+		#size-cells = <1>;
-+		ranges;
-+		rsvd@41200000 {
-+			reg = <0x41200000 0x300000>;
-+			no-map;
-+		};
-+	};
-+
-+	aliases {
-+		serial0 = &uart4;
-+		mdio-gpio0 = &mdio0;
-+	};
-+
-+	chosen {
-+		linux,stdout-path = "serial0:115200n8";
-+	};
-+
-+	soc {
-+		pinmux@800000 {
-+			i2c4_pins: i2c4_pinmux {
-+				pins = "gpio12", "gpio13";
-+				function = "gsbi4";
-+				bias-disable;
-+			};
-+
-+			spi_pins: spi_pins {
-+				mux {
-+					pins = "gpio18", "gpio19", "gpio21";
-+					function = "gsbi5";
-+					drive-strength = <10>;
-+					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;
-+				};
-+			};
-+
-+			mdio0_pins: mdio0_pins {
-+				mux {
-+					pins = "gpio0", "gpio1";
-+					function = "gpio";
-+					drive-strength = <8>;
-+					bias-disable;
-+				};
-+			};
-+
-+			rgmii2_pins: rgmii2_pins {
-+				mux {
-+					pins = "gpio27", "gpio28", "gpio29", "gpio30", "gpio31", "gpio32",
-+					       "gpio51", "gpio52", "gpio59", "gpio60", "gpio61", "gpio62" ;
-+					function = "rgmii2";
-+					drive-strength = <8>;
-+					bias-disable;
-+				};
-+			};
-+		};
-+
-+		gsbi@16300000 {
-+			qcom,mode = <GSBI_PROT_I2C_UART>;
-+			status = "ok";
-+			serial@16340000 {
-+				status = "ok";
-+			};
-+			/*
-+			 * The i2c device on gsbi4 should not be enabled.
-+			 * On ipq806x designs gsbi4 i2c is meant for exclusive
-+			 * RPM usage. Turning this on in kernel manifests as
-+			 * i2c failure for the RPM.
-+			 */
-+		};
-+
-+		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>;
-+
-+					SBL1@0 {
-+						label = "SBL1";
-+						reg = <0x0 0x20000>;
-+						read-only;
-+					};
-+					MIBIB@20000 {
-+						label = "MIBIB";
-+						reg = <0x20000 0x20000>;
-+						read-only;
-+					};
-+					SBL2@40000 {
-+						label = "SBL2";
-+						reg = <0x40000 0x20000>;
-+						read-only;
-+					};
-+					SBL3@60000 {
-+						label = "SBL3";
-+						reg = <0x60000 0x30000>;
-+						read-only;
-+					};
-+					DDRCONFIG@90000 {
-+						label = "DDRCONFIG";
-+						reg = <0x90000 0x10000>;
-+						read-only;
-+					};
-+					SSD@a0000 {
-+						label = "SSD";
-+						reg = <0xa0000 0x10000>;
-+						read-only;
-+					};
-+					TZ@b0000 {
-+						label = "TZ";
-+						reg = <0xb0000 0x30000>;
-+						read-only;
-+					};
-+					RPM@e0000 {
-+						label = "RPM";
-+						reg = <0xe0000 0x20000>;
-+						read-only;
-+					};
-+					fs-uboot@100000 {
-+						label = "fs-uboot";
-+						reg = <0x100000 0x70000>;
-+						read-only;
-+					};
-+					uboot-env@170000 {
-+						label = "uboot-env";
-+						reg = <0x170000 0x40000>;
-+						read-only;
-+					};
-+					radio@1b0000 {
-+						label = "radio";
-+						reg = <0x1b0000 0x40000>;
-+						read-only;
-+					};
-+					os-image@1f0000 {
-+						label = "os-image";
-+						reg = <0x1f0000 0x200000>;
-+					};
-+					rootfs@3f0000 {
-+						label = "rootfs";
-+						reg = <0x3f0000 0x1b00000>;
-+					};
-+					defaultmac: default-mac@1ef0000 {
-+						label = "default-mac";
-+						reg = <0x1ef0000 0x00200>;
-+						read-only;
-+					};
-+					pin@1ef0200 {
-+						label = "pin";
-+						reg = <0x1ef0200 0x00200>;
-+						read-only;
-+					};
-+					product-info@1ef0400 {
-+						label = "product-info";
-+						reg = <0x1ef0400 0x0fc00>;
-+						read-only;
-+					};
-+					partition-table@1f00000 {
-+						label = "partition-table";
-+						reg = <0x1f00000 0x10000>;
-+						read-only;
-+					};
-+					soft-version@1f10000 {
-+						label = "soft-version";
-+						reg = <0x1f10000 0x10000>;
-+						read-only;
-+					};
-+					support-list@1f20000 {
-+						label = "support-list";
-+						reg = <0x1f20000 0x10000>;
-+						read-only;
-+					};
-+					profile@1f30000 {
-+						label = "profile";
-+						reg = <0x1f30000 0x10000>;
-+						read-only;
-+					};
-+					default-config@1f40000 {
-+						label = "default-config";
-+						reg = <0x1f40000 0x10000>;
-+						read-only;
-+					};
-+					user-config@1f50000 {
-+						label = "user-config";
-+						reg = <0x1f50000 0x40000>;
-+						read-only;
-+					};
-+					qos-db@1f90000 {
-+						label = "qos-db";
-+						reg = <0x1f90000 0x40000>;
-+						read-only;
-+					};
-+					usb-config@1fd0000 {
-+						label = "usb-config";
-+						reg = <0x1fd0000 0x10000>;
-+						read-only;
-+					};
-+					log@1fe0000 {
-+						label = "log";
-+						reg = <0x1fe0000 0x20000>;
-+						read-only;
-+					};
-+				};
-+			};
-+		};
-+
-+		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";
-+		};
-+
-+		pcie0: pci@1b500000 {
-+			status = "ok";
-+			phy-tx0-term-offset = <7>;
-+		};
-+
-+		pcie1: pci@1b700000 {
-+			status = "ok";
-+			phy-tx0-term-offset = <7>;
-+		};
-+
-+		mdio0: mdio {
-+			compatible = "virtual,mdio-gpio";
-+			#address-cells = <1>;
-+			#size-cells = <0>;
-+			gpios = <&qcom_pinmux 1 0 &qcom_pinmux 0 0>;
-+			pinctrl-0 = <&mdio0_pins>;
-+			pinctrl-names = "default";
-+
-+			phy0: ethernet-phy@0 {
-+				device_type = "ethernet-phy";
-+				reg = <0>;
-+				qca,ar8327-initvals = <
-+					0x00004 0x7600000   /* PAD0_MODE */
-+					0x00008 0x1000000   /* PAD5_MODE */
-+					0x0000c 0x80        /* PAD6_MODE */
-+					0x000e4 0xaa545     /* MAC_POWER_SEL */
-+					0x000e0 0xc74164de  /* SGMII_CTRL */
-+					0x0007c 0x4e        /* PORT0_STATUS */
-+					0x00094 0x4e        /* PORT6_STATUS */
-+					>;
-+			};
-+
-+			phy4: ethernet-phy@4 {
-+				device_type = "ethernet-phy";
-+				reg = <4>;
-+			};
-+		};
-+
-+		gmac1: ethernet@37200000 {
-+			status = "ok";
-+			phy-mode = "rgmii";
-+			qcom,id = <1>;
-+
-+			pinctrl-0 = <&rgmii2_pins>;
-+			pinctrl-names = "default";
-+
-+			mtd-mac-address = <&defaultmac 0x8>;
-+			mtd-mac-address-increment = <1>;
-+
-+			fixed-link {
-+				speed = <1000>;
-+				full-duplex;
-+			};
-+		};
-+
-+		gmac2: ethernet@37400000 {
-+			status = "ok";
-+			phy-mode = "sgmii";
-+			qcom,id = <2>;
-+
-+			mtd-mac-address = <&defaultmac 0x8>;
-+
-+			fixed-link {
-+				speed = <1000>;
-+				full-duplex;
-+			};
-+		};
-+	};
-+
-+	gpio-keys {
-+		compatible = "gpio-keys";
-+
-+		wifi {
-+			label = "wifi";
-+			gpios = <&qcom_pinmux 49 1>;
-+			linux,code = <KEY_WLAN>;
-+		};
-+
-+		reset {
-+			label = "reset";
-+			gpios = <&qcom_pinmux 64 1>;
-+			linux,code = <KEY_RESTART>;
-+		};
-+
-+		wps {
-+			label = "wps";
-+			gpios = <&qcom_pinmux 65 1>;
-+			linux,code = <KEY_WPS_BUTTON>;
-+		};
-+                ledgeneral {
-+			label = "ledgeneral";
-+			gpios = <&qcom_pinmux 16 1>;
-+			linux,code = <KEY_DOLLAR>;
-+		};
-+	};
-+
-+	gpio-leds {
-+		compatible = "gpio-leds";
-+
-+		lan {
-+			label = "lan:blue";
-+			gpios = <&qcom_pinmux 6 0>;
-+		};
-+                usb4 {
-+			label = "usb_4:blue";
-+			gpios = <&qcom_pinmux 7 0>;
-+		};
-+                usb2 {
-+			label = "usb_2:blue";
-+			gpios = <&qcom_pinmux 8 0>;
-+		};
-+                wps {
-+			label = "wps:blue";
-+			gpios = <&qcom_pinmux 9 0>;
-+		};
-+                wan_blue {
-+			label = "wan:blue";
-+			gpios = <&qcom_pinmux 33 1>;
-+		};
-+                status {
-+			label = "status:blue";
-+			gpios = <&qcom_pinmux 53 0>;
-+			default-state = "on";
-+		};
-+                ledgnr {
-+			label = "ledgnr:blue";
-+			gpios = <&qcom_pinmux 66 0>;
-+		};
-+        };
-+};
-+
-+&adm_dma {
-+	status = "ok";
-+};