[source] ipq806x: remove v4.4 support

LEDE Commits lede-commits at lists.infradead.org
Wed Mar 22 02:12:22 PDT 2017


blogic pushed a commit to source.git, branch master:
https://git.lede-project.org/3a3564ead5e4cf2f6ff73302c1e680b5575079ec

commit 3a3564ead5e4cf2f6ff73302c1e680b5575079ec
Author: John Crispin <john at phrozen.org>
AuthorDate: Wed Mar 22 09:43:01 2017 +0100

    ipq806x: remove v4.4 support
    
    Signed-off-by: John Crispin <john at phrozen.org>
---
 target/linux/ipq806x/config-4.4                    |  426 ----
 ...add-API-register-brd-clks-bckwrds-cmptblt.patch |  135 --
 .../002-make-reset-control-ops-const.patch         |   35 -
 .../patches-4.4/003-mv-cxo-pxo-xo-into-DT.patch    |  172 --
 ...f_node_put-after-calling-of_parse_phandle.patch |   25 -
 ...006-mfd-qcom_rpm-Handle-message-RAM-clock.patch |   90 -
 ...watchdog-core-add-restart-handler-support.patch |  205 --
 ...watchdog-core-add-reboot-notifier-support.patch |  160 --
 ...t-class-watchdog_class-instead-of-pointer.patch |  111 --
 ...ad-device-status-through-sysfs-attributes.patch |  260 ---
 ...-Create-watchdog-device-in-watchdog_dev-c.patch |  261 ---
 ...tain-variables-based-on-variable-lifetime.patch |  969 ----------
 ...tchdog-device-from-struct-watchdog_device.patch |  117 --
 .../009-8-watchdog-kill-unref-ref-ops.patch        |   26 -
 .../010-1-qcom-wdt-use-core-restart-handler.patch  |  113 --
 ...-Do-not-set-dev-in-struct-watchdog_device.patch |   25 -
 ...ta-parameters-to-restart-handler-callback.patch |   51 -
 .../010-4-watchdog-qcom-Report-reboot-reason.patch |   46 -
 ...or-standalone-watchdog-not-in-timer-block.patch |  162 --
 ...figure-BARK-time-in-addition-to-BITE-time.patch |   60 -
 ...dog-driver-data-reference-count-callbacks.patch |   95 -
 ...tchdog-da9052_wdt-Drop-reference-counting.patch |   87 -
 ...tchdog-da9055_wdt-Drop-reference-counting.patch |   80 -
 ...1-clk-qcom-Add-support-for-SMD-RPM-Clocks.patch |  746 --------
 ...012-2-clk-qcom-Add-support-for-RPM-Clocks.patch |  586 ------
 ...-3-clk-qcom-clk-rpm-Fix-clk_hw-references.patch |   94 -
 ...l-qcom-tsens-Add-a-skeletal-TSENS-drivers.patch |  536 ------
 ...-8916-Add-support-for-8916-family-of-SoCs.patch |  165 --
 ...-8974-Add-support-for-8974-family-of-SoCs.patch |  293 ---
 ...-8960-Add-support-for-8960-family-of-SoCs.patch |  364 ----
 ...ens-8916-mark-PM-functions-__maybe_unused.patch |   46 -
 ...-2-thermal-of-thermal-Add-devm-version-of.patch |  143 --
 ...-core-export-apis-to-get-slope-and-offset.patch |  101 -
 ...-return-error-for-non-word-aligned-access.patch |   42 -
 ...em-core-fix-error-path-in-nvmem_add_cells.patch |   34 -
 ...mem-Add-flag-to-export-NVMEM-to-root-only.patch |  101 -
 ...tibility-support-for-older-EEPROM-drivers.patch |  181 --
 .../patches-4.4/020-add-ap148-bootargs.patch       |   61 -
 .../patches-4.4/021-add-ap148-partitions.patch     |   19 -
 .../ipq806x/patches-4.4/022-add-db149-dts.patch    |  160 --
 ...M-dts-ipq806x-Disable-i2c-device-on-gsbi4.patch |   52 -
 .../patches-4.4/024-ap148-add-memory-node.patch    |   14 -
 ...lect-ARM_CPU_SUSPEND-for-power-management.patch |   30 -
 ...33-ARM-qcom-add-SFPB-nodes-to-IPQ806x-dts.patch |   33 -
 ...-qcom-add-SMEM-device-node-to-IPQ806x-dts.patch |   36 -
 ...37-mtd-add-SMEM-parser-for-QCOM-platforms.patch |  275 ---
 .../096-01-usb-dwc3-core-purge-dev_dbg-calls.patch |   42 -
 ...3-Update-maximum_speed-for-SuperSpeedPlus.patch |   52 -
 ...dwc3-Validate-the-maximum_speed-parameter.patch |   68 -
 ...96-04-usb-dwc3-DWC_usb31-controller-check.patch |   28 -
 ...Update-register-fields-for-SuperSpeedPlus.patch |   42 -
 ...6-06-usb-dwc3-core-improve-reset-sequence.patch |  100 -
 .../096-07-usb-dwc3-drop-FIFO-resizing-logic.patch |  242 ---
 .../096-08-usb-dwc3-remove-num_event_buffers.patch |  265 ---
 .../096-09-usb-dwc3-drop-ev_buffs-array.patch      |   96 -
 ...dwc3-core-fix-PHY-handling-during-suspend.patch |   67 -
 .../097-1-usb-dwc3-add-generic-OF-glue-layer.patch |  234 ---
 ...sb-dwc3-of-simple-fix-build-warning-on-PM.patch |   36 -
 ...move-impossible-check-for-of_clk_get_pare.patch |   47 -
 ...tform_set_drvdata-in-dwc3_of_simple_probe.patch |   27 -
 ...b-phy-Add-Qualcomm-DWC3-HS-SS-PHY-drivers.patch |  512 -----
 ...1-ARM-qcom-add-USB-nodes-to-ipq806x-ap148.patch |  123 --
 ...CI-qcom-Document-PCIe-devicetree-bindings.patch |  263 ---
 ...-qcom-Add-Qualcomm-PCIe-controller-driver.patch |  752 --------
 ...-qcom-add-pcie-nodes-to-ipq806x-platforms.patch |  245 ---
 ...tomatically-select-PCI_DOMAINS-if-PCI-is-.patch |   29 -
 .../patches-4.4/114-pcie-add-ctlr-init.patch       |  311 ---
 .../patches-4.4/115-add-pcie-aux-clk-dts.patch     |   80 -
 .../patches-4.4/126-add-rpm-to-ipq8064-dts.patch   |   87 -
 ...-Add-Krait-L2-register-accessor-functions.patch |  144 --
 ...ux-Split-out-register-accessors-for-reuse.patch |  177 --
 ...ending-high-rates-to-downstream-clocks-du.patch |  122 --
 .../patches-4.4/136-clk-Add-safe-switch-hook.patch |  151 --
 ...dd-support-for-High-Frequency-PLLs-HFPLLs.patch |  351 ----
 .../138-clk-qcom-Add-HFPLL-driver.patch            |  206 --
 .../139-clk-qcom-Add-IPQ806X-s-HFPLLs.patch        |  127 --
 ...140-clk-qcom-Add-support-for-Krait-clocks.patch |  272 ---
 .../141-clk-qcom-Add-KPSS-ACC-GCC-driver.patch     |  207 --
 ...lk-qcom-Add-Krait-clock-controller-driver.patch |  435 -----
 ...-module-to-register-cpufreq-on-Krait-CPUs.patch |  304 ---
 ...m-Add-necessary-DT-data-for-Krait-cpufreq.patch |   96 -
 ...-bindings-qcom_adm-Fix-channel-specifiers.patch |   76 -
 .../patches-4.4/156-dmaengine-Add-ADM-driver.patch |  964 ----------
 .../157-ARM-DT-ipq8064-Add-ADM-device-node.patch   |   42 -
 ...g-to-access-bad-block-markers-in-raw-mode.patch |   83 -
 ...-mtd-nand-Qualcomm-NAND-controller-driver.patch | 2024 --------------------
 ...63-dt-bindings-qcom_nandc-Add-DT-bindings.patch |   82 -
 ...-dts-Add-NAND-controller-node-for-ipq806x.patch |   51 -
 ...nable-NAND-node-on-IPQ8064-AP148-platform.patch |   76 -
 ...h-qcom-dts-enable-qcom-smem-on-AP148-NAND.patch |   11 -
 .../167-ARM-qcom_rpm_fix_support_for_smb208.patch  |   50 -
 .../patches-4.4/168-ARM-qcom-add-smb208-DT.patch   |   74 -
 ...Support-adjusting-OPP-voltages-at-runtime.patch |  145 --
 ...call-dev_pm_opp_get_voltage-freq-RCU-free.patch |  114 --
 ...ufreq-dt-Handle-OPP-voltage-adjust-events.patch |  184 --
 ...ufreq-dt-Add-L2-frequency-scaling-support.patch |  161 --
 ...missing-rcu_read_lock-for-find_device_opp.patch |   33 -
 .../patches-4.4/175-add-regmap-mux-div.patch       |  386 ----
 ...com-Always-add-factor-clock-for-xo-clocks.patch |   53 -
 ...cpuidle-Add-cpuidle-support-for-QCOM-cpus.patch |   29 -
 .../300-arch-arm-force-ZRELADDR-on-arch-qcom.patch |   62 -
 .../302-mtd-qcom-smem-rename-rootfs-ubi.patch      |   13 -
 .../303-add-saw_l2-and-sns-into-ipq8064-DT.patch   |   41 -
 .../304-add-cpu-idle-state-into-ipq8064-DT.patch   |   58 -
 .../305-add-board-clocks-and-rpmcc-into-DT.patch   |   43 -
 .../patches-4.4/306-add-RPM-msg-RAM-into-DT.patch  |   22 -
 ...c-Added-the-enable-regs-and-mask-for-PRNG.patch |   25 -
 ...pq806x-Increase-Atomic-Coherent-Pool-size.patch |   52 -
 .../309-clk-gcc-add-tsens-child-node.patch         |   38 -
 .../310-add-necessary-thermal-data.patch           |  150 --
 .../patches-4.4/311-add-rpmcc-for-ipq806x.patch    |   81 -
 .../patches-4.4/315-disable-usb3-phy-suspend.patch |   36 -
 .../patches-4.4/316-dt-add-prng-support.patch      |   16 -
 .../ipq806x/patches-4.4/400-dsa-add-qca.patch      | 1068 -----------
 ...RM-dts-qcom-add-mdio-nodes-to-ap148-db149.patch |  146 --
 ...-qcom-add-gmac-nodes-to-ipq806x-platforms.patch |  216 ---
 ...-qup-Fix-fifo-and-dma-support-for-IPQ806x.patch |  129 --
 ...up-Make-sure-mode-is-only-determined-once.patch |  220 ---
 ...11-spi-qup-Fix-transaction-done-signaling.patch |   30 -
 .../711-stmmac-fix-ipq806x-DMA-configuration.patch |  117 --
 ...12-spi-qup-Fix-DMA-mode-to-work-correctly.patch |  221 ---
 ...-spi-qup-Fix-block-mode-to-work-correctly.patch |  312 ---
 ...-spi-qup-properly-detect-extra-interrupts.patch |   62 -
 ...-t-re-read-opflags-to-see-if-transaction-.patch |   27 -
 .../linux/ipq806x/patches-4.4/800-devicetree.patch |   29 -
 .../patches-4.4/801-override-compiler-flags.patch  |   11 -
 .../802-GPIO-add-named-gpio-exports.patch          |  166 --
 .../996-ATAG_DTB_COMPAT_CMDLINE_MANGLE.patch       |  185 --
 128 files changed, 22377 deletions(-)

diff --git a/target/linux/ipq806x/config-4.4 b/target/linux/ipq806x/config-4.4
deleted file mode 100644
index 898e32f..0000000
--- a/target/linux/ipq806x/config-4.4
+++ /dev/null
@@ -1,426 +0,0 @@
-CONFIG_ALIGNMENT_TRAP=y
-# CONFIG_AMBA_PL08X is not set
-CONFIG_APQ_GCC_8084=y
-CONFIG_APQ_MMCC_8084=y
-CONFIG_AR8216_PHY=y
-CONFIG_ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE=y
-CONFIG_ARCH_HAS_ELF_RANDOMIZE=y
-CONFIG_ARCH_HAS_GCOV_PROFILE_ALL=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_SELECT_MEMORY_MODEL is not set
-# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
-CONFIG_ARCH_SUPPORTS_ATOMIC_RMW=y
-CONFIG_ARCH_SUPPORTS_BIG_ENDIAN=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=y
-# CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_EXTEND is not set
-# CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_FROM_BOOTLOADER is not set
-CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_MANGLE=y
-CONFIG_ARM_CPU_SUSPEND=y
-# CONFIG_ARM_CPU_TOPOLOGY is not set
-CONFIG_ARM_GIC=y
-CONFIG_ARM_HAS_SG_CHAIN=y
-CONFIG_ARM_L1_CACHE_SHIFT=6
-CONFIG_ARM_L1_CACHE_SHIFT_6=y
-# CONFIG_ARM_LPAE is not set
-CONFIG_ARM_PATCH_PHYS_VIRT=y
-CONFIG_ARM_QCOM_CPUFREQ=y
-CONFIG_ARM_QCOM_CPUIDLE=y
-# CONFIG_ARM_SMMU is not set
-# 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_BLK_DEV_LOOP=y
-# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
-CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
-CONFIG_BOUNCE=y
-# CONFIG_CACHE_L2X0 is not set
-CONFIG_CLKDEV_LOOKUP=y
-CONFIG_CLKSRC_OF=y
-CONFIG_CLKSRC_PROBE=y
-CONFIG_CLKSRC_QCOM=y
-CONFIG_CLONE_BACKWARDS=y
-CONFIG_COMMON_CLK=y
-CONFIG_COMMON_CLK_QCOM=y
-CONFIG_CPUFREQ_DT=y
-CONFIG_CPU_32v6K=y
-CONFIG_CPU_32v7=y
-CONFIG_CPU_ABRT_EV7=y
-# CONFIG_CPU_BIG_ENDIAN is not set
-# 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_ONDEMAND=y
-# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set
-CONFIG_CPU_FREQ_GOV_COMMON=y
-# CONFIG_CPU_FREQ_GOV_CONSERVATIVE is not set
-CONFIG_CPU_FREQ_GOV_ONDEMAND=y
-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_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=y
-CONFIG_CPU_TLB_V7=y
-CONFIG_CPU_V7=y
-CONFIG_CRC16=y
-# CONFIG_CRC32_SARWATE is not set
-CONFIG_CRC32_SLICEBY8=y
-CONFIG_CRYPTO_DEFLATE=y
-CONFIG_CRYPTO_LZO=y
-CONFIG_CRYPTO_RNG2=y
-CONFIG_CRYPTO_WORKQUEUE=y
-CONFIG_DCACHE_WORD_ACCESS=y
-CONFIG_DEBUG_GPIO=y
-CONFIG_DEBUG_LL_INCLUDE="mach/debug-macro.S"
-# CONFIG_DEBUG_UART_8250 is not set
-# CONFIG_DEBUG_USER is not set
-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_SUNXI is not set
-# CONFIG_DW_DMAC_PCI is not set
-CONFIG_DYNAMIC_DEBUG=y
-CONFIG_EDAC_ATOMIC_SCRUB=y
-CONFIG_EDAC_SUPPORT=y
-CONFIG_ETHERNET_PACKET_MANGLE=y
-CONFIG_FIXED_PHY=y
-CONFIG_FIX_EARLYCON_MEM=y
-CONFIG_GENERIC_ALLOCATOR=y
-CONFIG_GENERIC_BUG=y
-CONFIG_GENERIC_CLOCKEVENTS=y
-CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y
-CONFIG_GENERIC_IDLE_POLL_SETUP=y
-CONFIG_GENERIC_IO=y
-CONFIG_GENERIC_IRQ_SHOW=y
-CONFIG_GENERIC_IRQ_SHOW_LEVEL=y
-CONFIG_GENERIC_MSI_IRQ=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_GENERIC_TIME_VSYSCALL=y
-CONFIG_GPIOLIB=y
-CONFIG_GPIOLIB_IRQCHIP=y
-CONFIG_GPIO_DEVRES=y
-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_BITREVERSE=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_IDE=y
-CONFIG_HAVE_IRQ_TIME_ACCOUNTING=y
-CONFIG_HAVE_MEMBLOCK=y
-CONFIG_HAVE_MOD_ARCH_SPECIFIC=y
-CONFIG_HAVE_NET_DSA=y
-CONFIG_HAVE_OPROFILE=y
-CONFIG_HAVE_OPTPROBES=y
-CONFIG_HAVE_PERF_EVENTS=y
-CONFIG_HAVE_PERF_REGS=y
-CONFIG_HAVE_PERF_USER_STACK_DUMP=y
-CONFIG_HAVE_PROC_CPU=y
-CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y
-CONFIG_HAVE_SMP=y
-CONFIG_HAVE_SYSCALL_TRACEPOINTS=y
-CONFIG_HAVE_UID16=y
-CONFIG_HAVE_VIRT_CPU_ACCOUNTING_GEN=y
-CONFIG_HIGHMEM=y
-# CONFIG_HIGHPTE is not set
-CONFIG_HWMON=y
-CONFIG_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_HELPER_AUTO=y
-CONFIG_I2C_QUP=y
-CONFIG_INITRAMFS_SOURCE=""
-CONFIG_IOMMU_HELPER=y
-# CONFIG_IOMMU_IO_PGTABLE_LPAE is not set
-CONFIG_IOMMU_SUPPORT=y
-CONFIG_IPQ_GCC_806X=y
-# CONFIG_IPQ_LCC_806X is not set
-CONFIG_IRQCHIP=y
-CONFIG_IRQ_DOMAIN=y
-CONFIG_IRQ_DOMAIN_HIERARCHY=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_LIBFDT=y
-CONFIG_LOCKUP_DETECTOR=y
-CONFIG_LOCK_SPIN_ON_OWNER=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_MMC=y
-CONFIG_MMC_ARMMMCI=y
-CONFIG_MMC_BLOCK=y
-CONFIG_MMC_BLOCK_MINORS=16
-CONFIG_MMC_QCOM_DML=y
-CONFIG_MMC_SDHCI=y
-CONFIG_MMC_SDHCI_MSM=y
-# CONFIG_MMC_SDHCI_PCI is not set
-CONFIG_MMC_SDHCI_PLTFM=y
-# CONFIG_MMC_TIFM_SD is not set
-CONFIG_MODULES_USE_ELF_REL=y
-CONFIG_MSM_GCC_8660=y
-# CONFIG_MSM_GCC_8916 is not set
-CONFIG_MSM_GCC_8960=y
-CONFIG_MSM_GCC_8974=y
-# CONFIG_MSM_LCC_8960 is not set
-CONFIG_MSM_MMCC_8960=y
-CONFIG_MSM_MMCC_8974=y
-CONFIG_MTD_CMDLINE_PARTS=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_DSA=y
-# CONFIG_NET_DSA_AR8XXX is not set
-CONFIG_NET_DSA_HWMON=y
-CONFIG_NET_FLOW_LIMIT=y
-CONFIG_NET_PTP_CLASSIFY=y
-CONFIG_NET_SWITCHDEV=y
-CONFIG_NO_BOOTMEM=y
-CONFIG_NO_HZ=y
-CONFIG_NO_HZ_COMMON=y
-CONFIG_NO_HZ_IDLE=y
-CONFIG_NR_CPUS=4
-CONFIG_NVMEM=y
-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_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_PAGE_OFFSET=0xC0000000
-CONFIG_PCI=y
-CONFIG_PCIEAER=y
-CONFIG_PCIEPORTBUS=y
-CONFIG_PCIE_DW=y
-CONFIG_PCIE_QCOM=y
-CONFIG_PCI_DEBUG=y
-CONFIG_PCI_DISABLE_COMMON_QUIRKS=y
-CONFIG_PCI_DOMAINS=y
-CONFIG_PCI_DOMAINS_GENERIC=y
-CONFIG_PCI_MSI=y
-CONFIG_PERF_USE_VMALLOC=y
-CONFIG_PGTABLE_LEVELS=2
-CONFIG_PHYLIB=y
-# CONFIG_PHY_QCOM_APQ8064_SATA is not set
-CONFIG_PHY_QCOM_IPQ806X_SATA=y
-# CONFIG_PHY_QCOM_UFS is not set
-CONFIG_PINCTRL=y
-CONFIG_PINCTRL_APQ8064=y
-# CONFIG_PINCTRL_APQ8084 is not set
-CONFIG_PINCTRL_IPQ8064=y
-CONFIG_PINCTRL_MSM=y
-# CONFIG_PINCTRL_MSM8660 is not set
-# CONFIG_PINCTRL_MSM8916 is not set
-# CONFIG_PINCTRL_MSM8960 is not set
-CONFIG_PINCTRL_MSM8X74=y
-# CONFIG_PINCTRL_QCOM_SPMI_PMIC is not set
-# CONFIG_PINCTRL_QCOM_SSBI_PMIC is not set
-# CONFIG_PL330_DMA is not set
-CONFIG_PM_OPP=y
-CONFIG_POWER_RESET=y
-CONFIG_POWER_RESET_MSM=y
-CONFIG_POWER_SUPPLY=y
-CONFIG_PPS=y
-CONFIG_PRINTK_TIME=y
-CONFIG_PTP_1588_CLOCK=y
-CONFIG_QCOM_ADM=y
-CONFIG_QCOM_BAM_DMA=y
-CONFIG_QCOM_CLK_RPM=y
-CONFIG_QCOM_GDSC=y
-CONFIG_QCOM_GSBI=y
-CONFIG_QCOM_HFPLL=y
-CONFIG_QCOM_PM=y
-CONFIG_QCOM_QFPROM=y
-CONFIG_QCOM_RPMCC=y
-CONFIG_QCOM_SCM=y
-CONFIG_QCOM_SCM_32=y
-# CONFIG_QCOM_SMD is not set
-CONFIG_QCOM_SMEM=y
-CONFIG_QCOM_TSENS=y
-CONFIG_QCOM_WDT=y
-CONFIG_RAS=y
-CONFIG_RATIONAL=y
-CONFIG_RCU_CPU_STALL_TIMEOUT=21
-CONFIG_RCU_STALL_COMMON=y
-CONFIG_REGMAP=y
-CONFIG_REGMAP_MMIO=y
-CONFIG_REGULATOR=y
-CONFIG_REGULATOR_FIXED_VOLTAGE=y
-CONFIG_REGULATOR_QCOM_RPM=y
-# CONFIG_REGULATOR_QCOM_SPMI 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_SCHED_INFO is not set
-# CONFIG_SCSI_DMA is not set
-CONFIG_SERIAL_8250_FSL=y
-# CONFIG_SERIAL_AMBA_PL010 is not set
-# CONFIG_SERIAL_AMBA_PL011 is not set
-CONFIG_SERIAL_MSM=y
-CONFIG_SERIAL_MSM_CONSOLE=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_SRCU=y
-CONFIG_STMMAC_ETH=y
-CONFIG_STMMAC_PLATFORM=y
-CONFIG_SWCONFIG=y
-CONFIG_SWCONFIG_LEDS=y
-CONFIG_SWIOTLB=y
-CONFIG_SWP_EMULATE=y
-CONFIG_SYS_SUPPORTS_APM_EMULATION=y
-CONFIG_THERMAL=y
-CONFIG_THERMAL_DEFAULT_GOV_STEP_WISE=y
-CONFIG_THERMAL_GOV_STEP_WISE=y
-CONFIG_THERMAL_HWMON=y
-CONFIG_THERMAL_OF=y
-# CONFIG_THUMB2_KERNEL is not set
-CONFIG_TICK_CPU_ACCOUNTING=y
-CONFIG_TREE_RCU=y
-CONFIG_UBIFS_FS=y
-CONFIG_UBIFS_FS_ADVANCED_COMPR=y
-CONFIG_UBIFS_FS_LZO=y
-CONFIG_UBIFS_FS_ZLIB=y
-CONFIG_UEVENT_HELPER_PATH=""
-CONFIG_UNCOMPRESS_INCLUDE="debug/uncompress.h"
-CONFIG_USB_SUPPORT=y
-CONFIG_USE_OF=y
-CONFIG_VDSO=y
-CONFIG_VECTORS_BASE=0xffff0000
-CONFIG_VFP=y
-CONFIG_VFPv3=y
-CONFIG_WATCHDOG_CORE=y
-# CONFIG_WATCHDOG_SYSFS is not set
-# CONFIG_WL_TI 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-4.4/001-add-API-register-brd-clks-bckwrds-cmptblt.patch b/target/linux/ipq806x/patches-4.4/001-add-API-register-brd-clks-bckwrds-cmptblt.patch
deleted file mode 100644
index b9056e9..0000000
--- a/target/linux/ipq806x/patches-4.4/001-add-API-register-brd-clks-bckwrds-cmptblt.patch
+++ /dev/null
@@ -1,135 +0,0 @@
-From ee15faffef11309219aa87a24efc86f6dd13f7cb Mon Sep 17 00:00:00 2001
-From: Stephen Boyd <sboyd at codeaurora.org>
-Date: Mon, 26 Oct 2015 17:11:32 -0700
-Subject: clk: qcom: common: Add API to register board clocks backwards
- compatibly
-
-We want to put the XO board clocks into the dt files, but we also
-need to be backwards compatible with an older dtb. Add an API to
-the common code to do this. This also makes a place for us to
-handle the case when the RPM clock driver is enabled and we don't
-want to register the fixed factor clock.
-
-Cc: Georgi Djakov <georgi.djakov at linaro.org>
-Signed-off-by: Stephen Boyd <sboyd at codeaurora.org>
----
- drivers/clk/qcom/common.c | 87 +++++++++++++++++++++++++++++++++++++++++++++++
- drivers/clk/qcom/common.h |  4 +++
- 2 files changed, 91 insertions(+)
-
---- a/drivers/clk/qcom/common.c
-+++ b/drivers/clk/qcom/common.c
-@@ -17,6 +17,7 @@
- #include <linux/platform_device.h>
- #include <linux/clk-provider.h>
- #include <linux/reset-controller.h>
-+#include <linux/of.h>
- 
- #include "common.h"
- #include "clk-rcg.h"
-@@ -88,6 +89,92 @@ static void qcom_cc_gdsc_unregister(void
- 	gdsc_unregister(data);
- }
- 
-+/*
-+ * Backwards compatibility with old DTs. Register a pass-through factor 1/1
-+ * clock to translate 'path' clk into 'name' clk and regsiter the 'path'
-+ * clk as a fixed rate clock if it isn't present.
-+ */
-+static int _qcom_cc_register_board_clk(struct device *dev, const char *path,
-+				       const char *name, unsigned long rate,
-+				       bool add_factor)
-+{
-+	struct device_node *node = NULL;
-+	struct device_node *clocks_node;
-+	struct clk_fixed_factor *factor;
-+	struct clk_fixed_rate *fixed;
-+	struct clk *clk;
-+	struct clk_init_data init_data = { };
-+
-+	clocks_node = of_find_node_by_path("/clocks");
-+	if (clocks_node)
-+		node = of_find_node_by_name(clocks_node, path);
-+	of_node_put(clocks_node);
-+
-+	if (!node) {
-+		fixed = devm_kzalloc(dev, sizeof(*fixed), GFP_KERNEL);
-+		if (!fixed)
-+			return -EINVAL;
-+
-+		fixed->fixed_rate = rate;
-+		fixed->hw.init = &init_data;
-+
-+		init_data.name = path;
-+		init_data.flags = CLK_IS_ROOT;
-+		init_data.ops = &clk_fixed_rate_ops;
-+
-+		clk = devm_clk_register(dev, &fixed->hw);
-+		if (IS_ERR(clk))
-+			return PTR_ERR(clk);
-+	}
-+	of_node_put(node);
-+
-+	if (add_factor) {
-+		factor = devm_kzalloc(dev, sizeof(*factor), GFP_KERNEL);
-+		if (!factor)
-+			return -EINVAL;
-+
-+		factor->mult = factor->div = 1;
-+		factor->hw.init = &init_data;
-+
-+		init_data.name = name;
-+		init_data.parent_names = &path;
-+		init_data.num_parents = 1;
-+		init_data.flags = 0;
-+		init_data.ops = &clk_fixed_factor_ops;
-+
-+		clk = devm_clk_register(dev, &factor->hw);
-+		if (IS_ERR(clk))
-+			return PTR_ERR(clk);
-+	}
-+
-+	return 0;
-+}
-+
-+int qcom_cc_register_board_clk(struct device *dev, const char *path,
-+			       const char *name, unsigned long rate)
-+{
-+	bool add_factor = true;
-+	struct device_node *node;
-+
-+	/* The RPM clock driver will add the factor clock if present */
-+	if (IS_ENABLED(CONFIG_QCOM_RPMCC)) {
-+		node = of_find_compatible_node(NULL, NULL, "qcom,rpmcc");
-+		if (of_device_is_available(node))
-+			add_factor = false;
-+		of_node_put(node);
-+	}
-+
-+	return _qcom_cc_register_board_clk(dev, path, name, rate, add_factor);
-+}
-+EXPORT_SYMBOL_GPL(qcom_cc_register_board_clk);
-+
-+int qcom_cc_register_sleep_clk(struct device *dev)
-+{
-+	return _qcom_cc_register_board_clk(dev, "sleep_clk", "sleep_clk_src",
-+					   32768, true);
-+}
-+EXPORT_SYMBOL_GPL(qcom_cc_register_sleep_clk);
-+
- int qcom_cc_really_probe(struct platform_device *pdev,
- 			 const struct qcom_cc_desc *desc, struct regmap *regmap)
- {
---- a/drivers/clk/qcom/common.h
-+++ b/drivers/clk/qcom/common.h
-@@ -37,6 +37,10 @@ extern const struct freq_tbl *qcom_find_
- extern int qcom_find_src_index(struct clk_hw *hw, const struct parent_map *map,
- 			       u8 src);
- 
-+extern int qcom_cc_register_board_clk(struct device *dev, const char *path,
-+				      const char *name, unsigned long rate);
-+extern int qcom_cc_register_sleep_clk(struct device *dev);
-+
- extern struct regmap *qcom_cc_map(struct platform_device *pdev,
- 				  const struct qcom_cc_desc *desc);
- extern int qcom_cc_really_probe(struct platform_device *pdev,
diff --git a/target/linux/ipq806x/patches-4.4/002-make-reset-control-ops-const.patch b/target/linux/ipq806x/patches-4.4/002-make-reset-control-ops-const.patch
deleted file mode 100644
index 6261125..0000000
--- a/target/linux/ipq806x/patches-4.4/002-make-reset-control-ops-const.patch
+++ /dev/null
@@ -1,35 +0,0 @@
-From add479eeb1a208a31ab913ae7c97506a81383079 Mon Sep 17 00:00:00 2001
-From: Philipp Zabel <p.zabel at pengutronix.de>
-Date: Thu, 25 Feb 2016 10:45:12 +0100
-Subject: clk: qcom: Make reset_control_ops const
-
-The qcom_reset_ops structure is never modified. Make it const.
-
-Signed-off-by: Philipp Zabel <p.zabel at pengutronix.de>
-Signed-off-by: Stephen Boyd <sboyd at codeaurora.org>
----
- drivers/clk/qcom/reset.c | 2 +-
- drivers/clk/qcom/reset.h | 2 +-
- 2 files changed, 2 insertions(+), 2 deletions(-)
-
---- a/drivers/clk/qcom/reset.c
-+++ b/drivers/clk/qcom/reset.c
-@@ -55,7 +55,7 @@ qcom_reset_deassert(struct reset_control
- 	return regmap_update_bits(rst->regmap, map->reg, mask, 0);
- }
- 
--struct reset_control_ops qcom_reset_ops = {
-+const struct reset_control_ops qcom_reset_ops = {
- 	.reset = qcom_reset,
- 	.assert = qcom_reset_assert,
- 	.deassert = qcom_reset_deassert,
---- a/drivers/clk/qcom/reset.h
-+++ b/drivers/clk/qcom/reset.h
-@@ -32,6 +32,6 @@ struct qcom_reset_controller {
- #define to_qcom_reset_controller(r) \
- 	container_of(r, struct qcom_reset_controller, rcdev);
- 
--extern struct reset_control_ops qcom_reset_ops;
-+extern const struct reset_control_ops qcom_reset_ops;
- 
- #endif
diff --git a/target/linux/ipq806x/patches-4.4/003-mv-cxo-pxo-xo-into-DT.patch b/target/linux/ipq806x/patches-4.4/003-mv-cxo-pxo-xo-into-DT.patch
deleted file mode 100644
index 4932e70..0000000
--- a/target/linux/ipq806x/patches-4.4/003-mv-cxo-pxo-xo-into-DT.patch
+++ /dev/null
@@ -1,172 +0,0 @@
-From a085f877a882b465fce74188c9d8efd12bd5acd4 Mon Sep 17 00:00:00 2001
-From: Stephen Boyd <sboyd at codeaurora.org>
-Date: Mon, 26 Oct 2015 18:10:09 -0700
-Subject: clk: qcom: Move cxo/pxo/xo into dt files
-
-Put these clocks into the dt files instead of registering them
-from C code. This provides a few benefits. It allows us to
-specify the frequency of these clocks at the board level instead
-of hard-coding them in the driver. It allows us to insert an RPM
-clock in between the consumers of the crystals and the actual
-clock. And finally, it helps us transition the GCC driver to use
-RPM clocks when that configuration is enabled.
-
-Cc: Georgi Djakov <georgi.djakov at linaro.org>
-Signed-off-by: Stephen Boyd <sboyd at codeaurora.org>
----
- drivers/clk/qcom/gcc-apq8084.c | 16 +++++++---------
- drivers/clk/qcom/gcc-ipq806x.c | 14 ++++++--------
- drivers/clk/qcom/gcc-msm8660.c | 15 +++++++--------
- drivers/clk/qcom/gcc-msm8960.c | 14 ++++++--------
- drivers/clk/qcom/gcc-msm8974.c | 17 +++++++----------
- 5 files changed, 33 insertions(+), 43 deletions(-)
-
---- a/drivers/clk/qcom/gcc-apq8084.c
-+++ b/drivers/clk/qcom/gcc-apq8084.c
-@@ -3607,18 +3607,16 @@ MODULE_DEVICE_TABLE(of, gcc_apq8084_matc
- 
- static int gcc_apq8084_probe(struct platform_device *pdev)
- {
--	struct clk *clk;
-+	int ret;
- 	struct device *dev = &pdev->dev;
- 
--	/* Temporary until RPM clocks supported */
--	clk = clk_register_fixed_rate(dev, "xo", NULL, CLK_IS_ROOT, 19200000);
--	if (IS_ERR(clk))
--		return PTR_ERR(clk);
-+	ret = qcom_cc_register_board_clk(dev, "xo_board", "xo", 19200000);
-+	if (ret)
-+		return ret;
- 
--	clk = clk_register_fixed_rate(dev, "sleep_clk_src", NULL,
--				      CLK_IS_ROOT, 32768);
--	if (IS_ERR(clk))
--		return PTR_ERR(clk);
-+	ret = qcom_cc_register_sleep_clk(dev);
-+	if (ret)
-+		return ret;
- 
- 	return qcom_cc_probe(pdev, &gcc_apq8084_desc);
- }
---- a/drivers/clk/qcom/gcc-ipq806x.c
-+++ b/drivers/clk/qcom/gcc-ipq806x.c
-@@ -3023,19 +3023,17 @@ MODULE_DEVICE_TABLE(of, gcc_ipq806x_matc
- 
- static int gcc_ipq806x_probe(struct platform_device *pdev)
- {
--	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);
--	if (IS_ERR(clk))
--		return PTR_ERR(clk);
-+	ret = qcom_cc_register_board_clk(dev, "cxo_board", "cxo", 25000000);
-+	if (ret)
-+		return ret;
- 
--	clk = clk_register_fixed_rate(dev, "pxo", NULL, CLK_IS_ROOT, 25000000);
--	if (IS_ERR(clk))
--		return PTR_ERR(clk);
-+	ret = qcom_cc_register_board_clk(dev, "pxo_board", "pxo", 25000000);
-+	if (ret)
-+		return ret;
- 
- 	ret = qcom_cc_probe(pdev, &gcc_ipq806x_desc);
- 	if (ret)
---- a/drivers/clk/qcom/gcc-msm8660.c
-+++ b/drivers/clk/qcom/gcc-msm8660.c
-@@ -2720,17 +2720,16 @@ MODULE_DEVICE_TABLE(of, gcc_msm8660_matc
- 
- static int gcc_msm8660_probe(struct platform_device *pdev)
- {
--	struct clk *clk;
-+	int ret;
- 	struct device *dev = &pdev->dev;
- 
--	/* Temporary until RPM clocks supported */
--	clk = clk_register_fixed_rate(dev, "cxo", NULL, CLK_IS_ROOT, 19200000);
--	if (IS_ERR(clk))
--		return PTR_ERR(clk);
-+	ret = qcom_cc_register_board_clk(dev, "cxo_board", "cxo", 19200000);
-+	if (ret)
-+		return ret;
- 
--	clk = clk_register_fixed_rate(dev, "pxo", NULL, CLK_IS_ROOT, 27000000);
--	if (IS_ERR(clk))
--		return PTR_ERR(clk);
-+	ret = qcom_cc_register_board_clk(dev, "pxo_board", "pxo", 27000000);
-+	if (ret)
-+		return ret;
- 
- 	return qcom_cc_probe(pdev, &gcc_msm8660_desc);
- }
---- a/drivers/clk/qcom/gcc-msm8960.c
-+++ b/drivers/clk/qcom/gcc-msm8960.c
-@@ -3503,7 +3503,6 @@ MODULE_DEVICE_TABLE(of, gcc_msm8960_matc
- 
- static int gcc_msm8960_probe(struct platform_device *pdev)
- {
--	struct clk *clk;
- 	struct device *dev = &pdev->dev;
- 	const struct of_device_id *match;
- 	struct platform_device *tsens;
-@@ -3513,14 +3512,13 @@ static int gcc_msm8960_probe(struct plat
- 	if (!match)
- 		return -EINVAL;
- 
--	/* Temporary until RPM clocks supported */
--	clk = clk_register_fixed_rate(dev, "cxo", NULL, CLK_IS_ROOT, 19200000);
--	if (IS_ERR(clk))
--		return PTR_ERR(clk);
-+	ret = qcom_cc_register_board_clk(dev, "cxo_board", "cxo", 19200000);
-+	if (ret)
-+		return ret;
- 
--	clk = clk_register_fixed_rate(dev, "pxo", NULL, CLK_IS_ROOT, 27000000);
--	if (IS_ERR(clk))
--		return PTR_ERR(clk);
-+	ret = qcom_cc_register_board_clk(dev, "pxo_board", "pxo", 27000000);
-+	if (ret)
-+		return ret;
- 
- 	ret = qcom_cc_probe(pdev, match->data);
- 	if (ret)
---- a/drivers/clk/qcom/gcc-msm8974.c
-+++ b/drivers/clk/qcom/gcc-msm8974.c
-@@ -2717,7 +2717,7 @@ static void msm8974_pro_clock_override(v
- 
- static int gcc_msm8974_probe(struct platform_device *pdev)
- {
--	struct clk *clk;
-+	int ret;
- 	struct device *dev = &pdev->dev;
- 	bool pro;
- 	const struct of_device_id *id;
-@@ -2730,16 +2730,13 @@ static int gcc_msm8974_probe(struct plat
- 	if (pro)
- 		msm8974_pro_clock_override();
- 
--	/* Temporary until RPM clocks supported */
--	clk = clk_register_fixed_rate(dev, "xo", NULL, CLK_IS_ROOT, 19200000);
--	if (IS_ERR(clk))
--		return PTR_ERR(clk);
--
--	/* Should move to DT node? */
--	clk = clk_register_fixed_rate(dev, "sleep_clk_src", NULL,
--				      CLK_IS_ROOT, 32768);
--	if (IS_ERR(clk))
--		return PTR_ERR(clk);
-+	ret = qcom_cc_register_board_clk(dev, "xo_board", "xo", 19200000);
-+	if (ret)
-+		return ret;
-+
-+	ret = qcom_cc_register_sleep_clk(dev);
-+	if (ret)
-+		return ret;
- 
- 	return qcom_cc_probe(pdev, &gcc_msm8974_desc);
- }
diff --git a/target/linux/ipq806x/patches-4.4/005-mfd-qcom_rpm-Add-missing-of_node_put-after-calling-of_parse_phandle.patch b/target/linux/ipq806x/patches-4.4/005-mfd-qcom_rpm-Add-missing-of_node_put-after-calling-of_parse_phandle.patch
deleted file mode 100644
index b3cef7b..0000000
--- a/target/linux/ipq806x/patches-4.4/005-mfd-qcom_rpm-Add-missing-of_node_put-after-calling-of_parse_phandle.patch
+++ /dev/null
@@ -1,25 +0,0 @@
-From 349290fc9e761aaef6d6882721189f668ec5ff49 Mon Sep 17 00:00:00 2001
-From: Peter Chen <peter.chen at nxp.com>
-Date: Fri, 15 Jul 2016 17:38:46 +0800
-Subject: mfd: qcom_rpm: Add missing of_node_put after calling of_parse_phandle
-
-of_node_put needs to be called when the device node which is got
-from of_parse_phandle has finished using.
-
-Signed-off-by: Peter Chen <peter.chen at nxp.com>
-Reviewed-by: Bjorn Andersson <bjorn.andersson at linaro.org>
-Signed-off-by: Lee Jones <lee.jones at linaro.org>
----
- drivers/mfd/qcom_rpm.c | 1 +
- 1 file changed, 1 insertion(+)
-
---- a/drivers/mfd/qcom_rpm.c
-+++ b/drivers/mfd/qcom_rpm.c
-@@ -538,6 +538,7 @@ static int qcom_rpm_probe(struct platfor
- 	}
- 
- 	rpm->ipc_regmap = syscon_node_to_regmap(syscon_np);
-+	of_node_put(syscon_np);
- 	if (IS_ERR(rpm->ipc_regmap))
- 		return PTR_ERR(rpm->ipc_regmap);
- 
diff --git a/target/linux/ipq806x/patches-4.4/006-mfd-qcom_rpm-Handle-message-RAM-clock.patch b/target/linux/ipq806x/patches-4.4/006-mfd-qcom_rpm-Handle-message-RAM-clock.patch
deleted file mode 100644
index 96b768d..0000000
--- a/target/linux/ipq806x/patches-4.4/006-mfd-qcom_rpm-Handle-message-RAM-clock.patch
+++ /dev/null
@@ -1,90 +0,0 @@
-From 3526403353c2a1b94c3181f900582626d23c339b Mon Sep 17 00:00:00 2001
-From: Linus Walleij <linus.walleij at linaro.org>
-Date: Thu, 18 Aug 2016 20:40:45 +0200
-Subject: mfd: qcom_rpm: Handle message RAM clock
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-The MSM8660, APQ8060, IPQ806x and MSM8960 have a GCC clock
-to the message RAM used by the RPM. This needs to be enabled
-for messages to pass through. This is a crude solution that
-simply prepare/enable at probe() and disable/unprepare
-at remove(). More elaborate PM is probably possible to
-add later.
-
-The construction uses IS_ERR() to gracefully handle the
-platforms that do not provide a message RAM clock. It will
-bail out of probe only if the clock is hitting a probe
-deferral situation.
-
-Of course this requires the proper device tree set-up:
-
-rpm: rpm at 104000 {
-    compatible = "qcom,rpm-msm8660";
-    clocks = <&gcc RPM_MSG_RAM_H_CLK>;
-    clock-names = "ram";
-    ...
-};
-
-I have provided this in the MSM8660 device tree, and will
-provide patches for the other targets.
-
-Cc: Björn Andersson <bjorn.andersson at linaro.org>
-Signed-off-by: Linus Walleij <linus.walleij at linaro.org>
-Signed-off-by: Lee Jones <lee.jones at linaro.org>
----
- drivers/mfd/qcom_rpm.c | 20 ++++++++++++++++++++
- 1 file changed, 20 insertions(+)
-
---- a/drivers/mfd/qcom_rpm.c
-+++ b/drivers/mfd/qcom_rpm.c
-@@ -21,6 +21,7 @@
- #include <linux/mfd/qcom_rpm.h>
- #include <linux/mfd/syscon.h>
- #include <linux/regmap.h>
-+#include <linux/clk.h>
- 
- #include <dt-bindings/mfd/qcom-rpm.h>
- 
-@@ -48,6 +49,7 @@ struct qcom_rpm {
- 	struct regmap *ipc_regmap;
- 	unsigned ipc_offset;
- 	unsigned ipc_bit;
-+	struct clk *ramclk;
- 
- 	struct completion ack;
- 	struct mutex lock;
-@@ -503,6 +505,20 @@ static int qcom_rpm_probe(struct platfor
- 	mutex_init(&rpm->lock);
- 	init_completion(&rpm->ack);
- 
-+	/* Enable message RAM clock */
-+	rpm->ramclk = devm_clk_get(&pdev->dev, "ram");
-+	if (IS_ERR(rpm->ramclk)) {
-+		ret = PTR_ERR(rpm->ramclk);
-+		if (ret == -EPROBE_DEFER)
-+			return ret;
-+		/*
-+		 * Fall through in all other cases, as the clock is
-+		 * optional. (Does not exist on all platforms.)
-+		 */
-+		rpm->ramclk = NULL;
-+	}
-+	clk_prepare_enable(rpm->ramclk); /* Accepts NULL */
-+
- 	irq_ack = platform_get_irq_byname(pdev, "ack");
- 	if (irq_ack < 0) {
- 		dev_err(&pdev->dev, "required ack interrupt missing\n");
-@@ -621,7 +637,11 @@ static int qcom_rpm_probe(struct platfor
- 
- static int qcom_rpm_remove(struct platform_device *pdev)
- {
-+	struct qcom_rpm *rpm = dev_get_drvdata(&pdev->dev);
-+
- 	of_platform_depopulate(&pdev->dev);
-+	clk_disable_unprepare(rpm->ramclk);
-+
- 	return 0;
- }
- 
diff --git a/target/linux/ipq806x/patches-4.4/009-1-watchdog-core-add-restart-handler-support.patch b/target/linux/ipq806x/patches-4.4/009-1-watchdog-core-add-restart-handler-support.patch
deleted file mode 100644
index 0534e78..0000000
--- a/target/linux/ipq806x/patches-4.4/009-1-watchdog-core-add-restart-handler-support.patch
+++ /dev/null
@@ -1,205 +0,0 @@
-From 2165bf524da5f5e496d1cdb8c5afae1345ecce1e Mon Sep 17 00:00:00 2001
-From: Damien Riegel <damien.riegel at savoirfairelinux.com>
-Date: Mon, 16 Nov 2015 12:27:59 -0500
-Subject: watchdog: core: add restart handler support
-
-Many watchdog drivers implement the same code to register a restart
-handler. This patch provides a generic way to set such a function.
-
-The patch adds a new restart watchdog operation. If a restart priority
-greater than 0 is needed, the driver can call
-watchdog_set_restart_priority to set it.
-
-Suggested-by: Vivien Didelot <vivien.didelot at savoirfairelinux.com>
-Signed-off-by: Damien Riegel <damien.riegel at savoirfairelinux.com>
-Reviewed-by: Guenter Roeck <linux at roeck-us.net>
-Reviewed-by: Vivien Didelot <vivien.didelot at savoirfairelinux.com>
-Signed-off-by: Guenter Roeck <linux at roeck-us.net>
-Signed-off-by: Wim Van Sebroeck <wim at iguana.be>
----
- Documentation/watchdog/watchdog-kernel-api.txt | 19 ++++++++++
- drivers/watchdog/watchdog_core.c               | 48 ++++++++++++++++++++++++++
- include/linux/watchdog.h                       |  6 ++++
- 3 files changed, 73 insertions(+)
-
---- a/Documentation/watchdog/watchdog-kernel-api.txt
-+++ b/Documentation/watchdog/watchdog-kernel-api.txt
-@@ -53,6 +53,7 @@ struct watchdog_device {
- 	unsigned int timeout;
- 	unsigned int min_timeout;
- 	unsigned int max_timeout;
-+	struct notifier_block restart_nb;
- 	void *driver_data;
- 	struct mutex lock;
- 	unsigned long status;
-@@ -75,6 +76,10 @@ It contains following fields:
- * timeout: the watchdog timer's timeout value (in seconds).
- * min_timeout: the watchdog timer's minimum timeout value (in seconds).
- * max_timeout: the watchdog timer's maximum timeout value (in seconds).
-+* restart_nb: notifier block that is registered for machine restart, for
-+  internal use only. If a watchdog is capable of restarting the machine, it
-+  should define ops->restart. Priority can be changed through
-+  watchdog_set_restart_priority.
- * bootstatus: status of the device after booting (reported with watchdog
-   WDIOF_* status bits).
- * driver_data: a pointer to the drivers private data of a watchdog device.
-@@ -100,6 +105,7 @@ struct watchdog_ops {
- 	unsigned int (*status)(struct watchdog_device *);
- 	int (*set_timeout)(struct watchdog_device *, unsigned int);
- 	unsigned int (*get_timeleft)(struct watchdog_device *);
-+	int (*restart)(struct watchdog_device *);
- 	void (*ref)(struct watchdog_device *);
- 	void (*unref)(struct watchdog_device *);
- 	long (*ioctl)(struct watchdog_device *, unsigned int, unsigned long);
-@@ -164,6 +170,8 @@ they are supported. These optional routi
-   (Note: the WDIOF_SETTIMEOUT needs to be set in the options field of the
-   watchdog's info structure).
- * get_timeleft: this routines returns the time that's left before a reset.
-+* restart: this routine restarts the machine. It returns 0 on success or a
-+  negative errno code for failure.
- * ref: the operation that calls kref_get on the kref of a dynamically
-   allocated watchdog_device struct.
- * unref: the operation that calls kref_put on the kref of a dynamically
-@@ -231,3 +239,14 @@ the device tree (if the module timeout p
- to set the default timeout value as timeout value in the watchdog_device and
- then use this function to set the user "preferred" timeout value.
- This routine returns zero on success and a negative errno code for failure.
-+
-+To change the priority of the restart handler the following helper should be
-+used:
-+
-+void watchdog_set_restart_priority(struct watchdog_device *wdd, int priority);
-+
-+User should follow the following guidelines for setting the priority:
-+* 0: should be called in last resort, has limited restart capabilities
-+* 128: default restart handler, use if no other handler is expected to be
-+  available, and/or if restart is sufficient to restart the entire system
-+* 255: highest priority, will preempt all other restart handlers
---- a/drivers/watchdog/watchdog_core.c
-+++ b/drivers/watchdog/watchdog_core.c
-@@ -32,6 +32,7 @@
- #include <linux/types.h>	/* For standard types */
- #include <linux/errno.h>	/* For the -ENODEV/... values */
- #include <linux/kernel.h>	/* For printk/panic/... */
-+#include <linux/reboot.h>	/* For restart handler */
- #include <linux/watchdog.h>	/* For watchdog specific items */
- #include <linux/init.h>		/* For __init/__exit/... */
- #include <linux/idr.h>		/* For ida_* macros */
-@@ -137,6 +138,41 @@ int watchdog_init_timeout(struct watchdo
- }
- EXPORT_SYMBOL_GPL(watchdog_init_timeout);
- 
-+static int watchdog_restart_notifier(struct notifier_block *nb,
-+				     unsigned long action, void *data)
-+{
-+	struct watchdog_device *wdd = container_of(nb, struct watchdog_device,
-+						   restart_nb);
-+
-+	int ret;
-+
-+	ret = wdd->ops->restart(wdd);
-+	if (ret)
-+		return NOTIFY_BAD;
-+
-+	return NOTIFY_DONE;
-+}
-+
-+/**
-+ * watchdog_set_restart_priority - Change priority of restart handler
-+ * @wdd: watchdog device
-+ * @priority: priority of the restart handler, should follow these guidelines:
-+ *   0:   use watchdog's restart function as last resort, has limited restart
-+ *        capabilies
-+ *   128: default restart handler, use if no other handler is expected to be
-+ *        available and/or if restart is sufficient to restart the entire system
-+ *   255: preempt all other handlers
-+ *
-+ * If a wdd->ops->restart function is provided when watchdog_register_device is
-+ * called, it will be registered as a restart handler with the priority given
-+ * here.
-+ */
-+void watchdog_set_restart_priority(struct watchdog_device *wdd, int priority)
-+{
-+	wdd->restart_nb.priority = priority;
-+}
-+EXPORT_SYMBOL_GPL(watchdog_set_restart_priority);
-+
- static int __watchdog_register_device(struct watchdog_device *wdd)
- {
- 	int ret, id = -1, devno;
-@@ -202,6 +238,15 @@ static int __watchdog_register_device(st
- 		return ret;
- 	}
- 
-+	if (wdd->ops->restart) {
-+		wdd->restart_nb.notifier_call = watchdog_restart_notifier;
-+
-+		ret = register_restart_handler(&wdd->restart_nb);
-+		if (ret)
-+			dev_warn(wdd->dev, "Cannot register restart handler (%d)\n",
-+				 ret);
-+	}
-+
- 	return 0;
- }
- 
-@@ -238,6 +283,9 @@ static void __watchdog_unregister_device
- 	if (wdd == NULL)
- 		return;
- 
-+	if (wdd->ops->restart)
-+		unregister_restart_handler(&wdd->restart_nb);
-+
- 	devno = wdd->cdev.dev;
- 	ret = watchdog_dev_unregister(wdd);
- 	if (ret)
---- a/include/linux/watchdog.h
-+++ b/include/linux/watchdog.h
-@@ -12,6 +12,7 @@
- #include <linux/bitops.h>
- #include <linux/device.h>
- #include <linux/cdev.h>
-+#include <linux/notifier.h>
- #include <uapi/linux/watchdog.h>
- 
- struct watchdog_ops;
-@@ -26,6 +27,7 @@ struct watchdog_device;
-  * @status:	The routine that shows the status of the watchdog device.
-  * @set_timeout:The routine for setting the watchdog devices timeout value (in seconds).
-  * @get_timeleft:The routine that gets the time left before a reset (in seconds).
-+ * @restart:	The routine for restarting the machine.
-  * @ref:	The ref operation for dyn. allocated watchdog_device structs
-  * @unref:	The unref operation for dyn. allocated watchdog_device structs
-  * @ioctl:	The routines that handles extra ioctl calls.
-@@ -45,6 +47,7 @@ struct watchdog_ops {
- 	unsigned int (*status)(struct watchdog_device *);
- 	int (*set_timeout)(struct watchdog_device *, unsigned int);
- 	unsigned int (*get_timeleft)(struct watchdog_device *);
-+	int (*restart)(struct watchdog_device *);
- 	void (*ref)(struct watchdog_device *);
- 	void (*unref)(struct watchdog_device *);
- 	long (*ioctl)(struct watchdog_device *, unsigned int, unsigned long);
-@@ -62,6 +65,7 @@ struct watchdog_ops {
-  * @timeout:	The watchdog devices timeout value (in seconds).
-  * @min_timeout:The watchdog devices minimum timeout value (in seconds).
-  * @max_timeout:The watchdog devices maximum timeout value (in seconds).
-+ * @restart_nb:	The notifier block to register a restart function.
-  * @driver-data:Pointer to the drivers private data.
-  * @lock:	Lock for watchdog core internal use only.
-  * @status:	Field that contains the devices internal status bits.
-@@ -88,6 +92,7 @@ struct watchdog_device {
- 	unsigned int timeout;
- 	unsigned int min_timeout;
- 	unsigned int max_timeout;
-+	struct notifier_block restart_nb;
- 	void *driver_data;
- 	struct mutex lock;
- 	unsigned long status;
-@@ -142,6 +147,7 @@ static inline void *watchdog_get_drvdata
- }
- 
- /* drivers/watchdog/watchdog_core.c */
-+void watchdog_set_restart_priority(struct watchdog_device *wdd, int priority);
- extern int watchdog_init_timeout(struct watchdog_device *wdd,
- 				  unsigned int timeout_parm, struct device *dev);
- extern int watchdog_register_device(struct watchdog_device *);
diff --git a/target/linux/ipq806x/patches-4.4/009-2-watchdog-core-add-reboot-notifier-support.patch b/target/linux/ipq806x/patches-4.4/009-2-watchdog-core-add-reboot-notifier-support.patch
deleted file mode 100644
index 2afa4e5..0000000
--- a/target/linux/ipq806x/patches-4.4/009-2-watchdog-core-add-reboot-notifier-support.patch
+++ /dev/null
@@ -1,160 +0,0 @@
-From e131319669e0ef5e6fcd75174daeffa40492135c Mon Sep 17 00:00:00 2001
-From: Damien Riegel <damien.riegel at savoirfairelinux.com>
-Date: Fri, 20 Nov 2015 16:54:51 -0500
-Subject: watchdog: core: add reboot notifier support
-
-Many watchdog drivers register a reboot notifier in order to stop the
-watchdog on system reboot. Thus we can factorize this code in the
-watchdog core.
-
-For that purpose, a new notifier block is added in watchdog_device for
-internal use only, as well as a new watchdog_stop_on_reboot helper
-function.
-
-If this helper is called, watchdog core registers the related notifier
-block and will stop the watchdog when SYS_HALT or SYS_DOWN is received.
-
-Since this operation can be critical on some platforms, abort the device
-registration if the reboot notifier registration fails.
-
-Suggested-by: Vivien Didelot <vivien.didelot at savoirfairelinux.com>
-Signed-off-by: Damien Riegel <damien.riegel at savoirfairelinux.com>
-Reviewed-by: Vivien Didelot <vivien.didelot at savoirfairelinux.com>
-Signed-off-by: Guenter Roeck <linux at roeck-us.net>
-Signed-off-by: Wim Van Sebroeck <wim at iguana.be>
----
- Documentation/watchdog/watchdog-kernel-api.txt |  8 ++++++
- drivers/watchdog/watchdog_core.c               | 37 ++++++++++++++++++++++++++
- include/linux/watchdog.h                       |  9 +++++++
- 3 files changed, 54 insertions(+)
-
---- a/Documentation/watchdog/watchdog-kernel-api.txt
-+++ b/Documentation/watchdog/watchdog-kernel-api.txt
-@@ -53,6 +53,7 @@ struct watchdog_device {
- 	unsigned int timeout;
- 	unsigned int min_timeout;
- 	unsigned int max_timeout;
-+	struct notifier_block reboot_nb;
- 	struct notifier_block restart_nb;
- 	void *driver_data;
- 	struct mutex lock;
-@@ -76,6 +77,9 @@ It contains following fields:
- * timeout: the watchdog timer's timeout value (in seconds).
- * min_timeout: the watchdog timer's minimum timeout value (in seconds).
- * max_timeout: the watchdog timer's maximum timeout value (in seconds).
-+* reboot_nb: notifier block that is registered for reboot notifications, for
-+  internal use only. If the driver calls watchdog_stop_on_reboot, watchdog core
-+  will stop the watchdog on such notifications.
- * restart_nb: notifier block that is registered for machine restart, for
-   internal use only. If a watchdog is capable of restarting the machine, it
-   should define ops->restart. Priority can be changed through
-@@ -240,6 +244,10 @@ to set the default timeout value as time
- then use this function to set the user "preferred" timeout value.
- This routine returns zero on success and a negative errno code for failure.
- 
-+To disable the watchdog on reboot, the user must call the following helper:
-+
-+static inline void watchdog_stop_on_reboot(struct watchdog_device *wdd);
-+
- To change the priority of the restart handler the following helper should be
- used:
- 
---- a/drivers/watchdog/watchdog_core.c
-+++ b/drivers/watchdog/watchdog_core.c
-@@ -138,6 +138,25 @@ int watchdog_init_timeout(struct watchdo
- }
- EXPORT_SYMBOL_GPL(watchdog_init_timeout);
- 
-+static int watchdog_reboot_notifier(struct notifier_block *nb,
-+				    unsigned long code, void *data)
-+{
-+	struct watchdog_device *wdd = container_of(nb, struct watchdog_device,
-+						   reboot_nb);
-+
-+	if (code == SYS_DOWN || code == SYS_HALT) {
-+		if (watchdog_active(wdd)) {
-+			int ret;
-+
-+			ret = wdd->ops->stop(wdd);
-+			if (ret)
-+				return NOTIFY_BAD;
-+		}
-+	}
-+
-+	return NOTIFY_DONE;
-+}
-+
- static int watchdog_restart_notifier(struct notifier_block *nb,
- 				     unsigned long action, void *data)
- {
-@@ -238,6 +257,21 @@ static int __watchdog_register_device(st
- 		return ret;
- 	}
- 
-+	if (test_bit(WDOG_STOP_ON_REBOOT, &wdd->status)) {
-+		wdd->reboot_nb.notifier_call = watchdog_reboot_notifier;
-+
-+		ret = register_reboot_notifier(&wdd->reboot_nb);
-+		if (ret) {
-+			dev_err(wdd->dev, "Cannot register reboot notifier (%d)\n",
-+				ret);
-+			watchdog_dev_unregister(wdd);
-+			device_destroy(watchdog_class, devno);
-+			ida_simple_remove(&watchdog_ida, wdd->id);
-+			wdd->dev = NULL;
-+			return ret;
-+		}
-+	}
-+
- 	if (wdd->ops->restart) {
- 		wdd->restart_nb.notifier_call = watchdog_restart_notifier;
- 
-@@ -286,6 +320,9 @@ static void __watchdog_unregister_device
- 	if (wdd->ops->restart)
- 		unregister_restart_handler(&wdd->restart_nb);
- 
-+	if (test_bit(WDOG_STOP_ON_REBOOT, &wdd->status))
-+		unregister_reboot_notifier(&wdd->reboot_nb);
-+
- 	devno = wdd->cdev.dev;
- 	ret = watchdog_dev_unregister(wdd);
- 	if (ret)
---- a/include/linux/watchdog.h
-+++ b/include/linux/watchdog.h
-@@ -65,6 +65,7 @@ struct watchdog_ops {
-  * @timeout:	The watchdog devices timeout value (in seconds).
-  * @min_timeout:The watchdog devices minimum timeout value (in seconds).
-  * @max_timeout:The watchdog devices maximum timeout value (in seconds).
-+ * @reboot_nb:	The notifier block to stop watchdog on reboot.
-  * @restart_nb:	The notifier block to register a restart function.
-  * @driver-data:Pointer to the drivers private data.
-  * @lock:	Lock for watchdog core internal use only.
-@@ -92,6 +93,7 @@ struct watchdog_device {
- 	unsigned int timeout;
- 	unsigned int min_timeout;
- 	unsigned int max_timeout;
-+	struct notifier_block reboot_nb;
- 	struct notifier_block restart_nb;
- 	void *driver_data;
- 	struct mutex lock;
-@@ -102,6 +104,7 @@ struct watchdog_device {
- #define WDOG_ALLOW_RELEASE	2	/* Did we receive the magic char ? */
- #define WDOG_NO_WAY_OUT		3	/* Is 'nowayout' feature set ? */
- #define WDOG_UNREGISTERED	4	/* Has the device been unregistered */
-+#define WDOG_STOP_ON_REBOOT	5	/* Should be stopped on reboot */
- 	struct list_head deferred;
- };
- 
-@@ -121,6 +124,12 @@ static inline void watchdog_set_nowayout
- 		set_bit(WDOG_NO_WAY_OUT, &wdd->status);
- }
- 
-+/* Use the following function to stop the watchdog on reboot */
-+static inline void watchdog_stop_on_reboot(struct watchdog_device *wdd)
-+{
-+	set_bit(WDOG_STOP_ON_REBOOT, &wdd->status);
-+}
-+
- /* Use the following function to check if a timeout value is invalid */
- static inline bool watchdog_timeout_invalid(struct watchdog_device *wdd, unsigned int t)
- {
diff --git a/target/linux/ipq806x/patches-4.4/009-3-watchdog-Use-static-struct-class-watchdog_class-instead-of-pointer.patch b/target/linux/ipq806x/patches-4.4/009-3-watchdog-Use-static-struct-class-watchdog_class-instead-of-pointer.patch
deleted file mode 100644
index 1906a1f..0000000
--- a/target/linux/ipq806x/patches-4.4/009-3-watchdog-Use-static-struct-class-watchdog_class-instead-of-pointer.patch
+++ /dev/null
@@ -1,111 +0,0 @@
-From 906d7a5cfeda508e7361f021605579a00cd82815 Mon Sep 17 00:00:00 2001
-From: Pratyush Anand <panand at redhat.com>
-Date: Thu, 17 Dec 2015 17:53:58 +0530
-Subject: watchdog: Use static struct class watchdog_class in stead of pointer
-
-We need few sysfs attributes to know different status of a watchdog device.
-To do that, we need to associate .dev_groups with watchdog_class. So
-convert it from pointer to static.
-Putting this static struct in watchdog_dev.c, so that static device
-attributes defined in that file can be attached to it.
-
-Signed-off-by: Pratyush Anand <panand at redhat.com>
-Suggested-by: Guenter Roeck <linux at roeck-us.net>
-Reviewed-by: Guenter Roeck <linux at roeck-us.net>
-Signed-off-by: Guenter Roeck <linux at roeck-us.net>
-Signed-off-by: Wim Van Sebroeck <wim at iguana.be>
----
- drivers/watchdog/watchdog_core.c | 15 ++-------------
- drivers/watchdog/watchdog_core.h |  2 +-
- drivers/watchdog/watchdog_dev.c  | 26 ++++++++++++++++++++++----
- 3 files changed, 25 insertions(+), 18 deletions(-)
-
---- a/drivers/watchdog/watchdog_core.c
-+++ b/drivers/watchdog/watchdog_core.c
-@@ -370,19 +370,9 @@ static int __init watchdog_deferred_regi
- 
- static int __init watchdog_init(void)
- {
--	int err;
--
--	watchdog_class = class_create(THIS_MODULE, "watchdog");
--	if (IS_ERR(watchdog_class)) {
--		pr_err("couldn't create class\n");
-+	watchdog_class = watchdog_dev_init();
-+	if (IS_ERR(watchdog_class))
- 		return PTR_ERR(watchdog_class);
--	}
--
--	err = watchdog_dev_init();
--	if (err < 0) {
--		class_destroy(watchdog_class);
--		return err;
--	}
- 
- 	watchdog_deferred_registration();
- 	return 0;
-@@ -391,7 +381,6 @@ static int __init watchdog_init(void)
- static void __exit watchdog_exit(void)
- {
- 	watchdog_dev_exit();
--	class_destroy(watchdog_class);
- 	ida_destroy(&watchdog_ida);
- }
- 
---- a/drivers/watchdog/watchdog_core.h
-+++ b/drivers/watchdog/watchdog_core.h
-@@ -33,5 +33,5 @@
-  */
- extern int watchdog_dev_register(struct watchdog_device *);
- extern int watchdog_dev_unregister(struct watchdog_device *);
--extern int __init watchdog_dev_init(void);
-+extern struct class * __init watchdog_dev_init(void);
- extern void __exit watchdog_dev_exit(void);
---- a/drivers/watchdog/watchdog_dev.c
-+++ b/drivers/watchdog/watchdog_dev.c
-@@ -581,18 +581,35 @@ int watchdog_dev_unregister(struct watch
- 	return 0;
- }
- 
-+static struct class watchdog_class = {
-+	.name =		"watchdog",
-+	.owner =	THIS_MODULE,
-+};
-+
- /*
-  *	watchdog_dev_init: init dev part of watchdog core
-  *
-  *	Allocate a range of chardev nodes to use for watchdog devices
-  */
- 
--int __init watchdog_dev_init(void)
-+struct class * __init watchdog_dev_init(void)
- {
--	int err = alloc_chrdev_region(&watchdog_devt, 0, MAX_DOGS, "watchdog");
--	if (err < 0)
-+	int err;
-+
-+	err = class_register(&watchdog_class);
-+	if (err < 0) {
-+		pr_err("couldn't register class\n");
-+		return ERR_PTR(err);
-+	}
-+
-+	err = alloc_chrdev_region(&watchdog_devt, 0, MAX_DOGS, "watchdog");
-+	if (err < 0) {
- 		pr_err("watchdog: unable to allocate char dev region\n");
--	return err;
-+		class_unregister(&watchdog_class);
-+		return ERR_PTR(err);
-+	}
-+
-+	return &watchdog_class;
- }
- 
- /*
-@@ -604,4 +621,5 @@ int __init watchdog_dev_init(void)
- void __exit watchdog_dev_exit(void)
- {
- 	unregister_chrdev_region(watchdog_devt, MAX_DOGS);
-+	class_unregister(&watchdog_class);
- }
diff --git a/target/linux/ipq806x/patches-4.4/009-4-watchdog-Read-device-status-through-sysfs-attributes.patch b/target/linux/ipq806x/patches-4.4/009-4-watchdog-Read-device-status-through-sysfs-attributes.patch
deleted file mode 100644
index fd4b38a..0000000
--- a/target/linux/ipq806x/patches-4.4/009-4-watchdog-Read-device-status-through-sysfs-attributes.patch
+++ /dev/null
@@ -1,260 +0,0 @@
-From 33b711269ade3f6bc9d9d15e4343e6fa922d999b Mon Sep 17 00:00:00 2001
-From: Pratyush Anand <panand at redhat.com>
-Date: Thu, 17 Dec 2015 17:53:59 +0530
-Subject: watchdog: Read device status through sysfs attributes
-
-This patch adds following attributes to watchdog device's sysfs interface
-to read its different status.
-
-* state - reads whether device is active or not
-* identity - reads Watchdog device's identity string.
-* timeout - reads current timeout.
-* timeleft - reads timeleft before watchdog generates a reset
-* bootstatus - reads status of the watchdog device at boot
-* status - reads watchdog device's  internal status bits
-* nowayout - reads whether nowayout feature was set or not
-
-Testing with iTCO_wdt:
- # cd /sys/class/watchdog/watchdog1/
- # ls
-bootstatus  dev  device  identity  nowayout  power  state
-subsystem  timeleft  timeout  uevent
- # cat identity
-iTCO_wdt
- # cat timeout
-30
- # cat state
-inactive
- # echo > /dev/watchdog1
- # cat timeleft
-26
- # cat state
-active
- # cat bootstatus
-0
- # cat nowayout
-0
-
-Signed-off-by: Pratyush Anand <panand at redhat.com>
-Reviewed-by: Guenter Roeck <linux at roeck-us.net>
-Signed-off-by: Guenter Roeck <linux at roeck-us.net>
-Signed-off-by: Wim Van Sebroeck <wim at iguana.be>
----
- Documentation/ABI/testing/sysfs-class-watchdog |  51 +++++++++++
- drivers/watchdog/Kconfig                       |   7 ++
- drivers/watchdog/watchdog_core.c               |   2 +-
- drivers/watchdog/watchdog_dev.c                | 114 +++++++++++++++++++++++++
- 4 files changed, 173 insertions(+), 1 deletion(-)
- create mode 100644 Documentation/ABI/testing/sysfs-class-watchdog
-
---- /dev/null
-+++ b/Documentation/ABI/testing/sysfs-class-watchdog
-@@ -0,0 +1,51 @@
-+What:		/sys/class/watchdog/watchdogn/bootstatus
-+Date:		August 2015
-+Contact:	Wim Van Sebroeck <wim at iguana.be>
-+Description:
-+		It is a read only file. It contains status of the watchdog
-+		device at boot. It is equivalent to WDIOC_GETBOOTSTATUS of
-+		ioctl interface.
-+
-+What:		/sys/class/watchdog/watchdogn/identity
-+Date:		August 2015
-+Contact:	Wim Van Sebroeck <wim at iguana.be>
-+Description:
-+		It is a read only file. It contains identity string of
-+		watchdog device.
-+
-+What:		/sys/class/watchdog/watchdogn/nowayout
-+Date:		August 2015
-+Contact:	Wim Van Sebroeck <wim at iguana.be>
-+Description:
-+		It is a read only file. While reading, it gives '1' if that
-+		device supports nowayout feature else, it gives '0'.
-+
-+What:		/sys/class/watchdog/watchdogn/state
-+Date:		August 2015
-+Contact:	Wim Van Sebroeck <wim at iguana.be>
-+Description:
-+		It is a read only file. It gives active/inactive status of
-+		watchdog device.
-+
-+What:		/sys/class/watchdog/watchdogn/status
-+Date:		August 2015
-+Contact:	Wim Van Sebroeck <wim at iguana.be>
-+Description:
-+		It is a read only file. It contains watchdog device's
-+		internal status bits. It is equivalent to WDIOC_GETSTATUS
-+		of ioctl interface.
-+
-+What:		/sys/class/watchdog/watchdogn/timeleft
-+Date:		August 2015
-+Contact:	Wim Van Sebroeck <wim at iguana.be>
-+Description:
-+		It is a read only file. It contains value of time left for
-+		reset generation. It is equivalent to WDIOC_GETTIMELEFT of
-+		ioctl interface.
-+
-+What:		/sys/class/watchdog/watchdogn/timeout
-+Date:		August 2015
-+Contact:	Wim Van Sebroeck <wim at iguana.be>
-+Description:
-+		It is a read only file. It is read to know about current
-+		value of timeout programmed.
---- a/drivers/watchdog/Kconfig
-+++ b/drivers/watchdog/Kconfig
-@@ -46,6 +46,13 @@ config WATCHDOG_NOWAYOUT
- 	  get killed. If you say Y here, the watchdog cannot be stopped once
- 	  it has been started.
- 
-+config WATCHDOG_SYSFS
-+	bool "Read different watchdog information through sysfs"
-+	default n
-+	help
-+	  Say Y here if you want to enable watchdog device status read through
-+	  sysfs attributes.
-+
- #
- # General Watchdog drivers
- #
---- a/drivers/watchdog/watchdog_core.c
-+++ b/drivers/watchdog/watchdog_core.c
-@@ -249,7 +249,7 @@ static int __watchdog_register_device(st
- 
- 	devno = wdd->cdev.dev;
- 	wdd->dev = device_create(watchdog_class, wdd->parent, devno,
--					NULL, "watchdog%d", wdd->id);
-+					wdd, "watchdog%d", wdd->id);
- 	if (IS_ERR(wdd->dev)) {
- 		watchdog_dev_unregister(wdd);
- 		ida_simple_remove(&watchdog_ida, id);
---- a/drivers/watchdog/watchdog_dev.c
-+++ b/drivers/watchdog/watchdog_dev.c
-@@ -247,6 +247,119 @@ out_timeleft:
- 	return err;
- }
- 
-+#ifdef CONFIG_WATCHDOG_SYSFS
-+static ssize_t nowayout_show(struct device *dev, struct device_attribute *attr,
-+				char *buf)
-+{
-+	struct watchdog_device *wdd = dev_get_drvdata(dev);
-+
-+	return sprintf(buf, "%d\n", !!test_bit(WDOG_NO_WAY_OUT, &wdd->status));
-+}
-+static DEVICE_ATTR_RO(nowayout);
-+
-+static ssize_t status_show(struct device *dev, struct device_attribute *attr,
-+				char *buf)
-+{
-+	struct watchdog_device *wdd = dev_get_drvdata(dev);
-+	ssize_t status;
-+	unsigned int val;
-+
-+	status = watchdog_get_status(wdd, &val);
-+	if (!status)
-+		status = sprintf(buf, "%u\n", val);
-+
-+	return status;
-+}
-+static DEVICE_ATTR_RO(status);
-+
-+static ssize_t bootstatus_show(struct device *dev,
-+				struct device_attribute *attr, char *buf)
-+{
-+	struct watchdog_device *wdd = dev_get_drvdata(dev);
-+
-+	return sprintf(buf, "%u\n", wdd->bootstatus);
-+}
-+static DEVICE_ATTR_RO(bootstatus);
-+
-+static ssize_t timeleft_show(struct device *dev, struct device_attribute *attr,
-+				char *buf)
-+{
-+	struct watchdog_device *wdd = dev_get_drvdata(dev);
-+	ssize_t status;
-+	unsigned int val;
-+
-+	status = watchdog_get_timeleft(wdd, &val);
-+	if (!status)
-+		status = sprintf(buf, "%u\n", val);
-+
-+	return status;
-+}
-+static DEVICE_ATTR_RO(timeleft);
-+
-+static ssize_t timeout_show(struct device *dev, struct device_attribute *attr,
-+				char *buf)
-+{
-+	struct watchdog_device *wdd = dev_get_drvdata(dev);
-+
-+	return sprintf(buf, "%u\n", wdd->timeout);
-+}
-+static DEVICE_ATTR_RO(timeout);
-+
-+static ssize_t identity_show(struct device *dev, struct device_attribute *attr,
-+				char *buf)
-+{
-+	struct watchdog_device *wdd = dev_get_drvdata(dev);
-+
-+	return sprintf(buf, "%s\n", wdd->info->identity);
-+}
-+static DEVICE_ATTR_RO(identity);
-+
-+static ssize_t state_show(struct device *dev, struct device_attribute *attr,
-+				char *buf)
-+{
-+	struct watchdog_device *wdd = dev_get_drvdata(dev);
-+
-+	if (watchdog_active(wdd))
-+		return sprintf(buf, "active\n");
-+
-+	return sprintf(buf, "inactive\n");
-+}
-+static DEVICE_ATTR_RO(state);
-+
-+static umode_t wdt_is_visible(struct kobject *kobj, struct attribute *attr,
-+				int n)
-+{
-+	struct device *dev = container_of(kobj, struct device, kobj);
-+	struct watchdog_device *wdd = dev_get_drvdata(dev);
-+	umode_t mode = attr->mode;
-+
-+	if (attr == &dev_attr_status.attr && !wdd->ops->status)
-+		mode = 0;
-+	else if (attr == &dev_attr_timeleft.attr && !wdd->ops->get_timeleft)
-+		mode = 0;
-+
-+	return mode;
-+}
-+static struct attribute *wdt_attrs[] = {
-+	&dev_attr_state.attr,
-+	&dev_attr_identity.attr,
-+	&dev_attr_timeout.attr,
-+	&dev_attr_timeleft.attr,
-+	&dev_attr_bootstatus.attr,
-+	&dev_attr_status.attr,
-+	&dev_attr_nowayout.attr,
-+	NULL,
-+};
-+
-+static const struct attribute_group wdt_group = {
-+	.attrs = wdt_attrs,
-+	.is_visible = wdt_is_visible,
-+};
-+__ATTRIBUTE_GROUPS(wdt);
-+#else
-+#define wdt_groups	NULL
-+#endif
-+
- /*
-  *	watchdog_ioctl_op: call the watchdog drivers ioctl op if defined
-  *	@wdd: the watchdog device to do the ioctl on
-@@ -584,6 +697,7 @@ int watchdog_dev_unregister(struct watch
- static struct class watchdog_class = {
- 	.name =		"watchdog",
- 	.owner =	THIS_MODULE,
-+	.dev_groups =	wdt_groups,
- };
- 
- /*
diff --git a/target/linux/ipq806x/patches-4.4/009-5-watchdog-Create-watchdog-device-in-watchdog_dev-c.patch b/target/linux/ipq806x/patches-4.4/009-5-watchdog-Create-watchdog-device-in-watchdog_dev-c.patch
deleted file mode 100644
index 059ebdd..0000000
--- a/target/linux/ipq806x/patches-4.4/009-5-watchdog-Create-watchdog-device-in-watchdog_dev-c.patch
+++ /dev/null
@@ -1,261 +0,0 @@
-From 32ecc6392654a0db34b310e8924b5b2c3b8bf503 Mon Sep 17 00:00:00 2001
-From: Guenter Roeck <linux at roeck-us.net>
-Date: Fri, 25 Dec 2015 16:01:40 -0800
-Subject: watchdog: Create watchdog device in watchdog_dev.c
-
-The watchdog character device is currently created in watchdog_dev.c,
-and the watchdog device in watchdog_core.c. This results in
-cross-dependencies, since device creation needs to know the watchdog
-character device number as well as the watchdog class, both of which
-reside in watchdog_dev.c.
-
-Create the watchdog device in watchdog_dev.c to simplify the code.
-
-Inspired by earlier patch set from Damien Riegel.
-
-Cc: Damien Riegel <damien.riegel at savoirfairelinux.com>
-Signed-off-by: Guenter Roeck <linux at roeck-us.net>
-Signed-off-by: Wim Van Sebroeck <wim at iguana.be>
----
- drivers/watchdog/watchdog_core.c | 33 ++++--------------
- drivers/watchdog/watchdog_core.h |  4 +--
- drivers/watchdog/watchdog_dev.c  | 73 +++++++++++++++++++++++++++++++++-------
- 3 files changed, 69 insertions(+), 41 deletions(-)
-
---- a/drivers/watchdog/watchdog_core.c
-+++ b/drivers/watchdog/watchdog_core.c
-@@ -42,7 +42,6 @@
- #include "watchdog_core.h"	/* For watchdog_dev_register/... */
- 
- static DEFINE_IDA(watchdog_ida);
--static struct class *watchdog_class;
- 
- /*
-  * Deferred Registration infrastructure.
-@@ -194,7 +193,7 @@ EXPORT_SYMBOL_GPL(watchdog_set_restart_p
- 
- static int __watchdog_register_device(struct watchdog_device *wdd)
- {
--	int ret, id = -1, devno;
-+	int ret, id = -1;
- 
- 	if (wdd == NULL || wdd->info == NULL || wdd->ops == NULL)
- 		return -EINVAL;
-@@ -247,16 +246,6 @@ static int __watchdog_register_device(st
- 		}
- 	}
- 
--	devno = wdd->cdev.dev;
--	wdd->dev = device_create(watchdog_class, wdd->parent, devno,
--					wdd, "watchdog%d", wdd->id);
--	if (IS_ERR(wdd->dev)) {
--		watchdog_dev_unregister(wdd);
--		ida_simple_remove(&watchdog_ida, id);
--		ret = PTR_ERR(wdd->dev);
--		return ret;
--	}
--
- 	if (test_bit(WDOG_STOP_ON_REBOOT, &wdd->status)) {
- 		wdd->reboot_nb.notifier_call = watchdog_reboot_notifier;
- 
-@@ -265,9 +254,7 @@ static int __watchdog_register_device(st
- 			dev_err(wdd->dev, "Cannot register reboot notifier (%d)\n",
- 				ret);
- 			watchdog_dev_unregister(wdd);
--			device_destroy(watchdog_class, devno);
- 			ida_simple_remove(&watchdog_ida, wdd->id);
--			wdd->dev = NULL;
- 			return ret;
- 		}
- 	}
-@@ -311,9 +298,6 @@ EXPORT_SYMBOL_GPL(watchdog_register_devi
- 
- static void __watchdog_unregister_device(struct watchdog_device *wdd)
- {
--	int ret;
--	int devno;
--
- 	if (wdd == NULL)
- 		return;
- 
-@@ -323,13 +307,8 @@ static void __watchdog_unregister_device
- 	if (test_bit(WDOG_STOP_ON_REBOOT, &wdd->status))
- 		unregister_reboot_notifier(&wdd->reboot_nb);
- 
--	devno = wdd->cdev.dev;
--	ret = watchdog_dev_unregister(wdd);
--	if (ret)
--		pr_err("error unregistering /dev/watchdog (err=%d)\n", ret);
--	device_destroy(watchdog_class, devno);
-+	watchdog_dev_unregister(wdd);
- 	ida_simple_remove(&watchdog_ida, wdd->id);
--	wdd->dev = NULL;
- }
- 
- /**
-@@ -370,9 +349,11 @@ static int __init watchdog_deferred_regi
- 
- static int __init watchdog_init(void)
- {
--	watchdog_class = watchdog_dev_init();
--	if (IS_ERR(watchdog_class))
--		return PTR_ERR(watchdog_class);
-+	int err;
-+
-+	err = watchdog_dev_init();
-+	if (err < 0)
-+		return err;
- 
- 	watchdog_deferred_registration();
- 	return 0;
---- a/drivers/watchdog/watchdog_core.h
-+++ b/drivers/watchdog/watchdog_core.h
-@@ -32,6 +32,6 @@
-  *	Functions/procedures to be called by the core
-  */
- extern int watchdog_dev_register(struct watchdog_device *);
--extern int watchdog_dev_unregister(struct watchdog_device *);
--extern struct class * __init watchdog_dev_init(void);
-+extern void watchdog_dev_unregister(struct watchdog_device *);
-+extern int __init watchdog_dev_init(void);
- extern void __exit watchdog_dev_exit(void);
---- a/drivers/watchdog/watchdog_dev.c
-+++ b/drivers/watchdog/watchdog_dev.c
-@@ -628,17 +628,18 @@ static struct miscdevice watchdog_miscde
- };
- 
- /*
-- *	watchdog_dev_register: register a watchdog device
-+ *	watchdog_cdev_register: register watchdog character device
-  *	@wdd: watchdog device
-+ *	@devno: character device number
-  *
-- *	Register a watchdog device including handling the legacy
-+ *	Register a watchdog character device including handling the legacy
-  *	/dev/watchdog node. /dev/watchdog is actually a miscdevice and
-  *	thus we set it up like that.
-  */
- 
--int watchdog_dev_register(struct watchdog_device *wdd)
-+static int watchdog_cdev_register(struct watchdog_device *wdd, dev_t devno)
- {
--	int err, devno;
-+	int err;
- 
- 	if (wdd->id == 0) {
- 		old_wdd = wdd;
-@@ -656,7 +657,6 @@ int watchdog_dev_register(struct watchdo
- 	}
- 
- 	/* Fill in the data structures */
--	devno = MKDEV(MAJOR(watchdog_devt), wdd->id);
- 	cdev_init(&wdd->cdev, &watchdog_fops);
- 	wdd->cdev.owner = wdd->ops->owner;
- 
-@@ -674,13 +674,14 @@ int watchdog_dev_register(struct watchdo
- }
- 
- /*
-- *	watchdog_dev_unregister: unregister a watchdog device
-+ *	watchdog_cdev_unregister: unregister watchdog character device
-  *	@watchdog: watchdog device
-  *
-- *	Unregister the watchdog and if needed the legacy /dev/watchdog device.
-+ *	Unregister watchdog character device and if needed the legacy
-+ *	/dev/watchdog device.
-  */
- 
--int watchdog_dev_unregister(struct watchdog_device *wdd)
-+static void watchdog_cdev_unregister(struct watchdog_device *wdd)
- {
- 	mutex_lock(&wdd->lock);
- 	set_bit(WDOG_UNREGISTERED, &wdd->status);
-@@ -691,7 +692,6 @@ int watchdog_dev_unregister(struct watch
- 		misc_deregister(&watchdog_miscdev);
- 		old_wdd = NULL;
- 	}
--	return 0;
- }
- 
- static struct class watchdog_class = {
-@@ -701,29 +701,76 @@ static struct class watchdog_class = {
- };
- 
- /*
-+ *	watchdog_dev_register: register a watchdog device
-+ *	@wdd: watchdog device
-+ *
-+ *	Register a watchdog device including handling the legacy
-+ *	/dev/watchdog node. /dev/watchdog is actually a miscdevice and
-+ *	thus we set it up like that.
-+ */
-+
-+int watchdog_dev_register(struct watchdog_device *wdd)
-+{
-+	struct device *dev;
-+	dev_t devno;
-+	int ret;
-+
-+	devno = MKDEV(MAJOR(watchdog_devt), wdd->id);
-+
-+	ret = watchdog_cdev_register(wdd, devno);
-+	if (ret)
-+		return ret;
-+
-+	dev = device_create(&watchdog_class, wdd->parent, devno, wdd,
-+			    "watchdog%d", wdd->id);
-+	if (IS_ERR(dev)) {
-+		watchdog_cdev_unregister(wdd);
-+		return PTR_ERR(dev);
-+	}
-+	wdd->dev = dev;
-+
-+	return ret;
-+}
-+
-+/*
-+ *	watchdog_dev_unregister: unregister a watchdog device
-+ *	@watchdog: watchdog device
-+ *
-+ *	Unregister watchdog device and if needed the legacy
-+ *	/dev/watchdog device.
-+ */
-+
-+void watchdog_dev_unregister(struct watchdog_device *wdd)
-+{
-+	watchdog_cdev_unregister(wdd);
-+	device_destroy(&watchdog_class, wdd->dev->devt);
-+	wdd->dev = NULL;
-+}
-+
-+/*
-  *	watchdog_dev_init: init dev part of watchdog core
-  *
-  *	Allocate a range of chardev nodes to use for watchdog devices
-  */
- 
--struct class * __init watchdog_dev_init(void)
-+int __init watchdog_dev_init(void)
- {
- 	int err;
- 
- 	err = class_register(&watchdog_class);
- 	if (err < 0) {
- 		pr_err("couldn't register class\n");
--		return ERR_PTR(err);
-+		return err;
- 	}
- 
- 	err = alloc_chrdev_region(&watchdog_devt, 0, MAX_DOGS, "watchdog");
- 	if (err < 0) {
- 		pr_err("watchdog: unable to allocate char dev region\n");
- 		class_unregister(&watchdog_class);
--		return ERR_PTR(err);
-+		return err;
- 	}
- 
--	return &watchdog_class;
-+	return 0;
- }
- 
- /*
diff --git a/target/linux/ipq806x/patches-4.4/009-6-watchdog-Separate-and-maintain-variables-based-on-variable-lifetime.patch b/target/linux/ipq806x/patches-4.4/009-6-watchdog-Separate-and-maintain-variables-based-on-variable-lifetime.patch
deleted file mode 100644
index 214dabf..0000000
--- a/target/linux/ipq806x/patches-4.4/009-6-watchdog-Separate-and-maintain-variables-based-on-variable-lifetime.patch
+++ /dev/null
@@ -1,969 +0,0 @@
-From b4ffb1909843b28f3b1b60197d517b123b7a9b66 Mon Sep 17 00:00:00 2001
-From: Guenter Roeck <linux at roeck-us.net>
-Date: Fri, 25 Dec 2015 16:01:42 -0800
-Subject: watchdog: Separate and maintain variables based on variable lifetime
-
-All variables required by the watchdog core to manage a watchdog are
-currently stored in struct watchdog_device. The lifetime of those
-variables is determined by the watchdog driver. However, the lifetime
-of variables used by the watchdog core differs from the lifetime of
-struct watchdog_device. To remedy this situation, watchdog drivers
-can implement ref and unref callbacks, to be used by the watchdog
-core to lock struct watchdog_device in memory.
-
-While this solves the immediate problem, it depends on watchdog drivers
-to actually implement the ref/unref callbacks. This is error prone,
-often not implemented in the first place, or not implemented correctly.
-
-To solve the problem without requiring driver support, split the variables
-in struct watchdog_device into two data structures - one for variables
-associated with the watchdog driver, one for variables associated with
-the watchdog core. With this approach, the watchdog core can keep track
-of its variable lifetime and no longer depends on ref/unref callbacks
-in the driver. As a side effect, some of the variables originally in
-struct watchdog_driver are now private to the watchdog core and no longer
-visible in watchdog drivers.
-
-As a side effect of the changes made, an ioctl will now always fail
-with -ENODEV after a watchdog device was unregistered with the character
-device still open. Previously, it would only fail with -ENODEV in some
-situations. Also, ioctl operations are now atomic from driver perspective.
-With this change, it is now guaranteed that the driver will not unregister
-a watchdog between a timeout change and the subsequent ping.
-
-The 'ref' and 'unref' callbacks in struct watchdog_driver are no longer
-used and marked as deprecated.
-
-Signed-off-by: Guenter Roeck <linux at roeck-us.net>
-Signed-off-by: Wim Van Sebroeck <wim at iguana.be>
----
- Documentation/watchdog/watchdog-kernel-api.txt |  45 +--
- drivers/watchdog/watchdog_core.c               |   2 -
- drivers/watchdog/watchdog_dev.c                | 383 +++++++++++++------------
- include/linux/watchdog.h                       |  22 +-
- 4 files changed, 218 insertions(+), 234 deletions(-)
-
---- a/Documentation/watchdog/watchdog-kernel-api.txt
-+++ b/Documentation/watchdog/watchdog-kernel-api.txt
-@@ -44,7 +44,6 @@ The watchdog device structure looks like
- 
- struct watchdog_device {
- 	int id;
--	struct cdev cdev;
- 	struct device *dev;
- 	struct device *parent;
- 	const struct watchdog_info *info;
-@@ -56,7 +55,7 @@ struct watchdog_device {
- 	struct notifier_block reboot_nb;
- 	struct notifier_block restart_nb;
- 	void *driver_data;
--	struct mutex lock;
-+	struct watchdog_core_data *wd_data;
- 	unsigned long status;
- 	struct list_head deferred;
- };
-@@ -66,8 +65,6 @@ It contains following fields:
-   /dev/watchdog0 cdev (dynamic major, minor 0) as well as the old
-   /dev/watchdog miscdev. The id is set automatically when calling
-   watchdog_register_device.
--* cdev: cdev for the dynamic /dev/watchdog<id> device nodes. This
--  field is also populated by watchdog_register_device.
- * dev: device under the watchdog class (created by watchdog_register_device).
- * parent: set this to the parent device (or NULL) before calling
-   watchdog_register_device.
-@@ -89,11 +86,10 @@ It contains following fields:
- * driver_data: a pointer to the drivers private data of a watchdog device.
-   This data should only be accessed via the watchdog_set_drvdata and
-   watchdog_get_drvdata routines.
--* lock: Mutex for WatchDog Timer Driver Core internal use only.
-+* wd_data: a pointer to watchdog core internal data.
- * status: this field contains a number of status bits that give extra
-   information about the status of the device (Like: is the watchdog timer
--  running/active, is the nowayout bit set, is the device opened via
--  the /dev/watchdog interface or not, ...).
-+  running/active, or is the nowayout bit set).
- * deferred: entry in wtd_deferred_reg_list which is used to
-   register early initialized watchdogs.
- 
-@@ -110,8 +106,8 @@ struct watchdog_ops {
- 	int (*set_timeout)(struct watchdog_device *, unsigned int);
- 	unsigned int (*get_timeleft)(struct watchdog_device *);
- 	int (*restart)(struct watchdog_device *);
--	void (*ref)(struct watchdog_device *);
--	void (*unref)(struct watchdog_device *);
-+	void (*ref)(struct watchdog_device *) __deprecated;
-+	void (*unref)(struct watchdog_device *) __deprecated;
- 	long (*ioctl)(struct watchdog_device *, unsigned int, unsigned long);
- };
- 
-@@ -120,20 +116,6 @@ driver's operations. This module owner w
- the watchdog is active. (This to avoid a system crash when you unload the
- module and /dev/watchdog is still open).
- 
--If the watchdog_device struct is dynamically allocated, just locking the module
--is not enough and a driver also needs to define the ref and unref operations to
--ensure the structure holding the watchdog_device does not go away.
--
--The simplest (and usually sufficient) implementation of this is to:
--1) Add a kref struct to the same structure which is holding the watchdog_device
--2) Define a release callback for the kref which frees the struct holding both
--3) Call kref_init on this kref *before* calling watchdog_register_device()
--4) Define a ref operation calling kref_get on this kref
--5) Define a unref operation calling kref_put on this kref
--6) When it is time to cleanup:
-- * Do not kfree() the struct holding both, the last kref_put will do this!
-- * *After* calling watchdog_unregister_device() call kref_put on the kref
--
- Some operations are mandatory and some are optional. The mandatory operations
- are:
- * start: this is a pointer to the routine that starts the watchdog timer
-@@ -176,34 +158,21 @@ they are supported. These optional routi
- * get_timeleft: this routines returns the time that's left before a reset.
- * restart: this routine restarts the machine. It returns 0 on success or a
-   negative errno code for failure.
--* ref: the operation that calls kref_get on the kref of a dynamically
--  allocated watchdog_device struct.
--* unref: the operation that calls kref_put on the kref of a dynamically
--  allocated watchdog_device struct.
- * ioctl: if this routine is present then it will be called first before we do
-   our own internal ioctl call handling. This routine should return -ENOIOCTLCMD
-   if a command is not supported. The parameters that are passed to the ioctl
-   call are: watchdog_device, cmd and arg.
- 
-+The 'ref' and 'unref' operations are no longer used and deprecated.
-+
- The status bits should (preferably) be set with the set_bit and clear_bit alike
- bit-operations. The status bits that are defined are:
- * WDOG_ACTIVE: this status bit indicates whether or not a watchdog timer device
-   is active or not. When the watchdog is active after booting, then you should
-   set this status bit (Note: when you register the watchdog timer device with
-   this bit set, then opening /dev/watchdog will skip the start operation)
--* WDOG_DEV_OPEN: this status bit shows whether or not the watchdog device
--  was opened via /dev/watchdog.
--  (This bit should only be used by the WatchDog Timer Driver Core).
--* WDOG_ALLOW_RELEASE: this bit stores whether or not the magic close character
--  has been sent (so that we can support the magic close feature).
--  (This bit should only be used by the WatchDog Timer Driver Core).
- * WDOG_NO_WAY_OUT: this bit stores the nowayout setting for the watchdog.
-   If this bit is set then the watchdog timer will not be able to stop.
--* WDOG_UNREGISTERED: this bit gets set by the WatchDog Timer Driver Core
--  after calling watchdog_unregister_device, and then checked before calling
--  any watchdog_ops, so that you can be sure that no operations (other then
--  unref) will get called after unregister, even if userspace still holds a
--  reference to /dev/watchdog
- 
-   To set the WDOG_NO_WAY_OUT status bit (before registering your watchdog
-   timer device) you can either:
---- a/drivers/watchdog/watchdog_core.c
-+++ b/drivers/watchdog/watchdog_core.c
-@@ -210,8 +210,6 @@ static int __watchdog_register_device(st
- 	 * corrupted in a later stage then we expect a kernel panic!
- 	 */
- 
--	mutex_init(&wdd->lock);
--
- 	/* Use alias for watchdog id if possible */
- 	if (wdd->parent) {
- 		ret = of_alias_get_id(wdd->parent->of_node, "watchdog");
---- a/drivers/watchdog/watchdog_dev.c
-+++ b/drivers/watchdog/watchdog_dev.c
-@@ -32,27 +32,51 @@
- 
- #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
- 
--#include <linux/module.h>	/* For module stuff/... */
--#include <linux/types.h>	/* For standard types (like size_t) */
-+#include <linux/cdev.h>		/* For character device */
- #include <linux/errno.h>	/* For the -ENODEV/... values */
--#include <linux/kernel.h>	/* For printk/panic/... */
- #include <linux/fs.h>		/* For file operations */
--#include <linux/watchdog.h>	/* For watchdog specific items */
--#include <linux/miscdevice.h>	/* For handling misc devices */
- #include <linux/init.h>		/* For __init/__exit/... */
-+#include <linux/kernel.h>	/* For printk/panic/... */
-+#include <linux/kref.h>		/* For data references */
-+#include <linux/miscdevice.h>	/* For handling misc devices */
-+#include <linux/module.h>	/* For module stuff/... */
-+#include <linux/mutex.h>	/* For mutexes */
-+#include <linux/slab.h>		/* For memory functions */
-+#include <linux/types.h>	/* For standard types (like size_t) */
-+#include <linux/watchdog.h>	/* For watchdog specific items */
- #include <linux/uaccess.h>	/* For copy_to_user/put_user/... */
- 
- #include "watchdog_core.h"
- 
-+/*
-+ * struct watchdog_core_data - watchdog core internal data
-+ * @kref:	Reference count.
-+ * @cdev:	The watchdog's Character device.
-+ * @wdd:	Pointer to watchdog device.
-+ * @lock:	Lock for watchdog core.
-+ * @status:	Watchdog core internal status bits.
-+ */
-+struct watchdog_core_data {
-+	struct kref kref;
-+	struct cdev cdev;
-+	struct watchdog_device *wdd;
-+	struct mutex lock;
-+	unsigned long status;		/* Internal status bits */
-+#define _WDOG_DEV_OPEN		0	/* Opened ? */
-+#define _WDOG_ALLOW_RELEASE	1	/* Did we receive the magic char ? */
-+};
-+
- /* the dev_t structure to store the dynamically allocated watchdog devices */
- static dev_t watchdog_devt;
--/* the watchdog device behind /dev/watchdog */
--static struct watchdog_device *old_wdd;
-+/* Reference to watchdog device behind /dev/watchdog */
-+static struct watchdog_core_data *old_wd_data;
- 
- /*
-  *	watchdog_ping: ping the watchdog.
-  *	@wdd: the watchdog device to ping
-  *
-+ *	The caller must hold wd_data->lock.
-+ *
-  *	If the watchdog has no own ping operation then it needs to be
-  *	restarted via the start operation. This wrapper function does
-  *	exactly that.
-@@ -61,25 +85,16 @@ static struct watchdog_device *old_wdd;
- 
- static int watchdog_ping(struct watchdog_device *wdd)
- {
--	int err = 0;
--
--	mutex_lock(&wdd->lock);
--
--	if (test_bit(WDOG_UNREGISTERED, &wdd->status)) {
--		err = -ENODEV;
--		goto out_ping;
--	}
-+	int err;
- 
- 	if (!watchdog_active(wdd))
--		goto out_ping;
-+		return 0;
- 
- 	if (wdd->ops->ping)
- 		err = wdd->ops->ping(wdd);	/* ping the watchdog */
- 	else
- 		err = wdd->ops->start(wdd);	/* restart watchdog */
- 
--out_ping:
--	mutex_unlock(&wdd->lock);
- 	return err;
- }
- 
-@@ -87,6 +102,8 @@ out_ping:
-  *	watchdog_start: wrapper to start the watchdog.
-  *	@wdd: the watchdog device to start
-  *
-+ *	The caller must hold wd_data->lock.
-+ *
-  *	Start the watchdog if it is not active and mark it active.
-  *	This function returns zero on success or a negative errno code for
-  *	failure.
-@@ -94,24 +111,15 @@ out_ping:
- 
- static int watchdog_start(struct watchdog_device *wdd)
- {
--	int err = 0;
--
--	mutex_lock(&wdd->lock);
--
--	if (test_bit(WDOG_UNREGISTERED, &wdd->status)) {
--		err = -ENODEV;
--		goto out_start;
--	}
-+	int err;
- 
- 	if (watchdog_active(wdd))
--		goto out_start;
-+		return 0;
- 
- 	err = wdd->ops->start(wdd);
- 	if (err == 0)
- 		set_bit(WDOG_ACTIVE, &wdd->status);
- 
--out_start:
--	mutex_unlock(&wdd->lock);
- 	return err;
- }
- 
-@@ -119,6 +127,8 @@ out_start:
-  *	watchdog_stop: wrapper to stop the watchdog.
-  *	@wdd: the watchdog device to stop
-  *
-+ *	The caller must hold wd_data->lock.
-+ *
-  *	Stop the watchdog if it is still active and unmark it active.
-  *	This function returns zero on success or a negative errno code for
-  *	failure.
-@@ -127,93 +137,58 @@ out_start:
- 
- static int watchdog_stop(struct watchdog_device *wdd)
- {
--	int err = 0;
--
--	mutex_lock(&wdd->lock);
--
--	if (test_bit(WDOG_UNREGISTERED, &wdd->status)) {
--		err = -ENODEV;
--		goto out_stop;
--	}
-+	int err;
- 
- 	if (!watchdog_active(wdd))
--		goto out_stop;
-+		return 0;
- 
- 	if (test_bit(WDOG_NO_WAY_OUT, &wdd->status)) {
- 		dev_info(wdd->dev, "nowayout prevents watchdog being stopped!\n");
--		err = -EBUSY;
--		goto out_stop;
-+		return -EBUSY;
- 	}
- 
- 	err = wdd->ops->stop(wdd);
- 	if (err == 0)
- 		clear_bit(WDOG_ACTIVE, &wdd->status);
- 
--out_stop:
--	mutex_unlock(&wdd->lock);
- 	return err;
- }
- 
- /*
-  *	watchdog_get_status: wrapper to get the watchdog status
-  *	@wdd: the watchdog device to get the status from
-- *	@status: the status of the watchdog device
-+ *
-+ *	The caller must hold wd_data->lock.
-  *
-  *	Get the watchdog's status flags.
-  */
- 
--static int watchdog_get_status(struct watchdog_device *wdd,
--							unsigned int *status)
-+static unsigned int watchdog_get_status(struct watchdog_device *wdd)
- {
--	int err = 0;
--
--	*status = 0;
- 	if (!wdd->ops->status)
--		return -EOPNOTSUPP;
--
--	mutex_lock(&wdd->lock);
--
--	if (test_bit(WDOG_UNREGISTERED, &wdd->status)) {
--		err = -ENODEV;
--		goto out_status;
--	}
--
--	*status = wdd->ops->status(wdd);
-+		return 0;
- 
--out_status:
--	mutex_unlock(&wdd->lock);
--	return err;
-+	return wdd->ops->status(wdd);
- }
- 
- /*
-  *	watchdog_set_timeout: set the watchdog timer timeout
-  *	@wdd: the watchdog device to set the timeout for
-  *	@timeout: timeout to set in seconds
-+ *
-+ *	The caller must hold wd_data->lock.
-  */
- 
- static int watchdog_set_timeout(struct watchdog_device *wdd,
- 							unsigned int timeout)
- {
--	int err;
--
- 	if (!wdd->ops->set_timeout || !(wdd->info->options & WDIOF_SETTIMEOUT))
- 		return -EOPNOTSUPP;
- 
- 	if (watchdog_timeout_invalid(wdd, timeout))
- 		return -EINVAL;
- 
--	mutex_lock(&wdd->lock);
--
--	if (test_bit(WDOG_UNREGISTERED, &wdd->status)) {
--		err = -ENODEV;
--		goto out_timeout;
--	}
--
--	err = wdd->ops->set_timeout(wdd, timeout);
--
--out_timeout:
--	mutex_unlock(&wdd->lock);
--	return err;
-+	return wdd->ops->set_timeout(wdd, timeout);
- }
- 
- /*
-@@ -221,30 +196,22 @@ out_timeout:
-  *	@wdd: the watchdog device to get the remaining time from
-  *	@timeleft: the time that's left
-  *
-+ *	The caller must hold wd_data->lock.
-+ *
-  *	Get the time before a watchdog will reboot (if not pinged).
-  */
- 
- static int watchdog_get_timeleft(struct watchdog_device *wdd,
- 							unsigned int *timeleft)
- {
--	int err = 0;
--
- 	*timeleft = 0;
-+
- 	if (!wdd->ops->get_timeleft)
- 		return -EOPNOTSUPP;
- 
--	mutex_lock(&wdd->lock);
--
--	if (test_bit(WDOG_UNREGISTERED, &wdd->status)) {
--		err = -ENODEV;
--		goto out_timeleft;
--	}
--
- 	*timeleft = wdd->ops->get_timeleft(wdd);
- 
--out_timeleft:
--	mutex_unlock(&wdd->lock);
--	return err;
-+	return 0;
- }
- 
- #ifdef CONFIG_WATCHDOG_SYSFS
-@@ -261,14 +228,14 @@ static ssize_t status_show(struct device
- 				char *buf)
- {
- 	struct watchdog_device *wdd = dev_get_drvdata(dev);
--	ssize_t status;
--	unsigned int val;
-+	struct watchdog_core_data *wd_data = wdd->wd_data;
-+	unsigned int status;
- 
--	status = watchdog_get_status(wdd, &val);
--	if (!status)
--		status = sprintf(buf, "%u\n", val);
-+	mutex_lock(&wd_data->lock);
-+	status = watchdog_get_status(wdd);
-+	mutex_unlock(&wd_data->lock);
- 
--	return status;
-+	return sprintf(buf, "%u\n", status);
- }
- static DEVICE_ATTR_RO(status);
- 
-@@ -285,10 +252,13 @@ static ssize_t timeleft_show(struct devi
- 				char *buf)
- {
- 	struct watchdog_device *wdd = dev_get_drvdata(dev);
-+	struct watchdog_core_data *wd_data = wdd->wd_data;
- 	ssize_t status;
- 	unsigned int val;
- 
-+	mutex_lock(&wd_data->lock);
- 	status = watchdog_get_timeleft(wdd, &val);
-+	mutex_unlock(&wd_data->lock);
- 	if (!status)
- 		status = sprintf(buf, "%u\n", val);
- 
-@@ -365,28 +335,17 @@ __ATTRIBUTE_GROUPS(wdt);
-  *	@wdd: the watchdog device to do the ioctl on
-  *	@cmd: watchdog command
-  *	@arg: argument pointer
-+ *
-+ *	The caller must hold wd_data->lock.
-  */
- 
- static int watchdog_ioctl_op(struct watchdog_device *wdd, unsigned int cmd,
- 							unsigned long arg)
- {
--	int err;
--
- 	if (!wdd->ops->ioctl)
- 		return -ENOIOCTLCMD;
- 
--	mutex_lock(&wdd->lock);
--
--	if (test_bit(WDOG_UNREGISTERED, &wdd->status)) {
--		err = -ENODEV;
--		goto out_ioctl;
--	}
--
--	err = wdd->ops->ioctl(wdd, cmd, arg);
--
--out_ioctl:
--	mutex_unlock(&wdd->lock);
--	return err;
-+	return wdd->ops->ioctl(wdd, cmd, arg);
- }
- 
- /*
-@@ -404,10 +363,11 @@ out_ioctl:
- static ssize_t watchdog_write(struct file *file, const char __user *data,
- 						size_t len, loff_t *ppos)
- {
--	struct watchdog_device *wdd = file->private_data;
-+	struct watchdog_core_data *wd_data = file->private_data;
-+	struct watchdog_device *wdd;
-+	int err;
- 	size_t i;
- 	char c;
--	int err;
- 
- 	if (len == 0)
- 		return 0;
-@@ -416,18 +376,25 @@ static ssize_t watchdog_write(struct fil
- 	 * Note: just in case someone wrote the magic character
- 	 * five months ago...
- 	 */
--	clear_bit(WDOG_ALLOW_RELEASE, &wdd->status);
-+	clear_bit(_WDOG_ALLOW_RELEASE, &wd_data->status);
- 
- 	/* scan to see whether or not we got the magic character */
- 	for (i = 0; i != len; i++) {
- 		if (get_user(c, data + i))
- 			return -EFAULT;
- 		if (c == 'V')
--			set_bit(WDOG_ALLOW_RELEASE, &wdd->status);
-+			set_bit(_WDOG_ALLOW_RELEASE, &wd_data->status);
- 	}
- 
- 	/* someone wrote to us, so we send the watchdog a keepalive ping */
--	err = watchdog_ping(wdd);
-+
-+	err = -ENODEV;
-+	mutex_lock(&wd_data->lock);
-+	wdd = wd_data->wdd;
-+	if (wdd)
-+		err = watchdog_ping(wdd);
-+	mutex_unlock(&wd_data->lock);
-+
- 	if (err < 0)
- 		return err;
- 
-@@ -447,71 +414,94 @@ static ssize_t watchdog_write(struct fil
- static long watchdog_ioctl(struct file *file, unsigned int cmd,
- 							unsigned long arg)
- {
--	struct watchdog_device *wdd = file->private_data;
-+	struct watchdog_core_data *wd_data = file->private_data;
- 	void __user *argp = (void __user *)arg;
-+	struct watchdog_device *wdd;
- 	int __user *p = argp;
- 	unsigned int val;
- 	int err;
- 
-+	mutex_lock(&wd_data->lock);
-+
-+	wdd = wd_data->wdd;
-+	if (!wdd) {
-+		err = -ENODEV;
-+		goto out_ioctl;
-+	}
-+
- 	err = watchdog_ioctl_op(wdd, cmd, arg);
- 	if (err != -ENOIOCTLCMD)
--		return err;
-+		goto out_ioctl;
- 
- 	switch (cmd) {
- 	case WDIOC_GETSUPPORT:
--		return copy_to_user(argp, wdd->info,
-+		err = copy_to_user(argp, wdd->info,
- 			sizeof(struct watchdog_info)) ? -EFAULT : 0;
-+		break;
- 	case WDIOC_GETSTATUS:
--		err = watchdog_get_status(wdd, &val);
--		if (err == -ENODEV)
--			return err;
--		return put_user(val, p);
-+		val = watchdog_get_status(wdd);
-+		err = put_user(val, p);
-+		break;
- 	case WDIOC_GETBOOTSTATUS:
--		return put_user(wdd->bootstatus, p);
-+		err = put_user(wdd->bootstatus, p);
-+		break;
- 	case WDIOC_SETOPTIONS:
--		if (get_user(val, p))
--			return -EFAULT;
-+		if (get_user(val, p)) {
-+			err = -EFAULT;
-+			break;
-+		}
- 		if (val & WDIOS_DISABLECARD) {
- 			err = watchdog_stop(wdd);
- 			if (err < 0)
--				return err;
-+				break;
- 		}
--		if (val & WDIOS_ENABLECARD) {
-+		if (val & WDIOS_ENABLECARD)
- 			err = watchdog_start(wdd);
--			if (err < 0)
--				return err;
--		}
--		return 0;
-+		break;
- 	case WDIOC_KEEPALIVE:
--		if (!(wdd->info->options & WDIOF_KEEPALIVEPING))
--			return -EOPNOTSUPP;
--		return watchdog_ping(wdd);
-+		if (!(wdd->info->options & WDIOF_KEEPALIVEPING)) {
-+			err = -EOPNOTSUPP;
-+			break;
-+		}
-+		err = watchdog_ping(wdd);
-+		break;
- 	case WDIOC_SETTIMEOUT:
--		if (get_user(val, p))
--			return -EFAULT;
-+		if (get_user(val, p)) {
-+			err = -EFAULT;
-+			break;
-+		}
- 		err = watchdog_set_timeout(wdd, val);
- 		if (err < 0)
--			return err;
-+			break;
- 		/* If the watchdog is active then we send a keepalive ping
- 		 * to make sure that the watchdog keep's running (and if
- 		 * possible that it takes the new timeout) */
- 		err = watchdog_ping(wdd);
- 		if (err < 0)
--			return err;
-+			break;
- 		/* Fall */
- 	case WDIOC_GETTIMEOUT:
- 		/* timeout == 0 means that we don't know the timeout */
--		if (wdd->timeout == 0)
--			return -EOPNOTSUPP;
--		return put_user(wdd->timeout, p);
-+		if (wdd->timeout == 0) {
-+			err = -EOPNOTSUPP;
-+			break;
-+		}
-+		err = put_user(wdd->timeout, p);
-+		break;
- 	case WDIOC_GETTIMELEFT:
- 		err = watchdog_get_timeleft(wdd, &val);
--		if (err)
--			return err;
--		return put_user(val, p);
-+		if (err < 0)
-+			break;
-+		err = put_user(val, p);
-+		break;
- 	default:
--		return -ENOTTY;
-+		err = -ENOTTY;
-+		break;
- 	}
-+
-+out_ioctl:
-+	mutex_unlock(&wd_data->lock);
-+	return err;
- }
- 
- /*
-@@ -526,45 +516,59 @@ static long watchdog_ioctl(struct file *
- 
- static int watchdog_open(struct inode *inode, struct file *file)
- {
--	int err = -EBUSY;
-+	struct watchdog_core_data *wd_data;
- 	struct watchdog_device *wdd;
-+	int err;
- 
- 	/* Get the corresponding watchdog device */
- 	if (imajor(inode) == MISC_MAJOR)
--		wdd = old_wdd;
-+		wd_data = old_wd_data;
- 	else
--		wdd = container_of(inode->i_cdev, struct watchdog_device, cdev);
-+		wd_data = container_of(inode->i_cdev, struct watchdog_core_data,
-+				       cdev);
- 
- 	/* the watchdog is single open! */
--	if (test_and_set_bit(WDOG_DEV_OPEN, &wdd->status))
-+	if (test_and_set_bit(_WDOG_DEV_OPEN, &wd_data->status))
- 		return -EBUSY;
- 
-+	wdd = wd_data->wdd;
-+
- 	/*
- 	 * If the /dev/watchdog device is open, we don't want the module
- 	 * to be unloaded.
- 	 */
--	if (!try_module_get(wdd->ops->owner))
--		goto out;
-+	if (!try_module_get(wdd->ops->owner)) {
-+		err = -EBUSY;
-+		goto out_clear;
-+	}
- 
- 	err = watchdog_start(wdd);
- 	if (err < 0)
- 		goto out_mod;
- 
--	file->private_data = wdd;
-+	file->private_data = wd_data;
- 
--	if (wdd->ops->ref)
--		wdd->ops->ref(wdd);
-+	kref_get(&wd_data->kref);
- 
- 	/* dev/watchdog is a virtual (and thus non-seekable) filesystem */
- 	return nonseekable_open(inode, file);
- 
- out_mod:
--	module_put(wdd->ops->owner);
--out:
--	clear_bit(WDOG_DEV_OPEN, &wdd->status);
-+	module_put(wd_data->wdd->ops->owner);
-+out_clear:
-+	clear_bit(_WDOG_DEV_OPEN, &wd_data->status);
- 	return err;
- }
- 
-+static void watchdog_core_data_release(struct kref *kref)
-+{
-+	struct watchdog_core_data *wd_data;
-+
-+	wd_data = container_of(kref, struct watchdog_core_data, kref);
-+
-+	kfree(wd_data);
-+}
-+
- /*
-  *	watchdog_release: release the watchdog device.
-  *	@inode: inode of device
-@@ -577,9 +581,16 @@ out:
- 
- static int watchdog_release(struct inode *inode, struct file *file)
- {
--	struct watchdog_device *wdd = file->private_data;
-+	struct watchdog_core_data *wd_data = file->private_data;
-+	struct watchdog_device *wdd;
- 	int err = -EBUSY;
- 
-+	mutex_lock(&wd_data->lock);
-+
-+	wdd = wd_data->wdd;
-+	if (!wdd)
-+		goto done;
-+
- 	/*
- 	 * We only stop the watchdog if we received the magic character
- 	 * or if WDIOF_MAGICCLOSE is not set. If nowayout was set then
-@@ -587,29 +598,24 @@ static int watchdog_release(struct inode
- 	 */
- 	if (!test_bit(WDOG_ACTIVE, &wdd->status))
- 		err = 0;
--	else if (test_and_clear_bit(WDOG_ALLOW_RELEASE, &wdd->status) ||
-+	else if (test_and_clear_bit(_WDOG_ALLOW_RELEASE, &wd_data->status) ||
- 		 !(wdd->info->options & WDIOF_MAGICCLOSE))
- 		err = watchdog_stop(wdd);
- 
- 	/* If the watchdog was not stopped, send a keepalive ping */
- 	if (err < 0) {
--		mutex_lock(&wdd->lock);
--		if (!test_bit(WDOG_UNREGISTERED, &wdd->status))
--			dev_crit(wdd->dev, "watchdog did not stop!\n");
--		mutex_unlock(&wdd->lock);
-+		dev_crit(wdd->dev, "watchdog did not stop!\n");
- 		watchdog_ping(wdd);
- 	}
- 
--	/* Allow the owner module to be unloaded again */
--	module_put(wdd->ops->owner);
--
- 	/* make sure that /dev/watchdog can be re-opened */
--	clear_bit(WDOG_DEV_OPEN, &wdd->status);
--
--	/* Note wdd may be gone after this, do not use after this! */
--	if (wdd->ops->unref)
--		wdd->ops->unref(wdd);
-+	clear_bit(_WDOG_DEV_OPEN, &wd_data->status);
- 
-+done:
-+	mutex_unlock(&wd_data->lock);
-+	/* Allow the owner module to be unloaded again */
-+	module_put(wd_data->cdev.owner);
-+	kref_put(&wd_data->kref, watchdog_core_data_release);
- 	return 0;
- }
- 
-@@ -639,10 +645,20 @@ static struct miscdevice watchdog_miscde
- 
- static int watchdog_cdev_register(struct watchdog_device *wdd, dev_t devno)
- {
-+	struct watchdog_core_data *wd_data;
- 	int err;
- 
-+	wd_data = kzalloc(sizeof(struct watchdog_core_data), GFP_KERNEL);
-+	if (!wd_data)
-+		return -ENOMEM;
-+	kref_init(&wd_data->kref);
-+	mutex_init(&wd_data->lock);
-+
-+	wd_data->wdd = wdd;
-+	wdd->wd_data = wd_data;
-+
- 	if (wdd->id == 0) {
--		old_wdd = wdd;
-+		old_wd_data = wd_data;
- 		watchdog_miscdev.parent = wdd->parent;
- 		err = misc_register(&watchdog_miscdev);
- 		if (err != 0) {
-@@ -651,23 +667,25 @@ static int watchdog_cdev_register(struct
- 			if (err == -EBUSY)
- 				pr_err("%s: a legacy watchdog module is probably present.\n",
- 					wdd->info->identity);
--			old_wdd = NULL;
-+			old_wd_data = NULL;
-+			kfree(wd_data);
- 			return err;
- 		}
- 	}
- 
- 	/* Fill in the data structures */
--	cdev_init(&wdd->cdev, &watchdog_fops);
--	wdd->cdev.owner = wdd->ops->owner;
-+	cdev_init(&wd_data->cdev, &watchdog_fops);
-+	wd_data->cdev.owner = wdd->ops->owner;
- 
- 	/* Add the device */
--	err  = cdev_add(&wdd->cdev, devno, 1);
-+	err = cdev_add(&wd_data->cdev, devno, 1);
- 	if (err) {
- 		pr_err("watchdog%d unable to add device %d:%d\n",
- 			wdd->id,  MAJOR(watchdog_devt), wdd->id);
- 		if (wdd->id == 0) {
- 			misc_deregister(&watchdog_miscdev);
--			old_wdd = NULL;
-+			old_wd_data = NULL;
-+			kref_put(&wd_data->kref, watchdog_core_data_release);
- 		}
- 	}
- 	return err;
-@@ -683,15 +701,20 @@ static int watchdog_cdev_register(struct
- 
- static void watchdog_cdev_unregister(struct watchdog_device *wdd)
- {
--	mutex_lock(&wdd->lock);
--	set_bit(WDOG_UNREGISTERED, &wdd->status);
--	mutex_unlock(&wdd->lock);
-+	struct watchdog_core_data *wd_data = wdd->wd_data;
- 
--	cdev_del(&wdd->cdev);
-+	cdev_del(&wd_data->cdev);
- 	if (wdd->id == 0) {
- 		misc_deregister(&watchdog_miscdev);
--		old_wdd = NULL;
-+		old_wd_data = NULL;
- 	}
-+
-+	mutex_lock(&wd_data->lock);
-+	wd_data->wdd = NULL;
-+	wdd->wd_data = NULL;
-+	mutex_unlock(&wd_data->lock);
-+
-+	kref_put(&wd_data->kref, watchdog_core_data_release);
- }
- 
- static struct class watchdog_class = {
-@@ -742,9 +765,9 @@ int watchdog_dev_register(struct watchdo
- 
- void watchdog_dev_unregister(struct watchdog_device *wdd)
- {
--	watchdog_cdev_unregister(wdd);
- 	device_destroy(&watchdog_class, wdd->dev->devt);
- 	wdd->dev = NULL;
-+	watchdog_cdev_unregister(wdd);
- }
- 
- /*
---- a/include/linux/watchdog.h
-+++ b/include/linux/watchdog.h
-@@ -17,6 +17,7 @@
- 
- struct watchdog_ops;
- struct watchdog_device;
-+struct watchdog_core_data;
- 
- /** struct watchdog_ops - The watchdog-devices operations
-  *
-@@ -28,8 +29,6 @@ struct watchdog_device;
-  * @set_timeout:The routine for setting the watchdog devices timeout value (in seconds).
-  * @get_timeleft:The routine that gets the time left before a reset (in seconds).
-  * @restart:	The routine for restarting the machine.
-- * @ref:	The ref operation for dyn. allocated watchdog_device structs
-- * @unref:	The unref operation for dyn. allocated watchdog_device structs
-  * @ioctl:	The routines that handles extra ioctl calls.
-  *
-  * The watchdog_ops structure contains a list of low-level operations
-@@ -48,15 +47,14 @@ struct watchdog_ops {
- 	int (*set_timeout)(struct watchdog_device *, unsigned int);
- 	unsigned int (*get_timeleft)(struct watchdog_device *);
- 	int (*restart)(struct watchdog_device *);
--	void (*ref)(struct watchdog_device *);
--	void (*unref)(struct watchdog_device *);
-+	void (*ref)(struct watchdog_device *) __deprecated;
-+	void (*unref)(struct watchdog_device *) __deprecated;
- 	long (*ioctl)(struct watchdog_device *, unsigned int, unsigned long);
- };
- 
- /** struct watchdog_device - The structure that defines a watchdog device
-  *
-  * @id:		The watchdog's ID. (Allocated by watchdog_register_device)
-- * @cdev:	The watchdog's Character device.
-  * @dev:	The device for our watchdog
-  * @parent:	The parent bus device
-  * @info:	Pointer to a watchdog_info structure.
-@@ -67,8 +65,8 @@ struct watchdog_ops {
-  * @max_timeout:The watchdog devices maximum timeout value (in seconds).
-  * @reboot_nb:	The notifier block to stop watchdog on reboot.
-  * @restart_nb:	The notifier block to register a restart function.
-- * @driver-data:Pointer to the drivers private data.
-- * @lock:	Lock for watchdog core internal use only.
-+ * @driver_data:Pointer to the drivers private data.
-+ * @wd_data:	Pointer to watchdog core internal data.
-  * @status:	Field that contains the devices internal status bits.
-  * @deferred: entry in wtd_deferred_reg_list which is used to
-  *			   register early initialized watchdogs.
-@@ -84,7 +82,6 @@ struct watchdog_ops {
-  */
- struct watchdog_device {
- 	int id;
--	struct cdev cdev;
- 	struct device *dev;
- 	struct device *parent;
- 	const struct watchdog_info *info;
-@@ -96,15 +93,12 @@ struct watchdog_device {
- 	struct notifier_block reboot_nb;
- 	struct notifier_block restart_nb;
- 	void *driver_data;
--	struct mutex lock;
-+	struct watchdog_core_data *wd_data;
- 	unsigned long status;
- /* Bit numbers for status flags */
- #define WDOG_ACTIVE		0	/* Is the watchdog running/active */
--#define WDOG_DEV_OPEN		1	/* Opened via /dev/watchdog ? */
--#define WDOG_ALLOW_RELEASE	2	/* Did we receive the magic char ? */
--#define WDOG_NO_WAY_OUT		3	/* Is 'nowayout' feature set ? */
--#define WDOG_UNREGISTERED	4	/* Has the device been unregistered */
--#define WDOG_STOP_ON_REBOOT	5	/* Should be stopped on reboot */
-+#define WDOG_NO_WAY_OUT		1	/* Is 'nowayout' feature set ? */
-+#define WDOG_STOP_ON_REBOOT	2	/* Should be stopped on reboot */
- 	struct list_head deferred;
- };
- 
diff --git a/target/linux/ipq806x/patches-4.4/009-7-watchdog-Drop-pointer-to-watchdog-device-from-struct-watchdog_device.patch b/target/linux/ipq806x/patches-4.4/009-7-watchdog-Drop-pointer-to-watchdog-device-from-struct-watchdog_device.patch
deleted file mode 100644
index 9640cd4..0000000
--- a/target/linux/ipq806x/patches-4.4/009-7-watchdog-Drop-pointer-to-watchdog-device-from-struct-watchdog_device.patch
+++ /dev/null
@@ -1,117 +0,0 @@
-From 0254e953537c92df3e7d0176f401a211e944fd61 Mon Sep 17 00:00:00 2001
-From: Guenter Roeck <linux at roeck-us.net>
-Date: Sun, 3 Jan 2016 15:11:58 -0800
-Subject: watchdog: Drop pointer to watchdog device from struct watchdog_device
-
-The lifetime of the watchdog device pointer is different from the lifetime
-of its character device. Remove it entirely to avoid race conditions.
-
-Signed-off-by: Guenter Roeck <linux at roeck-us.net>
-Signed-off-by: Guenter Roeck <linux at roeck-us.net>
-Signed-off-by: Wim Van Sebroeck <wim at iguana.be>
----
- Documentation/watchdog/watchdog-kernel-api.txt | 2 --
- drivers/watchdog/watchdog_core.c               | 8 ++++----
- drivers/watchdog/watchdog_dev.c                | 9 ++++-----
- include/linux/watchdog.h                       | 2 --
- 4 files changed, 8 insertions(+), 13 deletions(-)
-
---- a/Documentation/watchdog/watchdog-kernel-api.txt
-+++ b/Documentation/watchdog/watchdog-kernel-api.txt
-@@ -44,7 +44,6 @@ The watchdog device structure looks like
- 
- struct watchdog_device {
- 	int id;
--	struct device *dev;
- 	struct device *parent;
- 	const struct watchdog_info *info;
- 	const struct watchdog_ops *ops;
-@@ -65,7 +64,6 @@ It contains following fields:
-   /dev/watchdog0 cdev (dynamic major, minor 0) as well as the old
-   /dev/watchdog miscdev. The id is set automatically when calling
-   watchdog_register_device.
--* dev: device under the watchdog class (created by watchdog_register_device).
- * parent: set this to the parent device (or NULL) before calling
-   watchdog_register_device.
- * info: a pointer to a watchdog_info structure. This structure gives some
---- a/drivers/watchdog/watchdog_core.c
-+++ b/drivers/watchdog/watchdog_core.c
-@@ -249,8 +249,8 @@ static int __watchdog_register_device(st
- 
- 		ret = register_reboot_notifier(&wdd->reboot_nb);
- 		if (ret) {
--			dev_err(wdd->dev, "Cannot register reboot notifier (%d)\n",
--				ret);
-+			pr_err("watchdog%d: Cannot register reboot notifier (%d)\n",
-+			       wdd->id, ret);
- 			watchdog_dev_unregister(wdd);
- 			ida_simple_remove(&watchdog_ida, wdd->id);
- 			return ret;
-@@ -262,8 +262,8 @@ static int __watchdog_register_device(st
- 
- 		ret = register_restart_handler(&wdd->restart_nb);
- 		if (ret)
--			dev_warn(wdd->dev, "Cannot register restart handler (%d)\n",
--				 ret);
-+			pr_warn("watchog%d: Cannot register restart handler (%d)\n",
-+				wdd->id, ret);
- 	}
- 
- 	return 0;
---- a/drivers/watchdog/watchdog_dev.c
-+++ b/drivers/watchdog/watchdog_dev.c
-@@ -143,7 +143,8 @@ static int watchdog_stop(struct watchdog
- 		return 0;
- 
- 	if (test_bit(WDOG_NO_WAY_OUT, &wdd->status)) {
--		dev_info(wdd->dev, "nowayout prevents watchdog being stopped!\n");
-+		pr_info("watchdog%d: nowayout prevents watchdog being stopped!\n",
-+			wdd->id);
- 		return -EBUSY;
- 	}
- 
-@@ -604,7 +605,7 @@ static int watchdog_release(struct inode
- 
- 	/* If the watchdog was not stopped, send a keepalive ping */
- 	if (err < 0) {
--		dev_crit(wdd->dev, "watchdog did not stop!\n");
-+		pr_crit("watchdog%d: watchdog did not stop!\n", wdd->id);
- 		watchdog_ping(wdd);
- 	}
- 
-@@ -750,7 +751,6 @@ int watchdog_dev_register(struct watchdo
- 		watchdog_cdev_unregister(wdd);
- 		return PTR_ERR(dev);
- 	}
--	wdd->dev = dev;
- 
- 	return ret;
- }
-@@ -765,8 +765,7 @@ int watchdog_dev_register(struct watchdo
- 
- void watchdog_dev_unregister(struct watchdog_device *wdd)
- {
--	device_destroy(&watchdog_class, wdd->dev->devt);
--	wdd->dev = NULL;
-+	device_destroy(&watchdog_class, wdd->wd_data->cdev.dev);
- 	watchdog_cdev_unregister(wdd);
- }
- 
---- a/include/linux/watchdog.h
-+++ b/include/linux/watchdog.h
-@@ -55,7 +55,6 @@ struct watchdog_ops {
- /** struct watchdog_device - The structure that defines a watchdog device
-  *
-  * @id:		The watchdog's ID. (Allocated by watchdog_register_device)
-- * @dev:	The device for our watchdog
-  * @parent:	The parent bus device
-  * @info:	Pointer to a watchdog_info structure.
-  * @ops:	Pointer to the list of watchdog operations.
-@@ -82,7 +81,6 @@ struct watchdog_ops {
-  */
- struct watchdog_device {
- 	int id;
--	struct device *dev;
- 	struct device *parent;
- 	const struct watchdog_info *info;
- 	const struct watchdog_ops *ops;
diff --git a/target/linux/ipq806x/patches-4.4/009-8-watchdog-kill-unref-ref-ops.patch b/target/linux/ipq806x/patches-4.4/009-8-watchdog-kill-unref-ref-ops.patch
deleted file mode 100644
index ba56a86..0000000
--- a/target/linux/ipq806x/patches-4.4/009-8-watchdog-kill-unref-ref-ops.patch
+++ /dev/null
@@ -1,26 +0,0 @@
-From 62cd1c40ce1c7c16835b599751c7a002eb5bbdf5 Mon Sep 17 00:00:00 2001
-From: Tomas Winkler <tomas.winkler at intel.com>
-Date: Sun, 3 Jan 2016 13:32:37 +0200
-Subject: watchdog: kill unref/ref ops
-
-ref/unref ops are not called at all so even marked them as deprecated
-is misleading, we need to just drop the API.
-
-Signed-off-by: Tomas Winkler <tomas.winkler at intel.com>
-Signed-off-by: Guenter Roeck <linux at roeck-us.net>
-Signed-off-by: Wim Van Sebroeck <wim at iguana.be>
----
- include/linux/watchdog.h | 2 --
- 1 file changed, 2 deletions(-)
-
---- a/include/linux/watchdog.h
-+++ b/include/linux/watchdog.h
-@@ -47,8 +47,6 @@ struct watchdog_ops {
- 	int (*set_timeout)(struct watchdog_device *, unsigned int);
- 	unsigned int (*get_timeleft)(struct watchdog_device *);
- 	int (*restart)(struct watchdog_device *);
--	void (*ref)(struct watchdog_device *) __deprecated;
--	void (*unref)(struct watchdog_device *) __deprecated;
- 	long (*ioctl)(struct watchdog_device *, unsigned int, unsigned long);
- };
- 
diff --git a/target/linux/ipq806x/patches-4.4/010-1-qcom-wdt-use-core-restart-handler.patch b/target/linux/ipq806x/patches-4.4/010-1-qcom-wdt-use-core-restart-handler.patch
deleted file mode 100644
index d36dedc..0000000
--- a/target/linux/ipq806x/patches-4.4/010-1-qcom-wdt-use-core-restart-handler.patch
+++ /dev/null
@@ -1,113 +0,0 @@
-From 80969a68ffed12f82e2a29908306ff43a6861a61 Mon Sep 17 00:00:00 2001
-From: Damien Riegel <damien.riegel at savoirfairelinux.com>
-Date: Mon, 16 Nov 2015 12:28:09 -0500
-Subject: watchdog: qcom-wdt: use core restart handler
-
-Get rid of the custom restart handler by using the one provided by the
-watchdog core.
-
-Signed-off-by: Damien Riegel <damien.riegel at savoirfairelinux.com>
-Reviewed-by: Guenter Roeck <linux at roeck-us.net>
-Reviewed-by: Vivien Didelot <vivien.didelot at savoirfairelinux.com>
-Signed-off-by: Guenter Roeck <linux at roeck-us.net>
-Signed-off-by: Wim Van Sebroeck <wim at iguana.be>
----
- drivers/watchdog/qcom-wdt.c | 49 ++++++++++++++++++---------------------------
- 1 file changed, 19 insertions(+), 30 deletions(-)
-
---- a/drivers/watchdog/qcom-wdt.c
-+++ b/drivers/watchdog/qcom-wdt.c
-@@ -17,7 +17,6 @@
- #include <linux/module.h>
- #include <linux/of.h>
- #include <linux/platform_device.h>
--#include <linux/reboot.h>
- #include <linux/watchdog.h>
- 
- #define WDT_RST		0x38
-@@ -28,7 +27,6 @@ struct qcom_wdt {
- 	struct watchdog_device	wdd;
- 	struct clk		*clk;
- 	unsigned long		rate;
--	struct notifier_block	restart_nb;
- 	void __iomem		*base;
- };
- 
-@@ -72,25 +70,9 @@ static int qcom_wdt_set_timeout(struct w
- 	return qcom_wdt_start(wdd);
- }
- 
--static const struct watchdog_ops qcom_wdt_ops = {
--	.start		= qcom_wdt_start,
--	.stop		= qcom_wdt_stop,
--	.ping		= qcom_wdt_ping,
--	.set_timeout	= qcom_wdt_set_timeout,
--	.owner		= THIS_MODULE,
--};
--
--static const struct watchdog_info qcom_wdt_info = {
--	.options	= WDIOF_KEEPALIVEPING
--			| WDIOF_MAGICCLOSE
--			| WDIOF_SETTIMEOUT,
--	.identity	= KBUILD_MODNAME,
--};
--
--static int qcom_wdt_restart(struct notifier_block *nb, unsigned long action,
--			    void *data)
-+static int qcom_wdt_restart(struct watchdog_device *wdd)
- {
--	struct qcom_wdt *wdt = container_of(nb, struct qcom_wdt, restart_nb);
-+	struct qcom_wdt *wdt = to_qcom_wdt(wdd);
- 	u32 timeout;
- 
- 	/*
-@@ -110,9 +92,25 @@ static int qcom_wdt_restart(struct notif
- 	wmb();
- 
- 	msleep(150);
--	return NOTIFY_DONE;
-+	return 0;
- }
- 
-+static const struct watchdog_ops qcom_wdt_ops = {
-+	.start		= qcom_wdt_start,
-+	.stop		= qcom_wdt_stop,
-+	.ping		= qcom_wdt_ping,
-+	.set_timeout	= qcom_wdt_set_timeout,
-+	.restart        = qcom_wdt_restart,
-+	.owner		= THIS_MODULE,
-+};
-+
-+static const struct watchdog_info qcom_wdt_info = {
-+	.options	= WDIOF_KEEPALIVEPING
-+			| WDIOF_MAGICCLOSE
-+			| WDIOF_SETTIMEOUT,
-+	.identity	= KBUILD_MODNAME,
-+};
-+
- static int qcom_wdt_probe(struct platform_device *pdev)
- {
- 	struct qcom_wdt *wdt;
-@@ -187,14 +185,6 @@ static int qcom_wdt_probe(struct platfor
- 		goto err_clk_unprepare;
- 	}
- 
--	/*
--	 * WDT restart notifier has priority 0 (use as a last resort)
--	 */
--	wdt->restart_nb.notifier_call = qcom_wdt_restart;
--	ret = register_restart_handler(&wdt->restart_nb);
--	if (ret)
--		dev_err(&pdev->dev, "failed to setup restart handler\n");
--
- 	platform_set_drvdata(pdev, wdt);
- 	return 0;
- 
-@@ -207,7 +197,6 @@ static int qcom_wdt_remove(struct platfo
- {
- 	struct qcom_wdt *wdt = platform_get_drvdata(pdev);
- 
--	unregister_restart_handler(&wdt->restart_nb);
- 	watchdog_unregister_device(&wdt->wdd);
- 	clk_disable_unprepare(wdt->clk);
- 	return 0;
diff --git a/target/linux/ipq806x/patches-4.4/010-2-qcom-wdt-Do-not-set-dev-in-struct-watchdog_device.patch b/target/linux/ipq806x/patches-4.4/010-2-qcom-wdt-Do-not-set-dev-in-struct-watchdog_device.patch
deleted file mode 100644
index 31371c2..0000000
--- a/target/linux/ipq806x/patches-4.4/010-2-qcom-wdt-Do-not-set-dev-in-struct-watchdog_device.patch
+++ /dev/null
@@ -1,25 +0,0 @@
-From 0933b453f1c7104d873aacf8524f8ac380a7ed08 Mon Sep 17 00:00:00 2001
-From: Guenter Roeck <linux at roeck-us.net>
-Date: Thu, 24 Dec 2015 14:22:04 -0800
-Subject: watchdog: qcom-wdt: Do not set 'dev' in struct watchdog_device
-
-The 'dev' pointer in struct watchdog_device is set by the watchdog core
-when registering the watchdog device and not by the driver. It points to
-the watchdog device, not its parent.
-
-Signed-off-by: Guenter Roeck <linux at roeck-us.net>
-Signed-off-by: Wim Van Sebroeck <wim at iguana.be>
----
- drivers/watchdog/qcom-wdt.c | 1 -
- 1 file changed, 1 deletion(-)
-
---- a/drivers/watchdog/qcom-wdt.c
-+++ b/drivers/watchdog/qcom-wdt.c
-@@ -164,7 +164,6 @@ static int qcom_wdt_probe(struct platfor
- 		goto err_clk_unprepare;
- 	}
- 
--	wdt->wdd.dev = &pdev->dev;
- 	wdt->wdd.info = &qcom_wdt_info;
- 	wdt->wdd.ops = &qcom_wdt_ops;
- 	wdt->wdd.min_timeout = 1;
diff --git a/target/linux/ipq806x/patches-4.4/010-3-watchdog-Add-action-and-data-parameters-to-restart-handler-callback.patch b/target/linux/ipq806x/patches-4.4/010-3-watchdog-Add-action-and-data-parameters-to-restart-handler-callback.patch
deleted file mode 100644
index 7ceff32..0000000
--- a/target/linux/ipq806x/patches-4.4/010-3-watchdog-Add-action-and-data-parameters-to-restart-handler-callback.patch
+++ /dev/null
@@ -1,51 +0,0 @@
-rom 4d8b229d5ea610affe672e919021e9d02cd877da Mon Sep 17 00:00:00 2001
-From: Guenter Roeck <linux at roeck-us.net>
-Date: Fri, 26 Feb 2016 17:32:49 -0800
-Subject: watchdog: Add 'action' and 'data' parameters to restart handler
- callback
-
-The 'action' (or restart mode) and data parameters may be used by restart
-handlers, so they should be passed to the restart callback functions.
-
-Cc: Sylvain Lemieux <slemieux at tycoint.com>
-Signed-off-by: Guenter Roeck <linux at roeck-us.net>
-Signed-off-by: Wim Van Sebroeck <wim at iguana.be>
----
- drivers/watchdog/qcom-wdt.c      | 3 ++-
- drivers/watchdog/watchdog_core.c | 2 +-
- include/linux/watchdog.h         | 2 +-
-
---- a/drivers/watchdog/qcom-wdt.c
-+++ b/drivers/watchdog/qcom-wdt.c
-@@ -70,7 +70,8 @@ static int qcom_wdt_set_timeout(struct w
- 	return qcom_wdt_start(wdd);
- }
- 
--static int qcom_wdt_restart(struct watchdog_device *wdd)
-+static int qcom_wdt_restart(struct watchdog_device *wdd, unsigned long action,
-+			    void *data)
- {
- 	struct qcom_wdt *wdt = to_qcom_wdt(wdd);
- 	u32 timeout;
---- a/drivers/watchdog/watchdog_core.c
-+++ b/drivers/watchdog/watchdog_core.c
-@@ -164,7 +164,7 @@ static int watchdog_restart_notifier(str
- 
- 	int ret;
- 
--	ret = wdd->ops->restart(wdd);
-+	ret = wdd->ops->restart(wdd, action, data);
- 	if (ret)
- 		return NOTIFY_BAD;
- 
---- a/include/linux/watchdog.h
-+++ b/include/linux/watchdog.h
-@@ -46,7 +46,7 @@ struct watchdog_ops {
- 	unsigned int (*status)(struct watchdog_device *);
- 	int (*set_timeout)(struct watchdog_device *, unsigned int);
- 	unsigned int (*get_timeleft)(struct watchdog_device *);
--	int (*restart)(struct watchdog_device *);
-+	int (*restart)(struct watchdog_device *, unsigned long, void *);
- 	long (*ioctl)(struct watchdog_device *, unsigned int, unsigned long);
- };
- 
diff --git a/target/linux/ipq806x/patches-4.4/010-4-watchdog-qcom-Report-reboot-reason.patch b/target/linux/ipq806x/patches-4.4/010-4-watchdog-qcom-Report-reboot-reason.patch
deleted file mode 100644
index f7fcaee..0000000
--- a/target/linux/ipq806x/patches-4.4/010-4-watchdog-qcom-Report-reboot-reason.patch
+++ /dev/null
@@ -1,46 +0,0 @@
-From b6ef36d2c1e391adc1fe1b2dd2a0f887a9f3052b Mon Sep 17 00:00:00 2001
-From: Guenter Roeck <groeck at chromium.org>
-Date: Mon, 4 Apr 2016 17:37:46 -0700
-Subject: watchdog: qcom: Report reboot reason
-
-The Qualcom watchdog timer block reports if the system was reset by the
-watchdog. Pass the information to user space.
-
-Reviewed-by: Grant Grundler <grundler at chromium.org>
-Tested-by: Grant Grundler <grundler at chromium.org>
-Signed-off-by: Guenter Roeck <groeck at chromium.org>
-Signed-off-by: Wim Van Sebroeck <wim at iguana.be>
----
- drivers/watchdog/qcom-wdt.c | 7 ++++++-
- 1 file changed, 6 insertions(+), 1 deletion(-)
-
---- a/drivers/watchdog/qcom-wdt.c
-+++ b/drivers/watchdog/qcom-wdt.c
-@@ -21,6 +21,7 @@
- 
- #define WDT_RST		0x38
- #define WDT_EN		0x40
-+#define WDT_STS		0x44
- #define WDT_BITE_TIME	0x5C
- 
- struct qcom_wdt {
-@@ -108,7 +109,8 @@ static const struct watchdog_ops qcom_wd
- static const struct watchdog_info qcom_wdt_info = {
- 	.options	= WDIOF_KEEPALIVEPING
- 			| WDIOF_MAGICCLOSE
--			| WDIOF_SETTIMEOUT,
-+			| WDIOF_SETTIMEOUT
-+			| WDIOF_CARDRESET,
- 	.identity	= KBUILD_MODNAME,
- };
- 
-@@ -171,6 +173,9 @@ static int qcom_wdt_probe(struct platfor
- 	wdt->wdd.max_timeout = 0x10000000U / wdt->rate;
- 	wdt->wdd.parent = &pdev->dev;
- 
-+	if (readl(wdt->base + WDT_STS) & 1)
-+		wdt->wdd.bootstatus = WDIOF_CARDRESET;
-+
- 	/*
- 	 * If 'timeout-sec' unspecified in devicetree, assume a 30 second
- 	 * default, unless the max timeout is less than 30 seconds, then use
diff --git a/target/linux/ipq806x/patches-4.4/010-5-watchdog-qcom-add-option-for-standalone-watchdog-not-in-timer-block.patch b/target/linux/ipq806x/patches-4.4/010-5-watchdog-qcom-add-option-for-standalone-watchdog-not-in-timer-block.patch
deleted file mode 100644
index 82dd875..0000000
--- a/target/linux/ipq806x/patches-4.4/010-5-watchdog-qcom-add-option-for-standalone-watchdog-not-in-timer-block.patch
+++ /dev/null
@@ -1,162 +0,0 @@
-From f0d9d0f4b44ae5503ea368e7f066b20f12ca1d37 Mon Sep 17 00:00:00 2001
-From: Matthew McClintock <mmcclint at codeaurora.org>
-Date: Wed, 29 Jun 2016 10:50:01 -0700
-Subject: watchdog: qcom: add option for standalone watchdog not in timer block
-
-Commit 0dfd582e026a ("watchdog: qcom: use timer devicetree
-binding") moved to use the watchdog as a subset timer
-register block. Some devices have the watchdog completely
-standalone with slightly different register offsets as
-well so let's account for the differences here.
-
-The existing "kpss-standalone" compatible string doesn't
-make it entirely clear exactly what the device is so
-rename to "kpss-wdt" to reflect watchdog timer
-functionality. Also update ipq4019 DTS with an SoC
-specific compatible.
-
-Signed-off-by: Matthew McClintock <mmcclint at codeaurora.org>
-Signed-off-by: Thomas Pedersen <twp at codeaurora.org>
-Reviewed-by: Guenter Roeck <linux at roeck-us.net>
-Signed-off-by: Guenter Roeck <linux at roeck-us.net>
-Signed-off-by: Wim Van Sebroeck <wim at iguana.be>
----
- .../devicetree/bindings/watchdog/qcom-wdt.txt      |  2 +
- arch/arm/boot/dts/qcom-ipq4019.dtsi                |  2 +-
- drivers/watchdog/qcom-wdt.c                        | 64 ++++++++++++++++------
- 3 files changed, 51 insertions(+), 17 deletions(-)
-
---- a/drivers/watchdog/qcom-wdt.c
-+++ b/drivers/watchdog/qcom-wdt.c
-@@ -18,19 +18,42 @@
- #include <linux/of.h>
- #include <linux/platform_device.h>
- #include <linux/watchdog.h>
-+#include <linux/of_device.h>
- 
--#define WDT_RST		0x38
--#define WDT_EN		0x40
--#define WDT_STS		0x44
--#define WDT_BITE_TIME	0x5C
-+enum wdt_reg {
-+	WDT_RST,
-+	WDT_EN,
-+	WDT_STS,
-+	WDT_BITE_TIME,
-+};
-+
-+static const u32 reg_offset_data_apcs_tmr[] = {
-+	[WDT_RST] = 0x38,
-+	[WDT_EN] = 0x40,
-+	[WDT_STS] = 0x44,
-+	[WDT_BITE_TIME] = 0x5C,
-+};
-+
-+static const u32 reg_offset_data_kpss[] = {
-+	[WDT_RST] = 0x4,
-+	[WDT_EN] = 0x8,
-+	[WDT_STS] = 0xC,
-+	[WDT_BITE_TIME] = 0x14,
-+};
- 
- struct qcom_wdt {
- 	struct watchdog_device	wdd;
- 	struct clk		*clk;
- 	unsigned long		rate;
- 	void __iomem		*base;
-+	const u32		*layout;
- };
- 
-+static void __iomem *wdt_addr(struct qcom_wdt *wdt, enum wdt_reg reg)
-+{
-+	return wdt->base + wdt->layout[reg];
-+}
-+
- static inline
- struct qcom_wdt *to_qcom_wdt(struct watchdog_device *wdd)
- {
-@@ -41,10 +64,10 @@ static int qcom_wdt_start(struct watchdo
- {
- 	struct qcom_wdt *wdt = to_qcom_wdt(wdd);
- 
--	writel(0, wdt->base + WDT_EN);
--	writel(1, wdt->base + WDT_RST);
--	writel(wdd->timeout * wdt->rate, wdt->base + WDT_BITE_TIME);
--	writel(1, wdt->base + WDT_EN);
-+	writel(0, wdt_addr(wdt, WDT_EN));
-+	writel(1, wdt_addr(wdt, WDT_RST));
-+	writel(wdd->timeout * wdt->rate, wdt_addr(wdt, WDT_BITE_TIME));
-+	writel(1, wdt_addr(wdt, WDT_EN));
- 	return 0;
- }
- 
-@@ -52,7 +75,7 @@ static int qcom_wdt_stop(struct watchdog
- {
- 	struct qcom_wdt *wdt = to_qcom_wdt(wdd);
- 
--	writel(0, wdt->base + WDT_EN);
-+	writel(0, wdt_addr(wdt, WDT_EN));
- 	return 0;
- }
- 
-@@ -60,7 +83,7 @@ static int qcom_wdt_ping(struct watchdog
- {
- 	struct qcom_wdt *wdt = to_qcom_wdt(wdd);
- 
--	writel(1, wdt->base + WDT_RST);
-+	writel(1, wdt_addr(wdt, WDT_RST));
- 	return 0;
- }
- 
-@@ -83,10 +106,10 @@ static int qcom_wdt_restart(struct watch
- 	 */
- 	timeout = 128 * wdt->rate / 1000;
- 
--	writel(0, wdt->base + WDT_EN);
--	writel(1, wdt->base + WDT_RST);
--	writel(timeout, wdt->base + WDT_BITE_TIME);
--	writel(1, wdt->base + WDT_EN);
-+	writel(0, wdt_addr(wdt, WDT_EN));
-+	writel(1, wdt_addr(wdt, WDT_RST));
-+	writel(timeout, wdt_addr(wdt, WDT_BITE_TIME));
-+	writel(1, wdt_addr(wdt, WDT_EN));
- 
- 	/*
- 	 * Actually make sure the above sequence hits hardware before sleeping.
-@@ -119,9 +142,16 @@ static int qcom_wdt_probe(struct platfor
- 	struct qcom_wdt *wdt;
- 	struct resource *res;
- 	struct device_node *np = pdev->dev.of_node;
-+	const u32 *regs;
- 	u32 percpu_offset;
- 	int ret;
- 
-+	regs = of_device_get_match_data(&pdev->dev);
-+	if (!regs) {
-+		dev_err(&pdev->dev, "Unsupported QCOM WDT module\n");
-+		return -ENODEV;
-+	}
-+
- 	wdt = devm_kzalloc(&pdev->dev, sizeof(*wdt), GFP_KERNEL);
- 	if (!wdt)
- 		return -ENOMEM;
-@@ -172,6 +202,7 @@ static int qcom_wdt_probe(struct platfor
- 	wdt->wdd.min_timeout = 1;
- 	wdt->wdd.max_timeout = 0x10000000U / wdt->rate;
- 	wdt->wdd.parent = &pdev->dev;
-+	wdt->layout = regs;
- 
- 	if (readl(wdt->base + WDT_STS) & 1)
- 		wdt->wdd.bootstatus = WDIOF_CARDRESET;
-@@ -208,8 +239,9 @@ static int qcom_wdt_remove(struct platfo
- }
- 
- static const struct of_device_id qcom_wdt_of_table[] = {
--	{ .compatible = "qcom,kpss-timer" },
--	{ .compatible = "qcom,scss-timer" },
-+	{ .compatible = "qcom,kpss-timer", .data = reg_offset_data_apcs_tmr },
-+	{ .compatible = "qcom,scss-timer", .data = reg_offset_data_apcs_tmr },
-+	{ .compatible = "qcom,kpss-wdt", .data = reg_offset_data_kpss },
- 	{ },
- };
- MODULE_DEVICE_TABLE(of, qcom_wdt_of_table);
diff --git a/target/linux/ipq806x/patches-4.4/010-6-watchdog-qcom-configure-BARK-time-in-addition-to-BITE-time.patch b/target/linux/ipq806x/patches-4.4/010-6-watchdog-qcom-configure-BARK-time-in-addition-to-BITE-time.patch
deleted file mode 100644
index bdc3f99..0000000
--- a/target/linux/ipq806x/patches-4.4/010-6-watchdog-qcom-configure-BARK-time-in-addition-to-BITE-time.patch
+++ /dev/null
@@ -1,60 +0,0 @@
-From 10073a205df269abcbd9c3fbc690a813827107ef Mon Sep 17 00:00:00 2001
-From: Matthew McClintock <mmcclint at codeaurora.org>
-Date: Tue, 28 Jun 2016 11:35:21 -0700
-Subject: watchdog: qcom: configure BARK time in addition to BITE time
-
-For certain parts and some versions of TZ, TZ will reset the chip
-when a BARK is triggered even though it was not configured here. So
-by default let's configure this BARK time as well.
-
-Signed-off-by: Matthew McClintock <mmcclint at codeaurora.org>
-Reviewed-by: Guenter Roeck <linux at roeck-us.net>
-Signed-off-by: Thomas Pedersen <twp at codeaurora.org>
-Signed-off-by: Guenter Roeck <linux at roeck-us.net>
-Signed-off-by: Wim Van Sebroeck <wim at iguana.be>
----
- drivers/watchdog/qcom-wdt.c | 5 +++++
- 1 file changed, 5 insertions(+)
-
---- a/drivers/watchdog/qcom-wdt.c
-+++ b/drivers/watchdog/qcom-wdt.c
-@@ -24,6 +24,7 @@ enum wdt_reg {
- 	WDT_RST,
- 	WDT_EN,
- 	WDT_STS,
-+	WDT_BARK_TIME,
- 	WDT_BITE_TIME,
- };
- 
-@@ -31,6 +32,7 @@ static const u32 reg_offset_data_apcs_tm
- 	[WDT_RST] = 0x38,
- 	[WDT_EN] = 0x40,
- 	[WDT_STS] = 0x44,
-+	[WDT_BARK_TIME] = 0x4C,
- 	[WDT_BITE_TIME] = 0x5C,
- };
- 
-@@ -38,6 +40,7 @@ static const u32 reg_offset_data_kpss[]
- 	[WDT_RST] = 0x4,
- 	[WDT_EN] = 0x8,
- 	[WDT_STS] = 0xC,
-+	[WDT_BARK_TIME] = 0x10,
- 	[WDT_BITE_TIME] = 0x14,
- };
- 
-@@ -66,6 +69,7 @@ static int qcom_wdt_start(struct watchdo
- 
- 	writel(0, wdt_addr(wdt, WDT_EN));
- 	writel(1, wdt_addr(wdt, WDT_RST));
-+	writel(wdd->timeout * wdt->rate, wdt_addr(wdt, WDT_BARK_TIME));
- 	writel(wdd->timeout * wdt->rate, wdt_addr(wdt, WDT_BITE_TIME));
- 	writel(1, wdt_addr(wdt, WDT_EN));
- 	return 0;
-@@ -108,6 +112,7 @@ static int qcom_wdt_restart(struct watch
- 
- 	writel(0, wdt_addr(wdt, WDT_EN));
- 	writel(1, wdt_addr(wdt, WDT_RST));
-+	writel(timeout, wdt_addr(wdt, WDT_BARK_TIME));
- 	writel(timeout, wdt_addr(wdt, WDT_BITE_TIME));
- 	writel(1, wdt_addr(wdt, WDT_EN));
- 
diff --git a/target/linux/ipq806x/patches-4.4/011-1-fix-bld-errs-hwmon-sch56xx-Drop-watchdog-driver-data-reference-count-callbacks.patch b/target/linux/ipq806x/patches-4.4/011-1-fix-bld-errs-hwmon-sch56xx-Drop-watchdog-driver-data-reference-count-callbacks.patch
deleted file mode 100644
index c78202b..0000000
--- a/target/linux/ipq806x/patches-4.4/011-1-fix-bld-errs-hwmon-sch56xx-Drop-watchdog-driver-data-reference-count-callbacks.patch
+++ /dev/null
@@ -1,95 +0,0 @@
-From 3b8d058cfe6a3b14abee324f4c4b33e64bf61aeb Mon Sep 17 00:00:00 2001
-From: Guenter Roeck <linux at roeck-us.net>
-Date: Fri, 25 Dec 2015 16:01:45 -0800
-Subject: hwmon: (sch56xx) Drop watchdog driver data reference count callbacks
-
-Reference counting is now implemented in the watchdog core and no longer
-required in watchdog drivers.
-
-Signed-off-by: Guenter Roeck <linux at roeck-us.net>
-Signed-off-by: Wim Van Sebroeck <wim at iguana.be>
----
- drivers/hwmon/sch56xx-common.c | 31 +------------------------------
- 1 file changed, 1 insertion(+), 30 deletions(-)
-
---- a/drivers/hwmon/sch56xx-common.c
-+++ b/drivers/hwmon/sch56xx-common.c
-@@ -30,7 +30,6 @@
- #include <linux/watchdog.h>
- #include <linux/miscdevice.h>
- #include <linux/uaccess.h>
--#include <linux/kref.h>
- #include <linux/slab.h>
- #include "sch56xx-common.h"
- 
-@@ -67,7 +66,6 @@ MODULE_PARM_DESC(nowayout, "Watchdog can
- struct sch56xx_watchdog_data {
- 	u16 addr;
- 	struct mutex *io_lock;
--	struct kref kref;
- 	struct watchdog_info wdinfo;
- 	struct watchdog_device wddev;
- 	u8 watchdog_preset;
-@@ -258,15 +256,6 @@ EXPORT_SYMBOL(sch56xx_read_virtual_reg12
-  * Watchdog routines
-  */
- 
--/* Release our data struct when we're unregistered *and*
--   all references to our watchdog device are released */
--static void watchdog_release_resources(struct kref *r)
--{
--	struct sch56xx_watchdog_data *data =
--		container_of(r, struct sch56xx_watchdog_data, kref);
--	kfree(data);
--}
--
- static int watchdog_set_timeout(struct watchdog_device *wddev,
- 				unsigned int timeout)
- {
-@@ -395,28 +384,12 @@ static int watchdog_stop(struct watchdog
- 	return 0;
- }
- 
--static void watchdog_ref(struct watchdog_device *wddev)
--{
--	struct sch56xx_watchdog_data *data = watchdog_get_drvdata(wddev);
--
--	kref_get(&data->kref);
--}
--
--static void watchdog_unref(struct watchdog_device *wddev)
--{
--	struct sch56xx_watchdog_data *data = watchdog_get_drvdata(wddev);
--
--	kref_put(&data->kref, watchdog_release_resources);
--}
--
- static const struct watchdog_ops watchdog_ops = {
- 	.owner		= THIS_MODULE,
- 	.start		= watchdog_start,
- 	.stop		= watchdog_stop,
- 	.ping		= watchdog_trigger,
- 	.set_timeout	= watchdog_set_timeout,
--	.ref		= watchdog_ref,
--	.unref		= watchdog_unref,
- };
- 
- struct sch56xx_watchdog_data *sch56xx_watchdog_register(struct device *parent,
-@@ -448,7 +421,6 @@ struct sch56xx_watchdog_data *sch56xx_wa
- 
- 	data->addr = addr;
- 	data->io_lock = io_lock;
--	kref_init(&data->kref);
- 
- 	strlcpy(data->wdinfo.identity, "sch56xx watchdog",
- 		sizeof(data->wdinfo.identity));
-@@ -494,8 +466,7 @@ EXPORT_SYMBOL(sch56xx_watchdog_register)
- void sch56xx_watchdog_unregister(struct sch56xx_watchdog_data *data)
- {
- 	watchdog_unregister_device(&data->wddev);
--	kref_put(&data->kref, watchdog_release_resources);
--	/* Don't touch data after this it may have been free-ed! */
-+	kfree(data);
- }
- EXPORT_SYMBOL(sch56xx_watchdog_unregister);
- 
diff --git a/target/linux/ipq806x/patches-4.4/011-2-fix-bld-errs-watchdog-da9052_wdt-Drop-reference-counting.patch b/target/linux/ipq806x/patches-4.4/011-2-fix-bld-errs-watchdog-da9052_wdt-Drop-reference-counting.patch
deleted file mode 100644
index 501bd13..0000000
--- a/target/linux/ipq806x/patches-4.4/011-2-fix-bld-errs-watchdog-da9052_wdt-Drop-reference-counting.patch
+++ /dev/null
@@ -1,87 +0,0 @@
-From 756d1e9247dff6d416b0c9e073247f5e808bb5fa Mon Sep 17 00:00:00 2001
-From: Guenter Roeck <linux at roeck-us.net>
-Date: Fri, 25 Dec 2015 16:01:43 -0800
-Subject: watchdog: da9052_wdt: Drop reference counting
-
-Reference counting is now implemented in the watchdog core and no longer
-required in watchdog drivers.
-
-Since it was implememented a no-op, and since the local memory is allocated
-with devm_kzalloc(), the reference counting code in the driver really did
-not really work anyway, and this patch effectively fixes a bug which could
-cause a crash on unloading if the watchdog device was still open.
-
-Signed-off-by: Guenter Roeck <linux at roeck-us.net>
-Signed-off-by: Wim Van Sebroeck <wim at iguana.be>
----
- drivers/watchdog/da9052_wdt.c | 24 ------------------------
- 1 file changed, 24 deletions(-)
-
---- a/drivers/watchdog/da9052_wdt.c
-+++ b/drivers/watchdog/da9052_wdt.c
-@@ -31,7 +31,6 @@
- struct da9052_wdt_data {
- 	struct watchdog_device wdt;
- 	struct da9052 *da9052;
--	struct kref kref;
- 	unsigned long jpast;
- };
- 
-@@ -51,10 +50,6 @@ static const struct {
- };
- 
- 
--static void da9052_wdt_release_resources(struct kref *r)
--{
--}
--
- static int da9052_wdt_set_timeout(struct watchdog_device *wdt_dev,
- 				  unsigned int timeout)
- {
-@@ -104,20 +99,6 @@ static int da9052_wdt_set_timeout(struct
- 	return 0;
- }
- 
--static void da9052_wdt_ref(struct watchdog_device *wdt_dev)
--{
--	struct da9052_wdt_data *driver_data = watchdog_get_drvdata(wdt_dev);
--
--	kref_get(&driver_data->kref);
--}
--
--static void da9052_wdt_unref(struct watchdog_device *wdt_dev)
--{
--	struct da9052_wdt_data *driver_data = watchdog_get_drvdata(wdt_dev);
--
--	kref_put(&driver_data->kref, da9052_wdt_release_resources);
--}
--
- static int da9052_wdt_start(struct watchdog_device *wdt_dev)
- {
- 	return da9052_wdt_set_timeout(wdt_dev, wdt_dev->timeout);
-@@ -170,8 +151,6 @@ static const struct watchdog_ops da9052_
- 	.stop = da9052_wdt_stop,
- 	.ping = da9052_wdt_ping,
- 	.set_timeout = da9052_wdt_set_timeout,
--	.ref = da9052_wdt_ref,
--	.unref = da9052_wdt_unref,
- };
- 
- 
-@@ -198,8 +177,6 @@ static int da9052_wdt_probe(struct platf
- 	da9052_wdt->parent = &pdev->dev;
- 	watchdog_set_drvdata(da9052_wdt, driver_data);
- 
--	kref_init(&driver_data->kref);
--
- 	ret = da9052_reg_update(da9052, DA9052_CONTROL_D_REG,
- 				DA9052_CONTROLD_TWDSCALE, 0);
- 	if (ret < 0) {
-@@ -225,7 +202,6 @@ static int da9052_wdt_remove(struct plat
- 	struct da9052_wdt_data *driver_data = platform_get_drvdata(pdev);
- 
- 	watchdog_unregister_device(&driver_data->wdt);
--	kref_put(&driver_data->kref, da9052_wdt_release_resources);
- 
- 	return 0;
- }
diff --git a/target/linux/ipq806x/patches-4.4/011-3-fix-bld-errs-watchdog-da9055_wdt-Drop-reference-counting.patch b/target/linux/ipq806x/patches-4.4/011-3-fix-bld-errs-watchdog-da9055_wdt-Drop-reference-counting.patch
deleted file mode 100644
index 3cf723a..0000000
--- a/target/linux/ipq806x/patches-4.4/011-3-fix-bld-errs-watchdog-da9055_wdt-Drop-reference-counting.patch
+++ /dev/null
@@ -1,80 +0,0 @@
-From 43f676ace2e0591718ff493d290bc49b35ec2ffc Mon Sep 17 00:00:00 2001
-From: Guenter Roeck <linux at roeck-us.net>
-Date: Fri, 25 Dec 2015 16:01:44 -0800
-Subject: watchdog: da9055_wdt: Drop reference counting
-
-Reference counting is now implemented in the watchdog core and no longer
-required in watchdog drivers.
-
-Since it was implememented a no-op, and since the local memory is allocated
-with devm_kzalloc(), the reference counting code in the driver really did
-not really work anyway, and this patch effectively fixes a bug which could
-cause a crash on unloading if the watchdog device was still open.
-
-Signed-off-by: Guenter Roeck <linux at roeck-us.net>
-Signed-off-by: Wim Van Sebroeck <wim at iguana.be>
----
- drivers/watchdog/da9055_wdt.c | 24 ------------------------
- 1 file changed, 24 deletions(-)
-
---- a/drivers/watchdog/da9055_wdt.c
-+++ b/drivers/watchdog/da9055_wdt.c
-@@ -35,7 +35,6 @@ MODULE_PARM_DESC(nowayout,
- struct da9055_wdt_data {
- 	struct watchdog_device wdt;
- 	struct da9055 *da9055;
--	struct kref kref;
- };
- 
- static const struct {
-@@ -99,24 +98,6 @@ static int da9055_wdt_ping(struct watchd
- 				 DA9055_WATCHDOG_MASK, 1);
- }
- 
--static void da9055_wdt_release_resources(struct kref *r)
--{
--}
--
--static void da9055_wdt_ref(struct watchdog_device *wdt_dev)
--{
--	struct da9055_wdt_data *driver_data = watchdog_get_drvdata(wdt_dev);
--
--	kref_get(&driver_data->kref);
--}
--
--static void da9055_wdt_unref(struct watchdog_device *wdt_dev)
--{
--	struct da9055_wdt_data *driver_data = watchdog_get_drvdata(wdt_dev);
--
--	kref_put(&driver_data->kref, da9055_wdt_release_resources);
--}
--
- static int da9055_wdt_start(struct watchdog_device *wdt_dev)
- {
- 	return da9055_wdt_set_timeout(wdt_dev, wdt_dev->timeout);
-@@ -138,8 +119,6 @@ static const struct watchdog_ops da9055_
- 	.stop = da9055_wdt_stop,
- 	.ping = da9055_wdt_ping,
- 	.set_timeout = da9055_wdt_set_timeout,
--	.ref = da9055_wdt_ref,
--	.unref = da9055_wdt_unref,
- };
- 
- static int da9055_wdt_probe(struct platform_device *pdev)
-@@ -165,8 +144,6 @@ static int da9055_wdt_probe(struct platf
- 	watchdog_set_nowayout(da9055_wdt, nowayout);
- 	watchdog_set_drvdata(da9055_wdt, driver_data);
- 
--	kref_init(&driver_data->kref);
--
- 	ret = da9055_wdt_stop(da9055_wdt);
- 	if (ret < 0) {
- 		dev_err(&pdev->dev, "Failed to stop watchdog, %d\n", ret);
-@@ -189,7 +166,6 @@ static int da9055_wdt_remove(struct plat
- 	struct da9055_wdt_data *driver_data = platform_get_drvdata(pdev);
- 
- 	watchdog_unregister_device(&driver_data->wdt);
--	kref_put(&driver_data->kref, da9055_wdt_release_resources);
- 
- 	return 0;
- }
diff --git a/target/linux/ipq806x/patches-4.4/012-1-clk-qcom-Add-support-for-SMD-RPM-Clocks.patch b/target/linux/ipq806x/patches-4.4/012-1-clk-qcom-Add-support-for-SMD-RPM-Clocks.patch
deleted file mode 100644
index 83b97bf..0000000
--- a/target/linux/ipq806x/patches-4.4/012-1-clk-qcom-Add-support-for-SMD-RPM-Clocks.patch
+++ /dev/null
@@ -1,746 +0,0 @@
-From patchwork Wed Nov  2 15:56:56 2016
-Content-Type: text/plain; charset="utf-8"
-MIME-Version: 1.0
-Content-Transfer-Encoding: 7bit
-Subject: [v9,1/3] clk: qcom: Add support for SMD-RPM Clocks
-From: Georgi Djakov <georgi.djakov at linaro.org>
-X-Patchwork-Id: 9409419
-Message-Id: <20161102155658.32203-2-georgi.djakov at linaro.org>
-To: sboyd at codeaurora.org, mturquette at baylibre.com
-Cc: linux-clk at vger.kernel.org, devicetree at vger.kernel.org,
- robh+dt at kernel.org, mark.rutland at arm.com,
- linux-kernel at vger.kernel.org, linux-arm-msm at vger.kernel.org,
- georgi.djakov at linaro.org
-Date: Wed,  2 Nov 2016 17:56:56 +0200
-
-This adds initial support for clocks controlled by the Resource
-Power Manager (RPM) processor on some Qualcomm SoCs, which use
-the qcom_smd_rpm driver to communicate with RPM.
-Such platforms are msm8916, apq8084 and msm8974.
-
-The RPM is a dedicated hardware engine for managing the shared
-SoC resources in order to keep the lowest power profile. It
-communicates with other hardware subsystems via shared memory
-and accepts clock requests, aggregates the requests and turns
-the clocks on/off or scales them on demand.
-
-This driver is based on the codeaurora.org driver:
-https://www.codeaurora.org/cgit/quic/la/kernel/msm-3.10/tree/drivers/clk/qcom/clock-rpm.c
-
-Signed-off-by: Georgi Djakov <georgi.djakov at linaro.org>
----
- .../devicetree/bindings/clock/qcom,rpmcc.txt       |  36 ++
- drivers/clk/qcom/Kconfig                           |  16 +
- drivers/clk/qcom/Makefile                          |   1 +
- drivers/clk/qcom/clk-smd-rpm.c                     | 571 +++++++++++++++++++++
- include/dt-bindings/clock/qcom,rpmcc.h             |  45 ++
- 5 files changed, 669 insertions(+)
- create mode 100644 Documentation/devicetree/bindings/clock/qcom,rpmcc.txt
- create mode 100644 drivers/clk/qcom/clk-smd-rpm.c
- create mode 100644 include/dt-bindings/clock/qcom,rpmcc.h
-
---
-To unsubscribe from this list: send the line "unsubscribe linux-arm-msm" in
-the body of a message to majordomo at vger.kernel.org
-More majordomo info at  http://vger.kernel.org/majordomo-info.html
-
---- /dev/null
-+++ b/Documentation/devicetree/bindings/clock/qcom,rpmcc.txt
-@@ -0,0 +1,36 @@
-+Qualcomm RPM Clock Controller Binding
-+------------------------------------------------
-+The RPM is a dedicated hardware engine for managing the shared
-+SoC resources in order to keep the lowest power profile. It
-+communicates with other hardware subsystems via shared memory
-+and accepts clock requests, aggregates the requests and turns
-+the clocks on/off or scales them on demand.
-+
-+Required properties :
-+- compatible : shall contain only one of the following. The generic
-+               compatible "qcom,rpmcc" should be also included.
-+
-+			"qcom,rpmcc-msm8916", "qcom,rpmcc"
-+
-+- #clock-cells : shall contain 1
-+
-+Example:
-+	smd {
-+		compatible = "qcom,smd";
-+
-+		rpm {
-+			interrupts = <0 168 1>;
-+			qcom,ipc = <&apcs 8 0>;
-+			qcom,smd-edge = <15>;
-+
-+			rpm_requests {
-+				compatible = "qcom,rpm-msm8916";
-+				qcom,smd-channels = "rpm_requests";
-+
-+				rpmcc: clock-controller {
-+					compatible = "qcom,rpmcc-msm8916", "qcom,rpmcc";
-+					#clock-cells = <1>;
-+				};
-+			};
-+		};
-+	};
---- a/drivers/clk/qcom/Kconfig
-+++ b/drivers/clk/qcom/Kconfig
-@@ -2,6 +2,9 @@ config QCOM_GDSC
- 	bool
- 	select PM_GENERIC_DOMAINS if PM
- 
-+config QCOM_RPMCC
-+	bool
-+
- config COMMON_CLK_QCOM
- 	tristate "Support for Qualcomm's clock controllers"
- 	depends on OF
-@@ -9,6 +12,19 @@ config COMMON_CLK_QCOM
- 	select REGMAP_MMIO
- 	select RESET_CONTROLLER
- 
-+config QCOM_CLK_SMD_RPM
-+	tristate "RPM over SMD based Clock Controller"
-+	depends on COMMON_CLK_QCOM && QCOM_SMD_RPM
-+	select QCOM_RPMCC
-+	help
-+	  The RPM (Resource Power Manager) is a dedicated hardware engine for
-+	  managing the shared SoC resources in order to keep the lowest power
-+	  profile. It communicates with other hardware subsystems via shared
-+	  memory and accepts clock requests, aggregates the requests and turns
-+	  the clocks on/off or scales them on demand.
-+	  Say Y if you want to support the clocks exposed by the RPM on
-+	  platforms such as apq8016, apq8084, msm8974 etc.
-+
- config APQ_GCC_8084
- 	tristate "APQ8084 Global Clock Controller"
- 	select QCOM_GDSC
---- a/drivers/clk/qcom/Makefile
-+++ b/drivers/clk/qcom/Makefile
-@@ -22,3 +22,4 @@ obj-$(CONFIG_MSM_LCC_8960) += lcc-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_CLK_SMD_RPM) += clk-smd-rpm.o
---- /dev/null
-+++ b/drivers/clk/qcom/clk-smd-rpm.c
-@@ -0,0 +1,571 @@
-+/*
-+ * Copyright (c) 2016, Linaro Limited
-+ * Copyright (c) 2014, The Linux Foundation. All rights reserved.
-+ *
-+ * This software is licensed under the terms of the GNU General Public
-+ * License version 2, as published by the Free Software Foundation, and
-+ * may be copied, distributed, and modified under those terms.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-+ * GNU General Public License for more details.
-+ */
-+
-+#include <linux/clk-provider.h>
-+#include <linux/err.h>
-+#include <linux/export.h>
-+#include <linux/init.h>
-+#include <linux/kernel.h>
-+#include <linux/module.h>
-+#include <linux/mutex.h>
-+#include <linux/of.h>
-+#include <linux/of_device.h>
-+#include <linux/platform_device.h>
-+#include <linux/soc/qcom/smd-rpm.h>
-+
-+#include <dt-bindings/clock/qcom,rpmcc.h>
-+#include <dt-bindings/mfd/qcom-rpm.h>
-+
-+#define QCOM_RPM_KEY_SOFTWARE_ENABLE			0x6e657773
-+#define QCOM_RPM_KEY_PIN_CTRL_CLK_BUFFER_ENABLE_KEY	0x62636370
-+#define QCOM_RPM_SMD_KEY_RATE				0x007a484b
-+#define QCOM_RPM_SMD_KEY_ENABLE				0x62616e45
-+#define QCOM_RPM_SMD_KEY_STATE				0x54415453
-+#define QCOM_RPM_SCALING_ENABLE_ID			0x2
-+
-+#define __DEFINE_CLK_SMD_RPM(_platform, _name, _active, type, r_id, stat_id,  \
-+			     key)					      \
-+	static struct clk_smd_rpm _platform##_##_active;		      \
-+	static struct clk_smd_rpm _platform##_##_name = {		      \
-+		.rpm_res_type = (type),					      \
-+		.rpm_clk_id = (r_id),					      \
-+		.rpm_status_id = (stat_id),				      \
-+		.rpm_key = (key),					      \
-+		.peer = &_platform##_##_active,				      \
-+		.rate = INT_MAX,					      \
-+		.hw.init = &(struct clk_init_data){			      \
-+			.ops = &clk_smd_rpm_ops,			      \
-+			.name = #_name,					      \
-+			.parent_names = (const char *[]){ "xo_board" },       \
-+			.num_parents = 1,				      \
-+		},							      \
-+	};								      \
-+	static struct clk_smd_rpm _platform##_##_active = {		      \
-+		.rpm_res_type = (type),					      \
-+		.rpm_clk_id = (r_id),					      \
-+		.rpm_status_id = (stat_id),				      \
-+		.active_only = true,					      \
-+		.rpm_key = (key),					      \
-+		.peer = &_platform##_##_name,				      \
-+		.rate = INT_MAX,					      \
-+		.hw.init = &(struct clk_init_data){			      \
-+			.ops = &clk_smd_rpm_ops,			      \
-+			.name = #_active,				      \
-+			.parent_names = (const char *[]){ "xo_board" },	      \
-+			.num_parents = 1,				      \
-+		},							      \
-+	}
-+
-+#define __DEFINE_CLK_SMD_RPM_BRANCH(_platform, _name, _active, type, r_id,    \
-+				    stat_id, r, key)			      \
-+	static struct clk_smd_rpm _platform##_##_active;		      \
-+	static struct clk_smd_rpm _platform##_##_name = {		      \
-+		.rpm_res_type = (type),					      \
-+		.rpm_clk_id = (r_id),					      \
-+		.rpm_status_id = (stat_id),				      \
-+		.rpm_key = (key),					      \
-+		.branch = true,						      \
-+		.peer = &_platform##_##_active,				      \
-+		.rate = (r),						      \
-+		.hw.init = &(struct clk_init_data){			      \
-+			.ops = &clk_smd_rpm_branch_ops,			      \
-+			.name = #_name,					      \
-+			.parent_names = (const char *[]){ "xo_board" },	      \
-+			.num_parents = 1,				      \
-+		},							      \
-+	};								      \
-+	static struct clk_smd_rpm _platform##_##_active = {		      \
-+		.rpm_res_type = (type),					      \
-+		.rpm_clk_id = (r_id),					      \
-+		.rpm_status_id = (stat_id),				      \
-+		.active_only = true,					      \
-+		.rpm_key = (key),					      \
-+		.branch = true,						      \
-+		.peer = &_platform##_##_name,				      \
-+		.rate = (r),						      \
-+		.hw.init = &(struct clk_init_data){			      \
-+			.ops = &clk_smd_rpm_branch_ops,			      \
-+			.name = #_active,				      \
-+			.parent_names = (const char *[]){ "xo_board" },	      \
-+			.num_parents = 1,				      \
-+		},							      \
-+	}
-+
-+#define DEFINE_CLK_SMD_RPM(_platform, _name, _active, type, r_id)	      \
-+		__DEFINE_CLK_SMD_RPM(_platform, _name, _active, type, r_id,   \
-+		0, QCOM_RPM_SMD_KEY_RATE)
-+
-+#define DEFINE_CLK_SMD_RPM_BRANCH(_platform, _name, _active, type, r_id, r)   \
-+		__DEFINE_CLK_SMD_RPM_BRANCH(_platform, _name, _active, type,  \
-+		r_id, 0, r, QCOM_RPM_SMD_KEY_ENABLE)
-+
-+#define DEFINE_CLK_SMD_RPM_QDSS(_platform, _name, _active, type, r_id)	      \
-+		__DEFINE_CLK_SMD_RPM(_platform, _name, _active, type, r_id,   \
-+		0, QCOM_RPM_SMD_KEY_STATE)
-+
-+#define DEFINE_CLK_SMD_RPM_XO_BUFFER(_platform, _name, _active, r_id)	      \
-+		__DEFINE_CLK_SMD_RPM_BRANCH(_platform, _name, _active,	      \
-+		QCOM_SMD_RPM_CLK_BUF_A, r_id, 0, 1000,			      \
-+		QCOM_RPM_KEY_SOFTWARE_ENABLE)
-+
-+#define DEFINE_CLK_SMD_RPM_XO_BUFFER_PINCTRL(_platform, _name, _active, r_id) \
-+		__DEFINE_CLK_SMD_RPM_BRANCH(_platform, _name, _active,	      \
-+		QCOM_SMD_RPM_CLK_BUF_A, r_id, 0, 1000,			      \
-+		QCOM_RPM_KEY_PIN_CTRL_CLK_BUFFER_ENABLE_KEY)
-+
-+#define to_clk_smd_rpm(_hw) container_of(_hw, struct clk_smd_rpm, hw)
-+
-+struct clk_smd_rpm {
-+	const int rpm_res_type;
-+	const int rpm_key;
-+	const int rpm_clk_id;
-+	const int rpm_status_id;
-+	const bool active_only;
-+	bool enabled;
-+	bool branch;
-+	struct clk_smd_rpm *peer;
-+	struct clk_hw hw;
-+	unsigned long rate;
-+	struct qcom_smd_rpm *rpm;
-+};
-+
-+struct clk_smd_rpm_req {
-+	__le32 key;
-+	__le32 nbytes;
-+	__le32 value;
-+};
-+
-+struct rpm_cc {
-+	struct qcom_rpm *rpm;
-+	struct clk_hw_onecell_data data;
-+	struct clk_hw *hws[];
-+};
-+
-+struct rpm_smd_clk_desc {
-+	struct clk_smd_rpm **clks;
-+	size_t num_clks;
-+};
-+
-+static DEFINE_MUTEX(rpm_smd_clk_lock);
-+
-+static int clk_smd_rpm_handoff(struct clk_smd_rpm *r)
-+{
-+	int ret;
-+	struct clk_smd_rpm_req req = {
-+		.key = cpu_to_le32(r->rpm_key),
-+		.nbytes = cpu_to_le32(sizeof(u32)),
-+		.value = cpu_to_le32(INT_MAX),
-+	};
-+
-+	ret = qcom_rpm_smd_write(r->rpm, QCOM_SMD_RPM_ACTIVE_STATE,
-+				 r->rpm_res_type, r->rpm_clk_id, &req,
-+				 sizeof(req));
-+	if (ret)
-+		return ret;
-+	ret = qcom_rpm_smd_write(r->rpm, QCOM_SMD_RPM_SLEEP_STATE,
-+				 r->rpm_res_type, r->rpm_clk_id, &req,
-+				 sizeof(req));
-+	if (ret)
-+		return ret;
-+
-+	return 0;
-+}
-+
-+static int clk_smd_rpm_set_rate_active(struct clk_smd_rpm *r,
-+				       unsigned long rate)
-+{
-+	struct clk_smd_rpm_req req = {
-+		.key = cpu_to_le32(r->rpm_key),
-+		.nbytes = cpu_to_le32(sizeof(u32)),
-+		.value = cpu_to_le32(DIV_ROUND_UP(rate, 1000)), /* to kHz */
-+	};
-+
-+	return qcom_rpm_smd_write(r->rpm, QCOM_SMD_RPM_ACTIVE_STATE,
-+				  r->rpm_res_type, r->rpm_clk_id, &req,
-+				  sizeof(req));
-+}
-+
-+static int clk_smd_rpm_set_rate_sleep(struct clk_smd_rpm *r,
-+				      unsigned long rate)
-+{
-+	struct clk_smd_rpm_req req = {
-+		.key = cpu_to_le32(r->rpm_key),
-+		.nbytes = cpu_to_le32(sizeof(u32)),
-+		.value = cpu_to_le32(DIV_ROUND_UP(rate, 1000)), /* to kHz */
-+	};
-+
-+	return qcom_rpm_smd_write(r->rpm, QCOM_SMD_RPM_SLEEP_STATE,
-+				  r->rpm_res_type, r->rpm_clk_id, &req,
-+				  sizeof(req));
-+}
-+
-+static void to_active_sleep(struct clk_smd_rpm *r, unsigned long rate,
-+			    unsigned long *active, unsigned long *sleep)
-+{
-+	*active = rate;
-+
-+	/*
-+	 * Active-only clocks don't care what the rate is during sleep. So,
-+	 * they vote for zero.
-+	 */
-+	if (r->active_only)
-+		*sleep = 0;
-+	else
-+		*sleep = *active;
-+}
-+
-+static int clk_smd_rpm_prepare(struct clk_hw *hw)
-+{
-+	struct clk_smd_rpm *r = to_clk_smd_rpm(hw);
-+	struct clk_smd_rpm *peer = r->peer;
-+	unsigned long this_rate = 0, this_sleep_rate = 0;
-+	unsigned long peer_rate = 0, peer_sleep_rate = 0;
-+	unsigned long active_rate, sleep_rate;
-+	int ret = 0;
-+
-+	mutex_lock(&rpm_smd_clk_lock);
-+
-+	/* Don't send requests to the RPM if the rate has not been set. */
-+	if (!r->rate)
-+		goto out;
-+
-+	to_active_sleep(r, r->rate, &this_rate, &this_sleep_rate);
-+
-+	/* Take peer clock's rate into account only if it's enabled. */
-+	if (peer->enabled)
-+		to_active_sleep(peer, peer->rate,
-+				&peer_rate, &peer_sleep_rate);
-+
-+	active_rate = max(this_rate, peer_rate);
-+
-+	if (r->branch)
-+		active_rate = !!active_rate;
-+
-+	ret = clk_smd_rpm_set_rate_active(r, active_rate);
-+	if (ret)
-+		goto out;
-+
-+	sleep_rate = max(this_sleep_rate, peer_sleep_rate);
-+	if (r->branch)
-+		sleep_rate = !!sleep_rate;
-+
-+	ret = clk_smd_rpm_set_rate_sleep(r, sleep_rate);
-+	if (ret)
-+		/* Undo the active set vote and restore it */
-+		ret = clk_smd_rpm_set_rate_active(r, peer_rate);
-+
-+out:
-+	if (!ret)
-+		r->enabled = true;
-+
-+	mutex_unlock(&rpm_smd_clk_lock);
-+
-+	return ret;
-+}
-+
-+static void clk_smd_rpm_unprepare(struct clk_hw *hw)
-+{
-+	struct clk_smd_rpm *r = to_clk_smd_rpm(hw);
-+	struct clk_smd_rpm *peer = r->peer;
-+	unsigned long peer_rate = 0, peer_sleep_rate = 0;
-+	unsigned long active_rate, sleep_rate;
-+	int ret;
-+
-+	mutex_lock(&rpm_smd_clk_lock);
-+
-+	if (!r->rate)
-+		goto out;
-+
-+	/* Take peer clock's rate into account only if it's enabled. */
-+	if (peer->enabled)
-+		to_active_sleep(peer, peer->rate, &peer_rate,
-+				&peer_sleep_rate);
-+
-+	active_rate = r->branch ? !!peer_rate : peer_rate;
-+	ret = clk_smd_rpm_set_rate_active(r, active_rate);
-+	if (ret)
-+		goto out;
-+
-+	sleep_rate = r->branch ? !!peer_sleep_rate : peer_sleep_rate;
-+	ret = clk_smd_rpm_set_rate_sleep(r, sleep_rate);
-+	if (ret)
-+		goto out;
-+
-+	r->enabled = false;
-+
-+out:
-+	mutex_unlock(&rpm_smd_clk_lock);
-+}
-+
-+static int clk_smd_rpm_set_rate(struct clk_hw *hw, unsigned long rate,
-+				unsigned long parent_rate)
-+{
-+	struct clk_smd_rpm *r = to_clk_smd_rpm(hw);
-+	struct clk_smd_rpm *peer = r->peer;
-+	unsigned long active_rate, sleep_rate;
-+	unsigned long this_rate = 0, this_sleep_rate = 0;
-+	unsigned long peer_rate = 0, peer_sleep_rate = 0;
-+	int ret = 0;
-+
-+	mutex_lock(&rpm_smd_clk_lock);
-+
-+	if (!r->enabled)
-+		goto out;
-+
-+	to_active_sleep(r, rate, &this_rate, &this_sleep_rate);
-+
-+	/* Take peer clock's rate into account only if it's enabled. */
-+	if (peer->enabled)
-+		to_active_sleep(peer, peer->rate,
-+				&peer_rate, &peer_sleep_rate);
-+
-+	active_rate = max(this_rate, peer_rate);
-+	ret = clk_smd_rpm_set_rate_active(r, active_rate);
-+	if (ret)
-+		goto out;
-+
-+	sleep_rate = max(this_sleep_rate, peer_sleep_rate);
-+	ret = clk_smd_rpm_set_rate_sleep(r, sleep_rate);
-+	if (ret)
-+		goto out;
-+
-+	r->rate = rate;
-+
-+out:
-+	mutex_unlock(&rpm_smd_clk_lock);
-+
-+	return ret;
-+}
-+
-+static long clk_smd_rpm_round_rate(struct clk_hw *hw, unsigned long rate,
-+				   unsigned long *parent_rate)
-+{
-+	/*
-+	 * RPM handles rate rounding and we don't have a way to
-+	 * know what the rate will be, so just return whatever
-+	 * rate is requested.
-+	 */
-+	return rate;
-+}
-+
-+static unsigned long clk_smd_rpm_recalc_rate(struct clk_hw *hw,
-+					     unsigned long parent_rate)
-+{
-+	struct clk_smd_rpm *r = to_clk_smd_rpm(hw);
-+
-+	/*
-+	 * RPM handles rate rounding and we don't have a way to
-+	 * know what the rate will be, so just return whatever
-+	 * rate was set.
-+	 */
-+	return r->rate;
-+}
-+
-+static int clk_smd_rpm_enable_scaling(struct qcom_smd_rpm *rpm)
-+{
-+	int ret;
-+	struct clk_smd_rpm_req req = {
-+		.key = cpu_to_le32(QCOM_RPM_SMD_KEY_ENABLE),
-+		.nbytes = cpu_to_le32(sizeof(u32)),
-+		.value = cpu_to_le32(1),
-+	};
-+
-+	ret = qcom_rpm_smd_write(rpm, QCOM_SMD_RPM_SLEEP_STATE,
-+				 QCOM_SMD_RPM_MISC_CLK,
-+				 QCOM_RPM_SCALING_ENABLE_ID, &req, sizeof(req));
-+	if (ret) {
-+		pr_err("RPM clock scaling (sleep set) not enabled!\n");
-+		return ret;
-+	}
-+
-+	ret = qcom_rpm_smd_write(rpm, QCOM_SMD_RPM_ACTIVE_STATE,
-+				 QCOM_SMD_RPM_MISC_CLK,
-+				 QCOM_RPM_SCALING_ENABLE_ID, &req, sizeof(req));
-+	if (ret) {
-+		pr_err("RPM clock scaling (active set) not enabled!\n");
-+		return ret;
-+	}
-+
-+	pr_debug("%s: RPM clock scaling is enabled\n", __func__);
-+	return 0;
-+}
-+
-+static const struct clk_ops clk_smd_rpm_ops = {
-+	.prepare	= clk_smd_rpm_prepare,
-+	.unprepare	= clk_smd_rpm_unprepare,
-+	.set_rate	= clk_smd_rpm_set_rate,
-+	.round_rate	= clk_smd_rpm_round_rate,
-+	.recalc_rate	= clk_smd_rpm_recalc_rate,
-+};
-+
-+static const struct clk_ops clk_smd_rpm_branch_ops = {
-+	.prepare	= clk_smd_rpm_prepare,
-+	.unprepare	= clk_smd_rpm_unprepare,
-+	.round_rate	= clk_smd_rpm_round_rate,
-+	.recalc_rate	= clk_smd_rpm_recalc_rate,
-+};
-+
-+/* msm8916 */
-+DEFINE_CLK_SMD_RPM(msm8916, pcnoc_clk, pcnoc_a_clk, QCOM_SMD_RPM_BUS_CLK, 0);
-+DEFINE_CLK_SMD_RPM(msm8916, snoc_clk, snoc_a_clk, QCOM_SMD_RPM_BUS_CLK, 1);
-+DEFINE_CLK_SMD_RPM(msm8916, bimc_clk, bimc_a_clk, QCOM_SMD_RPM_MEM_CLK, 0);
-+DEFINE_CLK_SMD_RPM_QDSS(msm8916, qdss_clk, qdss_a_clk, QCOM_SMD_RPM_MISC_CLK, 1);
-+DEFINE_CLK_SMD_RPM_XO_BUFFER(msm8916, bb_clk1, bb_clk1_a, 1);
-+DEFINE_CLK_SMD_RPM_XO_BUFFER(msm8916, bb_clk2, bb_clk2_a, 2);
-+DEFINE_CLK_SMD_RPM_XO_BUFFER(msm8916, rf_clk1, rf_clk1_a, 4);
-+DEFINE_CLK_SMD_RPM_XO_BUFFER(msm8916, rf_clk2, rf_clk2_a, 5);
-+DEFINE_CLK_SMD_RPM_XO_BUFFER_PINCTRL(msm8916, bb_clk1_pin, bb_clk1_a_pin, 1);
-+DEFINE_CLK_SMD_RPM_XO_BUFFER_PINCTRL(msm8916, bb_clk2_pin, bb_clk2_a_pin, 2);
-+DEFINE_CLK_SMD_RPM_XO_BUFFER_PINCTRL(msm8916, rf_clk1_pin, rf_clk1_a_pin, 4);
-+DEFINE_CLK_SMD_RPM_XO_BUFFER_PINCTRL(msm8916, rf_clk2_pin, rf_clk2_a_pin, 5);
-+
-+static struct clk_smd_rpm *msm8916_clks[] = {
-+	[RPM_SMD_PCNOC_CLK]		= &msm8916_pcnoc_clk,
-+	[RPM_SMD_PCNOC_A_CLK]		= &msm8916_pcnoc_a_clk,
-+	[RPM_SMD_SNOC_CLK]		= &msm8916_snoc_clk,
-+	[RPM_SMD_SNOC_A_CLK]		= &msm8916_snoc_a_clk,
-+	[RPM_SMD_BIMC_CLK]		= &msm8916_bimc_clk,
-+	[RPM_SMD_BIMC_A_CLK]		= &msm8916_bimc_a_clk,
-+	[RPM_SMD_QDSS_CLK]		= &msm8916_qdss_clk,
-+	[RPM_SMD_QDSS_A_CLK]		= &msm8916_qdss_a_clk,
-+	[RPM_SMD_BB_CLK1]		= &msm8916_bb_clk1,
-+	[RPM_SMD_BB_CLK1_A]		= &msm8916_bb_clk1_a,
-+	[RPM_SMD_BB_CLK2]		= &msm8916_bb_clk2,
-+	[RPM_SMD_BB_CLK2_A]		= &msm8916_bb_clk2_a,
-+	[RPM_SMD_RF_CLK1]		= &msm8916_rf_clk1,
-+	[RPM_SMD_RF_CLK1_A]		= &msm8916_rf_clk1_a,
-+	[RPM_SMD_RF_CLK2]		= &msm8916_rf_clk2,
-+	[RPM_SMD_RF_CLK2_A]		= &msm8916_rf_clk2_a,
-+	[RPM_SMD_BB_CLK1_PIN]		= &msm8916_bb_clk1_pin,
-+	[RPM_SMD_BB_CLK1_A_PIN]		= &msm8916_bb_clk1_a_pin,
-+	[RPM_SMD_BB_CLK2_PIN]		= &msm8916_bb_clk2_pin,
-+	[RPM_SMD_BB_CLK2_A_PIN]		= &msm8916_bb_clk2_a_pin,
-+	[RPM_SMD_RF_CLK1_PIN]		= &msm8916_rf_clk1_pin,
-+	[RPM_SMD_RF_CLK1_A_PIN]		= &msm8916_rf_clk1_a_pin,
-+	[RPM_SMD_RF_CLK2_PIN]		= &msm8916_rf_clk2_pin,
-+	[RPM_SMD_RF_CLK2_A_PIN]		= &msm8916_rf_clk2_a_pin,
-+};
-+
-+static const struct rpm_smd_clk_desc rpm_clk_msm8916 = {
-+	.clks = msm8916_clks,
-+	.num_clks = ARRAY_SIZE(msm8916_clks),
-+};
-+
-+static const struct of_device_id rpm_smd_clk_match_table[] = {
-+	{ .compatible = "qcom,rpmcc-msm8916", .data = &rpm_clk_msm8916 },
-+	{ }
-+};
-+MODULE_DEVICE_TABLE(of, rpm_smd_clk_match_table);
-+
-+static int rpm_smd_clk_probe(struct platform_device *pdev)
-+{
-+	struct clk_hw **hws;
-+	struct rpm_cc *rcc;
-+	struct clk_hw_onecell_data *data;
-+	int ret;
-+	size_t num_clks, i;
-+	struct qcom_smd_rpm *rpm;
-+	struct clk_smd_rpm **rpm_smd_clks;
-+	const struct rpm_smd_clk_desc *desc;
-+
-+	rpm = dev_get_drvdata(pdev->dev.parent);
-+	if (!rpm) {
-+		dev_err(&pdev->dev, "Unable to retrieve handle to RPM\n");
-+		return -ENODEV;
-+	}
-+
-+	desc = of_device_get_match_data(&pdev->dev);
-+	if (!desc)
-+		return -EINVAL;
-+
-+	rpm_smd_clks = desc->clks;
-+	num_clks = desc->num_clks;
-+
-+	rcc = devm_kzalloc(&pdev->dev, sizeof(*rcc) + sizeof(*hws) * num_clks,
-+			   GFP_KERNEL);
-+	if (!rcc)
-+		return -ENOMEM;
-+
-+	hws = rcc->hws;
-+	data = &rcc->data;
-+	data->num = num_clks;
-+
-+	for (i = 0; i < num_clks; i++) {
-+		if (!rpm_smd_clks[i]) {
-+			continue;
-+		}
-+
-+		rpm_smd_clks[i]->rpm = rpm;
-+
-+		ret = clk_smd_rpm_handoff(rpm_smd_clks[i]);
-+		if (ret)
-+			goto err;
-+	}
-+
-+	ret = clk_smd_rpm_enable_scaling(rpm);
-+	if (ret)
-+		goto err;
-+
-+	for (i = 0; i < num_clks; i++) {
-+		if (!rpm_smd_clks[i]) {
-+			data->hws[i] = ERR_PTR(-ENOENT);
-+			continue;
-+		}
-+
-+		ret = devm_clk_hw_register(&pdev->dev, &rpm_smd_clks[i]->hw);
-+		if (ret)
-+			goto err;
-+	}
-+
-+	ret = of_clk_add_hw_provider(pdev->dev.of_node, of_clk_hw_onecell_get,
-+				     data);
-+	if (ret)
-+		goto err;
-+
-+	return 0;
-+err:
-+	dev_err(&pdev->dev, "Error registering SMD clock driver (%d)\n", ret);
-+	return ret;
-+}
-+
-+static int rpm_smd_clk_remove(struct platform_device *pdev)
-+{
-+	of_clk_del_provider(pdev->dev.of_node);
-+	return 0;
-+}
-+
-+static struct platform_driver rpm_smd_clk_driver = {
-+	.driver = {
-+		.name = "qcom-clk-smd-rpm",
-+		.of_match_table = rpm_smd_clk_match_table,
-+	},
-+	.probe = rpm_smd_clk_probe,
-+	.remove = rpm_smd_clk_remove,
-+};
-+
-+static int __init rpm_smd_clk_init(void)
-+{
-+	return platform_driver_register(&rpm_smd_clk_driver);
-+}
-+core_initcall(rpm_smd_clk_init);
-+
-+static void __exit rpm_smd_clk_exit(void)
-+{
-+	platform_driver_unregister(&rpm_smd_clk_driver);
-+}
-+module_exit(rpm_smd_clk_exit);
-+
-+MODULE_DESCRIPTION("Qualcomm RPM over SMD Clock Controller Driver");
-+MODULE_LICENSE("GPL v2");
-+MODULE_ALIAS("platform:qcom-clk-smd-rpm");
---- /dev/null
-+++ b/include/dt-bindings/clock/qcom,rpmcc.h
-@@ -0,0 +1,45 @@
-+/*
-+ * Copyright 2015 Linaro Limited
-+ *
-+ * This software is licensed under the terms of the GNU General Public
-+ * License version 2, as published by the Free Software Foundation, and
-+ * may be copied, distributed, and modified under those terms.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-+ * GNU General Public License for more details.
-+ */
-+
-+#ifndef _DT_BINDINGS_CLK_MSM_RPMCC_H
-+#define _DT_BINDINGS_CLK_MSM_RPMCC_H
-+
-+/* msm8916 */
-+#define RPM_SMD_XO_CLK_SRC				0
-+#define RPM_SMD_XO_A_CLK_SRC			1
-+#define RPM_SMD_PCNOC_CLK				2
-+#define RPM_SMD_PCNOC_A_CLK				3
-+#define RPM_SMD_SNOC_CLK				4
-+#define RPM_SMD_SNOC_A_CLK				5
-+#define RPM_SMD_BIMC_CLK				6
-+#define RPM_SMD_BIMC_A_CLK				7
-+#define RPM_SMD_QDSS_CLK				8
-+#define RPM_SMD_QDSS_A_CLK				9
-+#define RPM_SMD_BB_CLK1				10
-+#define RPM_SMD_BB_CLK1_A				11
-+#define RPM_SMD_BB_CLK2				12
-+#define RPM_SMD_BB_CLK2_A				13
-+#define RPM_SMD_RF_CLK1				14
-+#define RPM_SMD_RF_CLK1_A				15
-+#define RPM_SMD_RF_CLK2				16
-+#define RPM_SMD_RF_CLK2_A				17
-+#define RPM_SMD_BB_CLK1_PIN				18
-+#define RPM_SMD_BB_CLK1_A_PIN			19
-+#define RPM_SMD_BB_CLK2_PIN				20
-+#define RPM_SMD_BB_CLK2_A_PIN			21
-+#define RPM_SMD_RF_CLK1_PIN				22
-+#define RPM_SMD_RF_CLK1_A_PIN			23
-+#define RPM_SMD_RF_CLK2_PIN				24
-+#define RPM_SMD_RF_CLK2_A_PIN			25
-+
-+#endif
diff --git a/target/linux/ipq806x/patches-4.4/012-2-clk-qcom-Add-support-for-RPM-Clocks.patch b/target/linux/ipq806x/patches-4.4/012-2-clk-qcom-Add-support-for-RPM-Clocks.patch
deleted file mode 100644
index 8a38ead..0000000
--- a/target/linux/ipq806x/patches-4.4/012-2-clk-qcom-Add-support-for-RPM-Clocks.patch
+++ /dev/null
@@ -1,586 +0,0 @@
-From 872f91b5ea720c72f81fb46d353c43ecb3263ffa Mon Sep 17 00:00:00 2001
-From: Georgi Djakov <georgi.djakov at linaro.org>
-Date: Wed, 2 Nov 2016 17:56:57 +0200
-Subject: clk: qcom: Add support for RPM Clocks
-
-This adds initial support for clocks controlled by the Resource
-Power Manager (RPM) processor on some Qualcomm SoCs, which use
-the qcom_rpm driver to communicate with RPM.
-Such platforms are apq8064 and msm8960.
-
-Signed-off-by: Georgi Djakov <georgi.djakov at linaro.org>
-Acked-by: Rob Herring <robh at kernel.org>
-Signed-off-by: Stephen Boyd <sboyd at codeaurora.org>
----
- .../devicetree/bindings/clock/qcom,rpmcc.txt       |   1 +
- drivers/clk/qcom/Kconfig                           |  13 +
- drivers/clk/qcom/Makefile                          |   1 +
- drivers/clk/qcom/clk-rpm.c                         | 489 +++++++++++++++++++++
- include/dt-bindings/clock/qcom,rpmcc.h             |  24 +
- 5 files changed, 528 insertions(+)
- create mode 100644 drivers/clk/qcom/clk-rpm.c
-
---- a/Documentation/devicetree/bindings/clock/qcom,rpmcc.txt
-+++ b/Documentation/devicetree/bindings/clock/qcom,rpmcc.txt
-@@ -11,6 +11,7 @@ Required properties :
-                compatible "qcom,rpmcc" should be also included.
- 
- 			"qcom,rpmcc-msm8916", "qcom,rpmcc"
-+			"qcom,rpmcc-apq8064", "qcom,rpmcc"
- 
- - #clock-cells : shall contain 1
- 
---- a/drivers/clk/qcom/Kconfig
-+++ b/drivers/clk/qcom/Kconfig
-@@ -12,6 +12,19 @@ config COMMON_CLK_QCOM
- 	select REGMAP_MMIO
- 	select RESET_CONTROLLER
- 
-+config QCOM_CLK_RPM
-+	tristate "RPM based Clock Controller"
-+	depends on COMMON_CLK_QCOM && MFD_QCOM_RPM
-+	select QCOM_RPMCC
-+	help
-+	  The RPM (Resource Power Manager) is a dedicated hardware engine for
-+	  managing the shared SoC resources in order to keep the lowest power
-+	  profile. It communicates with other hardware subsystems via shared
-+	  memory and accepts clock requests, aggregates the requests and turns
-+	  the clocks on/off or scales them on demand.
-+	  Say Y if you want to support the clocks exposed by the RPM on
-+	  platforms such as ipq806x, msm8660, msm8960 etc.
-+
- config QCOM_CLK_SMD_RPM
- 	tristate "RPM over SMD based Clock Controller"
- 	depends on COMMON_CLK_QCOM && QCOM_SMD_RPM
---- a/drivers/clk/qcom/Makefile
-+++ b/drivers/clk/qcom/Makefile
-@@ -23,3 +23,4 @@ obj-$(CONFIG_MSM_GCC_8974) += gcc-msm897
- obj-$(CONFIG_MSM_MMCC_8960) += mmcc-msm8960.o
- obj-$(CONFIG_MSM_MMCC_8974) += mmcc-msm8974.o
- obj-$(CONFIG_QCOM_CLK_SMD_RPM) += clk-smd-rpm.o
-+obj-$(CONFIG_QCOM_CLK_RPM) += clk-rpm.o
---- /dev/null
-+++ b/drivers/clk/qcom/clk-rpm.c
-@@ -0,0 +1,489 @@
-+/*
-+ * Copyright (c) 2016, Linaro Limited
-+ * Copyright (c) 2014, The Linux Foundation. All rights reserved.
-+ *
-+ * This software is licensed under the terms of the GNU General Public
-+ * License version 2, as published by the Free Software Foundation, and
-+ * may be copied, distributed, and modified under those terms.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-+ * GNU General Public License for more details.
-+ */
-+
-+#include <linux/clk-provider.h>
-+#include <linux/err.h>
-+#include <linux/export.h>
-+#include <linux/init.h>
-+#include <linux/kernel.h>
-+#include <linux/module.h>
-+#include <linux/mutex.h>
-+#include <linux/mfd/qcom_rpm.h>
-+#include <linux/of.h>
-+#include <linux/of_device.h>
-+#include <linux/platform_device.h>
-+
-+#include <dt-bindings/mfd/qcom-rpm.h>
-+#include <dt-bindings/clock/qcom,rpmcc.h>
-+
-+#define QCOM_RPM_MISC_CLK_TYPE				0x306b6c63
-+#define QCOM_RPM_SCALING_ENABLE_ID			0x2
-+
-+#define DEFINE_CLK_RPM(_platform, _name, _active, r_id)			      \
-+	static struct clk_rpm _platform##_##_active;			      \
-+	static struct clk_rpm _platform##_##_name = {			      \
-+		.rpm_clk_id = (r_id),					      \
-+		.peer = &_platform##_##_active,				      \
-+		.rate = INT_MAX,					      \
-+		.hw.init = &(struct clk_init_data){			      \
-+			.ops = &clk_rpm_ops,				      \
-+			.name = #_name,					      \
-+			.parent_names = (const char *[]){ "pxo_board" },      \
-+			.num_parents = 1,				      \
-+		},							      \
-+	};								      \
-+	static struct clk_rpm _platform##_##_active = {			      \
-+		.rpm_clk_id = (r_id),					      \
-+		.peer = &_platform##_##_name,				      \
-+		.active_only = true,					      \
-+		.rate = INT_MAX,					      \
-+		.hw.init = &(struct clk_init_data){			      \
-+			.ops = &clk_rpm_ops,				      \
-+			.name = #_active,				      \
-+			.parent_names = (const char *[]){ "pxo_board" },      \
-+			.num_parents = 1,				      \
-+		},							      \
-+	}
-+
-+#define DEFINE_CLK_RPM_PXO_BRANCH(_platform, _name, _active, r_id, r)	      \
-+	static struct clk_rpm _platform##_##_active;			      \
-+	static struct clk_rpm _platform##_##_name = {			      \
-+		.rpm_clk_id = (r_id),					      \
-+		.active_only = true,					      \
-+		.peer = &_platform##_##_active,				      \
-+		.rate = (r),						      \
-+		.branch = true,						      \
-+		.hw.init = &(struct clk_init_data){			      \
-+			.ops = &clk_rpm_branch_ops,			      \
-+			.name = #_name,					      \
-+			.parent_names = (const char *[]){ "pxo_board" },      \
-+			.num_parents = 1,				      \
-+		},							      \
-+	};								      \
-+	static struct clk_rpm _platform##_##_active = {			      \
-+		.rpm_clk_id = (r_id),					      \
-+		.peer = &_platform##_##_name,				      \
-+		.rate = (r),						      \
-+		.branch = true,						      \
-+		.hw.init = &(struct clk_init_data){			      \
-+			.ops = &clk_rpm_branch_ops,			      \
-+			.name = #_active,				      \
-+			.parent_names = (const char *[]){ "pxo_board" },      \
-+			.num_parents = 1,				      \
-+		},							      \
-+	}
-+
-+#define DEFINE_CLK_RPM_CXO_BRANCH(_platform, _name, _active, r_id, r)	      \
-+	static struct clk_rpm _platform##_##_active;			      \
-+	static struct clk_rpm _platform##_##_name = {			      \
-+		.rpm_clk_id = (r_id),					      \
-+		.peer = &_platform##_##_active,				      \
-+		.rate = (r),						      \
-+		.branch = true,						      \
-+		.hw.init = &(struct clk_init_data){			      \
-+			.ops = &clk_rpm_branch_ops,			      \
-+			.name = #_name,					      \
-+			.parent_names = (const char *[]){ "cxo_board" },      \
-+			.num_parents = 1,				      \
-+		},							      \
-+	};								      \
-+	static struct clk_rpm _platform##_##_active = {			      \
-+		.rpm_clk_id = (r_id),					      \
-+		.active_only = true,					      \
-+		.peer = &_platform##_##_name,				      \
-+		.rate = (r),						      \
-+		.branch = true,						      \
-+		.hw.init = &(struct clk_init_data){			      \
-+			.ops = &clk_rpm_branch_ops,			      \
-+			.name = #_active,				      \
-+			.parent_names = (const char *[]){ "cxo_board" },      \
-+			.num_parents = 1,				      \
-+		},							      \
-+	}
-+
-+#define to_clk_rpm(_hw) container_of(_hw, struct clk_rpm, hw)
-+
-+struct clk_rpm {
-+	const int rpm_clk_id;
-+	const bool active_only;
-+	unsigned long rate;
-+	bool enabled;
-+	bool branch;
-+	struct clk_rpm *peer;
-+	struct clk_hw hw;
-+	struct qcom_rpm *rpm;
-+};
-+
-+struct rpm_cc {
-+	struct qcom_rpm *rpm;
-+	struct clk_hw_onecell_data data;
-+	struct clk_hw *hws[];
-+};
-+
-+struct rpm_clk_desc {
-+	struct clk_rpm **clks;
-+	size_t num_clks;
-+};
-+
-+static DEFINE_MUTEX(rpm_clk_lock);
-+
-+static int clk_rpm_handoff(struct clk_rpm *r)
-+{
-+	int ret;
-+	u32 value = INT_MAX;
-+
-+	ret = qcom_rpm_write(r->rpm, QCOM_RPM_ACTIVE_STATE,
-+			     r->rpm_clk_id, &value, 1);
-+	if (ret)
-+		return ret;
-+	ret = qcom_rpm_write(r->rpm, QCOM_RPM_SLEEP_STATE,
-+			     r->rpm_clk_id, &value, 1);
-+	if (ret)
-+		return ret;
-+
-+	return 0;
-+}
-+
-+static int clk_rpm_set_rate_active(struct clk_rpm *r, unsigned long rate)
-+{
-+	u32 value = DIV_ROUND_UP(rate, 1000); /* to kHz */
-+
-+	return qcom_rpm_write(r->rpm, QCOM_RPM_ACTIVE_STATE,
-+			      r->rpm_clk_id, &value, 1);
-+}
-+
-+static int clk_rpm_set_rate_sleep(struct clk_rpm *r, unsigned long rate)
-+{
-+	u32 value = DIV_ROUND_UP(rate, 1000); /* to kHz */
-+
-+	return qcom_rpm_write(r->rpm, QCOM_RPM_SLEEP_STATE,
-+			      r->rpm_clk_id, &value, 1);
-+}
-+
-+static void to_active_sleep(struct clk_rpm *r, unsigned long rate,
-+			    unsigned long *active, unsigned long *sleep)
-+{
-+	*active = rate;
-+
-+	/*
-+	 * Active-only clocks don't care what the rate is during sleep. So,
-+	 * they vote for zero.
-+	 */
-+	if (r->active_only)
-+		*sleep = 0;
-+	else
-+		*sleep = *active;
-+}
-+
-+static int clk_rpm_prepare(struct clk_hw *hw)
-+{
-+	struct clk_rpm *r = to_clk_rpm(hw);
-+	struct clk_rpm *peer = r->peer;
-+	unsigned long this_rate = 0, this_sleep_rate = 0;
-+	unsigned long peer_rate = 0, peer_sleep_rate = 0;
-+	unsigned long active_rate, sleep_rate;
-+	int ret = 0;
-+
-+	mutex_lock(&rpm_clk_lock);
-+
-+	/* Don't send requests to the RPM if the rate has not been set. */
-+	if (!r->rate)
-+		goto out;
-+
-+	to_active_sleep(r, r->rate, &this_rate, &this_sleep_rate);
-+
-+	/* Take peer clock's rate into account only if it's enabled. */
-+	if (peer->enabled)
-+		to_active_sleep(peer, peer->rate,
-+				&peer_rate, &peer_sleep_rate);
-+
-+	active_rate = max(this_rate, peer_rate);
-+
-+	if (r->branch)
-+		active_rate = !!active_rate;
-+
-+	ret = clk_rpm_set_rate_active(r, active_rate);
-+	if (ret)
-+		goto out;
-+
-+	sleep_rate = max(this_sleep_rate, peer_sleep_rate);
-+	if (r->branch)
-+		sleep_rate = !!sleep_rate;
-+
-+	ret = clk_rpm_set_rate_sleep(r, sleep_rate);
-+	if (ret)
-+		/* Undo the active set vote and restore it */
-+		ret = clk_rpm_set_rate_active(r, peer_rate);
-+
-+out:
-+	if (!ret)
-+		r->enabled = true;
-+
-+	mutex_unlock(&rpm_clk_lock);
-+
-+	return ret;
-+}
-+
-+static void clk_rpm_unprepare(struct clk_hw *hw)
-+{
-+	struct clk_rpm *r = to_clk_rpm(hw);
-+	struct clk_rpm *peer = r->peer;
-+	unsigned long peer_rate = 0, peer_sleep_rate = 0;
-+	unsigned long active_rate, sleep_rate;
-+	int ret;
-+
-+	mutex_lock(&rpm_clk_lock);
-+
-+	if (!r->rate)
-+		goto out;
-+
-+	/* Take peer clock's rate into account only if it's enabled. */
-+	if (peer->enabled)
-+		to_active_sleep(peer, peer->rate, &peer_rate,
-+				&peer_sleep_rate);
-+
-+	active_rate = r->branch ? !!peer_rate : peer_rate;
-+	ret = clk_rpm_set_rate_active(r, active_rate);
-+	if (ret)
-+		goto out;
-+
-+	sleep_rate = r->branch ? !!peer_sleep_rate : peer_sleep_rate;
-+	ret = clk_rpm_set_rate_sleep(r, sleep_rate);
-+	if (ret)
-+		goto out;
-+
-+	r->enabled = false;
-+
-+out:
-+	mutex_unlock(&rpm_clk_lock);
-+}
-+
-+static int clk_rpm_set_rate(struct clk_hw *hw,
-+			    unsigned long rate, unsigned long parent_rate)
-+{
-+	struct clk_rpm *r = to_clk_rpm(hw);
-+	struct clk_rpm *peer = r->peer;
-+	unsigned long active_rate, sleep_rate;
-+	unsigned long this_rate = 0, this_sleep_rate = 0;
-+	unsigned long peer_rate = 0, peer_sleep_rate = 0;
-+	int ret = 0;
-+
-+	mutex_lock(&rpm_clk_lock);
-+
-+	if (!r->enabled)
-+		goto out;
-+
-+	to_active_sleep(r, rate, &this_rate, &this_sleep_rate);
-+
-+	/* Take peer clock's rate into account only if it's enabled. */
-+	if (peer->enabled)
-+		to_active_sleep(peer, peer->rate,
-+				&peer_rate, &peer_sleep_rate);
-+
-+	active_rate = max(this_rate, peer_rate);
-+	ret = clk_rpm_set_rate_active(r, active_rate);
-+	if (ret)
-+		goto out;
-+
-+	sleep_rate = max(this_sleep_rate, peer_sleep_rate);
-+	ret = clk_rpm_set_rate_sleep(r, sleep_rate);
-+	if (ret)
-+		goto out;
-+
-+	r->rate = rate;
-+
-+out:
-+	mutex_unlock(&rpm_clk_lock);
-+
-+	return ret;
-+}
-+
-+static long clk_rpm_round_rate(struct clk_hw *hw, unsigned long rate,
-+			       unsigned long *parent_rate)
-+{
-+	/*
-+	 * RPM handles rate rounding and we don't have a way to
-+	 * know what the rate will be, so just return whatever
-+	 * rate is requested.
-+	 */
-+	return rate;
-+}
-+
-+static unsigned long clk_rpm_recalc_rate(struct clk_hw *hw,
-+					 unsigned long parent_rate)
-+{
-+	struct clk_rpm *r = to_clk_rpm(hw);
-+
-+	/*
-+	 * RPM handles rate rounding and we don't have a way to
-+	 * know what the rate will be, so just return whatever
-+	 * rate was set.
-+	 */
-+	return r->rate;
-+}
-+
-+static const struct clk_ops clk_rpm_ops = {
-+	.prepare	= clk_rpm_prepare,
-+	.unprepare	= clk_rpm_unprepare,
-+	.set_rate	= clk_rpm_set_rate,
-+	.round_rate	= clk_rpm_round_rate,
-+	.recalc_rate	= clk_rpm_recalc_rate,
-+};
-+
-+static const struct clk_ops clk_rpm_branch_ops = {
-+	.prepare	= clk_rpm_prepare,
-+	.unprepare	= clk_rpm_unprepare,
-+	.round_rate	= clk_rpm_round_rate,
-+	.recalc_rate	= clk_rpm_recalc_rate,
-+};
-+
-+/* apq8064 */
-+DEFINE_CLK_RPM(apq8064, afab_clk, afab_a_clk, QCOM_RPM_APPS_FABRIC_CLK);
-+DEFINE_CLK_RPM(apq8064, cfpb_clk, cfpb_a_clk, QCOM_RPM_CFPB_CLK);
-+DEFINE_CLK_RPM(apq8064, daytona_clk, daytona_a_clk, QCOM_RPM_DAYTONA_FABRIC_CLK);
-+DEFINE_CLK_RPM(apq8064, ebi1_clk, ebi1_a_clk, QCOM_RPM_EBI1_CLK);
-+DEFINE_CLK_RPM(apq8064, mmfab_clk, mmfab_a_clk, QCOM_RPM_MM_FABRIC_CLK);
-+DEFINE_CLK_RPM(apq8064, mmfpb_clk, mmfpb_a_clk, QCOM_RPM_MMFPB_CLK);
-+DEFINE_CLK_RPM(apq8064, sfab_clk, sfab_a_clk, QCOM_RPM_SYS_FABRIC_CLK);
-+DEFINE_CLK_RPM(apq8064, sfpb_clk, sfpb_a_clk, QCOM_RPM_SFPB_CLK);
-+DEFINE_CLK_RPM(apq8064, qdss_clk, qdss_a_clk, QCOM_RPM_QDSS_CLK);
-+
-+static struct clk_rpm *apq8064_clks[] = {
-+	[RPM_APPS_FABRIC_CLK] = &apq8064_afab_clk,
-+	[RPM_APPS_FABRIC_A_CLK] = &apq8064_afab_a_clk,
-+	[RPM_CFPB_CLK] = &apq8064_cfpb_clk,
-+	[RPM_CFPB_A_CLK] = &apq8064_cfpb_a_clk,
-+	[RPM_DAYTONA_FABRIC_CLK] = &apq8064_daytona_clk,
-+	[RPM_DAYTONA_FABRIC_A_CLK] = &apq8064_daytona_a_clk,
-+	[RPM_EBI1_CLK] = &apq8064_ebi1_clk,
-+	[RPM_EBI1_A_CLK] = &apq8064_ebi1_a_clk,
-+	[RPM_MM_FABRIC_CLK] = &apq8064_mmfab_clk,
-+	[RPM_MM_FABRIC_A_CLK] = &apq8064_mmfab_a_clk,
-+	[RPM_MMFPB_CLK] = &apq8064_mmfpb_clk,
-+	[RPM_MMFPB_A_CLK] = &apq8064_mmfpb_a_clk,
-+	[RPM_SYS_FABRIC_CLK] = &apq8064_sfab_clk,
-+	[RPM_SYS_FABRIC_A_CLK] = &apq8064_sfab_a_clk,
-+	[RPM_SFPB_CLK] = &apq8064_sfpb_clk,
-+	[RPM_SFPB_A_CLK] = &apq8064_sfpb_a_clk,
-+	[RPM_QDSS_CLK] = &apq8064_qdss_clk,
-+	[RPM_QDSS_A_CLK] = &apq8064_qdss_a_clk,
-+};
-+
-+static const struct rpm_clk_desc rpm_clk_apq8064 = {
-+	.clks = apq8064_clks,
-+	.num_clks = ARRAY_SIZE(apq8064_clks),
-+};
-+
-+static const struct of_device_id rpm_clk_match_table[] = {
-+	{ .compatible = "qcom,rpmcc-apq8064", .data = &rpm_clk_apq8064 },
-+	{ }
-+};
-+MODULE_DEVICE_TABLE(of, rpm_clk_match_table);
-+
-+static int rpm_clk_probe(struct platform_device *pdev)
-+{
-+	struct clk_hw **hws;
-+	struct rpm_cc *rcc;
-+	struct clk_hw_onecell_data *data;
-+	int ret;
-+	size_t num_clks, i;
-+	struct qcom_rpm *rpm;
-+	struct clk_rpm **rpm_clks;
-+	const struct rpm_clk_desc *desc;
-+
-+	rpm = dev_get_drvdata(pdev->dev.parent);
-+	if (!rpm) {
-+		dev_err(&pdev->dev, "Unable to retrieve handle to RPM\n");
-+		return -ENODEV;
-+	}
-+
-+	desc = of_device_get_match_data(&pdev->dev);
-+	if (!desc)
-+		return -EINVAL;
-+
-+	rpm_clks = desc->clks;
-+	num_clks = desc->num_clks;
-+
-+	rcc = devm_kzalloc(&pdev->dev, sizeof(*rcc) + sizeof(*hws) * num_clks,
-+			   GFP_KERNEL);
-+	if (!rcc)
-+		return -ENOMEM;
-+
-+	hws = rcc->hws;
-+	data = &rcc->data;
-+	data->num = num_clks;
-+
-+	for (i = 0; i < num_clks; i++) {
-+		if (!rpm_clks[i])
-+			continue;
-+
-+		rpm_clks[i]->rpm = rpm;
-+
-+		ret = clk_rpm_handoff(rpm_clks[i]);
-+		if (ret)
-+			goto err;
-+	}
-+
-+	for (i = 0; i < num_clks; i++) {
-+		if (!rpm_clks[i]) {
-+			data->hws[i] = ERR_PTR(-ENOENT);
-+			continue;
-+		}
-+
-+		ret = devm_clk_hw_register(&pdev->dev, &rpm_clks[i]->hw);
-+		if (ret)
-+			goto err;
-+	}
-+
-+	ret = of_clk_add_hw_provider(pdev->dev.of_node, of_clk_hw_onecell_get,
-+				     data);
-+	if (ret)
-+		goto err;
-+
-+	return 0;
-+err:
-+	dev_err(&pdev->dev, "Error registering RPM Clock driver (%d)\n", ret);
-+	return ret;
-+}
-+
-+static int rpm_clk_remove(struct platform_device *pdev)
-+{
-+	of_clk_del_provider(pdev->dev.of_node);
-+	return 0;
-+}
-+
-+static struct platform_driver rpm_clk_driver = {
-+	.driver = {
-+		.name = "qcom-clk-rpm",
-+		.of_match_table = rpm_clk_match_table,
-+	},
-+	.probe = rpm_clk_probe,
-+	.remove = rpm_clk_remove,
-+};
-+
-+static int __init rpm_clk_init(void)
-+{
-+	return platform_driver_register(&rpm_clk_driver);
-+}
-+core_initcall(rpm_clk_init);
-+
-+static void __exit rpm_clk_exit(void)
-+{
-+	platform_driver_unregister(&rpm_clk_driver);
-+}
-+module_exit(rpm_clk_exit);
-+
-+MODULE_DESCRIPTION("Qualcomm RPM Clock Controller Driver");
-+MODULE_LICENSE("GPL v2");
-+MODULE_ALIAS("platform:qcom-clk-rpm");
---- a/include/dt-bindings/clock/qcom,rpmcc.h
-+++ b/include/dt-bindings/clock/qcom,rpmcc.h
-@@ -14,6 +14,30 @@
- #ifndef _DT_BINDINGS_CLK_MSM_RPMCC_H
- #define _DT_BINDINGS_CLK_MSM_RPMCC_H
- 
-+/* apq8064 */
-+#define RPM_PXO_CLK				0
-+#define RPM_PXO_A_CLK				1
-+#define RPM_CXO_CLK				2
-+#define RPM_CXO_A_CLK				3
-+#define RPM_APPS_FABRIC_CLK			4
-+#define RPM_APPS_FABRIC_A_CLK			5
-+#define RPM_CFPB_CLK				6
-+#define RPM_CFPB_A_CLK				7
-+#define RPM_QDSS_CLK				8
-+#define RPM_QDSS_A_CLK				9
-+#define RPM_DAYTONA_FABRIC_CLK			10
-+#define RPM_DAYTONA_FABRIC_A_CLK		11
-+#define RPM_EBI1_CLK				12
-+#define RPM_EBI1_A_CLK				13
-+#define RPM_MM_FABRIC_CLK			14
-+#define RPM_MM_FABRIC_A_CLK			15
-+#define RPM_MMFPB_CLK				16
-+#define RPM_MMFPB_A_CLK				17
-+#define RPM_SYS_FABRIC_CLK			18
-+#define RPM_SYS_FABRIC_A_CLK			19
-+#define RPM_SFPB_CLK				20
-+#define RPM_SFPB_A_CLK				21
-+
- /* msm8916 */
- #define RPM_SMD_XO_CLK_SRC				0
- #define RPM_SMD_XO_A_CLK_SRC			1
diff --git a/target/linux/ipq806x/patches-4.4/012-3-clk-qcom-clk-rpm-Fix-clk_hw-references.patch b/target/linux/ipq806x/patches-4.4/012-3-clk-qcom-clk-rpm-Fix-clk_hw-references.patch
deleted file mode 100644
index e5c1870..0000000
--- a/target/linux/ipq806x/patches-4.4/012-3-clk-qcom-clk-rpm-Fix-clk_hw-references.patch
+++ /dev/null
@@ -1,94 +0,0 @@
-From c260524aba53b57f72b5446ed553080df30b4d09 Mon Sep 17 00:00:00 2001
-From: Georgi Djakov <georgi.djakov at linaro.org>
-Date: Wed, 23 Nov 2016 16:52:49 +0200
-Subject: clk: qcom: clk-rpm: Fix clk_hw references
-
-Fix the clk_hw references to the actual clocks and add a xlate function
-to return the hw pointers from the already existing static array.
-
-Reported-by: Michael Scott <michael.scott at linaro.org>
-Signed-off-by: Georgi Djakov <georgi.djakov at linaro.org>
-Signed-off-by: Stephen Boyd <sboyd at codeaurora.org>
----
- drivers/clk/qcom/clk-rpm.c | 36 ++++++++++++++++++++++--------------
- 1 file changed, 22 insertions(+), 14 deletions(-)
-
---- a/drivers/clk/qcom/clk-rpm.c
-+++ b/drivers/clk/qcom/clk-rpm.c
-@@ -127,8 +127,8 @@ struct clk_rpm {
- 
- struct rpm_cc {
- 	struct qcom_rpm *rpm;
--	struct clk_hw_onecell_data data;
--	struct clk_hw *hws[];
-+	struct clk_rpm **clks;
-+	size_t num_clks;
- };
- 
- struct rpm_clk_desc {
-@@ -391,11 +391,23 @@ static const struct of_device_id rpm_clk
- };
- MODULE_DEVICE_TABLE(of, rpm_clk_match_table);
- 
-+static struct clk_hw *qcom_rpm_clk_hw_get(struct of_phandle_args *clkspec,
-+					  void *data)
-+{
-+	struct rpm_cc *rcc = data;
-+	unsigned int idx = clkspec->args[0];
-+
-+	if (idx >= rcc->num_clks) {
-+		pr_err("%s: invalid index %u\n", __func__, idx);
-+		return ERR_PTR(-EINVAL);
-+	}
-+
-+	return rcc->clks[idx] ? &rcc->clks[idx]->hw : ERR_PTR(-ENOENT);
-+}
-+
- static int rpm_clk_probe(struct platform_device *pdev)
- {
--	struct clk_hw **hws;
- 	struct rpm_cc *rcc;
--	struct clk_hw_onecell_data *data;
- 	int ret;
- 	size_t num_clks, i;
- 	struct qcom_rpm *rpm;
-@@ -415,14 +427,12 @@ static int rpm_clk_probe(struct platform
- 	rpm_clks = desc->clks;
- 	num_clks = desc->num_clks;
- 
--	rcc = devm_kzalloc(&pdev->dev, sizeof(*rcc) + sizeof(*hws) * num_clks,
--			   GFP_KERNEL);
-+	rcc = devm_kzalloc(&pdev->dev, sizeof(*rcc), GFP_KERNEL);
- 	if (!rcc)
- 		return -ENOMEM;
- 
--	hws = rcc->hws;
--	data = &rcc->data;
--	data->num = num_clks;
-+	rcc->clks = rpm_clks;
-+	rcc->num_clks = num_clks;
- 
- 	for (i = 0; i < num_clks; i++) {
- 		if (!rpm_clks[i])
-@@ -436,18 +446,16 @@ static int rpm_clk_probe(struct platform
- 	}
- 
- 	for (i = 0; i < num_clks; i++) {
--		if (!rpm_clks[i]) {
--			data->hws[i] = ERR_PTR(-ENOENT);
-+		if (!rpm_clks[i])
- 			continue;
--		}
- 
- 		ret = devm_clk_hw_register(&pdev->dev, &rpm_clks[i]->hw);
- 		if (ret)
- 			goto err;
- 	}
- 
--	ret = of_clk_add_hw_provider(pdev->dev.of_node, of_clk_hw_onecell_get,
--				     data);
-+	ret = of_clk_add_hw_provider(pdev->dev.of_node, qcom_rpm_clk_hw_get,
-+				     rcc);
- 	if (ret)
- 		goto err;
- 
diff --git a/target/linux/ipq806x/patches-4.4/015-1-thermal-qcom-tsens-Add-a-skeletal-TSENS-drivers.patch b/target/linux/ipq806x/patches-4.4/015-1-thermal-qcom-tsens-Add-a-skeletal-TSENS-drivers.patch
deleted file mode 100644
index ef7e2f4..0000000
--- a/target/linux/ipq806x/patches-4.4/015-1-thermal-qcom-tsens-Add-a-skeletal-TSENS-drivers.patch
+++ /dev/null
@@ -1,536 +0,0 @@
-From 9066073c6c27994a30187abf3b674770b4088348 Mon Sep 17 00:00:00 2001
-From: Rajendra Nayak <rnayak at codeaurora.org>
-Date: Thu, 5 May 2016 14:21:39 +0530
-Subject: thermal: qcom: tsens: Add a skeletal TSENS drivers
-
-TSENS is Qualcomms' thermal temperature sensor device. It
-supports reading temperatures from multiple thermal sensors
-present on various QCOM SoCs.
-Calibration data is generally read from a non-volatile memory
-(eeprom) device.
-
-Add a skeleton driver with all the necessary abstractions so
-a variety of qcom device families which support TSENS can
-add driver extensions.
-
-Also add the required device tree bindings which can be used
-to describe the TSENS device in DT.
-
-Signed-off-by: Rajendra Nayak <rnayak at codeaurora.org>
-Reviewed-by: Lina Iyer <lina.iyer at linaro.org>
-Signed-off-by: Eduardo Valentin <edubezval at gmail.com>
-Signed-off-by: Zhang Rui <rui.zhang at intel.com>
----
- .../devicetree/bindings/thermal/qcom-tsens.txt     |  21 +++
- drivers/thermal/Kconfig                            |   5 +
- drivers/thermal/Makefile                           |   1 +
- drivers/thermal/qcom/Kconfig                       |  11 ++
- drivers/thermal/qcom/Makefile                      |   2 +
- drivers/thermal/qcom/tsens-common.c                | 141 +++++++++++++++
- drivers/thermal/qcom/tsens.c                       | 195 +++++++++++++++++++++
- drivers/thermal/qcom/tsens.h                       |  90 ++++++++++
- 8 files changed, 466 insertions(+)
- create mode 100644 Documentation/devicetree/bindings/thermal/qcom-tsens.txt
- create mode 100644 drivers/thermal/qcom/Kconfig
- create mode 100644 drivers/thermal/qcom/Makefile
- create mode 100644 drivers/thermal/qcom/tsens-common.c
- create mode 100644 drivers/thermal/qcom/tsens.c
- create mode 100644 drivers/thermal/qcom/tsens.h
-
---- /dev/null
-+++ b/Documentation/devicetree/bindings/thermal/qcom-tsens.txt
-@@ -0,0 +1,21 @@
-+* QCOM SoC Temperature Sensor (TSENS)
-+
-+Required properties:
-+- compatible :
-+ - "qcom,msm8916-tsens" : For 8916 Family of SoCs
-+ - "qcom,msm8974-tsens" : For 8974 Family of SoCs
-+ - "qcom,msm8996-tsens" : For 8996 Family of SoCs
-+
-+- reg: Address range of the thermal registers
-+- #thermal-sensor-cells : Should be 1. See ./thermal.txt for a description.
-+- Refer to Documentation/devicetree/bindings/nvmem/nvmem.txt to know how to specify
-+nvmem cells
-+
-+Example:
-+tsens: thermal-sensor at 900000 {
-+		compatible = "qcom,msm8916-tsens";
-+		reg = <0x4a8000 0x2000>;
-+		nvmem-cells = <&tsens_caldata>, <&tsens_calsel>;
-+		nvmem-cell-names = "caldata", "calsel";
-+		#thermal-sensor-cells = <1>;
-+	};
---- a/drivers/thermal/Kconfig
-+++ b/drivers/thermal/Kconfig
-@@ -391,4 +391,9 @@ config QCOM_SPMI_TEMP_ALARM
- 	  real time die temperature if an ADC is present or an estimate of the
- 	  temperature based upon the over temperature stage value.
- 
-+menu "Qualcomm thermal drivers"
-+depends on (ARCH_QCOM && OF) || COMPILE_TEST
-+source "drivers/thermal/qcom/Kconfig"
-+endmenu
-+
- endif
---- a/drivers/thermal/Makefile
-+++ b/drivers/thermal/Makefile
-@@ -48,3 +48,4 @@ obj-$(CONFIG_INTEL_PCH_THERMAL)	+= intel
- obj-$(CONFIG_ST_THERMAL)	+= st/
- obj-$(CONFIG_TEGRA_SOCTHERM)	+= tegra_soctherm.o
- obj-$(CONFIG_HISI_THERMAL)     += hisi_thermal.o
-+obj-$(CONFIG_QCOM_TSENS)	+= qcom/
---- /dev/null
-+++ b/drivers/thermal/qcom/Kconfig
-@@ -0,0 +1,11 @@
-+config QCOM_TSENS
-+	tristate "Qualcomm TSENS Temperature Alarm"
-+	depends on THERMAL
-+	depends on QCOM_QFPROM
-+	depends on ARCH_QCOM || COMPILE_TEST
-+	help
-+	  This enables the thermal sysfs driver for the TSENS device. It shows
-+	  up in Sysfs as a thermal zone with multiple trip points. Disabling the
-+	  thermal zone device via the mode file results in disabling the sensor.
-+	  Also able to set threshold temperature for both hot and cold and update
-+	  when a threshold is reached.
---- /dev/null
-+++ b/drivers/thermal/qcom/Makefile
-@@ -0,0 +1,2 @@
-+obj-$(CONFIG_QCOM_TSENS)	+= qcom_tsens.o
-+qcom_tsens-y			+= tsens.o tsens-common.o
---- /dev/null
-+++ b/drivers/thermal/qcom/tsens-common.c
-@@ -0,0 +1,141 @@
-+/*
-+ * 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/err.h>
-+#include <linux/io.h>
-+#include <linux/nvmem-consumer.h>
-+#include <linux/of_address.h>
-+#include <linux/platform_device.h>
-+#include <linux/regmap.h>
-+#include "tsens.h"
-+
-+#define S0_ST_ADDR		0x1030
-+#define SN_ADDR_OFFSET		0x4
-+#define SN_ST_TEMP_MASK		0x3ff
-+#define CAL_DEGC_PT1		30
-+#define CAL_DEGC_PT2		120
-+#define SLOPE_FACTOR		1000
-+#define SLOPE_DEFAULT		3200
-+
-+char *qfprom_read(struct device *dev, const char *cname)
-+{
-+	struct nvmem_cell *cell;
-+	ssize_t data;
-+	char *ret;
-+
-+	cell = nvmem_cell_get(dev, cname);
-+	if (IS_ERR(cell))
-+		return ERR_CAST(cell);
-+
-+	ret = nvmem_cell_read(cell, &data);
-+	nvmem_cell_put(cell);
-+
-+	return ret;
-+}
-+
-+/*
-+ * Use this function on devices where slope and offset calculations
-+ * depend on calibration data read from qfprom. On others the slope
-+ * and offset values are derived from tz->tzp->slope and tz->tzp->offset
-+ * resp.
-+ */
-+void compute_intercept_slope(struct tsens_device *tmdev, u32 *p1,
-+			     u32 *p2, u32 mode)
-+{
-+	int i;
-+	int num, den;
-+
-+	for (i = 0; i < tmdev->num_sensors; i++) {
-+		dev_dbg(tmdev->dev,
-+			"sensor%d - data_point1:%#x data_point2:%#x\n",
-+			i, p1[i], p2[i]);
-+
-+		tmdev->sensor[i].slope = SLOPE_DEFAULT;
-+		if (mode == TWO_PT_CALIB) {
-+			/*
-+			 * slope (m) = adc_code2 - adc_code1 (y2 - y1)/
-+			 *	temp_120_degc - temp_30_degc (x2 - x1)
-+			 */
-+			num = p2[i] - p1[i];
-+			num *= SLOPE_FACTOR;
-+			den = CAL_DEGC_PT2 - CAL_DEGC_PT1;
-+			tmdev->sensor[i].slope = num / den;
-+		}
-+
-+		tmdev->sensor[i].offset = (p1[i] * SLOPE_FACTOR) -
-+				(CAL_DEGC_PT1 *
-+				tmdev->sensor[i].slope);
-+		dev_dbg(tmdev->dev, "offset:%d\n", tmdev->sensor[i].offset);
-+	}
-+}
-+
-+static inline int code_to_degc(u32 adc_code, const struct tsens_sensor *s)
-+{
-+	int degc, num, den;
-+
-+	num = (adc_code * SLOPE_FACTOR) - s->offset;
-+	den = s->slope;
-+
-+	if (num > 0)
-+		degc = num + (den / 2);
-+	else if (num < 0)
-+		degc = num - (den / 2);
-+	else
-+		degc = num;
-+
-+	degc /= den;
-+
-+	return degc;
-+}
-+
-+int get_temp_common(struct tsens_device *tmdev, int id, int *temp)
-+{
-+	struct tsens_sensor *s = &tmdev->sensor[id];
-+	u32 code;
-+	unsigned int sensor_addr;
-+	int last_temp = 0, ret;
-+
-+	sensor_addr = S0_ST_ADDR + s->hw_id * SN_ADDR_OFFSET;
-+	ret = regmap_read(tmdev->map, sensor_addr, &code);
-+	if (ret)
-+		return ret;
-+	last_temp = code & SN_ST_TEMP_MASK;
-+
-+	*temp = code_to_degc(last_temp, s) * 1000;
-+
-+	return 0;
-+}
-+
-+static const struct regmap_config tsens_config = {
-+	.reg_bits	= 32,
-+	.val_bits	= 32,
-+	.reg_stride	= 4,
-+};
-+
-+int __init init_common(struct tsens_device *tmdev)
-+{
-+	void __iomem *base;
-+
-+	base = of_iomap(tmdev->dev->of_node, 0);
-+	if (IS_ERR(base))
-+		return -EINVAL;
-+
-+	tmdev->map = devm_regmap_init_mmio(tmdev->dev, base, &tsens_config);
-+	if (!tmdev->map) {
-+		iounmap(base);
-+		return -ENODEV;
-+	}
-+
-+	return 0;
-+}
---- /dev/null
-+++ b/drivers/thermal/qcom/tsens.c
-@@ -0,0 +1,195 @@
-+/*
-+ * 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/err.h>
-+#include <linux/module.h>
-+#include <linux/of.h>
-+#include <linux/platform_device.h>
-+#include <linux/pm.h>
-+#include <linux/slab.h>
-+#include <linux/thermal.h>
-+#include "tsens.h"
-+
-+static int tsens_get_temp(void *data, int *temp)
-+{
-+	const struct tsens_sensor *s = data;
-+	struct tsens_device *tmdev = s->tmdev;
-+
-+	return tmdev->ops->get_temp(tmdev, s->id, temp);
-+}
-+
-+static int tsens_get_trend(void *data, long *temp)
-+{
-+	const struct tsens_sensor *s = data;
-+	struct tsens_device *tmdev = s->tmdev;
-+
-+	if (tmdev->ops->get_trend)
-+		return tmdev->ops->get_trend(tmdev, s->id, temp);
-+
-+	return -ENOTSUPP;
-+}
-+
-+static int tsens_suspend(struct device *dev)
-+{
-+	struct tsens_device *tmdev = dev_get_drvdata(dev);
-+
-+	if (tmdev->ops && tmdev->ops->suspend)
-+		return tmdev->ops->suspend(tmdev);
-+
-+	return 0;
-+}
-+
-+static int tsens_resume(struct device *dev)
-+{
-+	struct tsens_device *tmdev = dev_get_drvdata(dev);
-+
-+	if (tmdev->ops && tmdev->ops->resume)
-+		return tmdev->ops->resume(tmdev);
-+
-+	return 0;
-+}
-+
-+static SIMPLE_DEV_PM_OPS(tsens_pm_ops, tsens_suspend, tsens_resume);
-+
-+static const struct of_device_id tsens_table[] = {
-+	{
-+		.compatible = "qcom,msm8916-tsens",
-+	}, {
-+		.compatible = "qcom,msm8974-tsens",
-+	},
-+	{}
-+};
-+MODULE_DEVICE_TABLE(of, tsens_table);
-+
-+static const struct thermal_zone_of_device_ops tsens_of_ops = {
-+	.get_temp = tsens_get_temp,
-+	.get_trend = tsens_get_trend,
-+};
-+
-+static int tsens_register(struct tsens_device *tmdev)
-+{
-+	int i;
-+	struct thermal_zone_device *tzd;
-+	u32 *hw_id, n = tmdev->num_sensors;
-+
-+	hw_id = devm_kcalloc(tmdev->dev, n, sizeof(u32), GFP_KERNEL);
-+	if (!hw_id)
-+		return -ENOMEM;
-+
-+	for (i = 0;  i < tmdev->num_sensors; i++) {
-+		tmdev->sensor[i].tmdev = tmdev;
-+		tmdev->sensor[i].id = i;
-+		tzd = devm_thermal_zone_of_sensor_register(tmdev->dev, i,
-+							   &tmdev->sensor[i],
-+							   &tsens_of_ops);
-+		if (IS_ERR(tzd))
-+			continue;
-+		tmdev->sensor[i].tzd = tzd;
-+		if (tmdev->ops->enable)
-+			tmdev->ops->enable(tmdev, i);
-+	}
-+	return 0;
-+}
-+
-+static int tsens_probe(struct platform_device *pdev)
-+{
-+	int ret, i;
-+	struct device *dev;
-+	struct device_node *np;
-+	struct tsens_sensor *s;
-+	struct tsens_device *tmdev;
-+	const struct tsens_data *data;
-+	const struct of_device_id *id;
-+
-+	if (pdev->dev.of_node)
-+		dev = &pdev->dev;
-+	else
-+		dev = pdev->dev.parent;
-+
-+	np = dev->of_node;
-+
-+	id = of_match_node(tsens_table, np);
-+	if (!id)
-+		return -EINVAL;
-+
-+	data = id->data;
-+
-+	if (data->num_sensors <= 0) {
-+		dev_err(dev, "invalid number of sensors\n");
-+		return -EINVAL;
-+	}
-+
-+	tmdev = devm_kzalloc(dev, sizeof(*tmdev) +
-+			     data->num_sensors * sizeof(*s), GFP_KERNEL);
-+	if (!tmdev)
-+		return -ENOMEM;
-+
-+	tmdev->dev = dev;
-+	tmdev->num_sensors = data->num_sensors;
-+	tmdev->ops = data->ops;
-+	for (i = 0;  i < tmdev->num_sensors; i++) {
-+		if (data->hw_ids)
-+			tmdev->sensor[i].hw_id = data->hw_ids[i];
-+		else
-+			tmdev->sensor[i].hw_id = i;
-+	}
-+
-+	if (!tmdev->ops || !tmdev->ops->init || !tmdev->ops->get_temp)
-+		return -EINVAL;
-+
-+	ret = tmdev->ops->init(tmdev);
-+	if (ret < 0) {
-+		dev_err(dev, "tsens init failed\n");
-+		return ret;
-+	}
-+
-+	if (tmdev->ops->calibrate) {
-+		ret = tmdev->ops->calibrate(tmdev);
-+		if (ret < 0) {
-+			dev_err(dev, "tsens calibration failed\n");
-+			return ret;
-+		}
-+	}
-+
-+	ret = tsens_register(tmdev);
-+
-+	platform_set_drvdata(pdev, tmdev);
-+
-+	return ret;
-+}
-+
-+static int tsens_remove(struct platform_device *pdev)
-+{
-+	struct tsens_device *tmdev = platform_get_drvdata(pdev);
-+
-+	if (tmdev->ops->disable)
-+		tmdev->ops->disable(tmdev);
-+
-+	return 0;
-+}
-+
-+static struct platform_driver tsens_driver = {
-+	.probe = tsens_probe,
-+	.remove = tsens_remove,
-+	.driver = {
-+		.name = "qcom-tsens",
-+		.pm	= &tsens_pm_ops,
-+		.of_match_table = tsens_table,
-+	},
-+};
-+module_platform_driver(tsens_driver);
-+
-+MODULE_LICENSE("GPL v2");
-+MODULE_DESCRIPTION("QCOM Temperature Sensor driver");
-+MODULE_ALIAS("platform:qcom-tsens");
---- /dev/null
-+++ b/drivers/thermal/qcom/tsens.h
-@@ -0,0 +1,90 @@
-+/*
-+ * 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.
-+ */
-+#ifndef __QCOM_TSENS_H__
-+#define __QCOM_TSENS_H__
-+
-+#define ONE_PT_CALIB		0x1
-+#define ONE_PT_CALIB2		0x2
-+#define TWO_PT_CALIB		0x3
-+
-+struct tsens_device;
-+
-+struct tsens_sensor {
-+	struct tsens_device		*tmdev;
-+	struct thermal_zone_device	*tzd;
-+	int				offset;
-+	int				id;
-+	int				hw_id;
-+	int				slope;
-+	u32				status;
-+};
-+
-+/**
-+ * struct tsens_ops - operations as supported by the tsens device
-+ * @init: Function to initialize the tsens device
-+ * @calibrate: Function to calibrate the tsens device
-+ * @get_temp: Function which returns the temp in millidegC
-+ * @enable: Function to enable (clocks/power) tsens device
-+ * @disable: Function to disable the tsens device
-+ * @suspend: Function to suspend the tsens device
-+ * @resume: Function to resume the tsens device
-+ * @get_trend: Function to get the thermal/temp trend
-+ */
-+struct tsens_ops {
-+	/* mandatory callbacks */
-+	int (*init)(struct tsens_device *);
-+	int (*calibrate)(struct tsens_device *);
-+	int (*get_temp)(struct tsens_device *, int, int *);
-+	/* optional callbacks */
-+	int (*enable)(struct tsens_device *, int);
-+	void (*disable)(struct tsens_device *);
-+	int (*suspend)(struct tsens_device *);
-+	int (*resume)(struct tsens_device *);
-+	int (*get_trend)(struct tsens_device *, int, long *);
-+};
-+
-+/**
-+ * struct tsens_data - tsens instance specific data
-+ * @num_sensors: Max number of sensors supported by platform
-+ * @ops: operations the tsens instance supports
-+ * @hw_ids: Subset of sensors ids supported by platform, if not the first n
-+ */
-+struct tsens_data {
-+	const u32		num_sensors;
-+	const struct tsens_ops	*ops;
-+	unsigned int		*hw_ids;
-+};
-+
-+/* Registers to be saved/restored across a context loss */
-+struct tsens_context {
-+	int	threshold;
-+	int	control;
-+};
-+
-+struct tsens_device {
-+	struct device			*dev;
-+	u32				num_sensors;
-+	struct regmap			*map;
-+	struct regmap_field		*status_field;
-+	struct tsens_context		ctx;
-+	bool				trdy;
-+	const struct tsens_ops		*ops;
-+	struct tsens_sensor		sensor[0];
-+};
-+
-+char *qfprom_read(struct device *, const char *);
-+void compute_intercept_slope(struct tsens_device *, u32 *, u32 *, u32);
-+int init_common(struct tsens_device *);
-+int get_temp_common(struct tsens_device *, int, int *);
-+
-+#endif /* __QCOM_TSENS_H__ */
diff --git a/target/linux/ipq806x/patches-4.4/015-2-thermal-qcom-tsens-8916-Add-support-for-8916-family-of-SoCs.patch b/target/linux/ipq806x/patches-4.4/015-2-thermal-qcom-tsens-8916-Add-support-for-8916-family-of-SoCs.patch
deleted file mode 100644
index d076196..0000000
--- a/target/linux/ipq806x/patches-4.4/015-2-thermal-qcom-tsens-8916-Add-support-for-8916-family-of-SoCs.patch
+++ /dev/null
@@ -1,165 +0,0 @@
-From 840a5bd3ed3fdd62456d4d26c3128ec10496555b Mon Sep 17 00:00:00 2001
-From: Rajendra Nayak <rnayak at codeaurora.org>
-Date: Thu, 5 May 2016 14:21:40 +0530
-Subject: thermal: qcom: tsens-8916: Add support for 8916 family of SoCs
-
-Add support to calibrate sensors on 8916 family and also add common
-functions to read temperature from sensors (This can be reused on
-other SoCs having similar TSENS device)
-The calibration data is read from eeprom using the generic nvmem
-framework apis.
-
-Based on the original code by Siddartha Mohanadoss and Stephen Boyd.
-
-Signed-off-by: Rajendra Nayak <rnayak at codeaurora.org>
-Signed-off-by: Eduardo Valentin <edubezval at gmail.com>
-Signed-off-by: Zhang Rui <rui.zhang at intel.com>
----
- drivers/thermal/qcom/Makefile     |   2 +-
- drivers/thermal/qcom/tsens-8916.c | 113 ++++++++++++++++++++++++++++++++++++++
- drivers/thermal/qcom/tsens.c      |   1 +
- drivers/thermal/qcom/tsens.h      |   2 +
- 4 files changed, 117 insertions(+), 1 deletion(-)
- create mode 100644 drivers/thermal/qcom/tsens-8916.c
-
---- a/drivers/thermal/qcom/Makefile
-+++ b/drivers/thermal/qcom/Makefile
-@@ -1,2 +1,2 @@
- obj-$(CONFIG_QCOM_TSENS)	+= qcom_tsens.o
--qcom_tsens-y			+= tsens.o tsens-common.o
-+qcom_tsens-y			+= tsens.o tsens-common.o tsens-8916.o
---- /dev/null
-+++ b/drivers/thermal/qcom/tsens-8916.c
-@@ -0,0 +1,113 @@
-+/*
-+ * 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/platform_device.h>
-+#include "tsens.h"
-+
-+/* eeprom layout data for 8916 */
-+#define BASE0_MASK	0x0000007f
-+#define BASE1_MASK	0xfe000000
-+#define BASE0_SHIFT	0
-+#define BASE1_SHIFT	25
-+
-+#define S0_P1_MASK	0x00000f80
-+#define S1_P1_MASK	0x003e0000
-+#define S2_P1_MASK	0xf8000000
-+#define S3_P1_MASK	0x000003e0
-+#define S4_P1_MASK	0x000f8000
-+
-+#define S0_P2_MASK	0x0001f000
-+#define S1_P2_MASK	0x07c00000
-+#define S2_P2_MASK	0x0000001f
-+#define S3_P2_MASK	0x00007c00
-+#define S4_P2_MASK	0x01f00000
-+
-+#define S0_P1_SHIFT	7
-+#define S1_P1_SHIFT	17
-+#define S2_P1_SHIFT	27
-+#define S3_P1_SHIFT	5
-+#define S4_P1_SHIFT	15
-+
-+#define S0_P2_SHIFT	12
-+#define S1_P2_SHIFT	22
-+#define S2_P2_SHIFT	0
-+#define S3_P2_SHIFT	10
-+#define S4_P2_SHIFT	20
-+
-+#define CAL_SEL_MASK	0xe0000000
-+#define CAL_SEL_SHIFT	29
-+
-+static int calibrate_8916(struct tsens_device *tmdev)
-+{
-+	int base0 = 0, base1 = 0, i;
-+	u32 p1[5], p2[5];
-+	int mode = 0;
-+	u32 *qfprom_cdata, *qfprom_csel;
-+
-+	qfprom_cdata = (u32 *)qfprom_read(tmdev->dev, "calib");
-+	if (IS_ERR(qfprom_cdata))
-+		return PTR_ERR(qfprom_cdata);
-+
-+	qfprom_csel = (u32 *)qfprom_read(tmdev->dev, "calib_sel");
-+	if (IS_ERR(qfprom_csel))
-+		return PTR_ERR(qfprom_csel);
-+
-+	mode = (qfprom_csel[0] & CAL_SEL_MASK) >> CAL_SEL_SHIFT;
-+	dev_dbg(tmdev->dev, "calibration mode is %d\n", mode);
-+
-+	switch (mode) {
-+	case TWO_PT_CALIB:
-+		base1 = (qfprom_cdata[1] & BASE1_MASK) >> BASE1_SHIFT;
-+		p2[0] = (qfprom_cdata[0] & S0_P2_MASK) >> S0_P2_SHIFT;
-+		p2[1] = (qfprom_cdata[0] & S1_P2_MASK) >> S1_P2_SHIFT;
-+		p2[2] = (qfprom_cdata[1] & S2_P2_MASK) >> S2_P2_SHIFT;
-+		p2[3] = (qfprom_cdata[1] & S3_P2_MASK) >> S3_P2_SHIFT;
-+		p2[4] = (qfprom_cdata[1] & S4_P2_MASK) >> S4_P2_SHIFT;
-+		for (i = 0; i < tmdev->num_sensors; i++)
-+			p2[i] = ((base1 + p2[i]) << 3);
-+		/* Fall through */
-+	case ONE_PT_CALIB2:
-+		base0 = (qfprom_cdata[0] & BASE0_MASK);
-+		p1[0] = (qfprom_cdata[0] & S0_P1_MASK) >> S0_P1_SHIFT;
-+		p1[1] = (qfprom_cdata[0] & S1_P1_MASK) >> S1_P1_SHIFT;
-+		p1[2] = (qfprom_cdata[0] & S2_P1_MASK) >> S2_P1_SHIFT;
-+		p1[3] = (qfprom_cdata[1] & S3_P1_MASK) >> S3_P1_SHIFT;
-+		p1[4] = (qfprom_cdata[1] & S4_P1_MASK) >> S4_P1_SHIFT;
-+		for (i = 0; i < tmdev->num_sensors; i++)
-+			p1[i] = (((base0) + p1[i]) << 3);
-+		break;
-+	default:
-+		for (i = 0; i < tmdev->num_sensors; i++) {
-+			p1[i] = 500;
-+			p2[i] = 780;
-+		}
-+		break;
-+	}
-+
-+	compute_intercept_slope(tmdev, p1, p2, mode);
-+
-+	return 0;
-+}
-+
-+const struct tsens_ops ops_8916 = {
-+	.init		= init_common,
-+	.calibrate	= calibrate_8916,
-+	.get_temp	= get_temp_common,
-+};
-+
-+const struct tsens_data data_8916 = {
-+	.num_sensors	= 5,
-+	.ops		= &ops_8916,
-+	.hw_ids		= (unsigned int []){0, 1, 2, 4, 5 },
-+};
---- a/drivers/thermal/qcom/tsens.c
-+++ b/drivers/thermal/qcom/tsens.c
-@@ -65,6 +65,7 @@ static SIMPLE_DEV_PM_OPS(tsens_pm_ops, t
- static const struct of_device_id tsens_table[] = {
- 	{
- 		.compatible = "qcom,msm8916-tsens",
-+		.data = &data_8916,
- 	}, {
- 		.compatible = "qcom,msm8974-tsens",
- 	},
---- a/drivers/thermal/qcom/tsens.h
-+++ b/drivers/thermal/qcom/tsens.h
-@@ -87,4 +87,6 @@ void compute_intercept_slope(struct tsen
- int init_common(struct tsens_device *);
- int get_temp_common(struct tsens_device *, int, int *);
- 
-+extern const struct tsens_data data_8916;
-+
- #endif /* __QCOM_TSENS_H__ */
diff --git a/target/linux/ipq806x/patches-4.4/015-3-thermal-qcom-tsens-8974-Add-support-for-8974-family-of-SoCs.patch b/target/linux/ipq806x/patches-4.4/015-3-thermal-qcom-tsens-8974-Add-support-for-8974-family-of-SoCs.patch
deleted file mode 100644
index 671f461..0000000
--- a/target/linux/ipq806x/patches-4.4/015-3-thermal-qcom-tsens-8974-Add-support-for-8974-family-of-SoCs.patch
+++ /dev/null
@@ -1,293 +0,0 @@
-From 5e6703bd2d83548998848865cb9a9a795f31a311 Mon Sep 17 00:00:00 2001
-From: Rajendra Nayak <rnayak at codeaurora.org>
-Date: Thu, 5 May 2016 14:21:41 +0530
-Subject: thermal: qcom: tsens-8974: Add support for 8974 family of SoCs
-
-Add .calibrate support for 8974 family as part of tsens_ops.
-
-Based on the original code by Siddartha Mohanadoss and Stephen Boyd.
-
-Signed-off-by: Rajendra Nayak <rnayak at codeaurora.org>
-Signed-off-by: Eduardo Valentin <edubezval at gmail.com>
-Signed-off-by: Zhang Rui <rui.zhang at intel.com>
----
- drivers/thermal/qcom/Makefile     |   2 +-
- drivers/thermal/qcom/tsens-8974.c | 244 ++++++++++++++++++++++++++++++++++++++
- drivers/thermal/qcom/tsens.c      |   1 +
- drivers/thermal/qcom/tsens.h      |   2 +-
- 4 files changed, 247 insertions(+), 2 deletions(-)
- create mode 100644 drivers/thermal/qcom/tsens-8974.c
-
---- a/drivers/thermal/qcom/Makefile
-+++ b/drivers/thermal/qcom/Makefile
-@@ -1,2 +1,2 @@
- obj-$(CONFIG_QCOM_TSENS)	+= qcom_tsens.o
--qcom_tsens-y			+= tsens.o tsens-common.o tsens-8916.o
-+qcom_tsens-y			+= tsens.o tsens-common.o tsens-8916.o tsens-8974.o
---- /dev/null
-+++ b/drivers/thermal/qcom/tsens-8974.c
-@@ -0,0 +1,244 @@
-+/*
-+ * 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/platform_device.h>
-+#include "tsens.h"
-+
-+/* eeprom layout data for 8974 */
-+#define BASE1_MASK		0xff
-+#define S0_P1_MASK		0x3f00
-+#define S1_P1_MASK		0xfc000
-+#define S2_P1_MASK		0x3f00000
-+#define S3_P1_MASK		0xfc000000
-+#define S4_P1_MASK		0x3f
-+#define S5_P1_MASK		0xfc0
-+#define S6_P1_MASK		0x3f000
-+#define S7_P1_MASK		0xfc0000
-+#define S8_P1_MASK		0x3f000000
-+#define S8_P1_MASK_BKP		0x3f
-+#define S9_P1_MASK		0x3f
-+#define S9_P1_MASK_BKP		0xfc0
-+#define S10_P1_MASK		0xfc0
-+#define S10_P1_MASK_BKP		0x3f000
-+#define CAL_SEL_0_1		0xc0000000
-+#define CAL_SEL_2		0x40000000
-+#define CAL_SEL_SHIFT		30
-+#define CAL_SEL_SHIFT_2		28
-+
-+#define S0_P1_SHIFT		8
-+#define S1_P1_SHIFT		14
-+#define S2_P1_SHIFT		20
-+#define S3_P1_SHIFT		26
-+#define S5_P1_SHIFT		6
-+#define S6_P1_SHIFT		12
-+#define S7_P1_SHIFT		18
-+#define S8_P1_SHIFT		24
-+#define S9_P1_BKP_SHIFT		6
-+#define S10_P1_SHIFT		6
-+#define S10_P1_BKP_SHIFT	12
-+
-+#define BASE2_SHIFT		12
-+#define BASE2_BKP_SHIFT		18
-+#define S0_P2_SHIFT		20
-+#define S0_P2_BKP_SHIFT		26
-+#define S1_P2_SHIFT		26
-+#define S2_P2_BKP_SHIFT		6
-+#define S3_P2_SHIFT		6
-+#define S3_P2_BKP_SHIFT		12
-+#define S4_P2_SHIFT		12
-+#define S4_P2_BKP_SHIFT		18
-+#define S5_P2_SHIFT		18
-+#define S5_P2_BKP_SHIFT		24
-+#define S6_P2_SHIFT		24
-+#define S7_P2_BKP_SHIFT		6
-+#define S8_P2_SHIFT		6
-+#define S8_P2_BKP_SHIFT		12
-+#define S9_P2_SHIFT		12
-+#define S9_P2_BKP_SHIFT		18
-+#define S10_P2_SHIFT		18
-+#define S10_P2_BKP_SHIFT	24
-+
-+#define BASE2_MASK		0xff000
-+#define BASE2_BKP_MASK		0xfc0000
-+#define S0_P2_MASK		0x3f00000
-+#define S0_P2_BKP_MASK		0xfc000000
-+#define S1_P2_MASK		0xfc000000
-+#define S1_P2_BKP_MASK		0x3f
-+#define S2_P2_MASK		0x3f
-+#define S2_P2_BKP_MASK		0xfc0
-+#define S3_P2_MASK		0xfc0
-+#define S3_P2_BKP_MASK		0x3f000
-+#define S4_P2_MASK		0x3f000
-+#define S4_P2_BKP_MASK		0xfc0000
-+#define S5_P2_MASK		0xfc0000
-+#define S5_P2_BKP_MASK		0x3f000000
-+#define S6_P2_MASK		0x3f000000
-+#define S6_P2_BKP_MASK		0x3f
-+#define S7_P2_MASK		0x3f
-+#define S7_P2_BKP_MASK		0xfc0
-+#define S8_P2_MASK		0xfc0
-+#define S8_P2_BKP_MASK		0x3f000
-+#define S9_P2_MASK		0x3f000
-+#define S9_P2_BKP_MASK		0xfc0000
-+#define S10_P2_MASK		0xfc0000
-+#define S10_P2_BKP_MASK		0x3f000000
-+
-+#define BKP_SEL			0x3
-+#define BKP_REDUN_SEL		0xe0000000
-+#define BKP_REDUN_SHIFT		29
-+
-+#define BIT_APPEND		0x3
-+
-+static int calibrate_8974(struct tsens_device *tmdev)
-+{
-+	int base1 = 0, base2 = 0, i;
-+	u32 p1[11], p2[11];
-+	int mode = 0;
-+	u32 *calib, *bkp;
-+	u32 calib_redun_sel;
-+
-+	calib = (u32 *)qfprom_read(tmdev->dev, "calib");
-+	if (IS_ERR(calib))
-+		return PTR_ERR(calib);
-+
-+	bkp = (u32 *)qfprom_read(tmdev->dev, "calib_backup");
-+	if (IS_ERR(bkp))
-+		return PTR_ERR(bkp);
-+
-+	calib_redun_sel =  bkp[1] & BKP_REDUN_SEL;
-+	calib_redun_sel >>= BKP_REDUN_SHIFT;
-+
-+	if (calib_redun_sel == BKP_SEL) {
-+		mode = (calib[4] & CAL_SEL_0_1) >> CAL_SEL_SHIFT;
-+		mode |= (calib[5] & CAL_SEL_2) >> CAL_SEL_SHIFT_2;
-+
-+		switch (mode) {
-+		case TWO_PT_CALIB:
-+			base2 = (bkp[2] & BASE2_BKP_MASK) >> BASE2_BKP_SHIFT;
-+			p2[0] = (bkp[2] & S0_P2_BKP_MASK) >> S0_P2_BKP_SHIFT;
-+			p2[1] = (bkp[3] & S1_P2_BKP_MASK);
-+			p2[2] = (bkp[3] & S2_P2_BKP_MASK) >> S2_P2_BKP_SHIFT;
-+			p2[3] = (bkp[3] & S3_P2_BKP_MASK) >> S3_P2_BKP_SHIFT;
-+			p2[4] = (bkp[3] & S4_P2_BKP_MASK) >> S4_P2_BKP_SHIFT;
-+			p2[5] = (calib[4] & S5_P2_BKP_MASK) >> S5_P2_BKP_SHIFT;
-+			p2[6] = (calib[5] & S6_P2_BKP_MASK);
-+			p2[7] = (calib[5] & S7_P2_BKP_MASK) >> S7_P2_BKP_SHIFT;
-+			p2[8] = (calib[5] & S8_P2_BKP_MASK) >> S8_P2_BKP_SHIFT;
-+			p2[9] = (calib[5] & S9_P2_BKP_MASK) >> S9_P2_BKP_SHIFT;
-+			p2[10] = (calib[5] & S10_P2_BKP_MASK) >> S10_P2_BKP_SHIFT;
-+			/* Fall through */
-+		case ONE_PT_CALIB:
-+		case ONE_PT_CALIB2:
-+			base1 = bkp[0] & BASE1_MASK;
-+			p1[0] = (bkp[0] & S0_P1_MASK) >> S0_P1_SHIFT;
-+			p1[1] = (bkp[0] & S1_P1_MASK) >> S1_P1_SHIFT;
-+			p1[2] = (bkp[0] & S2_P1_MASK) >> S2_P1_SHIFT;
-+			p1[3] = (bkp[0] & S3_P1_MASK) >> S3_P1_SHIFT;
-+			p1[4] = (bkp[1] & S4_P1_MASK);
-+			p1[5] = (bkp[1] & S5_P1_MASK) >> S5_P1_SHIFT;
-+			p1[6] = (bkp[1] & S6_P1_MASK) >> S6_P1_SHIFT;
-+			p1[7] = (bkp[1] & S7_P1_MASK) >> S7_P1_SHIFT;
-+			p1[8] = (bkp[2] & S8_P1_MASK_BKP) >> S8_P1_SHIFT;
-+			p1[9] = (bkp[2] & S9_P1_MASK_BKP) >> S9_P1_BKP_SHIFT;
-+			p1[10] = (bkp[2] & S10_P1_MASK_BKP) >> S10_P1_BKP_SHIFT;
-+			break;
-+		}
-+	} else {
-+		mode = (calib[1] & CAL_SEL_0_1) >> CAL_SEL_SHIFT;
-+		mode |= (calib[3] & CAL_SEL_2) >> CAL_SEL_SHIFT_2;
-+
-+		switch (mode) {
-+		case TWO_PT_CALIB:
-+			base2 = (calib[2] & BASE2_MASK) >> BASE2_SHIFT;
-+			p2[0] = (calib[2] & S0_P2_MASK) >> S0_P2_SHIFT;
-+			p2[1] = (calib[2] & S1_P2_MASK) >> S1_P2_SHIFT;
-+			p2[2] = (calib[3] & S2_P2_MASK);
-+			p2[3] = (calib[3] & S3_P2_MASK) >> S3_P2_SHIFT;
-+			p2[4] = (calib[3] & S4_P2_MASK) >> S4_P2_SHIFT;
-+			p2[5] = (calib[3] & S5_P2_MASK) >> S5_P2_SHIFT;
-+			p2[6] = (calib[3] & S6_P2_MASK) >> S6_P2_SHIFT;
-+			p2[7] = (calib[4] & S7_P2_MASK);
-+			p2[8] = (calib[4] & S8_P2_MASK) >> S8_P2_SHIFT;
-+			p2[9] = (calib[4] & S9_P2_MASK) >> S9_P2_SHIFT;
-+			p2[10] = (calib[4] & S10_P2_MASK) >> S10_P2_SHIFT;
-+			/* Fall through */
-+		case ONE_PT_CALIB:
-+		case ONE_PT_CALIB2:
-+			base1 = calib[0] & BASE1_MASK;
-+			p1[0] = (calib[0] & S0_P1_MASK) >> S0_P1_SHIFT;
-+			p1[1] = (calib[0] & S1_P1_MASK) >> S1_P1_SHIFT;
-+			p1[2] = (calib[0] & S2_P1_MASK) >> S2_P1_SHIFT;
-+			p1[3] = (calib[0] & S3_P1_MASK) >> S3_P1_SHIFT;
-+			p1[4] = (calib[1] & S4_P1_MASK);
-+			p1[5] = (calib[1] & S5_P1_MASK) >> S5_P1_SHIFT;
-+			p1[6] = (calib[1] & S6_P1_MASK) >> S6_P1_SHIFT;
-+			p1[7] = (calib[1] & S7_P1_MASK) >> S7_P1_SHIFT;
-+			p1[8] = (calib[1] & S8_P1_MASK) >> S8_P1_SHIFT;
-+			p1[9] = (calib[2] & S9_P1_MASK);
-+			p1[10] = (calib[2] & S10_P1_MASK) >> S10_P1_SHIFT;
-+			break;
-+		}
-+	}
-+
-+	switch (mode) {
-+	case ONE_PT_CALIB:
-+		for (i = 0; i < tmdev->num_sensors; i++)
-+			p1[i] += (base1 << 2) | BIT_APPEND;
-+		break;
-+	case TWO_PT_CALIB:
-+		for (i = 0; i < tmdev->num_sensors; i++) {
-+			p2[i] += base2;
-+			p2[i] <<= 2;
-+			p2[i] |= BIT_APPEND;
-+		}
-+		/* Fall through */
-+	case ONE_PT_CALIB2:
-+		for (i = 0; i < tmdev->num_sensors; i++) {
-+			p1[i] += base1;
-+			p1[i] <<= 2;
-+			p1[i] |= BIT_APPEND;
-+		}
-+		break;
-+	default:
-+		for (i = 0; i < tmdev->num_sensors; i++)
-+			p2[i] = 780;
-+		p1[0] = 502;
-+		p1[1] = 509;
-+		p1[2] = 503;
-+		p1[3] = 509;
-+		p1[4] = 505;
-+		p1[5] = 509;
-+		p1[6] = 507;
-+		p1[7] = 510;
-+		p1[8] = 508;
-+		p1[9] = 509;
-+		p1[10] = 508;
-+		break;
-+	}
-+
-+	compute_intercept_slope(tmdev, p1, p2, mode);
-+
-+	return 0;
-+}
-+
-+const struct tsens_ops ops_8974 = {
-+	.init		= init_common,
-+	.calibrate	= calibrate_8974,
-+	.get_temp	= get_temp_common,
-+};
-+
-+const struct tsens_data data_8974 = {
-+	.num_sensors	= 11,
-+	.ops		= &ops_8974,
-+};
---- a/drivers/thermal/qcom/tsens.c
-+++ b/drivers/thermal/qcom/tsens.c
-@@ -68,6 +68,7 @@ static const struct of_device_id tsens_t
- 		.data = &data_8916,
- 	}, {
- 		.compatible = "qcom,msm8974-tsens",
-+		.data = &data_8974,
- 	},
- 	{}
- };
---- a/drivers/thermal/qcom/tsens.h
-+++ b/drivers/thermal/qcom/tsens.h
-@@ -87,6 +87,6 @@ void compute_intercept_slope(struct tsen
- int init_common(struct tsens_device *);
- int get_temp_common(struct tsens_device *, int, int *);
- 
--extern const struct tsens_data data_8916;
-+extern const struct tsens_data data_8916, data_8974;
- 
- #endif /* __QCOM_TSENS_H__ */
diff --git a/target/linux/ipq806x/patches-4.4/015-4-thermal-qcom-tsens-8960-Add-support-for-8960-family-of-SoCs.patch b/target/linux/ipq806x/patches-4.4/015-4-thermal-qcom-tsens-8960-Add-support-for-8960-family-of-SoCs.patch
deleted file mode 100644
index 05490cd..0000000
--- a/target/linux/ipq806x/patches-4.4/015-4-thermal-qcom-tsens-8960-Add-support-for-8960-family-of-SoCs.patch
+++ /dev/null
@@ -1,364 +0,0 @@
-From 20d4fd84bf524ad91e2cc3e4ab4020c27cfc0081 Mon Sep 17 00:00:00 2001
-From: Rajendra Nayak <rnayak at codeaurora.org>
-Date: Thu, 5 May 2016 14:21:43 +0530
-Subject: thermal: qcom: tsens-8960: Add support for 8960 family of SoCs
-
-8960 family of SoCs have the TSENS device as part of GCC, hence
-the driver probes the virtual child device created by GCC and
-uses the parent to extract all DT properties and reuses the GCC
-regmap.
-
-Also GCC/TSENS are part of a  domain thats not always ON.
-Hence add .suspend and .resume hooks to save and restore some of
-the inited register context.
-
-Also 8960 family have some of the TSENS init sequence thats
-required to be done by the HLOS driver (some later versions of TSENS
-do not export these registers to non-secure world, and hence need
-these initializations to be done by secure bootloaders)
-
-8660 from the same family has just one sensor and hence some register
-offset/layout differences which need special handling in the driver.
-
-Based on the original code from Siddartha Mohanadoss, Stephen Boyd and
-Narendran Rajan.
-
-Signed-off-by: Rajendra Nayak <rnayak at codeaurora.org>
-Signed-off-by: Eduardo Valentin <edubezval at gmail.com>
-Signed-off-by: Zhang Rui <rui.zhang at intel.com>
----
- drivers/thermal/qcom/Makefile     |   2 +-
- drivers/thermal/qcom/tsens-8960.c | 292 ++++++++++++++++++++++++++++++++++++++
- drivers/thermal/qcom/tsens.c      |   8 +-
- drivers/thermal/qcom/tsens.h      |   2 +-
- 4 files changed, 298 insertions(+), 6 deletions(-)
- create mode 100644 drivers/thermal/qcom/tsens-8960.c
-
---- a/drivers/thermal/qcom/Makefile
-+++ b/drivers/thermal/qcom/Makefile
-@@ -1,2 +1,2 @@
- obj-$(CONFIG_QCOM_TSENS)	+= qcom_tsens.o
--qcom_tsens-y			+= tsens.o tsens-common.o tsens-8916.o tsens-8974.o
-+qcom_tsens-y			+= tsens.o tsens-common.o tsens-8916.o tsens-8974.o tsens-8960.o
---- /dev/null
-+++ b/drivers/thermal/qcom/tsens-8960.c
-@@ -0,0 +1,292 @@
-+/*
-+ * 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/platform_device.h>
-+#include <linux/delay.h>
-+#include <linux/bitops.h>
-+#include <linux/regmap.h>
-+#include <linux/thermal.h>
-+#include "tsens.h"
-+
-+#define CAL_MDEGC		30000
-+
-+#define CONFIG_ADDR		0x3640
-+#define CONFIG_ADDR_8660	0x3620
-+/* CONFIG_ADDR bitmasks */
-+#define CONFIG			0x9b
-+#define CONFIG_MASK		0xf
-+#define CONFIG_8660		1
-+#define CONFIG_SHIFT_8660	28
-+#define CONFIG_MASK_8660	(3 << CONFIG_SHIFT_8660)
-+
-+#define STATUS_CNTL_ADDR_8064	0x3660
-+#define CNTL_ADDR		0x3620
-+/* CNTL_ADDR bitmasks */
-+#define EN			BIT(0)
-+#define SW_RST			BIT(1)
-+#define SENSOR0_EN		BIT(3)
-+#define SLP_CLK_ENA		BIT(26)
-+#define SLP_CLK_ENA_8660	BIT(24)
-+#define MEASURE_PERIOD		1
-+#define SENSOR0_SHIFT		3
-+
-+/* INT_STATUS_ADDR bitmasks */
-+#define MIN_STATUS_MASK		BIT(0)
-+#define LOWER_STATUS_CLR	BIT(1)
-+#define UPPER_STATUS_CLR	BIT(2)
-+#define MAX_STATUS_MASK		BIT(3)
-+
-+#define THRESHOLD_ADDR		0x3624
-+/* THRESHOLD_ADDR bitmasks */
-+#define THRESHOLD_MAX_LIMIT_SHIFT	24
-+#define THRESHOLD_MIN_LIMIT_SHIFT	16
-+#define THRESHOLD_UPPER_LIMIT_SHIFT	8
-+#define THRESHOLD_LOWER_LIMIT_SHIFT	0
-+
-+/* Initial temperature threshold values */
-+#define LOWER_LIMIT_TH		0x50
-+#define UPPER_LIMIT_TH		0xdf
-+#define MIN_LIMIT_TH		0x0
-+#define MAX_LIMIT_TH		0xff
-+
-+#define S0_STATUS_ADDR		0x3628
-+#define INT_STATUS_ADDR		0x363c
-+#define TRDY_MASK		BIT(7)
-+#define TIMEOUT_US		100
-+
-+static int suspend_8960(struct tsens_device *tmdev)
-+{
-+	int ret;
-+	unsigned int mask;
-+	struct regmap *map = tmdev->map;
-+
-+	ret = regmap_read(map, THRESHOLD_ADDR, &tmdev->ctx.threshold);
-+	if (ret)
-+		return ret;
-+
-+	ret = regmap_read(map, CNTL_ADDR, &tmdev->ctx.control);
-+	if (ret)
-+		return ret;
-+
-+	if (tmdev->num_sensors > 1)
-+		mask = SLP_CLK_ENA | EN;
-+	else
-+		mask = SLP_CLK_ENA_8660 | EN;
-+
-+	ret = regmap_update_bits(map, CNTL_ADDR, mask, 0);
-+	if (ret)
-+		return ret;
-+
-+	return 0;
-+}
-+
-+static int resume_8960(struct tsens_device *tmdev)
-+{
-+	int ret;
-+	struct regmap *map = tmdev->map;
-+
-+	ret = regmap_update_bits(map, CNTL_ADDR, SW_RST, SW_RST);
-+	if (ret)
-+		return ret;
-+
-+	/*
-+	 * Separate CONFIG restore is not needed only for 8660 as
-+	 * config is part of CTRL Addr and its restored as such
-+	 */
-+	if (tmdev->num_sensors > 1) {
-+		ret = regmap_update_bits(map, CONFIG_ADDR, CONFIG_MASK, CONFIG);
-+		if (ret)
-+			return ret;
-+	}
-+
-+	ret = regmap_write(map, THRESHOLD_ADDR, tmdev->ctx.threshold);
-+	if (ret)
-+		return ret;
-+
-+	ret = regmap_write(map, CNTL_ADDR, tmdev->ctx.control);
-+	if (ret)
-+		return ret;
-+
-+	return 0;
-+}
-+
-+static int enable_8960(struct tsens_device *tmdev, int id)
-+{
-+	int ret;
-+	u32 reg, mask;
-+
-+	ret = regmap_read(tmdev->map, CNTL_ADDR, &reg);
-+	if (ret)
-+		return ret;
-+
-+	mask = BIT(id + SENSOR0_SHIFT);
-+	ret = regmap_write(tmdev->map, CNTL_ADDR, reg | SW_RST);
-+	if (ret)
-+		return ret;
-+
-+	if (tmdev->num_sensors > 1)
-+		reg |= mask | SLP_CLK_ENA | EN;
-+	else
-+		reg |= mask | SLP_CLK_ENA_8660 | EN;
-+
-+	ret = regmap_write(tmdev->map, CNTL_ADDR, reg);
-+	if (ret)
-+		return ret;
-+
-+	return 0;
-+}
-+
-+static void disable_8960(struct tsens_device *tmdev)
-+{
-+	int ret;
-+	u32 reg_cntl;
-+	u32 mask;
-+
-+	mask = GENMASK(tmdev->num_sensors - 1, 0);
-+	mask <<= SENSOR0_SHIFT;
-+	mask |= EN;
-+
-+	ret = regmap_read(tmdev->map, CNTL_ADDR, &reg_cntl);
-+	if (ret)
-+		return;
-+
-+	reg_cntl &= ~mask;
-+
-+	if (tmdev->num_sensors > 1)
-+		reg_cntl &= ~SLP_CLK_ENA;
-+	else
-+		reg_cntl &= ~SLP_CLK_ENA_8660;
-+
-+	regmap_write(tmdev->map, CNTL_ADDR, reg_cntl);
-+}
-+
-+static int init_8960(struct tsens_device *tmdev)
-+{
-+	int ret, i;
-+	u32 reg_cntl;
-+
-+	tmdev->map = dev_get_regmap(tmdev->dev, NULL);
-+	if (!tmdev->map)
-+		return -ENODEV;
-+
-+	/*
-+	 * The status registers for each sensor are discontiguous
-+	 * because some SoCs have 5 sensors while others have more
-+	 * but the control registers stay in the same place, i.e
-+	 * directly after the first 5 status registers.
-+	 */
-+	for (i = 0; i < tmdev->num_sensors; i++) {
-+		if (i >= 5)
-+			tmdev->sensor[i].status = S0_STATUS_ADDR + 40;
-+		tmdev->sensor[i].status += i * 4;
-+	}
-+
-+	reg_cntl = SW_RST;
-+	ret = regmap_update_bits(tmdev->map, CNTL_ADDR, SW_RST, reg_cntl);
-+	if (ret)
-+		return ret;
-+
-+	if (tmdev->num_sensors > 1) {
-+		reg_cntl |= SLP_CLK_ENA | (MEASURE_PERIOD << 18);
-+		reg_cntl &= ~SW_RST;
-+		ret = regmap_update_bits(tmdev->map, CONFIG_ADDR,
-+					 CONFIG_MASK, CONFIG);
-+	} else {
-+		reg_cntl |= SLP_CLK_ENA_8660 | (MEASURE_PERIOD << 16);
-+		reg_cntl &= ~CONFIG_MASK_8660;
-+		reg_cntl |= CONFIG_8660 << CONFIG_SHIFT_8660;
-+	}
-+
-+	reg_cntl |= GENMASK(tmdev->num_sensors - 1, 0) << SENSOR0_SHIFT;
-+	ret = regmap_write(tmdev->map, CNTL_ADDR, reg_cntl);
-+	if (ret)
-+		return ret;
-+
-+	reg_cntl |= EN;
-+	ret = regmap_write(tmdev->map, CNTL_ADDR, reg_cntl);
-+	if (ret)
-+		return ret;
-+
-+	return 0;
-+}
-+
-+static int calibrate_8960(struct tsens_device *tmdev)
-+{
-+	int i;
-+	char *data;
-+
-+	ssize_t num_read = tmdev->num_sensors;
-+	struct tsens_sensor *s = tmdev->sensor;
-+
-+	data = qfprom_read(tmdev->dev, "calib");
-+	if (IS_ERR(data))
-+		data = qfprom_read(tmdev->dev, "calib_backup");
-+	if (IS_ERR(data))
-+		return PTR_ERR(data);
-+
-+	for (i = 0; i < num_read; i++, s++)
-+		s->offset = data[i];
-+
-+	return 0;
-+}
-+
-+/* Temperature on y axis and ADC-code on x-axis */
-+static inline int code_to_mdegC(u32 adc_code, const struct tsens_sensor *s)
-+{
-+	int slope, offset;
-+
-+	slope = thermal_zone_get_slope(s->tzd);
-+	offset = CAL_MDEGC - slope * s->offset;
-+
-+	return adc_code * slope + offset;
-+}
-+
-+static int get_temp_8960(struct tsens_device *tmdev, int id, int *temp)
-+{
-+	int ret;
-+	u32 code, trdy;
-+	const struct tsens_sensor *s = &tmdev->sensor[id];
-+	unsigned long timeout;
-+
-+	timeout = jiffies + usecs_to_jiffies(TIMEOUT_US);
-+	do {
-+		ret = regmap_read(tmdev->map, INT_STATUS_ADDR, &trdy);
-+		if (ret)
-+			return ret;
-+		if (!(trdy & TRDY_MASK))
-+			continue;
-+		ret = regmap_read(tmdev->map, s->status, &code);
-+		if (ret)
-+			return ret;
-+		*temp = code_to_mdegC(code, s);
-+		return 0;
-+	} while (time_before(jiffies, timeout));
-+
-+	return -ETIMEDOUT;
-+}
-+
-+const struct tsens_ops ops_8960 = {
-+	.init		= init_8960,
-+	.calibrate	= calibrate_8960,
-+	.get_temp	= get_temp_8960,
-+	.enable		= enable_8960,
-+	.disable	= disable_8960,
-+	.suspend	= suspend_8960,
-+	.resume		= resume_8960,
-+};
-+
-+const struct tsens_data data_8960 = {
-+	.num_sensors	= 11,
-+	.ops		= &ops_8960,
-+};
---- a/drivers/thermal/qcom/tsens.c
-+++ b/drivers/thermal/qcom/tsens.c
-@@ -122,10 +122,10 @@ static int tsens_probe(struct platform_d
- 	np = dev->of_node;
- 
- 	id = of_match_node(tsens_table, np);
--	if (!id)
--		return -EINVAL;
--
--	data = id->data;
-+	if (id)
-+		data = id->data;
-+	else
-+		data = &data_8960;
- 
- 	if (data->num_sensors <= 0) {
- 		dev_err(dev, "invalid number of sensors\n");
---- a/drivers/thermal/qcom/tsens.h
-+++ b/drivers/thermal/qcom/tsens.h
-@@ -87,6 +87,6 @@ void compute_intercept_slope(struct tsen
- int init_common(struct tsens_device *);
- int get_temp_common(struct tsens_device *, int, int *);
- 
--extern const struct tsens_data data_8916, data_8974;
-+extern const struct tsens_data data_8916, data_8974, data_8960;
- 
- #endif /* __QCOM_TSENS_H__ */
diff --git a/target/linux/ipq806x/patches-4.4/015-8-qcom-tsens-8916-mark-PM-functions-__maybe_unused.patch b/target/linux/ipq806x/patches-4.4/015-8-qcom-tsens-8916-mark-PM-functions-__maybe_unused.patch
deleted file mode 100644
index 39d2173..0000000
--- a/target/linux/ipq806x/patches-4.4/015-8-qcom-tsens-8916-mark-PM-functions-__maybe_unused.patch
+++ /dev/null
@@ -1,46 +0,0 @@
-From 5b97469a55872a30a0d53a1279a8ae8b1c68b52c Mon Sep 17 00:00:00 2001
-From: Arnd Bergmann <arnd at arndb.de>
-Date: Mon, 4 Jul 2016 15:12:28 +0200
-Subject: thermal: qcom: tsens-8916: mark PM functions __maybe_unused
-
-The newly added tsens-8916 driver produces warnings when CONFIG_PM
-is disabled:
-
-drivers/thermal/qcom/tsens.c:53:12: error: 'tsens_resume' defined but not used [-Werror=unused-function]
- static int tsens_resume(struct device *dev)
-            ^~~~~~~~~~~~
-drivers/thermal/qcom/tsens.c:43:12: error: 'tsens_suspend' defined but not used [-Werror=unused-function]
- static int tsens_suspend(struct device *dev)
-            ^~~~~~~~~~~~~
-
-This marks both functions __maybe_unused to let the compiler
-know that they might be used in other configurations, without
-adding ugly #ifdef logic.
-
-Signed-off-by: Arnd Bergmann <arnd at arndb.de>
-Reviewed-by: Rajendra Nayak <rnayak at codeaurora.org>
-Signed-off-by: Zhang Rui <rui.zhang at intel.com>
----
- drivers/thermal/qcom/tsens.c | 4 ++--
- 1 file changed, 2 insertions(+), 2 deletions(-)
-
---- a/drivers/thermal/qcom/tsens.c
-+++ b/drivers/thermal/qcom/tsens.c
-@@ -40,7 +40,7 @@ static int tsens_get_trend(void *data, l
- 	return -ENOTSUPP;
- }
- 
--static int tsens_suspend(struct device *dev)
-+static int  __maybe_unused tsens_suspend(struct device *dev)
- {
- 	struct tsens_device *tmdev = dev_get_drvdata(dev);
- 
-@@ -50,7 +50,7 @@ static int tsens_suspend(struct device *
- 	return 0;
- }
- 
--static int tsens_resume(struct device *dev)
-+static int __maybe_unused tsens_resume(struct device *dev)
- {
- 	struct tsens_device *tmdev = dev_get_drvdata(dev);
- 
diff --git a/target/linux/ipq806x/patches-4.4/016-2-thermal-of-thermal-Add-devm-version-of.patch b/target/linux/ipq806x/patches-4.4/016-2-thermal-of-thermal-Add-devm-version-of.patch
deleted file mode 100644
index 1ca7326..0000000
--- a/target/linux/ipq806x/patches-4.4/016-2-thermal-of-thermal-Add-devm-version-of.patch
+++ /dev/null
@@ -1,143 +0,0 @@
-From e498b4984db82b4ba3ceea7dba813222a31e9c2e Mon Sep 17 00:00:00 2001
-From: Laxman Dewangan <ldewangan at nvidia.com>
-Date: Wed, 9 Mar 2016 18:40:06 +0530
-Subject: thermal: of-thermal: Add devm version of
- thermal_zone_of_sensor_register
-
-Add resource managed version of thermal_zone_of_sensor_register() and
-thermal_zone_of_sensor_unregister().
-
-This helps in reducing the code size in error path, remove of
-driver remove callbacks and making proper sequence for deallocations.
-
-Signed-off-by: Laxman Dewangan <ldewangan at nvidia.com>
-Signed-off-by: Eduardo Valentin <edubezval at gmail.com>
----
- drivers/thermal/of-thermal.c | 81 ++++++++++++++++++++++++++++++++++++++++++++
- include/linux/thermal.h      | 18 ++++++++++
- 2 files changed, 99 insertions(+)
-
---- a/drivers/thermal/of-thermal.c
-+++ b/drivers/thermal/of-thermal.c
-@@ -559,6 +559,87 @@ void thermal_zone_of_sensor_unregister(s
- }
- EXPORT_SYMBOL_GPL(thermal_zone_of_sensor_unregister);
- 
-+static void devm_thermal_zone_of_sensor_release(struct device *dev, void *res)
-+{
-+	thermal_zone_of_sensor_unregister(dev,
-+					  *(struct thermal_zone_device **)res);
-+}
-+
-+static int devm_thermal_zone_of_sensor_match(struct device *dev, void *res,
-+					     void *data)
-+{
-+	struct thermal_zone_device **r = res;
-+
-+	if (WARN_ON(!r || !*r))
-+		return 0;
-+
-+	return *r == data;
-+}
-+
-+/**
-+ * devm_thermal_zone_of_sensor_register - Resource managed version of
-+ *				thermal_zone_of_sensor_register()
-+ * @dev: a valid struct device pointer of a sensor device. Must contain
-+ *       a valid .of_node, for the sensor node.
-+ * @sensor_id: a sensor identifier, in case the sensor IP has more
-+ *	       than one sensors
-+ * @data: a private pointer (owned by the caller) that will be passed
-+ *	  back, when a temperature reading is needed.
-+ * @ops: struct thermal_zone_of_device_ops *. Must contain at least .get_temp.
-+ *
-+ * Refer thermal_zone_of_sensor_register() for more details.
-+ *
-+ * Return: On success returns a valid struct thermal_zone_device,
-+ * otherwise, it returns a corresponding ERR_PTR(). Caller must
-+ * check the return value with help of IS_ERR() helper.
-+ * Registered hermal_zone_device device will automatically be
-+ * released when device is unbounded.
-+ */
-+struct thermal_zone_device *devm_thermal_zone_of_sensor_register(
-+	struct device *dev, int sensor_id,
-+	void *data, const struct thermal_zone_of_device_ops *ops)
-+{
-+	struct thermal_zone_device **ptr, *tzd;
-+
-+	ptr = devres_alloc(devm_thermal_zone_of_sensor_release, sizeof(*ptr),
-+			   GFP_KERNEL);
-+	if (!ptr)
-+		return ERR_PTR(-ENOMEM);
-+
-+	tzd = thermal_zone_of_sensor_register(dev, sensor_id, data, ops);
-+	if (IS_ERR(tzd)) {
-+		devres_free(ptr);
-+		return tzd;
-+	}
-+
-+	*ptr = tzd;
-+	devres_add(dev, ptr);
-+
-+	return tzd;
-+}
-+EXPORT_SYMBOL_GPL(devm_thermal_zone_of_sensor_register);
-+
-+/**
-+ * devm_thermal_zone_of_sensor_unregister - Resource managed version of
-+ *				thermal_zone_of_sensor_unregister().
-+ * @dev: Device for which which resource was allocated.
-+ * @tzd: a pointer to struct thermal_zone_device where the sensor is registered.
-+ *
-+ * This function removes the sensor callbacks and private data from the
-+ * thermal zone device registered with devm_thermal_zone_of_sensor_register()
-+ * API. It will also silent the zone by remove the .get_temp() and .get_trend()
-+ * thermal zone device callbacks.
-+ * Normally this function will not need to be called and the resource
-+ * management code will ensure that the resource is freed.
-+ */
-+void devm_thermal_zone_of_sensor_unregister(struct device *dev,
-+					    struct thermal_zone_device *tzd)
-+{
-+	WARN_ON(devres_release(dev, devm_thermal_zone_of_sensor_release,
-+			       devm_thermal_zone_of_sensor_match, tzd));
-+}
-+EXPORT_SYMBOL_GPL(devm_thermal_zone_of_sensor_unregister);
-+
- /***   functions parsing device tree nodes   ***/
- 
- /**
---- a/include/linux/thermal.h
-+++ b/include/linux/thermal.h
-@@ -364,6 +364,11 @@ thermal_zone_of_sensor_register(struct d
- 				const struct thermal_zone_of_device_ops *ops);
- void thermal_zone_of_sensor_unregister(struct device *dev,
- 				       struct thermal_zone_device *tz);
-+struct thermal_zone_device *devm_thermal_zone_of_sensor_register(
-+		struct device *dev, int id, void *data,
-+		const struct thermal_zone_of_device_ops *ops);
-+void devm_thermal_zone_of_sensor_unregister(struct device *dev,
-+					    struct thermal_zone_device *tz);
- #else
- static inline struct thermal_zone_device *
- thermal_zone_of_sensor_register(struct device *dev, int id, void *data,
-@@ -378,6 +383,19 @@ void thermal_zone_of_sensor_unregister(s
- {
- }
- 
-+static inline struct thermal_zone_device *devm_thermal_zone_of_sensor_register(
-+		struct device *dev, int id, void *data,
-+		const struct thermal_zone_of_device_ops *ops)
-+{
-+	return ERR_PTR(-ENODEV);
-+}
-+
-+static inline
-+void devm_thermal_zone_of_sensor_unregister(struct device *dev,
-+					    struct thermal_zone_device *tz)
-+{
-+}
-+
- #endif
- 
- #if IS_ENABLED(CONFIG_THERMAL)
diff --git a/target/linux/ipq806x/patches-4.4/017-09-thermal-core-export-apis-to-get-slope-and-offset.patch b/target/linux/ipq806x/patches-4.4/017-09-thermal-core-export-apis-to-get-slope-and-offset.patch
deleted file mode 100644
index 3fbe5f5..0000000
--- a/target/linux/ipq806x/patches-4.4/017-09-thermal-core-export-apis-to-get-slope-and-offset.patch
+++ /dev/null
@@ -1,101 +0,0 @@
-From 4a7069a32c99a81950de035535b0a064dcceaeba Mon Sep 17 00:00:00 2001
-From: Rajendra Nayak <rnayak at codeaurora.org>
-Date: Thu, 5 May 2016 14:21:42 +0530
-Subject: [PATCH] thermal: core: export apis to get slope and offset
-
-Add apis for platform thermal drivers to query for slope and offset
-attributes, which might be needed for temperature calculations.
-
-Signed-off-by: Rajendra Nayak <rnayak at codeaurora.org>
-Signed-off-by: Eduardo Valentin <edubezval at gmail.com>
-Signed-off-by: Zhang Rui <rui.zhang at intel.com>
----
- Documentation/thermal/sysfs-api.txt | 12 ++++++++++++
- drivers/thermal/thermal_core.c      | 30 ++++++++++++++++++++++++++++++
- include/linux/thermal.h             |  8 ++++++++
- 3 files changed, 50 insertions(+)
-
---- a/Documentation/thermal/sysfs-api.txt
-+++ b/Documentation/thermal/sysfs-api.txt
-@@ -72,6 +72,18 @@ temperature) and throttle appropriate de
-     It deletes the corresponding entry form /sys/class/thermal folder and
-     unbind all the thermal cooling devices it uses.
- 
-+1.1.7 int thermal_zone_get_slope(struct thermal_zone_device *tz)
-+
-+	This interface is used to read the slope attribute value
-+	for the thermal zone device, which might be useful for platform
-+	drivers for temperature calculations.
-+
-+1.1.8 int thermal_zone_get_offset(struct thermal_zone_device *tz)
-+
-+	This interface is used to read the offset attribute value
-+	for the thermal zone device, which might be useful for platform
-+	drivers for temperature calculations.
-+
- 1.2 thermal cooling device interface
- 1.2.1 struct thermal_cooling_device *thermal_cooling_device_register(char *name,
- 		void *devdata, struct thermal_cooling_device_ops *)
---- a/drivers/thermal/thermal_core.c
-+++ b/drivers/thermal/thermal_core.c
-@@ -2061,6 +2061,36 @@ exit:
- }
- EXPORT_SYMBOL_GPL(thermal_zone_get_zone_by_name);
- 
-+/**
-+ * thermal_zone_get_slope - return the slope attribute of the thermal zone
-+ * @tz: thermal zone device with the slope attribute
-+ *
-+ * Return: If the thermal zone device has a slope attribute, return it, else
-+ * return 1.
-+ */
-+int thermal_zone_get_slope(struct thermal_zone_device *tz)
-+{
-+	if (tz && tz->tzp)
-+		return tz->tzp->slope;
-+	return 1;
-+}
-+EXPORT_SYMBOL_GPL(thermal_zone_get_slope);
-+
-+/**
-+ * thermal_zone_get_offset - return the offset attribute of the thermal zone
-+ * @tz: thermal zone device with the offset attribute
-+ *
-+ * Return: If the thermal zone device has a offset attribute, return it, else
-+ * return 0.
-+ */
-+int thermal_zone_get_offset(struct thermal_zone_device *tz)
-+{
-+	if (tz && tz->tzp)
-+		return tz->tzp->offset;
-+	return 0;
-+}
-+EXPORT_SYMBOL_GPL(thermal_zone_get_offset);
-+
- #ifdef CONFIG_NET
- static const struct genl_multicast_group thermal_event_mcgrps[] = {
- 	{ .name = THERMAL_GENL_MCAST_GROUP_NAME, },
---- a/include/linux/thermal.h
-+++ b/include/linux/thermal.h
-@@ -432,6 +432,8 @@ thermal_of_cooling_device_register(struc
- void thermal_cooling_device_unregister(struct thermal_cooling_device *);
- struct thermal_zone_device *thermal_zone_get_zone_by_name(const char *name);
- int thermal_zone_get_temp(struct thermal_zone_device *tz, int *temp);
-+int thermal_zone_get_slope(struct thermal_zone_device *tz);
-+int thermal_zone_get_offset(struct thermal_zone_device *tz);
- 
- int get_tz_trend(struct thermal_zone_device *, int);
- struct thermal_instance *get_thermal_instance(struct thermal_zone_device *,
-@@ -489,6 +491,12 @@ static inline struct thermal_zone_device
- static inline int thermal_zone_get_temp(
- 		struct thermal_zone_device *tz, int *temp)
- { return -ENODEV; }
-+static inline int thermal_zone_get_slope(
-+		struct thermal_zone_device *tz)
-+{ return -ENODEV; }
-+static inline int thermal_zone_get_offset(
-+		struct thermal_zone_device *tz)
-+{ return -ENODEV; }
- static inline int get_tz_trend(struct thermal_zone_device *tz, int trip)
- { return -ENODEV; }
- static inline struct thermal_instance *
diff --git a/target/linux/ipq806x/patches-4.4/019-1-nvmem-core-return-error-for-non-word-aligned-access.patch b/target/linux/ipq806x/patches-4.4/019-1-nvmem-core-return-error-for-non-word-aligned-access.patch
deleted file mode 100644
index 13415f5..0000000
--- a/target/linux/ipq806x/patches-4.4/019-1-nvmem-core-return-error-for-non-word-aligned-access.patch
+++ /dev/null
@@ -1,42 +0,0 @@
-From 313a72ff983cc2e00ac4dcb791d40ebf2f9d5718 Mon Sep 17 00:00:00 2001
-From: Srinivas Kandagatla <srinivas.kandagatla at linaro.org>
-Date: Tue, 17 Nov 2015 09:12:41 +0000
-Subject: nvmem: core: return error for non word aligned access
-
-nvmem providers have restrictions on register strides, so return error
-when users attempt to read/write buffers with sizes which are less
-than word size.
-
-Without this patch the userspace would continue to try as it does not
-get any error from the nvmem core, resulting in a hang or endless loop
-in userspace.
-
-Reported-by: Ariel D'Alessandro <ariel at vanguardiasur.com.ar>
-Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla at linaro.org>
-Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
----
- drivers/nvmem/core.c | 6 ++++++
- 1 file changed, 6 insertions(+)
-
---- a/drivers/nvmem/core.c
-+++ b/drivers/nvmem/core.c
-@@ -70,6 +70,9 @@ static ssize_t bin_attr_nvmem_read(struc
- 	if (pos >= nvmem->size)
- 		return 0;
- 
-+	if (count < nvmem->word_size)
-+		return -EINVAL;
-+
- 	if (pos + count > nvmem->size)
- 		count = nvmem->size - pos;
- 
-@@ -95,6 +98,9 @@ static ssize_t bin_attr_nvmem_write(stru
- 	if (pos >= nvmem->size)
- 		return 0;
- 
-+	if (count < nvmem->word_size)
-+		return -EINVAL;
-+
- 	if (pos + count > nvmem->size)
- 		count = nvmem->size - pos;
- 
diff --git a/target/linux/ipq806x/patches-4.4/019-2-nvmem-core-fix-error-path-in-nvmem_add_cells.patch b/target/linux/ipq806x/patches-4.4/019-2-nvmem-core-fix-error-path-in-nvmem_add_cells.patch
deleted file mode 100644
index 1f9473b..0000000
--- a/target/linux/ipq806x/patches-4.4/019-2-nvmem-core-fix-error-path-in-nvmem_add_cells.patch
+++ /dev/null
@@ -1,34 +0,0 @@
-From dfdf141429f0895b63c882facc42c86f225033cb Mon Sep 17 00:00:00 2001
-From: Rasmus Villemoes <linux at rasmusvillemoes.dk>
-Date: Mon, 8 Feb 2016 22:04:29 +0100
-Subject: nvmem: core: fix error path in nvmem_add_cells()
-
-The current code fails to nvmem_cell_drop(cells[0]) - even worse, if
-the loop above fails already at i==0, we'll enter an essentially
-infinite loop doing nvmem_cell_drop on cells[-1], cells[-2], ... which
-is unlikely to end well.
-
-Also, we're not freeing the temporary backing array cells on the error
-path.
-
-Signed-off-by: Rasmus Villemoes <linux at rasmusvillemoes.dk>
-Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
----
- drivers/nvmem/core.c | 4 +++-
- 1 file changed, 3 insertions(+), 1 deletion(-)
-
---- a/drivers/nvmem/core.c
-+++ b/drivers/nvmem/core.c
-@@ -294,9 +294,11 @@ static int nvmem_add_cells(struct nvmem_
- 
- 	return 0;
- err:
--	while (--i)
-+	while (i--)
- 		nvmem_cell_drop(cells[i]);
- 
-+	kfree(cells);
-+
- 	return rval;
- }
- 
diff --git a/target/linux/ipq806x/patches-4.4/019-3-nvmem-Add-flag-to-export-NVMEM-to-root-only.patch b/target/linux/ipq806x/patches-4.4/019-3-nvmem-Add-flag-to-export-NVMEM-to-root-only.patch
deleted file mode 100644
index 77136ea..0000000
--- a/target/linux/ipq806x/patches-4.4/019-3-nvmem-Add-flag-to-export-NVMEM-to-root-only.patch
+++ /dev/null
@@ -1,101 +0,0 @@
-From 811b0d6538b9f26f3eb0f90fe4e6118f2480ec6f Mon Sep 17 00:00:00 2001
-From: Andrew Lunn <andrew at lunn.ch>
-Date: Fri, 26 Feb 2016 20:59:18 +0100
-Subject: nvmem: Add flag to export NVMEM to root only
-
-Legacy AT24, AT25 EEPROMs are exported in sys so that only root can
-read the contents. The EEPROMs may contain sensitive information. Add
-a flag so the provide can indicate that NVMEM should also restrict
-access to root only.
-
-Signed-off-by: Andrew Lunn <andrew at lunn.ch>
-Acked-by: Srinivas Kandagatla <srinivas.kandagatla at linaro.org>
-Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
----
- drivers/nvmem/core.c           | 57 ++++++++++++++++++++++++++++++++++++++++--
- include/linux/nvmem-provider.h |  1 +
- 2 files changed, 56 insertions(+), 2 deletions(-)
-
---- a/drivers/nvmem/core.c
-+++ b/drivers/nvmem/core.c
-@@ -161,6 +161,53 @@ static const struct attribute_group *nvm
- 	NULL,
- };
- 
-+/* default read/write permissions, root only */
-+static struct bin_attribute bin_attr_rw_root_nvmem = {
-+	.attr	= {
-+		.name	= "nvmem",
-+		.mode	= S_IWUSR | S_IRUSR,
-+	},
-+	.read	= bin_attr_nvmem_read,
-+	.write	= bin_attr_nvmem_write,
-+};
-+
-+static struct bin_attribute *nvmem_bin_rw_root_attributes[] = {
-+	&bin_attr_rw_root_nvmem,
-+	NULL,
-+};
-+
-+static const struct attribute_group nvmem_bin_rw_root_group = {
-+	.bin_attrs	= nvmem_bin_rw_root_attributes,
-+};
-+
-+static const struct attribute_group *nvmem_rw_root_dev_groups[] = {
-+	&nvmem_bin_rw_root_group,
-+	NULL,
-+};
-+
-+/* read only permission, root only */
-+static struct bin_attribute bin_attr_ro_root_nvmem = {
-+	.attr	= {
-+		.name	= "nvmem",
-+		.mode	= S_IRUSR,
-+	},
-+	.read	= bin_attr_nvmem_read,
-+};
-+
-+static struct bin_attribute *nvmem_bin_ro_root_attributes[] = {
-+	&bin_attr_ro_root_nvmem,
-+	NULL,
-+};
-+
-+static const struct attribute_group nvmem_bin_ro_root_group = {
-+	.bin_attrs	= nvmem_bin_ro_root_attributes,
-+};
-+
-+static const struct attribute_group *nvmem_ro_root_dev_groups[] = {
-+	&nvmem_bin_ro_root_group,
-+	NULL,
-+};
-+
- static void nvmem_release(struct device *dev)
- {
- 	struct nvmem_device *nvmem = to_nvmem_device(dev);
-@@ -355,8 +402,14 @@ struct nvmem_device *nvmem_register(cons
- 	nvmem->read_only = of_property_read_bool(np, "read-only") |
- 			   config->read_only;
- 
--	nvmem->dev.groups = nvmem->read_only ? nvmem_ro_dev_groups :
--					       nvmem_rw_dev_groups;
-+	if (config->root_only)
-+		nvmem->dev.groups = nvmem->read_only ?
-+			nvmem_ro_root_dev_groups :
-+			nvmem_rw_root_dev_groups;
-+	else
-+		nvmem->dev.groups = nvmem->read_only ?
-+			nvmem_ro_dev_groups :
-+			nvmem_rw_dev_groups;
- 
- 	device_initialize(&nvmem->dev);
- 
---- a/include/linux/nvmem-provider.h
-+++ b/include/linux/nvmem-provider.h
-@@ -23,6 +23,7 @@ struct nvmem_config {
- 	const struct nvmem_cell_info	*cells;
- 	int			ncells;
- 	bool			read_only;
-+	bool			root_only;
- };
- 
- #if IS_ENABLED(CONFIG_NVMEM)
diff --git a/target/linux/ipq806x/patches-4.4/019-4-nvmem-Add-backwards-compatibility-support-for-older-EEPROM-drivers.patch b/target/linux/ipq806x/patches-4.4/019-4-nvmem-Add-backwards-compatibility-support-for-older-EEPROM-drivers.patch
deleted file mode 100644
index 6344d0e..0000000
--- a/target/linux/ipq806x/patches-4.4/019-4-nvmem-Add-backwards-compatibility-support-for-older-EEPROM-drivers.patch
+++ /dev/null
@@ -1,181 +0,0 @@
-From b6c217ab9be6895384cf0b284ace84ad79e5c53b Mon Sep 17 00:00:00 2001
-From: Andrew Lunn <andrew at lunn.ch>
-Date: Fri, 26 Feb 2016 20:59:19 +0100
-Subject: nvmem: Add backwards compatibility support for older EEPROM drivers.
-
-Older drivers made an 'eeprom' file available in the /sys device
-directory. Have the NVMEM core provide this to retain backwards
-compatibility.
-
-Signed-off-by: Andrew Lunn <andrew at lunn.ch>
-Acked-by: Srinivas Kandagatla <srinivas.kandagatla at linaro.org>
-Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
----
- drivers/nvmem/core.c           | 84 ++++++++++++++++++++++++++++++++++++++----
- include/linux/nvmem-provider.h |  4 +-
- 2 files changed, 79 insertions(+), 9 deletions(-)
-
---- a/drivers/nvmem/core.c
-+++ b/drivers/nvmem/core.c
-@@ -38,8 +38,13 @@ struct nvmem_device {
- 	int			users;
- 	size_t			size;
- 	bool			read_only;
-+	int			flags;
-+	struct bin_attribute	eeprom;
-+	struct device		*base_dev;
- };
- 
-+#define FLAG_COMPAT		BIT(0)
-+
- struct nvmem_cell {
- 	const char		*name;
- 	int			offset;
-@@ -56,16 +61,26 @@ static DEFINE_IDA(nvmem_ida);
- static LIST_HEAD(nvmem_cells);
- static DEFINE_MUTEX(nvmem_cells_mutex);
- 
-+#ifdef CONFIG_DEBUG_LOCK_ALLOC
-+static struct lock_class_key eeprom_lock_key;
-+#endif
-+
- #define to_nvmem_device(d) container_of(d, struct nvmem_device, dev)
- 
- static ssize_t bin_attr_nvmem_read(struct file *filp, struct kobject *kobj,
- 				    struct bin_attribute *attr,
- 				    char *buf, loff_t pos, size_t count)
- {
--	struct device *dev = container_of(kobj, struct device, kobj);
--	struct nvmem_device *nvmem = to_nvmem_device(dev);
-+	struct device *dev;
-+	struct nvmem_device *nvmem;
- 	int rc;
- 
-+	if (attr->private)
-+		dev = attr->private;
-+	else
-+		dev = container_of(kobj, struct device, kobj);
-+	nvmem = to_nvmem_device(dev);
-+
- 	/* Stop the user from reading */
- 	if (pos >= nvmem->size)
- 		return 0;
-@@ -90,10 +105,16 @@ static ssize_t bin_attr_nvmem_write(stru
- 				     struct bin_attribute *attr,
- 				     char *buf, loff_t pos, size_t count)
- {
--	struct device *dev = container_of(kobj, struct device, kobj);
--	struct nvmem_device *nvmem = to_nvmem_device(dev);
-+	struct device *dev;
-+	struct nvmem_device *nvmem;
- 	int rc;
- 
-+	if (attr->private)
-+		dev = attr->private;
-+	else
-+		dev = container_of(kobj, struct device, kobj);
-+	nvmem = to_nvmem_device(dev);
-+
- 	/* Stop the user from writing */
- 	if (pos >= nvmem->size)
- 		return 0;
-@@ -349,6 +370,43 @@ err:
- 	return rval;
- }
- 
-+/*
-+ * nvmem_setup_compat() - Create an additional binary entry in
-+ * drivers sys directory, to be backwards compatible with the older
-+ * drivers/misc/eeprom drivers.
-+ */
-+static int nvmem_setup_compat(struct nvmem_device *nvmem,
-+			      const struct nvmem_config *config)
-+{
-+	int rval;
-+
-+	if (!config->base_dev)
-+		return -EINVAL;
-+
-+	if (nvmem->read_only)
-+		nvmem->eeprom = bin_attr_ro_root_nvmem;
-+	else
-+		nvmem->eeprom = bin_attr_rw_root_nvmem;
-+	nvmem->eeprom.attr.name = "eeprom";
-+	nvmem->eeprom.size = nvmem->size;
-+#ifdef CONFIG_DEBUG_LOCK_ALLOC
-+	nvmem->eeprom.attr.key = &eeprom_lock_key;
-+#endif
-+	nvmem->eeprom.private = &nvmem->dev;
-+	nvmem->base_dev = config->base_dev;
-+
-+	rval = device_create_bin_file(nvmem->base_dev, &nvmem->eeprom);
-+	if (rval) {
-+		dev_err(&nvmem->dev,
-+			"Failed to create eeprom binary file %d\n", rval);
-+		return rval;
-+	}
-+
-+	nvmem->flags |= FLAG_COMPAT;
-+
-+	return 0;
-+}
-+
- /**
-  * nvmem_register() - Register a nvmem device for given nvmem_config.
-  * Also creates an binary entry in /sys/bus/nvmem/devices/dev-name/nvmem
-@@ -416,16 +474,23 @@ struct nvmem_device *nvmem_register(cons
- 	dev_dbg(&nvmem->dev, "Registering nvmem device %s\n", config->name);
- 
- 	rval = device_add(&nvmem->dev);
--	if (rval) {
--		ida_simple_remove(&nvmem_ida, nvmem->id);
--		kfree(nvmem);
--		return ERR_PTR(rval);
-+	if (rval)
-+		goto out;
-+
-+	if (config->compat) {
-+		rval = nvmem_setup_compat(nvmem, config);
-+		if (rval)
-+			goto out;
- 	}
- 
- 	if (config->cells)
- 		nvmem_add_cells(nvmem, config);
- 
- 	return nvmem;
-+out:
-+	ida_simple_remove(&nvmem_ida, nvmem->id);
-+	kfree(nvmem);
-+	return ERR_PTR(rval);
- }
- EXPORT_SYMBOL_GPL(nvmem_register);
- 
-@@ -445,6 +510,9 @@ int nvmem_unregister(struct nvmem_device
- 	}
- 	mutex_unlock(&nvmem_mutex);
- 
-+	if (nvmem->flags & FLAG_COMPAT)
-+		device_remove_bin_file(nvmem->base_dev, &nvmem->eeprom);
-+
- 	nvmem_device_remove_all_cells(nvmem);
- 	device_del(&nvmem->dev);
- 
---- a/include/linux/nvmem-provider.h
-+++ b/include/linux/nvmem-provider.h
-@@ -24,6 +24,9 @@ struct nvmem_config {
- 	int			ncells;
- 	bool			read_only;
- 	bool			root_only;
-+	/* To be only used by old driver/misc/eeprom drivers */
-+	bool			compat;
-+	struct device		*base_dev;
- };
- 
- #if IS_ENABLED(CONFIG_NVMEM)
-@@ -44,5 +47,4 @@ static inline int nvmem_unregister(struc
- }
- 
- #endif /* CONFIG_NVMEM */
--
- #endif  /* ifndef _LINUX_NVMEM_PROVIDER_H */
diff --git a/target/linux/ipq806x/patches-4.4/020-add-ap148-bootargs.patch b/target/linux/ipq806x/patches-4.4/020-add-ap148-bootargs.patch
deleted file mode 100644
index 9c33bad..0000000
--- a/target/linux/ipq806x/patches-4.4/020-add-ap148-bootargs.patch
+++ /dev/null
@@ -1,61 +0,0 @@
---- a/arch/arm/boot/dts/qcom-ipq8064-ap148.dts
-+++ b/arch/arm/boot/dts/qcom-ipq8064-ap148.dts
-@@ -4,14 +4,6 @@
- 	model = "Qualcomm IPQ8064/AP148";
- 	compatible = "qcom,ipq8064-ap148", "qcom,ipq8064";
- 
--	aliases {
--		serial0 = &gsbi4_serial;
--	};
--
--	chosen {
--		stdout-path = "serial0:115200n8";
--	};
--
- 	reserved-memory {
- 		#address-cells = <1>;
- 		#size-cells = <1>;
-@@ -22,6 +14,14 @@
- 		};
- 	};
- 
-+	alias {
-+		serial0 = &uart4;
-+	};
-+
-+	chosen {
-+		linux,stdout-path = "serial0:115200n8";
-+	};
-+
- 	soc {
- 		pinmux at 800000 {
- 			i2c4_pins: i2c4_pinmux {
---- a/arch/arm/boot/dts/qcom-ipq8064.dtsi
-+++ b/arch/arm/boot/dts/qcom-ipq8064.dtsi
-@@ -159,7 +159,7 @@
- 
- 			syscon-tcsr = <&tcsr>;
- 
--			serial at 12490000 {
-+			uart2: serial at 12490000 {
- 				compatible = "qcom,msm-uartdm-v1.3", "qcom,msm-uartdm";
- 				reg = <0x12490000 0x1000>,
- 				      <0x12480000 0x1000>;
-@@ -197,7 +197,7 @@
- 
- 			syscon-tcsr = <&tcsr>;
- 
--			gsbi4_serial: serial at 16340000 {
-+			uart4: serial at 16340000 {
- 				compatible = "qcom,msm-uartdm-v1.3", "qcom,msm-uartdm";
- 				reg = <0x16340000 0x1000>,
- 				      <0x16300000 0x1000>;
-@@ -234,7 +234,7 @@
- 
- 			syscon-tcsr = <&tcsr>;
- 
--			serial at 1a240000 {
-+			uart5: serial at 1a240000 {
- 				compatible = "qcom,msm-uartdm-v1.3", "qcom,msm-uartdm";
- 				reg = <0x1a240000 0x1000>,
- 				      <0x1a200000 0x1000>;
diff --git a/target/linux/ipq806x/patches-4.4/021-add-ap148-partitions.patch b/target/linux/ipq806x/patches-4.4/021-add-ap148-partitions.patch
deleted file mode 100644
index bfdb30f..0000000
--- a/target/linux/ipq806x/patches-4.4/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 at 0 {
--						label = "rootfs";
--						reg = <0x0 0x1000000>;
--					};
--
--					partition at 1 {
--						label = "scratch";
--						reg = <0x1000000 0x1000000>;
--					};
-+					linux,part-probe = "qcom-smem";
- 				};
- 			};
- 		};
diff --git a/target/linux/ipq806x/patches-4.4/022-add-db149-dts.patch b/target/linux/ipq806x/patches-4.4/022-add-db149-dts.patch
deleted file mode 100644
index 0845d3f..0000000
--- a/target/linux/ipq806x/patches-4.4/022-add-db149-dts.patch
+++ /dev/null
@@ -1,160 +0,0 @@
-From f26cc3733bdd697bd81ae505fc133fa7c9b6ea19 Mon Sep 17 00:00:00 2001
-From: Mathieu Olivari <mathieu at 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 at codeaurora.org>
----
- arch/arm/boot/dts/Makefile               |   1 +
- arch/arm/boot/dts/qcom-ipq8064-db149.dts | 132 +++++++++++++++++++++++++++++++
- 2 files changed, 133 insertions(+)
- create mode 100644 arch/arm/boot/dts/qcom-ipq8064-db149.dts
-
---- a/arch/arm/boot/dts/Makefile
-+++ b/arch/arm/boot/dts/Makefile
-@@ -506,6 +506,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 at 41200000 {
-+			reg = <0x41200000 0x300000>;
-+			no-map;
-+		};
-+	};
-+
-+	alias {
-+		serial0 = &uart2;
-+	};
-+
-+	chosen {
-+		linux,stdout-path = "serial0:115200n8";
-+	};
-+
-+	soc {
-+		pinmux at 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 at 12480000 {
-+			qcom,mode = <GSBI_PROT_I2C_UART>;
-+			status = "ok";
-+			uart2: serial at 12490000 {
-+				status = "ok";
-+			};
-+		};
-+
-+		gsbi5: gsbi at 1a200000 {
-+			qcom,mode = <GSBI_PROT_SPI>;
-+			status = "ok";
-+
-+			spi4: spi at 1a280000 {
-+				status = "ok";
-+				spi-max-frequency = <50000000>;
-+
-+				pinctrl-0 = <&spi_pins>;
-+				pinctrl-names = "default";
-+
-+				cs-gpios = <&qcom_pinmux 20 0>;
-+
-+				flash: m25p80 at 0 {
-+					compatible = "s25fl256s1";
-+					#address-cells = <1>;
-+					#size-cells = <1>;
-+					spi-max-frequency = <50000000>;
-+					reg = <0>;
-+					m25p,fast-read;
-+
-+					partition at 0 {
-+						label = "lowlevel_init";
-+						reg = <0x0 0x1b0000>;
-+					};
-+
-+					partition at 1 {
-+						label = "u-boot";
-+						reg = <0x1b0000 0x80000>;
-+					};
-+
-+					partition at 2 {
-+						label = "u-boot-env";
-+						reg = <0x230000 0x40000>;
-+					};
-+
-+					partition at 3 {
-+						label = "caldata";
-+						reg = <0x270000 0x40000>;
-+					};
-+
-+					partition at 4 {
-+						label = "firmware";
-+						reg = <0x2b0000 0x1d50000>;
-+					};
-+				};
-+			};
-+		};
-+
-+		sata-phy at 1b400000 {
-+			status = "ok";
-+		};
-+
-+		sata at 29000000 {
-+			status = "ok";
-+		};
-+
-+		phy at 100f8800 {		/* USB3 port 1 HS phy */
-+			status = "ok";
-+		};
-+
-+		phy at 100f8830 {		/* USB3 port 1 SS phy */
-+			status = "ok";
-+		};
-+
-+		phy at 110f8800 {		/* USB3 port 0 HS phy */
-+			status = "ok";
-+		};
-+
-+		phy at 110f8830 {		/* USB3 port 0 SS phy */
-+			status = "ok";
-+		};
-+
-+		usb30 at 0 {
-+			status = "ok";
-+		};
-+
-+		usb30 at 1 {
-+			status = "ok";
-+		};
-+	};
-+};
diff --git a/target/linux/ipq806x/patches-4.4/023-ARM-dts-ipq806x-Disable-i2c-device-on-gsbi4.patch b/target/linux/ipq806x/patches-4.4/023-ARM-dts-ipq806x-Disable-i2c-device-on-gsbi4.patch
deleted file mode 100644
index 705306d..0000000
--- a/target/linux/ipq806x/patches-4.4/023-ARM-dts-ipq806x-Disable-i2c-device-on-gsbi4.patch
+++ /dev/null
@@ -1,52 +0,0 @@
---- a/arch/arm/boot/dts/qcom-ipq8064-ap148.dts
-+++ b/arch/arm/boot/dts/qcom-ipq8064-ap148.dts
-@@ -47,14 +47,12 @@
- 				status = "ok";
- 			};
- 
--			i2c4: i2c at 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 at 1a200000 {
---- a/drivers/clk/qcom/gcc-ipq806x.c
-+++ b/drivers/clk/qcom/gcc-ipq806x.c
-@@ -294,7 +294,7 @@ static struct clk_rcg gsbi1_uart_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,
- 		},
- 	},
- };
-@@ -312,7 +312,7 @@ static struct clk_branch gsbi1_uart_clk
- 			},
- 			.num_parents = 1,
- 			.ops = &clk_branch_ops,
--			.flags = CLK_SET_RATE_PARENT,
-+			.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
- 		},
- 	},
- };
-@@ -890,7 +890,7 @@ static struct clk_branch gsbi1_h_clk = {
- 		.hw.init = &(struct clk_init_data){
- 			.name = "gsbi1_h_clk",
- 			.ops = &clk_branch_ops,
--			.flags = CLK_IS_ROOT,
-+			.flags = CLK_IS_ROOT | CLK_IGNORE_UNUSED,
- 		},
- 	},
- };
diff --git a/target/linux/ipq806x/patches-4.4/024-ap148-add-memory-node.patch b/target/linux/ipq806x/patches-4.4/024-ap148-add-memory-node.patch
deleted file mode 100644
index f026ed9..0000000
--- a/target/linux/ipq806x/patches-4.4/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 at 0 {
-+		reg = <0x42000000 0x1e000000>;
-+		device_type = "memory";
-+	};
-+
- 	reserved-memory {
- 		#address-cells = <1>;
- 		#size-cells = <1>;
diff --git a/target/linux/ipq806x/patches-4.4/030-ARM-qcom-select-ARM_CPU_SUSPEND-for-power-management.patch b/target/linux/ipq806x/patches-4.4/030-ARM-qcom-select-ARM_CPU_SUSPEND-for-power-management.patch
deleted file mode 100644
index cb2d303..0000000
--- a/target/linux/ipq806x/patches-4.4/030-ARM-qcom-select-ARM_CPU_SUSPEND-for-power-management.patch
+++ /dev/null
@@ -1,30 +0,0 @@
-From: Arnd Bergmann <arnd at arndb.de>
-Date: Tue, 24 Nov 2015 23:13:09 +0100
-Subject: [PATCH] ARM: qcom: select ARM_CPU_SUSPEND for power management
-
-The qcom spm driver uses cpu_resume_arm(), which is not included
-in the kernel in all configurations:
-
-drivers/built-in.o: In function `qcom_cpu_spc':
-:(.text+0xbc022): undefined reference to `cpu_suspend'
-drivers/built-in.o: In function `qcom_cpuidle_init':
-:(.init.text+0x610c): undefined reference to `cpu_resume_arm'
-
-This adds a 'select' Kconfig statement to ensure it's always
-enabled.
-
-Signed-off-by: Arnd Bergmann <arnd at arndb.de>
-Reviewed-by: Stephen Boyd <sboyd at codeaurora.org>
-Signed-off-by: Andy Gross <agross at codeaurora.org>
----
-
---- a/drivers/soc/qcom/Kconfig
-+++ b/drivers/soc/qcom/Kconfig
-@@ -13,6 +13,7 @@ config QCOM_GSBI
- config QCOM_PM
- 	bool "Qualcomm Power Management"
- 	depends on ARCH_QCOM && !ARM64
-+	select ARM_CPU_SUSPEND
- 	select QCOM_SCM
- 	help
- 	  QCOM Platform specific power driver to manage cores and L2 low power
diff --git a/target/linux/ipq806x/patches-4.4/033-ARM-qcom-add-SFPB-nodes-to-IPQ806x-dts.patch b/target/linux/ipq806x/patches-4.4/033-ARM-qcom-add-SFPB-nodes-to-IPQ806x-dts.patch
deleted file mode 100644
index e1d317d..0000000
--- a/target/linux/ipq806x/patches-4.4/033-ARM-qcom-add-SFPB-nodes-to-IPQ806x-dts.patch
+++ /dev/null
@@ -1,33 +0,0 @@
-From c7c482da19a5e4ba7101198c21c2434056b0b2da Mon Sep 17 00:00:00 2001
-From: Mathieu Olivari <mathieu at 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 at 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
-@@ -329,5 +329,16 @@
- 			#reset-cells = <1>;
- 		};
- 
-+		sfpb_mutex_block: syscon at 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-4.4/036-ARM-qcom-add-SMEM-device-node-to-IPQ806x-dts.patch b/target/linux/ipq806x/patches-4.4/036-ARM-qcom-add-SMEM-device-node-to-IPQ806x-dts.patch
deleted file mode 100644
index 06b1405..0000000
--- a/target/linux/ipq806x/patches-4.4/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 at 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 at 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
-@@ -55,7 +55,7 @@
- 			no-map;
- 		};
- 
--		smem at 41000000 {
-+		smem: smem at 41000000 {
- 			reg = <0x41000000 0x200000>;
- 			no-map;
- 		};
-@@ -341,4 +341,10 @@
- 
- 		#hwlock-cells = <1>;
- 	};
-+
-+	smem {
-+		compatible = "qcom,smem";
-+		memory-region = <&smem>;
-+		hwlocks = <&sfpb_mutex 3>;
-+	};
- };
diff --git a/target/linux/ipq806x/patches-4.4/037-mtd-add-SMEM-parser-for-QCOM-platforms.patch b/target/linux/ipq806x/patches-4.4/037-mtd-add-SMEM-parser-for-QCOM-platforms.patch
deleted file mode 100644
index 7c0c803..0000000
--- a/target/linux/ipq806x/patches-4.4/037-mtd-add-SMEM-parser-for-QCOM-platforms.patch
+++ /dev/null
@@ -1,275 +0,0 @@
-From 61e8e1b1af77f24339da3f0822a76fa65ed635c6 Mon Sep 17 00:00:00 2001
-From: Mathieu Olivari <mathieu at codeaurora.org>
-Date: Thu, 13 Aug 2015 09:53:14 -0700
-Subject: [PATCH] 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 at codeaurora.org>
-Signed-off-by: Ram Chandra Jangir <rjangi at codeaurora.org>
----
- drivers/mtd/Kconfig          |   7 ++
- drivers/mtd/Makefile         |   1 +
- drivers/mtd/qcom_smem_part.c | 228 +++++++++++++++++++++++++++++++++++++++++++
- 3 files changed, 236 insertions(+)
- create mode 100644 drivers/mtd/qcom_smem_part.c
-
---- a/drivers/mtd/Kconfig
-+++ b/drivers/mtd/Kconfig
-@@ -190,6 +190,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"
- 
- #
---- 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
---- /dev/null
-+++ b/drivers/mtd/qcom_smem_part.c
-@@ -0,0 +1,228 @@
-+/*
-+ * 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)
-+{
-+	size_t size;
-+
-+	*smem_blksz = qcom_smem_get(SMEM_HOST_APPS, SMEM_BOOT_FLASH_BLOCK_SIZE,
-+			    	    &size);
-+
-+	if (IS_ERR(*smem_blksz)) {
-+		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)
-+{
-+	size_t size;
-+
-+	*smem_flash_type = qcom_smem_get(SMEM_HOST_APPS, SMEM_BOOT_FLASH_TYPE,
-+			    		&size);
-+
-+	if (IS_ERR(*smem_flash_type)) {
-+		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)
-+{
-+	size_t size;
-+
-+	*pparts = qcom_smem_get(SMEM_HOST_APPS, SMEM_AARM_PARTITION_TABLE,
-+				&size);
-+
-+	if (IS_ERR(*pparts)) {
-+		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 at codeaurora.org>");
-+MODULE_DESCRIPTION("Parsing code for SMEM based partition tables");
diff --git a/target/linux/ipq806x/patches-4.4/096-01-usb-dwc3-core-purge-dev_dbg-calls.patch b/target/linux/ipq806x/patches-4.4/096-01-usb-dwc3-core-purge-dev_dbg-calls.patch
deleted file mode 100644
index 6ace50c..0000000
--- a/target/linux/ipq806x/patches-4.4/096-01-usb-dwc3-core-purge-dev_dbg-calls.patch
+++ /dev/null
@@ -1,42 +0,0 @@
-From 1407bf13e3bf5f1168484c3e68b6ef9d8cf2bc72 Mon Sep 17 00:00:00 2001
-From: Felipe Balbi <balbi at ti.com>
-Date: Mon, 16 Nov 2015 16:06:37 -0600
-Subject: usb: dwc3: core: purge dev_dbg() calls
-
-The last few dev_dbg() messages are converted to
-tracepoints and we can finally ignore dev_dbg()
-messages during debug sessions.
-
-Signed-off-by: Felipe Balbi <balbi at ti.com>
----
- drivers/usb/dwc3/core.c | 8 +++++---
- 1 file changed, 5 insertions(+), 3 deletions(-)
-
---- a/drivers/usb/dwc3/core.c
-+++ b/drivers/usb/dwc3/core.c
-@@ -272,7 +272,8 @@ static int dwc3_event_buffers_setup(stru
- 
- 	for (n = 0; n < dwc->num_event_buffers; n++) {
- 		evt = dwc->ev_buffs[n];
--		dev_dbg(dwc->dev, "Event buf %p dma %08llx length %d\n",
-+		dwc3_trace(trace_dwc3_core,
-+				"Event buf %p dma %08llx length %d\n",
- 				evt->buf, (unsigned long long) evt->dma,
- 				evt->length);
- 
-@@ -608,12 +609,13 @@ static int dwc3_core_init(struct dwc3 *d
- 		reg |= DWC3_GCTL_GBLHIBERNATIONEN;
- 		break;
- 	default:
--		dev_dbg(dwc->dev, "No power optimization available\n");
-+		dwc3_trace(trace_dwc3_core, "No power optimization available\n");
- 	}
- 
- 	/* check if current dwc3 is on simulation board */
- 	if (dwc->hwparams.hwparams6 & DWC3_GHWPARAMS6_EN_FPGA) {
--		dev_dbg(dwc->dev, "it is on FPGA board\n");
-+		dwc3_trace(trace_dwc3_core,
-+				"running on FPGA platform\n");
- 		dwc->is_fpga = true;
- 	}
- 
diff --git a/target/linux/ipq806x/patches-4.4/096-02-usb-dwc3-Update-maximum_speed-for-SuperSpeedPlus.patch b/target/linux/ipq806x/patches-4.4/096-02-usb-dwc3-Update-maximum_speed-for-SuperSpeedPlus.patch
deleted file mode 100644
index de0e47f..0000000
--- a/target/linux/ipq806x/patches-4.4/096-02-usb-dwc3-Update-maximum_speed-for-SuperSpeedPlus.patch
+++ /dev/null
@@ -1,52 +0,0 @@
-From 2c7f1bd9127a1a49ee25d9c2b2ce17b11c7fb05f Mon Sep 17 00:00:00 2001
-From: John Youn <John.Youn at synopsys.com>
-Date: Fri, 5 Feb 2016 17:08:59 -0800
-Subject: usb: dwc3: Update maximum_speed for SuperSpeedPlus
-
-If the maximum_speed is not set, set it to a known value, either
-SuperSpeed or SuperSpeedPlus based on the type of controller we are
-using. If we are on DWC_usb31 controller, check the PHY interface to see
-if it is capable of SuperSpeedPlus.
-
-Also this check is moved after dwc3_core_init() so that we can check
-dwc->revision.
-
-Signed-off-by: John Youn <johnyoun at synopsys.com>
-Signed-off-by: Felipe Balbi <balbi at kernel.org>
----
- drivers/usb/dwc3/core.c | 17 +++++++++++++----
- 1 file changed, 13 insertions(+), 4 deletions(-)
-
---- a/drivers/usb/dwc3/core.c
-+++ b/drivers/usb/dwc3/core.c
-@@ -962,10 +962,6 @@ static int dwc3_probe(struct platform_de
- 		fladj = pdata->fladj_value;
- 	}
- 
--	/* default to superspeed if no maximum_speed passed */
--	if (dwc->maximum_speed == USB_SPEED_UNKNOWN)
--		dwc->maximum_speed = USB_SPEED_SUPER;
--
- 	dwc->lpm_nyet_threshold = lpm_nyet_threshold;
- 	dwc->tx_de_emphasis = tx_de_emphasis;
- 
-@@ -1016,6 +1012,19 @@ static int dwc3_probe(struct platform_de
- 		goto err1;
- 	}
- 
-+	/* default to superspeed if no maximum_speed passed */
-+	if (dwc->maximum_speed == USB_SPEED_UNKNOWN) {
-+		dwc->maximum_speed = USB_SPEED_SUPER;
-+
-+		/*
-+		 * default to superspeed plus if we are capable.
-+		 */
-+		if (dwc3_is_usb31(dwc) &&
-+		    (DWC3_GHWPARAMS3_SSPHY_IFC(dwc->hwparams.hwparams3) ==
-+		     DWC3_GHWPARAMS3_SSPHY_IFC_GEN2))
-+			dwc->maximum_speed = USB_SPEED_SUPER_PLUS;
-+	}
-+
- 	/* Adjust Frame Length */
- 	dwc3_frame_length_adjustment(dwc, fladj);
- 
diff --git a/target/linux/ipq806x/patches-4.4/096-03-usb-dwc3-Validate-the-maximum_speed-parameter.patch b/target/linux/ipq806x/patches-4.4/096-03-usb-dwc3-Validate-the-maximum_speed-parameter.patch
deleted file mode 100644
index 0f17918..0000000
--- a/target/linux/ipq806x/patches-4.4/096-03-usb-dwc3-Validate-the-maximum_speed-parameter.patch
+++ /dev/null
@@ -1,68 +0,0 @@
-From 77966eb85e6d988a6daaf8ac14ac33026ceb3ab7 Mon Sep 17 00:00:00 2001
-From: John Youn <John.Youn at synopsys.com>
-Date: Fri, 19 Feb 2016 17:31:01 -0800
-Subject: usb: dwc3: Validate the maximum_speed parameter
-
-Check that dwc->maximum_speed is set to a valid value. Also add an error
-when we use it later if we encounter an invalid value.
-
-Signed-off-by: John Youn <johnyoun at synopsys.com>
-Signed-off-by: Felipe Balbi <balbi at kernel.org>
----
- drivers/usb/dwc3/core.c   | 18 ++++++++++++++++--
- drivers/usb/dwc3/gadget.c |  9 ++++++---
- 2 files changed, 22 insertions(+), 5 deletions(-)
-
---- a/drivers/usb/dwc3/core.c
-+++ b/drivers/usb/dwc3/core.c
-@@ -1012,8 +1012,20 @@ static int dwc3_probe(struct platform_de
- 		goto err1;
- 	}
- 
--	/* default to superspeed if no maximum_speed passed */
--	if (dwc->maximum_speed == USB_SPEED_UNKNOWN) {
-+	/* Check the maximum_speed parameter */
-+	switch (dwc->maximum_speed) {
-+	case USB_SPEED_LOW:
-+	case USB_SPEED_FULL:
-+	case USB_SPEED_HIGH:
-+	case USB_SPEED_SUPER:
-+	case USB_SPEED_SUPER_PLUS:
-+		break;
-+	default:
-+		dev_err(dev, "invalid maximum_speed parameter %d\n",
-+			dwc->maximum_speed);
-+		/* fall through */
-+	case USB_SPEED_UNKNOWN:
-+		/* default to superspeed */
- 		dwc->maximum_speed = USB_SPEED_SUPER;
- 
- 		/*
-@@ -1023,6 +1035,8 @@ static int dwc3_probe(struct platform_de
- 		    (DWC3_GHWPARAMS3_SSPHY_IFC(dwc->hwparams.hwparams3) ==
- 		     DWC3_GHWPARAMS3_SSPHY_IFC_GEN2))
- 			dwc->maximum_speed = USB_SPEED_SUPER_PLUS;
-+
-+		break;
- 	}
- 
- 	/* Adjust Frame Length */
---- a/drivers/usb/dwc3/gadget.c
-+++ b/drivers/usb/dwc3/gadget.c
-@@ -1634,10 +1634,13 @@ static int dwc3_gadget_start(struct usb_
- 		case USB_SPEED_HIGH:
- 			reg |= DWC3_DSTS_HIGHSPEED;
- 			break;
--		case USB_SPEED_SUPER:	/* FALLTHROUGH */
--		case USB_SPEED_UNKNOWN:	/* FALTHROUGH */
- 		default:
--			reg |= DWC3_DSTS_SUPERSPEED;
-+			dev_err(dwc->dev, "invalid dwc->maximum_speed (%d)\n",
-+				dwc->maximum_speed);
-+			/* fall through */
-+		case USB_SPEED_SUPER:
-+			reg |= DWC3_DCFG_SUPERSPEED;
-+			break;
- 		}
- 	}
- 	dwc3_writel(dwc->regs, DWC3_DCFG, reg);
diff --git a/target/linux/ipq806x/patches-4.4/096-04-usb-dwc3-DWC_usb31-controller-check.patch b/target/linux/ipq806x/patches-4.4/096-04-usb-dwc3-DWC_usb31-controller-check.patch
deleted file mode 100644
index b6f5830..0000000
--- a/target/linux/ipq806x/patches-4.4/096-04-usb-dwc3-DWC_usb31-controller-check.patch
+++ /dev/null
@@ -1,28 +0,0 @@
-From c4137a9c841ec7fb300782d211f2d6907f4d6e20 Mon Sep 17 00:00:00 2001
-From: John Youn <John.Youn at synopsys.com>
-Date: Fri, 5 Feb 2016 17:08:18 -0800
-Subject: usb: dwc3: DWC_usb31 controller check
-
-Add a convenience function to check if the controller is DWC_usb31.
-
-Signed-off-by: John Youn <johnyoun at synopsys.com>
-Signed-off-by: Felipe Balbi <balbi at kernel.org>
----
- drivers/usb/dwc3/core.h | 6 ++++++
- 1 file changed, 6 insertions(+)
-
---- a/drivers/usb/dwc3/core.h
-+++ b/drivers/usb/dwc3/core.h
-@@ -1019,6 +1019,12 @@ struct dwc3_gadget_ep_cmd_params {
- void dwc3_set_mode(struct dwc3 *dwc, u32 mode);
- int dwc3_gadget_resize_tx_fifos(struct dwc3 *dwc);
- 
-+/* check whether we are on the DWC_usb31 core */
-+static inline bool dwc3_is_usb31(struct dwc3 *dwc)
-+{
-+	return !!(dwc->revision & DWC3_REVISION_IS_DWC31);
-+}
-+
- #if IS_ENABLED(CONFIG_USB_DWC3_HOST) || IS_ENABLED(CONFIG_USB_DWC3_DUAL_ROLE)
- int dwc3_host_init(struct dwc3 *dwc);
- void dwc3_host_exit(struct dwc3 *dwc);
diff --git a/target/linux/ipq806x/patches-4.4/096-05-usb-dwc3-Update-register-fields-for-SuperSpeedPlus.patch b/target/linux/ipq806x/patches-4.4/096-05-usb-dwc3-Update-register-fields-for-SuperSpeedPlus.patch
deleted file mode 100644
index 264893d..0000000
--- a/target/linux/ipq806x/patches-4.4/096-05-usb-dwc3-Update-register-fields-for-SuperSpeedPlus.patch
+++ /dev/null
@@ -1,42 +0,0 @@
-From 1f38f88a24c86d46cf47782ffabd5457f231f8ca Mon Sep 17 00:00:00 2001
-From: John Youn <John.Youn at synopsys.com>
-Date: Fri, 5 Feb 2016 17:08:31 -0800
-Subject: usb: dwc3: Update register fields for SuperSpeedPlus
-
-Update various registers fields definitions for the DWC_usb31 controller
-for SuperSpeedPlus support.
-
-Signed-off-by: John Youn <johnyoun at synopsys.com>
-Signed-off-by: Felipe Balbi <balbi at kernel.org>
----
- drivers/usb/dwc3/core.h | 5 ++++-
- 1 file changed, 4 insertions(+), 1 deletion(-)
-
---- a/drivers/usb/dwc3/core.h
-+++ b/drivers/usb/dwc3/core.h
-@@ -220,7 +220,8 @@
- /* Global HWPARAMS3 Register */
- #define DWC3_GHWPARAMS3_SSPHY_IFC(n)		((n) & 3)
- #define DWC3_GHWPARAMS3_SSPHY_IFC_DIS		0
--#define DWC3_GHWPARAMS3_SSPHY_IFC_ENA		1
-+#define DWC3_GHWPARAMS3_SSPHY_IFC_GEN1		1
-+#define DWC3_GHWPARAMS3_SSPHY_IFC_GEN2		2 /* DWC_usb31 only */
- #define DWC3_GHWPARAMS3_HSPHY_IFC(n)		(((n) & (3 << 2)) >> 2)
- #define DWC3_GHWPARAMS3_HSPHY_IFC_DIS		0
- #define DWC3_GHWPARAMS3_HSPHY_IFC_UTMI		1
-@@ -246,6 +247,7 @@
- #define DWC3_DCFG_DEVADDR_MASK	DWC3_DCFG_DEVADDR(0x7f)
- 
- #define DWC3_DCFG_SPEED_MASK	(7 << 0)
-+#define DWC3_DCFG_SUPERSPEED_PLUS (5 << 0)  /* DWC_usb31 only */
- #define DWC3_DCFG_SUPERSPEED	(4 << 0)
- #define DWC3_DCFG_HIGHSPEED	(0 << 0)
- #define DWC3_DCFG_FULLSPEED2	(1 << 0)
-@@ -336,6 +338,7 @@
- 
- #define DWC3_DSTS_CONNECTSPD		(7 << 0)
- 
-+#define DWC3_DSTS_SUPERSPEED_PLUS	(5 << 0) /* DWC_usb31 only */
- #define DWC3_DSTS_SUPERSPEED		(4 << 0)
- #define DWC3_DSTS_HIGHSPEED		(0 << 0)
- #define DWC3_DSTS_FULLSPEED2		(1 << 0)
diff --git a/target/linux/ipq806x/patches-4.4/096-06-usb-dwc3-core-improve-reset-sequence.patch b/target/linux/ipq806x/patches-4.4/096-06-usb-dwc3-core-improve-reset-sequence.patch
deleted file mode 100644
index 428a796..0000000
--- a/target/linux/ipq806x/patches-4.4/096-06-usb-dwc3-core-improve-reset-sequence.patch
+++ /dev/null
@@ -1,100 +0,0 @@
-From f59dcab176293b646e1358144c93c58c3cda2813 Mon Sep 17 00:00:00 2001
-From: Felipe Balbi <felipe.balbi at linux.intel.com>
-Date: Fri, 11 Mar 2016 10:51:52 +0200
-Subject: usb: dwc3: core: improve reset sequence
-
-According to Synopsys Databook, we shouldn't be
-relying on GCTL.CORESOFTRESET bit as that's only for
-debugging purposes. Instead, let's use DCTL.CSFTRST
-if we're OTG or PERIPHERAL mode.
-
-Host side block will be reset by XHCI driver if
-necessary. Note that this reduces amount of time
-spent on dwc3_probe() by a long margin.
-
-We're still gonna wait for reset to finish for a
-long time (default to 1ms max), but tests show that
-the reset polling loop executed at most 19 times
-(modprobe dwc3 && modprobe -r dwc3 executed 1000
-times in a row).
-
-Suggested-by: Mian Yousaf Kaukab <yousaf.kaukab at intel.com>
-Signed-off-by: Felipe Balbi <felipe.balbi at linux.intel.com>
----
- drivers/usb/dwc3/core.c | 48 ++++++++++++++++++------------------------------
- 1 file changed, 18 insertions(+), 30 deletions(-)
-
---- a/drivers/usb/dwc3/core.c
-+++ b/drivers/usb/dwc3/core.c
-@@ -67,23 +67,9 @@ void dwc3_set_mode(struct dwc3 *dwc, u32
- static int dwc3_core_soft_reset(struct dwc3 *dwc)
- {
- 	u32		reg;
-+	int		retries = 1000;
- 	int		ret;
- 
--	/* Before Resetting PHY, put Core in Reset */
--	reg = dwc3_readl(dwc->regs, DWC3_GCTL);
--	reg |= DWC3_GCTL_CORESOFTRESET;
--	dwc3_writel(dwc->regs, DWC3_GCTL, reg);
--
--	/* Assert USB3 PHY reset */
--	reg = dwc3_readl(dwc->regs, DWC3_GUSB3PIPECTL(0));
--	reg |= DWC3_GUSB3PIPECTL_PHYSOFTRST;
--	dwc3_writel(dwc->regs, DWC3_GUSB3PIPECTL(0), reg);
--
--	/* Assert USB2 PHY reset */
--	reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0));
--	reg |= DWC3_GUSB2PHYCFG_PHYSOFTRST;
--	dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), reg);
--
- 	usb_phy_init(dwc->usb2_phy);
- 	usb_phy_init(dwc->usb3_phy);
- 	ret = phy_init(dwc->usb2_generic_phy);
-@@ -95,26 +81,28 @@ static int dwc3_core_soft_reset(struct d
- 		phy_exit(dwc->usb2_generic_phy);
- 		return ret;
- 	}
--	mdelay(100);
- 
--	/* Clear USB3 PHY reset */
--	reg = dwc3_readl(dwc->regs, DWC3_GUSB3PIPECTL(0));
--	reg &= ~DWC3_GUSB3PIPECTL_PHYSOFTRST;
--	dwc3_writel(dwc->regs, DWC3_GUSB3PIPECTL(0), reg);
--
--	/* Clear USB2 PHY reset */
--	reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0));
--	reg &= ~DWC3_GUSB2PHYCFG_PHYSOFTRST;
--	dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), reg);
--
--	mdelay(100);
--
--	/* After PHYs are stable we can take Core out of reset state */
--	reg = dwc3_readl(dwc->regs, DWC3_GCTL);
--	reg &= ~DWC3_GCTL_CORESOFTRESET;
--	dwc3_writel(dwc->regs, DWC3_GCTL, reg);
-+	/*
-+	 * We're resetting only the device side because, if we're in host mode,
-+	 * XHCI driver will reset the host block. If dwc3 was configured for
-+	 * host-only mode, then we can return early.
-+	 */
-+	if (dwc->dr_mode == USB_DR_MODE_HOST)
-+		return 0;
-+
-+	reg = dwc3_readl(dwc->regs, DWC3_DCTL);
-+	reg |= DWC3_DCTL_CSFTRST;
-+	dwc3_writel(dwc->regs, DWC3_DCTL, reg);
-+
-+	do {
-+		reg = dwc3_readl(dwc->regs, DWC3_DCTL);
-+		if (!(reg & DWC3_DCTL_CSFTRST))
-+			return 0;
-+
-+		udelay(1);
-+	} while (--retries);
- 
--	return 0;
-+	return -ETIMEDOUT;
- }
- 
- /**
diff --git a/target/linux/ipq806x/patches-4.4/096-07-usb-dwc3-drop-FIFO-resizing-logic.patch b/target/linux/ipq806x/patches-4.4/096-07-usb-dwc3-drop-FIFO-resizing-logic.patch
deleted file mode 100644
index 132d131..0000000
--- a/target/linux/ipq806x/patches-4.4/096-07-usb-dwc3-drop-FIFO-resizing-logic.patch
+++ /dev/null
@@ -1,242 +0,0 @@
-From bc5081617faeb3b2f0c126dc37264b87af7da47f Mon Sep 17 00:00:00 2001
-From: Felipe Balbi <felipe.balbi at linux.intel.com>
-Date: Thu, 4 Feb 2016 14:18:01 +0200
-Subject: usb: dwc3: drop FIFO resizing logic
-
-That FIFO resizing logic was added to support OMAP5
-ES1.0 which had a bogus default FIFO size. I can't
-remember the exact size of default FIFO, but it was
-less than one bulk superspeed packet (<1024) which
-would prevent USB3 from ever working on OMAP5 ES1.0.
-
-However, OMAP5 ES1.0 support has been dropped by
-commit aa2f4b16f830 ("ARM: OMAP5: id: Remove ES1.0
-support") which renders FIFO resizing unnecessary.
-
-Tested-by: Kishon Vijay Abraham I <kishon at ti.com>
-Signed-off-by: Felipe Balbi <felipe.balbi at linux.intel.com>
----
- Documentation/devicetree/bindings/usb/dwc3.txt     |  4 +-
- .../devicetree/bindings/usb/qcom,dwc3.txt          |  1 -
- drivers/usb/dwc3/core.c                            |  4 -
- drivers/usb/dwc3/core.h                            |  5 --
- drivers/usb/dwc3/ep0.c                             |  9 ---
- drivers/usb/dwc3/gadget.c                          | 86 ----------------------
- drivers/usb/dwc3/platform_data.h                   |  1 -
- 7 files changed, 2 insertions(+), 108 deletions(-)
-
---- a/Documentation/devicetree/bindings/usb/dwc3.txt
-+++ b/Documentation/devicetree/bindings/usb/dwc3.txt
-@@ -14,7 +14,6 @@ Optional properties:
-    the second element is expected to be a handle to the USB3/SS PHY
-  - phys: from the *Generic PHY* bindings
-  - phy-names: from the *Generic PHY* bindings
-- - tx-fifo-resize: determines if the FIFO *has* to be reallocated.
-  - snps,usb3_lpm_capable: determines if platform is USB3 LPM capable
-  - snps,disable_scramble_quirk: true when SW should disable data scrambling.
- 	Only really useful for FPGA builds.
-@@ -47,6 +46,8 @@ Optional properties:
- 	register for post-silicon frame length adjustment when the
- 	fladj_30mhz_sdbnd signal is invalid or incorrect.
- 
-+ - <DEPRECATED> tx-fifo-resize: determines if the FIFO *has* to be reallocated.
-+
- This is usually a subnode to DWC3 glue to which it is connected.
- 
- dwc3 at 4a030000 {
-@@ -54,5 +55,4 @@ dwc3 at 4a030000 {
- 	reg = <0x4a030000 0xcfff>;
- 	interrupts = <0 92 4>
- 	usb-phy = <&usb2_phy>, <&usb3,phy>;
--	tx-fifo-resize;
- };
---- a/Documentation/devicetree/bindings/usb/qcom,dwc3.txt
-+++ b/Documentation/devicetree/bindings/usb/qcom,dwc3.txt
-@@ -59,7 +59,6 @@ Example device nodes:
- 				interrupts = <0 205 0x4>;
- 				phys = <&hs_phy>, <&ss_phy>;
- 				phy-names = "usb2-phy", "usb3-phy";
--				tx-fifo-resize;
- 				dr_mode = "host";
- 			};
- 		};
---- a/drivers/usb/dwc3/core.c
-+++ b/drivers/usb/dwc3/core.c
-@@ -882,9 +882,6 @@ static int dwc3_probe(struct platform_de
- 	dwc->usb3_lpm_capable = device_property_read_bool(dev,
- 				"snps,usb3_lpm_capable");
- 
--	dwc->needs_fifo_resize = device_property_read_bool(dev,
--				"tx-fifo-resize");
--
- 	dwc->disable_scramble_quirk = device_property_read_bool(dev,
- 				"snps,disable_scramble_quirk");
- 	dwc->u2exit_lfps_quirk = device_property_read_bool(dev,
-@@ -926,7 +923,6 @@ static int dwc3_probe(struct platform_de
- 		if (pdata->hird_threshold)
- 			hird_threshold = pdata->hird_threshold;
- 
--		dwc->needs_fifo_resize = pdata->tx_fifo_resize;
- 		dwc->usb3_lpm_capable = pdata->usb3_lpm_capable;
- 		dwc->dr_mode = pdata->dr_mode;
- 
---- a/drivers/usb/dwc3/core.h
-+++ b/drivers/usb/dwc3/core.h
-@@ -705,9 +705,7 @@ struct dwc3_scratchpad_array {
-  * 	0	- utmi_sleep_n
-  * 	1	- utmi_l1_suspend_n
-  * @is_fpga: true when we are using the FPGA board
-- * @needs_fifo_resize: not all users might want fifo resizing, flag it
-  * @pullups_connected: true when Run/Stop bit is set
-- * @resize_fifos: tells us it's ok to reconfigure our TxFIFO sizes.
-  * @setup_packet_pending: true when there's a Setup Packet in FIFO. Workaround
-  * @start_config_issued: true when StartConfig command has been issued
-  * @three_stage_setup: set if we perform a three phase setup
-@@ -850,9 +848,7 @@ struct dwc3 {
- 	unsigned		has_lpm_erratum:1;
- 	unsigned		is_utmi_l1_suspend:1;
- 	unsigned		is_fpga:1;
--	unsigned		needs_fifo_resize:1;
- 	unsigned		pullups_connected:1;
--	unsigned		resize_fifos:1;
- 	unsigned		setup_packet_pending:1;
- 	unsigned		three_stage_setup:1;
- 	unsigned		usb3_lpm_capable:1;
-@@ -1020,7 +1016,6 @@ struct dwc3_gadget_ep_cmd_params {
- 
- /* prototypes */
- void dwc3_set_mode(struct dwc3 *dwc, u32 mode);
--int dwc3_gadget_resize_tx_fifos(struct dwc3 *dwc);
- 
- /* check whether we are on the DWC_usb31 core */
- static inline bool dwc3_is_usb31(struct dwc3 *dwc)
---- a/drivers/usb/dwc3/ep0.c
-+++ b/drivers/usb/dwc3/ep0.c
-@@ -587,9 +587,6 @@ static int dwc3_ep0_set_config(struct dw
- 			reg = dwc3_readl(dwc->regs, DWC3_DCTL);
- 			reg |= (DWC3_DCTL_ACCEPTU1ENA | DWC3_DCTL_ACCEPTU2ENA);
- 			dwc3_writel(dwc->regs, DWC3_DCTL, reg);
--
--			dwc->resize_fifos = true;
--			dwc3_trace(trace_dwc3_ep0, "resize FIFOs flag SET");
- 		}
- 		break;
- 
-@@ -1028,12 +1025,6 @@ static int dwc3_ep0_start_control_status
- 
- static void __dwc3_ep0_do_control_status(struct dwc3 *dwc, struct dwc3_ep *dep)
- {
--	if (dwc->resize_fifos) {
--		dwc3_trace(trace_dwc3_ep0, "Resizing FIFOs");
--		dwc3_gadget_resize_tx_fifos(dwc);
--		dwc->resize_fifos = 0;
--	}
--
- 	WARN_ON(dwc3_ep0_start_control_status(dep));
- }
- 
---- a/drivers/usb/dwc3/gadget.c
-+++ b/drivers/usb/dwc3/gadget.c
-@@ -145,92 +145,6 @@ int dwc3_gadget_set_link_state(struct dw
- 	return -ETIMEDOUT;
- }
- 
--/**
-- * dwc3_gadget_resize_tx_fifos - reallocate fifo spaces for current use-case
-- * @dwc: pointer to our context structure
-- *
-- * This function will a best effort FIFO allocation in order
-- * to improve FIFO usage and throughput, while still allowing
-- * us to enable as many endpoints as possible.
-- *
-- * Keep in mind that this operation will be highly dependent
-- * on the configured size for RAM1 - which contains TxFifo -,
-- * the amount of endpoints enabled on coreConsultant tool, and
-- * the width of the Master Bus.
-- *
-- * In the ideal world, we would always be able to satisfy the
-- * following equation:
-- *
-- * ((512 + 2 * MDWIDTH-Bytes) + (Number of IN Endpoints - 1) * \
-- * (3 * (1024 + MDWIDTH-Bytes) + MDWIDTH-Bytes)) / MDWIDTH-Bytes
-- *
-- * Unfortunately, due to many variables that's not always the case.
-- */
--int dwc3_gadget_resize_tx_fifos(struct dwc3 *dwc)
--{
--	int		last_fifo_depth = 0;
--	int		ram1_depth;
--	int		fifo_size;
--	int		mdwidth;
--	int		num;
--
--	if (!dwc->needs_fifo_resize)
--		return 0;
--
--	ram1_depth = DWC3_RAM1_DEPTH(dwc->hwparams.hwparams7);
--	mdwidth = DWC3_MDWIDTH(dwc->hwparams.hwparams0);
--
--	/* MDWIDTH is represented in bits, we need it in bytes */
--	mdwidth >>= 3;
--
--	/*
--	 * FIXME For now we will only allocate 1 wMaxPacketSize space
--	 * for each enabled endpoint, later patches will come to
--	 * improve this algorithm so that we better use the internal
--	 * FIFO space
--	 */
--	for (num = 0; num < dwc->num_in_eps; num++) {
--		/* bit0 indicates direction; 1 means IN ep */
--		struct dwc3_ep	*dep = dwc->eps[(num << 1) | 1];
--		int		mult = 1;
--		int		tmp;
--
--		if (!(dep->flags & DWC3_EP_ENABLED))
--			continue;
--
--		if (usb_endpoint_xfer_bulk(dep->endpoint.desc)
--				|| usb_endpoint_xfer_isoc(dep->endpoint.desc))
--			mult = 3;
--
--		/*
--		 * REVISIT: the following assumes we will always have enough
--		 * space available on the FIFO RAM for all possible use cases.
--		 * Make sure that's true somehow and change FIFO allocation
--		 * accordingly.
--		 *
--		 * If we have Bulk or Isochronous endpoints, we want
--		 * them to be able to be very, very fast. So we're giving
--		 * those endpoints a fifo_size which is enough for 3 full
--		 * packets
--		 */
--		tmp = mult * (dep->endpoint.maxpacket + mdwidth);
--		tmp += mdwidth;
--
--		fifo_size = DIV_ROUND_UP(tmp, mdwidth);
--
--		fifo_size |= (last_fifo_depth << 16);
--
--		dwc3_trace(trace_dwc3_gadget, "%s: Fifo Addr %04x Size %d",
--				dep->name, last_fifo_depth, fifo_size & 0xffff);
--
--		dwc3_writel(dwc->regs, DWC3_GTXFIFOSIZ(num), fifo_size);
--
--		last_fifo_depth += (fifo_size & 0xffff);
--	}
--
--	return 0;
--}
--
- void dwc3_gadget_giveback(struct dwc3_ep *dep, struct dwc3_request *req,
- 		int status)
- {
---- a/drivers/usb/dwc3/platform_data.h
-+++ b/drivers/usb/dwc3/platform_data.h
-@@ -23,7 +23,6 @@
- struct dwc3_platform_data {
- 	enum usb_device_speed maximum_speed;
- 	enum usb_dr_mode dr_mode;
--	bool tx_fifo_resize;
- 	bool usb3_lpm_capable;
- 
- 	unsigned is_utmi_l1_suspend:1;
diff --git a/target/linux/ipq806x/patches-4.4/096-08-usb-dwc3-remove-num_event_buffers.patch b/target/linux/ipq806x/patches-4.4/096-08-usb-dwc3-remove-num_event_buffers.patch
deleted file mode 100644
index 5067548..0000000
--- a/target/linux/ipq806x/patches-4.4/096-08-usb-dwc3-remove-num_event_buffers.patch
+++ /dev/null
@@ -1,265 +0,0 @@
-From 660e9bde74d6915227d7ee3485b11e5f52637b26 Mon Sep 17 00:00:00 2001
-From: Felipe Balbi <felipe.balbi at linux.intel.com>
-Date: Wed, 30 Mar 2016 09:26:24 +0300
-Subject: usb: dwc3: remove num_event_buffers
-
-We never, ever route any of the other event buffers
-so we might as well drop support for them.
-
-Until someone has a real, proper benefit for
-multiple event buffers, we will rely on a single
-one. This also helps reduce memory footprint of
-dwc3.ko which won't allocate memory for the extra
-event buffers.
-
-Signed-off-by: Felipe Balbi <felipe.balbi at linux.intel.com>
----
- drivers/usb/dwc3/core.c   | 81 +++++++++++++++++++----------------------------
- drivers/usb/dwc3/core.h   |  2 --
- drivers/usb/dwc3/gadget.c | 38 +++++++---------------
- 3 files changed, 44 insertions(+), 77 deletions(-)
-
---- a/drivers/usb/dwc3/core.c
-+++ b/drivers/usb/dwc3/core.c
-@@ -203,13 +203,10 @@ static struct dwc3_event_buffer *dwc3_al
- static void dwc3_free_event_buffers(struct dwc3 *dwc)
- {
- 	struct dwc3_event_buffer	*evt;
--	int i;
- 
--	for (i = 0; i < dwc->num_event_buffers; i++) {
--		evt = dwc->ev_buffs[i];
--		if (evt)
--			dwc3_free_one_event_buffer(dwc, evt);
--	}
-+	evt = dwc->ev_buffs[0];
-+	if (evt)
-+		dwc3_free_one_event_buffer(dwc, evt);
- }
- 
- /**
-@@ -222,27 +219,19 @@ static void dwc3_free_event_buffers(stru
-  */
- static int dwc3_alloc_event_buffers(struct dwc3 *dwc, unsigned length)
- {
--	int			num;
--	int			i;
--
--	num = DWC3_NUM_INT(dwc->hwparams.hwparams1);
--	dwc->num_event_buffers = num;
-+	struct dwc3_event_buffer *evt;
- 
--	dwc->ev_buffs = devm_kzalloc(dwc->dev, sizeof(*dwc->ev_buffs) * num,
-+	dwc->ev_buffs = devm_kzalloc(dwc->dev, sizeof(*dwc->ev_buffs),
- 			GFP_KERNEL);
- 	if (!dwc->ev_buffs)
- 		return -ENOMEM;
- 
--	for (i = 0; i < num; i++) {
--		struct dwc3_event_buffer	*evt;
--
--		evt = dwc3_alloc_one_event_buffer(dwc, length);
--		if (IS_ERR(evt)) {
--			dev_err(dwc->dev, "can't allocate event buffer\n");
--			return PTR_ERR(evt);
--		}
--		dwc->ev_buffs[i] = evt;
-+	evt = dwc3_alloc_one_event_buffer(dwc, length);
-+	if (IS_ERR(evt)) {
-+		dev_err(dwc->dev, "can't allocate event buffer\n");
-+		return PTR_ERR(evt);
- 	}
-+	dwc->ev_buffs[0] = evt;
- 
- 	return 0;
- }
-@@ -256,25 +245,22 @@ static int dwc3_alloc_event_buffers(stru
- static int dwc3_event_buffers_setup(struct dwc3 *dwc)
- {
- 	struct dwc3_event_buffer	*evt;
--	int				n;
- 
--	for (n = 0; n < dwc->num_event_buffers; n++) {
--		evt = dwc->ev_buffs[n];
--		dwc3_trace(trace_dwc3_core,
--				"Event buf %p dma %08llx length %d\n",
--				evt->buf, (unsigned long long) evt->dma,
--				evt->length);
--
--		evt->lpos = 0;
--
--		dwc3_writel(dwc->regs, DWC3_GEVNTADRLO(n),
--				lower_32_bits(evt->dma));
--		dwc3_writel(dwc->regs, DWC3_GEVNTADRHI(n),
--				upper_32_bits(evt->dma));
--		dwc3_writel(dwc->regs, DWC3_GEVNTSIZ(n),
--				DWC3_GEVNTSIZ_SIZE(evt->length));
--		dwc3_writel(dwc->regs, DWC3_GEVNTCOUNT(n), 0);
--	}
-+	evt = dwc->ev_buffs[0];
-+	dwc3_trace(trace_dwc3_core,
-+			"Event buf %p dma %08llx length %d\n",
-+			evt->buf, (unsigned long long) evt->dma,
-+			evt->length);
-+
-+	evt->lpos = 0;
-+
-+	dwc3_writel(dwc->regs, DWC3_GEVNTADRLO(0),
-+			lower_32_bits(evt->dma));
-+	dwc3_writel(dwc->regs, DWC3_GEVNTADRHI(0),
-+			upper_32_bits(evt->dma));
-+	dwc3_writel(dwc->regs, DWC3_GEVNTSIZ(0),
-+			DWC3_GEVNTSIZ_SIZE(evt->length));
-+	dwc3_writel(dwc->regs, DWC3_GEVNTCOUNT(0), 0);
- 
- 	return 0;
- }
-@@ -282,19 +268,16 @@ static int dwc3_event_buffers_setup(stru
- static void dwc3_event_buffers_cleanup(struct dwc3 *dwc)
- {
- 	struct dwc3_event_buffer	*evt;
--	int				n;
- 
--	for (n = 0; n < dwc->num_event_buffers; n++) {
--		evt = dwc->ev_buffs[n];
-+	evt = dwc->ev_buffs[0];
- 
--		evt->lpos = 0;
-+	evt->lpos = 0;
- 
--		dwc3_writel(dwc->regs, DWC3_GEVNTADRLO(n), 0);
--		dwc3_writel(dwc->regs, DWC3_GEVNTADRHI(n), 0);
--		dwc3_writel(dwc->regs, DWC3_GEVNTSIZ(n), DWC3_GEVNTSIZ_INTMASK
--				| DWC3_GEVNTSIZ_SIZE(0));
--		dwc3_writel(dwc->regs, DWC3_GEVNTCOUNT(n), 0);
--	}
-+	dwc3_writel(dwc->regs, DWC3_GEVNTADRLO(0), 0);
-+	dwc3_writel(dwc->regs, DWC3_GEVNTADRHI(0), 0);
-+	dwc3_writel(dwc->regs, DWC3_GEVNTSIZ(0), DWC3_GEVNTSIZ_INTMASK
-+			| DWC3_GEVNTSIZ_SIZE(0));
-+	dwc3_writel(dwc->regs, DWC3_GEVNTCOUNT(0), 0);
- }
- 
- static int dwc3_alloc_scratch_buffers(struct dwc3 *dwc)
---- a/drivers/usb/dwc3/core.h
-+++ b/drivers/usb/dwc3/core.h
-@@ -663,7 +663,6 @@ struct dwc3_scratchpad_array {
-  * @regs: base address for our registers
-  * @regs_size: address space size
-  * @nr_scratch: number of scratch buffers
-- * @num_event_buffers: calculated number of event buffers
-  * @u1u2: only used on revisions <1.83a for workaround
-  * @maximum_speed: maximum speed requested (mainly for testing purposes)
-  * @revision: revision register contents
-@@ -773,7 +772,6 @@ struct dwc3 {
- 	u32			gctl;
- 
- 	u32			nr_scratch;
--	u32			num_event_buffers;
- 	u32			u1u2;
- 	u32			maximum_speed;
- 
---- a/drivers/usb/dwc3/gadget.c
-+++ b/drivers/usb/dwc3/gadget.c
-@@ -2556,14 +2556,14 @@ static void dwc3_process_event_entry(str
- 	}
- }
- 
--static irqreturn_t dwc3_process_event_buf(struct dwc3 *dwc, u32 buf)
-+static irqreturn_t dwc3_process_event_buf(struct dwc3 *dwc)
- {
- 	struct dwc3_event_buffer *evt;
- 	irqreturn_t ret = IRQ_NONE;
- 	int left;
- 	u32 reg;
- 
--	evt = dwc->ev_buffs[buf];
-+	evt = dwc->ev_buffs[0];
- 	left = evt->count;
- 
- 	if (!(evt->flags & DWC3_EVENT_PENDING))
-@@ -2588,7 +2588,7 @@ static irqreturn_t dwc3_process_event_bu
- 		evt->lpos = (evt->lpos + 4) % DWC3_EVENT_BUFFERS_SIZE;
- 		left -= 4;
- 
--		dwc3_writel(dwc->regs, DWC3_GEVNTCOUNT(buf), 4);
-+		dwc3_writel(dwc->regs, DWC3_GEVNTCOUNT(0), 4);
- 	}
- 
- 	evt->count = 0;
-@@ -2596,9 +2596,9 @@ static irqreturn_t dwc3_process_event_bu
- 	ret = IRQ_HANDLED;
- 
- 	/* Unmask interrupt */
--	reg = dwc3_readl(dwc->regs, DWC3_GEVNTSIZ(buf));
-+	reg = dwc3_readl(dwc->regs, DWC3_GEVNTSIZ(0));
- 	reg &= ~DWC3_GEVNTSIZ_INTMASK;
--	dwc3_writel(dwc->regs, DWC3_GEVNTSIZ(buf), reg);
-+	dwc3_writel(dwc->regs, DWC3_GEVNTSIZ(0), reg);
- 
- 	return ret;
- }
-@@ -2608,27 +2608,23 @@ static irqreturn_t dwc3_thread_interrupt
- 	struct dwc3 *dwc = _dwc;
- 	unsigned long flags;
- 	irqreturn_t ret = IRQ_NONE;
--	int i;
- 
- 	spin_lock_irqsave(&dwc->lock, flags);
--
--	for (i = 0; i < dwc->num_event_buffers; i++)
--		ret |= dwc3_process_event_buf(dwc, i);
--
-+	ret = dwc3_process_event_buf(dwc);
- 	spin_unlock_irqrestore(&dwc->lock, flags);
- 
- 	return ret;
- }
- 
--static irqreturn_t dwc3_check_event_buf(struct dwc3 *dwc, u32 buf)
-+static irqreturn_t dwc3_check_event_buf(struct dwc3 *dwc)
- {
- 	struct dwc3_event_buffer *evt;
- 	u32 count;
- 	u32 reg;
- 
--	evt = dwc->ev_buffs[buf];
-+	evt = dwc->ev_buffs[0];
- 
--	count = dwc3_readl(dwc->regs, DWC3_GEVNTCOUNT(buf));
-+	count = dwc3_readl(dwc->regs, DWC3_GEVNTCOUNT(0));
- 	count &= DWC3_GEVNTCOUNT_MASK;
- 	if (!count)
- 		return IRQ_NONE;
-@@ -2637,9 +2633,9 @@ static irqreturn_t dwc3_check_event_buf(
- 	evt->flags |= DWC3_EVENT_PENDING;
- 
- 	/* Mask interrupt */
--	reg = dwc3_readl(dwc->regs, DWC3_GEVNTSIZ(buf));
-+	reg = dwc3_readl(dwc->regs, DWC3_GEVNTSIZ(0));
- 	reg |= DWC3_GEVNTSIZ_INTMASK;
--	dwc3_writel(dwc->regs, DWC3_GEVNTSIZ(buf), reg);
-+	dwc3_writel(dwc->regs, DWC3_GEVNTSIZ(0), reg);
- 
- 	return IRQ_WAKE_THREAD;
- }
-@@ -2647,18 +2643,8 @@ static irqreturn_t dwc3_check_event_buf(
- static irqreturn_t dwc3_interrupt(int irq, void *_dwc)
- {
- 	struct dwc3			*dwc = _dwc;
--	int				i;
--	irqreturn_t			ret = IRQ_NONE;
--
--	for (i = 0; i < dwc->num_event_buffers; i++) {
--		irqreturn_t status;
- 
--		status = dwc3_check_event_buf(dwc, i);
--		if (status == IRQ_WAKE_THREAD)
--			ret = status;
--	}
--
--	return ret;
-+	return dwc3_check_event_buf(dwc);
- }
- 
- /**
diff --git a/target/linux/ipq806x/patches-4.4/096-09-usb-dwc3-drop-ev_buffs-array.patch b/target/linux/ipq806x/patches-4.4/096-09-usb-dwc3-drop-ev_buffs-array.patch
deleted file mode 100644
index 827b621..0000000
--- a/target/linux/ipq806x/patches-4.4/096-09-usb-dwc3-drop-ev_buffs-array.patch
+++ /dev/null
@@ -1,96 +0,0 @@
-From 696c8b1282205caa5206264449f80ef756f14ef7 Mon Sep 17 00:00:00 2001
-From: Felipe Balbi <felipe.balbi at linux.intel.com>
-Date: Wed, 30 Mar 2016 09:37:03 +0300
-Subject: usb: dwc3: drop ev_buffs array
-
-we will be using a single event buffer and that
-renders ev_buffs array unnecessary. Let's remove it
-in favor of a single pointer to a single event
-buffer.
-
-Signed-off-by: Felipe Balbi <felipe.balbi at linux.intel.com>
----
- drivers/usb/dwc3/core.c   | 13 ++++---------
- drivers/usb/dwc3/core.h   |  2 +-
- drivers/usb/dwc3/gadget.c |  4 ++--
- 3 files changed, 7 insertions(+), 12 deletions(-)
-
---- a/drivers/usb/dwc3/core.c
-+++ b/drivers/usb/dwc3/core.c
-@@ -204,7 +204,7 @@ static void dwc3_free_event_buffers(stru
- {
- 	struct dwc3_event_buffer	*evt;
- 
--	evt = dwc->ev_buffs[0];
-+	evt = dwc->ev_buf;
- 	if (evt)
- 		dwc3_free_one_event_buffer(dwc, evt);
- }
-@@ -221,17 +221,12 @@ static int dwc3_alloc_event_buffers(stru
- {
- 	struct dwc3_event_buffer *evt;
- 
--	dwc->ev_buffs = devm_kzalloc(dwc->dev, sizeof(*dwc->ev_buffs),
--			GFP_KERNEL);
--	if (!dwc->ev_buffs)
--		return -ENOMEM;
--
- 	evt = dwc3_alloc_one_event_buffer(dwc, length);
- 	if (IS_ERR(evt)) {
- 		dev_err(dwc->dev, "can't allocate event buffer\n");
- 		return PTR_ERR(evt);
- 	}
--	dwc->ev_buffs[0] = evt;
-+	dwc->ev_buf = evt;
- 
- 	return 0;
- }
-@@ -246,7 +241,7 @@ static int dwc3_event_buffers_setup(stru
- {
- 	struct dwc3_event_buffer	*evt;
- 
--	evt = dwc->ev_buffs[0];
-+	evt = dwc->ev_buf;
- 	dwc3_trace(trace_dwc3_core,
- 			"Event buf %p dma %08llx length %d\n",
- 			evt->buf, (unsigned long long) evt->dma,
-@@ -269,7 +264,7 @@ static void dwc3_event_buffers_cleanup(s
- {
- 	struct dwc3_event_buffer	*evt;
- 
--	evt = dwc->ev_buffs[0];
-+	evt = dwc->ev_buf;
- 
- 	evt->lpos = 0;
- 
---- a/drivers/usb/dwc3/core.h
-+++ b/drivers/usb/dwc3/core.h
-@@ -748,7 +748,7 @@ struct dwc3 {
- 	struct platform_device	*xhci;
- 	struct resource		xhci_resources[DWC3_XHCI_RESOURCES_NUM];
- 
--	struct dwc3_event_buffer **ev_buffs;
-+	struct dwc3_event_buffer *ev_buf;
- 	struct dwc3_ep		*eps[DWC3_ENDPOINTS_NUM];
- 
- 	struct usb_gadget	gadget;
---- a/drivers/usb/dwc3/gadget.c
-+++ b/drivers/usb/dwc3/gadget.c
-@@ -2563,7 +2563,7 @@ static irqreturn_t dwc3_process_event_bu
- 	int left;
- 	u32 reg;
- 
--	evt = dwc->ev_buffs[0];
-+	evt = dwc->ev_buf;
- 	left = evt->count;
- 
- 	if (!(evt->flags & DWC3_EVENT_PENDING))
-@@ -2622,7 +2622,7 @@ static irqreturn_t dwc3_check_event_buf(
- 	u32 count;
- 	u32 reg;
- 
--	evt = dwc->ev_buffs[0];
-+	evt = dwc->ev_buf;
- 
- 	count = dwc3_readl(dwc->regs, DWC3_GEVNTCOUNT(0));
- 	count &= DWC3_GEVNTCOUNT_MASK;
diff --git a/target/linux/ipq806x/patches-4.4/096-10-usb-dwc3-core-fix-PHY-handling-during-suspend.patch b/target/linux/ipq806x/patches-4.4/096-10-usb-dwc3-core-fix-PHY-handling-during-suspend.patch
deleted file mode 100644
index 8bf09ed..0000000
--- a/target/linux/ipq806x/patches-4.4/096-10-usb-dwc3-core-fix-PHY-handling-during-suspend.patch
+++ /dev/null
@@ -1,67 +0,0 @@
-From 5c4ad318de3b8e8680d654c82a254c4b65243739 Mon Sep 17 00:00:00 2001
-From: Felipe Balbi <balbi at kernel.org>
-Date: Mon, 11 Apr 2016 17:12:34 +0300
-Subject: usb: dwc3: core: fix PHY handling during suspend
-
-we need to power off the PHY during suspend and
-power it back on during resume.
-
-Signed-off-by: Felipe Balbi <balbi at kernel.org>
-[nsekhar at ti.com: fix call to usb_phy_set_suspend() in dwc3_suspend()]
-Signed-off-by: Sekhar Nori <nsekhar at ti.com>
-Signed-off-by: Roger Quadros <rogerq at ti.com>
-Signed-off-by: Felipe Balbi <felipe.balbi at linux.intel.com>
----
- drivers/usb/dwc3/core.c | 23 ++++++++++++++++++++++-
- 1 file changed, 22 insertions(+), 1 deletion(-)
-
---- a/drivers/usb/dwc3/core.c
-+++ b/drivers/usb/dwc3/core.c
-@@ -1124,6 +1124,11 @@ static int dwc3_suspend(struct device *d
- 	phy_exit(dwc->usb2_generic_phy);
- 	phy_exit(dwc->usb3_generic_phy);
- 
-+	usb_phy_set_suspend(dwc->usb2_phy, 1);
-+	usb_phy_set_suspend(dwc->usb3_phy, 1);
-+	WARN_ON(phy_power_off(dwc->usb2_generic_phy) < 0);
-+	WARN_ON(phy_power_off(dwc->usb3_generic_phy) < 0);
-+
- 	pinctrl_pm_select_sleep_state(dev);
- 
- 	return 0;
-@@ -1137,11 +1142,21 @@ static int dwc3_resume(struct device *de
- 
- 	pinctrl_pm_select_default_state(dev);
- 
-+	usb_phy_set_suspend(dwc->usb2_phy, 0);
-+	usb_phy_set_suspend(dwc->usb3_phy, 0);
-+	ret = phy_power_on(dwc->usb2_generic_phy);
-+	if (ret < 0)
-+		return ret;
-+
-+	ret = phy_power_on(dwc->usb3_generic_phy);
-+	if (ret < 0)
-+		goto err_usb2phy_power;
-+
- 	usb_phy_init(dwc->usb3_phy);
- 	usb_phy_init(dwc->usb2_phy);
- 	ret = phy_init(dwc->usb2_generic_phy);
- 	if (ret < 0)
--		return ret;
-+		goto err_usb3phy_power;
- 
- 	ret = phy_init(dwc->usb3_generic_phy);
- 	if (ret < 0)
-@@ -1174,6 +1189,12 @@ static int dwc3_resume(struct device *de
- err_usb2phy_init:
- 	phy_exit(dwc->usb2_generic_phy);
- 
-+err_usb3phy_power:
-+	phy_power_off(dwc->usb3_generic_phy);
-+
-+err_usb2phy_power:
-+	phy_power_off(dwc->usb2_generic_phy);
-+
- 	return ret;
- }
- 
diff --git a/target/linux/ipq806x/patches-4.4/097-1-usb-dwc3-add-generic-OF-glue-layer.patch b/target/linux/ipq806x/patches-4.4/097-1-usb-dwc3-add-generic-OF-glue-layer.patch
deleted file mode 100644
index 214bedc..0000000
--- a/target/linux/ipq806x/patches-4.4/097-1-usb-dwc3-add-generic-OF-glue-layer.patch
+++ /dev/null
@@ -1,234 +0,0 @@
-From 41c2b5280cd2fa3e198c422cdf223ba6e48f857a Mon Sep 17 00:00:00 2001
-From: Felipe Balbi <balbi at ti.com>
-Date: Wed, 18 Nov 2015 13:15:20 -0600
-Subject: [PATCH] usb: dwc3: add generic OF glue layer
-
-For simple platforms which merely enable some clocks
-and populate its children, we can use this generic
-glue layer to avoid boilerplate code duplication.
-
-For now this supports Qcom and Xilinx, but if we
-find a way to add generic handling of regulators and
-optional PHYs, we can absorb exynos as well.
-
-Tested-by: Subbaraya Sundeep Bhatta <subbaraya.sundeep.bhatta at xilinx.com>
-Signed-off-by: Felipe Balbi <balbi at ti.com>
-(cherry picked from commit 16adc674d0d68a50dfc725574738d7ae11cf5d7e)
-
-Change-Id: I6fd260442997b198dc12ca726814b7a9518e6353
-Signed-off-by: Nitheesh Sekar <nsekar at codeaurora.org>
----
- drivers/usb/dwc3/Kconfig          |   9 ++
- drivers/usb/dwc3/Makefile         |   1 +
- drivers/usb/dwc3/dwc3-of-simple.c | 178 ++++++++++++++++++++++++++++++++++++++
- 3 files changed, 188 insertions(+)
- create mode 100644 drivers/usb/dwc3/dwc3-of-simple.c
-
---- a/drivers/usb/dwc3/Kconfig
-+++ b/drivers/usb/dwc3/Kconfig
-@@ -87,6 +87,15 @@ config USB_DWC3_KEYSTONE
- 	  Support of USB2/3 functionality in TI Keystone2 platforms.
- 	  Say 'Y' or 'M' here if you have one such device
- 
-+config USB_DWC3_OF_SIMPLE
-+       tristate "Generic OF Simple Glue Layer"
-+       depends on OF && COMMON_CLK
-+       default USB_DWC3
-+       help
-+         Support USB2/3 functionality in simple SoC integrations.
-+	 Currently supports Xilinx and Qualcomm DWC USB3 IP.
-+	 Say 'Y' or 'M' if you have one such device.
-+
- config USB_DWC3_ST
- 	tristate "STMicroelectronics Platforms"
- 	depends on ARCH_STI && OF
---- a/drivers/usb/dwc3/Makefile
-+++ b/drivers/usb/dwc3/Makefile
-@@ -37,5 +37,6 @@ obj-$(CONFIG_USB_DWC3_OMAP)		+= dwc3-oma
- obj-$(CONFIG_USB_DWC3_EXYNOS)		+= dwc3-exynos.o
- obj-$(CONFIG_USB_DWC3_PCI)		+= dwc3-pci.o
- obj-$(CONFIG_USB_DWC3_KEYSTONE)		+= dwc3-keystone.o
-+obj-$(CONFIG_USB_DWC3_OF_SIMPLE)	+= dwc3-of-simple.o
- obj-$(CONFIG_USB_DWC3_QCOM)		+= dwc3-qcom.o
- obj-$(CONFIG_USB_DWC3_ST)		+= dwc3-st.o
---- /dev/null
-+++ b/drivers/usb/dwc3/dwc3-of-simple.c
-@@ -0,0 +1,178 @@
-+/**
-+ * dwc3-of-simple.c - OF glue layer for simple integrations
-+ *
-+ * Copyright (c) 2015 Texas Instruments Incorporated - http://www.ti.com
-+ *
-+ * Author: Felipe Balbi <balbi at ti.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  of
-+ * the License 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.
-+ *
-+ * This is a combination of the old dwc3-qcom.c by Ivan T. Ivanov
-+ * <iivanov at mm-sol.com> and the original patch adding support for Xilinx' SoC
-+ * by Subbaraya Sundeep Bhatta <subbaraya.sundeep.bhatta at xilinx.com>
-+ */
-+
-+#include <linux/module.h>
-+#include <linux/kernel.h>
-+#include <linux/slab.h>
-+#include <linux/platform_device.h>
-+#include <linux/dma-mapping.h>
-+#include <linux/clk.h>
-+#include <linux/clk-provider.h>
-+#include <linux/of.h>
-+#include <linux/of_platform.h>
-+#include <linux/pm_runtime.h>
-+
-+struct dwc3_of_simple {
-+	struct device		*dev;
-+	struct clk		**clks;
-+	int			num_clocks;
-+};
-+
-+static int dwc3_of_simple_probe(struct platform_device *pdev)
-+{
-+	struct dwc3_of_simple	*simple;
-+	struct device		*dev = &pdev->dev;
-+	struct device_node	*np = dev->of_node;
-+
-+	int			ret;
-+	int			i;
-+
-+	simple = devm_kzalloc(dev, sizeof(*simple), GFP_KERNEL);
-+	if (!simple)
-+		return -ENOMEM;
-+
-+	ret = of_clk_get_parent_count(np);
-+	if (ret < 0)
-+		return ret;
-+
-+	simple->num_clocks = ret;
-+
-+	simple->clks = devm_kcalloc(dev, simple->num_clocks,
-+			sizeof(struct clk *), GFP_KERNEL);
-+	if (!simple->clks)
-+		return -ENOMEM;
-+
-+	simple->dev = dev;
-+
-+	for (i = 0; i < simple->num_clocks; i++) {
-+		struct clk	*clk;
-+
-+		clk = of_clk_get(np, i);
-+		if (IS_ERR(clk)) {
-+			while (--i >= 0)
-+				clk_put(simple->clks[i]);
-+			return PTR_ERR(clk);
-+		}
-+
-+		ret = clk_prepare_enable(clk);
-+		if (ret < 0) {
-+			while (--i >= 0) {
-+				clk_disable_unprepare(simple->clks[i]);
-+				clk_put(simple->clks[i]);
-+			}
-+			clk_put(clk);
-+
-+			return ret;
-+		}
-+
-+		simple->clks[i] = clk;
-+	}
-+
-+	ret = of_platform_populate(np, NULL, NULL, dev);
-+	if (ret) {
-+		for (i = 0; i < simple->num_clocks; i++) {
-+			clk_disable_unprepare(simple->clks[i]);
-+			clk_put(simple->clks[i]);
-+		}
-+
-+		return ret;
-+	}
-+
-+	pm_runtime_set_active(dev);
-+	pm_runtime_enable(dev);
-+	pm_runtime_get_sync(dev);
-+
-+	return 0;
-+}
-+
-+static int dwc3_of_simple_remove(struct platform_device *pdev)
-+{
-+	struct dwc3_of_simple	*simple = platform_get_drvdata(pdev);
-+	struct device		*dev = &pdev->dev;
-+	int			i;
-+
-+	for (i = 0; i < simple->num_clocks; i++) {
-+		clk_unprepare(simple->clks[i]);
-+		clk_put(simple->clks[i]);
-+	}
-+
-+	of_platform_depopulate(dev);
-+
-+	pm_runtime_put_sync(dev);
-+	pm_runtime_disable(dev);
-+
-+	return 0;
-+}
-+
-+static int dwc3_of_simple_runtime_suspend(struct device *dev)
-+{
-+	struct dwc3_of_simple	*simple = dev_get_drvdata(dev);
-+	int			i;
-+
-+	for (i = 0; i < simple->num_clocks; i++)
-+		clk_disable(simple->clks[i]);
-+
-+	return 0;
-+}
-+
-+static int dwc3_of_simple_runtime_resume(struct device *dev)
-+{
-+	struct dwc3_of_simple	*simple = dev_get_drvdata(dev);
-+	int			ret;
-+	int			i;
-+
-+	for (i = 0; i < simple->num_clocks; i++) {
-+		ret = clk_enable(simple->clks[i]);
-+		if (ret < 0) {
-+			while (--i >= 0)
-+				clk_disable(simple->clks[i]);
-+			return ret;
-+		}
-+	}
-+
-+	return 0;
-+}
-+
-+static const struct dev_pm_ops dwc3_of_simple_dev_pm_ops = {
-+	SET_RUNTIME_PM_OPS(dwc3_of_simple_runtime_suspend,
-+			dwc3_of_simple_runtime_resume, NULL)
-+};
-+
-+static const struct of_device_id of_dwc3_simple_match[] = {
-+	{ .compatible = "qcom,dwc3" },
-+	{ .compatible = "xlnx,zynqmp-dwc3" },
-+	{ /* Sentinel */ }
-+};
-+MODULE_DEVICE_TABLE(of, of_dwc3_simple_match);
-+
-+static struct platform_driver dwc3_of_simple_driver = {
-+	.probe		= dwc3_of_simple_probe,
-+	.remove		= dwc3_of_simple_remove,
-+	.driver		= {
-+		.name	= "dwc3-of-simple",
-+		.of_match_table = of_dwc3_simple_match,
-+	},
-+};
-+
-+module_platform_driver(dwc3_of_simple_driver);
-+MODULE_LICENSE("GPL v2");
-+MODULE_DESCRIPTION("DesignWare USB3 OF Simple Glue Layer");
-+MODULE_AUTHOR("Felipe Balbi <balbi at ti.com>");
diff --git a/target/linux/ipq806x/patches-4.4/097-2-usb-dwc3-of-simple-fix-build-warning-on-PM.patch b/target/linux/ipq806x/patches-4.4/097-2-usb-dwc3-of-simple-fix-build-warning-on-PM.patch
deleted file mode 100644
index b982c82..0000000
--- a/target/linux/ipq806x/patches-4.4/097-2-usb-dwc3-of-simple-fix-build-warning-on-PM.patch
+++ /dev/null
@@ -1,36 +0,0 @@
-From 131386d63ca3177d471aa93808c69b85fdac520d Mon Sep 17 00:00:00 2001
-From: Felipe Balbi <balbi at ti.com>
-Date: Tue, 22 Dec 2015 21:56:10 -0600
-Subject: [PATCH] usb: dwc3: of-simple: fix build warning on !PM
-
-if we have a !PM kernel build, our runtime
-suspend/resume callbacks will be left defined but
-unused. Add a ifdef CONFIG_PM guard.
-
-Signed-off-by: Felipe Balbi <balbi at ti.com>
-(cherry picked from commit 5072cfc40a80cea3749fd3413b3896630d8c787e)
-
-Change-Id: I088186c33aa917ec8da2985372ceefc289b24242
-Signed-off-by: Nitheesh Sekar <nsekar at codeaurora.org>
----
- drivers/usb/dwc3/dwc3-of-simple.c | 2 ++
- 1 file changed, 2 insertions(+)
-
---- a/drivers/usb/dwc3/dwc3-of-simple.c
-+++ b/drivers/usb/dwc3/dwc3-of-simple.c
-@@ -122,6 +122,7 @@ static int dwc3_of_simple_remove(struct
- 	return 0;
- }
- 
-+#ifdef CONFIG_PM
- static int dwc3_of_simple_runtime_suspend(struct device *dev)
- {
- 	struct dwc3_of_simple	*simple = dev_get_drvdata(dev);
-@@ -150,6 +151,7 @@ static int dwc3_of_simple_runtime_resume
- 
- 	return 0;
- }
-+#endif
- 
- static const struct dev_pm_ops dwc3_of_simple_dev_pm_ops = {
- 	SET_RUNTIME_PM_OPS(dwc3_of_simple_runtime_suspend,
diff --git a/target/linux/ipq806x/patches-4.4/097-3-usb-dwc3-Remove-impossible-check-for-of_clk_get_pare.patch b/target/linux/ipq806x/patches-4.4/097-3-usb-dwc3-Remove-impossible-check-for-of_clk_get_pare.patch
deleted file mode 100644
index 32f9e34..0000000
--- a/target/linux/ipq806x/patches-4.4/097-3-usb-dwc3-Remove-impossible-check-for-of_clk_get_pare.patch
+++ /dev/null
@@ -1,47 +0,0 @@
-From 07c8b15688055d81ac8e1c8c964b9e4c302287f1 Mon Sep 17 00:00:00 2001
-From: Stephen Boyd <sboyd at codeaurora.org>
-Date: Mon, 22 Feb 2016 11:12:47 -0800
-Subject: [PATCH] usb: dwc3: Remove impossible check for
- of_clk_get_parent_count() < 0
-
-The check for < 0 is impossible now that
-of_clk_get_parent_count() returns an unsigned int. Simplify the
-code and update the types.
-
-Acked-by: Felipe Balbi <balbi at kernel.org>
-Cc: <linux-usb at vger.kernel.org>
-Signed-off-by: Stephen Boyd <sboyd at codeaurora.org>
-(cherry picked from commit 3d755dcc20dd452b52532eca17da40ebbd12aee9)
-
-Change-Id: Iaa38e064d801fb36c855fea51c0443840368e0d3
-Signed-off-by: Nitheesh Sekar <nsekar at codeaurora.org>
----
- drivers/usb/dwc3/dwc3-of-simple.c | 9 +++++----
- 1 file changed, 5 insertions(+), 4 deletions(-)
-
---- a/drivers/usb/dwc3/dwc3-of-simple.c
-+++ b/drivers/usb/dwc3/dwc3-of-simple.c
-@@ -42,6 +42,7 @@ static int dwc3_of_simple_probe(struct p
- 	struct device		*dev = &pdev->dev;
- 	struct device_node	*np = dev->of_node;
- 
-+	unsigned int		count;
- 	int			ret;
- 	int			i;
- 
-@@ -49,11 +50,11 @@ static int dwc3_of_simple_probe(struct p
- 	if (!simple)
- 		return -ENOMEM;
- 
--	ret = of_clk_get_parent_count(np);
--	if (ret < 0)
--		return ret;
-+	count = of_clk_get_parent_count(np);
-+	if (!count)
-+		return -ENOENT;
- 
--	simple->num_clocks = ret;
-+	simple->num_clocks = count;
- 
- 	simple->clks = devm_kcalloc(dev, simple->num_clocks,
- 			sizeof(struct clk *), GFP_KERNEL);
diff --git a/target/linux/ipq806x/patches-4.4/097-4-usb-dwc3-fix-missing-platform_set_drvdata-in-dwc3_of_simple_probe.patch b/target/linux/ipq806x/patches-4.4/097-4-usb-dwc3-fix-missing-platform_set_drvdata-in-dwc3_of_simple_probe.patch
deleted file mode 100644
index 2d18e41..0000000
--- a/target/linux/ipq806x/patches-4.4/097-4-usb-dwc3-fix-missing-platform_set_drvdata-in-dwc3_of_simple_probe.patch
+++ /dev/null
@@ -1,27 +0,0 @@
-From 4c4f106c032ff32b89c98a4d819e68e6e643c14e Mon Sep 17 00:00:00 2001
-From: Wei Yongjun <weiyj.lk at gmail.com>
-Date: Tue, 26 Jul 2016 14:47:00 +0000
-Subject: usb: dwc3: fix missing platform_set_drvdata() in
- dwc3_of_simple_probe()
-
-Add missing platform_set_drvdata() in dwc3_of_simple_probe(), otherwise
-calling platform_get_drvdata() in remove returns NULL.
-
-This is detected by Coccinelle semantic patch.
-
-Signed-off-by: Wei Yongjun <weiyj.lk at gmail.com>
-Signed-off-by: Felipe Balbi <felipe.balbi at linux.intel.com>
----
- drivers/usb/dwc3/dwc3-of-simple.c | 1 +
- 1 file changed, 1 insertion(+)
-
---- a/drivers/usb/dwc3/dwc3-of-simple.c
-+++ b/drivers/usb/dwc3/dwc3-of-simple.c
-@@ -61,6 +61,7 @@ static int dwc3_of_simple_probe(struct p
- 	if (!simple->clks)
- 		return -ENOMEM;
- 
-+	platform_set_drvdata(pdev, simple);
- 	simple->dev = dev;
- 
- 	for (i = 0; i < simple->num_clocks; i++) {
diff --git a/target/linux/ipq806x/patches-4.4/100-usb-phy-Add-Qualcomm-DWC3-HS-SS-PHY-drivers.patch b/target/linux/ipq806x/patches-4.4/100-usb-phy-Add-Qualcomm-DWC3-HS-SS-PHY-drivers.patch
deleted file mode 100644
index 0da1927..0000000
--- a/target/linux/ipq806x/patches-4.4/100-usb-phy-Add-Qualcomm-DWC3-HS-SS-PHY-drivers.patch
+++ /dev/null
@@ -1,512 +0,0 @@
---- a/drivers/phy/Kconfig
-+++ b/drivers/phy/Kconfig
-@@ -390,4 +390,15 @@ config PHY_CYGNUS_PCIE
- 	  Enable this to support the Broadcom Cygnus PCIe PHY.
- 	  If unsure, say N.
- 
-+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
-@@ -48,3 +48,4 @@ obj-$(CONFIG_PHY_TUSB1210)		+= phy-tusb1
- obj-$(CONFIG_PHY_BRCMSTB_SATA)		+= phy-brcmstb-sata.o
- obj-$(CONFIG_PHY_PISTACHIO_USB)		+= phy-pistachio-usb.o
- obj-$(CONFIG_PHY_CYGNUS_PCIE)		+= phy-bcm-cygnus-pcie.o
-+obj-$(CONFIG_PHY_QCOM_DWC3)		+= phy-qcom-dwc3.o
---- /dev/null
-+++ b/drivers/phy/phy-qcom-dwc3.c
-@@ -0,0 +1,484 @@
-+/* Copyright (c) 2014-2015, 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)
-+
-+/* SS CAP register bits */
-+#define SS_CR_CAP_ADDR_REG		BIT(0)
-+#define SS_CR_CAP_DATA_REG		BIT(0)
-+#define SS_CR_READ_REG			BIT(0)
-+#define SS_CR_WRITE_REG			BIT(0)
-+
-+struct qcom_dwc3_usb_phy {
-+	void __iomem		*base;
-+	struct device		*dev;
-+	struct clk		*xo_clk;
-+	struct clk		*ref_clk;
-+};
-+
-+struct qcom_dwc3_phy_drvdata {
-+	struct phy_ops	ops;
-+	u32		clk_rate;
-+};
-+
-+/**
-+ * 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(struct qcom_dwc3_usb_phy *phy_dwc3,
-+					u32 addr, u32 val)
-+{
-+	int ret;
-+
-+	writel(addr, phy_dwc3->base + CR_PROTOCOL_DATA_IN_REG);
-+	writel(SS_CR_CAP_ADDR_REG, phy_dwc3->base + CR_PROTOCOL_CAP_ADDR_REG);
-+
-+	ret = wait_for_latch(phy_dwc3->base + CR_PROTOCOL_CAP_ADDR_REG);
-+	if (ret)
-+		goto err_wait;
-+
-+	writel(val, phy_dwc3->base + CR_PROTOCOL_DATA_IN_REG);
-+	writel(SS_CR_CAP_DATA_REG, phy_dwc3->base + CR_PROTOCOL_CAP_DATA_REG);
-+
-+	ret = wait_for_latch(phy_dwc3->base + CR_PROTOCOL_CAP_DATA_REG);
-+	if (ret)
-+		goto err_wait;
-+
-+	writel(SS_CR_WRITE_REG, phy_dwc3->base + CR_PROTOCOL_WRITE_REG);
-+
-+	ret = wait_for_latch(phy_dwc3->base + CR_PROTOCOL_WRITE_REG);
-+
-+err_wait:
-+	if (ret)
-+		dev_err(phy_dwc3->dev, "timeout waiting for latch\n");
-+	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;
-+
-+	writel(addr, base + CR_PROTOCOL_DATA_IN_REG);
-+	writel(SS_CR_CAP_ADDR_REG, 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.
-+	 */
-+	writel(SS_CR_READ_REG, base + CR_PROTOCOL_READ_REG);
-+
-+	ret = wait_for_latch(base + CR_PROTOCOL_READ_REG);
-+	if (ret)
-+		goto err_wait;
-+
-+	/* throwaway read */
-+	readl(base + CR_PROTOCOL_DATA_OUT_REG);
-+
-+	writel(SS_CR_READ_REG, base + CR_PROTOCOL_READ_REG);
-+
-+	ret = wait_for_latch(base + CR_PROTOCOL_READ_REG);
-+	if (ret)
-+		goto err_wait;
-+
-+	*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 phy *phy)
-+{
-+	struct qcom_dwc3_usb_phy *phy_dwc3 = phy_get_drvdata(phy);
-+	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 phy *phy)
-+{
-+	struct qcom_dwc3_usb_phy *phy_dwc3 = phy_get_drvdata(phy);
-+	int ret;
-+	u32 data = 0;
-+
-+	/* reset phy */
-+	data = readl(phy_dwc3->base + SSUSB_PHY_CTRL_REG);
-+	writel(data | SSUSB_CTRL_SS_PHY_RESET,
-+		phy_dwc3->base + SSUSB_PHY_CTRL_REG);
-+	usleep_range(2000, 2200);
-+	writel(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(data, phy_dwc3->base + SSUSB_PHY_CTRL_REG);
-+
-+	/* wait for ref clk to become stable, this can take up to 30ms */
-+	msleep(30);
-+
-+	data |= SSUSB_CTRL_SS_PHY_EN | SSUSB_CTRL_LANE0_PWR_PRESENT;
-+	writel(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,
-+		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,
-+		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 phy *phy)
-+{
-+	struct qcom_dwc3_usb_phy *phy_dwc3 = phy_get_drvdata(phy);
-+
-+	/* 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
-+	 */
-+	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 const struct qcom_dwc3_phy_drvdata qcom_dwc3_hs_drvdata = {
-+	.ops = {
-+		.init		= qcom_dwc3_hs_phy_init,
-+		.power_on	= qcom_dwc3_phy_power_on,
-+		.power_off	= qcom_dwc3_phy_power_off,
-+		.owner		= THIS_MODULE,
-+	},
-+	.clk_rate = 60000000,
-+};
-+
-+static const struct qcom_dwc3_phy_drvdata qcom_dwc3_ss_drvdata = {
-+	.ops = {
-+		.init		= qcom_dwc3_ss_phy_init,
-+		.exit		= qcom_dwc3_ss_phy_exit,
-+		.power_on	= qcom_dwc3_phy_power_on,
-+		.power_off	= qcom_dwc3_phy_power_off,
-+		.owner		= THIS_MODULE,
-+	},
-+	.clk_rate = 125000000,
-+};
-+
-+static const struct of_device_id qcom_dwc3_phy_table[] = {
-+	{ .compatible = "qcom,dwc3-hs-usb-phy", .data = &qcom_dwc3_hs_drvdata },
-+	{ .compatible = "qcom,dwc3-ss-usb-phy", .data = &qcom_dwc3_ss_drvdata },
-+	{ /* 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 phy			*generic_phy;
-+	struct resource			*res;
-+	const struct of_device_id *match;
-+	const struct qcom_dwc3_phy_drvdata *data;
-+
-+	phy_dwc3 = devm_kzalloc(&pdev->dev, sizeof(*phy_dwc3), GFP_KERNEL);
-+	if (!phy_dwc3)
-+		return -ENOMEM;
-+
-+	match = of_match_node(qcom_dwc3_phy_table, pdev->dev.of_node);
-+	data = match->data;
-+
-+	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);
-+	}
-+
-+	clk_set_rate(phy_dwc3->ref_clk, data->clk_rate);
-+
-+	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;
-+	}
-+
-+	generic_phy = devm_phy_create(phy_dwc3->dev, pdev->dev.of_node,
-+				      &data->ops);
-+
-+	if (IS_ERR(generic_phy))
-+		return PTR_ERR(generic_phy);
-+
-+	phy_set_drvdata(generic_phy, phy_dwc3);
-+	platform_set_drvdata(pdev, 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 at codeaurora.org>");
-+MODULE_AUTHOR("Ivan T. Ivanov <iivanov at mm-sol.com>");
-+MODULE_DESCRIPTION("DesignWare USB3 QCOM PHY driver");
diff --git a/target/linux/ipq806x/patches-4.4/101-ARM-qcom-add-USB-nodes-to-ipq806x-ap148.patch b/target/linux/ipq806x/patches-4.4/101-ARM-qcom-add-USB-nodes-to-ipq806x-ap148.patch
deleted file mode 100644
index d1f19c3..0000000
--- a/target/linux/ipq806x/patches-4.4/101-ARM-qcom-add-USB-nodes-to-ipq806x-ap148.patch
+++ /dev/null
@@ -1,123 +0,0 @@
---- a/arch/arm/boot/dts/qcom-ipq8064-ap148.dts
-+++ b/arch/arm/boot/dts/qcom-ipq8064-ap148.dts
-@@ -92,5 +92,29 @@
- 		sata at 29000000 {
- 			status = "ok";
- 		};
-+
-+		phy at 100f8800 {		/* USB3 port 1 HS phy */
-+			status = "ok";
-+		};
-+
-+		phy at 100f8830 {		/* USB3 port 1 SS phy */
-+			status = "ok";
-+		};
-+
-+		phy at 110f8800 {		/* USB3 port 0 HS phy */
-+			status = "ok";
-+		};
-+
-+		phy at 110f8830 {		/* USB3 port 0 SS phy */
-+			status = "ok";
-+		};
-+
-+		usb30 at 0 {
-+			status = "ok";
-+		};
-+
-+		usb30 at 1 {
-+			status = "ok";
-+		};
- 	};
- };
---- a/arch/arm/boot/dts/qcom-ipq8064.dtsi
-+++ b/arch/arm/boot/dts/qcom-ipq8064.dtsi
-@@ -333,6 +333,88 @@
- 			compatible = "syscon";
- 			reg = <0x01200600 0x100>;
- 		};
-+
-+		hs_phy_1: phy at 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 at 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 at 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 at 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 at 0 {
-+			compatible = "qcom,dwc3";
-+			#address-cells = <1>;
-+			#size-cells = <1>;
-+			clocks = <&gcc USB30_0_MASTER_CLK>;
-+			clock-names = "core";
-+
-+			ranges;
-+
-+			status = "disabled";
-+
-+			dwc3 at 11000000 {
-+				compatible = "snps,dwc3";
-+				reg = <0x11000000 0xcd00>;
-+				interrupts = <0 110 0x4>;
-+				phys = <&hs_phy_0>, <&ss_phy_0>;
-+				phy-names = "usb2-phy", "usb3-phy";
-+				dr_mode = "host";
-+			};
-+		};
-+
-+		usb3_1: usb30 at 1 {
-+			compatible = "qcom,dwc3";
-+			#address-cells = <1>;
-+			#size-cells = <1>;
-+			clocks = <&gcc USB30_1_MASTER_CLK>;
-+			clock-names = "core";
-+
-+			ranges;
-+
-+			status = "disabled";
-+
-+			dwc3 at 10000000 {
-+				compatible = "snps,dwc3";
-+				reg = <0x10000000 0xcd00>;
-+				interrupts = <0 205 0x4>;
-+				phys = <&hs_phy_1>, <&ss_phy_1>;
-+				phy-names = "usb2-phy", "usb3-phy";
-+				dr_mode = "host";
-+			};
-+		};
- 	};
- 
- 	sfpb_mutex: sfpb-mutex {
diff --git a/target/linux/ipq806x/patches-4.4/110-DT-PCI-qcom-Document-PCIe-devicetree-bindings.patch b/target/linux/ipq806x/patches-4.4/110-DT-PCI-qcom-Document-PCIe-devicetree-bindings.patch
deleted file mode 100644
index 41f91fa..0000000
--- a/target/linux/ipq806x/patches-4.4/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 at mm-sol.com>
-X-Patchwork-Id: 6326181
-Message-Id: <1430743338-10441-4-git-send-email-svarbanov at mm-sol.com>
-To: Rob Herring <robh+dt at kernel.org>, Kumar Gala <galak at codeaurora.org>,
-	Mark Rutland <mark.rutland at arm.com>,
-	Grant Likely <grant.likely at linaro.org>,
-	Bjorn Helgaas <bhelgaas at google.com>,
-	Kishon Vijay Abraham I <kishon at ti.com>,
-	Russell King <linux at arm.linux.org.uk>, Arnd Bergmann <arnd at arndb.de>
-Cc: linux-arm-msm at vger.kernel.org, linux-kernel at vger.kernel.org,
-	linux-arm-kernel at lists.infradead.org, devicetree at vger.kernel.org,
-	linux-pci at vger.kernel.org, Mathieu Olivari <mathieu at codeaurora.org>,
-	Srinivas Kandagatla <srinivas.kandagatla at linaro.org>,
-	Stanimir Varbanov <svarbanov at mm-sol.com>
-Date: Mon,  4 May 2015 15:42:16 +0300
-
-Document Qualcomm PCIe driver devicetree bindings.
-
-Signed-off-by: Stanimir Varbanov <svarbanov at 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 at 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 at 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-4.4/111-PCI-qcom-Add-Qualcomm-PCIe-controller-driver.patch b/target/linux/ipq806x/patches-4.4/111-PCI-qcom-Add-Qualcomm-PCIe-controller-driver.patch
deleted file mode 100644
index b140787..0000000
--- a/target/linux/ipq806x/patches-4.4/111-PCI-qcom-Add-Qualcomm-PCIe-controller-driver.patch
+++ /dev/null
@@ -1,752 +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 at mm-sol.com>
-X-Patchwork-Id: 6326161
-Message-Id: <1430743338-10441-5-git-send-email-svarbanov at mm-sol.com>
-To: Rob Herring <robh+dt at kernel.org>, Kumar Gala <galak at codeaurora.org>,
-	Mark Rutland <mark.rutland at arm.com>,
-	Grant Likely <grant.likely at linaro.org>,
-	Bjorn Helgaas <bhelgaas at google.com>,
-	Kishon Vijay Abraham I <kishon at ti.com>,
-	Russell King <linux at arm.linux.org.uk>, Arnd Bergmann <arnd at arndb.de>
-Cc: linux-arm-msm at vger.kernel.org, linux-kernel at vger.kernel.org,
-	linux-arm-kernel at lists.infradead.org, devicetree at vger.kernel.org,
-	linux-pci at vger.kernel.org, Mathieu Olivari <mathieu at codeaurora.org>,
-	Srinivas Kandagatla <srinivas.kandagatla at linaro.org>,
-	Stanimir Varbanov <svarbanov at 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 at 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
-@@ -8248,6 +8248,13 @@ S:	Maintained
- F:	Documentation/devicetree/bindings/pci/hisilicon-pcie.txt
- F:	drivers/pci/host/pcie-hisi.c
- 
-+PCIE DRIVER FOR QUALCOMM MSM
-+M:     Stanimir Varbanov <svarbanov at mm-sol.com>
-+L:     linux-pci at vger.kernel.org
-+L:     linux-arm-msm at vger.kernel.org
-+S:     Maintained
-+F:     drivers/pci/host/*qcom*
-+
- PCMCIA SUBSYSTEM
- P:	Linux PCMCIA Team
- L:	linux-pcmcia at lists.infradead.org
---- a/drivers/pci/host/Kconfig
-+++ b/drivers/pci/host/Kconfig
-@@ -173,4 +173,13 @@ config PCI_HISI
- 	help
- 	  Say Y here if you want PCIe controller support on HiSilicon HIP05 SoC
- 
-+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,676 @@
-+/*
-+ * 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, 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", GPIOD_OUT_LOW);
-+	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 at 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
-@@ -20,3 +20,4 @@ obj-$(CONFIG_PCIE_IPROC_BCMA) += pcie-ip
- obj-$(CONFIG_PCIE_ALTERA) += pcie-altera.o
- obj-$(CONFIG_PCIE_ALTERA_MSI) += pcie-altera-msi.o
- obj-$(CONFIG_PCI_HISI) += pcie-hisi.o
-+obj-$(CONFIG_PCIE_QCOM) += pcie-qcom.o
diff --git a/target/linux/ipq806x/patches-4.4/112-ARM-dts-qcom-add-pcie-nodes-to-ipq806x-platforms.patch b/target/linux/ipq806x/patches-4.4/112-ARM-dts-qcom-add-pcie-nodes-to-ipq806x-platforms.patch
deleted file mode 100644
index 90631c6..0000000
--- a/target/linux/ipq806x/patches-4.4/112-ARM-dts-qcom-add-pcie-nodes-to-ipq806x-platforms.patch
+++ /dev/null
@@ -1,245 +0,0 @@
-From 5b40516b2f5fb9b2a7d6d3e2e924f12ec9d183a8 Mon Sep 17 00:00:00 2001
-From: Mathieu Olivari <mathieu at 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 at 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
-@@ -116,5 +116,15 @@
- 		usb30 at 1 {
- 			status = "ok";
- 		};
-+
-+		pcie0: pci at 1b500000 {
-+			status = "ok";
-+			phy-tx0-term-offset = <7>;
-+		};
-+
-+		pcie1: pci at 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 at 1 {
- 			status = "ok";
- 		};
-+
-+		pcie0: pci at 1b500000 {
-+			status = "ok";
-+		};
-+
-+		pcie1: pci at 1b700000 {
-+			status = "ok";
-+		};
-+
-+		pcie2: pci at 1b900000 {
-+			status = "ok";
-+		};
- 	};
- };
---- a/arch/arm/boot/dts/qcom-ipq8064.dtsi
-+++ b/arch/arm/boot/dts/qcom-ipq8064.dtsi
-@@ -4,6 +4,9 @@
- #include <dt-bindings/clock/qcom,gcc-ipq806x.h>
- #include <dt-bindings/clock/qcom,lcc-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";
-@@ -99,6 +102,34 @@
- 			interrupt-controller;
- 			#interrupt-cells = <2>;
- 			interrupts = <0 16 0x4>;
-+
-+			pcie0_pins: pcie0_pinmux {
-+				mux {
-+					pins = "gpio3";
-+					function = "pcie1_rst";
-+					drive-strength = <2>;
-+					bias-disable;
-+				};
-+			};
-+
-+			pcie1_pins: pcie1_pinmux {
-+				mux {
-+					pins = "gpio48";
-+					function = "pcie2_rst";
-+					drive-strength = <2>;
-+					bias-disable;
-+				};
-+			};
-+
-+			pcie2_pins: pcie2_pinmux {
-+				mux {
-+					pins = "gpio63";
-+					function = "pcie3_rst";
-+					drive-strength = <2>;
-+					bias-disable;
-+					output-low;
-+				};
-+			};
- 		};
- 
- 		intc: interrupt-controller at 2000000 {
-@@ -415,6 +446,144 @@
- 				dr_mode = "host";
- 			};
- 		};
-+
-+		pcie0: pci at 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-gpios = <&qcom_pinmux 3 GPIO_ACTIVE_LOW>;
-+
-+			status = "disabled";
-+		};
-+
-+		pcie1: pci at 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-gpios = <&qcom_pinmux 48 GPIO_ACTIVE_LOW>;
-+
-+			status = "disabled";
-+		};
-+
-+		pcie2: pci at 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-gpios = <&qcom_pinmux 63 GPIO_ACTIVE_LOW>;
-+
-+			status = "disabled";
-+		};
- 	};
- 
- 	sfpb_mutex: sfpb-mutex {
diff --git a/target/linux/ipq806x/patches-4.4/113-ARM-qcom-automatically-select-PCI_DOMAINS-if-PCI-is-.patch b/target/linux/ipq806x/patches-4.4/113-ARM-qcom-automatically-select-PCI_DOMAINS-if-PCI-is-.patch
deleted file mode 100644
index e2d3135..0000000
--- a/target/linux/ipq806x/patches-4.4/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 at 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 at 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
-@@ -5,6 +5,7 @@ menuconfig ARCH_QCOM
- 	select ARM_AMBA
- 	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-4.4/114-pcie-add-ctlr-init.patch b/target/linux/ipq806x/patches-4.4/114-pcie-add-ctlr-init.patch
deleted file mode 100644
index 6328113..0000000
--- a/target/linux/ipq806x/patches-4.4/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_base, pcie->dbi + PCIE20_PLR_IATU_LBAR);
-+	writel((pp->cfg0_base >> 32), pcie->dbi + PCIE20_PLR_IATU_UBAR);
-+	writel((pp->cfg0_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_base, pcie->dbi + PCIE20_PLR_IATU_LBAR);
-+	writel((pp->mem_base >> 32), pcie->dbi + PCIE20_PLR_IATU_UBAR);
-+	writel(pp->mem_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-4.4/115-add-pcie-aux-clk-dts.patch b/target/linux/ipq806x/patches-4.4/115-add-pcie-aux-clk-dts.patch
deleted file mode 100644
index 636a6c7..0000000
--- a/target/linux/ipq806x/patches-4.4/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
-@@ -475,15 +475,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";
-@@ -521,15 +527,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";
-@@ -567,15 +579,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-4.4/126-add-rpm-to-ipq8064-dts.patch b/target/linux/ipq806x/patches-4.4/126-add-rpm-to-ipq8064-dts.patch
deleted file mode 100644
index 6e589d2..0000000
--- a/target/linux/ipq806x/patches-4.4/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/clock/qcom,lcc-ipq806x.h>
- #include <dt-bindings/soc/qcom,gsbi.h>
- #include <dt-bindings/reset/qcom,gcc-ipq806x.h>
-@@ -93,6 +94,63 @@
- 			reg-names = "lpass-lpaif";
- 		};
- 
-+		rpm at 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 at 800000 {
- 			compatible = "qcom,ipq8064-pinctrl";
- 			reg = <0x800000 0x4000>;
-@@ -165,6 +223,12 @@
- 			reg = <0x02098000 0x1000>, <0x02008000 0x1000>;
- 		};
- 
-+		l2cc: clock-controller at 2011000 {
-+			compatible = "qcom,kpss-gcc", "syscon";
-+			reg = <0x2011000 0x1000>;
-+			clock-output-names = "acpu_l2_aux";
-+ 		};
-+
- 		saw0: regulator at 2089000 {
- 			compatible = "qcom,saw2";
- 			reg = <0x02089000 0x1000>, <0x02009000 0x1000>;
diff --git a/target/linux/ipq806x/patches-4.4/133-ARM-Add-Krait-L2-register-accessor-functions.patch b/target/linux/ipq806x/patches-4.4/133-ARM-Add-Krait-L2-register-accessor-functions.patch
deleted file mode 100644
index 36a92c8..0000000
--- a/target/linux/ipq806x/patches-4.4/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 at codeaurora.org>
-X-Patchwork-Id: 6063051
-Message-Id: <1426920332-9340-2-git-send-email-sboyd at codeaurora.org>
-To: Mike Turquette <mturquette at linaro.org>, Stephen Boyd <sboyd at codeaurora.org>
-Cc: linux-kernel at vger.kernel.org, linux-arm-msm at vger.kernel.org,
-	linux-pm at vger.kernel.org, linux-arm-kernel at lists.infradead.org,
-	Viresh Kumar <viresh.kumar at linaro.org>,
-	Mark Rutland <mark.rutland at arm.com>, Russell King <linux at arm.linux.org.uk>,
-	Courtney Cavin <courtney.cavin at 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 at arm.com>
-Cc: Russell King <linux at arm.linux.org.uk>
-Cc: Courtney Cavin <courtney.cavin at sonymobile.com>
-Signed-off-by: Stephen Boyd <sboyd at 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-4.4/134-clk-mux-Split-out-register-accessors-for-reuse.patch b/target/linux/ipq806x/patches-4.4/134-clk-mux-Split-out-register-accessors-for-reuse.patch
deleted file mode 100644
index 6efa5d8..0000000
--- a/target/linux/ipq806x/patches-4.4/134-clk-mux-Split-out-register-accessors-for-reuse.patch
+++ /dev/null
@@ -1,177 +0,0 @@
-From 4c28a15ea536281c8d619e5c6716ade914c79a6e Mon Sep 17 00:00:00 2001
-From: Stephen Boyd <sboyd at codeaurora.org>
-Date: Fri, 20 Mar 2015 23:45:21 -0700
-Subject: [PATCH 1/2] clk: mux: Split out register accessors for reuse
-
-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 at codeaurora.org>
-Signed-off-by: Ram Chandra Jangir <rjangi at codeaurora.org>
----
- drivers/clk/clk-mux.c        | 74 +++++++++++++++++++++++++++-----------------
- include/linux/clk-provider.h |  9 ++++--
- 2 files changed, 53 insertions(+), 30 deletions(-)
-
---- a/drivers/clk/clk-mux.c
-+++ b/drivers/clk/clk-mux.c
-@@ -28,35 +28,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_hw_get_num_parents(hw);
--	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)
-@@ -64,24 +53,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;
- 
--	else {
--		if (mux->flags & CLK_MUX_INDEX_BIT)
--			index = 1 << index;
-+	return clk_mux_get_parent(hw, val, mux->table, mux->flags);
-+}
-+
-+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);
- 	else
-@@ -105,7 +123,7 @@ 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,
- };
-@@ -120,7 +138,7 @@ struct clk *clk_register_mux_table(struc
- 		const char * const *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
-@@ -433,7 +433,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;
-@@ -449,6 +449,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 * const *parent_names, u8 num_parents,
- 		unsigned long flags,
-@@ -459,7 +464,7 @@ struct clk *clk_register_mux_table(struc
- 		const char * const *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-4.4/135-clk-Avoid-sending-high-rates-to-downstream-clocks-du.patch b/target/linux/ipq806x/patches-4.4/135-clk-Avoid-sending-high-rates-to-downstream-clocks-du.patch
deleted file mode 100644
index 5015d32..0000000
--- a/target/linux/ipq806x/patches-4.4/135-clk-Avoid-sending-high-rates-to-downstream-clocks-du.patch
+++ /dev/null
@@ -1,122 +0,0 @@
-From 39d42ce5031d2a4f92fa203b87acfbab340b15a2 Mon Sep 17 00:00:00 2001
-From: Stephen Boyd <sboyd at codeaurora.org>
-Date: Fri, 20 Mar 2015 23:45:22 -0700
-Subject: [PATCH 2/2] clk: Avoid sending high rates to downstream clocks during
- set_rate
-
-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 at codeaurora.org>
-Signed-off-by: Ram Chandra Jangir <rjangi at codeaurora.org>
----
- drivers/clk/clk.c | 34 ++++++++++++++++++++++------------
- 1 file changed, 22 insertions(+), 12 deletions(-)
-
---- a/drivers/clk/clk.c
-+++ b/drivers/clk/clk.c
-@@ -1427,21 +1427,24 @@ static struct clk_core *clk_propagate_ra
-  * walk down a subtree and set the new rates notifying the rate
-  * change on the way
-  */
--static void clk_change_rate(struct clk_core *core)
-+static void
-+clk_change_rate(struct clk_core *core, unsigned long best_parent_rate)
- {
- 	struct clk_core *child;
- 	struct hlist_node *tmp;
- 	unsigned long old_rate;
--	unsigned long best_parent_rate = 0;
- 	bool skip_set_rate = false;
- 	struct clk_core *old_parent;
- 
--	old_rate = core->rate;
-+	hlist_for_each_entry(child, &core->children, child_node) {
-+		/* Skip children who will be reparented to another clock */
-+		if (child->new_parent && child->new_parent != core)
-+			continue;
-+		if (child->new_rate > child->rate)
-+			clk_change_rate(child, core->new_rate);
-+	}
- 
--	if (core->new_parent)
--		best_parent_rate = core->new_parent->rate;
--	else if (core->parent)
--		best_parent_rate = core->parent->rate;
-+	old_rate = core->rate;
- 
- 	if (core->new_parent && core->new_parent != core->parent) {
- 		old_parent = __clk_set_parent_before(core, core->new_parent);
-@@ -1467,7 +1470,7 @@ static void clk_change_rate(struct clk_c
- 
- 	trace_clk_set_rate_complete(core, core->new_rate);
- 
--	core->rate = clk_recalc(core, best_parent_rate);
-+	core->rate = core->new_rate;
- 
- 	if (core->notifier_count && old_rate != core->rate)
- 		__clk_notify(core, POST_RATE_CHANGE, old_rate, core->rate);
-@@ -1483,12 +1486,13 @@ static void clk_change_rate(struct clk_c
- 		/* Skip children who will be reparented to another clock */
- 		if (child->new_parent && child->new_parent != core)
- 			continue;
--		clk_change_rate(child);
-+		if (child->new_rate != child->rate)
-+			clk_change_rate(child, core->new_rate);
- 	}
- 
- 	/* handle the new child who might not be in core->children yet */
--	if (core->new_child)
--		clk_change_rate(core->new_child);
-+	if (core->new_child && core->new_child->new_rate != core->new_child->rate)
-+		clk_change_rate(core->new_child, core->new_rate);
- }
- 
- static int clk_core_set_rate_nolock(struct clk_core *core,
-@@ -1497,6 +1501,7 @@ static int clk_core_set_rate_nolock(stru
- 	struct clk_core *top, *fail_clk;
- 	unsigned long rate = req_rate;
- 	int ret = 0;
-+	unsigned long parent_rate;
- 
- 	if (!core)
- 		return 0;
-@@ -1522,8 +1527,13 @@ static int clk_core_set_rate_nolock(stru
- 		return -EBUSY;
- 	}
- 
-+	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);
- 
- 	core->req_rate = req_rate;
- 
diff --git a/target/linux/ipq806x/patches-4.4/136-clk-Add-safe-switch-hook.patch b/target/linux/ipq806x/patches-4.4/136-clk-Add-safe-switch-hook.patch
deleted file mode 100644
index de3ac7d..0000000
--- a/target/linux/ipq806x/patches-4.4/136-clk-Add-safe-switch-hook.patch
+++ /dev/null
@@ -1,151 +0,0 @@
-From f7a00ea959be31f9b742042294a359d508edce94 Mon Sep 17 00:00:00 2001
-From: Stephen Boyd <sboyd at codeaurora.org>
-Date: Fri, 20 Mar 2015 23:45:23 -0700
-Subject: [PATCH] clk: Add safe switch hook
-
-Sometimes clocks can't accept their parent source turning off
-while the source is reprogrammed to a different rate. Most
-notably CPU clocks require a way to switch away from the current
-PLL they're running on, reprogram that PLL to a new rate, and
-then switch back to the PLL with the new rate once they're done.
-Add a hook that drivers can implement allowing them to return a
-'safe parent' that they can switch their parent to while the
-upstream source is reprogrammed to support this.
-
-Signed-off-by: Stephen Boyd <sboyd at codeaurora.org>
-Signed-off-by: Ram Chandra Jangir <rjangi at codeaurora.org>
----
- 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
-@@ -51,9 +51,12 @@ struct clk_core {
- 	struct clk_core		**parents;
- 	u8			num_parents;
- 	u8			new_parent_index;
-+	u8                      safe_parent_index;
- 	unsigned long		rate;
- 	unsigned long		req_rate;
-+	unsigned long           old_rate;
- 	unsigned long		new_rate;
-+	struct clk_core         *safe_parent;
- 	struct clk_core		*new_parent;
- 	struct clk_core		*new_child;
- 	unsigned long		flags;
-@@ -1271,7 +1274,8 @@ out:
- static void clk_calc_subtree(struct clk_core *core, unsigned long new_rate,
- 			     struct clk_core *new_parent, u8 p_index)
- {
--	struct clk_core *child;
-+	struct clk_core *child, *parent;
-+	struct clk_hw *parent_hw;
- 
- 	core->new_rate = new_rate;
- 	core->new_parent = new_parent;
-@@ -1281,6 +1285,18 @@ static void clk_calc_subtree(struct clk_
- 	if (new_parent && new_parent != core->parent)
- 		new_parent->new_child = core;
- 
-+	if (core->ops->get_safe_parent) {
-+		parent_hw = core->ops->get_safe_parent(core->hw);
-+		if (parent_hw) {
-+			parent = parent_hw->core;
-+			p_index = clk_fetch_parent_index(core, parent);
-+			core->safe_parent_index = p_index;
-+			core->safe_parent = parent;
-+		}
-+	} else {
-+		core->safe_parent = NULL;
-+	}
-+
- 	hlist_for_each_entry(child, &core->children, child_node) {
- 		child->new_rate = clk_recalc(child, new_rate);
- 		clk_calc_subtree(child, child->new_rate, NULL, 0);
-@@ -1393,14 +1409,43 @@ static struct clk_core *clk_propagate_ra
- 						  unsigned long event)
- {
- 	struct clk_core *child, *tmp_clk, *fail_clk = NULL;
-+	struct clk_core *old_parent;
- 	int ret = NOTIFY_DONE;
- 
--	if (core->rate == core->new_rate)
-+	if (core->rate == core->new_rate && event != POST_RATE_CHANGE)
- 		return NULL;
- 
-+	switch (event) {
-+	case PRE_RATE_CHANGE:
-+		if (core->safe_parent)
-+			core->ops->set_parent(core->hw, core->safe_parent_index);
-+		core->old_rate = core->rate;
-+		break;
-+	case POST_RATE_CHANGE:
-+		if (core->safe_parent) {
-+			old_parent = __clk_set_parent_before(core,
-+							    core->new_parent);
-+			if (core->ops->set_rate_and_parent) {
-+				core->ops->set_rate_and_parent(core->hw,
-+						core->new_rate,
-+						core->new_parent ?
-+						core->new_parent->rate : 0,
-+						core->new_parent_index);
-+			} else if (core->ops->set_parent) {
-+				core->ops->set_parent(core->hw,
-+						core->new_parent_index);
-+			}
-+			__clk_set_parent_after(core, core->new_parent,
-+						old_parent);
-+		}
-+		break;
-+	}
-+
- 	if (core->notifier_count) {
--		ret = __clk_notify(core, event, core->rate, core->new_rate);
--		if (ret & NOTIFY_STOP_MASK)
-+		if (event != POST_RATE_CHANGE || core->old_rate != core->rate)
-+			ret = __clk_notify(core, event, core->old_rate,
-+					   core->new_rate);
-+		if (ret & NOTIFY_STOP_MASK && event != POST_RATE_CHANGE)
- 			fail_clk = core;
- 	}
- 
-@@ -1446,7 +1491,8 @@ clk_change_rate(struct clk_core *core, u
- 
- 	old_rate = core->rate;
- 
--	if (core->new_parent && core->new_parent != core->parent) {
-+	if (core->new_parent && core->new_parent != core->parent &&
-+			!core->safe_parent) {
- 		old_parent = __clk_set_parent_before(core, core->new_parent);
- 		trace_clk_set_parent(core, core->new_parent);
- 
-@@ -1472,9 +1518,6 @@ clk_change_rate(struct clk_core *core, u
- 
- 	core->rate = core->new_rate;
- 
--	if (core->notifier_count && old_rate != core->rate)
--		__clk_notify(core, POST_RATE_CHANGE, old_rate, core->rate);
--
- 	if (core->flags & CLK_RECALC_NEW_RATES)
- 		(void)clk_calc_new_rates(core, core->new_rate);
- 
-@@ -1537,6 +1580,8 @@ static int clk_core_set_rate_nolock(stru
- 
- 	core->req_rate = req_rate;
- 
-+	clk_propagate_rate_change(top, POST_RATE_CHANGE);
-+
- 	return ret;
- }
- 
---- a/include/linux/clk-provider.h
-+++ b/include/linux/clk-provider.h
-@@ -202,6 +202,7 @@ struct clk_ops {
- 					  struct clk_rate_request *req);
- 	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,
diff --git a/target/linux/ipq806x/patches-4.4/137-clk-qcom-Add-support-for-High-Frequency-PLLs-HFPLLs.patch b/target/linux/ipq806x/patches-4.4/137-clk-qcom-Add-support-for-High-Frequency-PLLs-HFPLLs.patch
deleted file mode 100644
index 7e96449..0000000
--- a/target/linux/ipq806x/patches-4.4/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 at codeaurora.org>
-X-Patchwork-Id: 6063261
-Message-Id: <1426920332-9340-6-git-send-email-sboyd at codeaurora.org>
-To: Mike Turquette <mturquette at linaro.org>, Stephen Boyd <sboyd at codeaurora.org>
-Cc: linux-kernel at vger.kernel.org, linux-arm-msm at vger.kernel.org,
-	linux-pm at vger.kernel.org, linux-arm-kernel at lists.infradead.org,
-	Viresh Kumar <viresh.kumar at 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 at 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
-@@ -8,6 +8,7 @@ clk-qcom-y += clk-rcg2.o
- clk-qcom-y += clk-branch.o
- clk-qcom-y += clk-regmap-divider.o
- clk-qcom-y += clk-regmap-mux.o
-+clk-qcom-y += clk-hfpll.o
- clk-qcom-y += reset.o
- clk-qcom-$(CONFIG_QCOM_GDSC) += gdsc.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_hw_get_rate(hw);
-+
-+		/* 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-4.4/138-clk-qcom-Add-HFPLL-driver.patch b/target/linux/ipq806x/patches-4.4/138-clk-qcom-Add-HFPLL-driver.patch
deleted file mode 100644
index 8362320..0000000
--- a/target/linux/ipq806x/patches-4.4/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 at codeaurora.org>
-X-Patchwork-Id: 6063231
-Message-Id: <1426920332-9340-7-git-send-email-sboyd at codeaurora.org>
-To: Mike Turquette <mturquette at linaro.org>, Stephen Boyd <sboyd at codeaurora.org>
-Cc: linux-kernel at vger.kernel.org, linux-arm-msm at vger.kernel.org,
-	linux-pm at vger.kernel.org, linux-arm-kernel at lists.infradead.org,
-	Viresh Kumar <viresh.kumar at linaro.org>, <devicetree at 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 at vger.kernel.org>
-Signed-off-by: Stephen Boyd <sboyd at 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 at 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 at f908a000 {
-+		compatible = "qcom,hfpll";
-+		reg = <0xf908a000 0x30>, <0xf900a000 0x30>;
-+		clock-output-names = "hfpll0";
-+	};
---- a/drivers/clk/qcom/Kconfig
-+++ b/drivers/clk/qcom/Kconfig
-@@ -135,3 +135,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
-@@ -25,3 +25,4 @@ obj-$(CONFIG_MSM_MMCC_8960) += mmcc-msm8
- obj-$(CONFIG_MSM_MMCC_8974) += mmcc-msm8974.o
- obj-$(CONFIG_QCOM_CLK_SMD_RPM) += clk-smd-rpm.o
- obj-$(CONFIG_QCOM_CLK_RPM) += clk-rpm.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-4.4/139-clk-qcom-Add-IPQ806X-s-HFPLLs.patch b/target/linux/ipq806x/patches-4.4/139-clk-qcom-Add-IPQ806X-s-HFPLLs.patch
deleted file mode 100644
index a01decf..0000000
--- a/target/linux/ipq806x/patches-4.4/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 at codeaurora.org>
-X-Patchwork-Id: 6063241
-Message-Id: <1426920332-9340-9-git-send-email-sboyd at codeaurora.org>
-To: Mike Turquette <mturquette at linaro.org>, Stephen Boyd <sboyd at codeaurora.org>
-Cc: linux-kernel at vger.kernel.org, linux-arm-msm at vger.kernel.org,
-	linux-pm at vger.kernel.org, linux-arm-kernel at lists.infradead.org,
-	Viresh Kumar <viresh.kumar at linaro.org>
-Date: Fri, 20 Mar 2015 23:45:27 -0700
-
-Describe the HFPLLs present on IPQ806X devices.
-
-Signed-off-by: Stephen Boyd <sboyd at 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 = {
-@@ -113,6 +114,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,
-@@ -2837,6 +2917,9 @@ static struct clk_regmap *gcc_ipq806x_cl
- 	[UBI32_CORE2_CLK_SRC] = &ubi32_core2_src_clk.clkr,
- 	[NSSTCM_CLK_SRC] = &nss_tcm_src.clkr,
- 	[NSSTCM_CLK] = &nss_tcm_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-4.4/140-clk-qcom-Add-support-for-Krait-clocks.patch b/target/linux/ipq806x/patches-4.4/140-clk-qcom-Add-support-for-Krait-clocks.patch
deleted file mode 100644
index bbfcab9..0000000
--- a/target/linux/ipq806x/patches-4.4/140-clk-qcom-Add-support-for-Krait-clocks.patch
+++ /dev/null
@@ -1,272 +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 at codeaurora.org>
-X-Patchwork-Id: 6063251
-Message-Id: <1426920332-9340-10-git-send-email-sboyd at codeaurora.org>
-To: Mike Turquette <mturquette at linaro.org>, Stephen Boyd <sboyd at codeaurora.org>
-Cc: linux-kernel at vger.kernel.org, linux-arm-msm at vger.kernel.org,
-	linux-pm at vger.kernel.org, linux-arm-kernel at lists.infradead.org,
-	Viresh Kumar <viresh.kumar at 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 at 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
-@@ -143,3 +143,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
-@@ -8,6 +8,7 @@ clk-qcom-y += clk-rcg2.o
- clk-qcom-y += clk-branch.o
- clk-qcom-y += clk-regmap-divider.o
- clk-qcom-y += clk-regmap-mux.o
-+clk-qcom-$(CONFIG_KRAIT_CLOCKS) += clk-krait.o
- clk-qcom-y += clk-hfpll.o
- clk-qcom-y += reset.o
- clk-qcom-$(CONFIG_QCOM_GDSC) += gdsc.o
---- /dev/null
-+++ b/drivers/clk/qcom/clk-krait.c
-@@ -0,0 +1,167 @@
-+/*
-+ * 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,
-+						unsigned long *safe_freq)
-+{
-+	int i;
-+	struct krait_mux_clk *mux = to_krait_mux_clk(hw);
-+	int num_parents = clk_hw_get_num_parents(hw);
-+
-+	i = mux->safe_sel;
-+	for (i = 0; i < num_parents; i++)
-+		if (mux->safe_sel == mux->parent_map[i])
-+			break;
-+
-+	return clk_hw_get_parent_by_index(hw, 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_hw_round_rate(clk_hw_get_parent(hw), 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-4.4/141-clk-qcom-Add-KPSS-ACC-GCC-driver.patch b/target/linux/ipq806x/patches-4.4/141-clk-qcom-Add-KPSS-ACC-GCC-driver.patch
deleted file mode 100644
index 56374c5..0000000
--- a/target/linux/ipq806x/patches-4.4/141-clk-qcom-Add-KPSS-ACC-GCC-driver.patch
+++ /dev/null
@@ -1,207 +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 at codeaurora.org>
-X-Patchwork-Id: 6063201
-Message-Id: <1426920332-9340-11-git-send-email-sboyd at codeaurora.org>
-To: Mike Turquette <mturquette at linaro.org>, Stephen Boyd <sboyd at codeaurora.org>
-Cc: linux-kernel at vger.kernel.org, linux-arm-msm at vger.kernel.org,
-	linux-pm at vger.kernel.org, linux-arm-kernel at lists.infradead.org,
-	Viresh Kumar <viresh.kumar at linaro.org>, <devicetree at 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 at vger.kernel.org>
-Signed-off-by: Stephen Boyd <sboyd at 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 at 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 at 2011000 {
-+		compatible = "qcom,kpss-gcc";
-+		reg = <0x2011000 0x1000>;
-+		clock-output-names = "acpu_l2_aux";
-+	};
---- a/drivers/clk/qcom/Kconfig
-+++ b/drivers/clk/qcom/Kconfig
-@@ -144,6 +144,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
-@@ -9,6 +9,7 @@ clk-qcom-y += clk-branch.o
- clk-qcom-y += clk-regmap-divider.o
- clk-qcom-y += clk-regmap-mux.o
- clk-qcom-$(CONFIG_KRAIT_CLOCKS) += clk-krait.o
-+obj-$(CONFIG_KPSS_XCC) += kpss-xcc.o
- clk-qcom-y += clk-hfpll.o
- clk-qcom-y += reset.o
- clk-qcom-$(CONFIG_QCOM_GDSC) += gdsc.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-4.4/142-clk-qcom-Add-Krait-clock-controller-driver.patch b/target/linux/ipq806x/patches-4.4/142-clk-qcom-Add-Krait-clock-controller-driver.patch
deleted file mode 100644
index bd4e7bc..0000000
--- a/target/linux/ipq806x/patches-4.4/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 at codeaurora.org>
-X-Patchwork-Id: 6063121
-Message-Id: <1426920332-9340-12-git-send-email-sboyd at codeaurora.org>
-To: Mike Turquette <mturquette at linaro.org>, Stephen Boyd <sboyd at codeaurora.org>
-Cc: linux-kernel at vger.kernel.org, linux-arm-msm at vger.kernel.org,
-	linux-pm at vger.kernel.org, linux-arm-kernel at lists.infradead.org,
-	Viresh Kumar <viresh.kumar at linaro.org>, <devicetree at 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 at vger.kernel.org>
-Signed-off-by: Stephen Boyd <sboyd at 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
-@@ -152,6 +152,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
-@@ -28,3 +28,4 @@ obj-$(CONFIG_MSM_MMCC_8974) += mmcc-msm8
- obj-$(CONFIG_QCOM_CLK_SMD_RPM) += clk-smd-rpm.o
- obj-$(CONFIG_QCOM_CLK_RPM) += clk-rpm.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-4.4/143-cpufreq-Add-module-to-register-cpufreq-on-Krait-CPUs.patch b/target/linux/ipq806x/patches-4.4/143-cpufreq-Add-module-to-register-cpufreq-on-Krait-CPUs.patch
deleted file mode 100644
index e8d8ddf..0000000
--- a/target/linux/ipq806x/patches-4.4/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 at codeaurora.org>
-X-Patchwork-Id: 6063191
-Message-Id: <1426920332-9340-13-git-send-email-sboyd at codeaurora.org>
-To: Mike Turquette <mturquette at linaro.org>, Stephen Boyd <sboyd at codeaurora.org>
-Cc: linux-kernel at vger.kernel.org, linux-arm-msm at vger.kernel.org,
-	linux-pm at vger.kernel.org, linux-arm-kernel at lists.infradead.org,
-	Viresh Kumar <viresh.kumar at linaro.org>, <devicetree at 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 at vger.kernel.org>
-Signed-off-by: Stephen Boyd <sboyd at 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
-@@ -95,6 +95,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
-@@ -61,6 +61,7 @@ obj-$(CONFIG_ARM_MT8173_CPUFREQ)	+= mt81
- obj-$(CONFIG_ARM_OMAP2PLUS_CPUFREQ)	+= omap-cpufreq.o
- obj-$(CONFIG_ARM_PXA2xx_CPUFREQ)	+= 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-4.4/144-ARM-dts-qcom-Add-necessary-DT-data-for-Krait-cpufreq.patch b/target/linux/ipq806x/patches-4.4/144-ARM-dts-qcom-Add-necessary-DT-data-for-Krait-cpufreq.patch
deleted file mode 100644
index 45870c4..0000000
--- a/target/linux/ipq806x/patches-4.4/144-ARM-dts-qcom-Add-necessary-DT-data-for-Krait-cpufreq.patch
+++ /dev/null
@@ -1,96 +0,0 @@
---- a/arch/arm/boot/dts/qcom-ipq8064.dtsi
-+++ b/arch/arm/boot/dts/qcom-ipq8064.dtsi
-@@ -26,6 +26,11 @@
- 			next-level-cache = <&L2>;
- 			qcom,acc = <&acc0>;
- 			qcom,saw = <&saw0>;
-+			clocks = <&kraitcc 0>, <&kraitcc 4>;
-+			clock-names = "cpu", "l2";
-+			clock-latency = <100000>;
-+			cpu-supply = <&smb208_s2a>;
-+			voltage-tolerance = <5>;
- 		};
- 
- 		cpu at 1 {
-@@ -36,12 +41,20 @@
- 			next-level-cache = <&L2>;
- 			qcom,acc = <&acc1>;
- 			qcom,saw = <&saw1>;
-+			clocks = <&kraitcc 1>, <&kraitcc 4>;
-+			clock-names = "cpu", "l2";
-+			clock-latency = <100000>;
-+			cpu-supply = <&smb208_s2b>;
- 		};
- 
- 		L2: l2-cache {
- 			compatible = "cache";
- 			cache-level = <2>;
- 		};
-+
-+		qcom,l2 {
-+			qcom,l2-rates = <384000000 1000000000 1200000000>;
-+		};
- 	};
- 
- 	cpu-pmu {
-@@ -73,6 +86,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>;
-@@ -216,11 +269,13 @@
- 		acc0: clock-controller at 2088000 {
- 			compatible = "qcom,kpss-acc-v1";
- 			reg = <0x02088000 0x1000>, <0x02008000 0x1000>;
-+			clock-output-names = "acpu0_aux";
- 		};
- 
- 		acc1: clock-controller at 2098000 {
- 			compatible = "qcom,kpss-acc-v1";
- 			reg = <0x02098000 0x1000>, <0x02008000 0x1000>;
-+			clock-output-names = "acpu1_aux";
- 		};
- 
- 		l2cc: clock-controller at 2011000 {
diff --git a/target/linux/ipq806x/patches-4.4/155-dt-bindings-qcom_adm-Fix-channel-specifiers.patch b/target/linux/ipq806x/patches-4.4/155-dt-bindings-qcom_adm-Fix-channel-specifiers.patch
deleted file mode 100644
index 4f5c0ef..0000000
--- a/target/linux/ipq806x/patches-4.4/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 at codeaurora.org>
-X-Patchwork-Id: 6027361
-Message-Id: <1426571172-9711-2-git-send-email-agross at codeaurora.org>
-To: Vinod Koul <vinod.koul at intel.com>
-Cc: devicetree at vger.kernel.org, dmaengine at vger.kernel.org,
-	linux-arm-msm at vger.kernel.org, linux-kernel at vger.kernel.org,
-	linux-arm-kernel at lists.infradead.org, Kumar Gala <galak at codeaurora.org>,
-	Bjorn Andersson <bjorn.andersson at sonymobile.com>,
-	Andy Gross <agross at 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 at 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-4.4/156-dmaengine-Add-ADM-driver.patch b/target/linux/ipq806x/patches-4.4/156-dmaengine-Add-ADM-driver.patch
deleted file mode 100644
index 02038aa..0000000
--- a/target/linux/ipq806x/patches-4.4/156-dmaengine-Add-ADM-driver.patch
+++ /dev/null
@@ -1,964 +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 at codeaurora.org>
-X-Patchwork-Id: 6027351
-Message-Id: <1426571172-9711-3-git-send-email-agross at codeaurora.org>
-To: Vinod Koul <vinod.koul at intel.com>
-Cc: devicetree at vger.kernel.org, dmaengine at vger.kernel.org,
-	linux-arm-msm at vger.kernel.org, linux-kernel at vger.kernel.org,
-	linux-arm-kernel at lists.infradead.org, Kumar Gala <galak at codeaurora.org>,
-	Bjorn Andersson <bjorn.andersson at sonymobile.com>,
-	Andy Gross <agross at 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 at codeaurora.org>
-Reviewed-by: sricharan <sricharan at 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
-@@ -558,4 +558,14 @@ config DMATEST
- config DMA_ENGINE_RAID
- 	bool
- 
-+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,900 @@
-+/*
-+ * 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.directions = BIT(DMA_DEV_TO_MEM | DMA_MEM_TO_DEV);
-+	adev->common.residue_granularity = DMA_RESIDUE_GRANULARITY_DESCRIPTOR;
-+	adev->common.src_addr_widths = DMA_SLAVE_BUSWIDTH_4_BYTES;
-+	adev->common.dst_addr_widths = DMA_SLAVE_BUSWIDTH_4_BYTES;
-+	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 at codeaurora.org>");
-+MODULE_DESCRIPTION("QCOM ADM DMA engine driver");
-+MODULE_LICENSE("GPL v2");
---- a/drivers/dma/Makefile
-+++ b/drivers/dma/Makefile
-@@ -65,5 +65,6 @@ obj-$(CONFIG_TI_DMA_CROSSBAR) += ti-dma-
- obj-$(CONFIG_TI_EDMA) += edma.o
- obj-$(CONFIG_XGENE_DMA) += xgene-dma.o
- obj-$(CONFIG_ZX_DMA) += zx296702_dma.o
-+obj-$(CONFIG_QCOM_ADM) += qcom_adm.o
- 
- obj-y += xilinx/
diff --git a/target/linux/ipq806x/patches-4.4/157-ARM-DT-ipq8064-Add-ADM-device-node.patch b/target/linux/ipq806x/patches-4.4/157-ARM-DT-ipq8064-Add-ADM-device-node.patch
deleted file mode 100644
index 5383041..0000000
--- a/target/linux/ipq806x/patches-4.4/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 at 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 at 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
-@@ -721,6 +721,26 @@
- 
- 			status = "disabled";
- 		};
-+
-+		adm_dma: dma at 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-4.4/161-mtd-nand-Create-a-BBT-flag-to-access-bad-block-markers-in-raw-mode.patch b/target/linux/ipq806x/patches-4.4/161-mtd-nand-Create-a-BBT-flag-to-access-bad-block-markers-in-raw-mode.patch
deleted file mode 100644
index 154649d..0000000
--- a/target/linux/ipq806x/patches-4.4/161-mtd-nand-Create-a-BBT-flag-to-access-bad-block-markers-in-raw-mode.patch
+++ /dev/null
@@ -1,83 +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 at codeaurora.org>
-X-Patchwork-Id: 6927081
-Message-Id: <1438578498-32254-2-git-send-email-architt at codeaurora.org>
-To: linux-mtd at lists.infradead.org, dehrenberg at google.com,
-	cernekee at gmail.com, computersforpeace at gmail.com
-Cc: linux-arm-msm at vger.kernel.org, agross at codeaurora.org,
-	sboyd at codeaurora.org, linux-kernel at vger.kernel.org,
-	Archit Taneja <architt at 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 at codeaurora.org>
-Signed-off-by: Archit Taneja <architt at 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
-@@ -394,7 +394,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
-@@ -420,7 +420,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,12 @@ 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-4.4/162-mtd-nand-Qualcomm-NAND-controller-driver.patch b/target/linux/ipq806x/patches-4.4/162-mtd-nand-Qualcomm-NAND-controller-driver.patch
deleted file mode 100644
index 84ff6e7..0000000
--- a/target/linux/ipq806x/patches-4.4/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 at codeaurora.org>
-X-Patchwork-Id: 6927101
-Message-Id: <1438578498-32254-3-git-send-email-architt at codeaurora.org>
-To: linux-mtd at lists.infradead.org, dehrenberg at google.com,
-	cernekee at gmail.com, computersforpeace at gmail.com
-Cc: linux-arm-msm at vger.kernel.org, agross at codeaurora.org,
-	sboyd at codeaurora.org, linux-kernel at vger.kernel.org,
-	Archit Taneja <architt at 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 at codeaurora.org>
-Signed-off-by: Archit Taneja <architt at 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
-@@ -546,4 +546,11 @@ config MTD_NAND_HISI504
- 	help
- 	  Enables support for NAND controller on Hisilicon SoC Hip04.
- 
-+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 at codeaurora.org>");
-+MODULE_DESCRIPTION("Qualcomm NAND Controller driver");
-+MODULE_LICENSE("GPL v2");
---- a/drivers/mtd/nand/Makefile
-+++ b/drivers/mtd/nand/Makefile
-@@ -55,5 +55,6 @@ obj-$(CONFIG_MTD_NAND_BCM47XXNFLASH)	+=
- obj-$(CONFIG_MTD_NAND_SUNXI)		+= sunxi_nand.o
- obj-$(CONFIG_MTD_NAND_HISI504)	        += hisi504_nand.o
- obj-$(CONFIG_MTD_NAND_BRCMNAND)		+= brcmnand/
-+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-4.4/163-dt-bindings-qcom_nandc-Add-DT-bindings.patch b/target/linux/ipq806x/patches-4.4/163-dt-bindings-qcom_nandc-Add-DT-bindings.patch
deleted file mode 100644
index 6530eb1..0000000
--- a/target/linux/ipq806x/patches-4.4/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 at codeaurora.org>
-X-Patchwork-Id: 6927141
-Message-Id: <1438578498-32254-4-git-send-email-architt at codeaurora.org>
-To: linux-mtd at lists.infradead.org, dehrenberg at google.com,
-	cernekee at gmail.com, computersforpeace at gmail.com
-Cc: linux-arm-msm at vger.kernel.org, agross at codeaurora.org,
-	sboyd at codeaurora.org, linux-kernel at vger.kernel.org,
-	Archit Taneja <architt at codeaurora.org>, devicetree at vger.kernel.org
-Date: Mon,  3 Aug 2015 10:38:16 +0530
-
-Add DT bindings document for the Qualcomm NAND controller driver.
-
-Cc: devicetree at 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 at codeaurora.org>
-Signed-off-by: Archit Taneja <architt at 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 at 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 at 0 {
-+	...
-+	};
-+};
diff --git a/target/linux/ipq806x/patches-4.4/164-arm-qcom-dts-Add-NAND-controller-node-for-ipq806x.patch b/target/linux/ipq806x/patches-4.4/164-arm-qcom-dts-Add-NAND-controller-node-for-ipq806x.patch
deleted file mode 100644
index 664e7b5..0000000
--- a/target/linux/ipq806x/patches-4.4/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 at codeaurora.org>
-X-Patchwork-Id: 6927121
-Message-Id: <1438578498-32254-5-git-send-email-architt at codeaurora.org>
-To: linux-mtd at lists.infradead.org, dehrenberg at google.com,
-	cernekee at gmail.com, computersforpeace at gmail.com
-Cc: linux-arm-msm at vger.kernel.org, agross at codeaurora.org,
-	sboyd at codeaurora.org, linux-kernel at vger.kernel.org,
-	Archit Taneja <architt at codeaurora.org>, devicetree at 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 at vger.kernel.org
-
-Reviewed-by: Andy Gross <agross at codeaurora.org>
-Signed-off-by: Archit Taneja <architt at 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
-@@ -741,6 +741,22 @@
- 
- 			status = "disabled";
- 		};
-+
-+		nand at 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-4.4/165-arm-qcom-dts-Enable-NAND-node-on-IPQ8064-AP148-platform.patch b/target/linux/ipq806x/patches-4.4/165-arm-qcom-dts-Enable-NAND-node-on-IPQ8064-AP148-platform.patch
deleted file mode 100644
index 9de3d8f..0000000
--- a/target/linux/ipq806x/patches-4.4/165-arm-qcom-dts-Enable-NAND-node-on-IPQ8064-AP148-platform.patch
+++ /dev/null
@@ -1,76 +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 at codeaurora.org>
-X-Patchwork-Id: 6927091
-Message-Id: <1438578498-32254-6-git-send-email-architt at codeaurora.org>
-To: linux-mtd at lists.infradead.org, dehrenberg at google.com,
-	cernekee at gmail.com, computersforpeace at gmail.com
-Cc: linux-arm-msm at vger.kernel.org, agross at codeaurora.org,
-	sboyd at codeaurora.org, linux-kernel at vger.kernel.org,
-	Archit Taneja <architt at codeaurora.org>, devicetree at 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 at vger.kernel.org
-
-Signed-off-by: Archit Taneja <architt at 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,28 @@
- 					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 at 16300000 {
-@@ -126,5 +148,19 @@
- 			status = "ok";
- 			phy-tx0-term-offset = <7>;
- 		};
-+
-+		nand at 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-4.4/166-arch-qcom-dts-enable-qcom-smem-on-AP148-NAND.patch b/target/linux/ipq806x/patches-4.4/166-arch-qcom-dts-enable-qcom-smem-on-AP148-NAND.patch
deleted file mode 100644
index 7060282..0000000
--- a/target/linux/ipq806x/patches-4.4/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
-@@ -157,6 +157,8 @@
- 
- 			nand-ecc-strength = <4>;
- 			nand-bus-width = <8>;
-+
-+			linux,part-probe = "qcom-smem";
- 		};
- 	};
- };
diff --git a/target/linux/ipq806x/patches-4.4/167-ARM-qcom_rpm_fix_support_for_smb208.patch b/target/linux/ipq806x/patches-4.4/167-ARM-qcom_rpm_fix_support_for_smb208.patch
deleted file mode 100644
index 8da7034..0000000
--- a/target/linux/ipq806x/patches-4.4/167-ARM-qcom_rpm_fix_support_for_smb208.patch
+++ /dev/null
@@ -1,50 +0,0 @@
-
-In commit "regulator: qcom: Rework to single platform device" the smb208 regulator
-used in IPQ8064 was left out.
-
-Add it to that new framework and update Docs accordingly.
-
-Signed-off-by: Adrian Panella <ianchi74 at outlook.com>
-
---- a/Documentation/devicetree/bindings/mfd/qcom-rpm.txt
-+++ b/Documentation/devicetree/bindings/mfd/qcom-rpm.txt
-@@ -59,6 +59,7 @@ Regulator nodes are identified by their
- 		    "qcom,rpm-pm8058-regulators"
- 		    "qcom,rpm-pm8901-regulators"
- 		    "qcom,rpm-pm8921-regulators"
-+		    "qcom,rpm-smb208-regulators"
- 
- - vdd_l0_l1_lvs-supply:
- - vdd_l2_l11_l12-supply:
-@@ -156,6 +157,9 @@ pm8921:
- 	l29, lvs1, lvs2, lvs3, lvs4, lvs5, lvs6, lvs7, usb-switch, hdmi-switch,
- 	ncp
- 
-+smb208:
-+	s1a, s1b, s2a, s2b
-+
- The content of each sub-node is defined by the standard binding for regulators -
- see regulator.txt - with additional custom properties described below:
- 
---- a/drivers/regulator/qcom_rpm-regulator.c
-+++ b/drivers/regulator/qcom_rpm-regulator.c
-@@ -869,10 +869,19 @@ static const struct rpm_regulator_data r
- 	{ }
- };
- 
-+static const struct rpm_regulator_data rpm_smb208_regulators[] = {
-+	{ "s1a",  QCOM_RPM_SMB208_S1a, &smb208_smps, "vin_s1a" },
-+	{ "s1b",  QCOM_RPM_SMB208_S1b, &smb208_smps, "vin_s1b" },
-+	{ "s2a",  QCOM_RPM_SMB208_S2a, &smb208_smps, "vin_s2a" },
-+	{ "s2b",  QCOM_RPM_SMB208_S2b, &smb208_smps, "vin_s2b" },
-+	{ }
-+};
-+
- static const struct of_device_id rpm_of_match[] = {
- 	{ .compatible = "qcom,rpm-pm8058-regulators", .data = &rpm_pm8058_regulators },
- 	{ .compatible = "qcom,rpm-pm8901-regulators", .data = &rpm_pm8901_regulators },
- 	{ .compatible = "qcom,rpm-pm8921-regulators", .data = &rpm_pm8921_regulators },
-+	{ .compatible = "qcom,rpm-smb208-regulators", .data = &rpm_smb208_regulators },
- 	{ }
- };
- MODULE_DEVICE_TABLE(of, rpm_of_match);
diff --git a/target/linux/ipq806x/patches-4.4/168-ARM-qcom-add-smb208-DT.patch b/target/linux/ipq806x/patches-4.4/168-ARM-qcom-add-smb208-DT.patch
deleted file mode 100644
index 1a15a8c..0000000
--- a/target/linux/ipq806x/patches-4.4/168-ARM-qcom-add-smb208-DT.patch
+++ /dev/null
@@ -1,74 +0,0 @@
-Change DT to use new smb208 regulator driver.
-
-Signed-off-by: Adrian Panella <ianchi74 at outlook.com>
-
---- a/arch/arm/boot/dts/qcom-ipq8064.dtsi
-+++ b/arch/arm/boot/dts/qcom-ipq8064.dtsi
-@@ -162,45 +162,37 @@
- 			#address-cells = <1>;
- 			#size-cells = <0>;
- 
--			smb208_s1a: smb208-s1a {
--				compatible = "qcom,rpm-smb208";
--				reg = <QCOM_RPM_SMB208_S1a>;
-+			regulators {
-+				compatible = "qcom,rpm-smb208-regulators";
- 
--				regulator-min-microvolt = <1050000>;
--				regulator-max-microvolt = <1150000>;
-+				smb208_s1a: s1a {
-+					regulator-min-microvolt = <1050000>;
-+					regulator-max-microvolt = <1150000>;
- 
--				qcom,switch-mode-frequency = <1200000>;
-+					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>;
-+				smb208_s1b: s1b {
-+					regulator-min-microvolt = <1050000>;
-+					regulator-max-microvolt = <1150000>;
- 
--				regulator-min-microvolt = < 800000>;
--				regulator-max-microvolt = <1250000>;
-+					qcom,switch-mode-frequency = <1200000>;
-+				};
- 
--				qcom,switch-mode-frequency = <1200000>;
--			};
-+				smb208_s2a: s2a {
-+					regulator-min-microvolt = < 800000>;
-+					regulator-max-microvolt = <1250000>;
- 
--			smb208_s2b: smb208-s2b {
--				compatible = "qcom,rpm-smb208";
--				reg = <QCOM_RPM_SMB208_S2b>;
-+					qcom,switch-mode-frequency = <1200000>;
-+				};
- 
--				regulator-min-microvolt = < 800000>;
--				regulator-max-microvolt = <1250000>;
-+				smb208_s2b: s2b {
-+					regulator-min-microvolt = < 800000>;
-+					regulator-max-microvolt = <1250000>;
- 
--				qcom,switch-mode-frequency = <1200000>;
-+					qcom,switch-mode-frequency = <1200000>;
-+				};
- 			};
- 		};
- 
diff --git a/target/linux/ipq806x/patches-4.4/169-OPP-Support-adjusting-OPP-voltages-at-runtime.patch b/target/linux/ipq806x/patches-4.4/169-OPP-Support-adjusting-OPP-voltages-at-runtime.patch
deleted file mode 100644
index 8f0afb5..0000000
--- a/target/linux/ipq806x/patches-4.4/169-OPP-Support-adjusting-OPP-voltages-at-runtime.patch
+++ /dev/null
@@ -1,145 +0,0 @@
-From 111139c943a082364fbbcd9e0cc94cd442481340 Mon Sep 17 00:00:00 2001
-From: Stephen Boyd <sboyd at codeaurora.org>
-Date: Mon, 1 Jun 2015 18:47:56 -0700
-Subject: PM / OPP: Support adjusting OPP voltages at runtime
-
-On some SoCs the Adaptive Voltage Scaling (AVS) technique is
-employed to optimize the operating voltage of a device. At a
-given frequency, the hardware monitors dynamic factors and either
-makes a suggestion for how much to adjust a voltage for the
-current frequency, or it automatically adjusts the voltage
-without software intervention. Add an API to the OPP library for
-the former case, so that AVS type devices can update the voltages
-for an OPP when the hardware determines the voltage should
-change. The assumption is that drivers like CPUfreq or devfreq
-will register for the OPP notifiers and adjust the voltage
-according to suggestions that AVS makes.
-
-Cc: Nishanth Menon <nm at ti.com>
-Cc: Viresh Kumar <viresh.kumar at linaro.org>
-Signed-off-by: Stephen Boyd <sboyd at codeaurora.org>
-Acked-by: Viresh Kumar <viresh.kumar at linaro.org>
----
- drivers/base/power/opp/core.c | 77 +++++++++++++++++++++++++++++++++++++++++++
- include/linux/pm_opp.h        | 10 ++++++
- 2 files changed, 87 insertions(+)
-
---- a/drivers/base/power/opp/core.c
-+++ b/drivers/base/power/opp/core.c
-@@ -1039,6 +1039,83 @@ unlock:
- }
- 
- /**
-+ * dev_pm_opp_adjust_voltage() - helper to change the voltage of an opp
-+ * @dev:		device for which we do this operation
-+ * @freq:		OPP frequency to adjust voltage of
-+ * @u_volt:		new OPP voltage
-+ *
-+ * Change the voltage of an OPP with an RCU operation.
-+ *
-+ * Return: -EINVAL for bad pointers, -ENOMEM if no memory available for the
-+ * copy operation, returns 0 if no modifcation was done OR modification was
-+ * successful.
-+ *
-+ * Locking: The internal device_opp and opp structures are RCU protected.
-+ * Hence this function internally uses RCU updater strategy with mutex locks to
-+ * keep the integrity of the internal data structures. Callers should ensure
-+ * that this function is *NOT* called under RCU protection or in contexts where
-+ * mutex locking or synchronize_rcu() blocking calls cannot be used.
-+ */
-+int dev_pm_opp_adjust_voltage(struct device *dev, unsigned long freq,
-+				 unsigned long u_volt)
-+{
-+	struct device_opp *dev_opp;
-+	struct dev_pm_opp *new_opp, *tmp_opp, *opp = ERR_PTR(-ENODEV);
-+	int r = 0;
-+
-+	/* keep the node allocated */
-+	new_opp = kmalloc(sizeof(*new_opp), GFP_KERNEL);
-+	if (!new_opp)
-+		return -ENOMEM;
-+
-+	mutex_lock(&dev_opp_list_lock);
-+
-+	/* Find the device_opp */
-+	dev_opp = _find_device_opp(dev);
-+	if (IS_ERR(dev_opp)) {
-+		r = PTR_ERR(dev_opp);
-+		dev_warn(dev, "%s: Device OPP not found (%d)\n", __func__, r);
-+		goto unlock;
-+	}
-+
-+	/* Do we have the frequency? */
-+	list_for_each_entry(tmp_opp, &dev_opp->opp_list, node) {
-+		if (tmp_opp->rate == freq) {
-+			opp = tmp_opp;
-+			break;
-+		}
-+	}
-+	if (IS_ERR(opp)) {
-+		r = PTR_ERR(opp);
-+		goto unlock;
-+	}
-+
-+	/* Is update really needed? */
-+	if (opp->u_volt == u_volt)
-+		goto unlock;
-+	/* copy the old data over */
-+	*new_opp = *opp;
-+
-+	/* plug in new node */
-+	new_opp->u_volt = u_volt;
-+
-+	list_replace_rcu(&opp->node, &new_opp->node);
-+	mutex_unlock(&dev_opp_list_lock);
-+	call_srcu(&dev_opp->srcu_head.srcu, &opp->rcu_head, _kfree_opp_rcu);
-+
-+	/* Notify the change of the OPP */
-+	srcu_notifier_call_chain(&dev_opp->srcu_head, OPP_EVENT_ADJUST_VOLTAGE,
-+				 new_opp);
-+
-+	return 0;
-+
-+unlock:
-+	mutex_unlock(&dev_opp_list_lock);
-+	kfree(new_opp);
-+	return r;
-+}
-+
-+/**
-  * dev_pm_opp_enable() - Enable a specific OPP
-  * @dev:	device for which we do this operation
-  * @freq:	OPP frequency to enable
---- a/include/linux/pm_opp.h
-+++ b/include/linux/pm_opp.h
-@@ -22,6 +22,7 @@ struct device;
- 
- enum dev_pm_opp_event {
- 	OPP_EVENT_ADD, OPP_EVENT_REMOVE, OPP_EVENT_ENABLE, OPP_EVENT_DISABLE,
-+	OPP_EVENT_ADJUST_VOLTAGE,
- };
- 
- #if defined(CONFIG_PM_OPP)
-@@ -50,6 +51,9 @@ int dev_pm_opp_add(struct device *dev, u
- 		   unsigned long u_volt);
- void dev_pm_opp_remove(struct device *dev, unsigned long freq);
- 
-+int dev_pm_opp_adjust_voltage(struct device *dev, unsigned long freq,
-+		   unsigned long u_volt);
-+
- int dev_pm_opp_enable(struct device *dev, unsigned long freq);
- 
- int dev_pm_opp_disable(struct device *dev, unsigned long freq);
-@@ -114,6 +118,12 @@ static inline void dev_pm_opp_remove(str
- {
- }
- 
-+static inline int dev_pm_opp_adjust_voltage(struct device *dev,
-+		unsigned long freq, unsigned long u_volt)
-+{
-+	return 0;
-+}
-+
- static inline int dev_pm_opp_enable(struct device *dev, unsigned long freq)
- {
- 	return 0;
diff --git a/target/linux/ipq806x/patches-4.4/170-OPP-Allow-notifiers-to-call-dev_pm_opp_get_voltage-freq-RCU-free.patch b/target/linux/ipq806x/patches-4.4/170-OPP-Allow-notifiers-to-call-dev_pm_opp_get_voltage-freq-RCU-free.patch
deleted file mode 100644
index 7be47a3..0000000
--- a/target/linux/ipq806x/patches-4.4/170-OPP-Allow-notifiers-to-call-dev_pm_opp_get_voltage-freq-RCU-free.patch
+++ /dev/null
@@ -1,114 +0,0 @@
-From d330eae026b4a73e77ca0422f5cae5207d80f738 Mon Sep 17 00:00:00 2001
-From: Stephen Boyd <sboyd at codeaurora.org>
-Date: Mon, 1 Jun 2015 18:47:57 -0700
-Subject: OPP: Allow notifiers to call dev_pm_opp_get_{voltage, freq} RCU-free
-
-We pass the dev_pm_opp structure to OPP notifiers but the users
-of the notifier need to surround calls to dev_pm_opp_get_*() with
-RCU read locks to avoid lockdep warnings. The notifier is already
-called with the dev_opp's srcu lock held, so it should be safe to
-assume the devm_pm_opp structure is already protected inside the
-notifier. Update the lockdep check for this.
-
-Cc: Krzysztof Kozlowski <k.kozlowski at samsung.com>
-Signed-off-by: Stephen Boyd <sboyd at codeaurora.org>
----
- drivers/base/power/opp/core.c | 27 +++++++++++++++------------
- 1 file changed, 15 insertions(+), 12 deletions(-)
-
---- a/drivers/base/power/opp/core.c
-+++ b/drivers/base/power/opp/core.c
-@@ -31,9 +31,10 @@ static LIST_HEAD(dev_opp_list);
- /* Lock to allow exclusive modification to the device and opp lists */
- DEFINE_MUTEX(dev_opp_list_lock);
- 
--#define opp_rcu_lockdep_assert()					\
-+#define opp_rcu_lockdep_assert(s)					\
- do {									\
- 	RCU_LOCKDEP_WARN(!rcu_read_lock_held() &&			\
-+				!(s && srcu_read_lock_held(s)) &&	\
- 				!lockdep_is_held(&dev_opp_list_lock),	\
- 			   "Missing rcu_read_lock() or "		\
- 			   "dev_opp_list_lock protection");		\
-@@ -91,7 +92,7 @@ struct device_opp *_find_device_opp(stru
- {
- 	struct device_opp *dev_opp;
- 
--	opp_rcu_lockdep_assert();
-+	opp_rcu_lockdep_assert(NULL);
- 
- 	if (IS_ERR_OR_NULL(dev)) {
- 		pr_err("%s: Invalid parameters\n", __func__);
-@@ -125,10 +126,11 @@ unsigned long dev_pm_opp_get_voltage(str
- 	struct dev_pm_opp *tmp_opp;
- 	unsigned long v = 0;
- 
--	opp_rcu_lockdep_assert();
-+	opp_rcu_lockdep_assert(&opp->dev_opp->srcu_head.srcu);
- 
--	tmp_opp = rcu_dereference(opp);
--	if (IS_ERR_OR_NULL(tmp_opp))
-+	tmp_opp = srcu_dereference_check(opp, &opp->dev_opp->srcu_head.srcu,
-+					 rcu_read_lock_held());
-+	if (IS_ERR_OR_NULL(tmp_opp) || !tmp_opp->available)
- 		pr_err("%s: Invalid parameters\n", __func__);
- 	else
- 		v = tmp_opp->u_volt;
-@@ -157,9 +159,10 @@ unsigned long dev_pm_opp_get_freq(struct
- 	struct dev_pm_opp *tmp_opp;
- 	unsigned long f = 0;
- 
--	opp_rcu_lockdep_assert();
-+	opp_rcu_lockdep_assert(&opp->dev_opp->srcu_head.srcu);
- 
--	tmp_opp = rcu_dereference(opp);
-+	tmp_opp = srcu_dereference_check(opp, &opp->dev_opp->srcu_head.srcu,
-+					 rcu_read_lock_held());
- 	if (IS_ERR_OR_NULL(tmp_opp) || !tmp_opp->available)
- 		pr_err("%s: Invalid parameters\n", __func__);
- 	else
-@@ -191,7 +194,7 @@ bool dev_pm_opp_is_turbo(struct dev_pm_o
- {
- 	struct dev_pm_opp *tmp_opp;
- 
--	opp_rcu_lockdep_assert();
-+	opp_rcu_lockdep_assert(&opp->dev_opp->srcu_head.srcu);
- 
- 	tmp_opp = rcu_dereference(opp);
- 	if (IS_ERR_OR_NULL(tmp_opp) || !tmp_opp->available) {
-@@ -246,7 +249,7 @@ struct dev_pm_opp *dev_pm_opp_get_suspen
- {
- 	struct device_opp *dev_opp;
- 
--	opp_rcu_lockdep_assert();
-+	opp_rcu_lockdep_assert(NULL);
- 
- 	dev_opp = _find_device_opp(dev);
- 	if (IS_ERR(dev_opp) || !dev_opp->suspend_opp ||
-@@ -326,7 +329,7 @@ struct dev_pm_opp *dev_pm_opp_find_freq_
- 	struct device_opp *dev_opp;
- 	struct dev_pm_opp *temp_opp, *opp = ERR_PTR(-ERANGE);
- 
--	opp_rcu_lockdep_assert();
-+	opp_rcu_lockdep_assert(NULL);
- 
- 	dev_opp = _find_device_opp(dev);
- 	if (IS_ERR(dev_opp)) {
-@@ -374,7 +377,7 @@ struct dev_pm_opp *dev_pm_opp_find_freq_
- 	struct device_opp *dev_opp;
- 	struct dev_pm_opp *temp_opp, *opp = ERR_PTR(-ERANGE);
- 
--	opp_rcu_lockdep_assert();
-+	opp_rcu_lockdep_assert(NULL);
- 
- 	if (!dev || !freq) {
- 		dev_err(dev, "%s: Invalid argument freq=%p\n", __func__, freq);
-@@ -424,7 +427,7 @@ struct dev_pm_opp *dev_pm_opp_find_freq_
- 	struct device_opp *dev_opp;
- 	struct dev_pm_opp *temp_opp, *opp = ERR_PTR(-ERANGE);
- 
--	opp_rcu_lockdep_assert();
-+	opp_rcu_lockdep_assert(NULL);
- 
- 	if (!dev || !freq) {
- 		dev_err(dev, "%s: Invalid argument freq=%p\n", __func__, freq);
diff --git a/target/linux/ipq806x/patches-4.4/172-cpufreq-dt-Handle-OPP-voltage-adjust-events.patch b/target/linux/ipq806x/patches-4.4/172-cpufreq-dt-Handle-OPP-voltage-adjust-events.patch
deleted file mode 100644
index 60ebe13..0000000
--- a/target/linux/ipq806x/patches-4.4/172-cpufreq-dt-Handle-OPP-voltage-adjust-events.patch
+++ /dev/null
@@ -1,184 +0,0 @@
-From 175329015c8a0b480240da222822d2f8316f074d Mon Sep 17 00:00:00 2001
-From: Stephen Boyd <sboyd at codeaurora.org>
-Date: Mon, 1 Jun 2015 18:47:58 -0700
-Subject: cpufreq-dt: Handle OPP voltage adjust events
-
-On some SoCs the Adaptive Voltage Scaling (AVS) technique is
-employed to optimize the operating voltage of a device. At a
-given frequency, the hardware monitors dynamic factors and either
-makes a suggestion for how much to adjust a voltage for the
-current frequency, or it automatically adjusts the voltage
-without software intervention.
-
-In the former case, an AVS driver will call
-dev_pm_opp_modify_voltage() and update the voltage for the
-particular OPP the CPUs are using. Add an OPP notifier to
-cpufreq-dt so that we can adjust the voltage of the CPU when AVS
-updates the OPP.
-
-Signed-off-by: Stephen Boyd <sboyd at codeaurora.org>
----
- drivers/cpufreq/cpufreq-dt.c | 72 ++++++++++++++++++++++++++++++++++++++++----
- 1 file changed, 66 insertions(+), 6 deletions(-)
-
---- a/drivers/cpufreq/cpufreq-dt.c
-+++ b/drivers/cpufreq/cpufreq-dt.c
-@@ -34,6 +34,9 @@ struct private_data {
- 	struct regulator *cpu_reg;
- 	struct thermal_cooling_device *cdev;
- 	unsigned int voltage_tolerance; /* in percentage */
-+	struct notifier_block opp_nb;
-+	struct mutex lock;
-+	unsigned long opp_freq;
- };
- 
- static struct freq_attr *cpufreq_dt_attr[] = {
-@@ -42,6 +45,42 @@ static struct freq_attr *cpufreq_dt_attr
- 	NULL,
- };
- 
-+static int opp_notifier(struct notifier_block *nb, unsigned long event,
-+			void *data)
-+{
-+	struct dev_pm_opp *opp = data;
-+	struct private_data *priv = container_of(nb, struct private_data,
-+						 opp_nb);
-+	struct device *cpu_dev = priv->cpu_dev;
-+	struct regulator *cpu_reg = priv->cpu_reg;
-+	unsigned long volt, tol, freq;
-+	int ret = 0;
-+
-+	switch (event) {
-+		case OPP_EVENT_ADJUST_VOLTAGE:
-+			volt = dev_pm_opp_get_voltage(opp);
-+			freq = dev_pm_opp_get_freq(opp);
-+			tol = volt * priv->voltage_tolerance / 100;
-+
-+			mutex_lock(&priv->lock);
-+			if (freq == priv->opp_freq)
-+				ret = regulator_set_voltage_tol(cpu_reg, volt,
-+								tol);
-+			mutex_unlock(&priv->lock);
-+			if (ret) {
-+				dev_err(cpu_dev,
-+					"failed to scale voltage up: %d\n",
-+					ret);
-+				return ret;
-+			}
-+			break;
-+		default:
-+			break;
-+	}
-+
-+	return 0;
-+}
-+
- static int set_target(struct cpufreq_policy *policy, unsigned int index)
- {
- 	struct dev_pm_opp *opp;
-@@ -53,6 +92,7 @@ static int set_target(struct cpufreq_pol
- 	unsigned long volt = 0, volt_old = 0, tol = 0;
- 	unsigned int old_freq, new_freq;
- 	long freq_Hz, freq_exact;
-+	unsigned long opp_freq = 0;
- 	int ret;
- 
- 	freq_Hz = clk_round_rate(cpu_clk, freq_table[index].frequency * 1000);
-@@ -63,8 +103,8 @@ static int set_target(struct cpufreq_pol
- 	new_freq = freq_Hz / 1000;
- 	old_freq = clk_get_rate(cpu_clk) / 1000;
- 
-+	mutex_lock(&priv->lock);
- 	if (!IS_ERR(cpu_reg)) {
--		unsigned long opp_freq;
- 
- 		rcu_read_lock();
- 		opp = dev_pm_opp_find_freq_ceil(cpu_dev, &freq_Hz);
-@@ -72,7 +112,8 @@ static int set_target(struct cpufreq_pol
- 			rcu_read_unlock();
- 			dev_err(cpu_dev, "failed to find OPP for %ld\n",
- 				freq_Hz);
--			return PTR_ERR(opp);
-+			ret = PTR_ERR(opp);
-+			goto out;
- 		}
- 		volt = dev_pm_opp_get_voltage(opp);
- 		opp_freq = dev_pm_opp_get_freq(opp);
-@@ -93,7 +134,7 @@ static int set_target(struct cpufreq_pol
- 		if (ret) {
- 			dev_err(cpu_dev, "failed to scale voltage up: %d\n",
- 				ret);
--			return ret;
-+			goto out;
- 		}
- 	}
- 
-@@ -102,7 +143,7 @@ static int set_target(struct cpufreq_pol
- 		dev_err(cpu_dev, "failed to set clock rate: %d\n", ret);
- 		if (!IS_ERR(cpu_reg) && volt_old > 0)
- 			regulator_set_voltage_tol(cpu_reg, volt_old, tol);
--		return ret;
-+		goto out;
- 	}
- 
- 	/* scaling down?  scale voltage after frequency */
-@@ -112,9 +153,12 @@ static int set_target(struct cpufreq_pol
- 			dev_err(cpu_dev, "failed to scale voltage down: %d\n",
- 				ret);
- 			clk_set_rate(cpu_clk, old_freq * 1000);
-+			goto out;
- 		}
- 	}
--
-+	priv->opp_freq = opp_freq;
-+out:
-+	mutex_unlock(&priv->lock);
- 	return ret;
- }
- 
-@@ -201,6 +245,7 @@ static int cpufreq_init(struct cpufreq_p
- 	unsigned int transition_latency;
- 	bool need_update = false;
- 	int ret;
-+	struct srcu_notifier_head *opp_srcu_head;
- 
- 	ret = allocate_resources(policy->cpu, &cpu_dev, &cpu_reg, &cpu_clk);
- 	if (ret) {
-@@ -277,6 +322,19 @@ static int cpufreq_init(struct cpufreq_p
- 		goto out_free_opp;
- 	}
- 
-+	mutex_init(&priv->lock);
-+
-+	opp_srcu_head = dev_pm_opp_get_notifier(cpu_dev);
-+	if (IS_ERR(opp_srcu_head)) {
-+		ret = PTR_ERR(opp_srcu_head);
-+		goto out_free_priv;
-+	}
-+
-+	priv->opp_nb.notifier_call = opp_notifier;
-+	ret = srcu_notifier_chain_register(opp_srcu_head, &priv->opp_nb);
-+	if (ret)
-+		goto out_free_priv;
-+
- 	of_property_read_u32(np, "voltage-tolerance", &priv->voltage_tolerance);
- 
- 	if (!transition_latency)
-@@ -326,7 +384,7 @@ static int cpufreq_init(struct cpufreq_p
- 	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_free_priv;
-+		goto out_unregister_nb;
- 	}
- 
- 	priv->cpu_dev = cpu_dev;
-@@ -365,6 +423,8 @@ static int cpufreq_init(struct cpufreq_p
- 
- out_free_cpufreq_table:
- 	dev_pm_opp_free_cpufreq_table(cpu_dev, &freq_table);
-+out_unregister_nb:
-+	srcu_notifier_chain_unregister(opp_srcu_head, &priv->opp_nb);
- out_free_priv:
- 	kfree(priv);
- out_free_opp:
diff --git a/target/linux/ipq806x/patches-4.4/173-cpufreq-dt-Add-L2-frequency-scaling-support.patch b/target/linux/ipq806x/patches-4.4/173-cpufreq-dt-Add-L2-frequency-scaling-support.patch
deleted file mode 100644
index 5693052..0000000
--- a/target/linux/ipq806x/patches-4.4/173-cpufreq-dt-Add-L2-frequency-scaling-support.patch
+++ /dev/null
@@ -1,161 +0,0 @@
-From b4629f9e30e865402c643de6d4668be790fc0539 Mon Sep 17 00:00:00 2001
-From: Georgi Djakov <georgi.djakov at linaro.org>
-Date: Tue, 8 Sep 2015 11:24:41 +0300
-Subject: cpufreq-dt: Add L2 frequency scaling support
-
-Signed-off-by: Georgi Djakov <georgi.djakov at linaro.org>
-
-Conflicts:
-	drivers/cpufreq/cpufreq-dt.c
----
- drivers/cpufreq/cpufreq-dt.c | 54 ++++++++++++++++++++++++++++++++++++++------
- include/linux/cpufreq.h      |  2 ++
- 2 files changed, 49 insertions(+), 7 deletions(-)
-
---- a/drivers/cpufreq/cpufreq-dt.c
-+++ b/drivers/cpufreq/cpufreq-dt.c
-@@ -86,11 +86,13 @@ static int set_target(struct cpufreq_pol
- 	struct dev_pm_opp *opp;
- 	struct cpufreq_frequency_table *freq_table = policy->freq_table;
- 	struct clk *cpu_clk = policy->clk;
-+	struct clk *l2_clk = policy->l2_clk;
- 	struct private_data *priv = policy->driver_data;
- 	struct device *cpu_dev = priv->cpu_dev;
- 	struct regulator *cpu_reg = priv->cpu_reg;
- 	unsigned long volt = 0, volt_old = 0, tol = 0;
--	unsigned int old_freq, new_freq;
-+	unsigned int old_freq, new_freq, l2_freq;
-+	unsigned long new_l2_freq = 0;
- 	long freq_Hz, freq_exact;
- 	unsigned long opp_freq = 0;
- 	int ret;
-@@ -146,6 +148,30 @@ static int set_target(struct cpufreq_pol
- 		goto out;
- 	}
- 
-+	if (!IS_ERR(l2_clk) && policy->l2_rate[0] && policy->l2_rate[1] &&
-+	    policy->l2_rate[2]) {
-+		static unsigned long krait_l2[CONFIG_NR_CPUS] = { };
-+		int cpu, ret = 0;
-+
-+		if (freq_exact >= policy->l2_rate[2])
-+			new_l2_freq = policy->l2_rate[2];
-+		else if (freq_exact >= policy->l2_rate[1])
-+			new_l2_freq = policy->l2_rate[1];
-+		else
-+			new_l2_freq = policy->l2_rate[0];
-+
-+		krait_l2[policy->cpu] = new_l2_freq;
-+		for_each_present_cpu(cpu)
-+			new_l2_freq = max(new_l2_freq, krait_l2[cpu]);
-+
-+		l2_freq = clk_get_rate(l2_clk);
-+
-+		if (l2_freq != new_l2_freq) {
-+			/* scale l2 with the core */
-+			ret = clk_set_rate(l2_clk, new_l2_freq);
-+		}
-+	}
-+
- 	/* scaling down?  scale voltage after frequency */
- 	if (!IS_ERR(cpu_reg) && new_freq < old_freq) {
- 		ret = regulator_set_voltage_tol(cpu_reg, volt, tol);
-@@ -156,18 +182,21 @@ static int set_target(struct cpufreq_pol
- 			goto out;
- 		}
- 	}
-+
- 	priv->opp_freq = opp_freq;
-+
- out:
- 	mutex_unlock(&priv->lock);
- 	return ret;
- }
- 
- static int allocate_resources(int cpu, struct device **cdev,
--			      struct regulator **creg, struct clk **cclk)
-+			      struct regulator **creg, struct clk **cclk,
-+			      struct clk **l2)
- {
- 	struct device *cpu_dev;
- 	struct regulator *cpu_reg;
--	struct clk *cpu_clk;
-+	struct clk *cpu_clk, *l2_clk = NULL;
- 	int ret = 0;
- 	char *reg_cpu0 = "cpu0", *reg_cpu = "cpu", *reg;
- 
-@@ -227,6 +256,10 @@ try_again:
- 		*cdev = cpu_dev;
- 		*creg = cpu_reg;
- 		*cclk = cpu_clk;
-+
-+		l2_clk = clk_get(cpu_dev, "l2");
-+		if (!IS_ERR(l2_clk))
-+			*l2 = l2_clk;
- 	}
- 
- 	return ret;
-@@ -236,18 +269,20 @@ static int cpufreq_init(struct cpufreq_p
- {
- 	struct cpufreq_frequency_table *freq_table;
- 	struct device_node *np;
-+	struct device_node *l2_np;
- 	struct private_data *priv;
- 	struct device *cpu_dev;
- 	struct regulator *cpu_reg;
--	struct clk *cpu_clk;
- 	struct dev_pm_opp *suspend_opp;
-+	struct clk *cpu_clk, *l2_clk;
- 	unsigned long min_uV = ~0, max_uV = 0;
- 	unsigned int transition_latency;
- 	bool need_update = false;
- 	int ret;
- 	struct srcu_notifier_head *opp_srcu_head;
- 
--	ret = allocate_resources(policy->cpu, &cpu_dev, &cpu_reg, &cpu_clk);
-+	ret = allocate_resources(policy->cpu, &cpu_dev, &cpu_reg, &cpu_clk,
-+				 &l2_clk);
- 	if (ret) {
- 		pr_err("%s: Failed to allocate resources: %d\n", __func__, ret);
- 		return ret;
-@@ -398,6 +433,11 @@ static int cpufreq_init(struct cpufreq_p
- 	if (suspend_opp)
- 		policy->suspend_freq = dev_pm_opp_get_freq(suspend_opp) / 1000;
- 	rcu_read_unlock();
-+	policy->l2_clk = l2_clk;
-+
-+	l2_np = of_find_node_by_name(NULL, "qcom,l2");
-+	if (l2_np)
-+		of_property_read_u32_array(l2_np, "qcom,l2-rates", policy->l2_rate, 3);
- 
- 	ret = cpufreq_table_validate_and_show(policy, freq_table);
- 	if (ret) {
-@@ -498,7 +538,7 @@ static int dt_cpufreq_probe(struct platf
- {
- 	struct device *cpu_dev;
- 	struct regulator *cpu_reg;
--	struct clk *cpu_clk;
-+	struct clk *cpu_clk, *l2_clk;
- 	int ret;
- 
- 	/*
-@@ -508,7 +548,7 @@ static int dt_cpufreq_probe(struct platf
- 	 *
- 	 * FIXME: Is checking this only for CPU0 sufficient ?
- 	 */
--	ret = allocate_resources(0, &cpu_dev, &cpu_reg, &cpu_clk);
-+	ret = allocate_resources(0, &cpu_dev, &cpu_reg, &cpu_clk, &l2_clk);
- 	if (ret)
- 		return ret;
- 
---- a/include/linux/cpufreq.h
-+++ b/include/linux/cpufreq.h
-@@ -67,6 +67,8 @@ struct cpufreq_policy {
- 	unsigned int		cpu;    /* cpu managing this policy, must be online */
- 
- 	struct clk		*clk;
-+	struct clk		*l2_clk; /* L2 clock */
-+	unsigned int		l2_rate[3]; /* L2 bus clock rate thresholds */
- 	struct cpufreq_cpuinfo	cpuinfo;/* see above */
- 
- 	unsigned int		min;    /* in kHz */
diff --git a/target/linux/ipq806x/patches-4.4/174-cpufreq-dt-Add-missing-rcu_read_lock-for-find_device_opp.patch b/target/linux/ipq806x/patches-4.4/174-cpufreq-dt-Add-missing-rcu_read_lock-for-find_device_opp.patch
deleted file mode 100644
index 1242721..0000000
--- a/target/linux/ipq806x/patches-4.4/174-cpufreq-dt-Add-missing-rcu_read_lock-for-find_device_opp.patch
+++ /dev/null
@@ -1,33 +0,0 @@
-From dafae9c5b39e2871bfd8db0b4bad6e850e42ef49 Mon Sep 17 00:00:00 2001
-From: Georgi Djakov <georgi.djakov at linaro.org>
-Date: Wed, 13 Jan 2016 15:10:25 +0200
-Subject: cpufreq-dt: Add missing rcu_read_lock() for find_device_opp()
-
-The function dev_pm_opp_get_notifier() must be called with held
-rcu_read_lock. In order to keep the pointer valid, add rcu_read_lock().
-
-Signed-off-by: Georgi Djakov <georgi.djakov at linaro.org>
----
- drivers/cpufreq/cpufreq-dt.c | 3 +++
- 1 file changed, 3 insertions(+)
-
---- a/drivers/cpufreq/cpufreq-dt.c
-+++ b/drivers/cpufreq/cpufreq-dt.c
-@@ -359,14 +359,17 @@ static int cpufreq_init(struct cpufreq_p
- 
- 	mutex_init(&priv->lock);
- 
-+	rcu_read_lock();
- 	opp_srcu_head = dev_pm_opp_get_notifier(cpu_dev);
- 	if (IS_ERR(opp_srcu_head)) {
- 		ret = PTR_ERR(opp_srcu_head);
-+		rcu_read_unlock();
- 		goto out_free_priv;
- 	}
- 
- 	priv->opp_nb.notifier_call = opp_notifier;
- 	ret = srcu_notifier_chain_register(opp_srcu_head, &priv->opp_nb);
-+	rcu_read_unlock();
- 	if (ret)
- 		goto out_free_priv;
- 
diff --git a/target/linux/ipq806x/patches-4.4/175-add-regmap-mux-div.patch b/target/linux/ipq806x/patches-4.4/175-add-regmap-mux-div.patch
deleted file mode 100644
index b5c23b5..0000000
--- a/target/linux/ipq806x/patches-4.4/175-add-regmap-mux-div.patch
+++ /dev/null
@@ -1,386 +0,0 @@
-From 7727b1cae43e9abac746ef016c3dbf50ee81a6d6 Mon Sep 17 00:00:00 2001
-From: Georgi Djakov <georgi.djakov at linaro.org>
-Date: Wed, 18 Mar 2015 17:23:29 +0200
-Subject: clk: qcom: Add support for regmap mux-div clocks
-
-Add support for hardware that support switching both parent clocks and the
-divider at the same time. This avoids generating intermediate frequencies
-from either the old parent clock and new divider or new parent clock and
-old divider combinations.
-
-Signed-off-by: Georgi Djakov <georgi.djakov at linaro.org>
----
- drivers/clk/qcom/Makefile             |   1 +
- drivers/clk/qcom/clk-regmap-mux-div.c | 288 ++++++++++++++++++++++++++++++++++
- drivers/clk/qcom/clk-regmap-mux-div.h |  63 ++++++++
- 3 files changed, 352 insertions(+)
- create mode 100644 drivers/clk/qcom/clk-regmap-mux-div.c
- create mode 100644 drivers/clk/qcom/clk-regmap-mux-div.h
-
---- a/drivers/clk/qcom/Makefile
-+++ b/drivers/clk/qcom/Makefile
-@@ -8,6 +8,7 @@ clk-qcom-y += clk-rcg2.o
- clk-qcom-y += clk-branch.o
- clk-qcom-y += clk-regmap-divider.o
- clk-qcom-y += clk-regmap-mux.o
-+clk-qcom-y += clk-regmap-mux-div.o
- clk-qcom-$(CONFIG_KRAIT_CLOCKS) += clk-krait.o
- obj-$(CONFIG_KPSS_XCC) += kpss-xcc.o
- clk-qcom-y += clk-hfpll.o
---- /dev/null
-+++ b/drivers/clk/qcom/clk-regmap-mux-div.c
-@@ -0,0 +1,288 @@
-+/*
-+ * Copyright (c) 2015, Linaro Limited
-+ * Copyright (c) 2014, The Linux Foundation. All rights reserved.
-+ *
-+ * This software is licensed under the terms of the GNU General Public
-+ * License version 2, as published by the Free Software Foundation, and
-+ * may be copied, distributed, and modified under those terms.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-+ * GNU General Public License for more details.
-+ */
-+
-+#include <linux/bitops.h>
-+#include <linux/clk.h>
-+#include <linux/delay.h>
-+#include <linux/export.h>
-+#include <linux/kernel.h>
-+#include <linux/regmap.h>
-+
-+#include "clk-regmap-mux-div.h"
-+
-+#define CMD_RCGR			0x0
-+#define CMD_RCGR_UPDATE			BIT(0)
-+#define CMD_RCGR_DIRTY_CFG		BIT(4)
-+#define CMD_RCGR_ROOT_OFF		BIT(31)
-+#define CFG_RCGR			0x4
-+
-+static int __mux_div_update_config(struct clk_regmap_mux_div *md)
-+{
-+	int ret;
-+	u32 val, count;
-+	const char *name = clk_hw_get_name(&md->clkr.hw);
-+
-+	ret = regmap_update_bits(md->clkr.regmap, CMD_RCGR + md->reg_offset,
-+				 CMD_RCGR_UPDATE, CMD_RCGR_UPDATE);
-+	if (ret)
-+		return ret;
-+
-+	/* Wait for update to take effect */
-+	for (count = 500; count > 0; count--) {
-+		ret = regmap_read(md->clkr.regmap, CMD_RCGR + md->reg_offset,
-+				  &val);
-+		if (ret)
-+			return ret;
-+		if (!(val & CMD_RCGR_UPDATE))
-+			return 0;
-+		udelay(1);
-+	}
-+
-+	pr_err("%s: RCG did not update its configuration", name);
-+	return -EBUSY;
-+}
-+
-+static int __mux_div_set_src_div(struct clk_regmap_mux_div *md, u32 src_sel,
-+				 u32 src_div)
-+{
-+	int ret;
-+	u32 val, mask;
-+
-+	val = (src_div << md->hid_shift) | (src_sel << md->src_shift);
-+	mask = ((BIT(md->hid_width) - 1) << md->hid_shift) |
-+	       ((BIT(md->src_width) - 1) << md->src_shift);
-+
-+	ret = regmap_update_bits(md->clkr.regmap, CFG_RCGR + md->reg_offset,
-+				 mask, val);
-+	if (ret)
-+		return ret;
-+
-+	return __mux_div_update_config(md);
-+}
-+
-+static void __mux_div_get_src_div(struct clk_regmap_mux_div *md, u32 *src_sel,
-+				  u32 *src_div)
-+{
-+	u32 val, div, src;
-+	const char *name = clk_hw_get_name(&md->clkr.hw);
-+
-+	regmap_read(md->clkr.regmap, CMD_RCGR + md->reg_offset, &val);
-+
-+	if (val & CMD_RCGR_DIRTY_CFG) {
-+		pr_err("%s: RCG configuration is pending\n", name);
-+		return;
-+	}
-+
-+	regmap_read(md->clkr.regmap, CFG_RCGR + md->reg_offset, &val);
-+	src = (val >> md->src_shift);
-+	src &= BIT(md->src_width) - 1;
-+	*src_sel = src;
-+
-+	div = (val >> md->hid_shift);
-+	div &= BIT(md->hid_width) - 1;
-+	*src_div = div;
-+}
-+
-+static int mux_div_enable(struct clk_hw *hw)
-+{
-+	struct clk_regmap_mux_div *md = to_clk_regmap_mux_div(hw);
-+
-+	return __mux_div_set_src_div(md, md->src_sel, md->div);
-+}
-+
-+static inline bool is_better_rate(unsigned long req, unsigned long best,
-+				  unsigned long new)
-+{
-+	return (req <= new && new < best) || (best < req && best < new);
-+}
-+
-+static int mux_div_determine_rate(struct clk_hw *hw,
-+				  struct clk_rate_request *req)
-+{
-+	struct clk_regmap_mux_div *md = to_clk_regmap_mux_div(hw);
-+	unsigned int i, div, max_div;
-+	unsigned long actual_rate, best_rate = 0;
-+	unsigned long req_rate = req->rate;
-+
-+	for (i = 0; i < clk_hw_get_num_parents(hw); i++) {
-+		struct clk_hw *parent = clk_hw_get_parent_by_index(hw, i);
-+		unsigned long parent_rate = clk_hw_get_rate(parent);
-+
-+		max_div = BIT(md->hid_width) - 1;
-+		for (div = 1; div < max_div; div++) {
-+			parent_rate = mult_frac(req_rate, div, 2);
-+			parent_rate = clk_hw_round_rate(parent, parent_rate);
-+			actual_rate = mult_frac(parent_rate, 2, div);
-+
-+			if (is_better_rate(req_rate, best_rate, actual_rate)) {
-+				best_rate = actual_rate;
-+				req->rate = best_rate;
-+				req->best_parent_rate = parent_rate;
-+				req->best_parent_hw = parent;
-+			}
-+
-+			if (actual_rate < req_rate || best_rate <= req_rate)
-+				break;
-+		}
-+	}
-+
-+	if (!best_rate)
-+		return -EINVAL;
-+
-+	return 0;
-+}
-+
-+static int __mux_div_set_rate_and_parent(struct clk_hw *hw, unsigned long rate,
-+					 unsigned long prate, u32 src_sel)
-+{
-+	struct clk_regmap_mux_div *md = to_clk_regmap_mux_div(hw);
-+	int ret, i;
-+	u32 div, max_div, best_src = 0, best_div = 0;
-+	unsigned long actual_rate, best_rate = 0;
-+
-+	for (i = 0; i < clk_hw_get_num_parents(hw); i++) {
-+		struct clk_hw *parent = clk_hw_get_parent_by_index(hw, i);
-+		unsigned long parent_rate = clk_hw_get_rate(parent);
-+
-+		max_div = BIT(md->hid_width) - 1;
-+		for (div = 1; div < max_div; div++) {
-+			parent_rate = mult_frac(rate, div, 2);
-+			parent_rate = clk_hw_round_rate(parent, parent_rate);
-+			actual_rate = mult_frac(parent_rate, 2, div);
-+
-+			if (is_better_rate(rate, best_rate, actual_rate)) {
-+				best_rate = actual_rate;
-+				best_src = md->parent_map[i].cfg;
-+				best_div = div - 1;
-+			}
-+
-+			if (actual_rate < rate || best_rate <= rate)
-+				break;
-+		}
-+	}
-+
-+	ret = __mux_div_set_src_div(md, best_src, best_div);
-+	if (!ret) {
-+		md->div = best_div;
-+		md->src_sel = best_src;
-+	}
-+
-+	return ret;
-+}
-+
-+static u8 mux_div_get_parent(struct clk_hw *hw)
-+{
-+	struct clk_regmap_mux_div *md = to_clk_regmap_mux_div(hw);
-+	const char *name = clk_hw_get_name(hw);
-+	u32 i, div, src;
-+
-+	__mux_div_get_src_div(md, &src, &div);
-+
-+	for (i = 0; i < clk_hw_get_num_parents(hw); i++)
-+		if (src == md->parent_map[i].cfg)
-+			return i;
-+
-+	pr_err("%s: Can't find parent %d\n", name, src);
-+	return 0;
-+}
-+
-+static int mux_div_set_parent(struct clk_hw *hw, u8 index)
-+{
-+	struct clk_regmap_mux_div *md = to_clk_regmap_mux_div(hw);
-+
-+	return __mux_div_set_src_div(md, md->parent_map[index].cfg, md->div);
-+}
-+
-+static int mux_div_set_rate(struct clk_hw *hw,
-+			    unsigned long rate, unsigned long prate)
-+{
-+	struct clk_regmap_mux_div *md = to_clk_regmap_mux_div(hw);
-+
-+	return __mux_div_set_rate_and_parent(hw, rate, prate, md->src_sel);
-+}
-+
-+static int mux_div_set_rate_and_parent(struct clk_hw *hw,  unsigned long rate,
-+				       unsigned long prate, u8 index)
-+{
-+	struct clk_regmap_mux_div *md = to_clk_regmap_mux_div(hw);
-+
-+	return __mux_div_set_rate_and_parent(hw, rate, prate,
-+					     md->parent_map[index].cfg);
-+}
-+
-+static unsigned long mux_div_recalc_rate(struct clk_hw *hw, unsigned long prate)
-+{
-+	struct clk_regmap_mux_div *md = to_clk_regmap_mux_div(hw);
-+	u32 div, src;
-+	int i, num_parents = clk_hw_get_num_parents(hw);
-+	const char *name = clk_hw_get_name(hw);
-+
-+	__mux_div_get_src_div(md, &src, &div);
-+	for (i = 0; i < num_parents; i++)
-+		if (src == md->parent_map[i].cfg) {
-+			struct clk_hw *p = clk_hw_get_parent_by_index(hw, i);
-+			unsigned long parent_rate = clk_hw_get_rate(p);
-+
-+			return mult_frac(parent_rate, 2, div + 1);
-+		}
-+
-+	pr_err("%s: Can't find parent %d\n", name, src);
-+	return 0;
-+}
-+
-+static struct clk_hw *mux_div_get_safe_parent(struct clk_hw *hw,
-+					      unsigned long *safe_freq)
-+{
-+	int i;
-+	struct clk_regmap_mux_div *md = to_clk_regmap_mux_div(hw);
-+
-+	if (md->safe_freq)
-+		*safe_freq = md->safe_freq;
-+
-+	for (i = 0; i < clk_hw_get_num_parents(hw); i++)
-+		if (md->safe_src == md->parent_map[i].cfg)
-+			break;
-+
-+	return clk_hw_get_parent_by_index(hw, i);
-+}
-+
-+static void mux_div_disable(struct clk_hw *hw)
-+{
-+	struct clk_regmap_mux_div *md = to_clk_regmap_mux_div(hw);
-+	struct clk_hw *parent;
-+	u32 div;
-+
-+	if (!md->safe_freq || !md->safe_src)
-+		return;
-+
-+	parent = mux_div_get_safe_parent(hw, &md->safe_freq);
-+	div = divider_get_val(md->safe_freq, clk_get_rate(parent->clk), NULL,
-+			      md->hid_width, CLK_DIVIDER_ROUND_CLOSEST);
-+	div = 2 * div + 1;
-+
-+	__mux_div_set_src_div(md, md->safe_src, div);
-+}
-+
-+const struct clk_ops clk_regmap_mux_div_ops = {
-+	.enable = mux_div_enable,
-+	.disable = mux_div_disable,
-+	.get_parent = mux_div_get_parent,
-+	.set_parent = mux_div_set_parent,
-+	.set_rate = mux_div_set_rate,
-+	.set_rate_and_parent = mux_div_set_rate_and_parent,
-+	.determine_rate = mux_div_determine_rate,
-+	.recalc_rate = mux_div_recalc_rate,
-+	.get_safe_parent = mux_div_get_safe_parent,
-+};
-+EXPORT_SYMBOL_GPL(clk_regmap_mux_div_ops);
---- /dev/null
-+++ b/drivers/clk/qcom/clk-regmap-mux-div.h
-@@ -0,0 +1,63 @@
-+/*
-+ * Copyright (c) 2015, Linaro Limited
-+ * Copyright (c) 2014, The Linux Foundation. All rights reserved.
-+ *
-+ * This software is licensed under the terms of the GNU General Public
-+ * License version 2, as published by the Free Software Foundation, and
-+ * may be copied, distributed, and modified under those terms.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-+ * GNU General Public License for more details.
-+ */
-+
-+#ifndef __QCOM_CLK_REGMAP_MUX_DIV_H__
-+#define __QCOM_CLK_REGMAP_MUX_DIV_H__
-+
-+#include <linux/clk-provider.h>
-+#include "clk-regmap.h"
-+#include "clk-rcg.h"
-+
-+/**
-+ * struct mux_div_clk - combined mux/divider clock
-+ * @reg_offset: offset of the mux/divider register
-+ * @hid_width:	number of bits in half integer divider
-+ * @hid_shift:	lowest bit of hid value field
-+ * @src_width:	number of bits in source select
-+ * @src_shift:	lowest bit of source select field
-+ * @div:	the divider raw configuration value
-+ * @src_sel:	the mux index which will be used if the clock is enabled
-+ * @safe_src:	the safe source mux index for this clock
-+ * @safe_freq:	When switching rates from A to B, the mux div clock will
-+ *		instead switch from A -> safe_freq -> B. This allows the
-+ *		mux_div clock to change rates while enabled, even if this
-+ *		behavior is not supported by the parent clocks.
-+ *		If changing the rate of parent A also causes the rate of
-+ *		parent B to change, then safe_freq must be defined.
-+ *		safe_freq is expected to have a source clock which is always
-+ *		on and runs at only one rate.
-+ * @parent_map:	pointer to parent_map struct
-+ * @clkr:	handle between common and hardware-specific interfaces
-+ */
-+
-+struct clk_regmap_mux_div {
-+	u32				reg_offset;
-+	u32				hid_width;
-+	u32				hid_shift;
-+	u32				src_width;
-+	u32				src_shift;
-+	u32				div;
-+	u32				src_sel;
-+	u32				safe_src;
-+	unsigned long			safe_freq;
-+	const struct parent_map		*parent_map;
-+	struct clk_regmap		clkr;
-+};
-+
-+#define to_clk_regmap_mux_div(_hw) \
-+	container_of(to_clk_regmap(_hw), struct clk_regmap_mux_div, clkr)
-+
-+extern const struct clk_ops clk_regmap_mux_div_ops;
-+
-+#endif
diff --git a/target/linux/ipq806x/patches-4.4/180-clk-qcom-Always-add-factor-clock-for-xo-clocks.patch b/target/linux/ipq806x/patches-4.4/180-clk-qcom-Always-add-factor-clock-for-xo-clocks.patch
deleted file mode 100644
index c8d83e9..0000000
--- a/target/linux/ipq806x/patches-4.4/180-clk-qcom-Always-add-factor-clock-for-xo-clocks.patch
+++ /dev/null
@@ -1,53 +0,0 @@
-From patchwork Wed Nov  2 15:56:58 2016
-Content-Type: text/plain; charset="utf-8"
-MIME-Version: 1.0
-Content-Transfer-Encoding: 7bit
-Subject: [v9,3/3] clk: qcom: Always add factor clock for xo clocks
-From: Georgi Djakov <georgi.djakov at linaro.org>
-X-Patchwork-Id: 9409421
-Message-Id: <20161102155658.32203-4-georgi.djakov at linaro.org>
-To: sboyd at codeaurora.org, mturquette at baylibre.com
-Cc: linux-clk at vger.kernel.org, devicetree at vger.kernel.org,
- robh+dt at kernel.org, mark.rutland at arm.com,
- linux-kernel at vger.kernel.org, linux-arm-msm at vger.kernel.org,
- georgi.djakov at linaro.org
-Date: Wed,  2 Nov 2016 17:56:58 +0200
-
-Currently the RPM/RPM-SMD clock drivers do not register the xo clocks,
-so we should always add factor clock. When we later add xo clocks support
-into the drivers, we should update this function to skip registration.
-By doing so we avoid any DT dependencies.
-
-Signed-off-by: Georgi Djakov <georgi.djakov at linaro.org>
----
- drivers/clk/qcom/common.c | 15 ++++++---------
- 1 file changed, 6 insertions(+), 9 deletions(-)
-
---
-To unsubscribe from this list: send the line "unsubscribe linux-arm-msm" in
-the body of a message to majordomo at vger.kernel.org
-More majordomo info at  http://vger.kernel.org/majordomo-info.html
-
---- a/drivers/clk/qcom/common.c
-+++ b/drivers/clk/qcom/common.c
-@@ -154,15 +154,12 @@ int qcom_cc_register_board_clk(struct de
- 			       const char *name, unsigned long rate)
- {
- 	bool add_factor = true;
--	struct device_node *node;
- 
--	/* The RPM clock driver will add the factor clock if present */
--	if (IS_ENABLED(CONFIG_QCOM_RPMCC)) {
--		node = of_find_compatible_node(NULL, NULL, "qcom,rpmcc");
--		if (of_device_is_available(node))
--			add_factor = false;
--		of_node_put(node);
--	}
-+	/*
-+	 * TODO: The RPM clock driver currently does not support the xo clock.
-+	 * When xo is added to the RPM clock driver, we should change this
-+	 * function to skip registration of xo factor clocks.
-+	 */
- 
- 	return _qcom_cc_register_board_clk(dev, path, name, rate, add_factor);
- }
diff --git a/target/linux/ipq806x/patches-4.4/181-cpuidle-Add-cpuidle-support-for-QCOM-cpus.patch b/target/linux/ipq806x/patches-4.4/181-cpuidle-Add-cpuidle-support-for-QCOM-cpus.patch
deleted file mode 100644
index b766ec0..0000000
--- a/target/linux/ipq806x/patches-4.4/181-cpuidle-Add-cpuidle-support-for-QCOM-cpus.patch
+++ /dev/null
@@ -1,29 +0,0 @@
-From 252a4e72dfd7add3c37604449fd20db29d84c6f8 Mon Sep 17 00:00:00 2001
-From: Lina Iyer <lina.iyer at linaro.org>
-Date: Wed, 25 Mar 2015 14:25:29 -0600
-Subject: ARM: cpuidle: Add cpuidle support for QCOM cpus
-
-Define ARM_QCOM_CPUIDLE config item to enable cpuidle support.
-
-Cc: Stephen Boyd <sboyd at codeaurora.org>
-Cc: Arnd Bergmann <arnd at arndb.de>
-Cc: Kevin Hilman <khilman at linaro.org>
-Cc: Daniel Lezcano <daniel.lezcano at linaro.org>
-Signed-off-by: Lina Iyer <lina.iyer at linaro.org>
----
- drivers/cpuidle/Kconfig.arm | 7 +++++++
- 1 file changed, 7 insertions(+)
-
---- a/drivers/cpuidle/Kconfig.arm
-+++ b/drivers/cpuidle/Kconfig.arm
-@@ -74,3 +74,10 @@ config ARM_MVEBU_V7_CPUIDLE
- 	depends on ARCH_MVEBU && !ARM64
- 	help
- 	  Select this to enable cpuidle on Armada 370, 38x and XP processors.
-+
-+config ARM_QCOM_CPUIDLE
-+	bool "CPU Idle Driver for QCOM processors"
-+	depends on ARCH_QCOM
-+	select ARM_CPUIDLE
-+	help
-+	  Select this to enable cpuidle on QCOM processors.
diff --git a/target/linux/ipq806x/patches-4.4/300-arch-arm-force-ZRELADDR-on-arch-qcom.patch b/target/linux/ipq806x/patches-4.4/300-arch-arm-force-ZRELADDR-on-arch-qcom.patch
deleted file mode 100644
index 35ba6fb..0000000
--- a/target/linux/ipq806x/patches-4.4/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 at 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 at 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
-@@ -324,7 +324,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
-@@ -256,9 +256,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-4.4/302-mtd-qcom-smem-rename-rootfs-ubi.patch b/target/linux/ipq806x/patches-4.4/302-mtd-qcom-smem-rename-rootfs-ubi.patch
deleted file mode 100644
index 8890a91..0000000
--- a/target/linux/ipq806x/patches-4.4/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
-@@ -189,6 +189,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-4.4/303-add-saw_l2-and-sns-into-ipq8064-DT.patch b/target/linux/ipq806x/patches-4.4/303-add-saw_l2-and-sns-into-ipq8064-DT.patch
deleted file mode 100644
index f7ea6fd..0000000
--- a/target/linux/ipq806x/patches-4.4/303-add-saw_l2-and-sns-into-ipq8064-DT.patch
+++ /dev/null
@@ -1,41 +0,0 @@
---- a/arch/arm/boot/dts/qcom-ipq8064.dtsi
-+++ b/arch/arm/boot/dts/qcom-ipq8064.dtsi
-@@ -50,6 +50,7 @@
- 		L2: l2-cache {
- 			compatible = "cache";
- 			cache-level = <2>;
-+			qcom,saw = <&saw_l2>;
- 		};
- 
- 		qcom,l2 {
-@@ -277,17 +278,28 @@
-  		};
- 
- 		saw0: regulator at 2089000 {
--			compatible = "qcom,saw2";
-+			compatible = "qcom,saw2", "syscon";
- 			reg = <0x02089000 0x1000>, <0x02009000 0x1000>;
- 			regulator;
- 		};
- 
- 		saw1: regulator at 2099000 {
--			compatible = "qcom,saw2";
-+			compatible = "qcom,saw2", "syscon";
- 			reg = <0x02099000 0x1000>, <0x02009000 0x1000>;
- 			regulator;
- 		};
- 
-+		saw_l2: regulator at 02012000 {
-+			compatible = "qcom,saw2", "syscon";
-+			reg = <0x02012000 0x1000>;
-+			regulator;
-+		};
-+ 
-+		sic_non_secure: sic-non-secure at 12100000 {
-+			compatible = "syscon";
-+			reg = <0x12100000 0x10000>;
-+		};
-+
- 		gsbi2: gsbi at 12480000 {
- 			compatible = "qcom,gsbi-v1.0.0";
- 			cell-index = <2>;
diff --git a/target/linux/ipq806x/patches-4.4/304-add-cpu-idle-state-into-ipq8064-DT.patch b/target/linux/ipq806x/patches-4.4/304-add-cpu-idle-state-into-ipq8064-DT.patch
deleted file mode 100644
index 42b37ca..0000000
--- a/target/linux/ipq806x/patches-4.4/304-add-cpu-idle-state-into-ipq8064-DT.patch
+++ /dev/null
@@ -1,58 +0,0 @@
-From 3985d2c24d96f72211488fc6ebb53b032e4d0a05 Mon Sep 17 00:00:00 2001
-From: Pavel Kubelun <be.dissent at gmail.com>
-Date: Sun, 6 Nov 2016 19:02:34 +0300
-Subject: [PATCH] ipq806x: add cpu idle state into ipq8064 DT
-
-Signed-off-by: Pavel Kubelun <be.dissent at gmail.com>
----
- arch/arm/boot/dts/qcom-ipq8064.dtsi | 16 ++++++++++++++--
- 1 file changed, 14 insertions(+), 2 deletions(-)
-
---- a/arch/arm/boot/dts/qcom-ipq8064.dtsi
-+++ b/arch/arm/boot/dts/qcom-ipq8064.dtsi
-@@ -18,7 +18,7 @@
- 		#address-cells = <1>;
- 		#size-cells = <0>;
- 
--		cpu at 0 {
-+		cpu0: cpu at 0 {
- 			compatible = "qcom,krait";
- 			enable-method = "qcom,kpss-acc-v1";
- 			device_type = "cpu";
-@@ -31,9 +31,10 @@
- 			clock-latency = <100000>;
- 			cpu-supply = <&smb208_s2a>;
- 			voltage-tolerance = <5>;
-+			cpu-idle-states = <&CPU_SPC>;
- 		};
- 
--		cpu at 1 {
-+		cpu1: cpu at 1 {
- 			compatible = "qcom,krait";
- 			enable-method = "qcom,kpss-acc-v1";
- 			device_type = "cpu";
-@@ -45,6 +46,7 @@
- 			clock-names = "cpu", "l2";
- 			clock-latency = <100000>;
- 			cpu-supply = <&smb208_s2b>;
-+			cpu-idle-states = <&CPU_SPC>;
- 		};
- 
- 		L2: l2-cache {
-@@ -56,6 +58,16 @@
- 		qcom,l2 {
- 			qcom,l2-rates = <384000000 1000000000 1200000000>;
- 		};
-+
-+		idle-states {
-+			CPU_SPC: spc {
-+				compatible = "qcom,idle-state-spc",
-+						"arm,idle-state";
-+				entry-latency-us = <400>;
-+				exit-latency-us = <900>;
-+				min-residency-us = <3000>;
-+			};
-+		};
- 	};
- 
- 	cpu-pmu {
diff --git a/target/linux/ipq806x/patches-4.4/305-add-board-clocks-and-rpmcc-into-DT.patch b/target/linux/ipq806x/patches-4.4/305-add-board-clocks-and-rpmcc-into-DT.patch
deleted file mode 100644
index be45895..0000000
--- a/target/linux/ipq806x/patches-4.4/305-add-board-clocks-and-rpmcc-into-DT.patch
+++ /dev/null
@@ -1,43 +0,0 @@
-From 6da1b6260843da455cad8180c18d020679fd4a46 Mon Sep 17 00:00:00 2001
-From: Pavel Kubelun <be.dissent at gmail.com>
-Date: Sun, 6 Nov 2016 19:07:24 +0300
-Subject: [PATCH] ipq806x: add board clocks and rpmcc into DT
-
-Signed-off-by: Pavel Kubelun <be.dissent at gmail.com>
----
- arch/arm/boot/dts/qcom-ipq8064.dtsi | 17 +++++++++++++++++
- 1 file changed, 17 insertions(+)
-
---- a/arch/arm/boot/dts/qcom-ipq8064.dtsi
-+++ b/arch/arm/boot/dts/qcom-ipq8064.dtsi
-@@ -92,6 +92,18 @@
- 	};
- 
- 	clocks {
-+		cxo_board {
-+			compatible = "fixed-clock";
-+			#clock-cells = <0>;
-+			clock-frequency = <25000000>;
-+		};
-+
-+		pxo_board {
-+			compatible = "fixed-clock";
-+			#clock-cells = <0>;
-+			clock-frequency = <25000000>;
-+		};
-+
- 		sleep_clk: sleep_clk {
- 			compatible = "fixed-clock";
- 			clock-frequency = <32768>;
-@@ -175,6 +187,11 @@
- 			#address-cells = <1>;
- 			#size-cells = <0>;
- 
-+			rpmcc: clock-controller {
-+				compatible	= "qcom,rpmcc-ipq806x", "qcom,rpmcc";
-+				#clock-cells = <1>;
-+			};
-+
- 			regulators {
- 				compatible = "qcom,rpm-smb208-regulators";
- 
diff --git a/target/linux/ipq806x/patches-4.4/306-add-RPM-msg-RAM-into-DT.patch b/target/linux/ipq806x/patches-4.4/306-add-RPM-msg-RAM-into-DT.patch
deleted file mode 100644
index 005f980..0000000
--- a/target/linux/ipq806x/patches-4.4/306-add-RPM-msg-RAM-into-DT.patch
+++ /dev/null
@@ -1,22 +0,0 @@
-From 9bf6b333d6a4d3a3ef0d3fc7ca0becd008c81820 Mon Sep 17 00:00:00 2001
-From: Pavel Kubelun <be.dissent at gmail.com>
-Date: Sun, 6 Nov 2016 19:12:46 +0300
-Subject: [PATCH] ipq806x: add RPM msg RAM into DT
-
-Signed-off-by: Pavel Kubelun <be.dissent at gmail.com>
----
- arch/arm/boot/dts/qcom-ipq8064.dtsi | 3 +++
- 1 file changed, 3 insertions(+)
-
---- a/arch/arm/boot/dts/qcom-ipq8064.dtsi
-+++ b/arch/arm/boot/dts/qcom-ipq8064.dtsi
-@@ -184,6 +184,9 @@
- 					  "err",
- 					  "wakeup";
- 
-+			clocks = <&gcc RPM_MSG_RAM_H_CLK>;
-+			clock-names = "ram";
-+
- 			#address-cells = <1>;
- 			#size-cells = <0>;
- 
diff --git a/target/linux/ipq806x/patches-4.4/307-gcc-Added-the-enable-regs-and-mask-for-PRNG.patch b/target/linux/ipq806x/patches-4.4/307-gcc-Added-the-enable-regs-and-mask-for-PRNG.patch
deleted file mode 100644
index e90f4a6..0000000
--- a/target/linux/ipq806x/patches-4.4/307-gcc-Added-the-enable-regs-and-mask-for-PRNG.patch
+++ /dev/null
@@ -1,25 +0,0 @@
-From dd43e356db678a564ad2cc111962d72ba3162a38 Mon Sep 17 00:00:00 2001
-From: Abhishek Sahu <absahu at codeaurora.org>
-Date: Wed, 18 Nov 2015 12:38:56 +0530
-Subject: ipq806x: gcc: Added the enable regs and mask for PRNG
-
-kernel got hanged while reading from /dev/hwrng at the
-time of PRNG clock enable
-
-Change-Id: I89856c7e19e6639508e6a2774304583a3ec91172
-Signed-off-by: Abhishek Sahu <absahu at codeaurora.org>
----
- drivers/clk/qcom/gcc-ipq806x.c | 2 ++
- 1 file changed, 2 insertions(+)
-
---- a/drivers/clk/qcom/gcc-ipq806x.c
-+++ b/drivers/clk/qcom/gcc-ipq806x.c
-@@ -1240,6 +1240,8 @@ static struct clk_rcg prng_src = {
- 		.parent_map = gcc_pxo_pll8_map,
- 	},
- 	.clkr = {
-+		.enable_reg = 0x2e80,
-+		.enable_mask = BIT(11),
- 		.hw.init = &(struct clk_init_data){
- 			.name = "prng_src",
- 			.parent_names = gcc_pxo_pll8,
diff --git a/target/linux/ipq806x/patches-4.4/308-soc-qcom-ipq806x-Increase-Atomic-Coherent-Pool-size.patch b/target/linux/ipq806x/patches-4.4/308-soc-qcom-ipq806x-Increase-Atomic-Coherent-Pool-size.patch
deleted file mode 100644
index 1c997ab..0000000
--- a/target/linux/ipq806x/patches-4.4/308-soc-qcom-ipq806x-Increase-Atomic-Coherent-Pool-size.patch
+++ /dev/null
@@ -1,52 +0,0 @@
-From 689a8f1ec58a88152669d21572a1539ad34024cb Mon Sep 17 00:00:00 2001
-From: Varadarajan Narayanan <varada at codeaurora.org>
-Date: Mon, 30 Mar 2015 13:25:21 +0530
-Subject: soc: qcom: ipq806x: Increase Atomic Coherent Pool size
-
-Linux 3.14, by default allocates a 256K Atomic Coherent Pool.
-However, Linux 3.4 seems to have allocated ~1.8M for the same.
-256K doesn't seem to be enough for the WiFi driver. Hence,
-setting the size to be similar to 3.4.
-
-CRs-Fixed: 810357
-
-Change-Id: I5b98a8531dcb33aff451a943f8b83402f9d13fa7
-Signed-off-by: Varadarajan Narayanan <varada at codeaurora.org>
----
- arch/arm/mach-qcom/board.c | 20 ++++++++++++++++++++
- 1 file changed, 20 insertions(+)
-
---- a/arch/arm/mach-qcom/board.c
-+++ b/arch/arm/mach-qcom/board.c
-@@ -12,6 +12,11 @@
- 
- #include <linux/init.h>
- 
-+#include <linux/err.h>
-+#include <linux/io.h>
-+#include <linux/module.h>
-+#include <linux/dma-mapping.h>
-+
- #include <asm/mach/arch.h>
- 
- static const char * const qcom_dt_match[] __initconst = {
-@@ -28,3 +33,19 @@ static const char * const qcom_dt_match[
- DT_MACHINE_START(QCOM_DT, "Qualcomm (Flattened Device Tree)")
- 	.dt_compat = qcom_dt_match,
- MACHINE_END
-+
-+
-+static int __init qcom_atomic_pool_size_set(void)
-+{
-+#define ATOMIC_DMA_COHERENT_POOL_SIZE	SZ_2M
-+
-+	init_dma_coherent_pool_size(ATOMIC_DMA_COHERENT_POOL_SIZE);
-+
-+	return 0;
-+}
-+
-+/*
-+ * This should happen before atomic_pool_init(), which is a
-+ * postcore_initcall.
-+ */
-+core_initcall(qcom_atomic_pool_size_set);
diff --git a/target/linux/ipq806x/patches-4.4/309-clk-gcc-add-tsens-child-node.patch b/target/linux/ipq806x/patches-4.4/309-clk-gcc-add-tsens-child-node.patch
deleted file mode 100644
index 0eae3e7..0000000
--- a/target/linux/ipq806x/patches-4.4/309-clk-gcc-add-tsens-child-node.patch
+++ /dev/null
@@ -1,38 +0,0 @@
-From 856371ca1561ca9b3280cc323ff296c7c5e1fa93 Mon Sep 17 00:00:00 2001
-From: Pavel Kubelun <be.dissent at gmail.com>
-Date: Tue, 22 Nov 2016 17:37:56 +0300
-Subject: [PATCH] ipq806x: clk: gcc: add tsens child node
-
-Thermal sensors in ipq806x are inside a Global clock controller.
-Add a child node into it to be used by the TSENS driver.
-
-Signed-off-by: Pavel Kubelun <be.dissent at gmail.com>
-
----
- drivers/clk/qcom/gcc-ipq806x.c | 8 ++++++++
- 1 file changed, 8 insertions(+)
-
---- a/drivers/clk/qcom/gcc-ipq806x.c
-+++ b/drivers/clk/qcom/gcc-ipq806x.c
-@@ -3109,6 +3109,7 @@ MODULE_DEVICE_TABLE(of, gcc_ipq806x_matc
- static int gcc_ipq806x_probe(struct platform_device *pdev)
- {
- 	struct device *dev = &pdev->dev;
-+	struct platform_device *tsens;
- 	struct regmap *regmap;
- 	int ret;
- 
-@@ -3138,6 +3139,13 @@ static int gcc_ipq806x_probe(struct plat
- 	regmap_write(regmap, 0x3cf8, 8);
- 	regmap_write(regmap, 0x3d18, 8);
- 
-+	tsens = platform_device_register_data(&pdev->dev, "qcom-tsens", -1,
-+					      NULL, 0);
-+	if (IS_ERR(tsens))
-+		return PTR_ERR(tsens);
-+
-+	platform_set_drvdata(pdev, tsens);
-+
- 	return 0;
- }
- 
diff --git a/target/linux/ipq806x/patches-4.4/310-add-necessary-thermal-data.patch b/target/linux/ipq806x/patches-4.4/310-add-necessary-thermal-data.patch
deleted file mode 100644
index b2564a5..0000000
--- a/target/linux/ipq806x/patches-4.4/310-add-necessary-thermal-data.patch
+++ /dev/null
@@ -1,150 +0,0 @@
---- a/arch/arm/boot/dts/qcom-ipq8064.dtsi
-+++ b/arch/arm/boot/dts/qcom-ipq8064.dtsi
-@@ -31,6 +31,9 @@
- 			clock-latency = <100000>;
- 			cpu-supply = <&smb208_s2a>;
- 			voltage-tolerance = <5>;
-+			cooling-min-state = <0>;
-+			cooling-max-state = <10>;
-+			#cooling-cells = <2>;
- 			cpu-idle-states = <&CPU_SPC>;
- 		};
- 
-@@ -46,6 +49,9 @@
- 			clock-names = "cpu", "l2";
- 			clock-latency = <100000>;
- 			cpu-supply = <&smb208_s2b>;
-+			cooling-min-state = <0>;
-+			cooling-max-state = <10>;
-+			#cooling-cells = <2>;
- 			cpu-idle-states = <&CPU_SPC>;
- 		};
- 
-@@ -70,6 +76,92 @@
- 		};
- 	};
- 
-+	thermal-zones {
-+		cpu-thermal0 {
-+			polling-delay-passive = <250>;
-+			polling-delay = <1000>;
-+
-+			thermal-sensors = <&gcc 5>;
-+			coefficients = <1132 0>;
-+
-+			trips {
-+				cpu_alert0: trip0 {
-+					temperature = <75000>;
-+					hysteresis = <2000>;
-+					type = "passive";
-+				};
-+				cpu_crit0: trip1 {
-+					temperature = <110000>;
-+					hysteresis = <2000>;
-+					type = "critical";
-+				};
-+			};
-+		};
-+
-+		cpu-thermal1 {
-+			polling-delay-passive = <250>;
-+			polling-delay = <1000>;
-+
-+			thermal-sensors = <&gcc 6>;
-+			coefficients = <1132 0>;
-+
-+			trips {
-+				cpu_alert1: trip0 {
-+					temperature = <75000>;
-+					hysteresis = <2000>;
-+					type = "passive";
-+				};
-+				cpu_crit1: trip1 {
-+					temperature = <110000>;
-+					hysteresis = <2000>;
-+					type = "critical";
-+				};
-+			};
-+		};
-+
-+		cpu-thermal2 {
-+			polling-delay-passive = <250>;
-+			polling-delay = <1000>;
-+
-+			thermal-sensors = <&gcc 7>;
-+			coefficients = <1199 0>;
-+
-+			trips {
-+				cpu_alert2: trip0 {
-+					temperature = <75000>;
-+					hysteresis = <2000>;
-+					type = "passive";
-+				};
-+				cpu_crit2: trip1 {
-+					temperature = <110000>;
-+					hysteresis = <2000>;
-+					type = "critical";
-+				};
-+			};
-+		};
-+
-+		cpu-thermal3 {
-+			polling-delay-passive = <250>;
-+			polling-delay = <1000>;
-+
-+			thermal-sensors = <&gcc 8>;
-+			coefficients = <1132 0>;
-+
-+			trips {
-+				cpu_alert3: trip0 {
-+					temperature = <75000>;
-+					hysteresis = <2000>;
-+					type = "passive";
-+				};
-+				cpu_crit3: trip1 {
-+					temperature = <110000>;
-+					hysteresis = <2000>;
-+					type = "critical";
-+				};
-+			};
-+		};
-+	};
-+
- 	cpu-pmu {
- 		compatible = "qcom,krait-pmu";
- 		interrupts = <1 10 0x304>;
-@@ -172,6 +264,21 @@
- 			reg-names = "lpass-lpaif";
- 		};
- 
-+		qfprom: qfprom at 700000 {
-+			compatible = "qcom,qfprom", "syscon";
-+			reg = <0x00700000 0x1000>;
-+			#address-cells = <1>;
-+			#size-cells = <1>;
-+			ranges;
-+
-+			tsens_calib: calib {
-+				reg = <0x400 0x10>;
-+			};
-+			tsens_backup: backup_calib {
-+				reg = <0x410 0x10>;
-+			};
-+		};
-+
- 		rpm at 108000 {
- 			compatible = "qcom,rpm-ipq8064";
- 			reg = <0x108000 0x1000>;
-@@ -499,8 +606,12 @@
- 		gcc: clock-controller at 900000 {
- 			compatible = "qcom,gcc-ipq8064";
- 			reg = <0x00900000 0x4000>;
-+			nvmem-cells = <&tsens_calib>, <&tsens_backup>;
-+			nvmem-cell-names = "calib", "calib_backup";
- 			#clock-cells = <1>;
- 			#reset-cells = <1>;
-+			#power-domain-cells = <1>;
-+			#thermal-sensor-cells = <1>;
- 		};
- 
- 		tcsr: syscon at 1a400000 {
diff --git a/target/linux/ipq806x/patches-4.4/311-add-rpmcc-for-ipq806x.patch b/target/linux/ipq806x/patches-4.4/311-add-rpmcc-for-ipq806x.patch
deleted file mode 100644
index bb9dd87..0000000
--- a/target/linux/ipq806x/patches-4.4/311-add-rpmcc-for-ipq806x.patch
+++ /dev/null
@@ -1,81 +0,0 @@
---- a/Documentation/devicetree/bindings/clock/qcom,rpmcc.txt
-+++ b/Documentation/devicetree/bindings/clock/qcom,rpmcc.txt
-@@ -12,6 +12,7 @@ Required properties :
- 
- 			"qcom,rpmcc-msm8916", "qcom,rpmcc"
- 			"qcom,rpmcc-apq8064", "qcom,rpmcc"
-+			"qcom,rpmcc-ipq806x", "qcom,rpmcc"
- 
- - #clock-cells : shall contain 1
- 
---- a/drivers/clk/qcom/clk-rpm.c
-+++ b/drivers/clk/qcom/clk-rpm.c
-@@ -359,6 +359,16 @@ DEFINE_CLK_RPM(apq8064, sfab_clk, sfab_a
- DEFINE_CLK_RPM(apq8064, sfpb_clk, sfpb_a_clk, QCOM_RPM_SFPB_CLK);
- DEFINE_CLK_RPM(apq8064, qdss_clk, qdss_a_clk, QCOM_RPM_QDSS_CLK);
- 
-+/* ipq806x */
-+DEFINE_CLK_RPM(ipq806x, afab_clk, afab_a_clk, QCOM_RPM_APPS_FABRIC_CLK);
-+DEFINE_CLK_RPM(ipq806x, cfpb_clk, cfpb_a_clk, QCOM_RPM_CFPB_CLK);
-+DEFINE_CLK_RPM(ipq806x, daytona_clk, daytona_a_clk, QCOM_RPM_DAYTONA_FABRIC_CLK);
-+DEFINE_CLK_RPM(ipq806x, ebi1_clk, ebi1_a_clk, QCOM_RPM_EBI1_CLK);
-+DEFINE_CLK_RPM(ipq806x, sfab_clk, sfab_a_clk, QCOM_RPM_SYS_FABRIC_CLK);
-+DEFINE_CLK_RPM(ipq806x, sfpb_clk, sfpb_a_clk, QCOM_RPM_SFPB_CLK);
-+DEFINE_CLK_RPM(ipq806x, nss_fabric_0_clk, nss_fabric_0_a_clk, QCOM_RPM_NSS_FABRIC_0_CLK);
-+DEFINE_CLK_RPM(ipq806x, nss_fabric_1_clk, nss_fabric_1_a_clk, QCOM_RPM_NSS_FABRIC_1_CLK);
-+
- static struct clk_rpm *apq8064_clks[] = {
- 	[RPM_APPS_FABRIC_CLK] = &apq8064_afab_clk,
- 	[RPM_APPS_FABRIC_A_CLK] = &apq8064_afab_a_clk,
-@@ -380,13 +390,38 @@ static struct clk_rpm *apq8064_clks[] =
- 	[RPM_QDSS_A_CLK] = &apq8064_qdss_a_clk,
- };
- 
-+static struct clk_rpm *ipq806x_clks[] = {
-+	[RPM_APPS_FABRIC_CLK] = &ipq806x_afab_clk,
-+	[RPM_APPS_FABRIC_A_CLK] = &ipq806x_afab_a_clk,
-+	[RPM_CFPB_CLK] = &ipq806x_cfpb_clk,
-+	[RPM_CFPB_A_CLK] = &ipq806x_cfpb_a_clk,
-+	[RPM_DAYTONA_FABRIC_CLK] = &ipq806x_daytona_clk,
-+	[RPM_DAYTONA_FABRIC_A_CLK] = &ipq806x_daytona_a_clk,
-+	[RPM_EBI1_CLK] = &ipq806x_ebi1_clk,
-+	[RPM_EBI1_A_CLK] = &ipq806x_ebi1_a_clk,
-+	[RPM_SYS_FABRIC_CLK] = &ipq806x_sfab_clk,
-+	[RPM_SYS_FABRIC_A_CLK] = &ipq806x_sfab_a_clk,
-+	[RPM_SFPB_CLK] = &ipq806x_sfpb_clk,
-+	[RPM_SFPB_A_CLK] = &ipq806x_sfpb_a_clk,
-+	[RPM_NSS_FABRIC_0_CLK] = &ipq806x_nss_fabric_0_clk,
-+	[RPM_NSS_FABRIC_0_A_CLK] = &ipq806x_nss_fabric_0_a_clk,
-+	[RPM_NSS_FABRIC_1_CLK] = &ipq806x_nss_fabric_1_clk,
-+	[RPM_NSS_FABRIC_1_A_CLK] = &ipq806x_nss_fabric_1_a_clk,
-+};
-+
- static const struct rpm_clk_desc rpm_clk_apq8064 = {
- 	.clks = apq8064_clks,
- 	.num_clks = ARRAY_SIZE(apq8064_clks),
- };
- 
-+static const struct rpm_clk_desc rpm_clk_ipq806x = {
-+	.clks = ipq806x_clks,
-+	.num_clks = ARRAY_SIZE(ipq806x_clks),
-+};
-+
- static const struct of_device_id rpm_clk_match_table[] = {
- 	{ .compatible = "qcom,rpmcc-apq8064", .data = &rpm_clk_apq8064 },
-+	{ .compatible = "qcom,rpmcc-ipq806x", .data = &rpm_clk_ipq806x },
- 	{ }
- };
- MODULE_DEVICE_TABLE(of, rpm_clk_match_table);
---- a/include/dt-bindings/clock/qcom,rpmcc.h
-+++ b/include/dt-bindings/clock/qcom,rpmcc.h
-@@ -37,6 +37,10 @@
- #define RPM_SYS_FABRIC_A_CLK			19
- #define RPM_SFPB_CLK				20
- #define RPM_SFPB_A_CLK				21
-+#define RPM_NSS_FABRIC_0_CLK				22
-+#define RPM_NSS_FABRIC_0_A_CLK				23
-+#define RPM_NSS_FABRIC_1_CLK				24
-+#define RPM_NSS_FABRIC_1_A_CLK				25
- 
- /* msm8916 */
- #define RPM_SMD_XO_CLK_SRC				0
diff --git a/target/linux/ipq806x/patches-4.4/315-disable-usb3-phy-suspend.patch b/target/linux/ipq806x/patches-4.4/315-disable-usb3-phy-suspend.patch
deleted file mode 100644
index 4b5d480..0000000
--- a/target/linux/ipq806x/patches-4.4/315-disable-usb3-phy-suspend.patch
+++ /dev/null
@@ -1,36 +0,0 @@
---- a/arch/arm/boot/dts/qcom-ipq8064.dtsi
-+++ b/arch/arm/boot/dts/qcom-ipq8064.dtsi
-@@ -678,6 +678,8 @@
- 			clocks = <&gcc USB30_0_MASTER_CLK>;
- 			clock-names = "core";
- 
-+			syscon-tcsr = <&tcsr 0xb0 1>;
-+
- 			ranges;
- 
- 			status = "disabled";
-@@ -689,6 +691,7 @@
- 				phys = <&hs_phy_0>, <&ss_phy_0>;
- 				phy-names = "usb2-phy", "usb3-phy";
- 				dr_mode = "host";
-+				snps,dis_u3_susphy_quirk;
- 			};
- 		};
- 
-@@ -699,6 +702,8 @@
- 			clocks = <&gcc USB30_1_MASTER_CLK>;
- 			clock-names = "core";
- 
-+			syscon-tcsr = <&tcsr 0xb0 0>;
-+
- 			ranges;
- 
- 			status = "disabled";
-@@ -710,6 +715,7 @@
- 				phys = <&hs_phy_1>, <&ss_phy_1>;
- 				phy-names = "usb2-phy", "usb3-phy";
- 				dr_mode = "host";
-+				snps,dis_u3_susphy_quirk;
- 			};
- 		};
- 
diff --git a/target/linux/ipq806x/patches-4.4/316-dt-add-prng-support.patch b/target/linux/ipq806x/patches-4.4/316-dt-add-prng-support.patch
deleted file mode 100644
index f2faf64..0000000
--- a/target/linux/ipq806x/patches-4.4/316-dt-add-prng-support.patch
+++ /dev/null
@@ -1,16 +0,0 @@
---- a/arch/arm/boot/dts/qcom-ipq8064.dtsi
-+++ b/arch/arm/boot/dts/qcom-ipq8064.dtsi
-@@ -336,6 +336,13 @@
- 			};
- 		};
- 
-+		rng at 1a500000 {
-+			compatible = "qcom,prng";
-+			reg = <0x1a500000 0x200>;
-+			clocks = <&gcc PRNG_CLK>;
-+			clock-names = "core";
-+		};
-+
- 		qcom_pinmux: pinmux at 800000 {
- 			compatible = "qcom,ipq8064-pinctrl";
- 			reg = <0x800000 0x4000>;
diff --git a/target/linux/ipq806x/patches-4.4/400-dsa-add-qca.patch b/target/linux/ipq806x/patches-4.4/400-dsa-add-qca.patch
deleted file mode 100644
index 1cadba2..0000000
--- a/target/linux/ipq806x/patches-4.4/400-dsa-add-qca.patch
+++ /dev/null
@@ -1,1068 +0,0 @@
-From patchwork Fri May 29 01:42:16 2015
-Content-Type: text/plain; charset="utf-8"
-MIME-Version: 1.0
-Content-Transfer-Encoding: 7bit
-Subject: [1/7] net: dsa: add new driver for ar8xxx family
-From: Mathieu Olivari <mathieu at codeaurora.org>
-X-Patchwork-Id: 477523
-X-Patchwork-Delegate: davem at davemloft.net
-Message-Id: <1432863742-18427-2-git-send-email-mathieu at codeaurora.org>
-To: robh+dt at kernel.org, pawel.moll at arm.com, mark.rutland at arm.com,
- ijc+devicetree at hellion.org.uk, galak at codeaurora.org,
- davem at davemloft.net, mathieu at codeaurora.org, andrew at lunn.ch,
- f.fainelli at gmail.com, linux at roeck-us.net, gang.chen.5i5j at gmail.com,
- jiri at resnulli.us, leitec at staticky.com, fabf at skynet.be,
- alexander.h.duyck at intel.com, pavel.nakonechny at skitlab.ru,
- joe at perches.com, sfeldma at gmail.com, nbd at nbd.name, juhosg at openwrt.org
-Cc: devicetree at vger.kernel.org, linux-kernel at vger.kernel.org,
- netdev at vger.kernel.org
-Date: Thu, 28 May 2015 18:42:16 -0700
-
-This patch contains initial init & registration code for QCA8337. It
-will detect a QCA8337 switch, if present and declared in DT/platform.
-
-Each port will be represented through a standalone net_device interface,
-as for other DSA switches. CPU can communicate with any of the ports by
-setting an IP@ on ethN interface. Ports cannot communicate with each
-other just yet.
-
-Link status will be reported through polling, and we don't use any
-encapsulation.
-
-Signed-off-by: Mathieu Olivari <mathieu at codeaurora.org>
----
- drivers/net/dsa/Kconfig  |   7 ++
- drivers/net/dsa/Makefile |   1 +
- drivers/net/dsa/ar8xxx.c | 303 +++++++++++++++++++++++++++++++++++++++++++++++
- drivers/net/dsa/ar8xxx.h |  82 +++++++++++++
- net/dsa/dsa.c            |   1 +
- 5 files changed, 394 insertions(+)
- create mode 100644 drivers/net/dsa/ar8xxx.c
- create mode 100644 drivers/net/dsa/ar8xxx.h
-
---- a/drivers/net/dsa/Kconfig
-+++ b/drivers/net/dsa/Kconfig
-@@ -65,4 +65,13 @@ config NET_DSA_BCM_SF2
- 	  This enables support for the Broadcom Starfighter 2 Ethernet
- 	  switch chips.
- 
-+config NET_DSA_AR8XXX
-+	tristate "Qualcomm Atheros AR8XXX Ethernet switch family support"
-+	depends on NET_DSA
-+	select NET_DSA_TAG_QCA
-+	select REGMAP
-+	---help---
-+	  This enables support for the Qualcomm Atheros AR8XXX Ethernet
-+	  switch chips.
-+
- endmenu
---- a/drivers/net/dsa/Makefile
-+++ b/drivers/net/dsa/Makefile
-@@ -14,3 +14,4 @@ ifdef CONFIG_NET_DSA_MV88E6171
- mv88e6xxx_drv-y += mv88e6171.o
- endif
- obj-$(CONFIG_NET_DSA_BCM_SF2)	+= bcm_sf2.o
-+obj-$(CONFIG_NET_DSA_AR8XXX)	+= ar8xxx.o
---- /dev/null
-+++ b/drivers/net/dsa/ar8xxx.c
-@@ -0,0 +1,529 @@
-+/*
-+ * Copyright (C) 2009 Felix Fietkau <nbd at nbd.name>
-+ * Copyright (C) 2011-2012 Gabor Juhos <juhosg at openwrt.org>
-+ * 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/module.h>
-+#include <linux/phy.h>
-+#include <linux/netdevice.h>
-+#include <net/dsa.h>
-+#include <linux/phy.h>
-+#include <linux/of_net.h>
-+#include <linux/of_platform.h>
-+
-+#include "ar8xxx.h"
-+
-+#define MIB_DESC(_s, _o, _n)	\
-+	{			\
-+		.size = (_s),	\
-+		.offset = (_o),	\
-+		.name = (_n),	\
-+	}
-+
-+static const struct ar8xxx_mib_desc ar8327_mib[] = {
-+	MIB_DESC(1, 0x00, "RxBroad"),
-+	MIB_DESC(1, 0x04, "RxPause"),
-+	MIB_DESC(1, 0x08, "RxMulti"),
-+	MIB_DESC(1, 0x0c, "RxFcsErr"),
-+	MIB_DESC(1, 0x10, "RxAlignErr"),
-+	MIB_DESC(1, 0x14, "RxRunt"),
-+	MIB_DESC(1, 0x18, "RxFragment"),
-+	MIB_DESC(1, 0x1c, "Rx64Byte"),
-+	MIB_DESC(1, 0x20, "Rx128Byte"),
-+	MIB_DESC(1, 0x24, "Rx256Byte"),
-+	MIB_DESC(1, 0x28, "Rx512Byte"),
-+	MIB_DESC(1, 0x2c, "Rx1024Byte"),
-+	MIB_DESC(1, 0x30, "Rx1518Byte"),
-+	MIB_DESC(1, 0x34, "RxMaxByte"),
-+	MIB_DESC(1, 0x38, "RxTooLong"),
-+	MIB_DESC(2, 0x3c, "RxGoodByte"),
-+	MIB_DESC(2, 0x44, "RxBadByte"),
-+	MIB_DESC(1, 0x4c, "RxOverFlow"),
-+	MIB_DESC(1, 0x50, "Filtered"),
-+	MIB_DESC(1, 0x54, "TxBroad"),
-+	MIB_DESC(1, 0x58, "TxPause"),
-+	MIB_DESC(1, 0x5c, "TxMulti"),
-+	MIB_DESC(1, 0x60, "TxUnderRun"),
-+	MIB_DESC(1, 0x64, "Tx64Byte"),
-+	MIB_DESC(1, 0x68, "Tx128Byte"),
-+	MIB_DESC(1, 0x6c, "Tx256Byte"),
-+	MIB_DESC(1, 0x70, "Tx512Byte"),
-+	MIB_DESC(1, 0x74, "Tx1024Byte"),
-+	MIB_DESC(1, 0x78, "Tx1518Byte"),
-+	MIB_DESC(1, 0x7c, "TxMaxByte"),
-+	MIB_DESC(1, 0x80, "TxOverSize"),
-+	MIB_DESC(2, 0x84, "TxByte"),
-+	MIB_DESC(1, 0x8c, "TxCollision"),
-+	MIB_DESC(1, 0x90, "TxAbortCol"),
-+	MIB_DESC(1, 0x94, "TxMultiCol"),
-+	MIB_DESC(1, 0x98, "TxSingleCol"),
-+	MIB_DESC(1, 0x9c, "TxExcDefer"),
-+	MIB_DESC(1, 0xa0, "TxDefer"),
-+	MIB_DESC(1, 0xa4, "TxLateCol"),
-+};
-+
-+u32
-+ar8xxx_mii_read32(struct mii_bus *bus, int phy_id, int regnum)
-+{
-+	u16 lo, hi;
-+
-+	lo = bus->read(bus, phy_id, regnum);
-+	hi = bus->read(bus, phy_id, regnum + 1);
-+
-+	return (hi << 16) | lo;
-+}
-+
-+void
-+ar8xxx_mii_write32(struct mii_bus *bus, int phy_id, int regnum, u32 val)
-+{
-+	u16 lo, hi;
-+
-+	lo = val & 0xffff;
-+	hi = (u16)(val >> 16);
-+
-+	bus->write(bus, phy_id, regnum, lo);
-+	bus->write(bus, phy_id, regnum + 1, hi);
-+}
-+
-+u32 ar8xxx_read(struct dsa_switch *ds, int reg)
-+{
-+	struct mii_bus *bus = dsa_host_dev_to_mii_bus(ds->master_dev);
-+	u16 r1, r2, page;
-+	u32 val;
-+
-+	split_addr((u32)reg, &r1, &r2, &page);
-+
-+	mutex_lock(&bus->mdio_lock);
-+
-+	bus->write(bus, 0x18, 0, page);
-+	wait_for_page_switch();
-+	val = ar8xxx_mii_read32(bus, 0x10 | r2, r1);
-+
-+	mutex_unlock(&bus->mdio_lock);
-+
-+	return val;
-+}
-+
-+void ar8xxx_write(struct dsa_switch *ds, int reg, u32 val)
-+{
-+	struct mii_bus *bus = dsa_host_dev_to_mii_bus(ds->master_dev);
-+	u16 r1, r2, page;
-+
-+	split_addr((u32)reg, &r1, &r2, &page);
-+
-+	mutex_lock(&bus->mdio_lock);
-+
-+	bus->write(bus, 0x18, 0, page);
-+	wait_for_page_switch();
-+	ar8xxx_mii_write32(bus, 0x10 | r2, r1, val);
-+
-+	mutex_unlock(&bus->mdio_lock);
-+}
-+
-+u32
-+ar8xxx_rmw(struct dsa_switch *ds, int reg, u32 mask, u32 val)
-+{
-+	struct mii_bus *bus = dsa_host_dev_to_mii_bus(ds->master_dev);
-+	u16 r1, r2, page;
-+	u32 ret;
-+
-+	split_addr((u32)reg, &r1, &r2, &page);
-+
-+	mutex_lock(&bus->mdio_lock);
-+
-+	bus->write(bus, 0x18, 0, page);
-+	wait_for_page_switch();
-+
-+	ret = ar8xxx_mii_read32(bus, 0x10 | r2, r1);
-+	ret &= ~mask;
-+	ret |= val;
-+	ar8xxx_mii_write32(bus, 0x10 | r2, r1, ret);
-+
-+	mutex_unlock(&bus->mdio_lock);
-+
-+	return ret;
-+}
-+
-+static char *ar8xxx_probe(struct device *host_dev, int sw_addr)
-+{
-+	struct mii_bus *bus = dsa_host_dev_to_mii_bus(host_dev);
-+	u32 phy_id;
-+
-+	if (!bus)
-+		return NULL;
-+
-+	/* sw_addr is irrelevant as the switch occupies the MDIO bus from
-+	 * addresses 0 to 4 (PHYs) and 16-23 (for MDIO 32bits protocol). So
-+	 * we'll probe address 0 to see if we see the right switch family.
-+	 */
-+	phy_id = mdiobus_read(bus, 0, MII_PHYSID1) << 16;
-+	phy_id |= mdiobus_read(bus, 0, MII_PHYSID2);
-+
-+	switch (phy_id) {
-+	case PHY_ID_QCA8337:
-+		return "QCA8337";
-+	default:
-+		return NULL;
-+	}
-+}
-+
-+static int ar8xxx_regmap_read(void *ctx, uint32_t reg, uint32_t *val)
-+{
-+	struct dsa_switch *ds = (struct dsa_switch *)ctx;
-+
-+	*val = ar8xxx_read(ds, reg);
-+
-+	return 0;
-+}
-+
-+static int ar8xxx_regmap_write(void *ctx, uint32_t reg, uint32_t val)
-+{
-+	struct dsa_switch *ds = (struct dsa_switch *)ctx;
-+
-+	ar8xxx_write(ds, reg, val);
-+
-+	return 0;
-+}
-+
-+static const struct regmap_range ar8xxx_readable_ranges[] = {
-+	regmap_reg_range(0x0000, 0x00e4), /* Global control */
-+	regmap_reg_range(0x0100, 0x0168), /* EEE control */
-+	regmap_reg_range(0x0200, 0x0270), /* Parser control */
-+	regmap_reg_range(0x0400, 0x0454), /* ACL */
-+	regmap_reg_range(0x0600, 0x0718), /* Lookup */
-+	regmap_reg_range(0x0800, 0x0b70), /* QM */
-+	regmap_reg_range(0x0C00, 0x0c80), /* PKT */
-+	regmap_reg_range(0x1000, 0x10ac), /* MIB - Port0 */
-+	regmap_reg_range(0x1100, 0x11ac), /* MIB - Port1 */
-+	regmap_reg_range(0x1200, 0x12ac), /* MIB - Port2 */
-+	regmap_reg_range(0x1300, 0x13ac), /* MIB - Port3 */
-+	regmap_reg_range(0x1400, 0x14ac), /* MIB - Port4 */
-+	regmap_reg_range(0x1500, 0x15ac), /* MIB - Port5 */
-+	regmap_reg_range(0x1600, 0x16ac), /* MIB - Port6 */
-+
-+};
-+
-+static struct regmap_access_table ar8xxx_readable_table = {
-+	.yes_ranges = ar8xxx_readable_ranges,
-+	.n_yes_ranges = ARRAY_SIZE(ar8xxx_readable_ranges),
-+};
-+
-+struct regmap_config ar8xxx_regmap_config = {
-+	.reg_bits = 16,
-+	.val_bits = 32,
-+	.reg_stride = 4,
-+	.max_register = 0x16ac, /* end MIB - Port6 range */
-+	.reg_read = ar8xxx_regmap_read,
-+	.reg_write = ar8xxx_regmap_write,
-+	.rd_table = &ar8xxx_readable_table,
-+};
-+
-+static int ar8xxx_set_pad_ctrl(struct dsa_switch *ds, int port, int mode)
-+{
-+	int reg;
-+
-+	switch (port) {
-+	case 0:
-+		reg = AR8327_REG_PORT0_PAD_CTRL;
-+		break;
-+	case 6:
-+		reg = AR8327_REG_PORT6_PAD_CTRL;
-+		break;
-+	default:
-+		pr_err("Can't set PAD_CTRL on port %d\n", port);
-+		return -EINVAL;
-+	}
-+
-+	/* DSA only supports 1 CPU port for now, so we'll take the assumption
-+	 * that P0 is connected to the CPU master_dev.
-+	 */
-+	switch (mode) {
-+	case PHY_INTERFACE_MODE_RGMII:
-+		ar8xxx_write(ds, reg,
-+			     AR8327_PORT_PAD_RGMII_EN |
-+			     AR8327_PORT_PAD_RGMII_TX_DELAY(3) |
-+			     AR8327_PORT_PAD_RGMII_RX_DELAY(3));
-+
-+		/* According to the datasheet, RGMII delay is enabled through
-+		 * PORT5_PAD_CTRL for all ports, rather than individual port
-+		 * registers
-+		 */
-+		ar8xxx_write(ds, AR8327_REG_PORT5_PAD_CTRL,
-+			     AR8327_PORT_PAD_RGMII_RX_DELAY_EN);
-+		break;
-+	case PHY_INTERFACE_MODE_SGMII:
-+		ar8xxx_write(ds, reg, AR8327_PORT_PAD_SGMII_EN);
-+		break;
-+	default:
-+		pr_err("xMII mode %d not supported\n", mode);
-+		return -EINVAL;
-+	}
-+
-+	return 0;
-+}
-+
-+static int ar8xxx_of_setup(struct dsa_switch *ds)
-+{
-+	struct device_node *dn = ds->pd->of_node;
-+	const char *s_phymode;
-+	int ret, mode;
-+	u32 phy_id, ctrl;
-+
-+	/* If port6-phy-mode property exists, configure it accordingly */
-+	if (!of_property_read_string(dn, "qca,port6-phy-mode", &s_phymode)) {
-+		for (mode = 0; mode < PHY_INTERFACE_MODE_MAX; mode++)
-+			if (!strcasecmp(s_phymode, phy_modes(mode)))
-+				break;
-+
-+		if (mode == PHY_INTERFACE_MODE_MAX)
-+			pr_err("Unknown phy-mode: \"%s\"\n", s_phymode);
-+
-+		ret = ar8xxx_set_pad_ctrl(ds, 6, mode);
-+		if (ret < 0)
-+			return ret;
-+	}
-+
-+	/* If a phy ID is specified for PORT6 mac, connect them together */
-+	if (!of_property_read_u32(dn, "qca,port6-phy-id", &phy_id)) {
-+		ar8xxx_rmw(ds, AR8327_PORT_LOOKUP_CTRL(6),
-+			   AR8327_PORT_LOOKUP_MEMBER, BIT(phy_to_port(phy_id)));
-+		ar8xxx_rmw(ds, AR8327_PORT_LOOKUP_CTRL(phy_to_port(phy_id)),
-+			   AR8327_PORT_LOOKUP_MEMBER, BIT(6));
-+
-+		/* We want the switch to be pass-through and act like a PHY on
-+		 * these ports. So BC/MC/UC & IGMP frames need to be accepted
-+		 */
-+		ctrl = BIT(phy_to_port(phy_id)) | BIT(6);
-+		ar8xxx_reg_set(ds, AR8327_REG_GLOBAL_FW_CTRL1,
-+			       ctrl << AR8327_GLOBAL_FW_CTRL1_IGMP_DP_S |
-+			       ctrl << AR8327_GLOBAL_FW_CTRL1_BC_DP_S |
-+			       ctrl << AR8327_GLOBAL_FW_CTRL1_MC_DP_S |
-+			       ctrl << AR8327_GLOBAL_FW_CTRL1_UC_DP_S);
-+	}
-+
-+	return 0;
-+}
-+
-+static int ar8xxx_setup(struct dsa_switch *ds)
-+{
-+	struct ar8xxx_priv *priv = ds_to_priv(ds);
-+	struct net_device *netdev = ds->dst->pd->of_netdev;
-+	int ret, i, phy_mode;
-+
-+	/* Start by setting up the register mapping */
-+	priv->regmap = devm_regmap_init(ds->master_dev, NULL, ds,
-+					&ar8xxx_regmap_config);
-+
-+	if (IS_ERR(priv->regmap))
-+		pr_warn("regmap initialization failed");
-+
-+	/* Initialize CPU port pad mode (xMII type, delays...) */
-+	phy_mode = of_get_phy_mode(netdev->dev.parent->of_node);
-+	if (phy_mode < 0) {
-+		pr_err("Can't find phy-mode for master device\n");
-+		return phy_mode;
-+	}
-+
-+	ret = ar8xxx_set_pad_ctrl(ds, 0, phy_mode);
-+	if (ret < 0)
-+		return ret;
-+
-+	/* Enable CPU Port */
-+	ar8xxx_reg_set(ds, AR8327_REG_GLOBAL_FW_CTRL0,
-+		       AR8327_GLOBAL_FW_CTRL0_CPU_PORT_EN);
-+
-+	/* Enable MIB counters */
-+	ar8xxx_reg_set(ds, AR8327_REG_MIB, AR8327_MIB_CPU_KEEP);
-+	ar8xxx_write(ds, AR8327_REG_MODULE_EN, AR8327_MODULE_EN_MIB);
-+
-+	/* Enable QCA header mode on Port 0 */
-+	ar8xxx_write(ds, AR8327_REG_PORT_HDR_CTRL(0),
-+		     AR8327_PORT_HDR_CTRL_ALL << AR8327_PORT_HDR_CTRL_TX_S |
-+		     AR8327_PORT_HDR_CTRL_ALL << AR8327_PORT_HDR_CTRL_RX_S);
-+
-+	/* Disable forwarding by default on all ports */
-+	for (i = 0; i < AR8327_NUM_PORTS; i++)
-+		ar8xxx_rmw(ds, AR8327_PORT_LOOKUP_CTRL(i),
-+			   AR8327_PORT_LOOKUP_MEMBER, 0);
-+
-+	/* Forward all unknown frames to CPU port for Linux processing */
-+	ar8xxx_write(ds, AR8327_REG_GLOBAL_FW_CTRL1,
-+		     BIT(0) << AR8327_GLOBAL_FW_CTRL1_IGMP_DP_S |
-+		     BIT(0) << AR8327_GLOBAL_FW_CTRL1_BC_DP_S |
-+		     BIT(0) << AR8327_GLOBAL_FW_CTRL1_MC_DP_S |
-+		     BIT(0) << AR8327_GLOBAL_FW_CTRL1_UC_DP_S);
-+
-+	/* Setup connection between CPU ports & PHYs */
-+	for (i = 0; i < DSA_MAX_PORTS; i++) {
-+		/* CPU port gets connected to all PHYs in the switch */
-+		if (dsa_is_cpu_port(ds, i)) {
-+			ar8xxx_rmw(ds, AR8327_PORT_LOOKUP_CTRL(0),
-+				   AR8327_PORT_LOOKUP_MEMBER,
-+				   ds->phys_port_mask << 1);
-+		}
-+
-+		/* Invividual PHYs gets connected to CPU port only */
-+		if (ds->phys_port_mask & BIT(i)) {
-+			int phy = phy_to_port(i);
-+
-+			ar8xxx_rmw(ds, AR8327_PORT_LOOKUP_CTRL(phy),
-+				   AR8327_PORT_LOOKUP_MEMBER, BIT(0));
-+
-+			/* Disable Auto-learning by default so the switch
-+			 * doesn't try to forward the frame to another port
-+			 */
-+			ar8xxx_reg_clear(ds, AR8327_PORT_LOOKUP_CTRL(phy),
-+					 AR8327_PORT_LOOKUP_LEARN);
-+		}
-+	}
-+
-+	ret = ar8xxx_of_setup(ds);
-+	if (ret < 0)
-+		return ret;
-+
-+	return 0;
-+}
-+
-+static int ar8xxx_set_addr(struct dsa_switch *ds, u8 *addr)
-+{
-+	return 0;
-+}
-+
-+static int ar8xxx_phy_read(struct dsa_switch *ds, int phy, int regnum)
-+{
-+	struct mii_bus *bus = dsa_host_dev_to_mii_bus(ds->master_dev);
-+
-+	return mdiobus_read(bus, phy, regnum);
-+}
-+
-+static int
-+ar8xxx_phy_write(struct dsa_switch *ds, int phy, int regnum, u16 val)
-+{
-+	struct mii_bus *bus = dsa_host_dev_to_mii_bus(ds->master_dev);
-+
-+	return mdiobus_write(bus, phy, regnum, val);
-+}
-+
-+static void ar8xxx_get_strings(struct dsa_switch *ds, int phy, uint8_t *data)
-+{
-+	int i;
-+
-+	for (i = 0; i < ARRAY_SIZE(ar8327_mib); i++) {
-+		strncpy(data + i * ETH_GSTRING_LEN, ar8327_mib[i].name,
-+			ETH_GSTRING_LEN);
-+	}
-+}
-+
-+static void ar8xxx_get_ethtool_stats(struct dsa_switch *ds, int phy,
-+				     uint64_t *data)
-+{
-+	const struct ar8xxx_mib_desc *mib;
-+	uint32_t reg, i, port;
-+	u64 hi;
-+
-+	port = phy_to_port(phy);
-+
-+	for (i = 0; i < ARRAY_SIZE(ar8327_mib); i++) {
-+		mib = &ar8327_mib[i];
-+		reg = AR8327_PORT_MIB_COUNTER(port) + mib->offset;
-+
-+		data[i] = ar8xxx_read(ds, reg);
-+		if (mib->size == 2) {
-+			hi = ar8xxx_read(ds, reg + 4);
-+			data[i] |= hi << 32;
-+		}
-+	}
-+}
-+
-+static int ar8xxx_get_sset_count(struct dsa_switch *ds)
-+{
-+	return ARRAY_SIZE(ar8327_mib);
-+}
-+
-+static void ar8xxx_poll_link(struct dsa_switch *ds)
-+{
-+	int i = 0;
-+	struct net_device *dev;
-+
-+	while ((dev = ds->ports[i++]) != NULL) {
-+		u32 status;
-+		int link;
-+		int speed;
-+		int duplex;
-+
-+		status = ar8xxx_read(ds, AR8327_REG_PORT_STATUS(i));
-+		link = !!(status & AR8XXX_PORT_STATUS_LINK_UP);
-+		duplex = !!(status & AR8XXX_PORT_STATUS_DUPLEX);
-+
-+		switch (status & AR8XXX_PORT_STATUS_SPEED) {
-+		case AR8XXX_PORT_SPEED_10M:
-+			speed = 10;
-+			break;
-+		case AR8XXX_PORT_SPEED_100M:
-+			speed = 100;
-+			break;
-+		case AR8XXX_PORT_SPEED_1000M:
-+			speed = 1000;
-+			break;
-+		default:
-+			speed = 0;
-+		}
-+
-+		if (!link) {
-+			/* This poll happens every ~1s, so we don't want to
-+			 * print the status every time. Only when the device
-+			 * transitions from Link UP to Link DOWN
-+			 */
-+			if (netif_carrier_ok(dev))
-+				netif_carrier_off(dev);
-+			continue;
-+		} else {
-+			/* Same thing here. But we detect a Link UP event */
-+			if (!netif_carrier_ok(dev))
-+				netif_carrier_on(dev);
-+			continue;
-+		}
-+	}
-+}
-+
-+static struct dsa_switch_driver ar8xxx_switch_driver = {
-+	.tag_protocol		= DSA_TAG_PROTO_QCA,
-+	.priv_size		= sizeof(struct ar8xxx_priv),
-+	.probe			= ar8xxx_probe,
-+	.setup			= ar8xxx_setup,
-+	.set_addr		= ar8xxx_set_addr,
-+	.poll_link		= ar8xxx_poll_link,
-+	.phy_read		= ar8xxx_phy_read,
-+	.phy_write		= ar8xxx_phy_write,
-+	.get_strings		= ar8xxx_get_strings,
-+	.get_ethtool_stats	= ar8xxx_get_ethtool_stats,
-+	.get_sset_count		= ar8xxx_get_sset_count,
-+};
-+
-+static int __init ar8xxx_init(void)
-+{
-+	register_switch_driver(&ar8xxx_switch_driver);
-+	return 0;
-+}
-+module_init(ar8xxx_init);
-+
-+static void __exit ar8xxx_cleanup(void)
-+{
-+	unregister_switch_driver(&ar8xxx_switch_driver);
-+}
-+module_exit(ar8xxx_cleanup);
-+
-+MODULE_AUTHOR("Mathieu Olivari <mathieu at codeaurora.org>");
-+MODULE_DESCRIPTION("Driver for AR8XXX ethernet switch family");
-+MODULE_LICENSE("GPL");
-+MODULE_ALIAS("platform:ar8xxx");
---- /dev/null
-+++ b/drivers/net/dsa/ar8xxx.h
-@@ -0,0 +1,156 @@
-+/*
-+ * Copyright (C) 2009 Felix Fietkau <nbd at nbd.name>
-+ * Copyright (C) 2011-2012 Gabor Juhos <juhosg at openwrt.org>
-+ * 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.
-+ */
-+
-+#ifndef __AR8XXX_H
-+#define __AR8XXX_H
-+
-+#include <linux/delay.h>
-+#include <linux/regmap.h>
-+
-+struct ar8xxx_priv {
-+	struct regmap *regmap;
-+};
-+
-+struct ar8xxx_mib_desc {
-+	unsigned int size;
-+	unsigned int offset;
-+	const char *name;
-+};
-+
-+#define AR8327_NUM_PORTS		7
-+
-+#define PHY_ID_QCA8337			0x004dd036
-+
-+#define AR8327_REG_PORT0_PAD_CTRL		0x004
-+#define AR8327_REG_PORT5_PAD_CTRL		0x008
-+#define AR8327_REG_PORT6_PAD_CTRL		0x00c
-+#define   AR8327_PORT_PAD_RGMII_EN		BIT(26)
-+#define   AR8327_PORT_PAD_RGMII_TX_DELAY(x)	((0x8 + (x & 0x3)) << 22)
-+#define   AR8327_PORT_PAD_RGMII_RX_DELAY(x)	((0x10 + (x & 0x3)) << 20)
-+#define   AR8327_PORT_PAD_RGMII_RX_DELAY_EN	BIT(24)
-+#define   AR8327_PORT_PAD_SGMII_EN		BIT(7)
-+
-+#define AR8327_REG_MODULE_EN			0x030
-+#define   AR8327_MODULE_EN_MIB			BIT(0)
-+#define	  AR8327_MODULE_EN_ACL			BIT(1)
-+#define	  AR8327_MODULE_EN_L3			BIT(2)
-+
-+#define AR8327_REG_MIB				0x034
-+#define   AR8327_MIB_CPU_KEEP			BIT(20)
-+
-+#define AR8327_REG_PORT_STATUS(_i)		(0x07c + (_i) * 4)
-+#define   AR8XXX_PORT_STATUS_SPEED	GENMASK(2, 0)
-+#define   AR8XXX_PORT_STATUS_SPEED_S	0
-+#define   AR8XXX_PORT_STATUS_TXMAC	BIT(2)
-+#define   AR8XXX_PORT_STATUS_RXMAC	BIT(3)
-+#define   AR8XXX_PORT_STATUS_TXFLOW	BIT(4)
-+#define   AR8XXX_PORT_STATUS_RXFLOW	BIT(5)
-+#define   AR8XXX_PORT_STATUS_DUPLEX	BIT(6)
-+#define   AR8XXX_PORT_STATUS_LINK_UP	BIT(8)
-+#define   AR8XXX_PORT_STATUS_LINK_AUTO	BIT(9)
-+#define   AR8XXX_PORT_STATUS_LINK_PAUSE	BIT(10)
-+
-+#define AR8327_REG_PORT_HDR_CTRL(_i)		(0x9c + (_i * 4))
-+#define   AR8327_PORT_HDR_CTRL_RX_MASK		GENMASK(3, 2)
-+#define   AR8327_PORT_HDR_CTRL_RX_S		2
-+#define   AR8327_PORT_HDR_CTRL_TX_MASK		GENMASK(1, 0)
-+#define   AR8327_PORT_HDR_CTRL_TX_S		0
-+#define   AR8327_PORT_HDR_CTRL_ALL		2
-+#define   AR8327_PORT_HDR_CTRL_MGMT		1
-+#define   AR8327_PORT_HDR_CTRL_NONE		0
-+
-+#define AR8327_REG_GLOBAL_FW_CTRL0		0x620
-+#define   AR8327_GLOBAL_FW_CTRL0_CPU_PORT_EN	BIT(10)
-+
-+#define AR8327_REG_GLOBAL_FW_CTRL1		0x624
-+#define   AR8327_GLOBAL_FW_CTRL1_IGMP_DP_MASK	GENMASK(30, 24)
-+#define   AR8327_GLOBAL_FW_CTRL1_IGMP_DP_S	24
-+#define   AR8327_GLOBAL_FW_CTRL1_BC_DP_MASK	GENMASK(22, 16)
-+#define   AR8327_GLOBAL_FW_CTRL1_BC_DP_S	16
-+#define   AR8327_GLOBAL_FW_CTRL1_MC_DP_MASK	GENMASK(14, 8)
-+#define   AR8327_GLOBAL_FW_CTRL1_MC_DP_S	8
-+#define   AR8327_GLOBAL_FW_CTRL1_UC_DP_MASK	GENMASK(6, 0)
-+#define   AR8327_GLOBAL_FW_CTRL1_UC_DP_S	0
-+
-+#define AR8327_PORT_LOOKUP_CTRL(_i)		(0x660 + (_i) * 0xc)
-+#define   AR8327_PORT_LOOKUP_MEMBER		GENMASK(6, 0)
-+#define   AR8327_PORT_LOOKUP_IN_MODE		GENMASK(9, 8)
-+#define   AR8327_PORT_LOOKUP_IN_MODE_S		8
-+#define   AR8327_PORT_LOOKUP_STATE		GENMASK(18, 16)
-+#define   AR8327_PORT_LOOKUP_STATE_S		16
-+#define   AR8327_PORT_LOOKUP_LEARN		BIT(20)
-+#define   AR8327_PORT_LOOKUP_ING_MIRROR_EN	BIT(25)
-+
-+#define AR8327_PORT_MIB_COUNTER(_i)		(0x1000 + (_i) * 0x100)
-+
-+/* port speed */
-+enum {
-+	AR8XXX_PORT_SPEED_10M = 0,
-+	AR8XXX_PORT_SPEED_100M = 1,
-+	AR8XXX_PORT_SPEED_1000M = 2,
-+	AR8XXX_PORT_SPEED_ERR = 3,
-+};
-+
-+static inline int port_to_phy(int port)
-+{
-+	if (port >= 1 && port <= 6)
-+		return port - 1;
-+
-+	return -1;
-+}
-+
-+static inline int phy_to_port(int phy)
-+{
-+	if (phy < 5)
-+		return phy + 1;
-+
-+	return -1;
-+}
-+
-+u32
-+ar8xxx_rmw(struct dsa_switch *ds, int reg, u32 mask, u32 val);
-+
-+static inline void
-+split_addr(u32 regaddr, u16 *r1, u16 *r2, u16 *page)
-+{
-+	regaddr >>= 1;
-+	*r1 = regaddr & 0x1e;
-+
-+	regaddr >>= 5;
-+	*r2 = regaddr & 0x7;
-+
-+	regaddr >>= 3;
-+	*page = regaddr & 0x1ff;
-+}
-+
-+static inline void
-+wait_for_page_switch(void)
-+{
-+	udelay(5);
-+}
-+
-+static inline void
-+ar8xxx_reg_set(struct dsa_switch *ds, int reg, u32 val)
-+{
-+	ar8xxx_rmw(ds, reg, 0, val);
-+}
-+
-+static inline void
-+ar8xxx_reg_clear(struct dsa_switch *ds, int reg, u32 val)
-+{
-+	ar8xxx_rmw(ds, reg, val, 0);
-+}
-+
-+#endif /* __AR8XXX_H */
---- a/net/dsa/dsa.c
-+++ b/net/dsa/dsa.c
-@@ -285,6 +285,11 @@ static int dsa_switch_setup_one(struct d
- 			dst->rcv = brcm_netdev_ops.rcv;
- 			break;
- #endif
-+#ifdef CONFIG_NET_DSA_TAG_QCA
-+		case DSA_TAG_PROTO_QCA:
-+			dst->rcv = qca_netdev_ops.rcv;
-+			break;
-+#endif
- 		case DSA_TAG_PROTO_NONE:
- 			break;
- 		default:
-@@ -1041,6 +1046,7 @@ static SIMPLE_DEV_PM_OPS(dsa_pm_ops, dsa
- 
- static const struct of_device_id dsa_of_match_table[] = {
- 	{ .compatible = "brcm,bcm7445-switch-v4.0" },
-+	{ .compatible = "qca,ar8xxx", },
- 	{ .compatible = "marvell,dsa", },
- 	{}
- };
---- a/include/net/dsa.h
-+++ b/include/net/dsa.h
-@@ -26,6 +26,7 @@ enum dsa_tag_protocol {
- 	DSA_TAG_PROTO_TRAILER,
- 	DSA_TAG_PROTO_EDSA,
- 	DSA_TAG_PROTO_BRCM,
-+	DSA_TAG_PROTO_QCA,
- };
- 
- #define DSA_MAX_SWITCHES	4
---- a/net/dsa/Kconfig
-+++ b/net/dsa/Kconfig
-@@ -26,6 +26,9 @@ config NET_DSA_HWMON
- 	  via the hwmon sysfs interface and exposes the onboard sensors.
- 
- # tagging formats
-+config NET_DSA_TAG_QCA
-+	bool
-+
- config NET_DSA_TAG_BRCM
- 	bool
- 
---- a/net/dsa/Makefile
-+++ b/net/dsa/Makefile
-@@ -3,6 +3,7 @@ obj-$(CONFIG_NET_DSA) += dsa_core.o
- dsa_core-y += dsa.o slave.o
- 
- # tagging formats
-+dsa_core-$(CONFIG_NET_DSA_TAG_QCA) += tag_qca.o
- dsa_core-$(CONFIG_NET_DSA_TAG_BRCM) += tag_brcm.o
- dsa_core-$(CONFIG_NET_DSA_TAG_DSA) += tag_dsa.o
- dsa_core-$(CONFIG_NET_DSA_TAG_EDSA) += tag_edsa.o
---- a/net/dsa/dsa_priv.h
-+++ b/net/dsa/dsa_priv.h
-@@ -78,5 +78,7 @@ extern const struct dsa_device_ops trail
- /* tag_brcm.c */
- extern const struct dsa_device_ops brcm_netdev_ops;
- 
-+/* tag_qca.c */
-+extern const struct dsa_device_ops qca_netdev_ops;
- 
- #endif
---- a/net/dsa/slave.c
-+++ b/net/dsa/slave.c
-@@ -1182,6 +1182,11 @@ int dsa_slave_create(struct dsa_switch *
- 		p->xmit = brcm_netdev_ops.xmit;
- 		break;
- #endif
-+#ifdef CONFIG_NET_DSA_TAG_QCA
-+	case DSA_TAG_PROTO_QCA:
-+		p->xmit = qca_netdev_ops.xmit;
-+		break;
-+#endif
- 	default:
- 		p->xmit	= dsa_slave_notag_xmit;
- 		break;
---- /dev/null
-+++ b/net/dsa/tag_qca.c
-@@ -0,0 +1,158 @@
-+/*
-+ * 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/etherdevice.h>
-+#include "dsa_priv.h"
-+
-+#define QCA_HDR_LEN	2
-+#define QCA_HDR_VERSION	0x2
-+
-+#define QCA_HDR_RECV_VERSION_MASK	GENMASK(15, 14)
-+#define QCA_HDR_RECV_VERSION_S		14
-+#define QCA_HDR_RECV_PRIORITY_MASK	GENMASK(13, 11)
-+#define QCA_HDR_RECV_PRIORITY_S		11
-+#define QCA_HDR_RECV_TYPE_MASK		GENMASK(10, 6)
-+#define QCA_HDR_RECV_TYPE_S		6
-+#define QCA_HDR_RECV_FRAME_IS_TAGGED	BIT(3)
-+#define QCA_HDR_RECV_SOURCE_PORT_MASK	GENMASK(2, 0)
-+
-+#define QCA_HDR_XMIT_VERSION_MASK	GENMASK(15, 14)
-+#define QCA_HDR_XMIT_VERSION_S		14
-+#define QCA_HDR_XMIT_PRIORITY_MASK	GENMASK(13, 11)
-+#define QCA_HDR_XMIT_PRIORITY_S		11
-+#define QCA_HDR_XMIT_CONTROL_MASK	GENMASK(10, 8)
-+#define QCA_HDR_XMIT_CONTROL_S		8
-+#define QCA_HDR_XMIT_FROM_CPU		BIT(7)
-+#define QCA_HDR_XMIT_DP_BIT_MASK	GENMASK(6, 0)
-+
-+static inline int reg_to_port(int reg)
-+{
-+	if (reg < 5)
-+		return reg + 1;
-+
-+	return -1;
-+}
-+
-+static inline int port_to_reg(int port)
-+{
-+	if (port >= 1 && port <= 6)
-+		return port - 1;
-+
-+	return -1;
-+}
-+
-+static netdev_tx_t qca_tag_xmit(struct sk_buff *skb, struct net_device *dev)
-+{
-+	struct dsa_slave_priv *p = netdev_priv(dev);
-+	u16 *phdr, hdr;
-+
-+	dev->stats.tx_packets++;
-+	dev->stats.tx_bytes += skb->len;
-+
-+	if (skb_cow_head(skb, 0) < 0)
-+		goto out_free;
-+
-+	skb_push(skb, QCA_HDR_LEN);
-+
-+	memmove(skb->data, skb->data + QCA_HDR_LEN, 2 * ETH_ALEN);
-+	phdr = (u16 *)(skb->data + 2 * ETH_ALEN);
-+
-+	/* Set the version field, and set destination port information */
-+	hdr = QCA_HDR_VERSION << QCA_HDR_XMIT_VERSION_S |
-+		QCA_HDR_XMIT_FROM_CPU |
-+		1 << reg_to_port(p->port);
-+
-+	*phdr = htons(hdr);
-+
-+	skb->dev = p->parent->dst->master_netdev;
-+	dev_queue_xmit(skb);
-+
-+	return NETDEV_TX_OK;
-+
-+out_free:
-+	kfree_skb(skb);
-+	return NETDEV_TX_OK;
-+}
-+
-+static int qca_tag_rcv(struct sk_buff *skb, struct net_device *dev,
-+		       struct packet_type *pt, struct net_device *orig_dev)
-+{
-+	struct dsa_switch_tree *dst = dev->dsa_ptr;
-+	struct dsa_switch *ds;
-+	u8 ver;
-+	int port, phy;
-+	__be16 *phdr, hdr;
-+
-+	if (unlikely(!dst))
-+		goto out_drop;
-+
-+	skb = skb_unshare(skb, GFP_ATOMIC);
-+	if (!skb)
-+		goto out;
-+
-+	if (unlikely(!pskb_may_pull(skb, QCA_HDR_LEN)))
-+		goto out_drop;
-+
-+	/* Ethernet is added by the switch between src addr and Ethertype
-+	 * At this point, skb->data points to ethertype so header should be
-+	 * right before
-+	 */
-+	phdr = (__be16 *)(skb->data - 2);
-+	hdr = ntohs(*phdr);
-+
-+	/* Make sure the version is correct */
-+	ver = (hdr & QCA_HDR_RECV_VERSION_MASK) >> QCA_HDR_RECV_VERSION_S;
-+	if (unlikely(ver != QCA_HDR_VERSION))
-+		goto out_drop;
-+
-+	/* Remove QCA tag and recalculate checksum */
-+	skb_pull_rcsum(skb, QCA_HDR_LEN);
-+	memmove(skb->data - ETH_HLEN, skb->data - ETH_HLEN - QCA_HDR_LEN,
-+		ETH_HLEN - QCA_HDR_LEN);
-+
-+	/* This protocol doesn't support cascading multiple switches so it's
-+	 * safe to assume the switch is first in the tree
-+	 */
-+	ds = dst->ds[0];
-+	if (!ds)
-+		goto out_drop;
-+
-+	/* Get source port information */
-+	port = (hdr & QCA_HDR_RECV_SOURCE_PORT_MASK);
-+	phy = port_to_reg(port);
-+	if (unlikely(phy < 0) || !ds->ports[phy])
-+		goto out_drop;
-+
-+	/* Update skb & forward the frame accordingly */
-+	skb_push(skb, ETH_HLEN);
-+	skb->pkt_type = PACKET_HOST;
-+	skb->dev = ds->ports[phy];
-+	skb->protocol = eth_type_trans(skb, skb->dev);
-+
-+	skb->dev->stats.rx_packets++;
-+	skb->dev->stats.rx_bytes += skb->len;
-+
-+	netif_receive_skb(skb);
-+
-+	return 0;
-+
-+out_drop:
-+	kfree_skb(skb);
-+out:
-+	return 0;
-+}
-+
-+const struct dsa_device_ops qca_netdev_ops = {
-+	.xmit	= qca_tag_xmit,
-+	.rcv	= qca_tag_rcv,
-+};
---- /dev/null
-+++ b/Documentation/devicetree/bindings/net/dsa/qca-ar8xxx.txt
-@@ -0,0 +1,70 @@
-+* Qualcomm Atheros AR8xxx switch family
-+
-+Required properties:
-+
-+- compatible: should be "qca,ar8xxx"
-+- dsa,mii-bus: phandle to the MDIO bus controller, see dsa/dsa.txt
-+- dsa,ethernet: phandle to the CPU network interface controller, see dsa/dsa.txt
-+- #size-cells: must be 0
-+- #address-cells: must be 2, see dsa/dsa.txt
-+
-+Subnodes:
-+
-+The integrated switch subnode should be specified according to the binding
-+described in dsa/dsa.txt.
-+
-+Optional properties:
-+
-+- qca,port6-phy-mode: if specified, the driver will configure Port 6 in the
-+  given phy-mode. See Documentation/devicetree/bindings/net/ethernet.txt for
-+  the list of valid phy-mode.
-+
-+- qca,port6-phy-id: if specified, the driver will connect Port 6 to the PHY
-+  given as a parameter. In this case, Port6 and the corresponding PHY will be
-+  isolated from the rest of the switch. From a system perspective, they will
-+  act as a regular PHY.
-+
-+Example:
-+
-+	dsa at 0 {
-+		compatible = "qca,ar8xxx";
-+		#address-cells = <2>;
-+		#size-cells = <0>;
-+
-+		dsa,ethernet = <&ethernet0>;
-+		dsa,mii-bus = <&mii_bus0>;
-+
-+		switch at 0 {
-+			#address-cells = <1>;
-+			#size-cells = <0>;
-+			reg = <0 0>;	/* MDIO address 0, switch 0 in tree */
-+
-+			qca,port6-phy-mode = "sgmii";
-+			qca,port6-phy-id = <4>;
-+
-+			port at 0 {
-+				reg = <11>;
-+				label = "cpu";
-+			};
-+
-+			port at 1 {
-+				reg = <0>;
-+				label = "lan1";
-+			};
-+
-+			port at 2 {
-+				reg = <1>;
-+				label = "lan2";
-+			};
-+
-+			port at 3 {
-+				reg = <2>;
-+				label = "lan3";
-+			};
-+
-+			port at 4 {
-+				reg = <3>;
-+				label = "lan4";
-+			};
-+		};
-+	};
diff --git a/target/linux/ipq806x/patches-4.4/707-ARM-dts-qcom-add-mdio-nodes-to-ap148-db149.patch b/target/linux/ipq806x/patches-4.4/707-ARM-dts-qcom-add-mdio-nodes-to-ap148-db149.patch
deleted file mode 100644
index 102cd76..0000000
--- a/target/linux/ipq806x/patches-4.4/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 at 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 at 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 {
-@@ -65,6 +66,15 @@
- 					bias-bus-hold;
- 				};
- 			};
-+
-+			mdio0_pins: mdio0_pins {
-+				mux {
-+					pins = "gpio0", "gpio1";
-+					function = "gpio";
-+					drive-strength = <8>;
-+					bias-disable;
-+				};
-+			};
- 		};
- 
- 		gsbi at 16300000 {
-@@ -160,6 +170,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 at 0 {
-+				device_type = "ethernet-phy";
-+				reg = <0>;
-+				qca,ar8327-initvals = <
-+					0x00004 0x7600000   /* PAD0_MODE */
-+					0x00008 0x1000000   /* PAD5_MODE */
-+					0x0000c 0x80        /* PAD6_MODE */
-+					0x000e4 0x6a545     /* MAC_POWER_SEL */
-+					0x000e0 0xc74164de  /* SGMII_CTRL */
-+					0x0007c 0x4e        /* PORT0_STATUS */
-+					0x00094 0x4e        /* PORT6_STATUS */
-+					>;
-+			};
-+
-+			phy4: ethernet-phy at 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 at 12480000 {
-@@ -140,5 +150,44 @@
- 		pcie2: pci at 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 at 0 {
-+				device_type = "ethernet-phy";
-+				reg = <0>;
-+				qca,ar8327-initvals = <
-+					0x00004 0x7600000   /* PAD0_MODE */
-+					0x00008 0x1000000   /* PAD5_MODE */
-+					0x0000c 0x80        /* PAD6_MODE */
-+					0x000e4 0x6a545     /* MAC_POWER_SEL */
-+					0x000e0 0xc74164de  /* SGMII_CTRL */
-+					0x0007c 0x4e        /* PORT0_STATUS */
-+					0x00094 0x4e        /* PORT6_STATUS */
-+				>;
-+			};
-+
-+			phy4: ethernet-phy at 4 {
-+				device_type = "ethernet-phy";
-+				reg = <4>;
-+			};
-+
-+			phy6: ethernet-phy at 6 {
-+				device_type = "ethernet-phy";
-+				reg = <6>;
-+			};
-+
-+			phy7: ethernet-phy at 7 {
-+				device_type = "ethernet-phy";
-+				reg = <7>;
-+			};
-+		};
- 	};
- };
diff --git a/target/linux/ipq806x/patches-4.4/708-ARM-dts-qcom-add-gmac-nodes-to-ipq806x-platforms.patch b/target/linux/ipq806x/patches-4.4/708-ARM-dts-qcom-add-gmac-nodes-to-ipq806x-platforms.patch
deleted file mode 100644
index b722dfa..0000000
--- a/target/linux/ipq806x/patches-4.4/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 at 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 at 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
-@@ -75,6 +75,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 at 16300000 {
-@@ -198,6 +208,31 @@
- 				reg = <4>;
- 			};
- 		};
-+
-+		gmac1: ethernet at 37200000 {
-+			status = "ok";
-+			phy-mode = "rgmii";
-+			qcom,id = <1>;
-+
-+			pinctrl-0 = <&rgmii2_pins>;
-+			pinctrl-names = "default";
-+
-+			fixed-link {
-+				speed = <1000>;
-+				full-duplex;
-+			};
-+		};
-+
-+		gmac2: ethernet at 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 at 12480000 {
-@@ -189,5 +197,40 @@
- 				reg = <7>;
- 			};
- 		};
-+
-+		gmac0: ethernet at 37000000 {
-+			status = "ok";
-+			phy-mode = "rgmii";
-+			qcom,id = <0>;
-+			phy-handle = <&phy4>;
-+
-+			pinctrl-0 = <&rgmii0_pins>;
-+			pinctrl-names = "default";
-+		};
-+
-+		gmac1: ethernet at 37200000 {
-+			status = "ok";
-+			phy-mode = "sgmii";
-+			qcom,id = <1>;
-+
-+			fixed-link {
-+				speed = <1000>;
-+				full-duplex;
-+			};
-+		};
-+
-+		gmac2: ethernet at 37400000 {
-+			status = "ok";
-+			phy-mode = "sgmii";
-+			qcom,id = <2>;
-+			phy-handle = <&phy6>;
-+		};
-+
-+		gmac3: ethernet at 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
-@@ -917,6 +917,92 @@
- 
- 			status = "disabled";
- 		};
-+
-+		nss_common: syscon at 03000000 {
-+			compatible = "syscon";
-+			reg = <0x03000000 0x0000FFFF>;
-+		};
-+
-+		qsgmii_csr: syscon at 1bb00000 {
-+			compatible = "syscon";
-+			reg = <0x1bb00000 0x000001FF>;
-+		};
-+
-+		gmac0: ethernet at 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 at 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 at 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 at 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-4.4/709-spi-qup-Fix-fifo-and-dma-support-for-IPQ806x.patch b/target/linux/ipq806x/patches-4.4/709-spi-qup-Fix-fifo-and-dma-support-for-IPQ806x.patch
deleted file mode 100644
index fa78a0a..0000000
--- a/target/linux/ipq806x/patches-4.4/709-spi-qup-Fix-fifo-and-dma-support-for-IPQ806x.patch
+++ /dev/null
@@ -1,129 +0,0 @@
-From 16d2871830ff3fe12a6bff582549a9264adff278 Mon Sep 17 00:00:00 2001
-From: Ram Chandra Jangir <rjangi at codeaurora.org>
-Date: Tue, 10 May 2016 20:19:31 +0530
-Subject: [PATCH] spi: qup: Fix fifo and dma support for IPQ806x
-
-Signed-off-by: Ram Chandra Jangir <rjangi at codeaurora.org>
----
- drivers/spi/spi-qup.c | 54 +++++++++++++++++++++++++++++++++++++++++++++++++--
- 1 file changed, 52 insertions(+), 2 deletions(-)
-
---- a/drivers/spi/spi-qup.c
-+++ b/drivers/spi/spi-qup.c
-@@ -24,6 +24,7 @@
- #include <linux/spi/spi.h>
- #include <linux/dmaengine.h>
- #include <linux/dma-mapping.h>
-+#include <linux/gpio.h>
- 
- #define QUP_CONFIG			0x0000
- #define QUP_STATE			0x0004
-@@ -152,6 +153,7 @@ struct spi_qup {
- 	int			use_dma;
- 	struct dma_slave_config	rx_conf;
- 	struct dma_slave_config	tx_conf;
-+	int mode;
- };
- 
- 
-@@ -370,7 +372,8 @@ static int spi_qup_do_pio(struct spi_mas
- 		return ret;
- 	}
- 
--	spi_qup_fifo_write(qup, xfer);
-+	if (qup->mode == QUP_IO_M_MODE_FIFO)
-+		spi_qup_fifo_write(qup, xfer);
- 
- 	return 0;
- }
-@@ -448,6 +451,7 @@ spi_qup_get_mode(struct spi_master *mast
- {
- 	struct spi_qup *qup = spi_master_get_devdata(master);
- 	u32 mode;
-+	size_t dma_align = dma_get_cache_alignment();
- 
- 	qup->w_size = 4;
- 
-@@ -458,6 +462,14 @@ spi_qup_get_mode(struct spi_master *mast
- 
- 	qup->n_words = xfer->len / qup->w_size;
- 
-+	if (!IS_ERR_OR_NULL(master->dma_rx) &&
-+			IS_ALIGNED((size_t)xfer->tx_buf, dma_align) &&
-+			IS_ALIGNED((size_t)xfer->rx_buf, dma_align) &&
-+			!is_vmalloc_addr(xfer->tx_buf) &&
-+			!is_vmalloc_addr(xfer->rx_buf) &&
-+			(xfer->len > 3*qup->in_blk_sz))
-+		qup->use_dma = 1;
-+
- 	if (qup->n_words <= (qup->in_fifo_sz / sizeof(u32)))
- 		mode = QUP_IO_M_MODE_FIFO;
- 	else
-@@ -491,7 +503,7 @@ static int spi_qup_io_config(struct spi_
- 		return -EIO;
- 	}
- 
--	mode = spi_qup_get_mode(spi->master, xfer);
-+	controller->mode = mode = spi_qup_get_mode(spi->master, xfer);
- 	n_words = controller->n_words;
- 
- 	if (mode == QUP_IO_M_MODE_FIFO) {
-@@ -500,6 +512,7 @@ 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);
-+		controller->use_dma = 0;
- 	} else if (!controller->use_dma) {
- 		writel_relaxed(n_words, controller->base + QUP_MX_INPUT_CNT);
- 		writel_relaxed(n_words, controller->base + QUP_MX_OUTPUT_CNT);
-@@ -750,6 +763,38 @@ err_tx:
- 	return ret;
- }
- 
-+static void spi_qup_set_cs(struct spi_device *spi, bool val)
-+{
-+	struct spi_qup *controller;
-+	u32 spi_ioc;
-+	u32 spi_ioc_orig;
-+
-+	controller = spi_master_get_devdata(spi->master);
-+	spi_ioc = readl_relaxed(controller->base + SPI_IO_CONTROL);
-+	spi_ioc_orig = spi_ioc;
-+	if (!val)
-+		spi_ioc |= SPI_IO_C_FORCE_CS;
-+	else
-+		spi_ioc &= ~SPI_IO_C_FORCE_CS;
-+
-+	if (spi_ioc != spi_ioc_orig)
-+		writel_relaxed(spi_ioc, controller->base + SPI_IO_CONTROL);
-+}
-+
-+static int spi_qup_setup(struct spi_device *spi)
-+{
-+	if (spi->cs_gpio >= 0) {
-+		if (spi->mode & SPI_CS_HIGH)
-+			gpio_set_value(spi->cs_gpio, 0);
-+		else
-+			gpio_set_value(spi->cs_gpio, 1);
-+
-+		udelay(10);
-+	}
-+
-+	return 0;
-+}
-+
- static int spi_qup_probe(struct platform_device *pdev)
- {
- 	struct spi_master *master;
-@@ -846,6 +891,11 @@ static int spi_qup_probe(struct platform
- 	if (of_device_is_compatible(dev->of_node, "qcom,spi-qup-v1.1.1"))
- 		controller->qup_v1 = 1;
- 
-+	if (!controller->qup_v1)
-+		master->set_cs = spi_qup_set_cs;
-+	else
-+		master->setup = spi_qup_setup;
-+
- 	spin_lock_init(&controller->lock);
- 	init_completion(&controller->done);
- 
diff --git a/target/linux/ipq806x/patches-4.4/710-spi-qup-Make-sure-mode-is-only-determined-once.patch b/target/linux/ipq806x/patches-4.4/710-spi-qup-Make-sure-mode-is-only-determined-once.patch
deleted file mode 100644
index 338c3a0..0000000
--- a/target/linux/ipq806x/patches-4.4/710-spi-qup-Make-sure-mode-is-only-determined-once.patch
+++ /dev/null
@@ -1,220 +0,0 @@
-From 93f99afbc534e00d72d58336061823055ee820f1 Mon Sep 17 00:00:00 2001
-From: Andy Gross <andy.gross at linaro.org>
-Date: Tue, 12 Apr 2016 09:11:47 -0500
-Subject: [PATCH] spi: qup: Make sure mode is only determined once
-
-This patch calculates the mode once.  All decisions on the current
-transaction
-is made using the mode instead of use_dma
-
-Signed-off-by: Andy Gross <andy.gross at linaro.org>
-
-Change-Id: If3cdd924355e037d77dc8201a72895fac0461aa5
----
- drivers/spi/spi-qup.c | 96 +++++++++++++++++++--------------------------------
- 1 file changed, 36 insertions(+), 60 deletions(-)
-
---- a/drivers/spi/spi-qup.c
-+++ b/drivers/spi/spi-qup.c
-@@ -150,13 +150,20 @@ struct spi_qup {
- 	int			rx_bytes;
- 	int			qup_v1;
- 
--	int			use_dma;
-+	int			mode;
- 	struct dma_slave_config	rx_conf;
- 	struct dma_slave_config	tx_conf;
--	int mode;
- };
- 
- 
-+static inline bool spi_qup_is_dma_xfer(int mode)
-+{
-+	if (mode == QUP_IO_M_MODE_DMOV || mode == QUP_IO_M_MODE_BAM)
-+		return true;
-+
-+	return false;
-+}
-+
- static inline bool spi_qup_is_valid_state(struct spi_qup *controller)
- {
- 	u32 opstate = readl_relaxed(controller->base + QUP_STATE);
-@@ -427,7 +434,7 @@ static irqreturn_t spi_qup_qup_irq(int i
- 		error = -EIO;
- 	}
- 
--	if (!controller->use_dma) {
-+	if (!spi_qup_is_dma_xfer(controller->mode)) {
- 		if (opflags & QUP_OP_IN_SERVICE_FLAG)
- 			spi_qup_fifo_read(controller, xfer);
- 
-@@ -446,43 +453,11 @@ static irqreturn_t spi_qup_qup_irq(int i
- 	return IRQ_HANDLED;
- }
- 
--static u32
--spi_qup_get_mode(struct spi_master *master, struct spi_transfer *xfer)
--{
--	struct spi_qup *qup = spi_master_get_devdata(master);
--	u32 mode;
--	size_t dma_align = dma_get_cache_alignment();
--
--	qup->w_size = 4;
--
--	if (xfer->bits_per_word <= 8)
--		qup->w_size = 1;
--	else if (xfer->bits_per_word <= 16)
--		qup->w_size = 2;
--
--	qup->n_words = xfer->len / qup->w_size;
--
--	if (!IS_ERR_OR_NULL(master->dma_rx) &&
--			IS_ALIGNED((size_t)xfer->tx_buf, dma_align) &&
--			IS_ALIGNED((size_t)xfer->rx_buf, dma_align) &&
--			!is_vmalloc_addr(xfer->tx_buf) &&
--			!is_vmalloc_addr(xfer->rx_buf) &&
--			(xfer->len > 3*qup->in_blk_sz))
--		qup->use_dma = 1;
--
--	if (qup->n_words <= (qup->in_fifo_sz / sizeof(u32)))
--		mode = QUP_IO_M_MODE_FIFO;
--	else
--		mode = QUP_IO_M_MODE_BLOCK;
--
--	return mode;
--}
--
- /* set clock freq ... bits per word */
- 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, control;
-+	u32 config, iomode, control;
- 	int ret, n_words;
- 
- 	if (spi->mode & SPI_LOOP && xfer->len > controller->in_fifo_sz) {
-@@ -503,24 +478,22 @@ static int spi_qup_io_config(struct spi_
- 		return -EIO;
- 	}
- 
--	controller->mode = mode = spi_qup_get_mode(spi->master, xfer);
-+	controller->w_size = DIV_ROUND_UP(xfer->bits_per_word, 8);
-+	controller->n_words = xfer->len / controller->w_size;
- 	n_words = controller->n_words;
- 
--	if (mode == QUP_IO_M_MODE_FIFO) {
-+	if (n_words <= (controller->in_fifo_sz / sizeof(u32))) {
-+		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 */
- 		writel_relaxed(0, controller->base + QUP_MX_INPUT_CNT);
- 		writel_relaxed(0, controller->base + QUP_MX_OUTPUT_CNT);
- 		controller->use_dma = 0;
--	} else if (!controller->use_dma) {
--		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);
--	} else {
--		mode = QUP_IO_M_MODE_BAM;
-+	} else if (spi->master->can_dma &&
-+	    spi->master->can_dma(spi->master, spi, xfer) &&
-+	    spi->master->cur_msg_mapped) {
-+		controller->mode = QUP_IO_M_MODE_BAM;
- 		writel_relaxed(0, controller->base + QUP_MX_READ_CNT);
- 		writel_relaxed(0, controller->base + QUP_MX_WRITE_CNT);
- 
-@@ -541,19 +514,26 @@ static int spi_qup_io_config(struct spi_
- 
- 			writel_relaxed(0, controller->base + QUP_MX_OUTPUT_CNT);
- 		}
-+	} else {
-+		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 */
-+		writel_relaxed(0, controller->base + QUP_MX_READ_CNT);
-+		writel_relaxed(0, controller->base + QUP_MX_WRITE_CNT);
- 	}
- 
- 	iomode = readl_relaxed(controller->base + QUP_IO_M_MODES);
- 	/* Set input and output transfer mode */
- 	iomode &= ~(QUP_IO_M_INPUT_MODE_MASK | QUP_IO_M_OUTPUT_MODE_MASK);
- 
--	if (!controller->use_dma)
-+	if (!spi_qup_is_dma_xfer(controller->mode))
- 		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);
-+	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);
- 
-@@ -594,7 +574,7 @@ static int spi_qup_io_config(struct spi_
- 	config |= xfer->bits_per_word - 1;
- 	config |= QUP_CONFIG_SPI_MODE;
- 
--	if (controller->use_dma) {
-+	if (spi_qup_is_dma_xfer(controller->mode)) {
- 		if (!xfer->tx_buf)
- 			config |= QUP_CONFIG_NO_OUTPUT;
- 		if (!xfer->rx_buf)
-@@ -612,7 +592,7 @@ static int spi_qup_io_config(struct spi_
- 		 * status change in BAM mode
- 		 */
- 
--		if (mode == QUP_IO_M_MODE_BAM)
-+		if (spi_qup_is_dma_xfer(controller->mode))
- 			mask = QUP_OP_IN_SERVICE_FLAG | QUP_OP_OUT_SERVICE_FLAG;
- 
- 		writel_relaxed(mask, controller->base + QUP_OPERATIONAL_MASK);
-@@ -646,7 +626,7 @@ static int spi_qup_transfer_one(struct s
- 	controller->tx_bytes = 0;
- 	spin_unlock_irqrestore(&controller->lock, flags);
- 
--	if (controller->use_dma)
-+	if (spi_qup_is_dma_xfer(controller->mode))
- 		ret = spi_qup_do_dma(master, xfer);
- 	else
- 		ret = spi_qup_do_pio(master, xfer);
-@@ -670,7 +650,7 @@ exit:
- 		ret = controller->error;
- 	spin_unlock_irqrestore(&controller->lock, flags);
- 
--	if (ret && controller->use_dma)
-+	if (ret && spi_qup_is_dma_xfer(controller->mode))
- 		spi_qup_dma_terminate(master, xfer);
- 
- 	return ret;
-@@ -681,9 +661,7 @@ static bool spi_qup_can_dma(struct spi_m
- {
- 	struct spi_qup *qup = spi_master_get_devdata(master);
- 	size_t dma_align = dma_get_cache_alignment();
--	u32 mode;
--
--	qup->use_dma = 0;
-+	int n_words;
- 
- 	if (xfer->rx_buf && (xfer->len % qup->in_blk_sz ||
- 	    IS_ERR_OR_NULL(master->dma_rx) ||
-@@ -695,12 +673,10 @@ static bool spi_qup_can_dma(struct spi_m
- 	    !IS_ALIGNED((size_t)xfer->tx_buf, dma_align)))
- 		return false;
- 
--	mode = spi_qup_get_mode(master, xfer);
--	if (mode == QUP_IO_M_MODE_FIFO)
-+	n_words = xfer->len / DIV_ROUND_UP(xfer->bits_per_word, 8);
-+	if (n_words <= (qup->in_fifo_sz / sizeof(u32)))
- 		return false;
- 
--	qup->use_dma = 1;
--
- 	return true;
- }
- 
diff --git a/target/linux/ipq806x/patches-4.4/711-spi-qup-Fix-transaction-done-signaling.patch b/target/linux/ipq806x/patches-4.4/711-spi-qup-Fix-transaction-done-signaling.patch
deleted file mode 100644
index 99f455e..0000000
--- a/target/linux/ipq806x/patches-4.4/711-spi-qup-Fix-transaction-done-signaling.patch
+++ /dev/null
@@ -1,30 +0,0 @@
-From 8e830bd17e945e74964a5b61353d74e34c0791cd Mon Sep 17 00:00:00 2001
-From: Andy Gross <andy.gross at linaro.org>
-Date: Fri, 29 Jan 2016 22:06:50 -0600
-Subject: [PATCH] spi: qup: Fix transaction done signaling
-
-Wait to signal done until we get all of the interrupts we are expecting
-to get for a transaction.  If we don't wait for the input done flag, we
-can be inbetween transactions when the done flag comes in and this can
-mess up the next transaction.
-
-Change-Id: I08d78376e71590663158d6434a3fb7c0623264c9
-CC: Grant Grundler <grundler at chromium.org>
-CC: Sarthak Kukreti <skukreti at codeaurora.org>
-Signed-off-by: Andy Gross <andy.gross at linaro.org>
----
- drivers/spi/spi-qup.c | 3 ++-
- 1 file changed, 2 insertions(+), 1 deletion(-)
-
---- a/drivers/spi/spi-qup.c
-+++ b/drivers/spi/spi-qup.c
-@@ -447,7 +447,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;
diff --git a/target/linux/ipq806x/patches-4.4/711-stmmac-fix-ipq806x-DMA-configuration.patch b/target/linux/ipq806x/patches-4.4/711-stmmac-fix-ipq806x-DMA-configuration.patch
deleted file mode 100644
index 5840031..0000000
--- a/target/linux/ipq806x/patches-4.4/711-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
-@@ -1641,9 +1641,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;
-@@ -1654,7 +1656,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-4.4/712-spi-qup-Fix-DMA-mode-to-work-correctly.patch b/target/linux/ipq806x/patches-4.4/712-spi-qup-Fix-DMA-mode-to-work-correctly.patch
deleted file mode 100644
index 9c7bbea..0000000
--- a/target/linux/ipq806x/patches-4.4/712-spi-qup-Fix-DMA-mode-to-work-correctly.patch
+++ /dev/null
@@ -1,221 +0,0 @@
-From ed56e6322b067a898a25bda1774eb1180a832246 Mon Sep 17 00:00:00 2001
-From: Andy Gross <andy.gross at linaro.org>
-Date: Tue, 2 Feb 2016 17:00:53 -0600
-Subject: [PATCH] spi: qup: Fix DMA mode to work correctly
-
-This patch fixes a few issues with the DMA mode.  The QUP needs to be
-placed in the run mode before the DMA transactions are executed.  The
-conditions for being able to DMA vary between revisions of the QUP.
-This is due to v1.1.1 using ADM DMA and later revisions using BAM.
-
-Change-Id: Ib1f876eaa05d079e0bca4358d2b25b2940986089
-Signed-off-by: Andy Gross <andy.gross at linaro.org>
----
- drivers/spi/spi-qup.c | 95 ++++++++++++++++++++++++++++++++++-----------------
- 1 file changed, 63 insertions(+), 32 deletions(-)
-
---- a/drivers/spi/spi-qup.c
-+++ b/drivers/spi/spi-qup.c
-@@ -143,6 +143,7 @@ struct spi_qup {
- 
- 	struct spi_transfer	*xfer;
- 	struct completion	done;
-+	struct completion	dma_tx_done;
- 	int			error;
- 	int			w_size;	/* bytes per SPI word */
- 	int			n_words;
-@@ -285,16 +286,16 @@ static void spi_qup_fifo_write(struct sp
- 
- static void spi_qup_dma_done(void *data)
- {
--	struct spi_qup *qup = data;
-+	struct completion *done = data;
- 
--	complete(&qup->done);
-+	complete(done);
- }
- 
- static int spi_qup_prep_sg(struct spi_master *master, struct spi_transfer *xfer,
- 			   enum dma_transfer_direction dir,
--			   dma_async_tx_callback callback)
-+			   dma_async_tx_callback callback,
-+			   void *data)
- {
--	struct spi_qup *qup = spi_master_get_devdata(master);
- 	unsigned long flags = DMA_PREP_INTERRUPT | DMA_PREP_FENCE;
- 	struct dma_async_tx_descriptor *desc;
- 	struct scatterlist *sgl;
-@@ -313,11 +314,11 @@ static int spi_qup_prep_sg(struct spi_ma
- 	}
- 
- 	desc = dmaengine_prep_slave_sg(chan, sgl, nents, dir, flags);
--	if (!desc)
--		return -EINVAL;
-+	if (IS_ERR_OR_NULL(desc))
-+		return desc ? PTR_ERR(desc) : -EINVAL;
- 
- 	desc->callback = callback;
--	desc->callback_param = qup;
-+	desc->callback_param = data;
- 
- 	cookie = dmaengine_submit(desc);
- 
-@@ -333,18 +334,29 @@ static void spi_qup_dma_terminate(struct
- 		dmaengine_terminate_all(master->dma_rx);
- }
- 
--static int spi_qup_do_dma(struct spi_master *master, struct spi_transfer *xfer)
-+static int spi_qup_do_dma(struct spi_master *master, struct spi_transfer *xfer,
-+unsigned long timeout)
- {
-+	struct spi_qup *qup = spi_master_get_devdata(master);
- 	dma_async_tx_callback rx_done = NULL, tx_done = NULL;
- 	int ret;
- 
-+	/* before issuing the descriptors, set the QUP to run */
-+	ret = spi_qup_set_state(qup, QUP_STATE_RUN);
-+	if (ret) {
-+		dev_warn(qup->dev, "cannot set RUN state\n");
-+		return ret;
-+	}
-+
- 	if (xfer->rx_buf)
- 		rx_done = spi_qup_dma_done;
--	else if (xfer->tx_buf)
-+
-+	if (xfer->tx_buf)
- 		tx_done = spi_qup_dma_done;
- 
- 	if (xfer->rx_buf) {
--		ret = spi_qup_prep_sg(master, xfer, DMA_DEV_TO_MEM, rx_done);
-+		ret = spi_qup_prep_sg(master, xfer, DMA_DEV_TO_MEM, rx_done,
-+				      &qup->done);
- 		if (ret)
- 			return ret;
- 
-@@ -352,17 +364,26 @@ static int spi_qup_do_dma(struct spi_mas
- 	}
- 
- 	if (xfer->tx_buf) {
--		ret = spi_qup_prep_sg(master, xfer, DMA_MEM_TO_DEV, tx_done);
-+		ret = spi_qup_prep_sg(master, xfer, DMA_MEM_TO_DEV, tx_done,
-+				      &qup->dma_tx_done);
- 		if (ret)
- 			return ret;
- 
- 		dma_async_issue_pending(master->dma_tx);
- 	}
- 
--	return 0;
-+	if (xfer->rx_buf && !wait_for_completion_timeout(&qup->done, timeout))
-+		return -ETIMEDOUT;
-+
-+	if (xfer->tx_buf &&
-+	    !wait_for_completion_timeout(&qup->dma_tx_done, timeout))
-+		ret = -ETIMEDOUT;
-+
-+	return ret;
- }
- 
--static int spi_qup_do_pio(struct spi_master *master, struct spi_transfer *xfer)
-+static int spi_qup_do_pio(struct spi_master *master, struct spi_transfer *xfer,
-+			  unsigned long timeout)
- {
- 	struct spi_qup *qup = spi_master_get_devdata(master);
- 	int ret;
-@@ -382,6 +403,15 @@ static int spi_qup_do_pio(struct spi_mas
- 	if (qup->mode == QUP_IO_M_MODE_FIFO)
- 		spi_qup_fifo_write(qup, xfer);
- 
-+	ret = spi_qup_set_state(qup, QUP_STATE_RUN);
-+	if (ret) {
-+		dev_warn(qup->dev, "cannot set RUN state\n");
-+		return ret;
-+	}
-+
-+	if (!wait_for_completion_timeout(&qup->done, timeout))
-+		return -ETIMEDOUT;
-+
- 	return 0;
- }
- 
-@@ -430,7 +460,6 @@ static irqreturn_t spi_qup_qup_irq(int i
- 			dev_warn(controller->dev, "CLK_OVER_RUN\n");
- 		if (spi_err & SPI_ERROR_CLK_UNDER_RUN)
- 			dev_warn(controller->dev, "CLK_UNDER_RUN\n");
--
- 		error = -EIO;
- 	}
- 
-@@ -619,6 +648,7 @@ static int spi_qup_transfer_one(struct s
- 	timeout = 100 * msecs_to_jiffies(timeout);
- 
- 	reinit_completion(&controller->done);
-+	reinit_completion(&controller->dma_tx_done);
- 
- 	spin_lock_irqsave(&controller->lock, flags);
- 	controller->xfer     = xfer;
-@@ -628,21 +658,13 @@ static int spi_qup_transfer_one(struct s
- 	spin_unlock_irqrestore(&controller->lock, flags);
- 
- 	if (spi_qup_is_dma_xfer(controller->mode))
--		ret = spi_qup_do_dma(master, xfer);
-+		ret = spi_qup_do_dma(master, xfer, timeout);
- 	else
--		ret = spi_qup_do_pio(master, xfer);
-+		ret = spi_qup_do_pio(master, xfer, timeout);
- 
- 	if (ret)
- 		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;
--
- exit:
- 	spi_qup_set_state(controller, QUP_STATE_RESET);
- 	spin_lock_irqsave(&controller->lock, flags);
-@@ -664,15 +686,23 @@ static bool spi_qup_can_dma(struct spi_m
- 	size_t dma_align = dma_get_cache_alignment();
- 	int n_words;
- 
--	if (xfer->rx_buf && (xfer->len % qup->in_blk_sz ||
--	    IS_ERR_OR_NULL(master->dma_rx) ||
--	    !IS_ALIGNED((size_t)xfer->rx_buf, dma_align)))
--		return false;
-+	if (xfer->rx_buf) {
-+		if (!IS_ALIGNED((size_t)xfer->rx_buf, dma_align) ||
-+		    IS_ERR_OR_NULL(master->dma_rx))
-+			return false;
- 
--	if (xfer->tx_buf && (xfer->len % qup->out_blk_sz ||
--	    IS_ERR_OR_NULL(master->dma_tx) ||
--	    !IS_ALIGNED((size_t)xfer->tx_buf, dma_align)))
--		return false;
-+		if (qup->qup_v1 && (xfer->len % qup->in_blk_sz))
-+			return false;
-+	}
-+
-+	if (xfer->tx_buf) {
-+		if (!IS_ALIGNED((size_t)xfer->tx_buf, dma_align) ||
-+		    IS_ERR_OR_NULL(master->dma_tx))
-+			return false;
-+
-+		if (qup->qup_v1 && (xfer->len % qup->out_blk_sz))
-+			return false;
-+	}
- 
- 	n_words = xfer->len / DIV_ROUND_UP(xfer->bits_per_word, 8);
- 	if (n_words <= (qup->in_fifo_sz / sizeof(u32)))
-@@ -875,6 +905,7 @@ static int spi_qup_probe(struct platform
- 
- 	spin_lock_init(&controller->lock);
- 	init_completion(&controller->done);
-+	init_completion(&controller->dma_tx_done);
- 
- 	iomode = readl_relaxed(base + QUP_IO_M_MODES);
- 
diff --git a/target/linux/ipq806x/patches-4.4/713-spi-qup-Fix-block-mode-to-work-correctly.patch b/target/linux/ipq806x/patches-4.4/713-spi-qup-Fix-block-mode-to-work-correctly.patch
deleted file mode 100644
index eb0b45c..0000000
--- a/target/linux/ipq806x/patches-4.4/713-spi-qup-Fix-block-mode-to-work-correctly.patch
+++ /dev/null
@@ -1,312 +0,0 @@
-From 148f77310a9ddf4db5036066458d7aed92cea9ae Mon Sep 17 00:00:00 2001
-From: Andy Gross <andy.gross at linaro.org>
-Date: Sun, 31 Jan 2016 21:28:13 -0600
-Subject: [PATCH] spi: qup: Fix block mode to work correctly
-
-This patch corrects the behavior of the BLOCK
-transactions.  During block transactions, the controller
-must be read/written to in block size transactions.
-
-Signed-off-by: Andy Gross <andy.gross at linaro.org>
-
-Change-Id: I4b4f4d25be57e6e8148f6f0d24bed376eb287ecf
----
- drivers/spi/spi-qup.c | 181 +++++++++++++++++++++++++++++++++++++++-----------
- 1 file changed, 141 insertions(+), 40 deletions(-)
-
---- a/drivers/spi/spi-qup.c
-+++ b/drivers/spi/spi-qup.c
-@@ -83,6 +83,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)
-@@ -156,6 +158,12 @@ struct spi_qup {
- 	struct dma_slave_config	tx_conf;
- };
- 
-+static inline bool spi_qup_is_flag_set(struct spi_qup *controller, u32 flag)
-+{
-+	u32 opflag = readl_relaxed(controller->base + QUP_OPERATIONAL);
-+
-+	return opflag & flag;
-+}
- 
- static inline bool spi_qup_is_dma_xfer(int mode)
- {
-@@ -217,29 +225,26 @@ 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_read_from_fifo(struct spi_qup *controller,
-+	struct spi_transfer *xfer, u32 num_words)
- {
- 	u8 *rx_buf = xfer->rx_buf;
--	u32 word, state;
--	int idx, shift, w_size;
--
--	w_size = controller->w_size;
-+	int i, shift, num_bytes;
-+	u32 word;
- 
--	while (controller->rx_bytes < xfer->len) {
--
--		state = readl_relaxed(controller->base + QUP_OPERATIONAL);
--		if (0 == (state & QUP_OP_IN_FIFO_NOT_EMPTY))
--			break;
-+	for (; num_words; num_words--) {
- 
- 		word = readl_relaxed(controller->base + QUP_INPUT_FIFO);
- 
-+		num_bytes = min_t(int, xfer->len - controller->rx_bytes,
-+					controller->w_size);
-+
- 		if (!rx_buf) {
--			controller->rx_bytes += w_size;
-+			controller->rx_bytes += num_bytes;
- 			continue;
- 		}
- 
--		for (idx = 0; idx < w_size; idx++, controller->rx_bytes++) {
-+		for (i = 0; i < num_bytes; i++, controller->rx_bytes++) {
- 			/*
- 			 * The data format depends on bytes per SPI word:
- 			 *  4 bytes: 0x12345678
-@@ -247,38 +252,80 @@ static void spi_qup_fifo_read(struct spi
- 			 *  1 byte : 0x00000012
- 			 */
- 			shift = BITS_PER_BYTE;
--			shift *= (w_size - idx - 1);
-+			shift *= (controller->w_size - i - 1);
- 			rx_buf[controller->rx_bytes] = word >> shift;
- 		}
- 	}
- }
- 
--static void spi_qup_fifo_write(struct spi_qup *controller,
-+static void spi_qup_read(struct spi_qup *controller,
- 			    struct spi_transfer *xfer)
- {
--	const u8 *tx_buf = xfer->tx_buf;
--	u32 word, state, data;
--	int idx, w_size;
-+	u32 remainder, words_per_block, num_words;
-+	bool is_block_mode = controller->mode == QUP_IO_M_MODE_BLOCK;
-+
-+	remainder = DIV_ROUND_UP(xfer->len - controller->rx_bytes,
-+				 controller->w_size);
-+	words_per_block = controller->in_blk_sz >> 2;
-+
-+	do {
-+		/* ACK by clearing service flag */
-+		writel_relaxed(QUP_OP_IN_SERVICE_FLAG,
-+			       controller->base + QUP_OPERATIONAL);
-+
-+		if (is_block_mode) {
-+			num_words = (remainder > words_per_block) ?
-+					words_per_block : remainder;
-+		} else {
-+			if (!spi_qup_is_flag_set(controller,
-+						 QUP_OP_IN_FIFO_NOT_EMPTY))
-+				break;
- 
--	w_size = controller->w_size;
-+			num_words = 1;
-+		}
-+
-+		/* read up to the maximum transfer size available */
-+		spi_qup_read_from_fifo(controller, xfer, num_words);
- 
--	while (controller->tx_bytes < xfer->len) {
-+		remainder -= num_words;
- 
--		state = readl_relaxed(controller->base + QUP_OPERATIONAL);
--		if (state & QUP_OP_OUT_FIFO_FULL)
-+		/* if block mode, check to see if next block is available */
-+		if (is_block_mode && !spi_qup_is_flag_set(controller,
-+					QUP_OP_IN_BLOCK_READ_REQ))
- 			break;
- 
-+	} while (remainder);
-+
-+	/*
-+	 * Due to extra stickiness of the QUP_OP_IN_SERVICE_FLAG during block
-+	 * mode reads, it has to be cleared again at the very end
-+	 */
-+	if (is_block_mode && spi_qup_is_flag_set(controller,
-+				QUP_OP_MAX_INPUT_DONE_FLAG))
-+		writel_relaxed(QUP_OP_IN_SERVICE_FLAG,
-+			       controller->base + QUP_OPERATIONAL);
-+
-+}
-+
-+static void spi_qup_write_to_fifo(struct spi_qup *controller,
-+	struct spi_transfer *xfer, u32 num_words)
-+{
-+	const u8 *tx_buf = xfer->tx_buf;
-+	int i, num_bytes;
-+	u32 word, data;
-+
-+	for (; num_words; num_words--) {
- 		word = 0;
--		for (idx = 0; idx < w_size; idx++, controller->tx_bytes++) {
- 
--			if (!tx_buf) {
--				controller->tx_bytes += w_size;
--				break;
-+		num_bytes = min_t(int, xfer->len - controller->tx_bytes,
-+				    controller->w_size);
-+		if (tx_buf)
-+			for (i = 0; i < num_bytes; i++) {
-+				data = tx_buf[controller->tx_bytes + i];
-+				word |= data << (BITS_PER_BYTE * (3 - i));
- 			}
- 
--			data = tx_buf[controller->tx_bytes];
--			word |= data << (BITS_PER_BYTE * (3 - idx));
--		}
-+		controller->tx_bytes += num_bytes;
- 
- 		writel_relaxed(word, controller->base + QUP_OUTPUT_FIFO);
- 	}
-@@ -291,6 +338,44 @@ static void spi_qup_dma_done(void *data)
- 	complete(done);
- }
- 
-+static void spi_qup_write(struct spi_qup *controller,
-+			    struct spi_transfer *xfer)
-+{
-+	bool is_block_mode = controller->mode == QUP_IO_M_MODE_BLOCK;
-+	u32 remainder, words_per_block, num_words;
-+
-+	remainder = DIV_ROUND_UP(xfer->len - controller->tx_bytes,
-+				 controller->w_size);
-+	words_per_block = controller->out_blk_sz >> 2;
-+
-+	do {
-+		/* ACK by clearing service flag */
-+		writel_relaxed(QUP_OP_OUT_SERVICE_FLAG,
-+			       controller->base + QUP_OPERATIONAL);
-+
-+		if (is_block_mode) {
-+			num_words = (remainder > words_per_block) ?
-+				words_per_block : remainder;
-+		} else {
-+			if (spi_qup_is_flag_set(controller,
-+						QUP_OP_OUT_FIFO_FULL))
-+				break;
-+
-+			num_words = 1;
-+		}
-+
-+		spi_qup_write_to_fifo(controller, xfer, num_words);
-+
-+		remainder -= num_words;
-+
-+		/* if block mode, check to see if next block is available */
-+		if (is_block_mode && !spi_qup_is_flag_set(controller,
-+					QUP_OP_OUT_BLOCK_WRITE_REQ))
-+			break;
-+
-+	} while (remainder);
-+}
-+
- static int spi_qup_prep_sg(struct spi_master *master, struct spi_transfer *xfer,
- 			   enum dma_transfer_direction dir,
- 			   dma_async_tx_callback callback,
-@@ -348,11 +433,13 @@ unsigned long timeout)
- 		return ret;
- 	}
- 
--	if (xfer->rx_buf)
--		rx_done = spi_qup_dma_done;
-+	if (!qup->qup_v1) {
-+		if (xfer->rx_buf)
-+			rx_done = spi_qup_dma_done;
- 
--	if (xfer->tx_buf)
--		tx_done = spi_qup_dma_done;
-+		if (xfer->tx_buf)
-+			tx_done = spi_qup_dma_done;
-+	}
- 
- 	if (xfer->rx_buf) {
- 		ret = spi_qup_prep_sg(master, xfer, DMA_DEV_TO_MEM, rx_done,
-@@ -401,7 +488,7 @@ static int spi_qup_do_pio(struct spi_mas
- 	}
- 
- 	if (qup->mode == QUP_IO_M_MODE_FIFO)
--		spi_qup_fifo_write(qup, xfer);
-+		spi_qup_write(qup, xfer);
- 
- 	ret = spi_qup_set_state(qup, QUP_STATE_RUN);
- 	if (ret) {
-@@ -434,10 +521,11 @@ 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) {
--		dev_err_ratelimited(controller->dev, "unexpected irq %08x %08x %08x\n",
-+		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;
- 	}
-@@ -463,12 +551,20 @@ static irqreturn_t spi_qup_qup_irq(int i
- 		error = -EIO;
- 	}
- 
--	if (!spi_qup_is_dma_xfer(controller->mode)) {
-+	if (spi_qup_is_dma_xfer(controller->mode)) {
-+		writel_relaxed(opflags, controller->base + QUP_OPERATIONAL);
-+		if (opflags & QUP_OP_IN_SERVICE_FLAG &&
-+		    opflags & QUP_OP_MAX_INPUT_DONE_FLAG)
-+			complete(&controller->done);
-+		if (opflags & QUP_OP_OUT_SERVICE_FLAG &&
-+		    opflags & QUP_OP_MAX_OUTPUT_DONE_FLAG)
-+			complete(&controller->dma_tx_done);
-+	} else {
- 		if (opflags & QUP_OP_IN_SERVICE_FLAG)
--			spi_qup_fifo_read(controller, xfer);
-+			spi_qup_read(controller, xfer);
- 
- 		if (opflags & QUP_OP_OUT_SERVICE_FLAG)
--			spi_qup_fifo_write(controller, xfer);
-+			spi_qup_write(controller, xfer);
- 	}
- 
- 	spin_lock_irqsave(&controller->lock, flags);
-@@ -476,6 +572,9 @@ static irqreturn_t spi_qup_qup_irq(int i
- 	controller->xfer = xfer;
- 	spin_unlock_irqrestore(&controller->lock, flags);
- 
-+	/* re-read opflags as flags may have changed due to actions above */
-+	opflags = readl_relaxed(controller->base + QUP_OPERATIONAL);
-+
- 	if ((controller->rx_bytes == xfer->len &&
- 		(opflags & QUP_OP_MAX_INPUT_DONE_FLAG)) ||  error)
- 		complete(&controller->done);
-@@ -519,11 +618,13 @@ 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);
--		controller->use_dma = 0;
- 	} else if (spi->master->can_dma &&
- 	    spi->master->can_dma(spi->master, spi, xfer) &&
- 	    spi->master->cur_msg_mapped) {
- 		controller->mode = QUP_IO_M_MODE_BAM;
-+		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);
- 
diff --git a/target/linux/ipq806x/patches-4.4/714-spi-qup-properly-detect-extra-interrupts.patch b/target/linux/ipq806x/patches-4.4/714-spi-qup-properly-detect-extra-interrupts.patch
deleted file mode 100644
index 0039962..0000000
--- a/target/linux/ipq806x/patches-4.4/714-spi-qup-properly-detect-extra-interrupts.patch
+++ /dev/null
@@ -1,62 +0,0 @@
-From b69e5e855aaae2dd9f7fc6f4a40af8e6e0cf98ee Mon Sep 17 00:00:00 2001
-From: Matthew McClintock <mmcclint at codeaurora.org>
-Date: Thu, 10 Mar 2016 16:44:55 -0600
-Subject: [PATCH] spi: qup: properly detect extra interrupts
-
-It's possible for a SPI transaction to complete and get another
-interrupt and have it processed on the same spi_transfer before the
-transfer_one can set it to NULL.
-
-This masks unexpected interrupts, so let's set the spi_transfer to
-NULL in the interrupt once the transaction is done. So we can
-properly detect these bad interrupts and print warning messages.
-
-Change-Id: I0e70ed59fb50e5c48a72a38f74bd178b17c9f24d
-Signed-off-by: Matthew McClintock <mmcclint at codeaurora.org>
----
- drivers/spi/spi-qup.c | 15 +++++++++------
- 1 file changed, 9 insertions(+), 6 deletions(-)
-
---- a/drivers/spi/spi-qup.c
-+++ b/drivers/spi/spi-qup.c
-@@ -509,6 +509,7 @@ static irqreturn_t spi_qup_qup_irq(int i
- 	u32 opflags, qup_err, spi_err;
- 	unsigned long flags;
- 	int error = 0;
-+	bool done = 0;
- 
- 	spin_lock_irqsave(&controller->lock, flags);
- 	xfer = controller->xfer;
-@@ -567,16 +568,19 @@ static irqreturn_t spi_qup_qup_irq(int i
- 			spi_qup_write(controller, xfer);
- 	}
- 
--	spin_lock_irqsave(&controller->lock, flags);
--	controller->error = error;
--	controller->xfer = xfer;
--	spin_unlock_irqrestore(&controller->lock, flags);
--
- 	/* re-read opflags as flags may have changed due to actions above */
- 	opflags = readl_relaxed(controller->base + QUP_OPERATIONAL);
- 
- 	if ((controller->rx_bytes == xfer->len &&
- 		(opflags & QUP_OP_MAX_INPUT_DONE_FLAG)) ||  error)
-+		done = true;
-+
-+	spin_lock_irqsave(&controller->lock, flags);
-+	controller->error = error;
-+	controller->xfer = done ? NULL : xfer;
-+	spin_unlock_irqrestore(&controller->lock, flags);
-+
-+	if (done)
- 		complete(&controller->done);
- 
- 	return IRQ_HANDLED;
-@@ -769,7 +773,6 @@ static int spi_qup_transfer_one(struct s
- exit:
- 	spi_qup_set_state(controller, QUP_STATE_RESET);
- 	spin_lock_irqsave(&controller->lock, flags);
--	controller->xfer = NULL;
- 	if (!ret)
- 		ret = controller->error;
- 	spin_unlock_irqrestore(&controller->lock, flags);
diff --git a/target/linux/ipq806x/patches-4.4/715-spi-qup-don-t-re-read-opflags-to-see-if-transaction-.patch b/target/linux/ipq806x/patches-4.4/715-spi-qup-don-t-re-read-opflags-to-see-if-transaction-.patch
deleted file mode 100644
index a08b442..0000000
--- a/target/linux/ipq806x/patches-4.4/715-spi-qup-don-t-re-read-opflags-to-see-if-transaction-.patch
+++ /dev/null
@@ -1,27 +0,0 @@
-From f57ff801665b868d8607c9e872466b54982564bc Mon Sep 17 00:00:00 2001
-From: Matthew McClintock <mmcclint at codeaurora.org>
-Date: Thu, 10 Mar 2016 16:48:27 -0600
-Subject: [PATCH] spi: qup: don't re-read opflags to see if transaction is done
- for reads
-
-For reads, we will get another interrupt so we need to handle things
-then. For writes, we can finish up now.
-
-Change-Id: I4fa95ae7bb9d78f8ba54c613b981b37d4ea81d7e
-Signed-off-by: Matthew McClintock <mmcclint at codeaurora.org>
----
- drivers/spi/spi-qup.c | 3 ++-
- 1 file changed, 2 insertions(+), 1 deletion(-)
-
---- a/drivers/spi/spi-qup.c
-+++ b/drivers/spi/spi-qup.c
-@@ -569,7 +569,8 @@ static irqreturn_t spi_qup_qup_irq(int i
- 	}
- 
- 	/* re-read opflags as flags may have changed due to actions above */
--	opflags = readl_relaxed(controller->base + QUP_OPERATIONAL);
-+	if (opflags & QUP_OP_OUT_SERVICE_FLAG)
-+		opflags = readl_relaxed(controller->base + QUP_OPERATIONAL);
- 
- 	if ((controller->rx_bytes == xfer->len &&
- 		(opflags & QUP_OP_MAX_INPUT_DONE_FLAG)) ||  error)
diff --git a/target/linux/ipq806x/patches-4.4/800-devicetree.patch b/target/linux/ipq806x/patches-4.4/800-devicetree.patch
deleted file mode 100644
index 916e2ef..0000000
--- a/target/linux/ipq806x/patches-4.4/800-devicetree.patch
+++ /dev/null
@@ -1,29 +0,0 @@
-From 7e77aa188a7a7c4391856a9e5ef5ef58f769e679 Mon Sep 17 00:00:00 2001
-From: Jonas Gorski <jogo at 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 at 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
-@@ -506,7 +506,14 @@ dtb-$(CONFIG_ARCH_QCOM) += \
- 	qcom-apq8084-ifc6540.dtb \
- 	qcom-apq8084-mtp.dtb \
- 	qcom-ipq8064-ap148.dtb \
-+	qcom-ipq8064-c2600.dtb \
-+	qcom-ipq8064-d7800.dtb \
- 	qcom-ipq8064-db149.dtb \
-+	qcom-ipq8064-ea8500.dtb \
-+	qcom-ipq8064-r7500.dtb \
-+	qcom-ipq8064-r7500v2.dtb \
-+	qcom-ipq8065-nbg6817.dtb \
-+	qcom-ipq8065-r7800.dtb \
- 	qcom-msm8660-surf.dtb \
- 	qcom-msm8960-cdp.dtb \
- 	qcom-msm8974-sony-xperia-honami.dtb
diff --git a/target/linux/ipq806x/patches-4.4/801-override-compiler-flags.patch b/target/linux/ipq806x/patches-4.4/801-override-compiler-flags.patch
deleted file mode 100644
index 5b419a7..0000000
--- a/target/linux/ipq806x/patches-4.4/801-override-compiler-flags.patch
+++ /dev/null
@@ -1,11 +0,0 @@
---- a/arch/arm/Makefile
-+++ b/arch/arm/Makefile
-@@ -72,7 +72,7 @@ KBUILD_CFLAGS	+= $(call cc-option,-fno-i
- # macro, but instead defines a whole series of macros which makes
- # testing for a specific architecture or later rather impossible.
- arch-$(CONFIG_CPU_32v7M)	=-D__LINUX_ARM_ARCH__=7 -march=armv7-m -Wa,-march=armv7-m
--arch-$(CONFIG_CPU_32v7)		=-D__LINUX_ARM_ARCH__=7 $(call cc-option,-march=armv7-a,-march=armv5t -Wa$(comma)-march=armv7-a)
-+arch-$(CONFIG_CPU_32v7)		=-D__LINUX_ARM_ARCH__=7 -mcpu=cortex-a15
- arch-$(CONFIG_CPU_32v6)		=-D__LINUX_ARM_ARCH__=6 $(call cc-option,-march=armv6,-march=armv5t -Wa$(comma)-march=armv6)
- # Only override the compiler option if ARMv6. The ARMv6K extensions are
- # always available in ARMv7
diff --git a/target/linux/ipq806x/patches-4.4/802-GPIO-add-named-gpio-exports.patch b/target/linux/ipq806x/patches-4.4/802-GPIO-add-named-gpio-exports.patch
deleted file mode 100644
index cfdab76..0000000
--- a/target/linux/ipq806x/patches-4.4/802-GPIO-add-named-gpio-exports.patch
+++ /dev/null
@@ -1,166 +0,0 @@
-From 4267880319bc1a2270d352e0ded6d6386242a7ef Mon Sep 17 00:00:00 2001
-From: John Crispin <blogic at openwrt.org>
-Date: Tue, 12 Aug 2014 20:49:27 +0200
-Subject: [PATCH 24/53] GPIO: add named gpio exports
-
-Signed-off-by: John Crispin <blogic at openwrt.org>
----
- drivers/gpio/gpiolib-of.c     |   68 +++++++++++++++++++++++++++++++++++++++++
- drivers/gpio/gpiolib-sysfs.c  |   10 +++++-
- include/asm-generic/gpio.h    |    6 ++++
- include/linux/gpio/consumer.h |    8 +++++
- 4 files changed, 91 insertions(+), 1 deletion(-)
-
---- a/drivers/gpio/gpiolib-of.c
-+++ b/drivers/gpio/gpiolib-of.c
-@@ -23,6 +23,8 @@
- #include <linux/pinctrl/pinctrl.h>
- #include <linux/slab.h>
- #include <linux/gpio/machine.h>
-+#include <linux/init.h>
-+#include <linux/platform_device.h>
- 
- #include "gpiolib.h"
- 
-@@ -450,3 +452,69 @@ void of_gpiochip_remove(struct gpio_chip
- 	gpiochip_remove_pin_ranges(chip);
- 	of_node_put(chip->of_node);
- }
-+
-+static struct of_device_id gpio_export_ids[] = {
-+	{ .compatible = "gpio-export" },
-+	{ /* sentinel */ }
-+};
-+
-+static int __init of_gpio_export_probe(struct platform_device *pdev)
-+{
-+	struct device_node *np = pdev->dev.of_node;
-+	struct device_node *cnp;
-+	u32 val;
-+	int nb = 0;
-+
-+	for_each_child_of_node(np, cnp) {
-+		const char *name = NULL;
-+		int gpio;
-+		bool dmc;
-+		int max_gpio = 1;
-+		int i;
-+
-+		of_property_read_string(cnp, "gpio-export,name", &name);
-+
-+		if (!name)
-+			max_gpio = of_gpio_count(cnp);
-+
-+		for (i = 0; i < max_gpio; i++) {
-+			unsigned flags = 0;
-+			enum of_gpio_flags of_flags;
-+
-+			gpio = of_get_gpio_flags(cnp, i, &of_flags);
-+
-+			if (of_flags == OF_GPIO_ACTIVE_LOW)
-+				flags |= GPIOF_ACTIVE_LOW;
-+
-+			if (!of_property_read_u32(cnp, "gpio-export,output", &val))
-+				flags |= val ? GPIOF_OUT_INIT_HIGH : GPIOF_OUT_INIT_LOW;
-+			else
-+				flags |= GPIOF_IN;
-+
-+			if (devm_gpio_request_one(&pdev->dev, gpio, flags, name ? name : of_node_full_name(np)))
-+				continue;
-+
-+			dmc = of_property_read_bool(cnp, "gpio-export,direction_may_change");
-+			gpio_export_with_name(gpio, dmc, name);
-+			nb++;
-+		}
-+	}
-+
-+	dev_info(&pdev->dev, "%d gpio(s) exported\n", nb);
-+
-+	return 0;
-+}
-+
-+static struct platform_driver gpio_export_driver = {
-+	.driver		= {
-+		.name		= "gpio-export",
-+		.owner	= THIS_MODULE,
-+		.of_match_table	= of_match_ptr(gpio_export_ids),
-+	},
-+};
-+
-+static int __init of_gpio_export_init(void)
-+{
-+	return platform_driver_probe(&gpio_export_driver, of_gpio_export_probe);
-+}
-+device_initcall(of_gpio_export_init);
---- a/drivers/gpio/gpiolib-sysfs.c
-+++ b/drivers/gpio/gpiolib-sysfs.c
-@@ -544,7 +544,7 @@ static struct class gpio_class = {
-  *
-  * Returns zero on success, else an error.
-  */
--int gpiod_export(struct gpio_desc *desc, bool direction_may_change)
-+int __gpiod_export(struct gpio_desc *desc, bool direction_may_change, const char *name)
- {
- 	struct gpio_chip	*chip;
- 	struct gpiod_data	*data;
-@@ -604,6 +604,8 @@ int gpiod_export(struct gpio_desc *desc,
- 	offset = gpio_chip_hwgpio(desc);
- 	if (chip->names && chip->names[offset])
- 		ioname = chip->names[offset];
-+	if (name)
-+		ioname = name;
- 
- 	dev = device_create_with_groups(&gpio_class, chip->dev,
- 					MKDEV(0, 0), data, gpio_groups,
-@@ -625,6 +627,12 @@ err_unlock:
- 	gpiod_dbg(desc, "%s: status %d\n", __func__, status);
- 	return status;
- }
-+EXPORT_SYMBOL_GPL(__gpiod_export);
-+
-+int gpiod_export(struct gpio_desc *desc, bool direction_may_change)
-+{
-+	return __gpiod_export(desc, direction_may_change, NULL);
-+}
- EXPORT_SYMBOL_GPL(gpiod_export);
- 
- static int match_export(struct device *dev, const void *desc)
---- a/include/asm-generic/gpio.h
-+++ b/include/asm-generic/gpio.h
-@@ -122,6 +122,12 @@ static inline int gpio_export(unsigned g
- 	return gpiod_export(gpio_to_desc(gpio), direction_may_change);
- }
- 
-+int __gpiod_export(struct gpio_desc *desc, bool direction_may_change, const char *name);
-+static inline int gpio_export_with_name(unsigned gpio, bool direction_may_change, const char *name)
-+{
-+	return __gpiod_export(gpio_to_desc(gpio), direction_may_change, name);
-+}
-+
- static inline int gpio_export_link(struct device *dev, const char *name,
- 				   unsigned gpio)
- {
---- a/include/linux/gpio/consumer.h
-+++ b/include/linux/gpio/consumer.h
-@@ -427,6 +427,7 @@ static inline struct gpio_desc *devm_get
- 
- #if IS_ENABLED(CONFIG_GPIOLIB) && IS_ENABLED(CONFIG_GPIO_SYSFS)
- 
-+int _gpiod_export(struct gpio_desc *desc, bool direction_may_change, const char *name);
- int gpiod_export(struct gpio_desc *desc, bool direction_may_change);
- int gpiod_export_link(struct device *dev, const char *name,
- 		      struct gpio_desc *desc);
-@@ -434,6 +435,13 @@ void gpiod_unexport(struct gpio_desc *de
- 
- #else  /* CONFIG_GPIOLIB && CONFIG_GPIO_SYSFS */
- 
-+static inline int _gpiod_export(struct gpio_desc *desc,
-+			       bool direction_may_change,
-+			       const char *name)
-+{
-+	return -ENOSYS;
-+}
-+
- static inline int gpiod_export(struct gpio_desc *desc,
- 			       bool direction_may_change)
- {
diff --git a/target/linux/ipq806x/patches-4.4/996-ATAG_DTB_COMPAT_CMDLINE_MANGLE.patch b/target/linux/ipq806x/patches-4.4/996-ATAG_DTB_COMPAT_CMDLINE_MANGLE.patch
deleted file mode 100644
index be15ec4..0000000
--- a/target/linux/ipq806x/patches-4.4/996-ATAG_DTB_COMPAT_CMDLINE_MANGLE.patch
+++ /dev/null
@@ -1,185 +0,0 @@
-Author: Adrian Panella <ianchi74 at outlook.com>
-Date:   Fri Jun 10 19:10:15 2016 -0500
-
-generic: Mangle bootloader's kernel arguments
-
-The command-line arguments provided by the boot loader will be
-appended to a new device tree property: bootloader-args.
-If there is a property "append-rootblock" in DT under /chosen
-and a root= option in bootloaders command line it will be parsed
-and added to DT bootargs with the form: <append-rootblock>XX.
-Only command line ATAG will be processed, the rest of the ATAGs
-sent by bootloader will be ignored.
-This is usefull in dual boot systems, to get the current root partition
-without afecting the rest of the system.
-
-
-Signed-off-by: Adrian Panella <ianchi74 at outlook.com>
-
---- a/arch/arm/Kconfig
-+++ b/arch/arm/Kconfig
-@@ -1928,6 +1928,17 @@ config ARM_ATAG_DTB_COMPAT_CMDLINE_EXTEN
- 	  The command-line arguments provided by the boot loader will be
- 	  appended to the the device tree bootargs property.
- 
-+config ARM_ATAG_DTB_COMPAT_CMDLINE_MANGLE
-+	bool "Append rootblock parsing bootloader's kernel arguments"
-+	help
-+	  The command-line arguments provided by the boot loader will be
-+	  appended to a new device tree property: bootloader-args.
-+	  If there is a property "append-rootblock" in DT under /chosen 
-+	  and a root= option in bootloaders command line it will be parsed 
-+	  and added to DT bootargs with the form: <append-rootblock>XX.
-+	  Only command line ATAG will be processed, the rest of the ATAGs
-+	  sent by bootloader will be ignored.
-+
- endchoice
- 
- config CMDLINE
---- a/arch/arm/boot/compressed/atags_to_fdt.c
-+++ b/arch/arm/boot/compressed/atags_to_fdt.c
-@@ -3,6 +3,8 @@
- 
- #if defined(CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_EXTEND)
- #define do_extend_cmdline 1
-+#elif defined(CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_MANGLE)
-+#define do_extend_cmdline 1
- #else
- #define do_extend_cmdline 0
- #endif
-@@ -66,6 +68,59 @@ static uint32_t get_cell_size(const void
- 	return cell_size;
- }
- 
-+#if defined(CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_MANGLE)
-+
-+static char *append_rootblock(char *dest, const char *str, int len, void *fdt)
-+{
-+	char *ptr, *end;
-+	char *root="root=";
-+	int i, l;
-+	const char *rootblock;
-+
-+	//ARM doesn't have __HAVE_ARCH_STRSTR, so search manually
-+	ptr = str - 1;
-+
-+	do {
-+		//first find an 'r' at the begining or after a space
-+		do {
-+			ptr++;
-+			ptr = strchr(ptr, 'r');
-+			if(!ptr) return dest;
-+
-+		} while (ptr != str && *(ptr-1) != ' ');
-+
-+		//then check for the rest
-+		for(i = 1; i <= 4; i++)
-+			if(*(ptr+i) != *(root+i)) break;
-+
-+	} while (i != 5);
-+
-+	end = strchr(ptr, ' ');
-+	end = end ? (end - 1) : (strchr(ptr, 0) - 1);
-+
-+	//find partition number (assumes format root=/dev/mtdXX | /dev/mtdblockXX | yy:XX )
-+	for( i = 0; end >= ptr && *end >= '0' && *end <= '9'; end--, i++);
-+	ptr = end + 1;
-+
-+	/* if append-rootblock property is set use it to append to command line */
-+	rootblock = getprop(fdt, "/chosen", "append-rootblock", &l);
-+	if(rootblock != NULL) {
-+		if(*dest != ' ') {
-+			*dest = ' ';
-+			dest++;
-+			len++;
-+		}
-+		if (len + l + i <= COMMAND_LINE_SIZE) {
-+			memcpy(dest, rootblock, l);
-+			dest += l - 1;
-+			memcpy(dest, ptr, i);
-+			dest += i;
-+		}
-+	}
-+	return dest;
-+}
-+#endif
-+
- static void merge_fdt_bootargs(void *fdt, const char *fdt_cmdline)
- {
- 	char cmdline[COMMAND_LINE_SIZE];
-@@ -85,12 +140,21 @@ static void merge_fdt_bootargs(void *fdt
- 
- 	/* and append the ATAG_CMDLINE */
- 	if (fdt_cmdline) {
-+
-+#if defined(CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_MANGLE)
-+		//save original bootloader args
-+		//and append ubi.mtd with root partition number to current cmdline
-+		setprop_string(fdt, "/chosen", "bootloader-args", fdt_cmdline);
-+		ptr = append_rootblock(ptr, fdt_cmdline, len, fdt);
-+
-+#else
- 		len = strlen(fdt_cmdline);
- 		if (ptr - cmdline + len + 2 < COMMAND_LINE_SIZE) {
- 			*ptr++ = ' ';
- 			memcpy(ptr, fdt_cmdline, len);
- 			ptr += len;
- 		}
-+#endif
- 	}
- 	*ptr = '\0';
- 
-@@ -147,7 +211,9 @@ int atags_to_fdt(void *atag_list, void *
- 			else
- 				setprop_string(fdt, "/chosen", "bootargs",
- 					       atag->u.cmdline.cmdline);
--		} else if (atag->hdr.tag == ATAG_MEM) {
-+		}
-+#ifndef CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_MANGLE
-+		else if (atag->hdr.tag == ATAG_MEM) {
- 			if (memcount >= sizeof(mem_reg_property)/4)
- 				continue;
- 			if (!atag->u.mem.size)
-@@ -186,6 +252,10 @@ int atags_to_fdt(void *atag_list, void *
- 		setprop(fdt, "/memory", "reg", mem_reg_property,
- 			4 * memcount * memsize);
- 	}
-+#else
-+
-+	}
-+#endif
- 
- 	return fdt_pack(fdt);
- }
---- a/init/main.c
-+++ b/init/main.c
-@@ -88,6 +88,10 @@
- #include <asm/sections.h>
- #include <asm/cacheflush.h>
- 
-+#if defined(CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_MANGLE)
-+#include <linux/of.h>
-+#endif
-+
- static int kernel_init(void *);
- 
- extern void init_IRQ(void);
-@@ -560,6 +564,18 @@ asmlinkage __visible void __init start_k
- 	page_alloc_init();
- 
- 	pr_notice("Kernel command line: %s\n", boot_command_line);
-+
-+#if defined(CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_MANGLE)
-+	//Show bootloader's original command line for reference
-+	if(of_chosen) {
-+		const char *prop = of_get_property(of_chosen, "bootloader-args", NULL);
-+		if(prop)
-+			pr_notice("Bootloader command line (ignored): %s\n", prop);
-+		else
-+			pr_notice("Bootloader command line not present\n");
-+	}
-+#endif
-+
- 	parse_early_param();
- 	after_dashes = parse_args("Booting kernel",
- 				  static_command_line, __start___param,



More information about the lede-commits mailing list