summaryrefslogtreecommitdiff
path: root/target/linux/ipq806x
diff options
context:
space:
mode:
Diffstat (limited to 'target/linux/ipq806x')
-rw-r--r--target/linux/ipq806x/Makefile2
-rw-r--r--target/linux/ipq806x/config-3.18371
-rw-r--r--target/linux/ipq806x/image/Makefile4
-rw-r--r--target/linux/ipq806x/patches/0001-ARM-dts-msm-split-out-msm8660-and-msm8960-soc-into-d.patch300
-rw-r--r--target/linux/ipq806x/patches/0002-ARM-msm-Remove-pen_release-usage.patch211
-rw-r--r--target/linux/ipq806x/patches/0003-ARM-msm-kill-off-hotplug.c.patch108
-rw-r--r--target/linux/ipq806x/patches/0004-clocksource-qcom-Move-clocksource-code-out-of-mach-m.patch771
-rw-r--r--target/linux/ipq806x/patches/0005-ARM-qcom-Split-Qualcomm-support-into-legacy-and-mult.patch1423
-rw-r--r--target/linux/ipq806x/patches/0006-clocksource-qcom-split-building-of-legacy-vs-multipl.patch73
-rw-r--r--target/linux/ipq806x/patches/0007-ARM-qcom-Rename-various-msm-prefixed-functions-to-qc.patch98
-rw-r--r--target/linux/ipq806x/patches/0008-ARM-Introduce-CPU_METHOD_OF_DECLARE-for-cpu-hotplug-.patch150
-rw-r--r--target/linux/ipq806x/patches/0009-ARM-qcom-Re-organize-platsmp-to-make-it-extensible.patch241
-rw-r--r--target/linux/ipq806x/patches/001-spi-qup-Add-DMA-capabilities.patch (renamed from target/linux/ipq806x/patches/0179-spi-qup-Add-DMA-capabilities.patch)102
-rw-r--r--target/linux/ipq806x/patches/0010-devicetree-bindings-Document-Krait-Scorpion-cpus-and.patch65
-rw-r--r--target/linux/ipq806x/patches/0011-devicetree-bindings-Document-qcom-kpss-acc.patch49
-rw-r--r--target/linux/ipq806x/patches/0012-devicetree-bindings-Document-qcom-saw2-node.patch54
-rw-r--r--target/linux/ipq806x/patches/0013-ARM-qcom-Add-SMP-support-for-KPSSv1.patch174
-rw-r--r--target/linux/ipq806x/patches/0014-ARM-qcom-Add-SMP-support-for-KPSSv2.patch167
-rw-r--r--target/linux/ipq806x/patches/0015-tty-serial-msm-Enable-building-msm_serial-for-ARCH_Q.patch27
-rw-r--r--target/linux/ipq806x/patches/0016-drm-msm-drop-ARCH_MSM-Kconfig-depend.patch28
-rw-r--r--target/linux/ipq806x/patches/0017-power-reset-msm-switch-Kconfig-to-ARCH_QCOM-depends.patch27
-rw-r--r--target/linux/ipq806x/patches/0018-hwrng-msm-switch-Kconfig-to-ARCH_QCOM-depends.patch33
-rw-r--r--target/linux/ipq806x/patches/0019-gpio-msm-switch-Kconfig-to-ARCH_QCOM-depends.patch27
-rw-r--r--target/linux/ipq806x/patches/002-v3-spi-qup-Fix-incorrect-block-transfers.patch376
-rw-r--r--target/linux/ipq806x/patches/0020-ARM-qcom-Enable-basic-support-for-Qualcomm-platforms.patch49
-rw-r--r--target/linux/ipq806x/patches/0021-ARM-dts-qcom-Add-nodes-necessary-for-SMP-boot.patch205
-rw-r--r--target/linux/ipq806x/patches/0022-ARM-dts-qcom-Add-RNG-device-tree-node.patch30
-rw-r--r--target/linux/ipq806x/patches/0023-ARM-dts-qcom-msm8960-cdp-Add-RNG-device-tree-node.patch29
-rw-r--r--target/linux/ipq806x/patches/0024-ARM-dts-msm-Add-krait-pmu-to-platforms-with-Krait-CP.patch46
-rw-r--r--target/linux/ipq806x/patches/0025-pinctrl-msm-drop-wake_irqs-bitmap.patch66
-rw-r--r--target/linux/ipq806x/patches/0026-pinctrl-msm-Silence-recursive-lockdep-warning.patch68
-rw-r--r--target/linux/ipq806x/patches/0027-pinctrl-msm-Check-for-ngpios-MAX_NR_GPIO.patch34
-rw-r--r--target/linux/ipq806x/patches/0028-pinctrl-msm-Drop-unused-includes.patch51
-rw-r--r--target/linux/ipq806x/patches/0029-pinctrl-msm-Drop-OF_IRQ-dependency.patch26
-rw-r--r--target/linux/ipq806x/patches/0030-pinctrl-msm-Replace-lookup-tables-with-math.patch61
-rw-r--r--target/linux/ipq806x/patches/0031-pinctrl-msm-Remove-impossible-WARN_ON-s.patch90
-rw-r--r--target/linux/ipq806x/patches/0032-pinctrl-msm-Simplify-msm_config_reg-and-callers.patch110
-rw-r--r--target/linux/ipq806x/patches/0033-pinctrl-msm-Support-output-high-low-configuration.patch64
-rw-r--r--target/linux/ipq806x/patches/0034-pinctrl-msm-Add-SPI8-pin-definitions.patch58
-rw-r--r--target/linux/ipq806x/patches/0035-pinctrl-msm-fix-up-out-of-order-merge-conflict.patch33
-rw-r--r--target/linux/ipq806x/patches/0036-pinctrl-msm-Correct-interrupt-code-for-TLMM-v2.patch48
-rw-r--r--target/linux/ipq806x/patches/0037-pinctrl-msm-Make-number-of-functions-variable.patch65
-rw-r--r--target/linux/ipq806x/patches/0038-pinctrl-msm-Add-definitions-for-the-APQ8064-platform.patch614
-rw-r--r--target/linux/ipq806x/patches/0039-pinctrl-msm8x74-make-Kconfig-dependency-more-strict.patch31
-rw-r--r--target/linux/ipq806x/patches/0040-pinctrl-qcom-Add-definitions-for-IPQ8064.patch701
-rw-r--r--target/linux/ipq806x/patches/0041-dt-Document-Qualcomm-IPQ8064-pinctrl-binding.patch114
-rw-r--r--target/linux/ipq806x/patches/0042-ARM-qcom-Select-PINCTRL-by-default-for-ARCH_QCOM.patch24
-rw-r--r--target/linux/ipq806x/patches/0043-pinctrl-qcom-Correct-name-for-pin-0.patch23
-rw-r--r--target/linux/ipq806x/patches/0044-dmaengine-qcom_bam_dma-Add-device-tree-binding.patch59
-rw-r--r--target/linux/ipq806x/patches/0045-dmaengine-add-Qualcomm-BAM-dma-driver.patch1164
-rw-r--r--target/linux/ipq806x/patches/0046-mmc-sdhci-msm-Qualcomm-SDHCI-binding-documentation.patch75
-rw-r--r--target/linux/ipq806x/patches/0047-mmc-sdhci-msm-Initial-support-for-Qualcomm-chipsets.patch265
-rw-r--r--target/linux/ipq806x/patches/0048-mmc-sdhci-msm-Add-platform_execute_tuning-implementa.patch467
-rw-r--r--target/linux/ipq806x/patches/0049-drivers-of-add-initialization-code-for-static-reserv.patch209
-rw-r--r--target/linux/ipq806x/patches/0050-drivers-of-add-initialization-code-for-dynamic-reser.patch316
-rw-r--r--target/linux/ipq806x/patches/0051-drivers-of-add-support-for-custom-reserved-memory-dr.patch147
-rw-r--r--target/linux/ipq806x/patches/0052-arm-add-support-for-reserved-memory-defined-by-devic.patch36
-rw-r--r--target/linux/ipq806x/patches/0053-of-document-bindings-for-reserved-memory-nodes.patch158
-rw-r--r--target/linux/ipq806x/patches/0054-of-only-scan-for-reserved-mem-when-fdt-present.patch30
-rw-r--r--target/linux/ipq806x/patches/0055-spmi-Linux-driver-framework-for-SPMI.patch919
-rw-r--r--target/linux/ipq806x/patches/0056-spmi-Add-MSM-PMIC-Arbiter-SPMI-controller.patch467
-rw-r--r--target/linux/ipq806x/patches/0057-spmi-pmic_arb-add-support-for-interrupt-handling.patch487
-rw-r--r--target/linux/ipq806x/patches/0058-spmi-pmic_arb-make-selectable-on-ARCH_QCOM.patch29
-rw-r--r--target/linux/ipq806x/patches/0059-spmi-pm-drop-bus-level-PM-suspend-resume-routines.patch69
-rw-r--r--target/linux/ipq806x/patches/0060-i2c-qup-New-bus-driver-for-the-Qualcomm-QUP-I2C-cont.patch825
-rw-r--r--target/linux/ipq806x/patches/0061-i2c-qup-Add-device-tree-bindings-information.patch65
-rw-r--r--target/linux/ipq806x/patches/0062-i2c-qup-off-by-ones-in-qup_i2c_probe.patch31
-rw-r--r--target/linux/ipq806x/patches/0063-i2c-qup-use-proper-type-fro-clk_freq.patch25
-rw-r--r--target/linux/ipq806x/patches/0064-i2c-qup-Fix-pm_runtime_get_sync-usage.patch26
-rw-r--r--target/linux/ipq806x/patches/0065-spi-Add-Qualcomm-QUP-SPI-controller-support.patch897
-rw-r--r--target/linux/ipq806x/patches/0066-spi-qup-Add-device-tree-bindings-information.patch105
-rw-r--r--target/linux/ipq806x/patches/0067-spi-qup-Remove-spi_master_put-in-spi_qup_remove.patch25
-rw-r--r--target/linux/ipq806x/patches/0068-spi-qup-Convert-ot-let-spi-core-handle-checking-tran.patch64
-rw-r--r--target/linux/ipq806x/patches/0069-spi-qup-Fix-build-error-due-to-a-typo.patch43
-rw-r--r--target/linux/ipq806x/patches/0070-spi-qup-Enable-driver-compilation-with-COMPILE_TEST.patch25
-rw-r--r--target/linux/ipq806x/patches/0071-spi-qup-Depend-on-ARM-COMPILE_TEST-to-avoid-build-er.patch35
-rw-r--r--target/linux/ipq806x/patches/0072-spi-qup-Remove-module-version.patch23
-rw-r--r--target/linux/ipq806x/patches/0073-spi-qup-Get-rid-of-using-struct-spi_qup_device.patch162
-rw-r--r--target/linux/ipq806x/patches/0074-spi-qup-Depend-on-ARCH_QCOM.patch31
-rw-r--r--target/linux/ipq806x/patches/0075-spi-qup-Correct-selection-of-FIFO-Block-mode.patch34
-rw-r--r--target/linux/ipq806x/patches/0078-clk-qcom-Consolidate-common-probe-code.patch734
-rw-r--r--target/linux/ipq806x/patches/0079-clk-qcom-Add-basic-support-for-APQ8064-global-clock-.patch114
-rw-r--r--target/linux/ipq806x/patches/0080-clk-qcom-Various-fixes-for-MSM8960-s-global-clock-co.patch92
-rw-r--r--target/linux/ipq806x/patches/0081-ARM-config-Add-qcom_defconfig.patch184
-rw-r--r--target/linux/ipq806x/patches/0082-ARM-qcom-Enable-GSBI-driver-in-defconfig.patch20
-rw-r--r--target/linux/ipq806x/patches/0083-soc-Introduce-drivers-soc-place-holder-for-SOC-speci.patch58
-rw-r--r--target/linux/ipq806x/patches/0084-soc-qcom-Add-GSBI-driver.patch145
-rw-r--r--target/linux/ipq806x/patches/0085-soc-qcom-fix-of_device_id-table.patch23
-rw-r--r--target/linux/ipq806x/patches/0086-msm_serial-Add-support-for-poll_-get-put-_char.patch239
-rw-r--r--target/linux/ipq806x/patches/0087-tty-serial-msm-Remove-direct-access-to-GSBI.patch144
-rw-r--r--target/linux/ipq806x/patches/0088-soc-qcom-Add-device-tree-binding-for-GSBI.patch126
-rw-r--r--target/linux/ipq806x/patches/0089-ARM-dts-MSM8974-Add-pinctrl-node.patch52
-rw-r--r--target/linux/ipq806x/patches/0090-ARM-dts-msm-Add-SDHC-controller-nodes-for-MSM8974-an.patch68
-rw-r--r--target/linux/ipq806x/patches/0091-ARM-dts-qcom-Update-msm8974-apq8074-device-trees.patch179
-rw-r--r--target/linux/ipq806x/patches/0092-ARM-dts-qcom-Update-msm8960-device-trees.patch261
-rw-r--r--target/linux/ipq806x/patches/0093-ARM-dts-qcom-Update-msm8660-device-trees.patch184
-rw-r--r--target/linux/ipq806x/patches/0094-ARM-dts-qcom-Add-initial-APQ8064-SoC-and-IFC6410-boa.patch249
-rw-r--r--target/linux/ipq806x/patches/0095-ARM-dts-qcom-Add-APQ8084-MTP-board-support.patch35
-rw-r--r--target/linux/ipq806x/patches/0096-ARM-dts-qcom-Add-APQ8084-SoC-support.patch208
-rw-r--r--target/linux/ipq806x/patches/0097-ARM-debug-qcom-make-UART-address-selection-configura.patch258
-rw-r--r--target/linux/ipq806x/patches/0098-ARM-debug-qcom-add-UART-addresses-to-Kconfig-help-fo.patch25
-rw-r--r--target/linux/ipq806x/patches/0099-ARM-qcom-Enable-ARM_AMBA-option-for-Qualcomm-SOCs.patch26
-rw-r--r--target/linux/ipq806x/patches/0100-clk-qcom-Fix-msm8660-GCC-probe.patch37
-rw-r--r--target/linux/ipq806x/patches/0101-clk-qcom-Fix-blsp2_ahb_clk-register-offset.patch25
-rw-r--r--target/linux/ipq806x/patches/0104-clk-qcom-Return-highest-rate-when-round_rate-exceeds.patch31
-rw-r--r--target/linux/ipq806x/patches/0105-clk-qcom-Support-display-RCG-clocks.patch371
-rw-r--r--target/linux/ipq806x/patches/0106-clk-qcom-Properly-support-display-clocks-on-msm8974.patch254
-rw-r--r--target/linux/ipq806x/patches/0107-clk-qcom-Support-msm8974pro-global-clock-control-har.patch236
-rw-r--r--target/linux/ipq806x/patches/0108-clk-qcom-Return-error-pointers-for-unimplemented-clo.patch32
-rw-r--r--target/linux/ipq806x/patches/0109-libahci-Allow-drivers-to-override-start_engine.patch212
-rw-r--r--target/linux/ipq806x/patches/0110-ahci-platform-Add-support-for-devices-with-more-then.patch242
-rw-r--r--target/linux/ipq806x/patches/0111-ahci-platform-Add-support-for-an-optional-regulator-.patch133
-rw-r--r--target/linux/ipq806x/patches/0112-ahci-platform-Add-enable_-disable_resources-helper-f.patch201
-rw-r--r--target/linux/ipq806x/patches/0113-ata-delete-non-required-instances-of-include-linux-i.patch765
-rw-r--r--target/linux/ipq806x/patches/0114-ahci-platform-Library-ise-ahci_probe-functionality.patch334
-rw-r--r--target/linux/ipq806x/patches/0115-ahci-platform-Library-ise-suspend-resume-functionali.patch173
-rw-r--r--target/linux/ipq806x/patches/0116-ata-ahci_platform-Add-DT-compatible-for-Synopsis-DWC.patch27
-rw-r--r--target/linux/ipq806x/patches/0117-ata-ahci_platform-Manage-SATA-PHY.patch134
-rw-r--r--target/linux/ipq806x/patches/0118-ata-ahci_platform-runtime-resume-the-device-before-u.patch79
-rw-r--r--target/linux/ipq806x/patches/0119-ahci_platform-Drop-support-for-ahci-strict-platform-.patch49
-rw-r--r--target/linux/ipq806x/patches/0120-ahci_platform-Drop-support-for-imx53-ahci-platform-d.patch105
-rw-r--r--target/linux/ipq806x/patches/0121-ahci_platform-Drop-unused-ahci_platform_data-members.patch55
-rw-r--r--target/linux/ipq806x/patches/0122-ata-ahci_platform-fix-devm_ioremap_resource-return-v.patch41
-rw-r--r--target/linux/ipq806x/patches/0123-ata-ahci_platform-fix-ahci_platform_data-suspend-met.patch45
-rw-r--r--target/linux/ipq806x/patches/0124-ata-move-library-code-from-ahci_platform.c-to-libahc.patch1145
-rw-r--r--target/linux/ipq806x/patches/0125-clk-qcom-Add-support-for-IPQ8064-s-global-clock-cont.patch2921
-rw-r--r--target/linux/ipq806x/patches/0126-clk-Add-safe-switch-hook.patch146
-rw-r--r--target/linux/ipq806x/patches/0127-clk-qcom-Add-support-for-setting-rates-on-PLLs.patch148
-rw-r--r--target/linux/ipq806x/patches/0128-clk-qcom-Add-support-for-banked-MD-RCGs.patch308
-rw-r--r--target/linux/ipq806x/patches/0129-clk-qcom-Add-support-for-NSS-GMAC-clocks-and-resets.patch860
-rw-r--r--target/linux/ipq806x/patches/0130-ARM-qcom-Add-initial-IPQ8064-SoC-and-AP148-device-tr.patch253
-rw-r--r--target/linux/ipq806x/patches/0131-ARM-qcom-config-Enable-IPQ806x-support.patch20
-rw-r--r--target/linux/ipq806x/patches/0132-XXX-Add-boot-support-for-u-boot.ipq-image.patch48
-rw-r--r--target/linux/ipq806x/patches/0133-spi-qup-Remove-chip-select-function.patch83
-rw-r--r--target/linux/ipq806x/patches/0134-spi-qup-Fix-order-of-spi_register_master.patch41
-rw-r--r--target/linux/ipq806x/patches/0135-spi-qup-Add-support-for-v1.1.1.patch125
-rw-r--r--target/linux/ipq806x/patches/0136-ARM-ipq8064-ap148-Add-i2c-pinctrl-nodes.patch86
-rw-r--r--target/linux/ipq806x/patches/0137-ARM-qcom-ipq8064-ap148-Add-SPI-related-bindings.patch124
-rw-r--r--target/linux/ipq806x/patches/0138-PCI-qcom-Add-support-for-pcie-controllers-on-IPQ8064.patch716
-rw-r--r--target/linux/ipq806x/patches/0139-ARM-dts-msm-Add-PCIe-related-nodes-for-IPQ8064-AP148.patch172
-rw-r--r--target/linux/ipq806x/patches/0140-ARM-qcom-config-Enable-PCI-support-for-IPQ806x.patch28
-rw-r--r--target/linux/ipq806x/patches/0141-ahci-platform-Bump-max-number-of-clocks-to-5.patch23
-rw-r--r--target/linux/ipq806x/patches/0142-ata-Add-Qualcomm-ARM-SoC-AHCI-SATA-host-controller-d.patch136
-rw-r--r--target/linux/ipq806x/patches/0143-ata-qcom-Add-device-tree-bindings-information.patch57
-rw-r--r--target/linux/ipq806x/patches/0144-phy-qcom-Add-driver-for-QCOM-IPQ806x-SATA-PHY.patch251
-rw-r--r--target/linux/ipq806x/patches/0145-phy-qcom-Add-device-tree-bindings-information.patch40
-rw-r--r--target/linux/ipq806x/patches/0146-ARM-dts-qcom-Add-SATA-support-for-IPQ8064-and-AP148-.patch65
-rw-r--r--target/linux/ipq806x/patches/0147-ARM-qcom-Enable-SATA-SATA-PHY-drivers-in-defconfig.patch37
-rw-r--r--target/linux/ipq806x/patches/0148-ARM-qcom-enable-default-CPU_IDLE-to-get-wfi-support-.patch21
-rw-r--r--target/linux/ipq806x/patches/0149-pinctrl-qcom-Add-BUS_HOLD-Keeper-bias.patch50
-rw-r--r--target/linux/ipq806x/patches/0150-mtd-nand-Add-Qualcomm-NAND-controller.patch8784
-rw-r--r--target/linux/ipq806x/patches/0151-ARM-ipq8064-Add-nand-device-info.patch108
-rw-r--r--target/linux/ipq806x/patches/0152-ARM-qcom-config-Add-NAND-config-options.patch22
-rw-r--r--target/linux/ipq806x/patches/0153-soc-qcom-tcsr-Add-TCSR-driver.patch153
-rw-r--r--target/linux/ipq806x/patches/0154-clk-qcom-Correct-UTMI-clock-frequency-table.patch24
-rw-r--r--target/linux/ipq806x/patches/0155-clk-qcom-Fix-incorrect-UTMI-DT-include-values.patch58
-rw-r--r--target/linux/ipq806x/patches/0156-usb-dwc3-Add-Qualcomm-DWC3-glue-layer-driver.patch202
-rw-r--r--target/linux/ipq806x/patches/0157-usb-phy-Add-Qualcomm-DWC3-HS-SS-PHY-drivers.patch861
-rw-r--r--target/linux/ipq806x/patches/0158-usb-dwc3-qcom-Add-device-tree-binding.patch125
-rw-r--r--target/linux/ipq806x/patches/0159-arm-ipq8064-Add-USB3-DT-information.patch155
-rw-r--r--target/linux/ipq806x/patches/0160-ARM-qcom-config-Add-TCSR-and-USB3-options.patch37
-rw-r--r--target/linux/ipq806x/patches/0161-ARM-Remove-ARCH_HAS_CPUFREQ-config-option.patch234
-rw-r--r--target/linux/ipq806x/patches/0162-PM-OPP-Remove-ARCH_HAS_OPP.patch115
-rw-r--r--target/linux/ipq806x/patches/0163-clk-return-probe-defer-when-DT-clock-not-yet-ready.patch42
-rw-r--r--target/linux/ipq806x/patches/0164-ARM-Add-Krait-L2-register-accessor-functions.patch133
-rw-r--r--target/linux/ipq806x/patches/0165-clk-qcom-Add-support-for-muxes-dividers-and-mux-divi.patch652
-rw-r--r--target/linux/ipq806x/patches/0166-clk-qcom-Add-support-for-High-Frequency-PLLs-HFPLLs.patch348
-rw-r--r--target/linux/ipq806x/patches/0167-clk-qcom-Add-HFPLL-driver.patch152
-rw-r--r--target/linux/ipq806x/patches/0168-clk-qcom-Add-MSM8960-s-HFPLLs.patch117
-rw-r--r--target/linux/ipq806x/patches/0169-clk-qcom-Add-support-for-Krait-clocks.patch190
-rw-r--r--target/linux/ipq806x/patches/0170-clk-qcom-Add-KPSS-ACC-GCC-driver.patch161
-rw-r--r--target/linux/ipq806x/patches/0171-clk-qcom-Add-Krait-clock-controller-driver.patch410
-rw-r--r--target/linux/ipq806x/patches/0172-cpufreq-Add-a-cpufreq-krait-based-on-cpufreq-cpu0.patch245
-rw-r--r--target/linux/ipq806x/patches/0173-cpufreq-Add-module-to-register-cpufreq-krait-device.patch94
-rw-r--r--target/linux/ipq806x/patches/0174-clk-qcom-Add-HFPLLs-to-IPQ806X-driver.patch116
-rw-r--r--target/linux/ipq806x/patches/0175-ARM-dts-ipq8064-Add-necessary-DT-data-for-Krait-cpuf.patch91
-rw-r--r--target/linux/ipq806x/patches/0176-ARM-qcom_defconfig-Enable-CPUfreq-options.patch39
-rw-r--r--target/linux/ipq806x/patches/0177-dmaengine-Add-QCOM-ADM-DMA-driver.patch921
-rw-r--r--target/linux/ipq806x/patches/0178-dmaengine-qcom_adm-Add-device-tree-binding.patch76
-rw-r--r--target/linux/ipq806x/patches/0180-ARM-dts-Add-ADM-DMA-nodes-and-SPI-linkage.patch83
-rw-r--r--target/linux/ipq806x/patches/0181-mtd-nand-qcom-Align-clk-and-reset-names.patch41
-rw-r--r--target/linux/ipq806x/patches/0182-qcom-Kconfig-Make-drivers-mutually-exclusive.patch47
182 files changed, 819 insertions, 43760 deletions
diff --git a/target/linux/ipq806x/Makefile b/target/linux/ipq806x/Makefile
index 875bb9c..f07c87d 100644
--- a/target/linux/ipq806x/Makefile
+++ b/target/linux/ipq806x/Makefile
@@ -9,7 +9,7 @@ FEATURES:=squashfs
CPU_TYPE:=cortex-a7
MAINTAINER:=John Crispin <blogic@openwrt.org>
-KERNEL_PATCHVER:=3.14
+KERNEL_PATCHVER:=3.18
KERNELNAME:=Image dtbs
diff --git a/target/linux/ipq806x/config-3.18 b/target/linux/ipq806x/config-3.18
new file mode 100644
index 0000000..22d8092
--- /dev/null
+++ b/target/linux/ipq806x/config-3.18
@@ -0,0 +1,371 @@
+CONFIG_ALIGNMENT_TRAP=y
+# CONFIG_AMBA_PL08X is not set
+# CONFIG_APM_EMULATION is not set
+CONFIG_APQ_GCC_8084=y
+CONFIG_APQ_MMCC_8084=y
+CONFIG_ARCH_BINFMT_ELF_RANDOMIZE_PIE=y
+CONFIG_ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE=y
+CONFIG_ARCH_HAS_SG_CHAIN=y
+CONFIG_ARCH_HAS_TICK_BROADCAST=y
+CONFIG_ARCH_HAVE_CUSTOM_GPIO_H=y
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
+CONFIG_ARCH_MIGHT_HAVE_PC_PARPORT=y
+CONFIG_ARCH_MSM8960=y
+CONFIG_ARCH_MSM8974=y
+CONFIG_ARCH_MSM8X60=y
+CONFIG_ARCH_MULTIPLATFORM=y
+# CONFIG_ARCH_MULTI_CPU_AUTO is not set
+CONFIG_ARCH_MULTI_V6_V7=y
+CONFIG_ARCH_MULTI_V7=y
+# CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED is not set
+CONFIG_ARCH_NR_GPIO=0
+CONFIG_ARCH_QCOM=y
+CONFIG_ARCH_REQUIRE_GPIOLIB=y
+# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
+# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
+CONFIG_ARCH_SUPPORTS_ATOMIC_RMW=y
+CONFIG_ARCH_SUPPORTS_UPROBES=y
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+CONFIG_ARCH_USE_BUILTIN_BSWAP=y
+CONFIG_ARCH_USE_CMPXCHG_LOCKREF=y
+CONFIG_ARCH_WANT_GENERAL_HUGETLB=y
+CONFIG_ARCH_WANT_IPC_PARSE_VERSION=y
+CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
+CONFIG_ARM=y
+CONFIG_ARM_AMBA=y
+CONFIG_ARM_ARCH_TIMER=y
+CONFIG_ARM_ARCH_TIMER_EVTSTREAM=y
+CONFIG_ARM_CPU_SUSPEND=y
+CONFIG_ARM_GIC=y
+CONFIG_ARM_HAS_SG_CHAIN=y
+CONFIG_ARM_L1_CACHE_SHIFT=6
+CONFIG_ARM_L1_CACHE_SHIFT_6=y
+# CONFIG_ARM_LPAE is not set
+CONFIG_ARM_PATCH_PHYS_VIRT=y
+# CONFIG_ARM_SP805_WATCHDOG is not set
+CONFIG_ARM_THUMB=y
+# CONFIG_ARM_THUMBEE is not set
+CONFIG_ARM_UNWIND=y
+CONFIG_ARM_VIRT_EXT=y
+CONFIG_AUTO_ZRELADDR=y
+# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
+CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
+CONFIG_BOUNCE=y
+CONFIG_BUILD_BIN2C=y
+# CONFIG_CACHE_L2X0 is not set
+CONFIG_CLEANCACHE=y
+CONFIG_CLKDEV_LOOKUP=y
+CONFIG_CLKSRC_OF=y
+CONFIG_CLKSRC_QCOM=y
+CONFIG_CLONE_BACKWARDS=y
+CONFIG_COMMON_CLK=y
+CONFIG_COMMON_CLK_QCOM=y
+CONFIG_COMPACTION=y
+CONFIG_COREDUMP=y
+CONFIG_CPU_32v6K=y
+CONFIG_CPU_32v7=y
+CONFIG_CPU_ABRT_EV7=y
+# CONFIG_CPU_BPREDICT_DISABLE is not set
+CONFIG_CPU_CACHE_V7=y
+CONFIG_CPU_CACHE_VIPT=y
+CONFIG_CPU_COPY_V6=y
+CONFIG_CPU_CP15=y
+CONFIG_CPU_CP15_MMU=y
+CONFIG_CPU_HAS_ASID=y
+# CONFIG_CPU_ICACHE_DISABLE is not set
+CONFIG_CPU_PABRT_V7=y
+CONFIG_CPU_PM=y
+CONFIG_CPU_RMAP=y
+CONFIG_CPU_TLB_V7=y
+CONFIG_CPU_V7=y
+CONFIG_CRC16=y
+# CONFIG_CRC32_SARWATE is not set
+CONFIG_CRC32_SLICEBY8=y
+CONFIG_CROSS_MEMORY_ATTACH=y
+# CONFIG_CRYPTO_SHA1_ARM_NEON is not set
+# CONFIG_CRYPTO_SHA512_ARM_NEON is not set
+CONFIG_CRYPTO_XZ=y
+CONFIG_DCACHE_WORD_ACCESS=y
+CONFIG_DEBUG_BUGVERBOSE=y
+CONFIG_DEBUG_GPIO=y
+CONFIG_DEBUG_LL_INCLUDE="mach/debug-macro.S"
+CONFIG_DEBUG_PREEMPT=y
+# CONFIG_DEBUG_UART_8250 is not set
+# CONFIG_DEBUG_UART_PL01X is not set
+# CONFIG_DEBUG_USER is not set
+CONFIG_DECOMPRESS_GZIP=y
+CONFIG_DMADEVICES=y
+CONFIG_DMA_ENGINE=y
+CONFIG_DMA_OF=y
+CONFIG_DMA_VIRTUAL_CHANNELS=y
+CONFIG_DTC=y
+# CONFIG_DW_DMAC_CORE is not set
+# CONFIG_DW_DMAC_PCI is not set
+CONFIG_DYNAMIC_DEBUG=y
+# CONFIG_EMAC_ROCKCHIP is not set
+CONFIG_FREEZER=y
+CONFIG_GENERIC_ALLOCATOR=y
+CONFIG_GENERIC_BUG=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+CONFIG_GENERIC_IDLE_POLL_SETUP=y
+CONFIG_GENERIC_IO=y
+CONFIG_GENERIC_IRQ_SHOW=y
+CONFIG_GENERIC_PCI_IOMAP=y
+CONFIG_GENERIC_PHY=y
+CONFIG_GENERIC_PINCONF=y
+CONFIG_GENERIC_SCHED_CLOCK=y
+CONFIG_GENERIC_SMP_IDLE_THREAD=y
+CONFIG_GENERIC_STRNCPY_FROM_USER=y
+CONFIG_GENERIC_STRNLEN_USER=y
+CONFIG_GPIOLIB=y
+CONFIG_GPIOLIB_IRQCHIP=y
+CONFIG_GPIO_DEVRES=y
+# CONFIG_GPIO_MSM_V2 is not set
+CONFIG_GPIO_SYSFS=y
+CONFIG_HANDLE_DOMAIN_IRQ=y
+CONFIG_HARDIRQS_SW_RESEND=y
+CONFIG_HAS_DMA=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT_MAP=y
+# CONFIG_HAVE_64BIT_ALIGNED_ACCESS is not set
+CONFIG_HAVE_ARCH_AUDITSYSCALL=y
+CONFIG_HAVE_ARCH_JUMP_LABEL=y
+CONFIG_HAVE_ARCH_KGDB=y
+CONFIG_HAVE_ARCH_PFN_VALID=y
+CONFIG_HAVE_ARCH_SECCOMP_FILTER=y
+CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_ARM_ARCH_TIMER=y
+# CONFIG_HAVE_BOOTMEM_INFO_NODE is not set
+CONFIG_HAVE_BPF_JIT=y
+CONFIG_HAVE_CC_STACKPROTECTOR=y
+CONFIG_HAVE_CLK=y
+CONFIG_HAVE_CLK_PREPARE=y
+CONFIG_HAVE_CONTEXT_TRACKING=y
+CONFIG_HAVE_C_RECORDMCOUNT=y
+CONFIG_HAVE_DEBUG_KMEMLEAK=y
+CONFIG_HAVE_DMA_API_DEBUG=y
+CONFIG_HAVE_DMA_ATTRS=y
+CONFIG_HAVE_DMA_CONTIGUOUS=y
+CONFIG_HAVE_DYNAMIC_FTRACE=y
+CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y
+CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
+CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
+CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_HAVE_GENERIC_DMA_COHERENT=y
+CONFIG_HAVE_HW_BREAKPOINT=y
+CONFIG_HAVE_IDE=y
+CONFIG_HAVE_IRQ_TIME_ACCOUNTING=y
+CONFIG_HAVE_KERNEL_GZIP=y
+CONFIG_HAVE_KERNEL_LZ4=y
+CONFIG_HAVE_KERNEL_LZMA=y
+CONFIG_HAVE_KERNEL_LZO=y
+CONFIG_HAVE_KERNEL_XZ=y
+CONFIG_HAVE_MEMBLOCK=y
+CONFIG_HAVE_MOD_ARCH_SPECIFIC=y
+CONFIG_HAVE_NET_DSA=y
+CONFIG_HAVE_OPROFILE=y
+CONFIG_HAVE_PERF_EVENTS=y
+CONFIG_HAVE_PERF_REGS=y
+CONFIG_HAVE_PERF_USER_STACK_DUMP=y
+CONFIG_HAVE_PROC_CPU=y
+CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y
+CONFIG_HAVE_SMP=y
+CONFIG_HAVE_SYSCALL_TRACEPOINTS=y
+CONFIG_HAVE_UID16=y
+CONFIG_HAVE_VIRT_CPU_ACCOUNTING_GEN=y
+CONFIG_HIGHMEM=y
+CONFIG_HIGHPTE=y
+CONFIG_HOTPLUG_CPU=y
+CONFIG_HWMON=y
+CONFIG_HW_RANDOM=y
+CONFIG_HW_RANDOM_MSM=y
+CONFIG_HZ_FIXED=0
+CONFIG_I2C=y
+CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_COMPAT=y
+CONFIG_I2C_HELPER_AUTO=y
+CONFIG_I2C_QUP=y
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_IOMMU_API=y
+CONFIG_IOMMU_HELPER=y
+CONFIG_IOMMU_PGTABLES_L2=y
+CONFIG_IOMMU_SUPPORT=y
+CONFIG_IPQ_GCC_806X=y
+CONFIG_IRQCHIP=y
+CONFIG_IRQ_DOMAIN=y
+CONFIG_IRQ_FORCED_THREADING=y
+CONFIG_IRQ_WORK=y
+CONFIG_KERNFS=y
+# CONFIG_LEDS_REGULATOR is not set
+CONFIG_LIBFDT=y
+CONFIG_LOCKUP_DETECTOR=y
+CONFIG_LZO_COMPRESS=y
+CONFIG_LZO_DECOMPRESS=y
+CONFIG_MDIO_BITBANG=y
+CONFIG_MDIO_BOARDINFO=y
+CONFIG_MDIO_GPIO=y
+# CONFIG_MFD_SPMI_PMIC is not set
+CONFIG_MIGHT_HAVE_CACHE_L2X0=y
+CONFIG_MIGHT_HAVE_PCI=y
+CONFIG_MIGRATION=y
+CONFIG_MODULES_USE_ELF_REL=y
+CONFIG_MSM_GCC_8660=y
+CONFIG_MSM_GCC_8960=y
+CONFIG_MSM_GCC_8974=y
+CONFIG_MSM_IOMMU=y
+CONFIG_MSM_MMCC_8960=y
+CONFIG_MSM_MMCC_8974=y
+CONFIG_MTD_CMDLINE_PARTS=y
+CONFIG_MTD_M25P80=y
+CONFIG_MTD_SPI_NOR=y
+CONFIG_MTD_SPLIT_SUPPORT=y
+CONFIG_MULTI_IRQ_HANDLER=y
+CONFIG_MUTEX_SPIN_ON_OWNER=y
+CONFIG_NEED_DMA_MAP_STATE=y
+CONFIG_NEON=y
+CONFIG_NET_FLOW_LIMIT=y
+CONFIG_NET_VENDOR_WIZNET=y
+CONFIG_NO_BOOTMEM=y
+CONFIG_NO_HZ=y
+CONFIG_NO_HZ_COMMON=y
+CONFIG_NO_HZ_IDLE=y
+CONFIG_NR_CPUS=4
+CONFIG_OF=y
+CONFIG_OF_ADDRESS=y
+CONFIG_OF_ADDRESS_PCI=y
+CONFIG_OF_EARLY_FLATTREE=y
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_GPIO=y
+CONFIG_OF_IOMMU=y
+CONFIG_OF_IRQ=y
+CONFIG_OF_MDIO=y
+CONFIG_OF_MTD=y
+CONFIG_OF_NET=y
+CONFIG_OF_PCI=y
+CONFIG_OF_PCI_IRQ=y
+CONFIG_OF_RESERVED_MEM=y
+CONFIG_OLD_SIGACTION=y
+CONFIG_OLD_SIGSUSPEND3=y
+CONFIG_PAGEFLAGS_EXTENDED=y
+CONFIG_PAGE_OFFSET=0xC0000000
+CONFIG_PCI=y
+CONFIG_PCI_MSI=y
+CONFIG_PERF_EVENTS=y
+CONFIG_PERF_USE_VMALLOC=y
+CONFIG_PHYLIB=y
+# CONFIG_PHY_QCOM_APQ8064_SATA is not set
+CONFIG_PHY_QCOM_IPQ806X_SATA=y
+CONFIG_PINCTRL=y
+CONFIG_PINCTRL_APQ8064=y
+# CONFIG_PINCTRL_APQ8084 is not set
+CONFIG_PINCTRL_IPQ8064=y
+CONFIG_PINCTRL_MSM=y
+# CONFIG_PINCTRL_MSM8960 is not set
+CONFIG_PINCTRL_MSM8X74=y
+# CONFIG_PL330_DMA is not set
+CONFIG_PM=y
+CONFIG_PM_CLK=y
+# CONFIG_PM_DEBUG is not set
+CONFIG_PM_SLEEP=y
+CONFIG_PM_SLEEP_SMP=y
+CONFIG_POWER_RESET=y
+# CONFIG_POWER_RESET_BRCMSTB is not set
+# CONFIG_POWER_RESET_GPIO is not set
+# CONFIG_POWER_RESET_GPIO_RESTART is not set
+# CONFIG_POWER_RESET_LTC2952 is not set
+CONFIG_POWER_RESET_MSM=y
+# CONFIG_POWER_RESET_SYSCON is not set
+CONFIG_POWER_SUPPLY=y
+CONFIG_PREEMPT=y
+CONFIG_PREEMPT_COUNT=y
+# CONFIG_PREEMPT_NONE is not set
+CONFIG_PREEMPT_RCU=y
+CONFIG_PRINTK_TIME=y
+CONFIG_PROC_PAGE_MONITOR=y
+CONFIG_QCOM_BAM_DMA=y
+CONFIG_QCOM_GSBI=y
+CONFIG_QCOM_SCM=y
+# CONFIG_QCOM_WDT is not set
+# CONFIG_RCU_BOOST is not set
+CONFIG_RCU_CPU_STALL_TIMEOUT=21
+CONFIG_RCU_CPU_STALL_VERBOSE=y
+CONFIG_RCU_STALL_COMMON=y
+CONFIG_RD_GZIP=y
+CONFIG_REGMAP=y
+CONFIG_REGMAP_MMIO=y
+CONFIG_REGULATOR=y
+# CONFIG_REGULATOR_DEBUG is not set
+# CONFIG_REGULATOR_USERSPACE_CONSUMER is not set
+CONFIG_RESET_CONTROLLER=y
+CONFIG_RFS_ACCEL=y
+CONFIG_RPS=y
+CONFIG_RTC_CLASS=y
+# CONFIG_RTC_DRV_CMOS is not set
+CONFIG_RWSEM_SPIN_ON_OWNER=y
+CONFIG_RWSEM_XCHGADD_ALGORITHM=y
+CONFIG_SCHED_HRTICK=y
+# CONFIG_SCSI_DMA is not set
+# CONFIG_SERIAL_AMBA_PL010 is not set
+# CONFIG_SERIAL_AMBA_PL011 is not set
+CONFIG_SERIAL_MSM=y
+CONFIG_SERIAL_MSM_CONSOLE=y
+# CONFIG_SLAB is not set
+CONFIG_SLUB=y
+CONFIG_SLUB_CPU_PARTIAL=y
+CONFIG_SMP=y
+CONFIG_SMP_ON_UP=y
+CONFIG_SPARSE_IRQ=y
+CONFIG_SPI=y
+CONFIG_SPI_MASTER=y
+CONFIG_SPI_QUP=y
+CONFIG_SPMI=y
+CONFIG_SPMI_MSM_PMIC_ARB=y
+CONFIG_STOP_MACHINE=y
+# CONFIG_STRIP_ASM_SYMS is not set
+CONFIG_SUSPEND=y
+CONFIG_SUSPEND_FREEZER=y
+CONFIG_SWCONFIG=y
+CONFIG_SWIOTLB=y
+CONFIG_SWP_EMULATE=y
+CONFIG_SYS_SUPPORTS_APM_EMULATION=y
+CONFIG_THERMAL=y
+# CONFIG_THERMAL_DEFAULT_GOV_FAIR_SHARE is not set
+CONFIG_THERMAL_DEFAULT_GOV_STEP_WISE=y
+# CONFIG_THERMAL_DEFAULT_GOV_USER_SPACE is not set
+# CONFIG_THERMAL_EMULATION is not set
+# CONFIG_THERMAL_GOV_FAIR_SHARE is not set
+CONFIG_THERMAL_GOV_STEP_WISE=y
+# CONFIG_THERMAL_GOV_USER_SPACE is not set
+CONFIG_THERMAL_HWMON=y
+CONFIG_THERMAL_OF=y
+# CONFIG_THUMB2_KERNEL is not set
+CONFIG_TICK_CPU_ACCOUNTING=y
+CONFIG_TIMER_STATS=y
+CONFIG_TREE_PREEMPT_RCU=y
+CONFIG_UEVENT_HELPER_PATH=""
+CONFIG_UID16=y
+CONFIG_UNCOMPRESS_INCLUDE="debug/uncompress.h"
+CONFIG_UNINLINE_SPIN_UNLOCK=y
+CONFIG_USE_OF=y
+CONFIG_VECTORS_BASE=0xffff0000
+# CONFIG_VFIO is not set
+CONFIG_VFP=y
+CONFIG_VFPv3=y
+CONFIG_VM_EVENT_COUNTERS=y
+# CONFIG_WIZNET_W5100 is not set
+# CONFIG_WIZNET_W5300 is not set
+# CONFIG_WL_TI is not set
+# CONFIG_WQ_POWER_EFFICIENT_DEFAULT is not set
+# CONFIG_XEN is not set
+CONFIG_XPS=y
+CONFIG_XZ_DEC_ARM=y
+CONFIG_XZ_DEC_BCJ=y
+CONFIG_ZBOOT_ROM_BSS=0
+CONFIG_ZBOOT_ROM_TEXT=0
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZONE_DMA_FLAG=0
diff --git a/target/linux/ipq806x/image/Makefile b/target/linux/ipq806x/image/Makefile
index 977e674..77d191f 100644
--- a/target/linux/ipq806x/image/Makefile
+++ b/target/linux/ipq806x/image/Makefile
@@ -24,6 +24,10 @@ define Image/BuildKernel
$(call Image/BuildKernel/FIT,qcom-ipq8064-ap148)
endef
+define Image/Build/squashfs
+ $(call prepare_generic_squashfs,$(KDIR)/root.squashfs)
+endef
+
define Image/Build
$(call Image/Build/$(1),$(1))
dd if=$(KDIR)/root.$(1) of=$(BIN_DIR)/$(IMG_PREFIX)-$(1)-root.img bs=2k conv=sync
diff --git a/target/linux/ipq806x/patches/0001-ARM-dts-msm-split-out-msm8660-and-msm8960-soc-into-d.patch b/target/linux/ipq806x/patches/0001-ARM-dts-msm-split-out-msm8660-and-msm8960-soc-into-d.patch
deleted file mode 100644
index 97c89b2..0000000
--- a/target/linux/ipq806x/patches/0001-ARM-dts-msm-split-out-msm8660-and-msm8960-soc-into-d.patch
+++ /dev/null
@@ -1,300 +0,0 @@
-From 3cdba35369b404875849008ea97cf1705e6060ed Mon Sep 17 00:00:00 2001
-From: Kumar Gala <galak@codeaurora.org>
-Date: Thu, 23 Jan 2014 14:09:54 -0600
-Subject: [PATCH 001/182] ARM: dts: msm: split out msm8660 and msm8960 soc
- into dts include
-
-Pull the SoC device tree bits into their own files so other boards based
-on these SoCs can include them and reduce duplication across a number of
-boards.
-
-Signed-off-by: Kumar Gala <galak@codeaurora.org>
----
- arch/arm/boot/dts/qcom-msm8660-surf.dts | 59 +-------------------------
- arch/arm/boot/dts/qcom-msm8660.dtsi | 63 ++++++++++++++++++++++++++++
- arch/arm/boot/dts/qcom-msm8960-cdp.dts | 66 +----------------------------
- arch/arm/boot/dts/qcom-msm8960.dtsi | 70 +++++++++++++++++++++++++++++++
- 4 files changed, 135 insertions(+), 123 deletions(-)
- create mode 100644 arch/arm/boot/dts/qcom-msm8660.dtsi
- create mode 100644 arch/arm/boot/dts/qcom-msm8960.dtsi
-
---- a/arch/arm/boot/dts/qcom-msm8660-surf.dts
-+++ b/arch/arm/boot/dts/qcom-msm8660-surf.dts
-@@ -1,63 +1,6 @@
--/dts-v1/;
--
--/include/ "skeleton.dtsi"
--
--#include <dt-bindings/clock/qcom,gcc-msm8660.h>
-+#include "qcom-msm8660.dtsi"
-
- / {
- model = "Qualcomm MSM8660 SURF";
- compatible = "qcom,msm8660-surf", "qcom,msm8660";
-- interrupt-parent = <&intc>;
--
-- intc: interrupt-controller@2080000 {
-- compatible = "qcom,msm-8660-qgic";
-- interrupt-controller;
-- #interrupt-cells = <3>;
-- reg = < 0x02080000 0x1000 >,
-- < 0x02081000 0x1000 >;
-- };
--
-- timer@2000000 {
-- compatible = "qcom,scss-timer", "qcom,msm-timer";
-- interrupts = <1 0 0x301>,
-- <1 1 0x301>,
-- <1 2 0x301>;
-- reg = <0x02000000 0x100>;
-- clock-frequency = <27000000>,
-- <32768>;
-- cpu-offset = <0x40000>;
-- };
--
-- msmgpio: gpio@800000 {
-- compatible = "qcom,msm-gpio";
-- reg = <0x00800000 0x4000>;
-- gpio-controller;
-- #gpio-cells = <2>;
-- ngpio = <173>;
-- interrupts = <0 16 0x4>;
-- interrupt-controller;
-- #interrupt-cells = <2>;
-- };
--
-- gcc: clock-controller@900000 {
-- compatible = "qcom,gcc-msm8660";
-- #clock-cells = <1>;
-- #reset-cells = <1>;
-- reg = <0x900000 0x4000>;
-- };
--
-- serial@19c40000 {
-- compatible = "qcom,msm-uartdm-v1.3", "qcom,msm-uartdm";
-- reg = <0x19c40000 0x1000>,
-- <0x19c00000 0x1000>;
-- interrupts = <0 195 0x0>;
-- clocks = <&gcc GSBI12_UART_CLK>, <&gcc GSBI12_H_CLK>;
-- clock-names = "core", "iface";
-- };
--
-- qcom,ssbi@500000 {
-- compatible = "qcom,ssbi";
-- reg = <0x500000 0x1000>;
-- qcom,controller-type = "pmic-arbiter";
-- };
- };
---- /dev/null
-+++ b/arch/arm/boot/dts/qcom-msm8660.dtsi
-@@ -0,0 +1,63 @@
-+/dts-v1/;
-+
-+/include/ "skeleton.dtsi"
-+
-+#include <dt-bindings/clock/qcom,gcc-msm8660.h>
-+
-+/ {
-+ model = "Qualcomm MSM8660";
-+ compatible = "qcom,msm8660";
-+ interrupt-parent = <&intc>;
-+
-+ intc: interrupt-controller@2080000 {
-+ compatible = "qcom,msm-8660-qgic";
-+ interrupt-controller;
-+ #interrupt-cells = <3>;
-+ reg = < 0x02080000 0x1000 >,
-+ < 0x02081000 0x1000 >;
-+ };
-+
-+ timer@2000000 {
-+ compatible = "qcom,scss-timer", "qcom,msm-timer";
-+ interrupts = <1 0 0x301>,
-+ <1 1 0x301>,
-+ <1 2 0x301>;
-+ reg = <0x02000000 0x100>;
-+ clock-frequency = <27000000>,
-+ <32768>;
-+ cpu-offset = <0x40000>;
-+ };
-+
-+ msmgpio: gpio@800000 {
-+ compatible = "qcom,msm-gpio";
-+ reg = <0x00800000 0x4000>;
-+ gpio-controller;
-+ #gpio-cells = <2>;
-+ ngpio = <173>;
-+ interrupts = <0 16 0x4>;
-+ interrupt-controller;
-+ #interrupt-cells = <2>;
-+ };
-+
-+ gcc: clock-controller@900000 {
-+ compatible = "qcom,gcc-msm8660";
-+ #clock-cells = <1>;
-+ #reset-cells = <1>;
-+ reg = <0x900000 0x4000>;
-+ };
-+
-+ serial@19c40000 {
-+ compatible = "qcom,msm-uartdm-v1.3", "qcom,msm-uartdm";
-+ reg = <0x19c40000 0x1000>,
-+ <0x19c00000 0x1000>;
-+ interrupts = <0 195 0x0>;
-+ clocks = <&gcc GSBI12_UART_CLK>, <&gcc GSBI12_H_CLK>;
-+ clock-names = "core", "iface";
-+ };
-+
-+ qcom,ssbi@500000 {
-+ compatible = "qcom,ssbi";
-+ reg = <0x500000 0x1000>;
-+ qcom,controller-type = "pmic-arbiter";
-+ };
-+};
---- a/arch/arm/boot/dts/qcom-msm8960-cdp.dts
-+++ b/arch/arm/boot/dts/qcom-msm8960-cdp.dts
-@@ -1,70 +1,6 @@
--/dts-v1/;
--
--/include/ "skeleton.dtsi"
--
--#include <dt-bindings/clock/qcom,gcc-msm8960.h>
-+#include "qcom-msm8960.dtsi"
-
- / {
- model = "Qualcomm MSM8960 CDP";
- compatible = "qcom,msm8960-cdp", "qcom,msm8960";
-- interrupt-parent = <&intc>;
--
-- intc: interrupt-controller@2000000 {
-- compatible = "qcom,msm-qgic2";
-- interrupt-controller;
-- #interrupt-cells = <3>;
-- reg = < 0x02000000 0x1000 >,
-- < 0x02002000 0x1000 >;
-- };
--
-- timer@200a000 {
-- compatible = "qcom,kpss-timer", "qcom,msm-timer";
-- interrupts = <1 1 0x301>,
-- <1 2 0x301>,
-- <1 3 0x301>;
-- reg = <0x0200a000 0x100>;
-- clock-frequency = <27000000>,
-- <32768>;
-- cpu-offset = <0x80000>;
-- };
--
-- msmgpio: gpio@800000 {
-- compatible = "qcom,msm-gpio";
-- gpio-controller;
-- #gpio-cells = <2>;
-- ngpio = <150>;
-- interrupts = <0 16 0x4>;
-- interrupt-controller;
-- #interrupt-cells = <2>;
-- reg = <0x800000 0x4000>;
-- };
--
-- gcc: clock-controller@900000 {
-- compatible = "qcom,gcc-msm8960";
-- #clock-cells = <1>;
-- #reset-cells = <1>;
-- reg = <0x900000 0x4000>;
-- };
--
-- clock-controller@4000000 {
-- compatible = "qcom,mmcc-msm8960";
-- reg = <0x4000000 0x1000>;
-- #clock-cells = <1>;
-- #reset-cells = <1>;
-- };
--
-- serial@16440000 {
-- compatible = "qcom,msm-uartdm-v1.3", "qcom,msm-uartdm";
-- reg = <0x16440000 0x1000>,
-- <0x16400000 0x1000>;
-- interrupts = <0 154 0x0>;
-- clocks = <&gcc GSBI5_UART_CLK>, <&gcc GSBI5_H_CLK>;
-- clock-names = "core", "iface";
-- };
--
-- qcom,ssbi@500000 {
-- compatible = "qcom,ssbi";
-- reg = <0x500000 0x1000>;
-- qcom,controller-type = "pmic-arbiter";
-- };
- };
---- /dev/null
-+++ b/arch/arm/boot/dts/qcom-msm8960.dtsi
-@@ -0,0 +1,70 @@
-+/dts-v1/;
-+
-+/include/ "skeleton.dtsi"
-+
-+#include <dt-bindings/clock/qcom,gcc-msm8960.h>
-+
-+/ {
-+ model = "Qualcomm MSM8960";
-+ compatible = "qcom,msm8960";
-+ interrupt-parent = <&intc>;
-+
-+ intc: interrupt-controller@2000000 {
-+ compatible = "qcom,msm-qgic2";
-+ interrupt-controller;
-+ #interrupt-cells = <3>;
-+ reg = < 0x02000000 0x1000 >,
-+ < 0x02002000 0x1000 >;
-+ };
-+
-+ timer@200a000 {
-+ compatible = "qcom,kpss-timer", "qcom,msm-timer";
-+ interrupts = <1 1 0x301>,
-+ <1 2 0x301>,
-+ <1 3 0x301>;
-+ reg = <0x0200a000 0x100>;
-+ clock-frequency = <27000000>,
-+ <32768>;
-+ cpu-offset = <0x80000>;
-+ };
-+
-+ msmgpio: gpio@800000 {
-+ compatible = "qcom,msm-gpio";
-+ gpio-controller;
-+ #gpio-cells = <2>;
-+ ngpio = <150>;
-+ interrupts = <0 16 0x4>;
-+ interrupt-controller;
-+ #interrupt-cells = <2>;
-+ reg = <0x800000 0x4000>;
-+ };
-+
-+ gcc: clock-controller@900000 {
-+ compatible = "qcom,gcc-msm8960";
-+ #clock-cells = <1>;
-+ #reset-cells = <1>;
-+ reg = <0x900000 0x4000>;
-+ };
-+
-+ clock-controller@4000000 {
-+ compatible = "qcom,mmcc-msm8960";
-+ reg = <0x4000000 0x1000>;
-+ #clock-cells = <1>;
-+ #reset-cells = <1>;
-+ };
-+
-+ serial@16440000 {
-+ compatible = "qcom,msm-uartdm-v1.3", "qcom,msm-uartdm";
-+ reg = <0x16440000 0x1000>,
-+ <0x16400000 0x1000>;
-+ interrupts = <0 154 0x0>;
-+ clocks = <&gcc GSBI5_UART_CLK>, <&gcc GSBI5_H_CLK>;
-+ clock-names = "core", "iface";
-+ };
-+
-+ qcom,ssbi@500000 {
-+ compatible = "qcom,ssbi";
-+ reg = <0x500000 0x1000>;
-+ qcom,controller-type = "pmic-arbiter";
-+ };
-+};
diff --git a/target/linux/ipq806x/patches/0002-ARM-msm-Remove-pen_release-usage.patch b/target/linux/ipq806x/patches/0002-ARM-msm-Remove-pen_release-usage.patch
deleted file mode 100644
index 19eaae6..0000000
--- a/target/linux/ipq806x/patches/0002-ARM-msm-Remove-pen_release-usage.patch
+++ /dev/null
@@ -1,211 +0,0 @@
-From 18d53dfa103e63154fb8e548d55016d6ad210d28 Mon Sep 17 00:00:00 2001
-From: Rohit Vaswani <rvaswani@codeaurora.org>
-Date: Fri, 21 Jun 2013 12:17:37 -0700
-Subject: [PATCH 002/182] ARM: msm: Remove pen_release usage
-
-pen_release is no longer required as the synchronization
-is now managed by generic arm code.
-This is done as suggested in https://lkml.org/lkml/2013/6/4/184
-
-Cc: Russell King <linux@arm.linux.org.uk>
-Signed-off-by: Rohit Vaswani <rvaswani@codeaurora.org>
-Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
-Signed-off-by: Kumar Gala <galak@codeaurora.org>
----
- arch/arm/mach-msm/Makefile | 2 +-
- arch/arm/mach-msm/headsmp.S | 39 ---------------------------------------
- arch/arm/mach-msm/hotplug.c | 31 ++++---------------------------
- arch/arm/mach-msm/platsmp.c | 37 +++----------------------------------
- 4 files changed, 8 insertions(+), 101 deletions(-)
- delete mode 100644 arch/arm/mach-msm/headsmp.S
-
---- a/arch/arm/mach-msm/Makefile
-+++ b/arch/arm/mach-msm/Makefile
-@@ -19,7 +19,7 @@ obj-$(CONFIG_MSM_SCM) += scm.o scm-boot.
- CFLAGS_scm.o :=$(call as-instr,.arch_extension sec,-DREQUIRES_SEC=1)
-
- obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o
--obj-$(CONFIG_SMP) += headsmp.o platsmp.o
-+obj-$(CONFIG_SMP) += platsmp.o
-
- obj-$(CONFIG_MACH_TROUT) += board-trout.o board-trout-gpio.o board-trout-mmc.o devices-msm7x00.o
- obj-$(CONFIG_MACH_TROUT) += board-trout.o board-trout-gpio.o board-trout-mmc.o board-trout-panel.o devices-msm7x00.o
---- a/arch/arm/mach-msm/headsmp.S
-+++ /dev/null
-@@ -1,39 +0,0 @@
--/*
-- * linux/arch/arm/mach-realview/headsmp.S
-- *
-- * Copyright (c) 2003 ARM Limited
-- * All Rights Reserved
-- *
-- * This program is free software; you can redistribute it and/or modify
-- * it under the terms of the GNU General Public License version 2 as
-- * published by the Free Software Foundation.
-- */
--#include <linux/linkage.h>
--#include <linux/init.h>
--
--/*
-- * MSM specific entry point for secondary CPUs. This provides
-- * a "holding pen" into which all secondary cores are held until we're
-- * ready for them to initialise.
-- */
--ENTRY(msm_secondary_startup)
-- mrc p15, 0, r0, c0, c0, 5
-- and r0, r0, #15
-- adr r4, 1f
-- ldmia r4, {r5, r6}
-- sub r4, r4, r5
-- add r6, r6, r4
--pen: ldr r7, [r6]
-- cmp r7, r0
-- bne pen
--
-- /*
-- * we've been released from the holding pen: secondary_stack
-- * should now contain the SVC stack for this core
-- */
-- b secondary_startup
--ENDPROC(msm_secondary_startup)
--
-- .align
--1: .long .
-- .long pen_release
---- a/arch/arm/mach-msm/hotplug.c
-+++ b/arch/arm/mach-msm/hotplug.c
-@@ -24,33 +24,10 @@ static inline void cpu_leave_lowpower(vo
-
- static inline void platform_do_lowpower(unsigned int cpu)
- {
-- /* Just enter wfi for now. TODO: Properly shut off the cpu. */
-- for (;;) {
-- /*
-- * here's the WFI
-- */
-- asm("wfi"
-- :
-- :
-- : "memory", "cc");
--
-- if (pen_release == cpu_logical_map(cpu)) {
-- /*
-- * OK, proper wakeup, we're done
-- */
-- break;
-- }
--
-- /*
-- * getting here, means that we have come out of WFI without
-- * having been woken up - this shouldn't happen
-- *
-- * The trouble is, letting people know about this is not really
-- * possible, since we are currently running incoherently, and
-- * therefore cannot safely call printk() or anything else
-- */
-- pr_debug("CPU%u: spurious wakeup call\n", cpu);
-- }
-+ asm("wfi"
-+ :
-+ :
-+ : "memory", "cc");
- }
-
- /*
---- a/arch/arm/mach-msm/platsmp.c
-+++ b/arch/arm/mach-msm/platsmp.c
-@@ -12,13 +12,10 @@
- #include <linux/errno.h>
- #include <linux/delay.h>
- #include <linux/device.h>
--#include <linux/jiffies.h>
- #include <linux/smp.h>
- #include <linux/io.h>
-
--#include <asm/cacheflush.h>
- #include <asm/cputype.h>
--#include <asm/mach-types.h>
- #include <asm/smp_plat.h>
-
- #include "scm-boot.h"
-@@ -28,7 +25,7 @@
- #define SCSS_CPU1CORE_RESET 0xD80
- #define SCSS_DBG_STATUS_CORE_PWRDUP 0xE64
-
--extern void msm_secondary_startup(void);
-+extern void secondary_startup(void);
-
- static DEFINE_SPINLOCK(boot_lock);
-
-@@ -41,13 +38,6 @@ static inline int get_core_count(void)
- static void msm_secondary_init(unsigned int cpu)
- {
- /*
-- * let the primary processor know we're out of the
-- * pen, then head off into the C entry point
-- */
-- pen_release = -1;
-- smp_wmb();
--
-- /*
- * Synchronise with the boot thread.
- */
- spin_lock(&boot_lock);
-@@ -57,7 +47,7 @@ static void msm_secondary_init(unsigned
- static void prepare_cold_cpu(unsigned int cpu)
- {
- int ret;
-- ret = scm_set_boot_addr(virt_to_phys(msm_secondary_startup),
-+ ret = scm_set_boot_addr(virt_to_phys(secondary_startup),
- SCM_FLAG_COLDBOOT_CPU1);
- if (ret == 0) {
- void __iomem *sc1_base_ptr;
-@@ -75,7 +65,6 @@ static void prepare_cold_cpu(unsigned in
-
- static int msm_boot_secondary(unsigned int cpu, struct task_struct *idle)
- {
-- unsigned long timeout;
- static int cold_boot_done;
-
- /* Only need to bring cpu out of reset this way once */
-@@ -91,39 +80,19 @@ static int msm_boot_secondary(unsigned i
- spin_lock(&boot_lock);
-
- /*
-- * The secondary processor is waiting to be released from
-- * the holding pen - release it, then wait for it to flag
-- * that it has been released by resetting pen_release.
-- *
-- * Note that "pen_release" is the hardware CPU ID, whereas
-- * "cpu" is Linux's internal ID.
-- */
-- pen_release = cpu_logical_map(cpu);
-- sync_cache_w(&pen_release);
--
-- /*
- * Send the secondary CPU a soft interrupt, thereby causing
- * the boot monitor to read the system wide flags register,
- * and branch to the address found there.
- */
- arch_send_wakeup_ipi_mask(cpumask_of(cpu));
-
-- timeout = jiffies + (1 * HZ);
-- while (time_before(jiffies, timeout)) {
-- smp_rmb();
-- if (pen_release == -1)
-- break;
--
-- udelay(10);
-- }
--
- /*
- * now the secondary core is starting up let it run its
- * calibrations, then wait for it to finish
- */
- spin_unlock(&boot_lock);
-
-- return pen_release != -1 ? -ENOSYS : 0;
-+ return 0;
- }
-
- /*
diff --git a/target/linux/ipq806x/patches/0003-ARM-msm-kill-off-hotplug.c.patch b/target/linux/ipq806x/patches/0003-ARM-msm-kill-off-hotplug.c.patch
deleted file mode 100644
index 79aa96f..0000000
--- a/target/linux/ipq806x/patches/0003-ARM-msm-kill-off-hotplug.c.patch
+++ /dev/null
@@ -1,108 +0,0 @@
-From b5a3a19e3efa6238c6a00a8f36a8ab2c25eeebc3 Mon Sep 17 00:00:00 2001
-From: Kumar Gala <galak@codeaurora.org>
-Date: Fri, 31 Jan 2014 13:48:29 -0600
-Subject: [PATCH 003/182] ARM: msm: kill off hotplug.c
-
-Right now hotplug.c only really implements msm_cpu_die as a wfi. Just
-move that implementation into platsmp.c. At the same time we use the
-existing wfi() instead of inline asm.
-
-Signed-off-by: Kumar Gala <galak@codeaurora.org>
----
- arch/arm/mach-msm/Makefile | 1 -
- arch/arm/mach-msm/common.h | 1 -
- arch/arm/mach-msm/hotplug.c | 51 -------------------------------------------
- arch/arm/mach-msm/platsmp.c | 7 ++++++
- 4 files changed, 7 insertions(+), 53 deletions(-)
- delete mode 100644 arch/arm/mach-msm/hotplug.c
-
---- a/arch/arm/mach-msm/Makefile
-+++ b/arch/arm/mach-msm/Makefile
-@@ -18,7 +18,6 @@ obj-$(CONFIG_MSM_SCM) += scm.o scm-boot.
-
- CFLAGS_scm.o :=$(call as-instr,.arch_extension sec,-DREQUIRES_SEC=1)
-
--obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o
- obj-$(CONFIG_SMP) += platsmp.o
-
- obj-$(CONFIG_MACH_TROUT) += board-trout.o board-trout-gpio.o board-trout-mmc.o devices-msm7x00.o
---- a/arch/arm/mach-msm/common.h
-+++ b/arch/arm/mach-msm/common.h
-@@ -24,7 +24,6 @@ extern void __iomem *__msm_ioremap_calle
- unsigned int mtype, void *caller);
-
- extern struct smp_operations msm_smp_ops;
--extern void msm_cpu_die(unsigned int cpu);
-
- struct msm_mmc_platform_data;
-
---- a/arch/arm/mach-msm/hotplug.c
-+++ /dev/null
-@@ -1,51 +0,0 @@
--/*
-- * Copyright (C) 2002 ARM Ltd.
-- * All Rights Reserved
-- *
-- * This program is free software; you can redistribute it and/or modify
-- * it under the terms of the GNU General Public License version 2 as
-- * published by the Free Software Foundation.
-- */
--#include <linux/kernel.h>
--#include <linux/errno.h>
--#include <linux/smp.h>
--
--#include <asm/smp_plat.h>
--
--#include "common.h"
--
--static inline void cpu_enter_lowpower(void)
--{
--}
--
--static inline void cpu_leave_lowpower(void)
--{
--}
--
--static inline void platform_do_lowpower(unsigned int cpu)
--{
-- asm("wfi"
-- :
-- :
-- : "memory", "cc");
--}
--
--/*
-- * platform-specific code to shutdown a CPU
-- *
-- * Called with IRQs disabled
-- */
--void __ref msm_cpu_die(unsigned int cpu)
--{
-- /*
-- * we're ready for shutdown now, so do it
-- */
-- cpu_enter_lowpower();
-- platform_do_lowpower(cpu);
--
-- /*
-- * bring this CPU back into the world of cache
-- * coherency, and then restore interrupts
-- */
-- cpu_leave_lowpower();
--}
---- a/arch/arm/mach-msm/platsmp.c
-+++ b/arch/arm/mach-msm/platsmp.c
-@@ -29,6 +29,13 @@ extern void secondary_startup(void);
-
- static DEFINE_SPINLOCK(boot_lock);
-
-+#ifdef CONFIG_HOTPLUG_CPU
-+static void __ref msm_cpu_die(unsigned int cpu)
-+{
-+ wfi();
-+}
-+#endif
-+
- static inline int get_core_count(void)
- {
- /* 1 + the PART[1:0] field of MIDR */
diff --git a/target/linux/ipq806x/patches/0004-clocksource-qcom-Move-clocksource-code-out-of-mach-m.patch b/target/linux/ipq806x/patches/0004-clocksource-qcom-Move-clocksource-code-out-of-mach-m.patch
deleted file mode 100644
index c726d3f..0000000
--- a/target/linux/ipq806x/patches/0004-clocksource-qcom-Move-clocksource-code-out-of-mach-m.patch
+++ /dev/null
@@ -1,771 +0,0 @@
-From 00009eabeb2074bef5c89e576a7a6d827c12c3d9 Mon Sep 17 00:00:00 2001
-From: Kumar Gala <galak@codeaurora.org>
-Date: Wed, 29 Jan 2014 16:17:30 -0600
-Subject: [PATCH 004/182] clocksource: qcom: Move clocksource code out of
- mach-msm
-
-We intend to share the clocksource code for MSM platforms between legacy
-and multiplatform supported qcom SoCs.
-
-Acked-by: Olof Johansson <olof@lixom.net>
-Signed-off-by: Kumar Gala <galak@codeaurora.org>
----
- arch/arm/mach-msm/Kconfig | 13 +-
- arch/arm/mach-msm/Makefile | 1 -
- arch/arm/mach-msm/timer.c | 333 --------------------------------------
- drivers/clocksource/Kconfig | 3 +
- drivers/clocksource/Makefile | 1 +
- drivers/clocksource/qcom-timer.c | 329 +++++++++++++++++++++++++++++++++++++
- 6 files changed, 338 insertions(+), 342 deletions(-)
- delete mode 100644 arch/arm/mach-msm/timer.c
- create mode 100644 drivers/clocksource/qcom-timer.c
-
---- a/arch/arm/mach-msm/Kconfig
-+++ b/arch/arm/mach-msm/Kconfig
-@@ -21,7 +21,7 @@ config ARCH_MSM8X60
- select CPU_V7
- select HAVE_SMP
- select MSM_SCM if SMP
-- select MSM_TIMER
-+ select CLKSRC_QCOM
-
- config ARCH_MSM8960
- bool "Enable support for MSM8960"
-@@ -29,7 +29,7 @@ config ARCH_MSM8960
- select CPU_V7
- select HAVE_SMP
- select MSM_SCM if SMP
-- select MSM_TIMER
-+ select CLKSRC_QCOM
-
- config ARCH_MSM8974
- bool "Enable support for MSM8974"
-@@ -54,7 +54,7 @@ config ARCH_MSM7X00A
- select MACH_TROUT if !MACH_HALIBUT
- select MSM_PROC_COMM
- select MSM_SMD
-- select MSM_TIMER
-+ select CLKSRC_QCOM
- select MSM_SMD_PKG3
-
- config ARCH_MSM7X30
-@@ -66,7 +66,7 @@ config ARCH_MSM7X30
- select MSM_GPIOMUX
- select MSM_PROC_COMM
- select MSM_SMD
-- select MSM_TIMER
-+ select CLKSRC_QCOM
- select MSM_VIC
-
- config ARCH_QSD8X50
-@@ -78,7 +78,7 @@ config ARCH_QSD8X50
- select MSM_GPIOMUX
- select MSM_PROC_COMM
- select MSM_SMD
-- select MSM_TIMER
-+ select CLKSRC_QCOM
- select MSM_VIC
-
- endchoice
-@@ -153,7 +153,4 @@ config MSM_GPIOMUX
- config MSM_SCM
- bool
-
--config MSM_TIMER
-- bool
--
- endif
---- a/arch/arm/mach-msm/Makefile
-+++ b/arch/arm/mach-msm/Makefile
-@@ -1,4 +1,3 @@
--obj-$(CONFIG_MSM_TIMER) += timer.o
- obj-$(CONFIG_MSM_PROC_COMM) += clock.o
-
- obj-$(CONFIG_MSM_VIC) += irq-vic.o
---- a/arch/arm/mach-msm/timer.c
-+++ /dev/null
-@@ -1,333 +0,0 @@
--/*
-- *
-- * Copyright (C) 2007 Google, Inc.
-- * Copyright (c) 2009-2012, The Linux Foundation. All rights reserved.
-- *
-- * This software is licensed under the terms of the GNU General Public
-- * License version 2, as published by the Free Software Foundation, and
-- * may be copied, distributed, and modified under those terms.
-- *
-- * This program is distributed in the hope that it will be useful,
-- * but WITHOUT ANY WARRANTY; without even the implied warranty of
-- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-- * GNU General Public License for more details.
-- *
-- */
--
--#include <linux/clocksource.h>
--#include <linux/clockchips.h>
--#include <linux/cpu.h>
--#include <linux/init.h>
--#include <linux/interrupt.h>
--#include <linux/irq.h>
--#include <linux/io.h>
--#include <linux/of.h>
--#include <linux/of_address.h>
--#include <linux/of_irq.h>
--#include <linux/sched_clock.h>
--
--#include <asm/mach/time.h>
--
--#include "common.h"
--
--#define TIMER_MATCH_VAL 0x0000
--#define TIMER_COUNT_VAL 0x0004
--#define TIMER_ENABLE 0x0008
--#define TIMER_ENABLE_CLR_ON_MATCH_EN BIT(1)
--#define TIMER_ENABLE_EN BIT(0)
--#define TIMER_CLEAR 0x000C
--#define DGT_CLK_CTL 0x10
--#define DGT_CLK_CTL_DIV_4 0x3
--#define TIMER_STS_GPT0_CLR_PEND BIT(10)
--
--#define GPT_HZ 32768
--
--#define MSM_DGT_SHIFT 5
--
--static void __iomem *event_base;
--static void __iomem *sts_base;
--
--static irqreturn_t msm_timer_interrupt(int irq, void *dev_id)
--{
-- struct clock_event_device *evt = dev_id;
-- /* Stop the timer tick */
-- if (evt->mode == CLOCK_EVT_MODE_ONESHOT) {
-- u32 ctrl = readl_relaxed(event_base + TIMER_ENABLE);
-- ctrl &= ~TIMER_ENABLE_EN;
-- writel_relaxed(ctrl, event_base + TIMER_ENABLE);
-- }
-- evt->event_handler(evt);
-- return IRQ_HANDLED;
--}
--
--static int msm_timer_set_next_event(unsigned long cycles,
-- struct clock_event_device *evt)
--{
-- u32 ctrl = readl_relaxed(event_base + TIMER_ENABLE);
--
-- ctrl &= ~TIMER_ENABLE_EN;
-- writel_relaxed(ctrl, event_base + TIMER_ENABLE);
--
-- writel_relaxed(ctrl, event_base + TIMER_CLEAR);
-- writel_relaxed(cycles, event_base + TIMER_MATCH_VAL);
--
-- if (sts_base)
-- while (readl_relaxed(sts_base) & TIMER_STS_GPT0_CLR_PEND)
-- cpu_relax();
--
-- writel_relaxed(ctrl | TIMER_ENABLE_EN, event_base + TIMER_ENABLE);
-- return 0;
--}
--
--static void msm_timer_set_mode(enum clock_event_mode mode,
-- struct clock_event_device *evt)
--{
-- u32 ctrl;
--
-- ctrl = readl_relaxed(event_base + TIMER_ENABLE);
-- ctrl &= ~(TIMER_ENABLE_EN | TIMER_ENABLE_CLR_ON_MATCH_EN);
--
-- switch (mode) {
-- case CLOCK_EVT_MODE_RESUME:
-- case CLOCK_EVT_MODE_PERIODIC:
-- break;
-- case CLOCK_EVT_MODE_ONESHOT:
-- /* Timer is enabled in set_next_event */
-- break;
-- case CLOCK_EVT_MODE_UNUSED:
-- case CLOCK_EVT_MODE_SHUTDOWN:
-- break;
-- }
-- writel_relaxed(ctrl, event_base + TIMER_ENABLE);
--}
--
--static struct clock_event_device __percpu *msm_evt;
--
--static void __iomem *source_base;
--
--static notrace cycle_t msm_read_timer_count(struct clocksource *cs)
--{
-- return readl_relaxed(source_base + TIMER_COUNT_VAL);
--}
--
--static notrace cycle_t msm_read_timer_count_shift(struct clocksource *cs)
--{
-- /*
-- * Shift timer count down by a constant due to unreliable lower bits
-- * on some targets.
-- */
-- return msm_read_timer_count(cs) >> MSM_DGT_SHIFT;
--}
--
--static struct clocksource msm_clocksource = {
-- .name = "dg_timer",
-- .rating = 300,
-- .read = msm_read_timer_count,
-- .mask = CLOCKSOURCE_MASK(32),
-- .flags = CLOCK_SOURCE_IS_CONTINUOUS,
--};
--
--static int msm_timer_irq;
--static int msm_timer_has_ppi;
--
--static int msm_local_timer_setup(struct clock_event_device *evt)
--{
-- int cpu = smp_processor_id();
-- int err;
--
-- evt->irq = msm_timer_irq;
-- evt->name = "msm_timer";
-- evt->features = CLOCK_EVT_FEAT_ONESHOT;
-- evt->rating = 200;
-- evt->set_mode = msm_timer_set_mode;
-- evt->set_next_event = msm_timer_set_next_event;
-- evt->cpumask = cpumask_of(cpu);
--
-- clockevents_config_and_register(evt, GPT_HZ, 4, 0xffffffff);
--
-- if (msm_timer_has_ppi) {
-- enable_percpu_irq(evt->irq, IRQ_TYPE_EDGE_RISING);
-- } else {
-- err = request_irq(evt->irq, msm_timer_interrupt,
-- IRQF_TIMER | IRQF_NOBALANCING |
-- IRQF_TRIGGER_RISING, "gp_timer", evt);
-- if (err)
-- pr_err("request_irq failed\n");
-- }
--
-- return 0;
--}
--
--static void msm_local_timer_stop(struct clock_event_device *evt)
--{
-- evt->set_mode(CLOCK_EVT_MODE_UNUSED, evt);
-- disable_percpu_irq(evt->irq);
--}
--
--static int msm_timer_cpu_notify(struct notifier_block *self,
-- unsigned long action, void *hcpu)
--{
-- /*
-- * Grab cpu pointer in each case to avoid spurious
-- * preemptible warnings
-- */
-- switch (action & ~CPU_TASKS_FROZEN) {
-- case CPU_STARTING:
-- msm_local_timer_setup(this_cpu_ptr(msm_evt));
-- break;
-- case CPU_DYING:
-- msm_local_timer_stop(this_cpu_ptr(msm_evt));
-- break;
-- }
--
-- return NOTIFY_OK;
--}
--
--static struct notifier_block msm_timer_cpu_nb = {
-- .notifier_call = msm_timer_cpu_notify,
--};
--
--static u64 notrace msm_sched_clock_read(void)
--{
-- return msm_clocksource.read(&msm_clocksource);
--}
--
--static void __init msm_timer_init(u32 dgt_hz, int sched_bits, int irq,
-- bool percpu)
--{
-- struct clocksource *cs = &msm_clocksource;
-- int res = 0;
--
-- msm_timer_irq = irq;
-- msm_timer_has_ppi = percpu;
--
-- msm_evt = alloc_percpu(struct clock_event_device);
-- if (!msm_evt) {
-- pr_err("memory allocation failed for clockevents\n");
-- goto err;
-- }
--
-- if (percpu)
-- res = request_percpu_irq(irq, msm_timer_interrupt,
-- "gp_timer", msm_evt);
--
-- if (res) {
-- pr_err("request_percpu_irq failed\n");
-- } else {
-- res = register_cpu_notifier(&msm_timer_cpu_nb);
-- if (res) {
-- free_percpu_irq(irq, msm_evt);
-- goto err;
-- }
--
-- /* Immediately configure the timer on the boot CPU */
-- msm_local_timer_setup(__this_cpu_ptr(msm_evt));
-- }
--
--err:
-- writel_relaxed(TIMER_ENABLE_EN, source_base + TIMER_ENABLE);
-- res = clocksource_register_hz(cs, dgt_hz);
-- if (res)
-- pr_err("clocksource_register failed\n");
-- sched_clock_register(msm_sched_clock_read, sched_bits, dgt_hz);
--}
--
--#ifdef CONFIG_OF
--static void __init msm_dt_timer_init(struct device_node *np)
--{
-- u32 freq;
-- int irq;
-- struct resource res;
-- u32 percpu_offset;
-- void __iomem *base;
-- void __iomem *cpu0_base;
--
-- base = of_iomap(np, 0);
-- if (!base) {
-- pr_err("Failed to map event base\n");
-- return;
-- }
--
-- /* We use GPT0 for the clockevent */
-- irq = irq_of_parse_and_map(np, 1);
-- if (irq <= 0) {
-- pr_err("Can't get irq\n");
-- return;
-- }
--
-- /* We use CPU0's DGT for the clocksource */
-- if (of_property_read_u32(np, "cpu-offset", &percpu_offset))
-- percpu_offset = 0;
--
-- if (of_address_to_resource(np, 0, &res)) {
-- pr_err("Failed to parse DGT resource\n");
-- return;
-- }
--
-- cpu0_base = ioremap(res.start + percpu_offset, resource_size(&res));
-- if (!cpu0_base) {
-- pr_err("Failed to map source base\n");
-- return;
-- }
--
-- if (of_property_read_u32(np, "clock-frequency", &freq)) {
-- pr_err("Unknown frequency\n");
-- return;
-- }
--
-- event_base = base + 0x4;
-- sts_base = base + 0x88;
-- source_base = cpu0_base + 0x24;
-- freq /= 4;
-- writel_relaxed(DGT_CLK_CTL_DIV_4, source_base + DGT_CLK_CTL);
--
-- msm_timer_init(freq, 32, irq, !!percpu_offset);
--}
--CLOCKSOURCE_OF_DECLARE(kpss_timer, "qcom,kpss-timer", msm_dt_timer_init);
--CLOCKSOURCE_OF_DECLARE(scss_timer, "qcom,scss-timer", msm_dt_timer_init);
--#endif
--
--static int __init msm_timer_map(phys_addr_t addr, u32 event, u32 source,
-- u32 sts)
--{
-- void __iomem *base;
--
-- base = ioremap(addr, SZ_256);
-- if (!base) {
-- pr_err("Failed to map timer base\n");
-- return -ENOMEM;
-- }
-- event_base = base + event;
-- source_base = base + source;
-- if (sts)
-- sts_base = base + sts;
--
-- return 0;
--}
--
--void __init msm7x01_timer_init(void)
--{
-- struct clocksource *cs = &msm_clocksource;
--
-- if (msm_timer_map(0xc0100000, 0x0, 0x10, 0x0))
-- return;
-- cs->read = msm_read_timer_count_shift;
-- cs->mask = CLOCKSOURCE_MASK((32 - MSM_DGT_SHIFT));
-- /* 600 KHz */
-- msm_timer_init(19200000 >> MSM_DGT_SHIFT, 32 - MSM_DGT_SHIFT, 7,
-- false);
--}
--
--void __init msm7x30_timer_init(void)
--{
-- if (msm_timer_map(0xc0100000, 0x4, 0x24, 0x80))
-- return;
-- msm_timer_init(24576000 / 4, 32, 1, false);
--}
--
--void __init qsd8x50_timer_init(void)
--{
-- if (msm_timer_map(0xAC100000, 0x0, 0x10, 0x34))
-- return;
-- msm_timer_init(19200000 / 4, 32, 7, false);
--}
---- a/drivers/clocksource/Kconfig
-+++ b/drivers/clocksource/Kconfig
-@@ -140,3 +140,6 @@ config VF_PIT_TIMER
- bool
- help
- Support for Period Interrupt Timer on Freescale Vybrid Family SoCs.
-+
-+config CLKSRC_QCOM
-+ bool
---- a/drivers/clocksource/Makefile
-+++ b/drivers/clocksource/Makefile
-@@ -32,6 +32,7 @@ obj-$(CONFIG_CLKSRC_EFM32) += time-efm32
- obj-$(CONFIG_CLKSRC_EXYNOS_MCT) += exynos_mct.o
- obj-$(CONFIG_CLKSRC_SAMSUNG_PWM) += samsung_pwm_timer.o
- obj-$(CONFIG_VF_PIT_TIMER) += vf_pit_timer.o
-+obj-$(CONFIG_CLKSRC_QCOM) += qcom-timer.o
-
- obj-$(CONFIG_ARM_ARCH_TIMER) += arm_arch_timer.o
- obj-$(CONFIG_ARM_GLOBAL_TIMER) += arm_global_timer.o
---- /dev/null
-+++ b/drivers/clocksource/qcom-timer.c
-@@ -0,0 +1,329 @@
-+/*
-+ *
-+ * Copyright (C) 2007 Google, Inc.
-+ * Copyright (c) 2009-2012,2014, The Linux Foundation. All rights reserved.
-+ *
-+ * This software is licensed under the terms of the GNU General Public
-+ * License version 2, as published by the Free Software Foundation, and
-+ * may be copied, distributed, and modified under those terms.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ * GNU General Public License for more details.
-+ *
-+ */
-+
-+#include <linux/clocksource.h>
-+#include <linux/clockchips.h>
-+#include <linux/cpu.h>
-+#include <linux/init.h>
-+#include <linux/interrupt.h>
-+#include <linux/irq.h>
-+#include <linux/io.h>
-+#include <linux/of.h>
-+#include <linux/of_address.h>
-+#include <linux/of_irq.h>
-+#include <linux/sched_clock.h>
-+
-+#define TIMER_MATCH_VAL 0x0000
-+#define TIMER_COUNT_VAL 0x0004
-+#define TIMER_ENABLE 0x0008
-+#define TIMER_ENABLE_CLR_ON_MATCH_EN BIT(1)
-+#define TIMER_ENABLE_EN BIT(0)
-+#define TIMER_CLEAR 0x000C
-+#define DGT_CLK_CTL 0x10
-+#define DGT_CLK_CTL_DIV_4 0x3
-+#define TIMER_STS_GPT0_CLR_PEND BIT(10)
-+
-+#define GPT_HZ 32768
-+
-+#define MSM_DGT_SHIFT 5
-+
-+static void __iomem *event_base;
-+static void __iomem *sts_base;
-+
-+static irqreturn_t msm_timer_interrupt(int irq, void *dev_id)
-+{
-+ struct clock_event_device *evt = dev_id;
-+ /* Stop the timer tick */
-+ if (evt->mode == CLOCK_EVT_MODE_ONESHOT) {
-+ u32 ctrl = readl_relaxed(event_base + TIMER_ENABLE);
-+ ctrl &= ~TIMER_ENABLE_EN;
-+ writel_relaxed(ctrl, event_base + TIMER_ENABLE);
-+ }
-+ evt->event_handler(evt);
-+ return IRQ_HANDLED;
-+}
-+
-+static int msm_timer_set_next_event(unsigned long cycles,
-+ struct clock_event_device *evt)
-+{
-+ u32 ctrl = readl_relaxed(event_base + TIMER_ENABLE);
-+
-+ ctrl &= ~TIMER_ENABLE_EN;
-+ writel_relaxed(ctrl, event_base + TIMER_ENABLE);
-+
-+ writel_relaxed(ctrl, event_base + TIMER_CLEAR);
-+ writel_relaxed(cycles, event_base + TIMER_MATCH_VAL);
-+
-+ if (sts_base)
-+ while (readl_relaxed(sts_base) & TIMER_STS_GPT0_CLR_PEND)
-+ cpu_relax();
-+
-+ writel_relaxed(ctrl | TIMER_ENABLE_EN, event_base + TIMER_ENABLE);
-+ return 0;
-+}
-+
-+static void msm_timer_set_mode(enum clock_event_mode mode,
-+ struct clock_event_device *evt)
-+{
-+ u32 ctrl;
-+
-+ ctrl = readl_relaxed(event_base + TIMER_ENABLE);
-+ ctrl &= ~(TIMER_ENABLE_EN | TIMER_ENABLE_CLR_ON_MATCH_EN);
-+
-+ switch (mode) {
-+ case CLOCK_EVT_MODE_RESUME:
-+ case CLOCK_EVT_MODE_PERIODIC:
-+ break;
-+ case CLOCK_EVT_MODE_ONESHOT:
-+ /* Timer is enabled in set_next_event */
-+ break;
-+ case CLOCK_EVT_MODE_UNUSED:
-+ case CLOCK_EVT_MODE_SHUTDOWN:
-+ break;
-+ }
-+ writel_relaxed(ctrl, event_base + TIMER_ENABLE);
-+}
-+
-+static struct clock_event_device __percpu *msm_evt;
-+
-+static void __iomem *source_base;
-+
-+static notrace cycle_t msm_read_timer_count(struct clocksource *cs)
-+{
-+ return readl_relaxed(source_base + TIMER_COUNT_VAL);
-+}
-+
-+static notrace cycle_t msm_read_timer_count_shift(struct clocksource *cs)
-+{
-+ /*
-+ * Shift timer count down by a constant due to unreliable lower bits
-+ * on some targets.
-+ */
-+ return msm_read_timer_count(cs) >> MSM_DGT_SHIFT;
-+}
-+
-+static struct clocksource msm_clocksource = {
-+ .name = "dg_timer",
-+ .rating = 300,
-+ .read = msm_read_timer_count,
-+ .mask = CLOCKSOURCE_MASK(32),
-+ .flags = CLOCK_SOURCE_IS_CONTINUOUS,
-+};
-+
-+static int msm_timer_irq;
-+static int msm_timer_has_ppi;
-+
-+static int msm_local_timer_setup(struct clock_event_device *evt)
-+{
-+ int cpu = smp_processor_id();
-+ int err;
-+
-+ evt->irq = msm_timer_irq;
-+ evt->name = "msm_timer";
-+ evt->features = CLOCK_EVT_FEAT_ONESHOT;
-+ evt->rating = 200;
-+ evt->set_mode = msm_timer_set_mode;
-+ evt->set_next_event = msm_timer_set_next_event;
-+ evt->cpumask = cpumask_of(cpu);
-+
-+ clockevents_config_and_register(evt, GPT_HZ, 4, 0xffffffff);
-+
-+ if (msm_timer_has_ppi) {
-+ enable_percpu_irq(evt->irq, IRQ_TYPE_EDGE_RISING);
-+ } else {
-+ err = request_irq(evt->irq, msm_timer_interrupt,
-+ IRQF_TIMER | IRQF_NOBALANCING |
-+ IRQF_TRIGGER_RISING, "gp_timer", evt);
-+ if (err)
-+ pr_err("request_irq failed\n");
-+ }
-+
-+ return 0;
-+}
-+
-+static void msm_local_timer_stop(struct clock_event_device *evt)
-+{
-+ evt->set_mode(CLOCK_EVT_MODE_UNUSED, evt);
-+ disable_percpu_irq(evt->irq);
-+}
-+
-+static int msm_timer_cpu_notify(struct notifier_block *self,
-+ unsigned long action, void *hcpu)
-+{
-+ /*
-+ * Grab cpu pointer in each case to avoid spurious
-+ * preemptible warnings
-+ */
-+ switch (action & ~CPU_TASKS_FROZEN) {
-+ case CPU_STARTING:
-+ msm_local_timer_setup(this_cpu_ptr(msm_evt));
-+ break;
-+ case CPU_DYING:
-+ msm_local_timer_stop(this_cpu_ptr(msm_evt));
-+ break;
-+ }
-+
-+ return NOTIFY_OK;
-+}
-+
-+static struct notifier_block msm_timer_cpu_nb = {
-+ .notifier_call = msm_timer_cpu_notify,
-+};
-+
-+static u64 notrace msm_sched_clock_read(void)
-+{
-+ return msm_clocksource.read(&msm_clocksource);
-+}
-+
-+static void __init msm_timer_init(u32 dgt_hz, int sched_bits, int irq,
-+ bool percpu)
-+{
-+ struct clocksource *cs = &msm_clocksource;
-+ int res = 0;
-+
-+ msm_timer_irq = irq;
-+ msm_timer_has_ppi = percpu;
-+
-+ msm_evt = alloc_percpu(struct clock_event_device);
-+ if (!msm_evt) {
-+ pr_err("memory allocation failed for clockevents\n");
-+ goto err;
-+ }
-+
-+ if (percpu)
-+ res = request_percpu_irq(irq, msm_timer_interrupt,
-+ "gp_timer", msm_evt);
-+
-+ if (res) {
-+ pr_err("request_percpu_irq failed\n");
-+ } else {
-+ res = register_cpu_notifier(&msm_timer_cpu_nb);
-+ if (res) {
-+ free_percpu_irq(irq, msm_evt);
-+ goto err;
-+ }
-+
-+ /* Immediately configure the timer on the boot CPU */
-+ msm_local_timer_setup(__this_cpu_ptr(msm_evt));
-+ }
-+
-+err:
-+ writel_relaxed(TIMER_ENABLE_EN, source_base + TIMER_ENABLE);
-+ res = clocksource_register_hz(cs, dgt_hz);
-+ if (res)
-+ pr_err("clocksource_register failed\n");
-+ sched_clock_register(msm_sched_clock_read, sched_bits, dgt_hz);
-+}
-+
-+#ifdef CONFIG_OF
-+static void __init msm_dt_timer_init(struct device_node *np)
-+{
-+ u32 freq;
-+ int irq;
-+ struct resource res;
-+ u32 percpu_offset;
-+ void __iomem *base;
-+ void __iomem *cpu0_base;
-+
-+ base = of_iomap(np, 0);
-+ if (!base) {
-+ pr_err("Failed to map event base\n");
-+ return;
-+ }
-+
-+ /* We use GPT0 for the clockevent */
-+ irq = irq_of_parse_and_map(np, 1);
-+ if (irq <= 0) {
-+ pr_err("Can't get irq\n");
-+ return;
-+ }
-+
-+ /* We use CPU0's DGT for the clocksource */
-+ if (of_property_read_u32(np, "cpu-offset", &percpu_offset))
-+ percpu_offset = 0;
-+
-+ if (of_address_to_resource(np, 0, &res)) {
-+ pr_err("Failed to parse DGT resource\n");
-+ return;
-+ }
-+
-+ cpu0_base = ioremap(res.start + percpu_offset, resource_size(&res));
-+ if (!cpu0_base) {
-+ pr_err("Failed to map source base\n");
-+ return;
-+ }
-+
-+ if (of_property_read_u32(np, "clock-frequency", &freq)) {
-+ pr_err("Unknown frequency\n");
-+ return;
-+ }
-+
-+ event_base = base + 0x4;
-+ sts_base = base + 0x88;
-+ source_base = cpu0_base + 0x24;
-+ freq /= 4;
-+ writel_relaxed(DGT_CLK_CTL_DIV_4, source_base + DGT_CLK_CTL);
-+
-+ msm_timer_init(freq, 32, irq, !!percpu_offset);
-+}
-+CLOCKSOURCE_OF_DECLARE(kpss_timer, "qcom,kpss-timer", msm_dt_timer_init);
-+CLOCKSOURCE_OF_DECLARE(scss_timer, "qcom,scss-timer", msm_dt_timer_init);
-+#endif
-+
-+static int __init msm_timer_map(phys_addr_t addr, u32 event, u32 source,
-+ u32 sts)
-+{
-+ void __iomem *base;
-+
-+ base = ioremap(addr, SZ_256);
-+ if (!base) {
-+ pr_err("Failed to map timer base\n");
-+ return -ENOMEM;
-+ }
-+ event_base = base + event;
-+ source_base = base + source;
-+ if (sts)
-+ sts_base = base + sts;
-+
-+ return 0;
-+}
-+
-+void __init msm7x01_timer_init(void)
-+{
-+ struct clocksource *cs = &msm_clocksource;
-+
-+ if (msm_timer_map(0xc0100000, 0x0, 0x10, 0x0))
-+ return;
-+ cs->read = msm_read_timer_count_shift;
-+ cs->mask = CLOCKSOURCE_MASK((32 - MSM_DGT_SHIFT));
-+ /* 600 KHz */
-+ msm_timer_init(19200000 >> MSM_DGT_SHIFT, 32 - MSM_DGT_SHIFT, 7,
-+ false);
-+}
-+
-+void __init msm7x30_timer_init(void)
-+{
-+ if (msm_timer_map(0xc0100000, 0x4, 0x24, 0x80))
-+ return;
-+ msm_timer_init(24576000 / 4, 32, 1, false);
-+}
-+
-+void __init qsd8x50_timer_init(void)
-+{
-+ if (msm_timer_map(0xAC100000, 0x0, 0x10, 0x34))
-+ return;
-+ msm_timer_init(19200000 / 4, 32, 7, false);
-+}
diff --git a/target/linux/ipq806x/patches/0005-ARM-qcom-Split-Qualcomm-support-into-legacy-and-mult.patch b/target/linux/ipq806x/patches/0005-ARM-qcom-Split-Qualcomm-support-into-legacy-and-mult.patch
deleted file mode 100644
index 4cd4c47..0000000
--- a/target/linux/ipq806x/patches/0005-ARM-qcom-Split-Qualcomm-support-into-legacy-and-mult.patch
+++ /dev/null
@@ -1,1423 +0,0 @@
-From 8c2a00c0129d6f718245f7a613c2bb28976b7973 Mon Sep 17 00:00:00 2001
-From: Kumar Gala <galak@codeaurora.org>
-Date: Tue, 21 Jan 2014 17:14:10 -0600
-Subject: [PATCH 005/182] ARM: qcom: Split Qualcomm support into legacy and
- multiplatform
-
-Introduce a new mach-qcom that will support SoCs that intend to be
-multiplatform compatible while keeping mach-msm to legacy SoC/board
-support that will not transition over to multiplatform.
-
-As part of this, we move support for MSM8X60, MSM8960 and MSM8974 over
-to mach-qcom.
-
-Signed-off-by: Kumar Gala <galak@codeaurora.org>
----
- MAINTAINERS | 8 ++
- arch/arm/Kconfig | 7 +-
- arch/arm/Kconfig.debug | 2 +-
- arch/arm/Makefile | 1 +
- arch/arm/boot/dts/Makefile | 6 +-
- arch/arm/mach-msm/Kconfig | 45 +------
- arch/arm/mach-msm/Makefile | 6 -
- arch/arm/mach-msm/board-dt.c | 41 ------
- arch/arm/mach-msm/platsmp.c | 137 -------------------
- arch/arm/mach-msm/scm-boot.c | 39 ------
- arch/arm/mach-msm/scm-boot.h | 22 ---
- arch/arm/mach-msm/scm.c | 299 -----------------------------------------
- arch/arm/mach-msm/scm.h | 25 ----
- arch/arm/mach-qcom/Kconfig | 33 +++++
- arch/arm/mach-qcom/Makefile | 5 +
- arch/arm/mach-qcom/board.c | 40 ++++++
- arch/arm/mach-qcom/platsmp.c | 137 +++++++++++++++++++
- arch/arm/mach-qcom/scm-boot.c | 39 ++++++
- arch/arm/mach-qcom/scm-boot.h | 22 +++
- arch/arm/mach-qcom/scm.c | 299 +++++++++++++++++++++++++++++++++++++++++
- arch/arm/mach-qcom/scm.h | 25 ++++
- 21 files changed, 619 insertions(+), 619 deletions(-)
- delete mode 100644 arch/arm/mach-msm/board-dt.c
- delete mode 100644 arch/arm/mach-msm/platsmp.c
- delete mode 100644 arch/arm/mach-msm/scm-boot.c
- delete mode 100644 arch/arm/mach-msm/scm-boot.h
- delete mode 100644 arch/arm/mach-msm/scm.c
- delete mode 100644 arch/arm/mach-msm/scm.h
- create mode 100644 arch/arm/mach-qcom/Kconfig
- create mode 100644 arch/arm/mach-qcom/Makefile
- create mode 100644 arch/arm/mach-qcom/board.c
- create mode 100644 arch/arm/mach-qcom/platsmp.c
- create mode 100644 arch/arm/mach-qcom/scm-boot.c
- create mode 100644 arch/arm/mach-qcom/scm-boot.h
- create mode 100644 arch/arm/mach-qcom/scm.c
- create mode 100644 arch/arm/mach-qcom/scm.h
-
---- a/MAINTAINERS
-+++ b/MAINTAINERS
-@@ -1168,6 +1168,14 @@ L: linux-arm-kernel@lists.infradead.org
- W: http://www.arm.linux.org.uk/
- S: Maintained
-
-+ARM/QUALCOMM SUPPORT
-+M: Kumar Gala <galak@codeaurora.org>
-+M: David Brown <davidb@codeaurora.org>
-+L: linux-arm-msm@vger.kernel.org
-+S: Maintained
-+F: arch/arm/mach-qcom/
-+T: git git://git.kernel.org/pub/scm/linux/kernel/git/galak/linux-qcom.git
-+
- ARM/RADISYS ENP2611 MACHINE SUPPORT
- M: Lennert Buytenhek <kernel@wantstofly.org>
- L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
---- a/arch/arm/Kconfig
-+++ b/arch/arm/Kconfig
-@@ -658,9 +658,8 @@ config ARCH_PXA
- help
- Support for Intel/Marvell's PXA2xx/PXA3xx processor line.
-
--config ARCH_MSM_NODT
-- bool "Qualcomm MSM"
-- select ARCH_MSM
-+config ARCH_MSM
-+ bool "Qualcomm MSM (non-multiplatform)"
- select ARCH_REQUIRE_GPIOLIB
- select COMMON_CLK
- select GENERIC_CLOCKEVENTS
-@@ -1006,6 +1005,8 @@ source "arch/arm/plat-pxa/Kconfig"
-
- source "arch/arm/mach-mmp/Kconfig"
-
-+source "arch/arm/mach-qcom/Kconfig"
-+
- source "arch/arm/mach-realview/Kconfig"
-
- source "arch/arm/mach-rockchip/Kconfig"
---- a/arch/arm/Kconfig.debug
-+++ b/arch/arm/Kconfig.debug
-@@ -956,7 +956,7 @@ config DEBUG_STI_UART
-
- config DEBUG_MSM_UART
- bool
-- depends on ARCH_MSM
-+ depends on ARCH_MSM || ARCH_QCOM
-
- config DEBUG_LL_INCLUDE
- string
---- a/arch/arm/Makefile
-+++ b/arch/arm/Makefile
-@@ -185,6 +185,7 @@ machine-$(CONFIG_ARCH_OMAP2PLUS) += omap
- machine-$(CONFIG_ARCH_ORION5X) += orion5x
- machine-$(CONFIG_ARCH_PICOXCELL) += picoxcell
- machine-$(CONFIG_ARCH_PXA) += pxa
-+machine-$(CONFIG_ARCH_QCOM) += qcom
- machine-$(CONFIG_ARCH_REALVIEW) += realview
- machine-$(CONFIG_ARCH_ROCKCHIP) += rockchip
- machine-$(CONFIG_ARCH_RPC) += rpc
---- a/arch/arm/boot/dts/Makefile
-+++ b/arch/arm/boot/dts/Makefile
-@@ -119,9 +119,6 @@ dtb-$(CONFIG_ARCH_KIRKWOOD) += kirkwood-
- kirkwood-ts219-6282.dtb
- dtb-$(CONFIG_ARCH_MARCO) += marco-evb.dtb
- dtb-$(CONFIG_ARCH_MOXART) += moxart-uc7112lx.dtb
--dtb-$(CONFIG_ARCH_MSM) += qcom-msm8660-surf.dtb \
-- qcom-msm8960-cdp.dtb \
-- qcom-apq8074-dragonboard.dtb
- dtb-$(CONFIG_ARCH_MVEBU) += armada-370-db.dtb \
- armada-370-mirabox.dtb \
- armada-370-netgear-rn102.dtb \
-@@ -234,6 +231,9 @@ dtb-$(CONFIG_ARCH_OMAP2PLUS) += omap2420
- dra7-evm.dtb
- dtb-$(CONFIG_ARCH_ORION5X) += orion5x-lacie-ethernet-disk-mini-v2.dtb
- dtb-$(CONFIG_ARCH_PRIMA2) += prima2-evb.dtb
-+dtb-$(CONFIG_ARCH_QCOM) += qcom-msm8660-surf.dtb \
-+ qcom-msm8960-cdp.dtb \
-+ qcom-apq8074-dragonboard.dtb
- dtb-$(CONFIG_ARCH_U8500) += ste-snowball.dtb \
- ste-hrefprev60-stuib.dtb \
- ste-hrefprev60-tvk.dtb \
---- a/arch/arm/mach-msm/Kconfig
-+++ b/arch/arm/mach-msm/Kconfig
-@@ -1,50 +1,9 @@
--config ARCH_MSM
-- bool
--
--config ARCH_MSM_DT
-- bool "Qualcomm MSM DT Support" if ARCH_MULTI_V7
-- select ARCH_MSM
-- select ARCH_REQUIRE_GPIOLIB
-- select CLKSRC_OF
-- select GENERIC_CLOCKEVENTS
-- help
-- Support for Qualcomm's devicetree based MSM systems.
--
- if ARCH_MSM
-
--menu "Qualcomm MSM SoC Selection"
-- depends on ARCH_MSM_DT
--
--config ARCH_MSM8X60
-- bool "Enable support for MSM8X60"
-- select ARM_GIC
-- select CPU_V7
-- select HAVE_SMP
-- select MSM_SCM if SMP
-- select CLKSRC_QCOM
--
--config ARCH_MSM8960
-- bool "Enable support for MSM8960"
-- select ARM_GIC
-- select CPU_V7
-- select HAVE_SMP
-- select MSM_SCM if SMP
-- select CLKSRC_QCOM
--
--config ARCH_MSM8974
-- bool "Enable support for MSM8974"
-- select ARM_GIC
-- select CPU_V7
-- select HAVE_ARM_ARCH_TIMER
-- select HAVE_SMP
-- select MSM_SCM if SMP
--
--endmenu
--
- choice
- prompt "Qualcomm MSM SoC Type"
- default ARCH_MSM7X00A
-- depends on ARCH_MSM_NODT
-+ depends on ARCH_MSM
-
- config ARCH_MSM7X00A
- bool "MSM7x00A / MSM7x01A"
-@@ -99,7 +58,7 @@ config MSM_VIC
- bool
-
- menu "Qualcomm MSM Board Type"
-- depends on ARCH_MSM_NODT
-+ depends on ARCH_MSM
-
- config MACH_HALIBUT
- depends on ARCH_MSM
---- a/arch/arm/mach-msm/Makefile
-+++ b/arch/arm/mach-msm/Makefile
-@@ -13,17 +13,11 @@ obj-$(CONFIG_ARCH_QSD8X50) += dma.o io.o
-
- obj-$(CONFIG_MSM_SMD) += smd.o smd_debug.o
- obj-$(CONFIG_MSM_SMD) += last_radio_log.o
--obj-$(CONFIG_MSM_SCM) += scm.o scm-boot.o
--
--CFLAGS_scm.o :=$(call as-instr,.arch_extension sec,-DREQUIRES_SEC=1)
--
--obj-$(CONFIG_SMP) += platsmp.o
-
- obj-$(CONFIG_MACH_TROUT) += board-trout.o board-trout-gpio.o board-trout-mmc.o devices-msm7x00.o
- obj-$(CONFIG_MACH_TROUT) += board-trout.o board-trout-gpio.o board-trout-mmc.o board-trout-panel.o devices-msm7x00.o
- obj-$(CONFIG_MACH_HALIBUT) += board-halibut.o devices-msm7x00.o
- obj-$(CONFIG_ARCH_MSM7X30) += board-msm7x30.o devices-msm7x30.o
- obj-$(CONFIG_ARCH_QSD8X50) += board-qsd8x50.o devices-qsd8x50.o
--obj-$(CONFIG_ARCH_MSM_DT) += board-dt.o
- obj-$(CONFIG_MSM_GPIOMUX) += gpiomux.o
- obj-$(CONFIG_ARCH_QSD8X50) += gpiomux-8x50.o
---- a/arch/arm/mach-msm/board-dt.c
-+++ /dev/null
-@@ -1,41 +0,0 @@
--/* Copyright (c) 2010-2012,2013 The Linux Foundation. All rights reserved.
-- *
-- * This program is free software; you can redistribute it and/or modify
-- * it under the terms of the GNU General Public License version 2 and
-- * only version 2 as published by the Free Software Foundation.
-- *
-- * This program is distributed in the hope that it will be useful,
-- * but WITHOUT ANY WARRANTY; without even the implied warranty of
-- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-- * GNU General Public License for more details.
-- */
--
--#include <linux/init.h>
--#include <linux/of.h>
--#include <linux/of_platform.h>
--
--#include <asm/mach/arch.h>
--#include <asm/mach/map.h>
--
--#include "common.h"
--
--static const char * const msm_dt_match[] __initconst = {
-- "qcom,msm8660-fluid",
-- "qcom,msm8660-surf",
-- "qcom,msm8960-cdp",
-- NULL
--};
--
--static const char * const apq8074_dt_match[] __initconst = {
-- "qcom,apq8074-dragonboard",
-- NULL
--};
--
--DT_MACHINE_START(MSM_DT, "Qualcomm MSM (Flattened Device Tree)")
-- .smp = smp_ops(msm_smp_ops),
-- .dt_compat = msm_dt_match,
--MACHINE_END
--
--DT_MACHINE_START(APQ_DT, "Qualcomm MSM (Flattened Device Tree)")
-- .dt_compat = apq8074_dt_match,
--MACHINE_END
---- a/arch/arm/mach-msm/platsmp.c
-+++ /dev/null
-@@ -1,137 +0,0 @@
--/*
-- * Copyright (C) 2002 ARM Ltd.
-- * All Rights Reserved
-- * Copyright (c) 2010, Code Aurora Forum. All rights reserved.
-- *
-- * This program is free software; you can redistribute it and/or modify
-- * it under the terms of the GNU General Public License version 2 as
-- * published by the Free Software Foundation.
-- */
--
--#include <linux/init.h>
--#include <linux/errno.h>
--#include <linux/delay.h>
--#include <linux/device.h>
--#include <linux/smp.h>
--#include <linux/io.h>
--
--#include <asm/cputype.h>
--#include <asm/smp_plat.h>
--
--#include "scm-boot.h"
--#include "common.h"
--
--#define VDD_SC1_ARRAY_CLAMP_GFS_CTL 0x15A0
--#define SCSS_CPU1CORE_RESET 0xD80
--#define SCSS_DBG_STATUS_CORE_PWRDUP 0xE64
--
--extern void secondary_startup(void);
--
--static DEFINE_SPINLOCK(boot_lock);
--
--#ifdef CONFIG_HOTPLUG_CPU
--static void __ref msm_cpu_die(unsigned int cpu)
--{
-- wfi();
--}
--#endif
--
--static inline int get_core_count(void)
--{
-- /* 1 + the PART[1:0] field of MIDR */
-- return ((read_cpuid_id() >> 4) & 3) + 1;
--}
--
--static void msm_secondary_init(unsigned int cpu)
--{
-- /*
-- * Synchronise with the boot thread.
-- */
-- spin_lock(&boot_lock);
-- spin_unlock(&boot_lock);
--}
--
--static void prepare_cold_cpu(unsigned int cpu)
--{
-- int ret;
-- ret = scm_set_boot_addr(virt_to_phys(secondary_startup),
-- SCM_FLAG_COLDBOOT_CPU1);
-- if (ret == 0) {
-- void __iomem *sc1_base_ptr;
-- sc1_base_ptr = ioremap_nocache(0x00902000, SZ_4K*2);
-- if (sc1_base_ptr) {
-- writel(0, sc1_base_ptr + VDD_SC1_ARRAY_CLAMP_GFS_CTL);
-- writel(0, sc1_base_ptr + SCSS_CPU1CORE_RESET);
-- writel(3, sc1_base_ptr + SCSS_DBG_STATUS_CORE_PWRDUP);
-- iounmap(sc1_base_ptr);
-- }
-- } else
-- printk(KERN_DEBUG "Failed to set secondary core boot "
-- "address\n");
--}
--
--static int msm_boot_secondary(unsigned int cpu, struct task_struct *idle)
--{
-- static int cold_boot_done;
--
-- /* Only need to bring cpu out of reset this way once */
-- if (cold_boot_done == false) {
-- prepare_cold_cpu(cpu);
-- cold_boot_done = true;
-- }
--
-- /*
-- * set synchronisation state between this boot processor
-- * and the secondary one
-- */
-- spin_lock(&boot_lock);
--
-- /*
-- * Send the secondary CPU a soft interrupt, thereby causing
-- * the boot monitor to read the system wide flags register,
-- * and branch to the address found there.
-- */
-- arch_send_wakeup_ipi_mask(cpumask_of(cpu));
--
-- /*
-- * now the secondary core is starting up let it run its
-- * calibrations, then wait for it to finish
-- */
-- spin_unlock(&boot_lock);
--
-- return 0;
--}
--
--/*
-- * Initialise the CPU possible map early - this describes the CPUs
-- * which may be present or become present in the system. The msm8x60
-- * does not support the ARM SCU, so just set the possible cpu mask to
-- * NR_CPUS.
-- */
--static void __init msm_smp_init_cpus(void)
--{
-- unsigned int i, ncores = get_core_count();
--
-- if (ncores > nr_cpu_ids) {
-- pr_warn("SMP: %u cores greater than maximum (%u), clipping\n",
-- ncores, nr_cpu_ids);
-- ncores = nr_cpu_ids;
-- }
--
-- for (i = 0; i < ncores; i++)
-- set_cpu_possible(i, true);
--}
--
--static void __init msm_smp_prepare_cpus(unsigned int max_cpus)
--{
--}
--
--struct smp_operations msm_smp_ops __initdata = {
-- .smp_init_cpus = msm_smp_init_cpus,
-- .smp_prepare_cpus = msm_smp_prepare_cpus,
-- .smp_secondary_init = msm_secondary_init,
-- .smp_boot_secondary = msm_boot_secondary,
--#ifdef CONFIG_HOTPLUG_CPU
-- .cpu_die = msm_cpu_die,
--#endif
--};
---- a/arch/arm/mach-msm/scm-boot.c
-+++ /dev/null
-@@ -1,39 +0,0 @@
--/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
-- *
-- * This program is free software; you can redistribute it and/or modify
-- * it under the terms of the GNU General Public License version 2 and
-- * only version 2 as published by the Free Software Foundation.
-- *
-- * This program is distributed in the hope that it will be useful,
-- * but WITHOUT ANY WARRANTY; without even the implied warranty of
-- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-- * GNU General Public License for more details.
-- *
-- * You should have received a copy of the GNU General Public License
-- * along with this program; if not, write to the Free Software
-- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
-- * 02110-1301, USA.
-- */
--
--#include <linux/module.h>
--#include <linux/slab.h>
--
--#include "scm.h"
--#include "scm-boot.h"
--
--/*
-- * Set the cold/warm boot address for one of the CPU cores.
-- */
--int scm_set_boot_addr(phys_addr_t addr, int flags)
--{
-- struct {
-- unsigned int flags;
-- phys_addr_t addr;
-- } cmd;
--
-- cmd.addr = addr;
-- cmd.flags = flags;
-- return scm_call(SCM_SVC_BOOT, SCM_BOOT_ADDR,
-- &cmd, sizeof(cmd), NULL, 0);
--}
--EXPORT_SYMBOL(scm_set_boot_addr);
---- a/arch/arm/mach-msm/scm-boot.h
-+++ /dev/null
-@@ -1,22 +0,0 @@
--/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
-- *
-- * This program is free software; you can redistribute it and/or modify
-- * it under the terms of the GNU General Public License version 2 and
-- * only version 2 as published by the Free Software Foundation.
-- *
-- * This program is distributed in the hope that it will be useful,
-- * but WITHOUT ANY WARRANTY; without even the implied warranty of
-- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-- * GNU General Public License for more details.
-- */
--#ifndef __MACH_SCM_BOOT_H
--#define __MACH_SCM_BOOT_H
--
--#define SCM_BOOT_ADDR 0x1
--#define SCM_FLAG_COLDBOOT_CPU1 0x1
--#define SCM_FLAG_WARMBOOT_CPU1 0x2
--#define SCM_FLAG_WARMBOOT_CPU0 0x4
--
--int scm_set_boot_addr(phys_addr_t addr, int flags);
--
--#endif
---- a/arch/arm/mach-msm/scm.c
-+++ /dev/null
-@@ -1,299 +0,0 @@
--/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
-- *
-- * This program is free software; you can redistribute it and/or modify
-- * it under the terms of the GNU General Public License version 2 and
-- * only version 2 as published by the Free Software Foundation.
-- *
-- * This program is distributed in the hope that it will be useful,
-- * but WITHOUT ANY WARRANTY; without even the implied warranty of
-- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-- * GNU General Public License for more details.
-- *
-- * You should have received a copy of the GNU General Public License
-- * along with this program; if not, write to the Free Software
-- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
-- * 02110-1301, USA.
-- */
--
--#include <linux/slab.h>
--#include <linux/io.h>
--#include <linux/module.h>
--#include <linux/mutex.h>
--#include <linux/errno.h>
--#include <linux/err.h>
--
--#include <asm/cacheflush.h>
--
--#include "scm.h"
--
--/* Cache line size for msm8x60 */
--#define CACHELINESIZE 32
--
--#define SCM_ENOMEM -5
--#define SCM_EOPNOTSUPP -4
--#define SCM_EINVAL_ADDR -3
--#define SCM_EINVAL_ARG -2
--#define SCM_ERROR -1
--#define SCM_INTERRUPTED 1
--
--static DEFINE_MUTEX(scm_lock);
--
--/**
-- * struct scm_command - one SCM command buffer
-- * @len: total available memory for command and response
-- * @buf_offset: start of command buffer
-- * @resp_hdr_offset: start of response buffer
-- * @id: command to be executed
-- * @buf: buffer returned from scm_get_command_buffer()
-- *
-- * An SCM command is laid out in memory as follows:
-- *
-- * ------------------- <--- struct scm_command
-- * | command header |
-- * ------------------- <--- scm_get_command_buffer()
-- * | command buffer |
-- * ------------------- <--- struct scm_response and
-- * | response header | scm_command_to_response()
-- * ------------------- <--- scm_get_response_buffer()
-- * | response buffer |
-- * -------------------
-- *
-- * There can be arbitrary padding between the headers and buffers so
-- * you should always use the appropriate scm_get_*_buffer() routines
-- * to access the buffers in a safe manner.
-- */
--struct scm_command {
-- u32 len;
-- u32 buf_offset;
-- u32 resp_hdr_offset;
-- u32 id;
-- u32 buf[0];
--};
--
--/**
-- * struct scm_response - one SCM response buffer
-- * @len: total available memory for response
-- * @buf_offset: start of response data relative to start of scm_response
-- * @is_complete: indicates if the command has finished processing
-- */
--struct scm_response {
-- u32 len;
-- u32 buf_offset;
-- u32 is_complete;
--};
--
--/**
-- * alloc_scm_command() - Allocate an SCM command
-- * @cmd_size: size of the command buffer
-- * @resp_size: size of the response buffer
-- *
-- * Allocate an SCM command, including enough room for the command
-- * and response headers as well as the command and response buffers.
-- *
-- * Returns a valid &scm_command on success or %NULL if the allocation fails.
-- */
--static struct scm_command *alloc_scm_command(size_t cmd_size, size_t resp_size)
--{
-- struct scm_command *cmd;
-- size_t len = sizeof(*cmd) + sizeof(struct scm_response) + cmd_size +
-- resp_size;
--
-- cmd = kzalloc(PAGE_ALIGN(len), GFP_KERNEL);
-- if (cmd) {
-- cmd->len = len;
-- cmd->buf_offset = offsetof(struct scm_command, buf);
-- cmd->resp_hdr_offset = cmd->buf_offset + cmd_size;
-- }
-- return cmd;
--}
--
--/**
-- * free_scm_command() - Free an SCM command
-- * @cmd: command to free
-- *
-- * Free an SCM command.
-- */
--static inline void free_scm_command(struct scm_command *cmd)
--{
-- kfree(cmd);
--}
--
--/**
-- * scm_command_to_response() - Get a pointer to a scm_response
-- * @cmd: command
-- *
-- * Returns a pointer to a response for a command.
-- */
--static inline struct scm_response *scm_command_to_response(
-- const struct scm_command *cmd)
--{
-- return (void *)cmd + cmd->resp_hdr_offset;
--}
--
--/**
-- * scm_get_command_buffer() - Get a pointer to a command buffer
-- * @cmd: command
-- *
-- * Returns a pointer to the command buffer of a command.
-- */
--static inline void *scm_get_command_buffer(const struct scm_command *cmd)
--{
-- return (void *)cmd->buf;
--}
--
--/**
-- * scm_get_response_buffer() - Get a pointer to a response buffer
-- * @rsp: response
-- *
-- * Returns a pointer to a response buffer of a response.
-- */
--static inline void *scm_get_response_buffer(const struct scm_response *rsp)
--{
-- return (void *)rsp + rsp->buf_offset;
--}
--
--static int scm_remap_error(int err)
--{
-- switch (err) {
-- case SCM_ERROR:
-- return -EIO;
-- case SCM_EINVAL_ADDR:
-- case SCM_EINVAL_ARG:
-- return -EINVAL;
-- case SCM_EOPNOTSUPP:
-- return -EOPNOTSUPP;
-- case SCM_ENOMEM:
-- return -ENOMEM;
-- }
-- return -EINVAL;
--}
--
--static u32 smc(u32 cmd_addr)
--{
-- int context_id;
-- register u32 r0 asm("r0") = 1;
-- register u32 r1 asm("r1") = (u32)&context_id;
-- register u32 r2 asm("r2") = cmd_addr;
-- do {
-- asm volatile(
-- __asmeq("%0", "r0")
-- __asmeq("%1", "r0")
-- __asmeq("%2", "r1")
-- __asmeq("%3", "r2")
--#ifdef REQUIRES_SEC
-- ".arch_extension sec\n"
--#endif
-- "smc #0 @ switch to secure world\n"
-- : "=r" (r0)
-- : "r" (r0), "r" (r1), "r" (r2)
-- : "r3");
-- } while (r0 == SCM_INTERRUPTED);
--
-- return r0;
--}
--
--static int __scm_call(const struct scm_command *cmd)
--{
-- int ret;
-- u32 cmd_addr = virt_to_phys(cmd);
--
-- /*
-- * Flush the entire cache here so callers don't have to remember
-- * to flush the cache when passing physical addresses to the secure
-- * side in the buffer.
-- */
-- flush_cache_all();
-- ret = smc(cmd_addr);
-- if (ret < 0)
-- ret = scm_remap_error(ret);
--
-- return ret;
--}
--
--/**
-- * scm_call() - Send an SCM command
-- * @svc_id: service identifier
-- * @cmd_id: command identifier
-- * @cmd_buf: command buffer
-- * @cmd_len: length of the command buffer
-- * @resp_buf: response buffer
-- * @resp_len: length of the response buffer
-- *
-- * Sends a command to the SCM and waits for the command to finish processing.
-- */
--int scm_call(u32 svc_id, u32 cmd_id, const void *cmd_buf, size_t cmd_len,
-- void *resp_buf, size_t resp_len)
--{
-- int ret;
-- struct scm_command *cmd;
-- struct scm_response *rsp;
--
-- cmd = alloc_scm_command(cmd_len, resp_len);
-- if (!cmd)
-- return -ENOMEM;
--
-- cmd->id = (svc_id << 10) | cmd_id;
-- if (cmd_buf)
-- memcpy(scm_get_command_buffer(cmd), cmd_buf, cmd_len);
--
-- mutex_lock(&scm_lock);
-- ret = __scm_call(cmd);
-- mutex_unlock(&scm_lock);
-- if (ret)
-- goto out;
--
-- rsp = scm_command_to_response(cmd);
-- do {
-- u32 start = (u32)rsp;
-- u32 end = (u32)scm_get_response_buffer(rsp) + resp_len;
-- start &= ~(CACHELINESIZE - 1);
-- while (start < end) {
-- asm ("mcr p15, 0, %0, c7, c6, 1" : : "r" (start)
-- : "memory");
-- start += CACHELINESIZE;
-- }
-- } while (!rsp->is_complete);
--
-- if (resp_buf)
-- memcpy(resp_buf, scm_get_response_buffer(rsp), resp_len);
--out:
-- free_scm_command(cmd);
-- return ret;
--}
--EXPORT_SYMBOL(scm_call);
--
--u32 scm_get_version(void)
--{
-- int context_id;
-- static u32 version = -1;
-- register u32 r0 asm("r0");
-- register u32 r1 asm("r1");
--
-- if (version != -1)
-- return version;
--
-- mutex_lock(&scm_lock);
--
-- r0 = 0x1 << 8;
-- r1 = (u32)&context_id;
-- do {
-- asm volatile(
-- __asmeq("%0", "r0")
-- __asmeq("%1", "r1")
-- __asmeq("%2", "r0")
-- __asmeq("%3", "r1")
--#ifdef REQUIRES_SEC
-- ".arch_extension sec\n"
--#endif
-- "smc #0 @ switch to secure world\n"
-- : "=r" (r0), "=r" (r1)
-- : "r" (r0), "r" (r1)
-- : "r2", "r3");
-- } while (r0 == SCM_INTERRUPTED);
--
-- version = r1;
-- mutex_unlock(&scm_lock);
--
-- return version;
--}
--EXPORT_SYMBOL(scm_get_version);
---- a/arch/arm/mach-msm/scm.h
-+++ /dev/null
-@@ -1,25 +0,0 @@
--/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
-- *
-- * This program is free software; you can redistribute it and/or modify
-- * it under the terms of the GNU General Public License version 2 and
-- * only version 2 as published by the Free Software Foundation.
-- *
-- * This program is distributed in the hope that it will be useful,
-- * but WITHOUT ANY WARRANTY; without even the implied warranty of
-- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-- * GNU General Public License for more details.
-- */
--#ifndef __MACH_SCM_H
--#define __MACH_SCM_H
--
--#define SCM_SVC_BOOT 0x1
--#define SCM_SVC_PIL 0x2
--
--extern int scm_call(u32 svc_id, u32 cmd_id, const void *cmd_buf, size_t cmd_len,
-- void *resp_buf, size_t resp_len);
--
--#define SCM_VERSION(major, minor) (((major) << 16) | ((minor) & 0xFF))
--
--extern u32 scm_get_version(void);
--
--#endif
---- /dev/null
-+++ b/arch/arm/mach-qcom/Kconfig
-@@ -0,0 +1,33 @@
-+config ARCH_QCOM
-+ bool "Qualcomm Support" if ARCH_MULTI_V7
-+ select ARCH_REQUIRE_GPIOLIB
-+ select ARM_GIC
-+ select CLKSRC_OF
-+ select GENERIC_CLOCKEVENTS
-+ select HAVE_SMP
-+ select QCOM_SCM if SMP
-+ help
-+ Support for Qualcomm's devicetree based systems.
-+
-+if ARCH_QCOM
-+
-+menu "Qualcomm SoC Selection"
-+
-+config ARCH_MSM8X60
-+ bool "Enable support for MSM8X60"
-+ select CLKSRC_QCOM
-+
-+config ARCH_MSM8960
-+ bool "Enable support for MSM8960"
-+ select CLKSRC_QCOM
-+
-+config ARCH_MSM8974
-+ bool "Enable support for MSM8974"
-+ select HAVE_ARM_ARCH_TIMER
-+
-+endmenu
-+
-+config QCOM_SCM
-+ bool
-+
-+endif
---- /dev/null
-+++ b/arch/arm/mach-qcom/Makefile
-@@ -0,0 +1,5 @@
-+obj-y := board.o
-+obj-$(CONFIG_SMP) += platsmp.o
-+obj-$(CONFIG_QCOM_SCM) += scm.o scm-boot.o
-+
-+CFLAGS_scm.o :=$(call as-instr,.arch_extension sec,-DREQUIRES_SEC=1)
---- /dev/null
-+++ b/arch/arm/mach-qcom/board.c
-@@ -0,0 +1,40 @@
-+/* Copyright (c) 2010-2014 The Linux Foundation. All rights reserved.
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 and
-+ * only version 2 as published by the Free Software Foundation.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ * GNU General Public License for more details.
-+ */
-+
-+#include <linux/init.h>
-+#include <linux/of.h>
-+#include <linux/of_platform.h>
-+
-+#include <asm/mach/arch.h>
-+#include <asm/mach/map.h>
-+
-+extern struct smp_operations msm_smp_ops;
-+
-+static const char * const qcom_dt_match[] __initconst = {
-+ "qcom,msm8660-surf",
-+ "qcom,msm8960-cdp",
-+ NULL
-+};
-+
-+static const char * const apq8074_dt_match[] __initconst = {
-+ "qcom,apq8074-dragonboard",
-+ NULL
-+};
-+
-+DT_MACHINE_START(QCOM_DT, "Qualcomm (Flattened Device Tree)")
-+ .smp = smp_ops(msm_smp_ops),
-+ .dt_compat = qcom_dt_match,
-+MACHINE_END
-+
-+DT_MACHINE_START(APQ_DT, "Qualcomm (Flattened Device Tree)")
-+ .dt_compat = apq8074_dt_match,
-+MACHINE_END
---- /dev/null
-+++ b/arch/arm/mach-qcom/platsmp.c
-@@ -0,0 +1,137 @@
-+/*
-+ * Copyright (C) 2002 ARM Ltd.
-+ * All Rights Reserved
-+ * Copyright (c) 2010, Code Aurora Forum. All rights reserved.
-+ * Copyright (c) 2014 The Linux Foundation. All rights reserved.
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation.
-+ */
-+
-+#include <linux/init.h>
-+#include <linux/errno.h>
-+#include <linux/delay.h>
-+#include <linux/device.h>
-+#include <linux/smp.h>
-+#include <linux/io.h>
-+
-+#include <asm/cputype.h>
-+#include <asm/smp_plat.h>
-+
-+#include "scm-boot.h"
-+
-+#define VDD_SC1_ARRAY_CLAMP_GFS_CTL 0x15A0
-+#define SCSS_CPU1CORE_RESET 0xD80
-+#define SCSS_DBG_STATUS_CORE_PWRDUP 0xE64
-+
-+extern void secondary_startup(void);
-+
-+static DEFINE_SPINLOCK(boot_lock);
-+
-+#ifdef CONFIG_HOTPLUG_CPU
-+static void __ref msm_cpu_die(unsigned int cpu)
-+{
-+ wfi();
-+}
-+#endif
-+
-+static inline int get_core_count(void)
-+{
-+ /* 1 + the PART[1:0] field of MIDR */
-+ return ((read_cpuid_id() >> 4) & 3) + 1;
-+}
-+
-+static void msm_secondary_init(unsigned int cpu)
-+{
-+ /*
-+ * Synchronise with the boot thread.
-+ */
-+ spin_lock(&boot_lock);
-+ spin_unlock(&boot_lock);
-+}
-+
-+static void prepare_cold_cpu(unsigned int cpu)
-+{
-+ int ret;
-+ ret = scm_set_boot_addr(virt_to_phys(secondary_startup),
-+ SCM_FLAG_COLDBOOT_CPU1);
-+ if (ret == 0) {
-+ void __iomem *sc1_base_ptr;
-+ sc1_base_ptr = ioremap_nocache(0x00902000, SZ_4K*2);
-+ if (sc1_base_ptr) {
-+ writel(0, sc1_base_ptr + VDD_SC1_ARRAY_CLAMP_GFS_CTL);
-+ writel(0, sc1_base_ptr + SCSS_CPU1CORE_RESET);
-+ writel(3, sc1_base_ptr + SCSS_DBG_STATUS_CORE_PWRDUP);
-+ iounmap(sc1_base_ptr);
-+ }
-+ } else
-+ printk(KERN_DEBUG "Failed to set secondary core boot "
-+ "address\n");
-+}
-+
-+static int msm_boot_secondary(unsigned int cpu, struct task_struct *idle)
-+{
-+ static int cold_boot_done;
-+
-+ /* Only need to bring cpu out of reset this way once */
-+ if (cold_boot_done == false) {
-+ prepare_cold_cpu(cpu);
-+ cold_boot_done = true;
-+ }
-+
-+ /*
-+ * set synchronisation state between this boot processor
-+ * and the secondary one
-+ */
-+ spin_lock(&boot_lock);
-+
-+ /*
-+ * Send the secondary CPU a soft interrupt, thereby causing
-+ * the boot monitor to read the system wide flags register,
-+ * and branch to the address found there.
-+ */
-+ arch_send_wakeup_ipi_mask(cpumask_of(cpu));
-+
-+ /*
-+ * now the secondary core is starting up let it run its
-+ * calibrations, then wait for it to finish
-+ */
-+ spin_unlock(&boot_lock);
-+
-+ return 0;
-+}
-+
-+/*
-+ * Initialise the CPU possible map early - this describes the CPUs
-+ * which may be present or become present in the system. The msm8x60
-+ * does not support the ARM SCU, so just set the possible cpu mask to
-+ * NR_CPUS.
-+ */
-+static void __init msm_smp_init_cpus(void)
-+{
-+ unsigned int i, ncores = get_core_count();
-+
-+ if (ncores > nr_cpu_ids) {
-+ pr_warn("SMP: %u cores greater than maximum (%u), clipping\n",
-+ ncores, nr_cpu_ids);
-+ ncores = nr_cpu_ids;
-+ }
-+
-+ for (i = 0; i < ncores; i++)
-+ set_cpu_possible(i, true);
-+}
-+
-+static void __init msm_smp_prepare_cpus(unsigned int max_cpus)
-+{
-+}
-+
-+struct smp_operations msm_smp_ops __initdata = {
-+ .smp_init_cpus = msm_smp_init_cpus,
-+ .smp_prepare_cpus = msm_smp_prepare_cpus,
-+ .smp_secondary_init = msm_secondary_init,
-+ .smp_boot_secondary = msm_boot_secondary,
-+#ifdef CONFIG_HOTPLUG_CPU
-+ .cpu_die = msm_cpu_die,
-+#endif
-+};
---- /dev/null
-+++ b/arch/arm/mach-qcom/scm-boot.c
-@@ -0,0 +1,39 @@
-+/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 and
-+ * only version 2 as published by the Free Software Foundation.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, write to the Free Software
-+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
-+ * 02110-1301, USA.
-+ */
-+
-+#include <linux/module.h>
-+#include <linux/slab.h>
-+
-+#include "scm.h"
-+#include "scm-boot.h"
-+
-+/*
-+ * Set the cold/warm boot address for one of the CPU cores.
-+ */
-+int scm_set_boot_addr(phys_addr_t addr, int flags)
-+{
-+ struct {
-+ unsigned int flags;
-+ phys_addr_t addr;
-+ } cmd;
-+
-+ cmd.addr = addr;
-+ cmd.flags = flags;
-+ return scm_call(SCM_SVC_BOOT, SCM_BOOT_ADDR,
-+ &cmd, sizeof(cmd), NULL, 0);
-+}
-+EXPORT_SYMBOL(scm_set_boot_addr);
---- /dev/null
-+++ b/arch/arm/mach-qcom/scm-boot.h
-@@ -0,0 +1,22 @@
-+/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 and
-+ * only version 2 as published by the Free Software Foundation.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ * GNU General Public License for more details.
-+ */
-+#ifndef __MACH_SCM_BOOT_H
-+#define __MACH_SCM_BOOT_H
-+
-+#define SCM_BOOT_ADDR 0x1
-+#define SCM_FLAG_COLDBOOT_CPU1 0x1
-+#define SCM_FLAG_WARMBOOT_CPU1 0x2
-+#define SCM_FLAG_WARMBOOT_CPU0 0x4
-+
-+int scm_set_boot_addr(phys_addr_t addr, int flags);
-+
-+#endif
---- /dev/null
-+++ b/arch/arm/mach-qcom/scm.c
-@@ -0,0 +1,299 @@
-+/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 and
-+ * only version 2 as published by the Free Software Foundation.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, write to the Free Software
-+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
-+ * 02110-1301, USA.
-+ */
-+
-+#include <linux/slab.h>
-+#include <linux/io.h>
-+#include <linux/module.h>
-+#include <linux/mutex.h>
-+#include <linux/errno.h>
-+#include <linux/err.h>
-+
-+#include <asm/cacheflush.h>
-+
-+#include "scm.h"
-+
-+/* Cache line size for msm8x60 */
-+#define CACHELINESIZE 32
-+
-+#define SCM_ENOMEM -5
-+#define SCM_EOPNOTSUPP -4
-+#define SCM_EINVAL_ADDR -3
-+#define SCM_EINVAL_ARG -2
-+#define SCM_ERROR -1
-+#define SCM_INTERRUPTED 1
-+
-+static DEFINE_MUTEX(scm_lock);
-+
-+/**
-+ * struct scm_command - one SCM command buffer
-+ * @len: total available memory for command and response
-+ * @buf_offset: start of command buffer
-+ * @resp_hdr_offset: start of response buffer
-+ * @id: command to be executed
-+ * @buf: buffer returned from scm_get_command_buffer()
-+ *
-+ * An SCM command is laid out in memory as follows:
-+ *
-+ * ------------------- <--- struct scm_command
-+ * | command header |
-+ * ------------------- <--- scm_get_command_buffer()
-+ * | command buffer |
-+ * ------------------- <--- struct scm_response and
-+ * | response header | scm_command_to_response()
-+ * ------------------- <--- scm_get_response_buffer()
-+ * | response buffer |
-+ * -------------------
-+ *
-+ * There can be arbitrary padding between the headers and buffers so
-+ * you should always use the appropriate scm_get_*_buffer() routines
-+ * to access the buffers in a safe manner.
-+ */
-+struct scm_command {
-+ u32 len;
-+ u32 buf_offset;
-+ u32 resp_hdr_offset;
-+ u32 id;
-+ u32 buf[0];
-+};
-+
-+/**
-+ * struct scm_response - one SCM response buffer
-+ * @len: total available memory for response
-+ * @buf_offset: start of response data relative to start of scm_response
-+ * @is_complete: indicates if the command has finished processing
-+ */
-+struct scm_response {
-+ u32 len;
-+ u32 buf_offset;
-+ u32 is_complete;
-+};
-+
-+/**
-+ * alloc_scm_command() - Allocate an SCM command
-+ * @cmd_size: size of the command buffer
-+ * @resp_size: size of the response buffer
-+ *
-+ * Allocate an SCM command, including enough room for the command
-+ * and response headers as well as the command and response buffers.
-+ *
-+ * Returns a valid &scm_command on success or %NULL if the allocation fails.
-+ */
-+static struct scm_command *alloc_scm_command(size_t cmd_size, size_t resp_size)
-+{
-+ struct scm_command *cmd;
-+ size_t len = sizeof(*cmd) + sizeof(struct scm_response) + cmd_size +
-+ resp_size;
-+
-+ cmd = kzalloc(PAGE_ALIGN(len), GFP_KERNEL);
-+ if (cmd) {
-+ cmd->len = len;
-+ cmd->buf_offset = offsetof(struct scm_command, buf);
-+ cmd->resp_hdr_offset = cmd->buf_offset + cmd_size;
-+ }
-+ return cmd;
-+}
-+
-+/**
-+ * free_scm_command() - Free an SCM command
-+ * @cmd: command to free
-+ *
-+ * Free an SCM command.
-+ */
-+static inline void free_scm_command(struct scm_command *cmd)
-+{
-+ kfree(cmd);
-+}
-+
-+/**
-+ * scm_command_to_response() - Get a pointer to a scm_response
-+ * @cmd: command
-+ *
-+ * Returns a pointer to a response for a command.
-+ */
-+static inline struct scm_response *scm_command_to_response(
-+ const struct scm_command *cmd)
-+{
-+ return (void *)cmd + cmd->resp_hdr_offset;
-+}
-+
-+/**
-+ * scm_get_command_buffer() - Get a pointer to a command buffer
-+ * @cmd: command
-+ *
-+ * Returns a pointer to the command buffer of a command.
-+ */
-+static inline void *scm_get_command_buffer(const struct scm_command *cmd)
-+{
-+ return (void *)cmd->buf;
-+}
-+
-+/**
-+ * scm_get_response_buffer() - Get a pointer to a response buffer
-+ * @rsp: response
-+ *
-+ * Returns a pointer to a response buffer of a response.
-+ */
-+static inline void *scm_get_response_buffer(const struct scm_response *rsp)
-+{
-+ return (void *)rsp + rsp->buf_offset;
-+}
-+
-+static int scm_remap_error(int err)
-+{
-+ switch (err) {
-+ case SCM_ERROR:
-+ return -EIO;
-+ case SCM_EINVAL_ADDR:
-+ case SCM_EINVAL_ARG:
-+ return -EINVAL;
-+ case SCM_EOPNOTSUPP:
-+ return -EOPNOTSUPP;
-+ case SCM_ENOMEM:
-+ return -ENOMEM;
-+ }
-+ return -EINVAL;
-+}
-+
-+static u32 smc(u32 cmd_addr)
-+{
-+ int context_id;
-+ register u32 r0 asm("r0") = 1;
-+ register u32 r1 asm("r1") = (u32)&context_id;
-+ register u32 r2 asm("r2") = cmd_addr;
-+ do {
-+ asm volatile(
-+ __asmeq("%0", "r0")
-+ __asmeq("%1", "r0")
-+ __asmeq("%2", "r1")
-+ __asmeq("%3", "r2")
-+#ifdef REQUIRES_SEC
-+ ".arch_extension sec\n"
-+#endif
-+ "smc #0 @ switch to secure world\n"
-+ : "=r" (r0)
-+ : "r" (r0), "r" (r1), "r" (r2)
-+ : "r3");
-+ } while (r0 == SCM_INTERRUPTED);
-+
-+ return r0;
-+}
-+
-+static int __scm_call(const struct scm_command *cmd)
-+{
-+ int ret;
-+ u32 cmd_addr = virt_to_phys(cmd);
-+
-+ /*
-+ * Flush the entire cache here so callers don't have to remember
-+ * to flush the cache when passing physical addresses to the secure
-+ * side in the buffer.
-+ */
-+ flush_cache_all();
-+ ret = smc(cmd_addr);
-+ if (ret < 0)
-+ ret = scm_remap_error(ret);
-+
-+ return ret;
-+}
-+
-+/**
-+ * scm_call() - Send an SCM command
-+ * @svc_id: service identifier
-+ * @cmd_id: command identifier
-+ * @cmd_buf: command buffer
-+ * @cmd_len: length of the command buffer
-+ * @resp_buf: response buffer
-+ * @resp_len: length of the response buffer
-+ *
-+ * Sends a command to the SCM and waits for the command to finish processing.
-+ */
-+int scm_call(u32 svc_id, u32 cmd_id, const void *cmd_buf, size_t cmd_len,
-+ void *resp_buf, size_t resp_len)
-+{
-+ int ret;
-+ struct scm_command *cmd;
-+ struct scm_response *rsp;
-+
-+ cmd = alloc_scm_command(cmd_len, resp_len);
-+ if (!cmd)
-+ return -ENOMEM;
-+
-+ cmd->id = (svc_id << 10) | cmd_id;
-+ if (cmd_buf)
-+ memcpy(scm_get_command_buffer(cmd), cmd_buf, cmd_len);
-+
-+ mutex_lock(&scm_lock);
-+ ret = __scm_call(cmd);
-+ mutex_unlock(&scm_lock);
-+ if (ret)
-+ goto out;
-+
-+ rsp = scm_command_to_response(cmd);
-+ do {
-+ u32 start = (u32)rsp;
-+ u32 end = (u32)scm_get_response_buffer(rsp) + resp_len;
-+ start &= ~(CACHELINESIZE - 1);
-+ while (start < end) {
-+ asm ("mcr p15, 0, %0, c7, c6, 1" : : "r" (start)
-+ : "memory");
-+ start += CACHELINESIZE;
-+ }
-+ } while (!rsp->is_complete);
-+
-+ if (resp_buf)
-+ memcpy(resp_buf, scm_get_response_buffer(rsp), resp_len);
-+out:
-+ free_scm_command(cmd);
-+ return ret;
-+}
-+EXPORT_SYMBOL(scm_call);
-+
-+u32 scm_get_version(void)
-+{
-+ int context_id;
-+ static u32 version = -1;
-+ register u32 r0 asm("r0");
-+ register u32 r1 asm("r1");
-+
-+ if (version != -1)
-+ return version;
-+
-+ mutex_lock(&scm_lock);
-+
-+ r0 = 0x1 << 8;
-+ r1 = (u32)&context_id;
-+ do {
-+ asm volatile(
-+ __asmeq("%0", "r0")
-+ __asmeq("%1", "r1")
-+ __asmeq("%2", "r0")
-+ __asmeq("%3", "r1")
-+#ifdef REQUIRES_SEC
-+ ".arch_extension sec\n"
-+#endif
-+ "smc #0 @ switch to secure world\n"
-+ : "=r" (r0), "=r" (r1)
-+ : "r" (r0), "r" (r1)
-+ : "r2", "r3");
-+ } while (r0 == SCM_INTERRUPTED);
-+
-+ version = r1;
-+ mutex_unlock(&scm_lock);
-+
-+ return version;
-+}
-+EXPORT_SYMBOL(scm_get_version);
---- /dev/null
-+++ b/arch/arm/mach-qcom/scm.h
-@@ -0,0 +1,25 @@
-+/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 and
-+ * only version 2 as published by the Free Software Foundation.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ * GNU General Public License for more details.
-+ */
-+#ifndef __MACH_SCM_H
-+#define __MACH_SCM_H
-+
-+#define SCM_SVC_BOOT 0x1
-+#define SCM_SVC_PIL 0x2
-+
-+extern int scm_call(u32 svc_id, u32 cmd_id, const void *cmd_buf, size_t cmd_len,
-+ void *resp_buf, size_t resp_len);
-+
-+#define SCM_VERSION(major, minor) (((major) << 16) | ((minor) & 0xFF))
-+
-+extern u32 scm_get_version(void);
-+
-+#endif
diff --git a/target/linux/ipq806x/patches/0006-clocksource-qcom-split-building-of-legacy-vs-multipl.patch b/target/linux/ipq806x/patches/0006-clocksource-qcom-split-building-of-legacy-vs-multipl.patch
deleted file mode 100644
index 79603f8..0000000
--- a/target/linux/ipq806x/patches/0006-clocksource-qcom-split-building-of-legacy-vs-multipl.patch
+++ /dev/null
@@ -1,73 +0,0 @@
-From 085d4b834dfced8580aab74707e30699b63e7c36 Mon Sep 17 00:00:00 2001
-From: Kumar Gala <galak@codeaurora.org>
-Date: Wed, 29 Jan 2014 17:01:37 -0600
-Subject: [PATCH 006/182] clocksource: qcom: split building of legacy vs
- multiplatform support
-
-The majority of the clocksource code for the Qualcomm platform is shared
-between newer (multiplatform) and older platforms. However there is a bit
-of code that isn't, so only build it for the appropriate config.
-
-Acked-by: Olof Johansson <olof@lixom.net>
-Signed-off-by: Kumar Gala <galak@codeaurora.org>
----
- drivers/clocksource/qcom-timer.c | 23 ++++++++++++-----------
- 1 file changed, 12 insertions(+), 11 deletions(-)
-
---- a/drivers/clocksource/qcom-timer.c
-+++ b/drivers/clocksource/qcom-timer.c
-@@ -106,15 +106,6 @@ static notrace cycle_t msm_read_timer_co
- return readl_relaxed(source_base + TIMER_COUNT_VAL);
- }
-
--static notrace cycle_t msm_read_timer_count_shift(struct clocksource *cs)
--{
-- /*
-- * Shift timer count down by a constant due to unreliable lower bits
-- * on some targets.
-- */
-- return msm_read_timer_count(cs) >> MSM_DGT_SHIFT;
--}
--
- static struct clocksource msm_clocksource = {
- .name = "dg_timer",
- .rating = 300,
-@@ -228,7 +219,7 @@ err:
- sched_clock_register(msm_sched_clock_read, sched_bits, dgt_hz);
- }
-
--#ifdef CONFIG_OF
-+#ifdef CONFIG_ARCH_QCOM
- static void __init msm_dt_timer_init(struct device_node *np)
- {
- u32 freq;
-@@ -281,7 +272,7 @@ static void __init msm_dt_timer_init(str
- }
- CLOCKSOURCE_OF_DECLARE(kpss_timer, "qcom,kpss-timer", msm_dt_timer_init);
- CLOCKSOURCE_OF_DECLARE(scss_timer, "qcom,scss-timer", msm_dt_timer_init);
--#endif
-+#else
-
- static int __init msm_timer_map(phys_addr_t addr, u32 event, u32 source,
- u32 sts)
-@@ -301,6 +292,15 @@ static int __init msm_timer_map(phys_add
- return 0;
- }
-
-+static notrace cycle_t msm_read_timer_count_shift(struct clocksource *cs)
-+{
-+ /*
-+ * Shift timer count down by a constant due to unreliable lower bits
-+ * on some targets.
-+ */
-+ return msm_read_timer_count(cs) >> MSM_DGT_SHIFT;
-+}
-+
- void __init msm7x01_timer_init(void)
- {
- struct clocksource *cs = &msm_clocksource;
-@@ -327,3 +327,4 @@ void __init qsd8x50_timer_init(void)
- return;
- msm_timer_init(19200000 / 4, 32, 7, false);
- }
-+#endif
diff --git a/target/linux/ipq806x/patches/0007-ARM-qcom-Rename-various-msm-prefixed-functions-to-qc.patch b/target/linux/ipq806x/patches/0007-ARM-qcom-Rename-various-msm-prefixed-functions-to-qc.patch
deleted file mode 100644
index cab5bcd..0000000
--- a/target/linux/ipq806x/patches/0007-ARM-qcom-Rename-various-msm-prefixed-functions-to-qc.patch
+++ /dev/null
@@ -1,98 +0,0 @@
-From 35eb6f73546d3b9475652a38fa641bd1a05a1ea1 Mon Sep 17 00:00:00 2001
-From: Kumar Gala <galak@codeaurora.org>
-Date: Tue, 4 Feb 2014 15:38:45 -0600
-Subject: [PATCH 007/182] ARM: qcom: Rename various msm prefixed functions to
- qcom
-
-As mach-qcom will support a number of different Qualcomm SoC platforms
-we replace the msm prefix on function names with qcom to be a bit more
-generic.
-
-Signed-off-by: Kumar Gala <galak@codeaurora.org>
----
- arch/arm/mach-qcom/board.c | 4 ++--
- arch/arm/mach-qcom/platsmp.c | 22 +++++++++++-----------
- 2 files changed, 13 insertions(+), 13 deletions(-)
-
---- a/arch/arm/mach-qcom/board.c
-+++ b/arch/arm/mach-qcom/board.c
-@@ -17,7 +17,7 @@
- #include <asm/mach/arch.h>
- #include <asm/mach/map.h>
-
--extern struct smp_operations msm_smp_ops;
-+extern struct smp_operations qcom_smp_ops;
-
- static const char * const qcom_dt_match[] __initconst = {
- "qcom,msm8660-surf",
-@@ -31,7 +31,7 @@ static const char * const apq8074_dt_mat
- };
-
- DT_MACHINE_START(QCOM_DT, "Qualcomm (Flattened Device Tree)")
-- .smp = smp_ops(msm_smp_ops),
-+ .smp = smp_ops(qcom_smp_ops),
- .dt_compat = qcom_dt_match,
- MACHINE_END
-
---- a/arch/arm/mach-qcom/platsmp.c
-+++ b/arch/arm/mach-qcom/platsmp.c
-@@ -30,7 +30,7 @@ extern void secondary_startup(void);
- static DEFINE_SPINLOCK(boot_lock);
-
- #ifdef CONFIG_HOTPLUG_CPU
--static void __ref msm_cpu_die(unsigned int cpu)
-+static void __ref qcom_cpu_die(unsigned int cpu)
- {
- wfi();
- }
-@@ -42,7 +42,7 @@ static inline int get_core_count(void)
- return ((read_cpuid_id() >> 4) & 3) + 1;
- }
-
--static void msm_secondary_init(unsigned int cpu)
-+static void qcom_secondary_init(unsigned int cpu)
- {
- /*
- * Synchronise with the boot thread.
-@@ -70,7 +70,7 @@ static void prepare_cold_cpu(unsigned in
- "address\n");
- }
-
--static int msm_boot_secondary(unsigned int cpu, struct task_struct *idle)
-+static int qcom_boot_secondary(unsigned int cpu, struct task_struct *idle)
- {
- static int cold_boot_done;
-
-@@ -108,7 +108,7 @@ static int msm_boot_secondary(unsigned i
- * does not support the ARM SCU, so just set the possible cpu mask to
- * NR_CPUS.
- */
--static void __init msm_smp_init_cpus(void)
-+static void __init qcom_smp_init_cpus(void)
- {
- unsigned int i, ncores = get_core_count();
-
-@@ -122,16 +122,16 @@ static void __init msm_smp_init_cpus(voi
- set_cpu_possible(i, true);
- }
-
--static void __init msm_smp_prepare_cpus(unsigned int max_cpus)
-+static void __init qcom_smp_prepare_cpus(unsigned int max_cpus)
- {
- }
-
--struct smp_operations msm_smp_ops __initdata = {
-- .smp_init_cpus = msm_smp_init_cpus,
-- .smp_prepare_cpus = msm_smp_prepare_cpus,
-- .smp_secondary_init = msm_secondary_init,
-- .smp_boot_secondary = msm_boot_secondary,
-+struct smp_operations qcom_smp_ops __initdata = {
-+ .smp_init_cpus = qcom_smp_init_cpus,
-+ .smp_prepare_cpus = qcom_smp_prepare_cpus,
-+ .smp_secondary_init = qcom_secondary_init,
-+ .smp_boot_secondary = qcom_boot_secondary,
- #ifdef CONFIG_HOTPLUG_CPU
-- .cpu_die = msm_cpu_die,
-+ .cpu_die = qcom_cpu_die,
- #endif
- };
diff --git a/target/linux/ipq806x/patches/0008-ARM-Introduce-CPU_METHOD_OF_DECLARE-for-cpu-hotplug-.patch b/target/linux/ipq806x/patches/0008-ARM-Introduce-CPU_METHOD_OF_DECLARE-for-cpu-hotplug-.patch
deleted file mode 100644
index b4a8b4b..0000000
--- a/target/linux/ipq806x/patches/0008-ARM-Introduce-CPU_METHOD_OF_DECLARE-for-cpu-hotplug-.patch
+++ /dev/null
@@ -1,150 +0,0 @@
-From 48f17325fef9cbebc5cb39aa78f4c1caff5d7b16 Mon Sep 17 00:00:00 2001
-From: Stephen Boyd <sboyd@codeaurora.org>
-Date: Wed, 30 Oct 2013 18:21:09 -0700
-Subject: [PATCH 008/182] ARM: Introduce CPU_METHOD_OF_DECLARE() for cpu
- hotplug/smp
-
-The goal of multi-platform kernels is to remove the need for mach
-directories and machine descriptors. To further that goal,
-introduce CPU_METHOD_OF_DECLARE() to allow cpu hotplug/smp
-support to be separated from the machine descriptors.
-Implementers should specify an enable-method property in their
-cpus node and then implement a matching set of smp_ops in their
-hotplug/smp code, wiring it up with the CPU_METHOD_OF_DECLARE()
-macro. When the kernel is compiled we'll collect all the
-enable-method smp_ops into one section for use at boot.
-
-At boot time we'll look for an enable-method in each cpu node and
-try to match that against all known CPU enable methods in the
-kernel. If there are no enable-methods in the cpu nodes we
-fallback to the cpus node and try to use any enable-method found
-there. If that doesn't work we fall back to the old way of using
-the machine descriptor.
-
-Acked-by: Mark Rutland <mark.rutland@arm.com>
-Cc: Russell King <linux@arm.linux.org.uk>
-Cc: <devicetree@vger.kernel.org>
-Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
-Signed-off-by: Kumar Gala <galak@codeaurora.org>
----
- arch/arm/include/asm/smp.h | 9 +++++++++
- arch/arm/kernel/devtree.c | 40 +++++++++++++++++++++++++++++++++++++
- include/asm-generic/vmlinux.lds.h | 10 ++++++++++
- 3 files changed, 59 insertions(+)
-
---- a/arch/arm/include/asm/smp.h
-+++ b/arch/arm/include/asm/smp.h
-@@ -114,6 +114,15 @@ struct smp_operations {
- #endif
- };
-
-+struct of_cpu_method {
-+ const char *method;
-+ struct smp_operations *ops;
-+};
-+
-+#define CPU_METHOD_OF_DECLARE(name, _method, _ops) \
-+ static const struct of_cpu_method __cpu_method_of_table_##name \
-+ __used __section(__cpu_method_of_table) \
-+ = { .method = _method, .ops = _ops }
- /*
- * set platform specific SMP operations
- */
---- a/arch/arm/kernel/devtree.c
-+++ b/arch/arm/kernel/devtree.c
-@@ -18,6 +18,7 @@
- #include <linux/of_fdt.h>
- #include <linux/of_irq.h>
- #include <linux/of_platform.h>
-+#include <linux/smp.h>
-
- #include <asm/cputype.h>
- #include <asm/setup.h>
-@@ -63,6 +64,34 @@ void __init arm_dt_memblock_reserve(void
- }
- }
-
-+#ifdef CONFIG_SMP
-+extern struct of_cpu_method __cpu_method_of_table_begin[];
-+extern struct of_cpu_method __cpu_method_of_table_end[];
-+
-+static int __init set_smp_ops_by_method(struct device_node *node)
-+{
-+ const char *method;
-+ struct of_cpu_method *m = __cpu_method_of_table_begin;
-+
-+ if (of_property_read_string(node, "enable-method", &method))
-+ return 0;
-+
-+ for (; m < __cpu_method_of_table_end; m++)
-+ if (!strcmp(m->method, method)) {
-+ smp_set_ops(m->ops);
-+ return 1;
-+ }
-+
-+ return 0;
-+}
-+#else
-+static inline int set_smp_ops_by_method(struct device_node *node)
-+{
-+ return 1;
-+}
-+#endif
-+
-+
- /*
- * arm_dt_init_cpu_maps - Function retrieves cpu nodes from the device tree
- * and builds the cpu logical map array containing MPIDR values related to
-@@ -79,6 +108,7 @@ void __init arm_dt_init_cpu_maps(void)
- * read as 0.
- */
- struct device_node *cpu, *cpus;
-+ int found_method = 0;
- u32 i, j, cpuidx = 1;
- u32 mpidr = is_smp() ? read_cpuid_mpidr() & MPIDR_HWID_BITMASK : 0;
-
-@@ -150,8 +180,18 @@ void __init arm_dt_init_cpu_maps(void)
- }
-
- tmp_map[i] = hwid;
-+
-+ if (!found_method)
-+ found_method = set_smp_ops_by_method(cpu);
- }
-
-+ /*
-+ * Fallback to an enable-method in the cpus node if nothing found in
-+ * a cpu node.
-+ */
-+ if (!found_method)
-+ set_smp_ops_by_method(cpus);
-+
- if (!bootcpu_valid) {
- pr_warn("DT missing boot CPU MPIDR[23:0], fall back to default cpu_logical_map\n");
- return;
---- a/include/asm-generic/vmlinux.lds.h
-+++ b/include/asm-generic/vmlinux.lds.h
-@@ -177,6 +177,15 @@
- #define CLK_OF_TABLES()
- #endif
-
-+#ifdef CONFIG_SMP
-+#define CPU_METHOD_OF_TABLES() . = ALIGN(8); \
-+ VMLINUX_SYMBOL(__cpu_method_of_table_begin) = .; \
-+ *(__cpu_method_of_table) \
-+ VMLINUX_SYMBOL(__cpu_method_of_table_end) = .;
-+#else
-+#define CPU_METHOD_OF_TABLES()
-+#endif
-+
- #define KERNEL_DTB() \
- STRUCT_ALIGN(); \
- VMLINUX_SYMBOL(__dtb_start) = .; \
-@@ -502,6 +511,7 @@
- MEM_DISCARD(init.rodata) \
- CLK_OF_TABLES() \
- CLKSRC_OF_TABLES() \
-+ CPU_METHOD_OF_TABLES() \
- KERNEL_DTB() \
- IRQCHIP_OF_MATCH_TABLE()
-
diff --git a/target/linux/ipq806x/patches/0009-ARM-qcom-Re-organize-platsmp-to-make-it-extensible.patch b/target/linux/ipq806x/patches/0009-ARM-qcom-Re-organize-platsmp-to-make-it-extensible.patch
deleted file mode 100644
index 4bab4c9..0000000
--- a/target/linux/ipq806x/patches/0009-ARM-qcom-Re-organize-platsmp-to-make-it-extensible.patch
+++ /dev/null
@@ -1,241 +0,0 @@
-From 391848e75f8b0ba14816da1ac8f2d838fd0d5744 Mon Sep 17 00:00:00 2001
-From: Rohit Vaswani <rvaswani@codeaurora.org>
-Date: Tue, 21 May 2013 19:13:29 -0700
-Subject: [PATCH 009/182] ARM: qcom: Re-organize platsmp to make it extensible
-
-This makes it easy to add SMP support for new devices by keying
-on a device node for the release sequence. We add the
-enable-method property for the cpus property to specify that we
-want to use the gcc-msm8660 release sequence (which is going to
-look for the global clock controller device node to map some
-Scorpion specific power and control registers). We also remove
-the nr_cpus detection code as that is done generically in the DT
-CPU detection code.
-
-Signed-off-by: Rohit Vaswani <rvaswani@codeaurora.org>
-[sboyd: Port to CPU_METHOD_OF_DECLARE]
-Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
-Signed-off-by: Kumar Gala <galak@codeaurora.org>
----
- arch/arm/mach-msm/common.h | 2 -
- arch/arm/mach-qcom/board.c | 14 -----
- arch/arm/mach-qcom/platsmp.c | 118 +++++++++++++++++++++++-------------------
- 3 files changed, 65 insertions(+), 69 deletions(-)
-
---- a/arch/arm/mach-msm/common.h
-+++ b/arch/arm/mach-msm/common.h
-@@ -23,8 +23,6 @@ extern void msm_map_qsd8x50_io(void);
- extern void __iomem *__msm_ioremap_caller(phys_addr_t phys_addr, size_t size,
- unsigned int mtype, void *caller);
-
--extern struct smp_operations msm_smp_ops;
--
- struct msm_mmc_platform_data;
-
- extern void msm_add_devices(void);
---- a/arch/arm/mach-qcom/board.c
-+++ b/arch/arm/mach-qcom/board.c
-@@ -11,30 +11,16 @@
- */
-
- #include <linux/init.h>
--#include <linux/of.h>
--#include <linux/of_platform.h>
-
- #include <asm/mach/arch.h>
--#include <asm/mach/map.h>
--
--extern struct smp_operations qcom_smp_ops;
-
- static const char * const qcom_dt_match[] __initconst = {
- "qcom,msm8660-surf",
- "qcom,msm8960-cdp",
-- NULL
--};
--
--static const char * const apq8074_dt_match[] __initconst = {
- "qcom,apq8074-dragonboard",
- NULL
- };
-
- DT_MACHINE_START(QCOM_DT, "Qualcomm (Flattened Device Tree)")
-- .smp = smp_ops(qcom_smp_ops),
- .dt_compat = qcom_dt_match,
- MACHINE_END
--
--DT_MACHINE_START(APQ_DT, "Qualcomm (Flattened Device Tree)")
-- .dt_compat = apq8074_dt_match,
--MACHINE_END
---- a/arch/arm/mach-qcom/platsmp.c
-+++ b/arch/arm/mach-qcom/platsmp.c
-@@ -13,17 +13,18 @@
- #include <linux/errno.h>
- #include <linux/delay.h>
- #include <linux/device.h>
-+#include <linux/of.h>
-+#include <linux/of_address.h>
- #include <linux/smp.h>
- #include <linux/io.h>
-
--#include <asm/cputype.h>
- #include <asm/smp_plat.h>
-
- #include "scm-boot.h"
-
--#define VDD_SC1_ARRAY_CLAMP_GFS_CTL 0x15A0
--#define SCSS_CPU1CORE_RESET 0xD80
--#define SCSS_DBG_STATUS_CORE_PWRDUP 0xE64
-+#define VDD_SC1_ARRAY_CLAMP_GFS_CTL 0x35a0
-+#define SCSS_CPU1CORE_RESET 0x2d80
-+#define SCSS_DBG_STATUS_CORE_PWRDUP 0x2e64
-
- extern void secondary_startup(void);
-
-@@ -36,12 +37,6 @@ static void __ref qcom_cpu_die(unsigned
- }
- #endif
-
--static inline int get_core_count(void)
--{
-- /* 1 + the PART[1:0] field of MIDR */
-- return ((read_cpuid_id() >> 4) & 3) + 1;
--}
--
- static void qcom_secondary_init(unsigned int cpu)
- {
- /*
-@@ -51,33 +46,41 @@ static void qcom_secondary_init(unsigned
- spin_unlock(&boot_lock);
- }
-
--static void prepare_cold_cpu(unsigned int cpu)
-+static int scss_release_secondary(unsigned int cpu)
- {
-- int ret;
-- ret = scm_set_boot_addr(virt_to_phys(secondary_startup),
-- SCM_FLAG_COLDBOOT_CPU1);
-- if (ret == 0) {
-- void __iomem *sc1_base_ptr;
-- sc1_base_ptr = ioremap_nocache(0x00902000, SZ_4K*2);
-- if (sc1_base_ptr) {
-- writel(0, sc1_base_ptr + VDD_SC1_ARRAY_CLAMP_GFS_CTL);
-- writel(0, sc1_base_ptr + SCSS_CPU1CORE_RESET);
-- writel(3, sc1_base_ptr + SCSS_DBG_STATUS_CORE_PWRDUP);
-- iounmap(sc1_base_ptr);
-- }
-- } else
-- printk(KERN_DEBUG "Failed to set secondary core boot "
-- "address\n");
-+ struct device_node *node;
-+ void __iomem *base;
-+
-+ node = of_find_compatible_node(NULL, NULL, "qcom,gcc-msm8660");
-+ if (!node) {
-+ pr_err("%s: can't find node\n", __func__);
-+ return -ENXIO;
-+ }
-+
-+ base = of_iomap(node, 0);
-+ of_node_put(node);
-+ if (!base)
-+ return -ENOMEM;
-+
-+ writel_relaxed(0, base + VDD_SC1_ARRAY_CLAMP_GFS_CTL);
-+ writel_relaxed(0, base + SCSS_CPU1CORE_RESET);
-+ writel_relaxed(3, base + SCSS_DBG_STATUS_CORE_PWRDUP);
-+ mb();
-+ iounmap(base);
-+
-+ return 0;
- }
-
--static int qcom_boot_secondary(unsigned int cpu, struct task_struct *idle)
-+static DEFINE_PER_CPU(int, cold_boot_done);
-+
-+static int qcom_boot_secondary(unsigned int cpu, int (*func)(unsigned int))
- {
-- static int cold_boot_done;
-+ int ret = 0;
-
-- /* Only need to bring cpu out of reset this way once */
-- if (cold_boot_done == false) {
-- prepare_cold_cpu(cpu);
-- cold_boot_done = true;
-+ if (!per_cpu(cold_boot_done, cpu)) {
-+ ret = func(cpu);
-+ if (!ret)
-+ per_cpu(cold_boot_done, cpu) = true;
- }
-
- /*
-@@ -99,39 +102,48 @@ static int qcom_boot_secondary(unsigned
- */
- spin_unlock(&boot_lock);
-
-- return 0;
-+ return ret;
- }
-
--/*
-- * Initialise the CPU possible map early - this describes the CPUs
-- * which may be present or become present in the system. The msm8x60
-- * does not support the ARM SCU, so just set the possible cpu mask to
-- * NR_CPUS.
-- */
--static void __init qcom_smp_init_cpus(void)
--{
-- unsigned int i, ncores = get_core_count();
--
-- if (ncores > nr_cpu_ids) {
-- pr_warn("SMP: %u cores greater than maximum (%u), clipping\n",
-- ncores, nr_cpu_ids);
-- ncores = nr_cpu_ids;
-- }
--
-- for (i = 0; i < ncores; i++)
-- set_cpu_possible(i, true);
-+static int msm8660_boot_secondary(unsigned int cpu, struct task_struct *idle)
-+{
-+ return qcom_boot_secondary(cpu, scss_release_secondary);
- }
-
- static void __init qcom_smp_prepare_cpus(unsigned int max_cpus)
- {
-+ int cpu, map;
-+ unsigned int flags = 0;
-+ static const int cold_boot_flags[] = {
-+ 0,
-+ SCM_FLAG_COLDBOOT_CPU1,
-+ };
-+
-+ for_each_present_cpu(cpu) {
-+ map = cpu_logical_map(cpu);
-+ if (WARN_ON(map >= ARRAY_SIZE(cold_boot_flags))) {
-+ set_cpu_present(cpu, false);
-+ continue;
-+ }
-+ flags |= cold_boot_flags[map];
-+ }
-+
-+ if (scm_set_boot_addr(virt_to_phys(secondary_startup), flags)) {
-+ for_each_present_cpu(cpu) {
-+ if (cpu == smp_processor_id())
-+ continue;
-+ set_cpu_present(cpu, false);
-+ }
-+ pr_warn("Failed to set CPU boot address, disabling SMP\n");
-+ }
- }
-
--struct smp_operations qcom_smp_ops __initdata = {
-- .smp_init_cpus = qcom_smp_init_cpus,
-+static struct smp_operations smp_msm8660_ops __initdata = {
- .smp_prepare_cpus = qcom_smp_prepare_cpus,
- .smp_secondary_init = qcom_secondary_init,
-- .smp_boot_secondary = qcom_boot_secondary,
-+ .smp_boot_secondary = msm8660_boot_secondary,
- #ifdef CONFIG_HOTPLUG_CPU
- .cpu_die = qcom_cpu_die,
- #endif
- };
-+CPU_METHOD_OF_DECLARE(qcom_smp, "qcom,gcc-msm8660", &smp_msm8660_ops);
diff --git a/target/linux/ipq806x/patches/0179-spi-qup-Add-DMA-capabilities.patch b/target/linux/ipq806x/patches/001-spi-qup-Add-DMA-capabilities.patch
index 2f7d318..62badd5 100644
--- a/target/linux/ipq806x/patches/0179-spi-qup-Add-DMA-capabilities.patch
+++ b/target/linux/ipq806x/patches/001-spi-qup-Add-DMA-capabilities.patch
@@ -1,17 +1,55 @@
-From 8322bafdcee1d7eaf15540ff013415bff1eacb28 Mon Sep 17 00:00:00 2001
+Content-Type: text/plain; charset="utf-8"
+MIME-Version: 1.0
+Content-Transfer-Encoding: 7bit
+Subject: spi: qup: Add DMA capabilities
From: Andy Gross <agross@codeaurora.org>
-Date: Thu, 26 Jun 2014 10:50:24 -0500
-Subject: [PATCH 179/182] spi: qup: Add DMA capabilities
+X-Patchwork-Id: 4432401
+Message-Id: <1403816781-31008-1-git-send-email-agross@codeaurora.org>
+To: Mark Brown <broonie@kernel.org>
+Cc: linux-spi@vger.kernel.org, Sagar Dharia <sdharia@codeaurora.org>,
+ Daniel Sneddon <dsneddon@codeaurora.org>,
+ Bjorn Andersson <bjorn.andersson@sonymobile.com>,
+ "Ivan T. Ivanov" <iivanov@mm-sol.com>,
+ linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org,
+ linux-arm-msm@vger.kernel.org, Andy Gross <agross@codeaurora.org>
+Date: Thu, 26 Jun 2014 16:06:21 -0500
This patch adds DMA capabilities to the spi-qup driver. If DMA channels are
present, the QUP will use DMA instead of block mode for transfers to/from SPI
-peripherals for transactions larger greater than the length of a block.
+peripherals for transactions larger than the length of a block.
Signed-off-by: Andy Gross <agross@codeaurora.org>
+
---
- drivers/spi/spi-qup.c | 361 ++++++++++++++++++++++++++++++++++++++++++++++---
- 1 file changed, 340 insertions(+), 21 deletions(-)
+.../devicetree/bindings/spi/qcom,spi-qup.txt | 10 +
+ drivers/spi/spi-qup.c | 361 ++++++++++++++++++--
+ 2 files changed, 350 insertions(+), 21 deletions(-)
+--- a/Documentation/devicetree/bindings/spi/qcom,spi-qup.txt
++++ b/Documentation/devicetree/bindings/spi/qcom,spi-qup.txt
+@@ -27,6 +27,11 @@ Optional properties:
+ - spi-max-frequency: Specifies maximum SPI clock frequency,
+ Units - Hz. Definition as per
+ Documentation/devicetree/bindings/spi/spi-bus.txt
++- dmas : Two DMA channel specifiers following the convention outlined
++ in bindings/dma/dma.txt
++- dma-names: Names for the dma channels, if present. There must be at
++ least one channel named "tx" for transmit and named "rx" for
++ receive.
+ - num-cs: total number of chipselects
+ - cs-gpios: should specify GPIOs used for chipselects.
+ The gpios will be referred to as reg = <index> in the SPI child
+@@ -51,6 +56,10 @@ Example:
+ clocks = <&gcc GCC_BLSP2_QUP2_SPI_APPS_CLK>, <&gcc GCC_BLSP2_AHB_CLK>;
+ clock-names = "core", "iface";
+
++ dmas = <&blsp2_bam 2>,
++ <&blsp2_bam 3>;
++ dma-names = "rx", "tx";
++
+ pinctrl-names = "default";
+ pinctrl-0 = <&spi8_default>;
+
--- a/drivers/spi/spi-qup.c
+++ b/drivers/spi/spi-qup.c
@@ -22,6 +22,8 @@
@@ -32,22 +70,25 @@ Signed-off-by: Andy Gross <agross@codeaurora.org>
/* high speed mode is when bus rate is greater then 26MHz */
#define SPI_HS_MIN_RATE 26000000
#define SPI_MAX_RATE 50000000
-@@ -143,6 +147,14 @@ struct spi_qup {
+@@ -143,6 +147,17 @@ struct spi_qup {
int tx_bytes;
int rx_bytes;
int qup_v1;
++
+ int use_dma;
+
+ struct dma_chan *rx_chan;
+ struct dma_slave_config rx_conf;
+ struct dma_chan *tx_chan;
+ struct dma_slave_config tx_conf;
-+ void *dummy;
++ dma_addr_t rx_dma;
++ dma_addr_t tx_dma;
++ void *dummy;
+ atomic_t dma_outstanding;
};
-@@ -266,6 +278,221 @@ static void spi_qup_fifo_write(struct sp
+@@ -266,6 +281,221 @@ static void spi_qup_fifo_write(struct sp
}
}
@@ -269,7 +310,7 @@ Signed-off-by: Andy Gross <agross@codeaurora.org>
static irqreturn_t spi_qup_qup_irq(int irq, void *dev_id)
{
struct spi_qup *controller = dev_id;
-@@ -315,11 +542,13 @@ static irqreturn_t spi_qup_qup_irq(int i
+@@ -315,11 +545,13 @@ static irqreturn_t spi_qup_qup_irq(int i
error = -EIO;
}
@@ -287,7 +328,7 @@ Signed-off-by: Andy Gross <agross@codeaurora.org>
spin_lock_irqsave(&controller->lock, flags);
controller->error = error;
-@@ -339,6 +568,8 @@ static int spi_qup_io_config(struct spi_
+@@ -339,6 +571,8 @@ static int spi_qup_io_config(struct spi_
struct spi_qup *controller = spi_master_get_devdata(spi->master);
u32 config, iomode, mode;
int ret, n_words, w_size;
@@ -296,21 +337,19 @@ Signed-off-by: Andy Gross <agross@codeaurora.org>
if (spi->mode & SPI_LOOP && xfer->len > controller->in_fifo_sz) {
dev_err(controller->dev, "too big size for loopback %d > %d\n",
-@@ -367,6 +598,13 @@ static int spi_qup_io_config(struct spi_
+@@ -367,6 +601,11 @@ static int spi_qup_io_config(struct spi_
n_words = xfer->len / w_size;
controller->w_size = w_size;
+ if (controller->rx_chan &&
+ IS_ALIGNED((size_t)xfer->tx_buf, dma_align) &&
-+ IS_ALIGNED((size_t)xfer->rx_buf, dma_align) &&
-+ !is_vmalloc_addr(xfer->tx_buf) &&
-+ !is_vmalloc_addr(xfer->rx_buf))
++ IS_ALIGNED((size_t)xfer->rx_buf, dma_align))
+ dma_available = 1;
+
if (n_words <= (controller->in_fifo_sz / sizeof(u32))) {
mode = QUP_IO_M_MODE_FIFO;
writel_relaxed(n_words, controller->base + QUP_MX_READ_CNT);
-@@ -374,19 +612,30 @@ static int spi_qup_io_config(struct spi_
+@@ -374,19 +613,31 @@ static int spi_qup_io_config(struct spi_
/* must be zero for FIFO */
writel_relaxed(0, controller->base + QUP_MX_INPUT_CNT);
writel_relaxed(0, controller->base + QUP_MX_OUTPUT_CNT);
@@ -335,6 +374,7 @@ Signed-off-by: Andy Gross <agross@codeaurora.org>
/* Set input and output transfer mode */
iomode &= ~(QUP_IO_M_INPUT_MODE_MASK | QUP_IO_M_OUTPUT_MODE_MASK);
- iomode &= ~(QUP_IO_M_PACK_EN | QUP_IO_M_UNPACK_EN);
++
+ if (!controller->use_dma)
+ iomode &= ~(QUP_IO_M_PACK_EN | QUP_IO_M_UNPACK_EN);
+ else
@@ -343,7 +383,7 @@ Signed-off-by: Andy Gross <agross@codeaurora.org>
iomode |= (mode << QUP_IO_M_OUTPUT_MODE_MASK_SHIFT);
iomode |= (mode << QUP_IO_M_INPUT_MODE_MASK_SHIFT);
-@@ -419,11 +668,20 @@ static int spi_qup_io_config(struct spi_
+@@ -419,6 +670,14 @@ static int spi_qup_io_config(struct spi_
config &= ~(QUP_CONFIG_NO_INPUT | QUP_CONFIG_NO_OUTPUT | QUP_CONFIG_N);
config |= xfer->bits_per_word - 1;
config |= QUP_CONFIG_SPI_MODE;
@@ -358,13 +398,7 @@ Signed-off-by: Andy Gross <agross@codeaurora.org>
writel_relaxed(config, controller->base + QUP_CONFIG);
/* only write to OPERATIONAL_MASK when register is present */
- if (!controller->qup_v1)
- writel_relaxed(0, controller->base + QUP_OPERATIONAL_MASK);
-+
- return 0;
- }
-
-@@ -452,26 +710,32 @@ static int spi_qup_transfer_one(struct s
+@@ -452,25 +711,29 @@ static int spi_qup_transfer_one(struct s
controller->tx_bytes = 0;
spin_unlock_irqrestore(&controller->lock, flags);
@@ -403,16 +437,13 @@ Signed-off-by: Andy Gross <agross@codeaurora.org>
- if (!wait_for_completion_timeout(&controller->done, timeout))
- ret = -ETIMEDOUT;
-+ if (!ret && !wait_for_completion_timeout(&controller->done,
-+ timeout))
++ if (!wait_for_completion_timeout(&controller->done, timeout))
+ ret = -ETIMEDOUT;
+ }
exit:
-+
spi_qup_set_state(controller, QUP_STATE_RESET);
spin_lock_irqsave(&controller->lock, flags);
- controller->xfer = NULL;
-@@ -553,6 +817,7 @@ static int spi_qup_probe(struct platform
+@@ -553,6 +816,7 @@ static int spi_qup_probe(struct platform
master->transfer_one = spi_qup_transfer_one;
master->dev.of_node = pdev->dev.of_node;
master->auto_runtime_pm = true;
@@ -420,9 +451,9 @@ Signed-off-by: Andy Gross <agross@codeaurora.org>
platform_set_drvdata(pdev, master);
-@@ -612,6 +877,55 @@ static int spi_qup_probe(struct platform
- writel_relaxed(SPI_ERROR_CLK_UNDER_RUN | SPI_ERROR_CLK_OVER_RUN,
- base + SPI_ERROR_FLAGS_EN);
+@@ -618,6 +882,56 @@ static int spi_qup_probe(struct platform
+ QUP_ERROR_INPUT_UNDER_RUN | QUP_ERROR_OUTPUT_UNDER_RUN,
+ base + QUP_ERROR_FLAGS_EN);
+ /* allocate dma resources, if available */
+ controller->rx_chan = dma_request_slave_channel(&pdev->dev, "rx");
@@ -473,9 +504,10 @@ Signed-off-by: Andy Gross <agross@codeaurora.org>
+ }
+ }
+
- /* if earlier version of the QUP, disable INPUT_OVERRUN */
- if (controller->qup_v1)
- writel_relaxed(QUP_ERROR_OUTPUT_OVER_RUN |
++
+ writel_relaxed(0, base + SPI_CONFIG);
+ writel_relaxed(SPI_IO_C_NO_TRI_STATE, base + SPI_IO_CONTROL);
+
@@ -730,6 +1044,11 @@ static int spi_qup_remove(struct platfor
if (ret)
return ret;
diff --git a/target/linux/ipq806x/patches/0010-devicetree-bindings-Document-Krait-Scorpion-cpus-and.patch b/target/linux/ipq806x/patches/0010-devicetree-bindings-Document-Krait-Scorpion-cpus-and.patch
deleted file mode 100644
index 751aa85..0000000
--- a/target/linux/ipq806x/patches/0010-devicetree-bindings-Document-Krait-Scorpion-cpus-and.patch
+++ /dev/null
@@ -1,65 +0,0 @@
-From 236d07c7bb0c758ea40ea0110d37306d2e7d9a4b Mon Sep 17 00:00:00 2001
-From: Rohit Vaswani <rvaswani@codeaurora.org>
-Date: Thu, 31 Oct 2013 17:26:33 -0700
-Subject: [PATCH 010/182] devicetree: bindings: Document Krait/Scorpion cpus
- and enable-method
-
-Scorpion and Krait don't use the spin-table enable-method.
-Instead they rely on mmio register accesses to enable power and
-clocks to bring CPUs out of reset. Document their enable-methods.
-
-Cc: <devicetree@vger.kernel.org>
-Signed-off-by: Rohit Vaswani <rvaswani@codeaurora.org>
-[sboyd: Split off into separate patch, renamed methods to
-match compatible nodes]
-Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
-Signed-off-by: Kumar Gala <galak@codeaurora.org>
----
- Documentation/devicetree/bindings/arm/cpus.txt | 25 +++++++++++++++++++++++-
- 1 file changed, 24 insertions(+), 1 deletion(-)
-
---- a/Documentation/devicetree/bindings/arm/cpus.txt
-+++ b/Documentation/devicetree/bindings/arm/cpus.txt
-@@ -180,7 +180,11 @@ nodes to be present and contain the prop
- be one of:
- "spin-table"
- "psci"
-- # On ARM 32-bit systems this property is optional.
-+ # On ARM 32-bit systems this property is optional and
-+ can be one of:
-+ "qcom,gcc-msm8660"
-+ "qcom,kpss-acc-v1"
-+ "qcom,kpss-acc-v2"
-
- - cpu-release-addr
- Usage: required for systems that have an "enable-method"
-@@ -191,6 +195,21 @@ nodes to be present and contain the prop
- property identifying a 64-bit zero-initialised
- memory location.
-
-+ - qcom,saw
-+ Usage: required for systems that have an "enable-method"
-+ property value of "qcom,kpss-acc-v1" or
-+ "qcom,kpss-acc-v2"
-+ Value type: <phandle>
-+ Definition: Specifies the SAW[1] node associated with this CPU.
-+
-+ - qcom,acc
-+ Usage: required for systems that have an "enable-method"
-+ property value of "qcom,kpss-acc-v1" or
-+ "qcom,kpss-acc-v2"
-+ Value type: <phandle>
-+ Definition: Specifies the ACC[2] node associated with this CPU.
-+
-+
- Example 1 (dual-cluster big.LITTLE system 32-bit):
-
- cpus {
-@@ -382,3 +401,7 @@ cpus {
- cpu-release-addr = <0 0x20000000>;
- };
- };
-+
-+--
-+[1] arm/msm/qcom,saw2.txt
-+[2] arm/msm/qcom,kpss-acc.txt
diff --git a/target/linux/ipq806x/patches/0011-devicetree-bindings-Document-qcom-kpss-acc.patch b/target/linux/ipq806x/patches/0011-devicetree-bindings-Document-qcom-kpss-acc.patch
deleted file mode 100644
index dfd4c32..0000000
--- a/target/linux/ipq806x/patches/0011-devicetree-bindings-Document-qcom-kpss-acc.patch
+++ /dev/null
@@ -1,49 +0,0 @@
-From 3a4fe9a3a4aff8b1f1c3685bc9b6adbe739d7367 Mon Sep 17 00:00:00 2001
-From: Stephen Boyd <sboyd@codeaurora.org>
-Date: Thu, 31 Oct 2013 18:20:30 -0700
-Subject: [PATCH 011/182] devicetree: bindings: Document qcom,kpss-acc
-
-The kpss acc binding describes the clock, reset, and power domain
-controller for a Krait CPU.
-
-Cc: <devicetree@vger.kernel.org>
-Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
-Signed-off-by: Kumar Gala <galak@codeaurora.org>
----
- .../devicetree/bindings/arm/msm/qcom,kpss-acc.txt | 30 ++++++++++++++++++++
- 1 file changed, 30 insertions(+)
- create mode 100644 Documentation/devicetree/bindings/arm/msm/qcom,kpss-acc.txt
-
---- /dev/null
-+++ b/Documentation/devicetree/bindings/arm/msm/qcom,kpss-acc.txt
-@@ -0,0 +1,30 @@
-+Krait Processor Sub-system (KPSS) Application Clock Controller (ACC)
-+
-+The KPSS ACC provides clock, power domain, and reset control to a Krait CPU.
-+There is one ACC register region per CPU within the KPSS remapped region as
-+well as an alias register region that remaps accesses to the ACC associated
-+with the CPU accessing the region.
-+
-+PROPERTIES
-+
-+- compatible:
-+ Usage: required
-+ Value type: <string>
-+ Definition: should be one of:
-+ "qcom,kpss-acc-v1"
-+ "qcom,kpss-acc-v2"
-+
-+- reg:
-+ Usage: required
-+ Value type: <prop-encoded-array>
-+ Definition: the first element specifies the base address and size of
-+ the register region. An optional second element specifies
-+ the base address and size of the alias register region.
-+
-+Example:
-+
-+ clock-controller@2088000 {
-+ compatible = "qcom,kpss-acc-v2";
-+ reg = <0x02088000 0x1000>,
-+ <0x02008000 0x1000>;
-+ };
diff --git a/target/linux/ipq806x/patches/0012-devicetree-bindings-Document-qcom-saw2-node.patch b/target/linux/ipq806x/patches/0012-devicetree-bindings-Document-qcom-saw2-node.patch
deleted file mode 100644
index 79aaf2d..0000000
--- a/target/linux/ipq806x/patches/0012-devicetree-bindings-Document-qcom-saw2-node.patch
+++ /dev/null
@@ -1,54 +0,0 @@
-From 17adce4d3de1fca7761607d572f4979557f0f604 Mon Sep 17 00:00:00 2001
-From: Stephen Boyd <sboyd@codeaurora.org>
-Date: Thu, 31 Oct 2013 18:20:30 -0700
-Subject: [PATCH 012/182] devicetree: bindings: Document qcom,saw2 node
-
-The saw2 binding describes the SPM/AVS wrapper hardware used to
-control the regulator supplying voltage to the Krait CPUs.
-
-Cc: <devicetree@vger.kernel.org>
-Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
-Signed-off-by: Kumar Gala <galak@codeaurora.org>
----
- .../devicetree/bindings/arm/msm/qcom,saw2.txt | 35 ++++++++++++++++++++
- 1 file changed, 35 insertions(+)
- create mode 100644 Documentation/devicetree/bindings/arm/msm/qcom,saw2.txt
-
---- /dev/null
-+++ b/Documentation/devicetree/bindings/arm/msm/qcom,saw2.txt
-@@ -0,0 +1,35 @@
-+SPM AVS Wrapper 2 (SAW2)
-+
-+The SAW2 is a wrapper around the Subsystem Power Manager (SPM) and the
-+Adaptive Voltage Scaling (AVS) hardware. The SPM is a programmable
-+micro-controller that transitions a piece of hardware (like a processor or
-+subsystem) into and out of low power modes via a direct connection to
-+the PMIC. It can also be wired up to interact with other processors in the
-+system, notifying them when a low power state is entered or exited.
-+
-+PROPERTIES
-+
-+- compatible:
-+ Usage: required
-+ Value type: <string>
-+ Definition: shall contain "qcom,saw2". A more specific value should be
-+ one of:
-+ "qcom,saw2-v1"
-+ "qcom,saw2-v1.1"
-+ "qcom,saw2-v2"
-+ "qcom,saw2-v2.1"
-+
-+- reg:
-+ Usage: required
-+ Value type: <prop-encoded-array>
-+ Definition: the first element specifies the base address and size of
-+ the register region. An optional second element specifies
-+ the base address and size of the alias register region.
-+
-+
-+Example:
-+
-+ regulator@2099000 {
-+ compatible = "qcom,saw2";
-+ reg = <0x02099000 0x1000>, <0x02009000 0x1000>;
-+ };
diff --git a/target/linux/ipq806x/patches/0013-ARM-qcom-Add-SMP-support-for-KPSSv1.patch b/target/linux/ipq806x/patches/0013-ARM-qcom-Add-SMP-support-for-KPSSv1.patch
deleted file mode 100644
index e1d9ae1..0000000
--- a/target/linux/ipq806x/patches/0013-ARM-qcom-Add-SMP-support-for-KPSSv1.patch
+++ /dev/null
@@ -1,174 +0,0 @@
-From 8e843640b3c4a43b963332fdc7b233948ad25a5b Mon Sep 17 00:00:00 2001
-From: Rohit Vaswani <rvaswani@codeaurora.org>
-Date: Tue, 21 May 2013 19:13:50 -0700
-Subject: [PATCH 013/182] ARM: qcom: Add SMP support for KPSSv1
-
-Implement support for the Krait CPU release sequence when the
-CPUs are part of the first version of the krait processor
-subsystem.
-
-Signed-off-by: Rohit Vaswani <rvaswani@codeaurora.org>
-Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
-Signed-off-by: Kumar Gala <galak@codeaurora.org>
----
- arch/arm/mach-qcom/platsmp.c | 106 +++++++++++++++++++++++++++++++++++++++++
- arch/arm/mach-qcom/scm-boot.h | 8 ++--
- 2 files changed, 111 insertions(+), 3 deletions(-)
-
---- a/arch/arm/mach-qcom/platsmp.c
-+++ b/arch/arm/mach-qcom/platsmp.c
-@@ -26,6 +26,16 @@
- #define SCSS_CPU1CORE_RESET 0x2d80
- #define SCSS_DBG_STATUS_CORE_PWRDUP 0x2e64
-
-+#define APCS_CPU_PWR_CTL 0x04
-+#define PLL_CLAMP BIT(8)
-+#define CORE_PWRD_UP BIT(7)
-+#define COREPOR_RST BIT(5)
-+#define CORE_RST BIT(4)
-+#define L2DT_SLP BIT(3)
-+#define CLAMP BIT(0)
-+
-+#define APCS_SAW2_VCTL 0x14
-+
- extern void secondary_startup(void);
-
- static DEFINE_SPINLOCK(boot_lock);
-@@ -71,6 +81,85 @@ static int scss_release_secondary(unsign
- return 0;
- }
-
-+static int kpssv1_release_secondary(unsigned int cpu)
-+{
-+ int ret = 0;
-+ void __iomem *reg, *saw_reg;
-+ struct device_node *cpu_node, *acc_node, *saw_node;
-+ u32 val;
-+
-+ cpu_node = of_get_cpu_node(cpu, NULL);
-+ if (!cpu_node)
-+ return -ENODEV;
-+
-+ acc_node = of_parse_phandle(cpu_node, "qcom,acc", 0);
-+ if (!acc_node) {
-+ ret = -ENODEV;
-+ goto out_acc;
-+ }
-+
-+ saw_node = of_parse_phandle(cpu_node, "qcom,saw", 0);
-+ if (!saw_node) {
-+ ret = -ENODEV;
-+ goto out_saw;
-+ }
-+
-+ reg = of_iomap(acc_node, 0);
-+ if (!reg) {
-+ ret = -ENOMEM;
-+ goto out_acc_map;
-+ }
-+
-+ saw_reg = of_iomap(saw_node, 0);
-+ if (!saw_reg) {
-+ ret = -ENOMEM;
-+ goto out_saw_map;
-+ }
-+
-+ /* Turn on CPU rail */
-+ writel_relaxed(0xA4, saw_reg + APCS_SAW2_VCTL);
-+ mb();
-+ udelay(512);
-+
-+ /* Krait bring-up sequence */
-+ val = PLL_CLAMP | L2DT_SLP | CLAMP;
-+ writel_relaxed(val, reg + APCS_CPU_PWR_CTL);
-+ val &= ~L2DT_SLP;
-+ writel_relaxed(val, reg + APCS_CPU_PWR_CTL);
-+ mb();
-+ ndelay(300);
-+
-+ val |= COREPOR_RST;
-+ writel_relaxed(val, reg + APCS_CPU_PWR_CTL);
-+ mb();
-+ udelay(2);
-+
-+ val &= ~CLAMP;
-+ writel_relaxed(val, reg + APCS_CPU_PWR_CTL);
-+ mb();
-+ udelay(2);
-+
-+ val &= ~COREPOR_RST;
-+ writel_relaxed(val, reg + APCS_CPU_PWR_CTL);
-+ mb();
-+ udelay(100);
-+
-+ val |= CORE_PWRD_UP;
-+ writel_relaxed(val, reg + APCS_CPU_PWR_CTL);
-+ mb();
-+
-+ iounmap(saw_reg);
-+out_saw_map:
-+ iounmap(reg);
-+out_acc_map:
-+ of_node_put(saw_node);
-+out_saw:
-+ of_node_put(acc_node);
-+out_acc:
-+ of_node_put(cpu_node);
-+ return ret;
-+}
-+
- static DEFINE_PER_CPU(int, cold_boot_done);
-
- static int qcom_boot_secondary(unsigned int cpu, int (*func)(unsigned int))
-@@ -110,6 +199,11 @@ static int msm8660_boot_secondary(unsign
- return qcom_boot_secondary(cpu, scss_release_secondary);
- }
-
-+static int kpssv1_boot_secondary(unsigned int cpu, struct task_struct *idle)
-+{
-+ return qcom_boot_secondary(cpu, kpssv1_release_secondary);
-+}
-+
- static void __init qcom_smp_prepare_cpus(unsigned int max_cpus)
- {
- int cpu, map;
-@@ -117,6 +211,8 @@ static void __init qcom_smp_prepare_cpus
- static const int cold_boot_flags[] = {
- 0,
- SCM_FLAG_COLDBOOT_CPU1,
-+ SCM_FLAG_COLDBOOT_CPU2,
-+ SCM_FLAG_COLDBOOT_CPU3,
- };
-
- for_each_present_cpu(cpu) {
-@@ -147,3 +243,13 @@ static struct smp_operations smp_msm8660
- #endif
- };
- CPU_METHOD_OF_DECLARE(qcom_smp, "qcom,gcc-msm8660", &smp_msm8660_ops);
-+
-+static struct smp_operations qcom_smp_kpssv1_ops __initdata = {
-+ .smp_prepare_cpus = qcom_smp_prepare_cpus,
-+ .smp_secondary_init = qcom_secondary_init,
-+ .smp_boot_secondary = kpssv1_boot_secondary,
-+#ifdef CONFIG_HOTPLUG_CPU
-+ .cpu_die = qcom_cpu_die,
-+#endif
-+};
-+CPU_METHOD_OF_DECLARE(qcom_smp_kpssv1, "qcom,kpss-acc-v1", &qcom_smp_kpssv1_ops);
---- a/arch/arm/mach-qcom/scm-boot.h
-+++ b/arch/arm/mach-qcom/scm-boot.h
-@@ -13,9 +13,11 @@
- #define __MACH_SCM_BOOT_H
-
- #define SCM_BOOT_ADDR 0x1
--#define SCM_FLAG_COLDBOOT_CPU1 0x1
--#define SCM_FLAG_WARMBOOT_CPU1 0x2
--#define SCM_FLAG_WARMBOOT_CPU0 0x4
-+#define SCM_FLAG_COLDBOOT_CPU1 0x01
-+#define SCM_FLAG_COLDBOOT_CPU2 0x08
-+#define SCM_FLAG_COLDBOOT_CPU3 0x20
-+#define SCM_FLAG_WARMBOOT_CPU0 0x04
-+#define SCM_FLAG_WARMBOOT_CPU1 0x02
-
- int scm_set_boot_addr(phys_addr_t addr, int flags);
-
diff --git a/target/linux/ipq806x/patches/0014-ARM-qcom-Add-SMP-support-for-KPSSv2.patch b/target/linux/ipq806x/patches/0014-ARM-qcom-Add-SMP-support-for-KPSSv2.patch
deleted file mode 100644
index 8f8ae49..0000000
--- a/target/linux/ipq806x/patches/0014-ARM-qcom-Add-SMP-support-for-KPSSv2.patch
+++ /dev/null
@@ -1,167 +0,0 @@
-From eb07c23d45ddf10fa89296e6c6c6aed553d8bbf5 Mon Sep 17 00:00:00 2001
-From: Rohit Vaswani <rvaswani@codeaurora.org>
-Date: Fri, 21 Jun 2013 17:09:13 -0700
-Subject: [PATCH 014/182] ARM: qcom: Add SMP support for KPSSv2
-
-Implement support for the Krait CPU release sequence when the
-CPUs are part of the second version of the Krait processor
-subsystem.
-
-Signed-off-by: Rohit Vaswani <rvaswani@codeaurora.org>
-Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
-Signed-off-by: Kumar Gala <galak@codeaurora.org>
----
- arch/arm/mach-qcom/platsmp.c | 123 ++++++++++++++++++++++++++++++++++++++++++
- 1 file changed, 123 insertions(+)
-
---- a/arch/arm/mach-qcom/platsmp.c
-+++ b/arch/arm/mach-qcom/platsmp.c
-@@ -34,7 +34,15 @@
- #define L2DT_SLP BIT(3)
- #define CLAMP BIT(0)
-
-+#define APC_PWR_GATE_CTL 0x14
-+#define BHS_CNT_SHIFT 24
-+#define LDO_PWR_DWN_SHIFT 16
-+#define LDO_BYP_SHIFT 8
-+#define BHS_SEG_SHIFT 1
-+#define BHS_EN BIT(0)
-+
- #define APCS_SAW2_VCTL 0x14
-+#define APCS_SAW2_2_VCTL 0x1c
-
- extern void secondary_startup(void);
-
-@@ -160,6 +168,106 @@ out_acc:
- return ret;
- }
-
-+static int kpssv2_release_secondary(unsigned int cpu)
-+{
-+ void __iomem *reg;
-+ struct device_node *cpu_node, *l2_node, *acc_node, *saw_node;
-+ void __iomem *l2_saw_base;
-+ unsigned reg_val;
-+ int ret;
-+
-+ cpu_node = of_get_cpu_node(cpu, NULL);
-+ if (!cpu_node)
-+ return -ENODEV;
-+
-+ acc_node = of_parse_phandle(cpu_node, "qcom,acc", 0);
-+ if (!acc_node) {
-+ ret = -ENODEV;
-+ goto out_acc;
-+ }
-+
-+ l2_node = of_parse_phandle(cpu_node, "next-level-cache", 0);
-+ if (!l2_node) {
-+ ret = -ENODEV;
-+ goto out_l2;
-+ }
-+
-+ saw_node = of_parse_phandle(l2_node, "qcom,saw", 0);
-+ if (!saw_node) {
-+ ret = -ENODEV;
-+ goto out_saw;
-+ }
-+
-+ reg = of_iomap(acc_node, 0);
-+ if (!reg) {
-+ ret = -ENOMEM;
-+ goto out_map;
-+ }
-+
-+ l2_saw_base = of_iomap(saw_node, 0);
-+ if (!l2_saw_base) {
-+ ret = -ENOMEM;
-+ goto out_saw_map;
-+ }
-+
-+ /* Turn on the BHS, turn off LDO Bypass and power down LDO */
-+ reg_val = (64 << BHS_CNT_SHIFT) | (0x3f << LDO_PWR_DWN_SHIFT) | BHS_EN;
-+ writel_relaxed(reg_val, reg + APC_PWR_GATE_CTL);
-+ mb();
-+ /* wait for the BHS to settle */
-+ udelay(1);
-+
-+ /* Turn on BHS segments */
-+ reg_val |= 0x3f << BHS_SEG_SHIFT;
-+ writel_relaxed(reg_val, reg + APC_PWR_GATE_CTL);
-+ mb();
-+ /* wait for the BHS to settle */
-+ udelay(1);
-+
-+ /* Finally turn on the bypass so that BHS supplies power */
-+ reg_val |= 0x3f << LDO_BYP_SHIFT;
-+ writel_relaxed(reg_val, reg + APC_PWR_GATE_CTL);
-+
-+ /* enable max phases */
-+ writel_relaxed(0x10003, l2_saw_base + APCS_SAW2_2_VCTL);
-+ mb();
-+ udelay(50);
-+
-+ reg_val = COREPOR_RST | CLAMP;
-+ writel_relaxed(reg_val, reg + APCS_CPU_PWR_CTL);
-+ mb();
-+ udelay(2);
-+
-+ reg_val &= ~CLAMP;
-+ writel_relaxed(reg_val, reg + APCS_CPU_PWR_CTL);
-+ mb();
-+ udelay(2);
-+
-+ reg_val &= ~COREPOR_RST;
-+ writel_relaxed(reg_val, reg + APCS_CPU_PWR_CTL);
-+ mb();
-+
-+ reg_val |= CORE_PWRD_UP;
-+ writel_relaxed(reg_val, reg + APCS_CPU_PWR_CTL);
-+ mb();
-+
-+ ret = 0;
-+
-+ iounmap(l2_saw_base);
-+out_saw_map:
-+ iounmap(reg);
-+out_map:
-+ of_node_put(saw_node);
-+out_saw:
-+ of_node_put(l2_node);
-+out_l2:
-+ of_node_put(acc_node);
-+out_acc:
-+ of_node_put(cpu_node);
-+
-+ return ret;
-+}
-+
- static DEFINE_PER_CPU(int, cold_boot_done);
-
- static int qcom_boot_secondary(unsigned int cpu, int (*func)(unsigned int))
-@@ -204,6 +312,11 @@ static int kpssv1_boot_secondary(unsigne
- return qcom_boot_secondary(cpu, kpssv1_release_secondary);
- }
-
-+static int kpssv2_boot_secondary(unsigned int cpu, struct task_struct *idle)
-+{
-+ return qcom_boot_secondary(cpu, kpssv2_release_secondary);
-+}
-+
- static void __init qcom_smp_prepare_cpus(unsigned int max_cpus)
- {
- int cpu, map;
-@@ -253,3 +366,13 @@ static struct smp_operations qcom_smp_kp
- #endif
- };
- CPU_METHOD_OF_DECLARE(qcom_smp_kpssv1, "qcom,kpss-acc-v1", &qcom_smp_kpssv1_ops);
-+
-+static struct smp_operations qcom_smp_kpssv2_ops __initdata = {
-+ .smp_prepare_cpus = qcom_smp_prepare_cpus,
-+ .smp_secondary_init = qcom_secondary_init,
-+ .smp_boot_secondary = kpssv2_boot_secondary,
-+#ifdef CONFIG_HOTPLUG_CPU
-+ .cpu_die = qcom_cpu_die,
-+#endif
-+};
-+CPU_METHOD_OF_DECLARE(qcom_smp_kpssv2, "qcom,kpss-acc-v2", &qcom_smp_kpssv2_ops);
diff --git a/target/linux/ipq806x/patches/0015-tty-serial-msm-Enable-building-msm_serial-for-ARCH_Q.patch b/target/linux/ipq806x/patches/0015-tty-serial-msm-Enable-building-msm_serial-for-ARCH_Q.patch
deleted file mode 100644
index 33870dc..0000000
--- a/target/linux/ipq806x/patches/0015-tty-serial-msm-Enable-building-msm_serial-for-ARCH_Q.patch
+++ /dev/null
@@ -1,27 +0,0 @@
-From 17368813d4182894c6d58b66f9fccd339364de8f Mon Sep 17 00:00:00 2001
-From: Kumar Gala <galak@codeaurora.org>
-Date: Wed, 29 Jan 2014 17:23:06 -0600
-Subject: [PATCH 015/182] tty: serial: msm: Enable building msm_serial for
- ARCH_QCOM
-
-We've split Qualcomm MSM support into legacy and multiplatform. So add
-the ability to build the serial driver on the newer ARCH_QCOM
-multiplatform.
-
-Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-Signed-off-by: Kumar Gala <galak@codeaurora.org>
----
- drivers/tty/serial/Kconfig | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/drivers/tty/serial/Kconfig
-+++ b/drivers/tty/serial/Kconfig
-@@ -1024,7 +1024,7 @@ config SERIAL_SGI_IOC3
-
- config SERIAL_MSM
- bool "MSM on-chip serial port support"
-- depends on ARCH_MSM
-+ depends on ARCH_MSM || ARCH_QCOM
- select SERIAL_CORE
-
- config SERIAL_MSM_CONSOLE
diff --git a/target/linux/ipq806x/patches/0016-drm-msm-drop-ARCH_MSM-Kconfig-depend.patch b/target/linux/ipq806x/patches/0016-drm-msm-drop-ARCH_MSM-Kconfig-depend.patch
deleted file mode 100644
index b80ad91..0000000
--- a/target/linux/ipq806x/patches/0016-drm-msm-drop-ARCH_MSM-Kconfig-depend.patch
+++ /dev/null
@@ -1,28 +0,0 @@
-From aa3cf89746c43172517378224277ba961c46e28c Mon Sep 17 00:00:00 2001
-From: Kumar Gala <galak@codeaurora.org>
-Date: Thu, 30 Jan 2014 14:45:05 -0600
-Subject: [PATCH 016/182] drm/msm: drop ARCH_MSM Kconfig depend
-
-The ARCH_MSM depend is redundant with ARCH_MSM8960, so we can remove it.
-Additionally, we are splitting Qualcomm MSM support into legacy (ARCH_MSM)
-and multiplatform (ARCH_QCOM). The MSM8960 with be ARCH_QCOM going forward
-so dropping ARCH_MSM will work properly for the new ARCH_QCOM multiplatform
-build.
-
-Acked-by: Rob Clark <robdclark@gmail.com>
-Signed-off-by: Kumar Gala <galak@codeaurora.org>
----
- drivers/gpu/drm/msm/Kconfig | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/drivers/gpu/drm/msm/Kconfig
-+++ b/drivers/gpu/drm/msm/Kconfig
-@@ -3,7 +3,7 @@ config DRM_MSM
- tristate "MSM DRM"
- depends on DRM
- depends on MSM_IOMMU
-- depends on (ARCH_MSM && ARCH_MSM8960) || (ARM && COMPILE_TEST)
-+ depends on ARCH_MSM8960 || (ARM && COMPILE_TEST)
- select DRM_KMS_HELPER
- select SHMEM
- select TMPFS
diff --git a/target/linux/ipq806x/patches/0017-power-reset-msm-switch-Kconfig-to-ARCH_QCOM-depends.patch b/target/linux/ipq806x/patches/0017-power-reset-msm-switch-Kconfig-to-ARCH_QCOM-depends.patch
deleted file mode 100644
index cf33efd..0000000
--- a/target/linux/ipq806x/patches/0017-power-reset-msm-switch-Kconfig-to-ARCH_QCOM-depends.patch
+++ /dev/null
@@ -1,27 +0,0 @@
-From 6e8707828be07397ee8ee437a6ef1b8f73f82287 Mon Sep 17 00:00:00 2001
-From: Kumar Gala <galak@codeaurora.org>
-Date: Thu, 30 Jan 2014 14:46:08 -0600
-Subject: [PATCH 017/182] power: reset: msm - switch Kconfig to ARCH_QCOM
- depends
-
-We've split Qualcomm MSM support into legacy and multiplatform. The reset
-driver is only relevant on the multiplatform supported SoCs so switch the
-Kconfig depends to ARCH_QCOM.
-
-Acked-by: Dmitry Eremin-Solenikov
-Signed-off-by: Kumar Gala <galak@codeaurora.org>
----
- drivers/power/reset/Kconfig | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/drivers/power/reset/Kconfig
-+++ b/drivers/power/reset/Kconfig
-@@ -22,7 +22,7 @@ config POWER_RESET_GPIO
-
- config POWER_RESET_MSM
- bool "Qualcomm MSM power-off driver"
-- depends on POWER_RESET && ARCH_MSM
-+ depends on POWER_RESET && ARCH_QCOM
- help
- Power off and restart support for Qualcomm boards.
-
diff --git a/target/linux/ipq806x/patches/0018-hwrng-msm-switch-Kconfig-to-ARCH_QCOM-depends.patch b/target/linux/ipq806x/patches/0018-hwrng-msm-switch-Kconfig-to-ARCH_QCOM-depends.patch
deleted file mode 100644
index 89cb8ac..0000000
--- a/target/linux/ipq806x/patches/0018-hwrng-msm-switch-Kconfig-to-ARCH_QCOM-depends.patch
+++ /dev/null
@@ -1,33 +0,0 @@
-From 4aa784548190c69d946b4dfbc0592a3ed7cd18da Mon Sep 17 00:00:00 2001
-From: Kumar Gala <galak@codeaurora.org>
-Date: Thu, 30 Jan 2014 14:43:49 -0600
-Subject: [PATCH 018/182] hwrng: msm: switch Kconfig to ARCH_QCOM depends
-
-We've split Qualcomm MSM support into legacy and multiplatform. The RNG
-driver is only relevant on the multiplatform supported SoCs so switch the
-Kconfig depends to ARCH_QCOM.
-
-Acked-by: Herbert Xu <herbert@gondor.apana.org.au>
-CC: Stanimir Varbanov <svarbanov@mm-sol.com>
-Signed-off-by: Kumar Gala <galak@codeaurora.org>
----
- drivers/char/hw_random/Kconfig | 6 +++---
- 1 file changed, 3 insertions(+), 3 deletions(-)
-
---- a/drivers/char/hw_random/Kconfig
-+++ b/drivers/char/hw_random/Kconfig
-@@ -342,11 +342,11 @@ config HW_RANDOM_TPM
- If unsure, say Y.
-
- config HW_RANDOM_MSM
-- tristate "Qualcomm MSM Random Number Generator support"
-- depends on HW_RANDOM && ARCH_MSM
-+ tristate "Qualcomm SoCs Random Number Generator support"
-+ depends on HW_RANDOM && ARCH_QCOM
- ---help---
- This driver provides kernel-side support for the Random Number
-- Generator hardware found on Qualcomm MSM SoCs.
-+ Generator hardware found on Qualcomm SoCs.
-
- To compile this driver as a module, choose M here. the
- module will be called msm-rng.
diff --git a/target/linux/ipq806x/patches/0019-gpio-msm-switch-Kconfig-to-ARCH_QCOM-depends.patch b/target/linux/ipq806x/patches/0019-gpio-msm-switch-Kconfig-to-ARCH_QCOM-depends.patch
deleted file mode 100644
index 1ead84b..0000000
--- a/target/linux/ipq806x/patches/0019-gpio-msm-switch-Kconfig-to-ARCH_QCOM-depends.patch
+++ /dev/null
@@ -1,27 +0,0 @@
-From 87d52cc8a390c5b208b6f0bddd90a2d01c906616 Mon Sep 17 00:00:00 2001
-From: Kumar Gala <galak@codeaurora.org>
-Date: Tue, 11 Feb 2014 14:08:06 -0600
-Subject: [PATCH 019/182] gpio: msm: switch Kconfig to ARCH_QCOM depends
-
-We've split Qualcomm MSM support into legacy and multiplatform. The gpio
-msm-v2 driver is only relevant on the multiplatform supported SoCs so
-switch the Kconfig depends to ARCH_QCOM.
-
-CC: Linus Walleij <linus.walleij@linaro.org>
-Acked-by: Alexandre Courbot <gnurou@gmail.com>
-Signed-off-by: Kumar Gala <galak@codeaurora.org>
----
- drivers/gpio/Kconfig | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/drivers/gpio/Kconfig
-+++ b/drivers/gpio/Kconfig
-@@ -192,7 +192,7 @@ config GPIO_MSM_V1
-
- config GPIO_MSM_V2
- tristate "Qualcomm MSM GPIO v2"
-- depends on GPIOLIB && OF && ARCH_MSM
-+ depends on GPIOLIB && OF && ARCH_QCOM
- help
- Say yes here to support the GPIO interface on ARM v7 based
- Qualcomm MSM chips. Most of the pins on the MSM can be
diff --git a/target/linux/ipq806x/patches/002-v3-spi-qup-Fix-incorrect-block-transfers.patch b/target/linux/ipq806x/patches/002-v3-spi-qup-Fix-incorrect-block-transfers.patch
new file mode 100644
index 0000000..62ee5b4
--- /dev/null
+++ b/target/linux/ipq806x/patches/002-v3-spi-qup-Fix-incorrect-block-transfers.patch
@@ -0,0 +1,376 @@
+Content-Type: text/plain; charset="utf-8"
+MIME-Version: 1.0
+Content-Transfer-Encoding: 7bit
+Subject: [v3] spi: qup: Fix incorrect block transfers
+From: Andy Gross <agross@codeaurora.org>
+X-Patchwork-Id: 5007321
+Message-Id: <1412112088-25928-1-git-send-email-agross@codeaurora.org>
+To: Mark Brown <broonie@kernel.org>
+Cc: linux-spi@vger.kernel.org, linux-kernel@vger.kernel.org,
+ linux-arm-kernel@lists.infradead.org, linux-arm-msm@vger.kernel.org,
+ "Ivan T. Ivanov" <iivanov@mm-sol.com>,
+ Bjorn Andersson <bjorn.andersson@sonymobile.com>,
+ Kumar Gala <galak@codeaurora.org>, Andy Gross <agross@codeaurora.org>
+Date: Tue, 30 Sep 2014 16:21:28 -0500
+
+This patch fixes a number of errors with the QUP block transfer mode. Errors
+manifested themselves as input underruns, output overruns, and timed out
+transactions.
+
+The block mode does not require the priming that occurs in FIFO mode. At the
+moment that the QUP is placed into the RUN state, the QUP will immediately raise
+an interrupt if the request is a write. Therefore, there is no need to prime
+the pump.
+
+In addition, the block transfers require that whole blocks of data are
+read/written at a time. The last block of data that completes a transaction may
+contain less than a full blocks worth of data.
+
+Each block of data results in an input/output service interrupt accompanied with
+a input/output block flag set. Additional block reads/writes require clearing
+of the service flag. It is ok to check for additional blocks of data in the
+ISR, but you have to ack every block you transfer. Imbalanced acks result in
+early return from complete transactions with pending interrupts that still have
+to be ack'd. The next transaction can be affected by these interrupts.
+Transactions are deemed complete when the MAX_INPUT or MAX_OUTPUT flag are set.
+
+Changes from v2:
+- Added in additional completion check so that transaction done is not
+ prematurely signaled.
+- Fixed various review comments.
+
+Changes from v1:
+- Split out read/write block function.
+- Removed extraneous checks for transfer length
+
+Signed-off-by: Andy Gross <agross@codeaurora.org>
+
+---
+drivers/spi/spi-qup.c | 201 ++++++++++++++++++++++++++++++++++++-------------
+ 1 file changed, 148 insertions(+), 53 deletions(-)
+
+--- a/drivers/spi/spi-qup.c
++++ b/drivers/spi/spi-qup.c
+@@ -82,6 +82,8 @@
+ #define QUP_IO_M_MODE_BAM 3
+
+ /* QUP_OPERATIONAL fields */
++#define QUP_OP_IN_BLOCK_READ_REQ BIT(13)
++#define QUP_OP_OUT_BLOCK_WRITE_REQ BIT(12)
+ #define QUP_OP_MAX_INPUT_DONE_FLAG BIT(11)
+ #define QUP_OP_MAX_OUTPUT_DONE_FLAG BIT(10)
+ #define QUP_OP_IN_SERVICE_FLAG BIT(9)
+@@ -147,6 +149,7 @@ struct spi_qup {
+ int tx_bytes;
+ int rx_bytes;
+ int qup_v1;
++ int mode;
+
+ int use_dma;
+
+@@ -213,30 +216,14 @@ static int spi_qup_set_state(struct spi_
+ return 0;
+ }
+
+-
+-static void spi_qup_fifo_read(struct spi_qup *controller,
+- struct spi_transfer *xfer)
++static void spi_qup_fill_read_buffer(struct spi_qup *controller,
++ struct spi_transfer *xfer, u32 data)
+ {
+ u8 *rx_buf = xfer->rx_buf;
+- u32 word, state;
+- int idx, shift, w_size;
+-
+- w_size = controller->w_size;
+-
+- while (controller->rx_bytes < xfer->len) {
+-
+- state = readl_relaxed(controller->base + QUP_OPERATIONAL);
+- if (0 == (state & QUP_OP_IN_FIFO_NOT_EMPTY))
+- break;
+-
+- word = readl_relaxed(controller->base + QUP_INPUT_FIFO);
+-
+- if (!rx_buf) {
+- controller->rx_bytes += w_size;
+- continue;
+- }
++ int idx, shift;
+
+- for (idx = 0; idx < w_size; idx++, controller->rx_bytes++) {
++ if (rx_buf)
++ for (idx = 0; idx < controller->w_size; idx++) {
+ /*
+ * The data format depends on bytes per SPI word:
+ * 4 bytes: 0x12345678
+@@ -244,41 +231,139 @@ static void spi_qup_fifo_read(struct spi
+ * 1 byte : 0x00000012
+ */
+ shift = BITS_PER_BYTE;
+- shift *= (w_size - idx - 1);
+- rx_buf[controller->rx_bytes] = word >> shift;
++ shift *= (controller->w_size - idx - 1);
++ rx_buf[controller->rx_bytes + idx] = data >> shift;
++ }
++
++ controller->rx_bytes += controller->w_size;
++}
++
++static void spi_qup_prepare_write_data(struct spi_qup *controller,
++ struct spi_transfer *xfer, u32 *data)
++{
++ const u8 *tx_buf = xfer->tx_buf;
++ u32 val;
++ int idx;
++
++ *data = 0;
++
++ if (tx_buf)
++ for (idx = 0; idx < controller->w_size; idx++) {
++ val = tx_buf[controller->tx_bytes + idx];
++ *data |= val << (BITS_PER_BYTE * (3 - idx));
+ }
++
++ controller->tx_bytes += controller->w_size;
++}
++
++static void spi_qup_fifo_read(struct spi_qup *controller,
++ struct spi_transfer *xfer)
++{
++ u32 data;
++
++ /* clear service request */
++ writel_relaxed(QUP_OP_IN_SERVICE_FLAG,
++ controller->base + QUP_OPERATIONAL);
++
++ while (controller->rx_bytes < xfer->len) {
++ if (!(readl_relaxed(controller->base + QUP_OPERATIONAL) &
++ QUP_OP_IN_FIFO_NOT_EMPTY))
++ break;
++
++ data = readl_relaxed(controller->base + QUP_INPUT_FIFO);
++
++ spi_qup_fill_read_buffer(controller, xfer, data);
+ }
+ }
+
+ static void spi_qup_fifo_write(struct spi_qup *controller,
+- struct spi_transfer *xfer)
++ struct spi_transfer *xfer)
+ {
+- const u8 *tx_buf = xfer->tx_buf;
+- u32 word, state, data;
+- int idx, w_size;
++ u32 data;
+
+- w_size = controller->w_size;
++ /* clear service request */
++ writel_relaxed(QUP_OP_OUT_SERVICE_FLAG,
++ controller->base + QUP_OPERATIONAL);
+
+ while (controller->tx_bytes < xfer->len) {
+
+- state = readl_relaxed(controller->base + QUP_OPERATIONAL);
+- if (state & QUP_OP_OUT_FIFO_FULL)
++ if (readl_relaxed(controller->base + QUP_OPERATIONAL) &
++ QUP_OP_OUT_FIFO_FULL)
+ break;
+
+- word = 0;
+- for (idx = 0; idx < w_size; idx++, controller->tx_bytes++) {
++ spi_qup_prepare_write_data(controller, xfer, &data);
++ writel_relaxed(data, controller->base + QUP_OUTPUT_FIFO);
+
+- if (!tx_buf) {
+- controller->tx_bytes += w_size;
+- break;
+- }
++ }
++}
+
+- data = tx_buf[controller->tx_bytes];
+- word |= data << (BITS_PER_BYTE * (3 - idx));
+- }
++static void spi_qup_block_read(struct spi_qup *controller,
++ struct spi_transfer *xfer)
++{
++ u32 data;
++ u32 reads_per_blk = controller->in_blk_sz >> 2;
++ u32 num_words = (xfer->len - controller->rx_bytes) / controller->w_size;
++ int i;
++
++ do {
++ /* ACK by clearing service flag */
++ writel_relaxed(QUP_OP_IN_SERVICE_FLAG,
++ controller->base + QUP_OPERATIONAL);
++
++ /* transfer up to a block size of data in a single pass */
++ for (i = 0; num_words && i < reads_per_blk; i++, num_words--) {
++
++ /* read data and fill up rx buffer */
++ data = readl_relaxed(controller->base + QUP_INPUT_FIFO);
++ spi_qup_fill_read_buffer(controller, xfer, data);
++ }
++
++ /* check to see if next block is ready */
++ if (!(readl_relaxed(controller->base + QUP_OPERATIONAL) &
++ QUP_OP_IN_BLOCK_READ_REQ))
++ break;
+
+- writel_relaxed(word, controller->base + QUP_OUTPUT_FIFO);
+- }
++ } while (num_words);
++
++ /*
++ * Due to extra stickiness of the QUP_OP_IN_SERVICE_FLAG during block
++ * reads, it has to be cleared again at the very end
++ */
++ if (readl_relaxed(controller->base + QUP_OPERATIONAL) &
++ QUP_OP_MAX_INPUT_DONE_FLAG)
++ writel_relaxed(QUP_OP_IN_SERVICE_FLAG,
++ controller->base + QUP_OPERATIONAL);
++
++}
++
++static void spi_qup_block_write(struct spi_qup *controller,
++ struct spi_transfer *xfer)
++{
++ u32 data;
++ u32 writes_per_blk = controller->out_blk_sz >> 2;
++ u32 num_words = (xfer->len - controller->tx_bytes) / controller->w_size;
++ int i;
++
++ do {
++ /* ACK by clearing service flag */
++ writel_relaxed(QUP_OP_OUT_SERVICE_FLAG,
++ controller->base + QUP_OPERATIONAL);
++
++ /* transfer up to a block size of data in a single pass */
++ for (i = 0; num_words && i < writes_per_blk; i++, num_words--) {
++
++ /* swizzle the bytes for output and write out */
++ spi_qup_prepare_write_data(controller, xfer, &data);
++ writel_relaxed(data,
++ controller->base + QUP_OUTPUT_FIFO);
++ }
++
++ /* check to see if next block is ready */
++ if (!(readl_relaxed(controller->base + QUP_OPERATIONAL) &
++ QUP_OP_OUT_BLOCK_WRITE_REQ))
++ break;
++
++ } while (num_words);
+ }
+
+ static void qup_dma_callback(void *data)
+@@ -515,9 +600,9 @@ static irqreturn_t spi_qup_qup_irq(int i
+
+ writel_relaxed(qup_err, controller->base + QUP_ERROR_FLAGS);
+ writel_relaxed(spi_err, controller->base + SPI_ERROR_FLAGS);
+- writel_relaxed(opflags, controller->base + QUP_OPERATIONAL);
+
+ if (!xfer) {
++ writel_relaxed(opflags, controller->base + QUP_OPERATIONAL);
+ dev_err_ratelimited(controller->dev, "unexpected irq %08x %08x %08x\n",
+ qup_err, spi_err, opflags);
+ return IRQ_HANDLED;
+@@ -546,11 +631,19 @@ static irqreturn_t spi_qup_qup_irq(int i
+ }
+
+ if (!controller->use_dma) {
+- if (opflags & QUP_OP_IN_SERVICE_FLAG)
+- spi_qup_fifo_read(controller, xfer);
++ if (opflags & QUP_OP_IN_SERVICE_FLAG) {
++ if (opflags & QUP_OP_IN_BLOCK_READ_REQ)
++ spi_qup_block_read(controller, xfer);
++ else
++ spi_qup_fifo_read(controller, xfer);
++ }
+
+- if (opflags & QUP_OP_OUT_SERVICE_FLAG)
+- spi_qup_fifo_write(controller, xfer);
++ if (opflags & QUP_OP_OUT_SERVICE_FLAG) {
++ if (opflags & QUP_OP_OUT_BLOCK_WRITE_REQ)
++ spi_qup_block_write(controller, xfer);
++ else
++ spi_qup_fifo_write(controller, xfer);
++ }
+ }
+
+ spin_lock_irqsave(&controller->lock, flags);
+@@ -558,7 +651,8 @@ static irqreturn_t spi_qup_qup_irq(int i
+ controller->xfer = xfer;
+ spin_unlock_irqrestore(&controller->lock, flags);
+
+- if (controller->rx_bytes == xfer->len || error)
++ if ((controller->rx_bytes == xfer->len &&
++ (opflags & QUP_OP_MAX_INPUT_DONE_FLAG)) || error)
+ complete(&controller->done);
+
+ return IRQ_HANDLED;
+@@ -569,7 +663,7 @@ static irqreturn_t spi_qup_qup_irq(int i
+ static int spi_qup_io_config(struct spi_device *spi, struct spi_transfer *xfer)
+ {
+ struct spi_qup *controller = spi_master_get_devdata(spi->master);
+- u32 config, iomode, mode;
++ u32 config, iomode;
+ int ret, n_words, w_size;
+ size_t dma_align = dma_get_cache_alignment();
+ u32 dma_available = 0;
+@@ -607,7 +701,7 @@ static int spi_qup_io_config(struct spi_
+ dma_available = 1;
+
+ if (n_words <= (controller->in_fifo_sz / sizeof(u32))) {
+- mode = QUP_IO_M_MODE_FIFO;
++ controller->mode = QUP_IO_M_MODE_FIFO;
+ writel_relaxed(n_words, controller->base + QUP_MX_READ_CNT);
+ writel_relaxed(n_words, controller->base + QUP_MX_WRITE_CNT);
+ /* must be zero for FIFO */
+@@ -615,7 +709,7 @@ static int spi_qup_io_config(struct spi_
+ writel_relaxed(0, controller->base + QUP_MX_OUTPUT_CNT);
+ controller->use_dma = 0;
+ } else if (!dma_available) {
+- mode = QUP_IO_M_MODE_BLOCK;
++ controller->mode = QUP_IO_M_MODE_BLOCK;
+ writel_relaxed(n_words, controller->base + QUP_MX_INPUT_CNT);
+ writel_relaxed(n_words, controller->base + QUP_MX_OUTPUT_CNT);
+ /* must be zero for BLOCK and BAM */
+@@ -623,7 +717,7 @@ static int spi_qup_io_config(struct spi_
+ writel_relaxed(0, controller->base + QUP_MX_WRITE_CNT);
+ controller->use_dma = 0;
+ } else {
+- mode = QUP_IO_M_MODE_DMOV;
++ controller->mode = QUP_IO_M_MODE_DMOV;
+ writel_relaxed(0, controller->base + QUP_MX_READ_CNT);
+ writel_relaxed(0, controller->base + QUP_MX_WRITE_CNT);
+ controller->use_dma = 1;
+@@ -638,8 +732,8 @@ static int spi_qup_io_config(struct spi_
+ else
+ iomode |= QUP_IO_M_PACK_EN | QUP_IO_M_UNPACK_EN;
+
+- iomode |= (mode << QUP_IO_M_OUTPUT_MODE_MASK_SHIFT);
+- iomode |= (mode << QUP_IO_M_INPUT_MODE_MASK_SHIFT);
++ iomode |= (controller->mode << QUP_IO_M_OUTPUT_MODE_MASK_SHIFT);
++ iomode |= (controller->mode << QUP_IO_M_INPUT_MODE_MASK_SHIFT);
+
+ writel_relaxed(iomode, controller->base + QUP_IO_M_MODES);
+
+@@ -724,7 +818,8 @@ static int spi_qup_transfer_one(struct s
+ goto exit;
+ }
+
+- spi_qup_fifo_write(controller, xfer);
++ if (controller->mode == QUP_IO_M_MODE_FIFO)
++ spi_qup_fifo_write(controller, xfer);
+
+ if (spi_qup_set_state(controller, QUP_STATE_RUN)) {
+ dev_warn(controller->dev, "cannot set EXECUTE state\n");
+@@ -741,6 +836,7 @@ exit:
+ if (!ret)
+ ret = controller->error;
+ spin_unlock_irqrestore(&controller->lock, flags);
++
+ return ret;
+ }
+
diff --git a/target/linux/ipq806x/patches/0020-ARM-qcom-Enable-basic-support-for-Qualcomm-platforms.patch b/target/linux/ipq806x/patches/0020-ARM-qcom-Enable-basic-support-for-Qualcomm-platforms.patch
deleted file mode 100644
index 7c1cb29..0000000
--- a/target/linux/ipq806x/patches/0020-ARM-qcom-Enable-basic-support-for-Qualcomm-platforms.patch
+++ /dev/null
@@ -1,49 +0,0 @@
-From a2f356a6d49f459a2dd681fe4a7c6a55aeb8893f Mon Sep 17 00:00:00 2001
-From: Kumar Gala <galak@codeaurora.org>
-Date: Tue, 25 Feb 2014 14:34:05 -0600
-Subject: [PATCH 020/182] ARM: qcom: Enable basic support for Qualcomm
- platforms in multi_v7_defconfig
-
-Enable support for the MSM8x60, MSM8960, and MSM8974 SoCs, clocks and
-serial console as part of the standard multi_v7_defconfig.
-
-Signed-off-by: Kumar Gala <galak@codeaurora.org>
-[khilman: removed non-qcom changes]
-Signed-off-by: Kevin Hilman <khilman@linaro.org>
----
- arch/arm/configs/multi_v7_defconfig | 10 ++++++++++
- 1 file changed, 10 insertions(+)
-
---- a/arch/arm/configs/multi_v7_defconfig
-+++ b/arch/arm/configs/multi_v7_defconfig
-@@ -31,6 +31,10 @@ CONFIG_SOC_OMAP5=y
- CONFIG_SOC_AM33XX=y
- CONFIG_SOC_DRA7XX=y
- CONFIG_SOC_AM43XX=y
-+CONFIG_ARCH_QCOM=y
-+CONFIG_ARCH_MSM8X60=y
-+CONFIG_ARCH_MSM8960=y
-+CONFIG_ARCH_MSM8974=y
- CONFIG_ARCH_ROCKCHIP=y
- CONFIG_ARCH_SOCFPGA=y
- CONFIG_PLAT_SPEAR=y
-@@ -146,6 +150,8 @@ CONFIG_SERIAL_SIRFSOC_CONSOLE=y
- CONFIG_SERIAL_TEGRA=y
- CONFIG_SERIAL_IMX=y
- CONFIG_SERIAL_IMX_CONSOLE=y
-+CONFIG_SERIAL_MSM=y
-+CONFIG_SERIAL_MSM_CONSOLE=y
- CONFIG_SERIAL_VT8500=y
- CONFIG_SERIAL_VT8500_CONSOLE=y
- CONFIG_SERIAL_OF_PLATFORM=y
-@@ -294,6 +300,10 @@ CONFIG_MFD_NVEC=y
- CONFIG_KEYBOARD_NVEC=y
- CONFIG_SERIO_NVEC_PS2=y
- CONFIG_NVEC_POWER=y
-+CONFIG_COMMON_CLK_QCOM=y
-+CONFIG_MSM_GCC_8660=y
-+CONFIG_MSM_MMCC_8960=y
-+CONFIG_MSM_MMCC_8974=y
- CONFIG_TEGRA_IOMMU_GART=y
- CONFIG_TEGRA_IOMMU_SMMU=y
- CONFIG_MEMORY=y
diff --git a/target/linux/ipq806x/patches/0021-ARM-dts-qcom-Add-nodes-necessary-for-SMP-boot.patch b/target/linux/ipq806x/patches/0021-ARM-dts-qcom-Add-nodes-necessary-for-SMP-boot.patch
deleted file mode 100644
index 232f2ef..0000000
--- a/target/linux/ipq806x/patches/0021-ARM-dts-qcom-Add-nodes-necessary-for-SMP-boot.patch
+++ /dev/null
@@ -1,205 +0,0 @@
-From 5a054211d9380cef5a09da7c5e815c827f330a96 Mon Sep 17 00:00:00 2001
-From: Rohit Vaswani <rvaswani@codeaurora.org>
-Date: Fri, 1 Nov 2013 10:10:40 -0700
-Subject: [PATCH 021/182] ARM: dts: qcom: Add nodes necessary for SMP boot
-
-Add the necessary nodes to support SMP on MSM8660, MSM8960, and
-MSM8974/APQ8074. While we're here also add in the error
-interrupts for the Krait cache error detection.
-
-Signed-off-by: Rohit Vaswani <rvaswani@codeaurora.org>
-[sboyd: Split into separate patch, add error interrupts]
-Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
-Signed-off-by: Kumar Gala <galak@codeaurora.org>
----
- arch/arm/boot/dts/qcom-msm8660.dtsi | 24 ++++++++++++
- arch/arm/boot/dts/qcom-msm8960.dtsi | 52 ++++++++++++++++++++++++++
- arch/arm/boot/dts/qcom-msm8974.dtsi | 69 +++++++++++++++++++++++++++++++++++
- 3 files changed, 145 insertions(+)
-
---- a/arch/arm/boot/dts/qcom-msm8660.dtsi
-+++ b/arch/arm/boot/dts/qcom-msm8660.dtsi
-@@ -9,6 +9,30 @@
- compatible = "qcom,msm8660";
- interrupt-parent = <&intc>;
-
-+ cpus {
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+ compatible = "qcom,scorpion";
-+ enable-method = "qcom,gcc-msm8660";
-+
-+ cpu@0 {
-+ device_type = "cpu";
-+ reg = <0>;
-+ next-level-cache = <&L2>;
-+ };
-+
-+ cpu@1 {
-+ device_type = "cpu";
-+ reg = <1>;
-+ next-level-cache = <&L2>;
-+ };
-+
-+ L2: l2-cache {
-+ compatible = "cache";
-+ cache-level = <2>;
-+ };
-+ };
-+
- intc: interrupt-controller@2080000 {
- compatible = "qcom,msm-8660-qgic";
- interrupt-controller;
---- a/arch/arm/boot/dts/qcom-msm8960.dtsi
-+++ b/arch/arm/boot/dts/qcom-msm8960.dtsi
-@@ -9,6 +9,36 @@
- compatible = "qcom,msm8960";
- interrupt-parent = <&intc>;
-
-+ cpus {
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+ interrupts = <1 14 0x304>;
-+ compatible = "qcom,krait";
-+ enable-method = "qcom,kpss-acc-v1";
-+
-+ cpu@0 {
-+ device_type = "cpu";
-+ reg = <0>;
-+ next-level-cache = <&L2>;
-+ qcom,acc = <&acc0>;
-+ qcom,saw = <&saw0>;
-+ };
-+
-+ cpu@1 {
-+ device_type = "cpu";
-+ reg = <1>;
-+ next-level-cache = <&L2>;
-+ qcom,acc = <&acc1>;
-+ qcom,saw = <&saw1>;
-+ };
-+
-+ L2: l2-cache {
-+ compatible = "cache";
-+ cache-level = <2>;
-+ interrupts = <0 2 0x4>;
-+ };
-+ };
-+
- intc: interrupt-controller@2000000 {
- compatible = "qcom,msm-qgic2";
- interrupt-controller;
-@@ -53,6 +83,28 @@
- #reset-cells = <1>;
- };
-
-+ acc0: clock-controller@2088000 {
-+ compatible = "qcom,kpss-acc-v1";
-+ reg = <0x02088000 0x1000>, <0x02008000 0x1000>;
-+ };
-+
-+ acc1: clock-controller@2098000 {
-+ compatible = "qcom,kpss-acc-v1";
-+ reg = <0x02098000 0x1000>, <0x02008000 0x1000>;
-+ };
-+
-+ saw0: regulator@2089000 {
-+ compatible = "qcom,saw2";
-+ reg = <0x02089000 0x1000>, <0x02009000 0x1000>;
-+ regulator;
-+ };
-+
-+ saw1: regulator@2099000 {
-+ compatible = "qcom,saw2";
-+ reg = <0x02099000 0x1000>, <0x02009000 0x1000>;
-+ regulator;
-+ };
-+
- serial@16440000 {
- compatible = "qcom,msm-uartdm-v1.3", "qcom,msm-uartdm";
- reg = <0x16440000 0x1000>,
---- a/arch/arm/boot/dts/qcom-msm8974.dtsi
-+++ b/arch/arm/boot/dts/qcom-msm8974.dtsi
-@@ -9,6 +9,49 @@
- compatible = "qcom,msm8974";
- interrupt-parent = <&intc>;
-
-+ cpus {
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+ interrupts = <1 9 0xf04>;
-+ compatible = "qcom,krait";
-+ enable-method = "qcom,kpss-acc-v2";
-+
-+ cpu@0 {
-+ device_type = "cpu";
-+ reg = <0>;
-+ next-level-cache = <&L2>;
-+ qcom,acc = <&acc0>;
-+ };
-+
-+ cpu@1 {
-+ device_type = "cpu";
-+ reg = <1>;
-+ next-level-cache = <&L2>;
-+ qcom,acc = <&acc1>;
-+ };
-+
-+ cpu@2 {
-+ device_type = "cpu";
-+ reg = <2>;
-+ next-level-cache = <&L2>;
-+ qcom,acc = <&acc2>;
-+ };
-+
-+ cpu@3 {
-+ device_type = "cpu";
-+ reg = <3>;
-+ next-level-cache = <&L2>;
-+ qcom,acc = <&acc3>;
-+ };
-+
-+ L2: l2-cache {
-+ compatible = "cache";
-+ cache-level = <2>;
-+ interrupts = <0 2 0x4>;
-+ qcom,saw = <&saw_l2>;
-+ };
-+ };
-+
- soc: soc {
- #address-cells = <1>;
- #size-cells = <1>;
-@@ -91,6 +134,32 @@
- };
- };
-
-+ saw_l2: regulator@f9012000 {
-+ compatible = "qcom,saw2";
-+ reg = <0xf9012000 0x1000>;
-+ regulator;
-+ };
-+
-+ acc0: clock-controller@f9088000 {
-+ compatible = "qcom,kpss-acc-v2";
-+ reg = <0xf9088000 0x1000>, <0xf9008000 0x1000>;
-+ };
-+
-+ acc1: clock-controller@f9098000 {
-+ compatible = "qcom,kpss-acc-v2";
-+ reg = <0xf9098000 0x1000>, <0xf9008000 0x1000>;
-+ };
-+
-+ acc2: clock-controller@f90a8000 {
-+ compatible = "qcom,kpss-acc-v2";
-+ reg = <0xf90a8000 0x1000>, <0xf9008000 0x1000>;
-+ };
-+
-+ acc3: clock-controller@f90b8000 {
-+ compatible = "qcom,kpss-acc-v2";
-+ reg = <0xf90b8000 0x1000>, <0xf9008000 0x1000>;
-+ };
-+
- restart@fc4ab000 {
- compatible = "qcom,pshold";
- reg = <0xfc4ab000 0x4>;
diff --git a/target/linux/ipq806x/patches/0022-ARM-dts-qcom-Add-RNG-device-tree-node.patch b/target/linux/ipq806x/patches/0022-ARM-dts-qcom-Add-RNG-device-tree-node.patch
deleted file mode 100644
index 76cff02..0000000
--- a/target/linux/ipq806x/patches/0022-ARM-dts-qcom-Add-RNG-device-tree-node.patch
+++ /dev/null
@@ -1,30 +0,0 @@
-From b0f93ef8f790e77049b6149416ef0ba05cce7089 Mon Sep 17 00:00:00 2001
-From: Stanimir Varbanov <svarbanov@mm-sol.com>
-Date: Fri, 7 Feb 2014 11:23:07 +0200
-Subject: [PATCH 022/182] ARM: dts: qcom: Add RNG device tree node
-
-Add the necessary DT node to probe the rng driver on
-msm8974 platforms.
-
-Signed-off-by: Stanimir Varbanov <svarbanov@mm-sol.com>
-Acked-by: Stephen Boyd <sboyd@codeaurora.org>
-Signed-off-by: Kumar Gala <galak@codeaurora.org>
----
- arch/arm/boot/dts/qcom-msm8974.dtsi | 7 +++++++
- 1 file changed, 7 insertions(+)
-
---- a/arch/arm/boot/dts/qcom-msm8974.dtsi
-+++ b/arch/arm/boot/dts/qcom-msm8974.dtsi
-@@ -186,5 +186,12 @@
- clocks = <&gcc GCC_BLSP1_UART2_APPS_CLK>, <&gcc GCC_BLSP1_AHB_CLK>;
- clock-names = "core", "iface";
- };
-+
-+ rng@f9bff000 {
-+ compatible = "qcom,prng";
-+ reg = <0xf9bff000 0x200>;
-+ clocks = <&gcc GCC_PRNG_AHB_CLK>;
-+ clock-names = "core";
-+ };
- };
- };
diff --git a/target/linux/ipq806x/patches/0023-ARM-dts-qcom-msm8960-cdp-Add-RNG-device-tree-node.patch b/target/linux/ipq806x/patches/0023-ARM-dts-qcom-msm8960-cdp-Add-RNG-device-tree-node.patch
deleted file mode 100644
index 36206d4..0000000
--- a/target/linux/ipq806x/patches/0023-ARM-dts-qcom-msm8960-cdp-Add-RNG-device-tree-node.patch
+++ /dev/null
@@ -1,29 +0,0 @@
-From 82bedcd5ad0b3ac8fe78f4be25b2ffa0691d7804 Mon Sep 17 00:00:00 2001
-From: Stanimir Varbanov <svarbanov@mm-sol.com>
-Date: Wed, 19 Feb 2014 16:33:06 +0200
-Subject: [PATCH 023/182] ARM: dts: qcom-msm8960-cdp: Add RNG device tree node
-
-Add the necessary DT node to probe the rng driver on
-msm8960-cdp platform.
-
-Signed-off-by: Stanimir Varbanov <svarbanov@mm-sol.com>
-Tested-by: Stephen Boyd <sboyd@codeaurora.org>
-Signed-off-by: Kumar Gala <galak@codeaurora.org>
----
- arch/arm/boot/dts/qcom-msm8960.dtsi | 7 +++++++
- 1 file changed, 7 insertions(+)
-
---- a/arch/arm/boot/dts/qcom-msm8960.dtsi
-+++ b/arch/arm/boot/dts/qcom-msm8960.dtsi
-@@ -119,4 +119,11 @@
- reg = <0x500000 0x1000>;
- qcom,controller-type = "pmic-arbiter";
- };
-+
-+ rng@1a500000 {
-+ compatible = "qcom,prng";
-+ reg = <0x1a500000 0x200>;
-+ clocks = <&gcc PRNG_CLK>;
-+ clock-names = "core";
-+ };
- };
diff --git a/target/linux/ipq806x/patches/0024-ARM-dts-msm-Add-krait-pmu-to-platforms-with-Krait-CP.patch b/target/linux/ipq806x/patches/0024-ARM-dts-msm-Add-krait-pmu-to-platforms-with-Krait-CP.patch
deleted file mode 100644
index b0cefc2..0000000
--- a/target/linux/ipq806x/patches/0024-ARM-dts-msm-Add-krait-pmu-to-platforms-with-Krait-CP.patch
+++ /dev/null
@@ -1,46 +0,0 @@
-From 02c987fb8a3607ab6e0ead0e5aaa7da753ce9537 Mon Sep 17 00:00:00 2001
-From: Stephen Boyd <sboyd@codeaurora.org>
-Date: Fri, 21 Feb 2014 11:09:50 +0000
-Subject: [PATCH 024/182] ARM: dts: msm: Add krait-pmu to platforms with Krait
- CPUs
-
-Allows us to probe the performance counters on Krait CPUs.
-
-Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
-Signed-off-by: Will Deacon <will.deacon@arm.com>
-[olof: Moved 8960 contents to the dtsi instead]
-Signed-off-by: Olof Johansson <olof@lixom.net>
----
- arch/arm/boot/dts/qcom-msm8960.dtsi | 6 ++++++
- arch/arm/boot/dts/qcom-msm8974.dtsi | 5 +++++
- 2 files changed, 11 insertions(+)
-
---- a/arch/arm/boot/dts/qcom-msm8960.dtsi
-+++ b/arch/arm/boot/dts/qcom-msm8960.dtsi
-@@ -39,6 +39,12 @@
- };
- };
-
-+ cpu-pmu {
-+ compatible = "qcom,krait-pmu";
-+ interrupts = <1 10 0x304>;
-+ qcom,no-pc-write;
-+ };
-+
- intc: interrupt-controller@2000000 {
- compatible = "qcom,msm-qgic2";
- interrupt-controller;
---- a/arch/arm/boot/dts/qcom-msm8974.dtsi
-+++ b/arch/arm/boot/dts/qcom-msm8974.dtsi
-@@ -52,6 +52,11 @@
- };
- };
-
-+ cpu-pmu {
-+ compatible = "qcom,krait-pmu";
-+ interrupts = <1 7 0xf04>;
-+ };
-+
- soc: soc {
- #address-cells = <1>;
- #size-cells = <1>;
diff --git a/target/linux/ipq806x/patches/0025-pinctrl-msm-drop-wake_irqs-bitmap.patch b/target/linux/ipq806x/patches/0025-pinctrl-msm-drop-wake_irqs-bitmap.patch
deleted file mode 100644
index d0771ff..0000000
--- a/target/linux/ipq806x/patches/0025-pinctrl-msm-drop-wake_irqs-bitmap.patch
+++ /dev/null
@@ -1,66 +0,0 @@
-From ef8eb0991f291df12c12477648235f955cc388b0 Mon Sep 17 00:00:00 2001
-From: Josh Cartwright <joshc@codeaurora.org>
-Date: Wed, 5 Mar 2014 13:33:08 -0600
-Subject: [PATCH 025/182] pinctrl: msm: drop wake_irqs bitmap
-
-Currently, the wake_irqs bitmap is used to track whether there are any
-gpio's which are configured as wake irqs, and uses this to determine
-whether or not to call enable_irq_wake()/disable_irq_wake() on the
-summary interrupt.
-
-However, the genirq core already handles this case, by maintaining a
-'wake_count' per irq_desc, and only calling into the controlling
-irq_chip when wake_count transitions 0 <-> 1.
-
-Drop this bitmap, and unconditionally call irq_set_irq_wake() on the
-summary interrupt.
-
-Signed-off-by: Josh Cartwright <joshc@codeaurora.org>
-Acked-by: Bjorn Andersson <bjorn.andersson@sonymobile.com>
-Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
----
- drivers/pinctrl/pinctrl-msm.c | 14 +-------------
- 1 file changed, 1 insertion(+), 13 deletions(-)
-
---- a/drivers/pinctrl/pinctrl-msm.c
-+++ b/drivers/pinctrl/pinctrl-msm.c
-@@ -50,7 +50,6 @@
- * @enabled_irqs: Bitmap of currently enabled irqs.
- * @dual_edge_irqs: Bitmap of irqs that need sw emulated dual edge
- * detection.
-- * @wake_irqs: Bitmap of irqs with requested as wakeup source.
- * @soc; Reference to soc_data of platform specific data.
- * @regs: Base address for the TLMM register map.
- */
-@@ -65,7 +64,6 @@ struct msm_pinctrl {
-
- DECLARE_BITMAP(dual_edge_irqs, MAX_NR_GPIO);
- DECLARE_BITMAP(enabled_irqs, MAX_NR_GPIO);
-- DECLARE_BITMAP(wake_irqs, MAX_NR_GPIO);
-
- const struct msm_pinctrl_soc_data *soc;
- void __iomem *regs;
-@@ -783,22 +781,12 @@ static int msm_gpio_irq_set_wake(struct
- {
- struct msm_pinctrl *pctrl;
- unsigned long flags;
-- unsigned ngpio;
-
- pctrl = irq_data_get_irq_chip_data(d);
-- ngpio = pctrl->chip.ngpio;
-
- spin_lock_irqsave(&pctrl->lock, flags);
-
-- if (on) {
-- if (bitmap_empty(pctrl->wake_irqs, ngpio))
-- enable_irq_wake(pctrl->irq);
-- set_bit(d->hwirq, pctrl->wake_irqs);
-- } else {
-- clear_bit(d->hwirq, pctrl->wake_irqs);
-- if (bitmap_empty(pctrl->wake_irqs, ngpio))
-- disable_irq_wake(pctrl->irq);
-- }
-+ irq_set_irq_wake(pctrl->irq, on);
-
- spin_unlock_irqrestore(&pctrl->lock, flags);
-
diff --git a/target/linux/ipq806x/patches/0026-pinctrl-msm-Silence-recursive-lockdep-warning.patch b/target/linux/ipq806x/patches/0026-pinctrl-msm-Silence-recursive-lockdep-warning.patch
deleted file mode 100644
index fe5008e..0000000
--- a/target/linux/ipq806x/patches/0026-pinctrl-msm-Silence-recursive-lockdep-warning.patch
+++ /dev/null
@@ -1,68 +0,0 @@
-From 9588c91936434166007c3a15ad7f4e2f3729c5e7 Mon Sep 17 00:00:00 2001
-From: Stephen Boyd <sboyd@codeaurora.org>
-Date: Thu, 6 Mar 2014 22:44:40 -0800
-Subject: [PATCH 026/182] pinctrl: msm: Silence recursive lockdep warning
-
-If a driver calls enable_irq_wake() on a gpio turned interrupt
-from the msm pinctrl driver we'll get a lockdep warning like so:
-
-=============================================
-[ INFO: possible recursive locking detected ]
-3.14.0-rc3 #2 Not tainted
----------------------------------------------
-modprobe/52 is trying to acquire lock:
- (&irq_desc_lock_class){-.....}, at: [<c026aea0>] __irq_get_desc_lock+0x48/0x88
-
-but task is already holding lock:
- (&irq_desc_lock_class){-.....}, at: [<c026aea0>] __irq_get_desc_lock+0x48/0x88
-
-other info that might help us debug this:
- Possible unsafe locking scenario:
-
- CPU0
- ----
- lock(&irq_desc_lock_class);
- lock(&irq_desc_lock_class);
-
- *** DEADLOCK ***
-
- May be due to missing lock nesting notation
-
-4 locks held by modprobe/52:
- #0: (&__lockdep_no_validate__){......}, at: [<c04f2864>] __driver_attach+0x48/0x98
- #1: (&__lockdep_no_validate__){......}, at: [<c04f2874>] __driver_attach+0x58/0x98
- #2: (&irq_desc_lock_class){-.....}, at: [<c026aea0>] __irq_get_desc_lock+0x48/0x88
- #3: (&(&pctrl->lock)->rlock){......}, at: [<c04bb4b8>] msm_gpio_irq_set_wake+0x20/0xa8
-
-Silence it by putting the gpios into their own lock class.
-
-Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
-Acked-by: Bjorn Andersson <bjorn.andersson@sonymobile.com>
-Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
----
- drivers/pinctrl/pinctrl-msm.c | 7 +++++++
- 1 file changed, 7 insertions(+)
-
---- a/drivers/pinctrl/pinctrl-msm.c
-+++ b/drivers/pinctrl/pinctrl-msm.c
-@@ -857,6 +857,12 @@ static void msm_gpio_irq_handler(unsigne
- chained_irq_exit(chip, desc);
- }
-
-+/*
-+ * This lock class tells lockdep that GPIO irqs are in a different
-+ * category than their parents, so it won't report false recursion.
-+ */
-+static struct lock_class_key gpio_lock_class;
-+
- static int msm_gpio_init(struct msm_pinctrl *pctrl)
- {
- struct gpio_chip *chip;
-@@ -895,6 +901,7 @@ static int msm_gpio_init(struct msm_pinc
-
- for (i = 0; i < chip->ngpio; i++) {
- irq = irq_create_mapping(pctrl->domain, i);
-+ irq_set_lockdep_class(irq, &gpio_lock_class);
- irq_set_chip_and_handler(irq, &msm_gpio_irq_chip, handle_edge_irq);
- irq_set_chip_data(irq, pctrl);
- }
diff --git a/target/linux/ipq806x/patches/0027-pinctrl-msm-Check-for-ngpios-MAX_NR_GPIO.patch b/target/linux/ipq806x/patches/0027-pinctrl-msm-Check-for-ngpios-MAX_NR_GPIO.patch
deleted file mode 100644
index 7cf4b14..0000000
--- a/target/linux/ipq806x/patches/0027-pinctrl-msm-Check-for-ngpios-MAX_NR_GPIO.patch
+++ /dev/null
@@ -1,34 +0,0 @@
-From 8341db7b05b688e8e5a93acd0e80b40be409d037 Mon Sep 17 00:00:00 2001
-From: Stephen Boyd <sboyd@codeaurora.org>
-Date: Thu, 6 Mar 2014 22:44:41 -0800
-Subject: [PATCH 027/182] pinctrl: msm: Check for ngpios > MAX_NR_GPIO
-
-Fail the probe and print a warning if SoC specific drivers have
-more GPIOs than there can be accounted for in the static bitmaps.
-This should avoid silent corruption/failures in the future.
-
-Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
-Acked-by: Bjorn Andersson <bjorn.andersson@sonymobile.com>
-Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
----
- drivers/pinctrl/pinctrl-msm.c | 6 +++++-
- 1 file changed, 5 insertions(+), 1 deletion(-)
-
---- a/drivers/pinctrl/pinctrl-msm.c
-+++ b/drivers/pinctrl/pinctrl-msm.c
-@@ -870,10 +870,14 @@ static int msm_gpio_init(struct msm_pinc
- int ret;
- int i;
- int r;
-+ unsigned ngpio = pctrl->soc->ngpios;
-+
-+ if (WARN_ON(ngpio > MAX_NR_GPIO))
-+ return -EINVAL;
-
- chip = &pctrl->chip;
- chip->base = 0;
-- chip->ngpio = pctrl->soc->ngpios;
-+ chip->ngpio = ngpio;
- chip->label = dev_name(pctrl->dev);
- chip->dev = pctrl->dev;
- chip->owner = THIS_MODULE;
diff --git a/target/linux/ipq806x/patches/0028-pinctrl-msm-Drop-unused-includes.patch b/target/linux/ipq806x/patches/0028-pinctrl-msm-Drop-unused-includes.patch
deleted file mode 100644
index d8cd970..0000000
--- a/target/linux/ipq806x/patches/0028-pinctrl-msm-Drop-unused-includes.patch
+++ /dev/null
@@ -1,51 +0,0 @@
-From d2caa906f865d6919c511a956ae63ab62b240eba Mon Sep 17 00:00:00 2001
-From: Stephen Boyd <sboyd@codeaurora.org>
-Date: Thu, 6 Mar 2014 22:44:42 -0800
-Subject: [PATCH 028/182] pinctrl: msm: Drop unused includes
-
-These includes are unused or can be handled via forward
-declarations. Remove them.
-
-Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
-Acked-by: Bjorn Andersson <bjorn.andersson@sonymobile.com>
-Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
----
- drivers/pinctrl/pinctrl-msm.c | 1 -
- drivers/pinctrl/pinctrl-msm.h | 5 +----
- drivers/pinctrl/pinctrl-msm8x74.c | 1 -
- 3 files changed, 1 insertion(+), 6 deletions(-)
-
---- a/drivers/pinctrl/pinctrl-msm.c
-+++ b/drivers/pinctrl/pinctrl-msm.c
-@@ -28,7 +28,6 @@
- #include <linux/interrupt.h>
- #include <linux/irq.h>
- #include <linux/irqchip/chained_irq.h>
--#include <linux/of_irq.h>
- #include <linux/spinlock.h>
-
- #include "core.h"
---- a/drivers/pinctrl/pinctrl-msm.h
-+++ b/drivers/pinctrl/pinctrl-msm.h
-@@ -13,10 +13,7 @@
- #ifndef __PINCTRL_MSM_H__
- #define __PINCTRL_MSM_H__
-
--#include <linux/pinctrl/pinctrl.h>
--#include <linux/pinctrl/pinmux.h>
--#include <linux/pinctrl/pinconf.h>
--#include <linux/pinctrl/machine.h>
-+struct pinctrl_pin_desc;
-
- /**
- * struct msm_function - a pinmux function
---- a/drivers/pinctrl/pinctrl-msm8x74.c
-+++ b/drivers/pinctrl/pinctrl-msm8x74.c
-@@ -15,7 +15,6 @@
- #include <linux/of.h>
- #include <linux/platform_device.h>
- #include <linux/pinctrl/pinctrl.h>
--#include <linux/pinctrl/pinmux.h>
-
- #include "pinctrl-msm.h"
-
diff --git a/target/linux/ipq806x/patches/0029-pinctrl-msm-Drop-OF_IRQ-dependency.patch b/target/linux/ipq806x/patches/0029-pinctrl-msm-Drop-OF_IRQ-dependency.patch
deleted file mode 100644
index 1357f3b..0000000
--- a/target/linux/ipq806x/patches/0029-pinctrl-msm-Drop-OF_IRQ-dependency.patch
+++ /dev/null
@@ -1,26 +0,0 @@
-From 2cfbd01bd994bd16dbee28a99553796f12848c4c Mon Sep 17 00:00:00 2001
-From: Stephen Boyd <sboyd@codeaurora.org>
-Date: Thu, 6 Mar 2014 22:44:43 -0800
-Subject: [PATCH 029/182] pinctrl: msm: Drop OF_IRQ dependency
-
-This driver doesn't rely on any functionality living in
-drivers/of/irq.c to compile. Drop this dependency.
-
-Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
-Acked-by: Bjorn Andersson <bjorn.andersson@sonymobile.com>
-Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
----
- drivers/pinctrl/Kconfig | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/drivers/pinctrl/Kconfig
-+++ b/drivers/pinctrl/Kconfig
-@@ -224,7 +224,7 @@ config PINCTRL_MSM
-
- config PINCTRL_MSM8X74
- tristate "Qualcomm 8x74 pin controller driver"
-- depends on GPIOLIB && OF && OF_IRQ
-+ depends on GPIOLIB && OF
- select PINCTRL_MSM
- help
- This is the pinctrl, pinmux, pinconf and gpiolib driver for the
diff --git a/target/linux/ipq806x/patches/0030-pinctrl-msm-Replace-lookup-tables-with-math.patch b/target/linux/ipq806x/patches/0030-pinctrl-msm-Replace-lookup-tables-with-math.patch
deleted file mode 100644
index 6bc94af..0000000
--- a/target/linux/ipq806x/patches/0030-pinctrl-msm-Replace-lookup-tables-with-math.patch
+++ /dev/null
@@ -1,61 +0,0 @@
-From e34d9fdac8182f6ce8933501fea6e84664060bf0 Mon Sep 17 00:00:00 2001
-From: Stephen Boyd <sboyd@codeaurora.org>
-Date: Thu, 6 Mar 2014 22:44:44 -0800
-Subject: [PATCH 030/182] pinctrl: msm: Replace lookup tables with math
-
-We don't need to waste space with these lookup tables, just do
-the math directly.
-
-Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
-Acked-by: Bjorn Andersson <bjorn.andersson@sonymobile.com>
-Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
----
- drivers/pinctrl/pinctrl-msm.c | 14 ++++++++------
- 1 file changed, 8 insertions(+), 6 deletions(-)
-
---- a/drivers/pinctrl/pinctrl-msm.c
-+++ b/drivers/pinctrl/pinctrl-msm.c
-@@ -258,8 +258,10 @@ static int msm_config_set(struct pinctrl
- #define MSM_PULL_DOWN 1
- #define MSM_PULL_UP 3
-
--static const unsigned msm_regval_to_drive[] = { 2, 4, 6, 8, 10, 12, 14, 16 };
--static const unsigned msm_drive_to_regval[] = { -1, -1, 0, -1, 1, -1, 2, -1, 3, -1, 4, -1, 5, -1, 6, -1, 7 };
-+static unsigned msm_regval_to_drive(u32 val)
-+{
-+ return (val + 1) * 2;
-+}
-
- static int msm_config_group_get(struct pinctrl_dev *pctldev,
- unsigned int group,
-@@ -296,7 +298,7 @@ static int msm_config_group_get(struct p
- arg = arg == MSM_PULL_UP;
- break;
- case PIN_CONFIG_DRIVE_STRENGTH:
-- arg = msm_regval_to_drive[arg];
-+ arg = msm_regval_to_drive(arg);
- break;
- default:
- dev_err(pctrl->dev, "Unsupported config parameter: %x\n",
-@@ -349,10 +351,10 @@ static int msm_config_group_set(struct p
- break;
- case PIN_CONFIG_DRIVE_STRENGTH:
- /* Check for invalid values */
-- if (arg >= ARRAY_SIZE(msm_drive_to_regval))
-+ if (arg > 16 || arg < 2 || (arg % 2) != 0)
- arg = -1;
- else
-- arg = msm_drive_to_regval[arg];
-+ arg = (arg / 2) - 1;
- break;
- default:
- dev_err(pctrl->dev, "Unsupported config parameter: %x\n",
-@@ -531,7 +533,7 @@ static void msm_gpio_dbg_show_one(struct
- pull = (ctl_reg >> g->pull_bit) & 3;
-
- seq_printf(s, " %-8s: %-3s %d", g->name, is_out ? "out" : "in", func);
-- seq_printf(s, " %dmA", msm_regval_to_drive[drive]);
-+ seq_printf(s, " %dmA", msm_regval_to_drive(drive));
- seq_printf(s, " %s", pulls[pull]);
- }
-
diff --git a/target/linux/ipq806x/patches/0031-pinctrl-msm-Remove-impossible-WARN_ON-s.patch b/target/linux/ipq806x/patches/0031-pinctrl-msm-Remove-impossible-WARN_ON-s.patch
deleted file mode 100644
index 3356efc..0000000
--- a/target/linux/ipq806x/patches/0031-pinctrl-msm-Remove-impossible-WARN_ON-s.patch
+++ /dev/null
@@ -1,90 +0,0 @@
-From 286113578287b9c7619b4104864cffb91820f49d Mon Sep 17 00:00:00 2001
-From: Stephen Boyd <sboyd@codeaurora.org>
-Date: Thu, 6 Mar 2014 22:44:45 -0800
-Subject: [PATCH 031/182] pinctrl: msm: Remove impossible WARN_ON()s
-
-All these functions are limited in what they can pass as the gpio
-or irq number to whatever is setup during probe. Remove the
-checks.
-
-Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
-Acked-by: Bjorn Andersson <bjorn.andersson@sonymobile.com>
-Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
----
- drivers/pinctrl/pinctrl-msm.c | 16 ----------------
- 1 file changed, 16 deletions(-)
-
---- a/drivers/pinctrl/pinctrl-msm.c
-+++ b/drivers/pinctrl/pinctrl-msm.c
-@@ -401,8 +401,6 @@ static int msm_gpio_direction_input(stru
- u32 val;
-
- g = &pctrl->soc->groups[offset];
-- if (WARN_ON(g->io_reg < 0))
-- return -EINVAL;
-
- spin_lock_irqsave(&pctrl->lock, flags);
-
-@@ -423,8 +421,6 @@ static int msm_gpio_direction_output(str
- u32 val;
-
- g = &pctrl->soc->groups[offset];
-- if (WARN_ON(g->io_reg < 0))
-- return -EINVAL;
-
- spin_lock_irqsave(&pctrl->lock, flags);
-
-@@ -451,8 +447,6 @@ static int msm_gpio_get(struct gpio_chip
- u32 val;
-
- g = &pctrl->soc->groups[offset];
-- if (WARN_ON(g->io_reg < 0))
-- return -EINVAL;
-
- val = readl(pctrl->regs + g->io_reg);
- return !!(val & BIT(g->in_bit));
-@@ -466,8 +460,6 @@ static void msm_gpio_set(struct gpio_chi
- u32 val;
-
- g = &pctrl->soc->groups[offset];
-- if (WARN_ON(g->io_reg < 0))
-- return;
-
- spin_lock_irqsave(&pctrl->lock, flags);
-
-@@ -616,8 +608,6 @@ static void msm_gpio_irq_mask(struct irq
-
- pctrl = irq_data_get_irq_chip_data(d);
- g = &pctrl->soc->groups[d->hwirq];
-- if (WARN_ON(g->intr_cfg_reg < 0))
-- return;
-
- spin_lock_irqsave(&pctrl->lock, flags);
-
-@@ -639,8 +629,6 @@ static void msm_gpio_irq_unmask(struct i
-
- pctrl = irq_data_get_irq_chip_data(d);
- g = &pctrl->soc->groups[d->hwirq];
-- if (WARN_ON(g->intr_status_reg < 0))
-- return;
-
- spin_lock_irqsave(&pctrl->lock, flags);
-
-@@ -666,8 +654,6 @@ static void msm_gpio_irq_ack(struct irq_
-
- pctrl = irq_data_get_irq_chip_data(d);
- g = &pctrl->soc->groups[d->hwirq];
-- if (WARN_ON(g->intr_status_reg < 0))
-- return;
-
- spin_lock_irqsave(&pctrl->lock, flags);
-
-@@ -692,8 +678,6 @@ static int msm_gpio_irq_set_type(struct
-
- pctrl = irq_data_get_irq_chip_data(d);
- g = &pctrl->soc->groups[d->hwirq];
-- if (WARN_ON(g->intr_cfg_reg < 0))
-- return -EINVAL;
-
- spin_lock_irqsave(&pctrl->lock, flags);
-
diff --git a/target/linux/ipq806x/patches/0032-pinctrl-msm-Simplify-msm_config_reg-and-callers.patch b/target/linux/ipq806x/patches/0032-pinctrl-msm-Simplify-msm_config_reg-and-callers.patch
deleted file mode 100644
index f7798ae..0000000
--- a/target/linux/ipq806x/patches/0032-pinctrl-msm-Simplify-msm_config_reg-and-callers.patch
+++ /dev/null
@@ -1,110 +0,0 @@
-From 2d9ffb1a3f87396c3b792124870ef63fc27c568f Mon Sep 17 00:00:00 2001
-From: Stephen Boyd <sboyd@codeaurora.org>
-Date: Thu, 6 Mar 2014 22:44:46 -0800
-Subject: [PATCH 032/182] pinctrl: msm: Simplify msm_config_reg() and callers
-
-We don't need to check for a negative reg here because reg is
-always the same and is always non-negative. Also, collapse the
-switch statement down for the duplicate cases.
-
-Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
-Acked-by: Bjorn Andersson <bjorn.andersson@sonymobile.com>
-Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
----
- drivers/pinctrl/pinctrl-msm.c | 29 +++++------------------------
- 1 file changed, 5 insertions(+), 24 deletions(-)
-
---- a/drivers/pinctrl/pinctrl-msm.c
-+++ b/drivers/pinctrl/pinctrl-msm.c
-@@ -200,28 +200,17 @@ static const struct pinmux_ops msm_pinmu
- static int msm_config_reg(struct msm_pinctrl *pctrl,
- const struct msm_pingroup *g,
- unsigned param,
-- s16 *reg,
- unsigned *mask,
- unsigned *bit)
- {
- switch (param) {
- case PIN_CONFIG_BIAS_DISABLE:
-- *reg = g->ctl_reg;
-- *bit = g->pull_bit;
-- *mask = 3;
-- break;
- case PIN_CONFIG_BIAS_PULL_DOWN:
-- *reg = g->ctl_reg;
-- *bit = g->pull_bit;
-- *mask = 3;
-- break;
- case PIN_CONFIG_BIAS_PULL_UP:
-- *reg = g->ctl_reg;
- *bit = g->pull_bit;
- *mask = 3;
- break;
- case PIN_CONFIG_DRIVE_STRENGTH:
-- *reg = g->ctl_reg;
- *bit = g->drv_bit;
- *mask = 7;
- break;
-@@ -230,12 +219,6 @@ static int msm_config_reg(struct msm_pin
- return -ENOTSUPP;
- }
-
-- if (*reg < 0) {
-- dev_err(pctrl->dev, "Config param %04x not supported on group %s\n",
-- param, g->name);
-- return -ENOTSUPP;
-- }
--
- return 0;
- }
-
-@@ -273,17 +256,16 @@ static int msm_config_group_get(struct p
- unsigned mask;
- unsigned arg;
- unsigned bit;
-- s16 reg;
- int ret;
- u32 val;
-
- g = &pctrl->soc->groups[group];
-
-- ret = msm_config_reg(pctrl, g, param, &reg, &mask, &bit);
-+ ret = msm_config_reg(pctrl, g, param, &mask, &bit);
- if (ret < 0)
- return ret;
-
-- val = readl(pctrl->regs + reg);
-+ val = readl(pctrl->regs + g->ctl_reg);
- arg = (val >> bit) & mask;
-
- /* Convert register value to pinconf value */
-@@ -323,7 +305,6 @@ static int msm_config_group_set(struct p
- unsigned mask;
- unsigned arg;
- unsigned bit;
-- s16 reg;
- int ret;
- u32 val;
- int i;
-@@ -334,7 +315,7 @@ static int msm_config_group_set(struct p
- param = pinconf_to_config_param(configs[i]);
- arg = pinconf_to_config_argument(configs[i]);
-
-- ret = msm_config_reg(pctrl, g, param, &reg, &mask, &bit);
-+ ret = msm_config_reg(pctrl, g, param, &mask, &bit);
- if (ret < 0)
- return ret;
-
-@@ -369,10 +350,10 @@ static int msm_config_group_set(struct p
- }
-
- spin_lock_irqsave(&pctrl->lock, flags);
-- val = readl(pctrl->regs + reg);
-+ val = readl(pctrl->regs + g->ctl_reg);
- val &= ~(mask << bit);
- val |= arg << bit;
-- writel(val, pctrl->regs + reg);
-+ writel(val, pctrl->regs + g->ctl_reg);
- spin_unlock_irqrestore(&pctrl->lock, flags);
- }
-
diff --git a/target/linux/ipq806x/patches/0033-pinctrl-msm-Support-output-high-low-configuration.patch b/target/linux/ipq806x/patches/0033-pinctrl-msm-Support-output-high-low-configuration.patch
deleted file mode 100644
index f2f7c7d..0000000
--- a/target/linux/ipq806x/patches/0033-pinctrl-msm-Support-output-high-low-configuration.patch
+++ /dev/null
@@ -1,64 +0,0 @@
-From 469f83e0ed374250be5fd6202ac535276a752fa8 Mon Sep 17 00:00:00 2001
-From: Bjorn Andersson <bjorn@kryo.se>
-Date: Tue, 4 Feb 2014 19:55:31 -0800
-Subject: [PATCH 033/182] pinctrl-msm: Support output-{high,low} configuration
-
-Add support for configuring pins as output with value as from the
-pinconf-generic interface.
-
-Signed-off-by: Bjorn Andersson <bjorn.andersson@sonymobile.com>
-Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
----
- drivers/pinctrl/pinctrl-msm.c | 27 +++++++++++++++++++++++++++
- 1 file changed, 27 insertions(+)
-
---- a/drivers/pinctrl/pinctrl-msm.c
-+++ b/drivers/pinctrl/pinctrl-msm.c
-@@ -214,6 +214,11 @@ static int msm_config_reg(struct msm_pin
- *bit = g->drv_bit;
- *mask = 7;
- break;
-+ case PIN_CONFIG_OUTPUT:
-+ *reg = g->ctl_reg;
-+ *bit = g->oe_bit;
-+ *mask = 1;
-+ break;
- default:
- dev_err(pctrl->dev, "Invalid config param %04x\n", param);
- return -ENOTSUPP;
-@@ -282,6 +287,14 @@ static int msm_config_group_get(struct p
- case PIN_CONFIG_DRIVE_STRENGTH:
- arg = msm_regval_to_drive(arg);
- break;
-+ case PIN_CONFIG_OUTPUT:
-+ /* Pin is not output */
-+ if (!arg)
-+ return -EINVAL;
-+
-+ val = readl(pctrl->regs + g->io_reg);
-+ arg = !!(val & BIT(g->in_bit));
-+ break;
- default:
- dev_err(pctrl->dev, "Unsupported config parameter: %x\n",
- param);
-@@ -337,6 +350,20 @@ static int msm_config_group_set(struct p
- else
- arg = (arg / 2) - 1;
- break;
-+ case PIN_CONFIG_OUTPUT:
-+ /* set output value */
-+ spin_lock_irqsave(&pctrl->lock, flags);
-+ val = readl(pctrl->regs + g->io_reg);
-+ if (arg)
-+ val |= BIT(g->out_bit);
-+ else
-+ val &= ~BIT(g->out_bit);
-+ writel(val, pctrl->regs + g->io_reg);
-+ spin_unlock_irqrestore(&pctrl->lock, flags);
-+
-+ /* enable output */
-+ arg = 1;
-+ break;
- default:
- dev_err(pctrl->dev, "Unsupported config parameter: %x\n",
- param);
diff --git a/target/linux/ipq806x/patches/0034-pinctrl-msm-Add-SPI8-pin-definitions.patch b/target/linux/ipq806x/patches/0034-pinctrl-msm-Add-SPI8-pin-definitions.patch
deleted file mode 100644
index a3f6d6a..0000000
--- a/target/linux/ipq806x/patches/0034-pinctrl-msm-Add-SPI8-pin-definitions.patch
+++ /dev/null
@@ -1,58 +0,0 @@
-From 77e4b572fcc4015e235f22fd93b8df35e452baf0 Mon Sep 17 00:00:00 2001
-From: "Ivan T. Ivanov" <iivanov@mm-sol.com>
-Date: Thu, 6 Feb 2014 17:28:48 +0200
-Subject: [PATCH 034/182] pinctrl-msm: Add SPI8 pin definitions
-
-Add pin, group and function definitions for SPI#8
-controller.
-
-Signed-off-by: Ivan T. Ivanov <iivanov@mm-sol.com>
-Acked-by: Bjorn Andersson <bjorn.andersson@sonymobile.com>
-Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
----
- drivers/pinctrl/pinctrl-msm8x74.c | 13 +++++++++----
- 1 file changed, 9 insertions(+), 4 deletions(-)
-
---- a/drivers/pinctrl/pinctrl-msm8x74.c
-+++ b/drivers/pinctrl/pinctrl-msm8x74.c
-@@ -405,6 +405,7 @@ enum msm8x74_functions {
- MSM_MUX_blsp_i2c6,
- MSM_MUX_blsp_i2c11,
- MSM_MUX_blsp_spi1,
-+ MSM_MUX_blsp_spi8,
- MSM_MUX_blsp_uart2,
- MSM_MUX_blsp_uart8,
- MSM_MUX_slimbus,
-@@ -415,6 +416,9 @@ static const char * const blsp_i2c2_grou
- static const char * const blsp_i2c6_groups[] = { "gpio29", "gpio30" };
- static const char * const blsp_i2c11_groups[] = { "gpio83", "gpio84" };
- static const char * const blsp_spi1_groups[] = { "gpio0", "gpio1", "gpio2", "gpio3" };
-+static const char * const blsp_spi8_groups[] = {
-+ "gpio45", "gpio46", "gpio47", "gpio48"
-+};
- static const char * const blsp_uart2_groups[] = { "gpio4", "gpio5" };
- static const char * const blsp_uart8_groups[] = { "gpio45", "gpio46" };
- static const char * const slimbus_groups[] = { "gpio70", "gpio71" };
-@@ -424,6 +428,7 @@ static const struct msm_function msm8x74
- FUNCTION(blsp_i2c6),
- FUNCTION(blsp_i2c11),
- FUNCTION(blsp_spi1),
-+ FUNCTION(blsp_spi8),
- FUNCTION(blsp_uart2),
- FUNCTION(blsp_uart8),
- FUNCTION(slimbus),
-@@ -475,10 +480,10 @@ static const struct msm_pingroup msm8x74
- PINGROUP(42, NA, NA, NA, NA, NA, NA, NA),
- PINGROUP(43, NA, NA, NA, NA, NA, NA, NA),
- PINGROUP(44, NA, NA, NA, NA, NA, NA, NA),
-- PINGROUP(45, NA, blsp_uart8, NA, NA, NA, NA, NA),
-- PINGROUP(46, NA, blsp_uart8, NA, NA, NA, NA, NA),
-- PINGROUP(47, NA, NA, NA, NA, NA, NA, NA),
-- PINGROUP(48, NA, NA, NA, NA, NA, NA, NA),
-+ PINGROUP(45, blsp_spi8, blsp_uart8, NA, NA, NA, NA, NA),
-+ PINGROUP(46, blsp_spi8, blsp_uart8, NA, NA, NA, NA, NA),
-+ PINGROUP(47, blsp_spi8, NA, NA, NA, NA, NA, NA),
-+ PINGROUP(48, blsp_spi8, NA, NA, NA, NA, NA, NA),
- PINGROUP(49, NA, NA, NA, NA, NA, NA, NA),
- PINGROUP(50, NA, NA, NA, NA, NA, NA, NA),
- PINGROUP(51, NA, NA, NA, NA, NA, NA, NA),
diff --git a/target/linux/ipq806x/patches/0035-pinctrl-msm-fix-up-out-of-order-merge-conflict.patch b/target/linux/ipq806x/patches/0035-pinctrl-msm-fix-up-out-of-order-merge-conflict.patch
deleted file mode 100644
index f0bd614..0000000
--- a/target/linux/ipq806x/patches/0035-pinctrl-msm-fix-up-out-of-order-merge-conflict.patch
+++ /dev/null
@@ -1,33 +0,0 @@
-From c73a138dd24049d06fe7b22518655ed9e7413cd2 Mon Sep 17 00:00:00 2001
-From: Linus Walleij <linus.walleij@linaro.org>
-Date: Fri, 14 Mar 2014 07:54:20 +0100
-Subject: [PATCH 035/182] pinctrl: msm: fix up out-of-order merge conflict
-
-Commit 051a58b4622f0e1b732acb750097c64bc00ddb93
-"pinctrl: msm: Simplify msm_config_reg() and callers"
-removed the local "reg" variable in the msm_config_reg()
-function, but the earlier
-commit ed118a5fd951bd2def8249ee251842c4f81fe4bd
-"pinctrl-msm: Support output-{high,low} configuration"
-introduced a new switchclause using it.
-
-Fix this up by removing the offending register assignment.
-
-Reported-by: Kbuild test robot <fengguang.wu@intel.com>
-Cc: Stephen Boyd <sboyd@codeaurora.org>
-Acked-by: Bjorn Andersson <bjorn.andersson@sonymobile.com>
-Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
----
- drivers/pinctrl/pinctrl-msm.c | 1 -
- 1 file changed, 1 deletion(-)
-
---- a/drivers/pinctrl/pinctrl-msm.c
-+++ b/drivers/pinctrl/pinctrl-msm.c
-@@ -215,7 +215,6 @@ static int msm_config_reg(struct msm_pin
- *mask = 7;
- break;
- case PIN_CONFIG_OUTPUT:
-- *reg = g->ctl_reg;
- *bit = g->oe_bit;
- *mask = 1;
- break;
diff --git a/target/linux/ipq806x/patches/0036-pinctrl-msm-Correct-interrupt-code-for-TLMM-v2.patch b/target/linux/ipq806x/patches/0036-pinctrl-msm-Correct-interrupt-code-for-TLMM-v2.patch
deleted file mode 100644
index 384e183..0000000
--- a/target/linux/ipq806x/patches/0036-pinctrl-msm-Correct-interrupt-code-for-TLMM-v2.patch
+++ /dev/null
@@ -1,48 +0,0 @@
-From 32787a9bba5a1ebeea891fd7aab954e6d344892a Mon Sep 17 00:00:00 2001
-From: Bjorn Andersson <bjorn.andersson@sonymobile.com>
-Date: Mon, 31 Mar 2014 14:49:54 -0700
-Subject: [PATCH 036/182] pinctrl: msm: Correct interrupt code for TLMM v2
-
-Acking interrupts are done differently between on v2 and v3, so add an extra
-attribute to the pingroup struct to let the platform definitions control this.
-Also make sure to start dual edge detection by detecting the rising edge.
-
-Signed-off-by: Bjorn Andersson <bjorn.andersson@sonymobile.com>
-Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
----
- drivers/pinctrl/pinctrl-msm.c | 6 +++++-
- drivers/pinctrl/pinctrl-msm.h | 1 +
- 2 files changed, 6 insertions(+), 1 deletion(-)
-
---- a/drivers/pinctrl/pinctrl-msm.c
-+++ b/drivers/pinctrl/pinctrl-msm.c
-@@ -665,7 +665,10 @@ static void msm_gpio_irq_ack(struct irq_
- spin_lock_irqsave(&pctrl->lock, flags);
-
- val = readl(pctrl->regs + g->intr_status_reg);
-- val &= ~BIT(g->intr_status_bit);
-+ if (g->intr_ack_high)
-+ val |= BIT(g->intr_status_bit);
-+ else
-+ val &= ~BIT(g->intr_status_bit);
- writel(val, pctrl->regs + g->intr_status_reg);
-
- if (test_bit(d->hwirq, pctrl->dual_edge_irqs))
-@@ -744,6 +747,7 @@ static int msm_gpio_irq_set_type(struct
- break;
- case IRQ_TYPE_EDGE_BOTH:
- val |= BIT(g->intr_detection_bit);
-+ val |= BIT(g->intr_polarity_bit);
- break;
- case IRQ_TYPE_LEVEL_LOW:
- break;
---- a/drivers/pinctrl/pinctrl-msm.h
-+++ b/drivers/pinctrl/pinctrl-msm.h
-@@ -84,6 +84,7 @@ struct msm_pingroup {
-
- unsigned intr_enable_bit:5;
- unsigned intr_status_bit:5;
-+ unsigned intr_ack_high:1;
-
- unsigned intr_target_bit:5;
- unsigned intr_raw_status_bit:5;
diff --git a/target/linux/ipq806x/patches/0037-pinctrl-msm-Make-number-of-functions-variable.patch b/target/linux/ipq806x/patches/0037-pinctrl-msm-Make-number-of-functions-variable.patch
deleted file mode 100644
index e36498b..0000000
--- a/target/linux/ipq806x/patches/0037-pinctrl-msm-Make-number-of-functions-variable.patch
+++ /dev/null
@@ -1,65 +0,0 @@
-From 1c11b14dd6d740e997919f0bf789bf921548dc0f Mon Sep 17 00:00:00 2001
-From: Bjorn Andersson <bjorn.andersson@sonymobile.com>
-Date: Mon, 31 Mar 2014 14:49:55 -0700
-Subject: [PATCH 037/182] pinctrl: msm: Make number of functions variable
-
-The various pins may have different number of functions defined, so make this
-number definable per pin instead of just increasing it to the largest one for
-all of the platforms.
-
-Signed-off-by: Bjorn Andersson <bjorn.andersson@sonymobile.com>
-Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
----
- drivers/pinctrl/pinctrl-msm.c | 4 ++--
- drivers/pinctrl/pinctrl-msm.h | 3 ++-
- drivers/pinctrl/pinctrl-msm8x74.c | 3 ++-
- 3 files changed, 6 insertions(+), 4 deletions(-)
-
---- a/drivers/pinctrl/pinctrl-msm.c
-+++ b/drivers/pinctrl/pinctrl-msm.c
-@@ -145,12 +145,12 @@ static int msm_pinmux_enable(struct pinc
- if (WARN_ON(g->mux_bit < 0))
- return -EINVAL;
-
-- for (i = 0; i < ARRAY_SIZE(g->funcs); i++) {
-+ for (i = 0; i < g->nfuncs; i++) {
- if (g->funcs[i] == function)
- break;
- }
-
-- if (WARN_ON(i == ARRAY_SIZE(g->funcs)))
-+ if (WARN_ON(i == g->nfuncs))
- return -EINVAL;
-
- spin_lock_irqsave(&pctrl->lock, flags);
---- a/drivers/pinctrl/pinctrl-msm.h
-+++ b/drivers/pinctrl/pinctrl-msm.h
-@@ -65,7 +65,8 @@ struct msm_pingroup {
- const unsigned *pins;
- unsigned npins;
-
-- unsigned funcs[8];
-+ unsigned *funcs;
-+ unsigned nfuncs;
-
- s16 ctl_reg;
- s16 io_reg;
---- a/drivers/pinctrl/pinctrl-msm8x74.c
-+++ b/drivers/pinctrl/pinctrl-msm8x74.c
-@@ -341,7 +341,7 @@ static const unsigned int sdc2_data_pins
- .name = "gpio" #id, \
- .pins = gpio##id##_pins, \
- .npins = ARRAY_SIZE(gpio##id##_pins), \
-- .funcs = { \
-+ .funcs = (int[]){ \
- MSM_MUX_NA, /* gpio mode */ \
- MSM_MUX_##f1, \
- MSM_MUX_##f2, \
-@@ -351,6 +351,7 @@ static const unsigned int sdc2_data_pins
- MSM_MUX_##f6, \
- MSM_MUX_##f7 \
- }, \
-+ .nfuncs = 8, \
- .ctl_reg = 0x1000 + 0x10 * id, \
- .io_reg = 0x1004 + 0x10 * id, \
- .intr_cfg_reg = 0x1008 + 0x10 * id, \
diff --git a/target/linux/ipq806x/patches/0038-pinctrl-msm-Add-definitions-for-the-APQ8064-platform.patch b/target/linux/ipq806x/patches/0038-pinctrl-msm-Add-definitions-for-the-APQ8064-platform.patch
deleted file mode 100644
index a177d35..0000000
--- a/target/linux/ipq806x/patches/0038-pinctrl-msm-Add-definitions-for-the-APQ8064-platform.patch
+++ /dev/null
@@ -1,614 +0,0 @@
-From 247288012122ccfe7d5d9af00a45814c6fdd94c5 Mon Sep 17 00:00:00 2001
-From: Bjorn Andersson <bjorn.andersson@sonymobile.com>
-Date: Mon, 31 Mar 2014 14:49:57 -0700
-Subject: [PATCH 038/182] pinctrl: msm: Add definitions for the APQ8064
- platform
-
-This adds pinctrl definitions for the GPIO pins of the TLMM v2 block in the
-Qualcomm APQ8064 platform.
-
-Signed-off-by: Bjorn Andersson <bjorn.andersson@sonymobile.com>
-Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
----
- drivers/pinctrl/Kconfig | 8 +
- drivers/pinctrl/Makefile | 1 +
- drivers/pinctrl/pinctrl-apq8064.c | 566 +++++++++++++++++++++++++++++++++++++
- 3 files changed, 575 insertions(+)
- create mode 100644 drivers/pinctrl/pinctrl-apq8064.c
-
---- a/drivers/pinctrl/Kconfig
-+++ b/drivers/pinctrl/Kconfig
-@@ -222,6 +222,14 @@ config PINCTRL_MSM
- select PINCONF
- select GENERIC_PINCONF
-
-+config PINCTRL_APQ8064
-+ tristate "Qualcomm APQ8064 pin controller driver"
-+ depends on GPIOLIB && OF
-+ select PINCTRL_MSM
-+ help
-+ This is the pinctrl, pinmux, pinconf and gpiolib driver for the
-+ Qualcomm TLMM block found in the Qualcomm APQ8064 platform.
-+
- config PINCTRL_MSM8X74
- tristate "Qualcomm 8x74 pin controller driver"
- depends on GPIOLIB && OF
---- a/drivers/pinctrl/Makefile
-+++ b/drivers/pinctrl/Makefile
-@@ -38,6 +38,7 @@ obj-$(CONFIG_PINCTRL_IMX23) += pinctrl-i
- obj-$(CONFIG_PINCTRL_IMX25) += pinctrl-imx25.o
- obj-$(CONFIG_PINCTRL_IMX28) += pinctrl-imx28.o
- obj-$(CONFIG_PINCTRL_MSM) += pinctrl-msm.o
-+obj-$(CONFIG_PINCTRL_APQ8064) += pinctrl-apq8064.o
- obj-$(CONFIG_PINCTRL_MSM8X74) += pinctrl-msm8x74.o
- obj-$(CONFIG_PINCTRL_NOMADIK) += pinctrl-nomadik.o
- obj-$(CONFIG_PINCTRL_STN8815) += pinctrl-nomadik-stn8815.o
---- /dev/null
-+++ b/drivers/pinctrl/pinctrl-apq8064.c
-@@ -0,0 +1,566 @@
-+/*
-+ * Copyright (c) 2014, Sony Mobile Communications AB.
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 and
-+ * only version 2 as published by the Free Software Foundation.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ * GNU General Public License for more details.
-+ */
-+
-+#include <linux/module.h>
-+#include <linux/of.h>
-+#include <linux/platform_device.h>
-+#include <linux/pinctrl/pinctrl.h>
-+
-+#include "pinctrl-msm.h"
-+
-+static const struct pinctrl_pin_desc apq8064_pins[] = {
-+ PINCTRL_PIN(0, "GPIO_0"),
-+ PINCTRL_PIN(1, "GPIO_1"),
-+ PINCTRL_PIN(2, "GPIO_2"),
-+ PINCTRL_PIN(3, "GPIO_3"),
-+ PINCTRL_PIN(4, "GPIO_4"),
-+ PINCTRL_PIN(5, "GPIO_5"),
-+ PINCTRL_PIN(6, "GPIO_6"),
-+ PINCTRL_PIN(7, "GPIO_7"),
-+ PINCTRL_PIN(8, "GPIO_8"),
-+ PINCTRL_PIN(9, "GPIO_9"),
-+ PINCTRL_PIN(10, "GPIO_10"),
-+ PINCTRL_PIN(11, "GPIO_11"),
-+ PINCTRL_PIN(12, "GPIO_12"),
-+ PINCTRL_PIN(13, "GPIO_13"),
-+ PINCTRL_PIN(14, "GPIO_14"),
-+ PINCTRL_PIN(15, "GPIO_15"),
-+ PINCTRL_PIN(16, "GPIO_16"),
-+ PINCTRL_PIN(17, "GPIO_17"),
-+ PINCTRL_PIN(18, "GPIO_18"),
-+ PINCTRL_PIN(19, "GPIO_19"),
-+ PINCTRL_PIN(20, "GPIO_20"),
-+ PINCTRL_PIN(21, "GPIO_21"),
-+ PINCTRL_PIN(22, "GPIO_22"),
-+ PINCTRL_PIN(23, "GPIO_23"),
-+ PINCTRL_PIN(24, "GPIO_24"),
-+ PINCTRL_PIN(25, "GPIO_25"),
-+ PINCTRL_PIN(26, "GPIO_26"),
-+ PINCTRL_PIN(27, "GPIO_27"),
-+ PINCTRL_PIN(28, "GPIO_28"),
-+ PINCTRL_PIN(29, "GPIO_29"),
-+ PINCTRL_PIN(30, "GPIO_30"),
-+ PINCTRL_PIN(31, "GPIO_31"),
-+ PINCTRL_PIN(32, "GPIO_32"),
-+ PINCTRL_PIN(33, "GPIO_33"),
-+ PINCTRL_PIN(34, "GPIO_34"),
-+ PINCTRL_PIN(35, "GPIO_35"),
-+ PINCTRL_PIN(36, "GPIO_36"),
-+ PINCTRL_PIN(37, "GPIO_37"),
-+ PINCTRL_PIN(38, "GPIO_38"),
-+ PINCTRL_PIN(39, "GPIO_39"),
-+ PINCTRL_PIN(40, "GPIO_40"),
-+ PINCTRL_PIN(41, "GPIO_41"),
-+ PINCTRL_PIN(42, "GPIO_42"),
-+ PINCTRL_PIN(43, "GPIO_43"),
-+ PINCTRL_PIN(44, "GPIO_44"),
-+ PINCTRL_PIN(45, "GPIO_45"),
-+ PINCTRL_PIN(46, "GPIO_46"),
-+ PINCTRL_PIN(47, "GPIO_47"),
-+ PINCTRL_PIN(48, "GPIO_48"),
-+ PINCTRL_PIN(49, "GPIO_49"),
-+ PINCTRL_PIN(50, "GPIO_50"),
-+ PINCTRL_PIN(51, "GPIO_51"),
-+ PINCTRL_PIN(52, "GPIO_52"),
-+ PINCTRL_PIN(53, "GPIO_53"),
-+ PINCTRL_PIN(54, "GPIO_54"),
-+ PINCTRL_PIN(55, "GPIO_55"),
-+ PINCTRL_PIN(56, "GPIO_56"),
-+ PINCTRL_PIN(57, "GPIO_57"),
-+ PINCTRL_PIN(58, "GPIO_58"),
-+ PINCTRL_PIN(59, "GPIO_59"),
-+ PINCTRL_PIN(60, "GPIO_60"),
-+ PINCTRL_PIN(61, "GPIO_61"),
-+ PINCTRL_PIN(62, "GPIO_62"),
-+ PINCTRL_PIN(63, "GPIO_63"),
-+ PINCTRL_PIN(64, "GPIO_64"),
-+ PINCTRL_PIN(65, "GPIO_65"),
-+ PINCTRL_PIN(66, "GPIO_66"),
-+ PINCTRL_PIN(67, "GPIO_67"),
-+ PINCTRL_PIN(68, "GPIO_68"),
-+ PINCTRL_PIN(69, "GPIO_69"),
-+ PINCTRL_PIN(70, "GPIO_70"),
-+ PINCTRL_PIN(71, "GPIO_71"),
-+ PINCTRL_PIN(72, "GPIO_72"),
-+ PINCTRL_PIN(73, "GPIO_73"),
-+ PINCTRL_PIN(74, "GPIO_74"),
-+ PINCTRL_PIN(75, "GPIO_75"),
-+ PINCTRL_PIN(76, "GPIO_76"),
-+ PINCTRL_PIN(77, "GPIO_77"),
-+ PINCTRL_PIN(78, "GPIO_78"),
-+ PINCTRL_PIN(79, "GPIO_79"),
-+ PINCTRL_PIN(80, "GPIO_80"),
-+ PINCTRL_PIN(81, "GPIO_81"),
-+ PINCTRL_PIN(82, "GPIO_82"),
-+ PINCTRL_PIN(83, "GPIO_83"),
-+ PINCTRL_PIN(84, "GPIO_84"),
-+ PINCTRL_PIN(85, "GPIO_85"),
-+ PINCTRL_PIN(86, "GPIO_86"),
-+ PINCTRL_PIN(87, "GPIO_87"),
-+ PINCTRL_PIN(88, "GPIO_88"),
-+ PINCTRL_PIN(89, "GPIO_89"),
-+};
-+
-+#define DECLARE_APQ_GPIO_PINS(pin) static const unsigned int gpio##pin##_pins[] = { pin }
-+DECLARE_APQ_GPIO_PINS(0);
-+DECLARE_APQ_GPIO_PINS(1);
-+DECLARE_APQ_GPIO_PINS(2);
-+DECLARE_APQ_GPIO_PINS(3);
-+DECLARE_APQ_GPIO_PINS(4);
-+DECLARE_APQ_GPIO_PINS(5);
-+DECLARE_APQ_GPIO_PINS(6);
-+DECLARE_APQ_GPIO_PINS(7);
-+DECLARE_APQ_GPIO_PINS(8);
-+DECLARE_APQ_GPIO_PINS(9);
-+DECLARE_APQ_GPIO_PINS(10);
-+DECLARE_APQ_GPIO_PINS(11);
-+DECLARE_APQ_GPIO_PINS(12);
-+DECLARE_APQ_GPIO_PINS(13);
-+DECLARE_APQ_GPIO_PINS(14);
-+DECLARE_APQ_GPIO_PINS(15);
-+DECLARE_APQ_GPIO_PINS(16);
-+DECLARE_APQ_GPIO_PINS(17);
-+DECLARE_APQ_GPIO_PINS(18);
-+DECLARE_APQ_GPIO_PINS(19);
-+DECLARE_APQ_GPIO_PINS(20);
-+DECLARE_APQ_GPIO_PINS(21);
-+DECLARE_APQ_GPIO_PINS(22);
-+DECLARE_APQ_GPIO_PINS(23);
-+DECLARE_APQ_GPIO_PINS(24);
-+DECLARE_APQ_GPIO_PINS(25);
-+DECLARE_APQ_GPIO_PINS(26);
-+DECLARE_APQ_GPIO_PINS(27);
-+DECLARE_APQ_GPIO_PINS(28);
-+DECLARE_APQ_GPIO_PINS(29);
-+DECLARE_APQ_GPIO_PINS(30);
-+DECLARE_APQ_GPIO_PINS(31);
-+DECLARE_APQ_GPIO_PINS(32);
-+DECLARE_APQ_GPIO_PINS(33);
-+DECLARE_APQ_GPIO_PINS(34);
-+DECLARE_APQ_GPIO_PINS(35);
-+DECLARE_APQ_GPIO_PINS(36);
-+DECLARE_APQ_GPIO_PINS(37);
-+DECLARE_APQ_GPIO_PINS(38);
-+DECLARE_APQ_GPIO_PINS(39);
-+DECLARE_APQ_GPIO_PINS(40);
-+DECLARE_APQ_GPIO_PINS(41);
-+DECLARE_APQ_GPIO_PINS(42);
-+DECLARE_APQ_GPIO_PINS(43);
-+DECLARE_APQ_GPIO_PINS(44);
-+DECLARE_APQ_GPIO_PINS(45);
-+DECLARE_APQ_GPIO_PINS(46);
-+DECLARE_APQ_GPIO_PINS(47);
-+DECLARE_APQ_GPIO_PINS(48);
-+DECLARE_APQ_GPIO_PINS(49);
-+DECLARE_APQ_GPIO_PINS(50);
-+DECLARE_APQ_GPIO_PINS(51);
-+DECLARE_APQ_GPIO_PINS(52);
-+DECLARE_APQ_GPIO_PINS(53);
-+DECLARE_APQ_GPIO_PINS(54);
-+DECLARE_APQ_GPIO_PINS(55);
-+DECLARE_APQ_GPIO_PINS(56);
-+DECLARE_APQ_GPIO_PINS(57);
-+DECLARE_APQ_GPIO_PINS(58);
-+DECLARE_APQ_GPIO_PINS(59);
-+DECLARE_APQ_GPIO_PINS(60);
-+DECLARE_APQ_GPIO_PINS(61);
-+DECLARE_APQ_GPIO_PINS(62);
-+DECLARE_APQ_GPIO_PINS(63);
-+DECLARE_APQ_GPIO_PINS(64);
-+DECLARE_APQ_GPIO_PINS(65);
-+DECLARE_APQ_GPIO_PINS(66);
-+DECLARE_APQ_GPIO_PINS(67);
-+DECLARE_APQ_GPIO_PINS(68);
-+DECLARE_APQ_GPIO_PINS(69);
-+DECLARE_APQ_GPIO_PINS(70);
-+DECLARE_APQ_GPIO_PINS(71);
-+DECLARE_APQ_GPIO_PINS(72);
-+DECLARE_APQ_GPIO_PINS(73);
-+DECLARE_APQ_GPIO_PINS(74);
-+DECLARE_APQ_GPIO_PINS(75);
-+DECLARE_APQ_GPIO_PINS(76);
-+DECLARE_APQ_GPIO_PINS(77);
-+DECLARE_APQ_GPIO_PINS(78);
-+DECLARE_APQ_GPIO_PINS(79);
-+DECLARE_APQ_GPIO_PINS(80);
-+DECLARE_APQ_GPIO_PINS(81);
-+DECLARE_APQ_GPIO_PINS(82);
-+DECLARE_APQ_GPIO_PINS(83);
-+DECLARE_APQ_GPIO_PINS(84);
-+DECLARE_APQ_GPIO_PINS(85);
-+DECLARE_APQ_GPIO_PINS(86);
-+DECLARE_APQ_GPIO_PINS(87);
-+DECLARE_APQ_GPIO_PINS(88);
-+DECLARE_APQ_GPIO_PINS(89);
-+
-+#define FUNCTION(fname) \
-+ [APQ_MUX_##fname] = { \
-+ .name = #fname, \
-+ .groups = fname##_groups, \
-+ .ngroups = ARRAY_SIZE(fname##_groups), \
-+ }
-+
-+#define PINGROUP(id, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10) \
-+ { \
-+ .name = "gpio" #id, \
-+ .pins = gpio##id##_pins, \
-+ .npins = ARRAY_SIZE(gpio##id##_pins), \
-+ .funcs = (int[]){ \
-+ APQ_MUX_NA, /* gpio mode */ \
-+ APQ_MUX_##f1, \
-+ APQ_MUX_##f2, \
-+ APQ_MUX_##f3, \
-+ APQ_MUX_##f4, \
-+ APQ_MUX_##f5, \
-+ APQ_MUX_##f6, \
-+ APQ_MUX_##f7, \
-+ APQ_MUX_##f8, \
-+ APQ_MUX_##f9, \
-+ APQ_MUX_##f10, \
-+ }, \
-+ .nfuncs = 11, \
-+ .ctl_reg = 0x1000 + 0x10 * id, \
-+ .io_reg = 0x1004 + 0x10 * id, \
-+ .intr_cfg_reg = 0x1008 + 0x10 * id, \
-+ .intr_status_reg = 0x100c + 0x10 * id, \
-+ .intr_target_reg = 0x400 + 0x4 * id, \
-+ .mux_bit = 2, \
-+ .pull_bit = 0, \
-+ .drv_bit = 6, \
-+ .oe_bit = 9, \
-+ .in_bit = 0, \
-+ .out_bit = 1, \
-+ .intr_enable_bit = 0, \
-+ .intr_status_bit = 0, \
-+ .intr_ack_high = 1, \
-+ .intr_target_bit = 0, \
-+ .intr_raw_status_bit = 3, \
-+ .intr_polarity_bit = 1, \
-+ .intr_detection_bit = 2, \
-+ .intr_detection_width = 1, \
-+ }
-+
-+enum apq8064_functions {
-+ APQ_MUX_cam_mclk,
-+ APQ_MUX_codec_mic_i2s,
-+ APQ_MUX_codec_spkr_i2s,
-+ APQ_MUX_gsbi1,
-+ APQ_MUX_gsbi2,
-+ APQ_MUX_gsbi3,
-+ APQ_MUX_gsbi4,
-+ APQ_MUX_gsbi4_cam_i2c,
-+ APQ_MUX_gsbi5,
-+ APQ_MUX_gsbi5_spi_cs1,
-+ APQ_MUX_gsbi5_spi_cs2,
-+ APQ_MUX_gsbi5_spi_cs3,
-+ APQ_MUX_gsbi6,
-+ APQ_MUX_gsbi6_spi_cs1,
-+ APQ_MUX_gsbi6_spi_cs2,
-+ APQ_MUX_gsbi6_spi_cs3,
-+ APQ_MUX_gsbi7,
-+ APQ_MUX_gsbi7_spi_cs1,
-+ APQ_MUX_gsbi7_spi_cs2,
-+ APQ_MUX_gsbi7_spi_cs3,
-+ APQ_MUX_gsbi_cam_i2c,
-+ APQ_MUX_hdmi,
-+ APQ_MUX_mi2s,
-+ APQ_MUX_riva_bt,
-+ APQ_MUX_riva_fm,
-+ APQ_MUX_riva_wlan,
-+ APQ_MUX_sdc2,
-+ APQ_MUX_sdc4,
-+ APQ_MUX_slimbus,
-+ APQ_MUX_spkr_i2s,
-+ APQ_MUX_tsif1,
-+ APQ_MUX_tsif2,
-+ APQ_MUX_usb2_hsic,
-+ APQ_MUX_NA,
-+};
-+
-+static const char * const cam_mclk_groups[] = {
-+ "gpio4" "gpio5"
-+};
-+static const char * const codec_mic_i2s_groups[] = {
-+ "gpio34", "gpio35", "gpio36", "gpio37", "gpio38"
-+};
-+static const char * const codec_spkr_i2s_groups[] = {
-+ "gpio39", "gpio40", "gpio41", "gpio42"
-+};
-+static const char * const gsbi1_groups[] = {
-+ "gpio18", "gpio19", "gpio20", "gpio21"
-+};
-+static const char * const gsbi2_groups[] = {
-+ "gpio22", "gpio23", "gpio24", "gpio25"
-+};
-+static const char * const gsbi3_groups[] = {
-+ "gpio6", "gpio7", "gpio8", "gpio9"
-+};
-+static const char * const gsbi4_groups[] = {
-+ "gpio10", "gpio11", "gpio12", "gpio13"
-+};
-+static const char * const gsbi4_cam_i2c_groups[] = {
-+ "gpio10", "gpio11", "gpio12", "gpio13"
-+};
-+static const char * const gsbi5_groups[] = {
-+ "gpio51", "gpio52", "gpio53", "gpio54"
-+};
-+static const char * const gsbi5_spi_cs1_groups[] = {
-+ "gpio47"
-+};
-+static const char * const gsbi5_spi_cs2_groups[] = {
-+ "gpio31"
-+};
-+static const char * const gsbi5_spi_cs3_groups[] = {
-+ "gpio32"
-+};
-+static const char * const gsbi6_groups[] = {
-+ "gpio14", "gpio15", "gpio16", "gpio17"
-+};
-+static const char * const gsbi6_spi_cs1_groups[] = {
-+ "gpio47"
-+};
-+static const char * const gsbi6_spi_cs2_groups[] = {
-+ "gpio31"
-+};
-+static const char * const gsbi6_spi_cs3_groups[] = {
-+ "gpio32"
-+};
-+static const char * const gsbi7_groups[] = {
-+ "gpio82", "gpio83", "gpio84", "gpio85"
-+};
-+static const char * const gsbi7_spi_cs1_groups[] = {
-+ "gpio47"
-+};
-+static const char * const gsbi7_spi_cs2_groups[] = {
-+ "gpio31"
-+};
-+static const char * const gsbi7_spi_cs3_groups[] = {
-+ "gpio32"
-+};
-+static const char * const gsbi_cam_i2c_groups[] = {
-+ "gpio10", "gpio11", "gpio12", "gpio13"
-+};
-+static const char * const hdmi_groups[] = {
-+ "gpio69", "gpio70", "gpio71", "gpio72"
-+};
-+static const char * const mi2s_groups[] = {
-+ "gpio27", "gpio28", "gpio29", "gpio30", "gpio31", "gpio32", "gpio33"
-+};
-+static const char * const riva_bt_groups[] = {
-+ "gpio16", "gpio17"
-+};
-+static const char * const riva_fm_groups[] = {
-+ "gpio14", "gpio15"
-+};
-+static const char * const riva_wlan_groups[] = {
-+ "gpio64", "gpio65", "gpio66", "gpio67", "gpio68"
-+};
-+static const char * const sdc2_groups[] = {
-+ "gpio57", "gpio58", "gpio59", "gpio60", "gpio61", "gpio62"
-+};
-+static const char * const sdc4_groups[] = {
-+ "gpio63", "gpio64", "gpio65", "gpio66", "gpio67", "gpio68"
-+};
-+static const char * const slimbus_groups[] = {
-+ "gpio40", "gpio41"
-+};
-+static const char * const spkr_i2s_groups[] = {
-+ "gpio47", "gpio48", "gpio49", "gpio50"
-+};
-+static const char * const tsif1_groups[] = {
-+ "gpio55", "gpio56", "gpio57"
-+};
-+static const char * const tsif2_groups[] = {
-+ "gpio58", "gpio59", "gpio60"
-+};
-+static const char * const usb2_hsic_groups[] = {
-+ "gpio88", "gpio89"
-+};
-+
-+static const struct msm_function apq8064_functions[] = {
-+ FUNCTION(cam_mclk),
-+ FUNCTION(codec_mic_i2s),
-+ FUNCTION(codec_spkr_i2s),
-+ FUNCTION(gsbi1),
-+ FUNCTION(gsbi2),
-+ FUNCTION(gsbi3),
-+ FUNCTION(gsbi4),
-+ FUNCTION(gsbi4_cam_i2c),
-+ FUNCTION(gsbi5),
-+ FUNCTION(gsbi5_spi_cs1),
-+ FUNCTION(gsbi5_spi_cs2),
-+ FUNCTION(gsbi5_spi_cs3),
-+ FUNCTION(gsbi6),
-+ FUNCTION(gsbi6_spi_cs1),
-+ FUNCTION(gsbi6_spi_cs2),
-+ FUNCTION(gsbi6_spi_cs3),
-+ FUNCTION(gsbi7),
-+ FUNCTION(gsbi7_spi_cs1),
-+ FUNCTION(gsbi7_spi_cs2),
-+ FUNCTION(gsbi7_spi_cs3),
-+ FUNCTION(gsbi_cam_i2c),
-+ FUNCTION(hdmi),
-+ FUNCTION(mi2s),
-+ FUNCTION(riva_bt),
-+ FUNCTION(riva_fm),
-+ FUNCTION(riva_wlan),
-+ FUNCTION(sdc2),
-+ FUNCTION(sdc4),
-+ FUNCTION(slimbus),
-+ FUNCTION(spkr_i2s),
-+ FUNCTION(tsif1),
-+ FUNCTION(tsif2),
-+ FUNCTION(usb2_hsic),
-+};
-+
-+static const struct msm_pingroup apq8064_groups[] = {
-+ PINGROUP(0, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-+ PINGROUP(1, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-+ PINGROUP(2, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-+ PINGROUP(3, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-+ PINGROUP(4, NA, NA, cam_mclk, NA, NA, NA, NA, NA, NA, NA),
-+ PINGROUP(5, NA, cam_mclk, NA, NA, NA, NA, NA, NA, NA, NA),
-+ PINGROUP(6, gsbi3, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-+ PINGROUP(7, gsbi3, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-+ PINGROUP(8, gsbi3, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-+ PINGROUP(9, gsbi3, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-+ PINGROUP(10, gsbi4, NA, NA, NA, NA, NA, NA, NA, gsbi4_cam_i2c, NA),
-+ PINGROUP(11, gsbi4, NA, NA, NA, NA, NA, NA, NA, NA, gsbi4_cam_i2c),
-+ PINGROUP(12, gsbi4, NA, NA, NA, NA, gsbi4_cam_i2c, NA, NA, NA, NA),
-+ PINGROUP(13, gsbi4, NA, NA, NA, NA, gsbi4_cam_i2c, NA, NA, NA, NA),
-+ PINGROUP(14, riva_fm, gsbi6, NA, NA, NA, NA, NA, NA, NA, NA),
-+ PINGROUP(15, riva_fm, gsbi6, NA, NA, NA, NA, NA, NA, NA, NA),
-+ PINGROUP(16, riva_bt, gsbi6, NA, NA, NA, NA, NA, NA, NA, NA),
-+ PINGROUP(17, riva_bt, gsbi6, NA, NA, NA, NA, NA, NA, NA, NA),
-+ PINGROUP(18, gsbi1, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-+ PINGROUP(19, gsbi1, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-+ PINGROUP(20, gsbi1, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-+ PINGROUP(21, gsbi1, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-+ PINGROUP(22, gsbi2, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-+ PINGROUP(23, gsbi2, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-+ PINGROUP(24, gsbi2, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-+ PINGROUP(25, gsbi2, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-+ PINGROUP(26, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-+ PINGROUP(27, mi2s, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-+ PINGROUP(28, mi2s, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-+ PINGROUP(29, mi2s, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-+ PINGROUP(30, mi2s, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-+ PINGROUP(31, mi2s, NA, gsbi5_spi_cs2, gsbi6_spi_cs2, gsbi7_spi_cs2, NA, NA, NA, NA, NA),
-+ PINGROUP(32, mi2s, NA, NA, NA, NA, gsbi5_spi_cs3, gsbi6_spi_cs3, gsbi7_spi_cs3, NA, NA),
-+ PINGROUP(33, mi2s, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-+ PINGROUP(34, codec_mic_i2s, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-+ PINGROUP(35, codec_mic_i2s, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-+ PINGROUP(36, codec_mic_i2s, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-+ PINGROUP(37, codec_mic_i2s, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-+ PINGROUP(38, codec_mic_i2s, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-+ PINGROUP(39, codec_spkr_i2s, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-+ PINGROUP(40, slimbus, codec_spkr_i2s, NA, NA, NA, NA, NA, NA, NA, NA),
-+ PINGROUP(41, slimbus, codec_spkr_i2s, NA, NA, NA, NA, NA, NA, NA, NA),
-+ PINGROUP(42, codec_spkr_i2s, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-+ PINGROUP(43, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-+ PINGROUP(44, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-+ PINGROUP(45, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-+ PINGROUP(46, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-+ PINGROUP(47, spkr_i2s, gsbi5_spi_cs1, gsbi6_spi_cs1, gsbi7_spi_cs1, NA, NA, NA, NA, NA, NA),
-+ PINGROUP(48, spkr_i2s, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-+ PINGROUP(49, spkr_i2s, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-+ PINGROUP(50, spkr_i2s, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-+ PINGROUP(51, NA, gsbi5, NA, NA, NA, NA, NA, NA, NA, NA),
-+ PINGROUP(52, NA, gsbi5, NA, NA, NA, NA, NA, NA, NA, NA),
-+ PINGROUP(53, NA, gsbi5, NA, NA, NA, NA, NA, NA, NA, NA),
-+ PINGROUP(54, NA, gsbi5, NA, NA, NA, NA, NA, NA, NA, NA),
-+ PINGROUP(55, tsif1, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-+ PINGROUP(56, tsif1, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-+ PINGROUP(57, tsif1, sdc2, NA, NA, NA, NA, NA, NA, NA, NA),
-+ PINGROUP(58, tsif2, sdc2, NA, NA, NA, NA, NA, NA, NA, NA),
-+ PINGROUP(59, tsif2, sdc2, NA, NA, NA, NA, NA, NA, NA, NA),
-+ PINGROUP(60, tsif2, sdc2, NA, NA, NA, NA, NA, NA, NA, NA),
-+ PINGROUP(61, NA, sdc2, NA, NA, NA, NA, NA, NA, NA, NA),
-+ PINGROUP(62, NA, sdc2, NA, NA, NA, NA, NA, NA, NA, NA),
-+ PINGROUP(63, NA, sdc4, NA, NA, NA, NA, NA, NA, NA, NA),
-+ PINGROUP(64, riva_wlan, sdc4, NA, NA, NA, NA, NA, NA, NA, NA),
-+ PINGROUP(65, riva_wlan, sdc4, NA, NA, NA, NA, NA, NA, NA, NA),
-+ PINGROUP(66, riva_wlan, sdc4, NA, NA, NA, NA, NA, NA, NA, NA),
-+ PINGROUP(67, riva_wlan, sdc4, NA, NA, NA, NA, NA, NA, NA, NA),
-+ PINGROUP(68, riva_wlan, sdc4, NA, NA, NA, NA, NA, NA, NA, NA),
-+ PINGROUP(69, hdmi, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-+ PINGROUP(70, hdmi, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-+ PINGROUP(71, hdmi, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-+ PINGROUP(72, hdmi, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-+ PINGROUP(73, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-+ PINGROUP(74, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-+ PINGROUP(75, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-+ PINGROUP(76, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-+ PINGROUP(77, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-+ PINGROUP(78, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-+ PINGROUP(79, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-+ PINGROUP(80, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-+ PINGROUP(81, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-+ PINGROUP(82, NA, gsbi7, NA, NA, NA, NA, NA, NA, NA, NA),
-+ PINGROUP(83, gsbi7, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-+ PINGROUP(84, NA, gsbi7, NA, NA, NA, NA, NA, NA, NA, NA),
-+ PINGROUP(85, NA, NA, gsbi7, NA, NA, NA, NA, NA, NA, NA),
-+ PINGROUP(86, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-+ PINGROUP(87, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-+ PINGROUP(88, usb2_hsic, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-+ PINGROUP(89, usb2_hsic, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-+};
-+
-+#define NUM_GPIO_PINGROUPS 90
-+
-+static const struct msm_pinctrl_soc_data apq8064_pinctrl = {
-+ .pins = apq8064_pins,
-+ .npins = ARRAY_SIZE(apq8064_pins),
-+ .functions = apq8064_functions,
-+ .nfunctions = ARRAY_SIZE(apq8064_functions),
-+ .groups = apq8064_groups,
-+ .ngroups = ARRAY_SIZE(apq8064_groups),
-+ .ngpios = NUM_GPIO_PINGROUPS,
-+};
-+
-+static int apq8064_pinctrl_probe(struct platform_device *pdev)
-+{
-+ return msm_pinctrl_probe(pdev, &apq8064_pinctrl);
-+}
-+
-+static const struct of_device_id apq8064_pinctrl_of_match[] = {
-+ { .compatible = "qcom,apq8064-pinctrl", },
-+ { },
-+};
-+
-+static struct platform_driver apq8064_pinctrl_driver = {
-+ .driver = {
-+ .name = "apq8064-pinctrl",
-+ .owner = THIS_MODULE,
-+ .of_match_table = apq8064_pinctrl_of_match,
-+ },
-+ .probe = apq8064_pinctrl_probe,
-+ .remove = msm_pinctrl_remove,
-+};
-+
-+static int __init apq8064_pinctrl_init(void)
-+{
-+ return platform_driver_register(&apq8064_pinctrl_driver);
-+}
-+arch_initcall(apq8064_pinctrl_init);
-+
-+static void __exit apq8064_pinctrl_exit(void)
-+{
-+ platform_driver_unregister(&apq8064_pinctrl_driver);
-+}
-+module_exit(apq8064_pinctrl_exit);
-+
-+MODULE_AUTHOR("Bjorn Andersson <bjorn.andersson@sonymobile.com>");
-+MODULE_DESCRIPTION("Qualcomm APQ8064 pinctrl driver");
-+MODULE_LICENSE("GPL v2");
-+MODULE_DEVICE_TABLE(of, apq8064_pinctrl_of_match);
diff --git a/target/linux/ipq806x/patches/0039-pinctrl-msm8x74-make-Kconfig-dependency-more-strict.patch b/target/linux/ipq806x/patches/0039-pinctrl-msm8x74-make-Kconfig-dependency-more-strict.patch
deleted file mode 100644
index 7c56af6..0000000
--- a/target/linux/ipq806x/patches/0039-pinctrl-msm8x74-make-Kconfig-dependency-more-strict.patch
+++ /dev/null
@@ -1,31 +0,0 @@
-From 8605197c200786888415bf2e30d1fbde6ba8ba03 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= <u.kleine-koenig@pengutronix.de>
-Date: Tue, 1 Apr 2014 22:25:59 +0200
-Subject: [PATCH 039/182] pinctrl: msm8x74: make Kconfig dependency more
- strict
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-This driver is only useful on MSM8x74, so let the driver depend on
-ARCH_QCOM but allow compile coverage testing.
-The main benefit is that the driver isn't available to be selected for
-machines that don't have the matching hardware.
-
-Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
-Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
----
- drivers/pinctrl/Kconfig | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/drivers/pinctrl/Kconfig
-+++ b/drivers/pinctrl/Kconfig
-@@ -232,7 +232,7 @@ config PINCTRL_APQ8064
-
- config PINCTRL_MSM8X74
- tristate "Qualcomm 8x74 pin controller driver"
-- depends on GPIOLIB && OF
-+ depends on GPIOLIB && OF && (ARCH_QCOM || COMPILE_TEST)
- select PINCTRL_MSM
- help
- This is the pinctrl, pinmux, pinconf and gpiolib driver for the
diff --git a/target/linux/ipq806x/patches/0040-pinctrl-qcom-Add-definitions-for-IPQ8064.patch b/target/linux/ipq806x/patches/0040-pinctrl-qcom-Add-definitions-for-IPQ8064.patch
deleted file mode 100644
index a54604a..0000000
--- a/target/linux/ipq806x/patches/0040-pinctrl-qcom-Add-definitions-for-IPQ8064.patch
+++ /dev/null
@@ -1,701 +0,0 @@
-From 9bbd9d7e40944ca95e07f363b68700225beb9bef Mon Sep 17 00:00:00 2001
-From: Andy Gross <agross@codeaurora.org>
-Date: Mon, 14 Apr 2014 22:10:35 -0500
-Subject: [PATCH 040/182] pinctrl: qcom: Add definitions for IPQ8064
-
-This adds pinctrl definitions for the GPIO pins of the TLMM v2 block in the
-Qualcomm IPQ8064 platform.
-
-Signed-off-by: Andy Gross <agross@codeaurora.org>
-Reviewed-by: Bjorn Andersson <bjorn.andersson@sonymobile.com>
-Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
----
- drivers/pinctrl/Kconfig | 8 +
- drivers/pinctrl/Makefile | 1 +
- drivers/pinctrl/pinctrl-ipq8064.c | 653 +++++++++++++++++++++++++++++++++++++
- 3 files changed, 662 insertions(+)
- create mode 100644 drivers/pinctrl/pinctrl-ipq8064.c
-
---- a/drivers/pinctrl/Kconfig
-+++ b/drivers/pinctrl/Kconfig
-@@ -230,6 +230,14 @@ config PINCTRL_APQ8064
- This is the pinctrl, pinmux, pinconf and gpiolib driver for the
- Qualcomm TLMM block found in the Qualcomm APQ8064 platform.
-
-+config PINCTRL_IPQ8064
-+ tristate "Qualcomm IPQ8064 pin controller driver"
-+ depends on GPIOLIB && OF
-+ select PINCTRL_MSM
-+ help
-+ This is the pinctrl, pinmux, pinconf and gpiolib driver for the
-+ Qualcomm TLMM block found in the Qualcomm IPQ8064 platform.
-+
- config PINCTRL_MSM8X74
- tristate "Qualcomm 8x74 pin controller driver"
- depends on GPIOLIB && OF && (ARCH_QCOM || COMPILE_TEST)
---- a/drivers/pinctrl/Makefile
-+++ b/drivers/pinctrl/Makefile
-@@ -39,6 +39,7 @@ obj-$(CONFIG_PINCTRL_IMX25) += pinctrl-i
- obj-$(CONFIG_PINCTRL_IMX28) += pinctrl-imx28.o
- obj-$(CONFIG_PINCTRL_MSM) += pinctrl-msm.o
- obj-$(CONFIG_PINCTRL_APQ8064) += pinctrl-apq8064.o
-+obj-$(CONFIG_PINCTRL_IPQ8064) += pinctrl-ipq8064.o
- obj-$(CONFIG_PINCTRL_MSM8X74) += pinctrl-msm8x74.o
- obj-$(CONFIG_PINCTRL_NOMADIK) += pinctrl-nomadik.o
- obj-$(CONFIG_PINCTRL_STN8815) += pinctrl-nomadik-stn8815.o
---- /dev/null
-+++ b/drivers/pinctrl/pinctrl-ipq8064.c
-@@ -0,0 +1,653 @@
-+/*
-+ * Copyright (c) 2014, The Linux Foundation. All rights reserved.
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 and
-+ * only version 2 as published by the Free Software Foundation.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ * GNU General Public License for more details.
-+ *
-+ */
-+
-+#include <linux/module.h>
-+#include <linux/of.h>
-+#include <linux/platform_device.h>
-+#include <linux/pinctrl/pinctrl.h>
-+
-+#include "pinctrl-msm.h"
-+
-+static const struct pinctrl_pin_desc ipq8064_pins[] = {
-+ PINCTRL_PIN(0, "GPIO_1"),
-+ PINCTRL_PIN(1, "GPIO_1"),
-+ PINCTRL_PIN(2, "GPIO_2"),
-+ PINCTRL_PIN(3, "GPIO_3"),
-+ PINCTRL_PIN(4, "GPIO_4"),
-+ PINCTRL_PIN(5, "GPIO_5"),
-+ PINCTRL_PIN(6, "GPIO_6"),
-+ PINCTRL_PIN(7, "GPIO_7"),
-+ PINCTRL_PIN(8, "GPIO_8"),
-+ PINCTRL_PIN(9, "GPIO_9"),
-+ PINCTRL_PIN(10, "GPIO_10"),
-+ PINCTRL_PIN(11, "GPIO_11"),
-+ PINCTRL_PIN(12, "GPIO_12"),
-+ PINCTRL_PIN(13, "GPIO_13"),
-+ PINCTRL_PIN(14, "GPIO_14"),
-+ PINCTRL_PIN(15, "GPIO_15"),
-+ PINCTRL_PIN(16, "GPIO_16"),
-+ PINCTRL_PIN(17, "GPIO_17"),
-+ PINCTRL_PIN(18, "GPIO_18"),
-+ PINCTRL_PIN(19, "GPIO_19"),
-+ PINCTRL_PIN(20, "GPIO_20"),
-+ PINCTRL_PIN(21, "GPIO_21"),
-+ PINCTRL_PIN(22, "GPIO_22"),
-+ PINCTRL_PIN(23, "GPIO_23"),
-+ PINCTRL_PIN(24, "GPIO_24"),
-+ PINCTRL_PIN(25, "GPIO_25"),
-+ PINCTRL_PIN(26, "GPIO_26"),
-+ PINCTRL_PIN(27, "GPIO_27"),
-+ PINCTRL_PIN(28, "GPIO_28"),
-+ PINCTRL_PIN(29, "GPIO_29"),
-+ PINCTRL_PIN(30, "GPIO_30"),
-+ PINCTRL_PIN(31, "GPIO_31"),
-+ PINCTRL_PIN(32, "GPIO_32"),
-+ PINCTRL_PIN(33, "GPIO_33"),
-+ PINCTRL_PIN(34, "GPIO_34"),
-+ PINCTRL_PIN(35, "GPIO_35"),
-+ PINCTRL_PIN(36, "GPIO_36"),
-+ PINCTRL_PIN(37, "GPIO_37"),
-+ PINCTRL_PIN(38, "GPIO_38"),
-+ PINCTRL_PIN(39, "GPIO_39"),
-+ PINCTRL_PIN(40, "GPIO_40"),
-+ PINCTRL_PIN(41, "GPIO_41"),
-+ PINCTRL_PIN(42, "GPIO_42"),
-+ PINCTRL_PIN(43, "GPIO_43"),
-+ PINCTRL_PIN(44, "GPIO_44"),
-+ PINCTRL_PIN(45, "GPIO_45"),
-+ PINCTRL_PIN(46, "GPIO_46"),
-+ PINCTRL_PIN(47, "GPIO_47"),
-+ PINCTRL_PIN(48, "GPIO_48"),
-+ PINCTRL_PIN(49, "GPIO_49"),
-+ PINCTRL_PIN(50, "GPIO_50"),
-+ PINCTRL_PIN(51, "GPIO_51"),
-+ PINCTRL_PIN(52, "GPIO_52"),
-+ PINCTRL_PIN(53, "GPIO_53"),
-+ PINCTRL_PIN(54, "GPIO_54"),
-+ PINCTRL_PIN(55, "GPIO_55"),
-+ PINCTRL_PIN(56, "GPIO_56"),
-+ PINCTRL_PIN(57, "GPIO_57"),
-+ PINCTRL_PIN(58, "GPIO_58"),
-+ PINCTRL_PIN(59, "GPIO_59"),
-+ PINCTRL_PIN(60, "GPIO_60"),
-+ PINCTRL_PIN(61, "GPIO_61"),
-+ PINCTRL_PIN(62, "GPIO_62"),
-+ PINCTRL_PIN(63, "GPIO_63"),
-+ PINCTRL_PIN(64, "GPIO_64"),
-+ PINCTRL_PIN(65, "GPIO_65"),
-+ PINCTRL_PIN(66, "GPIO_66"),
-+ PINCTRL_PIN(67, "GPIO_67"),
-+ PINCTRL_PIN(68, "GPIO_68"),
-+
-+ PINCTRL_PIN(69, "SDC3_CLK"),
-+ PINCTRL_PIN(70, "SDC3_CMD"),
-+ PINCTRL_PIN(71, "SDC3_DATA"),
-+};
-+
-+#define DECLARE_IPQ_GPIO_PINS(pin) static const unsigned int gpio##pin##_pins[] = { pin }
-+DECLARE_IPQ_GPIO_PINS(0);
-+DECLARE_IPQ_GPIO_PINS(1);
-+DECLARE_IPQ_GPIO_PINS(2);
-+DECLARE_IPQ_GPIO_PINS(3);
-+DECLARE_IPQ_GPIO_PINS(4);
-+DECLARE_IPQ_GPIO_PINS(5);
-+DECLARE_IPQ_GPIO_PINS(6);
-+DECLARE_IPQ_GPIO_PINS(7);
-+DECLARE_IPQ_GPIO_PINS(8);
-+DECLARE_IPQ_GPIO_PINS(9);
-+DECLARE_IPQ_GPIO_PINS(10);
-+DECLARE_IPQ_GPIO_PINS(11);
-+DECLARE_IPQ_GPIO_PINS(12);
-+DECLARE_IPQ_GPIO_PINS(13);
-+DECLARE_IPQ_GPIO_PINS(14);
-+DECLARE_IPQ_GPIO_PINS(15);
-+DECLARE_IPQ_GPIO_PINS(16);
-+DECLARE_IPQ_GPIO_PINS(17);
-+DECLARE_IPQ_GPIO_PINS(18);
-+DECLARE_IPQ_GPIO_PINS(19);
-+DECLARE_IPQ_GPIO_PINS(20);
-+DECLARE_IPQ_GPIO_PINS(21);
-+DECLARE_IPQ_GPIO_PINS(22);
-+DECLARE_IPQ_GPIO_PINS(23);
-+DECLARE_IPQ_GPIO_PINS(24);
-+DECLARE_IPQ_GPIO_PINS(25);
-+DECLARE_IPQ_GPIO_PINS(26);
-+DECLARE_IPQ_GPIO_PINS(27);
-+DECLARE_IPQ_GPIO_PINS(28);
-+DECLARE_IPQ_GPIO_PINS(29);
-+DECLARE_IPQ_GPIO_PINS(30);
-+DECLARE_IPQ_GPIO_PINS(31);
-+DECLARE_IPQ_GPIO_PINS(32);
-+DECLARE_IPQ_GPIO_PINS(33);
-+DECLARE_IPQ_GPIO_PINS(34);
-+DECLARE_IPQ_GPIO_PINS(35);
-+DECLARE_IPQ_GPIO_PINS(36);
-+DECLARE_IPQ_GPIO_PINS(37);
-+DECLARE_IPQ_GPIO_PINS(38);
-+DECLARE_IPQ_GPIO_PINS(39);
-+DECLARE_IPQ_GPIO_PINS(40);
-+DECLARE_IPQ_GPIO_PINS(41);
-+DECLARE_IPQ_GPIO_PINS(42);
-+DECLARE_IPQ_GPIO_PINS(43);
-+DECLARE_IPQ_GPIO_PINS(44);
-+DECLARE_IPQ_GPIO_PINS(45);
-+DECLARE_IPQ_GPIO_PINS(46);
-+DECLARE_IPQ_GPIO_PINS(47);
-+DECLARE_IPQ_GPIO_PINS(48);
-+DECLARE_IPQ_GPIO_PINS(49);
-+DECLARE_IPQ_GPIO_PINS(50);
-+DECLARE_IPQ_GPIO_PINS(51);
-+DECLARE_IPQ_GPIO_PINS(52);
-+DECLARE_IPQ_GPIO_PINS(53);
-+DECLARE_IPQ_GPIO_PINS(54);
-+DECLARE_IPQ_GPIO_PINS(55);
-+DECLARE_IPQ_GPIO_PINS(56);
-+DECLARE_IPQ_GPIO_PINS(57);
-+DECLARE_IPQ_GPIO_PINS(58);
-+DECLARE_IPQ_GPIO_PINS(59);
-+DECLARE_IPQ_GPIO_PINS(60);
-+DECLARE_IPQ_GPIO_PINS(61);
-+DECLARE_IPQ_GPIO_PINS(62);
-+DECLARE_IPQ_GPIO_PINS(63);
-+DECLARE_IPQ_GPIO_PINS(64);
-+DECLARE_IPQ_GPIO_PINS(65);
-+DECLARE_IPQ_GPIO_PINS(66);
-+DECLARE_IPQ_GPIO_PINS(67);
-+DECLARE_IPQ_GPIO_PINS(68);
-+
-+static const unsigned int sdc3_clk_pins[] = { 69 };
-+static const unsigned int sdc3_cmd_pins[] = { 70 };
-+static const unsigned int sdc3_data_pins[] = { 71 };
-+
-+#define FUNCTION(fname) \
-+ [IPQ_MUX_##fname] = { \
-+ .name = #fname, \
-+ .groups = fname##_groups, \
-+ .ngroups = ARRAY_SIZE(fname##_groups), \
-+ }
-+
-+#define PINGROUP(id, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10) \
-+ { \
-+ .name = "gpio" #id, \
-+ .pins = gpio##id##_pins, \
-+ .npins = ARRAY_SIZE(gpio##id##_pins), \
-+ .funcs = (int[]){ \
-+ IPQ_MUX_NA, /* gpio mode */ \
-+ IPQ_MUX_##f1, \
-+ IPQ_MUX_##f2, \
-+ IPQ_MUX_##f3, \
-+ IPQ_MUX_##f4, \
-+ IPQ_MUX_##f5, \
-+ IPQ_MUX_##f6, \
-+ IPQ_MUX_##f7, \
-+ IPQ_MUX_##f8, \
-+ IPQ_MUX_##f9, \
-+ IPQ_MUX_##f10, \
-+ }, \
-+ .nfuncs = 11, \
-+ .ctl_reg = 0x1000 + 0x10 * id, \
-+ .io_reg = 0x1004 + 0x10 * id, \
-+ .intr_cfg_reg = 0x1008 + 0x10 * id, \
-+ .intr_status_reg = 0x100c + 0x10 * id, \
-+ .intr_target_reg = 0x400 + 0x4 * id, \
-+ .mux_bit = 2, \
-+ .pull_bit = 0, \
-+ .drv_bit = 6, \
-+ .oe_bit = 9, \
-+ .in_bit = 0, \
-+ .out_bit = 1, \
-+ .intr_enable_bit = 0, \
-+ .intr_status_bit = 0, \
-+ .intr_ack_high = 1, \
-+ .intr_target_bit = 0, \
-+ .intr_raw_status_bit = 3, \
-+ .intr_polarity_bit = 1, \
-+ .intr_detection_bit = 2, \
-+ .intr_detection_width = 1, \
-+ }
-+
-+#define SDC_PINGROUP(pg_name, ctl, pull, drv) \
-+ { \
-+ .name = #pg_name, \
-+ .pins = pg_name##_pins, \
-+ .npins = ARRAY_SIZE(pg_name##_pins), \
-+ .ctl_reg = ctl, \
-+ .io_reg = 0, \
-+ .intr_cfg_reg = 0, \
-+ .intr_status_reg = 0, \
-+ .intr_target_reg = 0, \
-+ .mux_bit = -1, \
-+ .pull_bit = pull, \
-+ .drv_bit = drv, \
-+ .oe_bit = -1, \
-+ .in_bit = -1, \
-+ .out_bit = -1, \
-+ .intr_enable_bit = -1, \
-+ .intr_status_bit = -1, \
-+ .intr_target_bit = -1, \
-+ .intr_raw_status_bit = -1, \
-+ .intr_polarity_bit = -1, \
-+ .intr_detection_bit = -1, \
-+ .intr_detection_width = -1, \
-+ }
-+
-+enum ipq8064_functions {
-+ IPQ_MUX_mdio,
-+ IPQ_MUX_mi2s,
-+ IPQ_MUX_pdm,
-+ IPQ_MUX_ssbi,
-+ IPQ_MUX_spmi,
-+ IPQ_MUX_audio_pcm,
-+ IPQ_MUX_gsbi1,
-+ IPQ_MUX_gsbi2,
-+ IPQ_MUX_gsbi4,
-+ IPQ_MUX_gsbi5,
-+ IPQ_MUX_gsbi5_spi_cs1,
-+ IPQ_MUX_gsbi5_spi_cs2,
-+ IPQ_MUX_gsbi5_spi_cs3,
-+ IPQ_MUX_gsbi6,
-+ IPQ_MUX_gsbi7,
-+ IPQ_MUX_nss_spi,
-+ IPQ_MUX_sdc1,
-+ IPQ_MUX_spdif,
-+ IPQ_MUX_nand,
-+ IPQ_MUX_tsif1,
-+ IPQ_MUX_tsif2,
-+ IPQ_MUX_usb_fs_n,
-+ IPQ_MUX_usb_fs,
-+ IPQ_MUX_usb2_hsic,
-+ IPQ_MUX_rgmii2,
-+ IPQ_MUX_sata,
-+ IPQ_MUX_pcie1_rst,
-+ IPQ_MUX_pcie1_prsnt,
-+ IPQ_MUX_pcie1_pwrflt,
-+ IPQ_MUX_pcie1_pwren_n,
-+ IPQ_MUX_pcie1_pwren,
-+ IPQ_MUX_pcie1_clk_req,
-+ IPQ_MUX_pcie2_rst,
-+ IPQ_MUX_pcie2_prsnt,
-+ IPQ_MUX_pcie2_pwrflt,
-+ IPQ_MUX_pcie2_pwren_n,
-+ IPQ_MUX_pcie2_pwren,
-+ IPQ_MUX_pcie2_clk_req,
-+ IPQ_MUX_pcie3_rst,
-+ IPQ_MUX_pcie3_prsnt,
-+ IPQ_MUX_pcie3_pwrflt,
-+ IPQ_MUX_pcie3_pwren_n,
-+ IPQ_MUX_pcie3_pwren,
-+ IPQ_MUX_pcie3_clk_req,
-+ IPQ_MUX_ps_hold,
-+ IPQ_MUX_NA,
-+};
-+
-+static const char * const mdio_groups[] = {
-+ "gpio0", "gpio1", "gpio10", "gpio11",
-+};
-+
-+static const char * const mi2s_groups[] = {
-+ "gpio27", "gpio28", "gpio29", "gpio30", "gpio31", "gpio32",
-+ "gpio33", "gpio55", "gpio56", "gpio57", "gpio58",
-+};
-+
-+static const char * const pdm_groups[] = {
-+ "gpio3", "gpio16", "gpio17", "gpio22", "gpio30", "gpio31",
-+ "gpio34", "gpio35", "gpio52", "gpio55", "gpio56", "gpio58",
-+ "gpio59",
-+};
-+
-+static const char * const ssbi_groups[] = {
-+ "gpio10", "gpio11",
-+};
-+
-+static const char * const spmi_groups[] = {
-+ "gpio10", "gpio11",
-+};
-+
-+static const char * const audio_pcm_groups[] = {
-+ "gpio14", "gpio15", "gpio16", "gpio17",
-+};
-+
-+static const char * const gsbi1_groups[] = {
-+ "gpio51", "gpio52", "gpio53", "gpio54",
-+};
-+
-+static const char * const gsbi2_groups[] = {
-+ "gpio22", "gpio23", "gpio24", "gpio25",
-+};
-+
-+static const char * const gsbi4_groups[] = {
-+ "gpio10", "gpio11", "gpio12", "gpio13",
-+};
-+
-+static const char * const gsbi5_groups[] = {
-+ "gpio18", "gpio19", "gpio20", "gpio21",
-+};
-+
-+static const char * const gsbi5_spi_cs1_groups[] = {
-+ "gpio6", "gpio61",
-+};
-+
-+static const char * const gsbi5_spi_cs2_groups[] = {
-+ "gpio7", "gpio62",
-+};
-+
-+static const char * const gsbi5_spi_cs3_groups[] = {
-+ "gpio2",
-+};
-+
-+static const char * const gsbi6_groups[] = {
-+ "gpio27", "gpio28", "gpio29", "gpio30", "gpio55", "gpio56",
-+ "gpio57", "gpio58",
-+};
-+
-+static const char * const gsbi7_groups[] = {
-+ "gpio6", "gpio7", "gpio8", "gpio9",
-+};
-+
-+static const char * const nss_spi_groups[] = {
-+ "gpio14", "gpio15", "gpio16", "gpio17", "gpio55", "gpio56",
-+ "gpio57", "gpio58",
-+};
-+
-+static const char * const sdc1_groups[] = {
-+ "gpio38", "gpio39", "gpio40", "gpio41", "gpio42", "gpio43",
-+ "gpio44", "gpio45", "gpio46", "gpio47",
-+};
-+
-+static const char * const spdif_groups[] = {
-+ "gpio_10", "gpio_48",
-+};
-+
-+static const char * const nand_groups[] = {
-+ "gpio34", "gpio35", "gpio36", "gpio37", "gpio38", "gpio39",
-+ "gpio40", "gpio41", "gpio42", "gpio43", "gpio44", "gpio45",
-+ "gpio46", "gpio47",
-+};
-+
-+static const char * const tsif1_groups[] = {
-+ "gpio55", "gpio56", "gpio57", "gpio58",
-+};
-+
-+static const char * const tsif2_groups[] = {
-+ "gpio59", "gpio60", "gpio61", "gpio62",
-+};
-+
-+static const char * const usb_fs_n_groups[] = {
-+ "gpio6",
-+};
-+
-+static const char * const usb_fs_groups[] = {
-+ "gpio6", "gpio7", "gpio8",
-+};
-+
-+static const char * const usb2_hsic_groups[] = {
-+ "gpio67", "gpio68",
-+};
-+
-+static const char * const rgmii2_groups[] = {
-+ "gpio27", "gpio28", "gpio29", "gpio30", "gpio31", "gpio32",
-+ "gpio51", "gpio52", "gpio59", "gpio60", "gpio61", "gpio62",
-+};
-+
-+static const char * const sata_groups[] = {
-+ "gpio10",
-+};
-+
-+static const char * const pcie1_rst_groups[] = {
-+ "gpio3",
-+};
-+
-+static const char * const pcie1_prsnt_groups[] = {
-+ "gpio3", "gpio11",
-+};
-+
-+static const char * const pcie1_pwren_n_groups[] = {
-+ "gpio4", "gpio12",
-+};
-+
-+static const char * const pcie1_pwren_groups[] = {
-+ "gpio4", "gpio12",
-+};
-+
-+static const char * const pcie1_pwrflt_groups[] = {
-+ "gpio5", "gpio13",
-+};
-+
-+static const char * const pcie1_clk_req_groups[] = {
-+ "gpio5",
-+};
-+
-+static const char * const pcie2_rst_groups[] = {
-+ "gpio48",
-+};
-+
-+static const char * const pcie2_prsnt_groups[] = {
-+ "gpio11", "gpio48",
-+};
-+
-+static const char * const pcie2_pwren_n_groups[] = {
-+ "gpio12", "gpio49",
-+};
-+
-+static const char * const pcie2_pwren_groups[] = {
-+ "gpio12", "gpio49",
-+};
-+
-+static const char * const pcie2_pwrflt_groups[] = {
-+ "gpio13", "gpio50",
-+};
-+
-+static const char * const pcie2_clk_req_groups[] = {
-+ "gpio50",
-+};
-+
-+static const char * const pcie3_rst_groups[] = {
-+ "gpio63",
-+};
-+
-+static const char * const pcie3_prsnt_groups[] = {
-+ "gpio11",
-+};
-+
-+static const char * const pcie3_pwren_n_groups[] = {
-+ "gpio12",
-+};
-+
-+static const char * const pcie3_pwren_groups[] = {
-+ "gpio12",
-+};
-+
-+static const char * const pcie3_pwrflt_groups[] = {
-+ "gpio13",
-+};
-+
-+static const char * const pcie3_clk_req_groups[] = {
-+ "gpio65",
-+};
-+
-+static const char * const ps_hold_groups[] = {
-+ "gpio26",
-+};
-+
-+static const struct msm_function ipq8064_functions[] = {
-+ FUNCTION(mdio),
-+ FUNCTION(ssbi),
-+ FUNCTION(spmi),
-+ FUNCTION(mi2s),
-+ FUNCTION(pdm),
-+ FUNCTION(audio_pcm),
-+ FUNCTION(gsbi1),
-+ FUNCTION(gsbi2),
-+ FUNCTION(gsbi4),
-+ FUNCTION(gsbi5),
-+ FUNCTION(gsbi5_spi_cs1),
-+ FUNCTION(gsbi5_spi_cs2),
-+ FUNCTION(gsbi5_spi_cs3),
-+ FUNCTION(gsbi6),
-+ FUNCTION(gsbi7),
-+ FUNCTION(nss_spi),
-+ FUNCTION(sdc1),
-+ FUNCTION(spdif),
-+ FUNCTION(nand),
-+ FUNCTION(tsif1),
-+ FUNCTION(tsif2),
-+ FUNCTION(usb_fs_n),
-+ FUNCTION(usb_fs),
-+ FUNCTION(usb2_hsic),
-+ FUNCTION(rgmii2),
-+ FUNCTION(sata),
-+ FUNCTION(pcie1_rst),
-+ FUNCTION(pcie1_prsnt),
-+ FUNCTION(pcie1_pwren_n),
-+ FUNCTION(pcie1_pwren),
-+ FUNCTION(pcie1_pwrflt),
-+ FUNCTION(pcie1_clk_req),
-+ FUNCTION(pcie2_rst),
-+ FUNCTION(pcie2_prsnt),
-+ FUNCTION(pcie2_pwren_n),
-+ FUNCTION(pcie2_pwren),
-+ FUNCTION(pcie2_pwrflt),
-+ FUNCTION(pcie2_clk_req),
-+ FUNCTION(pcie3_rst),
-+ FUNCTION(pcie3_prsnt),
-+ FUNCTION(pcie3_pwren_n),
-+ FUNCTION(pcie3_pwren),
-+ FUNCTION(pcie3_pwrflt),
-+ FUNCTION(pcie3_clk_req),
-+ FUNCTION(ps_hold),
-+};
-+
-+static const struct msm_pingroup ipq8064_groups[] = {
-+ PINGROUP(0, mdio, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-+ PINGROUP(1, mdio, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-+ PINGROUP(2, gsbi5_spi_cs3, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-+ PINGROUP(3, pcie1_rst, pcie1_prsnt, pdm, NA, NA, NA, NA, NA, NA, NA),
-+ PINGROUP(4, pcie1_pwren_n, pcie1_pwren, NA, NA, NA, NA, NA, NA, NA, NA),
-+ PINGROUP(5, pcie1_clk_req, pcie1_pwrflt, NA, NA, NA, NA, NA, NA, NA, NA),
-+ PINGROUP(6, gsbi7, usb_fs, gsbi5_spi_cs1, usb_fs_n, NA, NA, NA, NA, NA, NA),
-+ PINGROUP(7, gsbi7, usb_fs, gsbi5_spi_cs2, NA, NA, NA, NA, NA, NA, NA),
-+ PINGROUP(8, gsbi7, usb_fs, NA, NA, NA, NA, NA, NA, NA, NA),
-+ PINGROUP(9, gsbi7, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-+ PINGROUP(10, gsbi4, spdif, sata, ssbi, mdio, spmi, NA, NA, NA, NA),
-+ PINGROUP(11, gsbi4, pcie2_prsnt, pcie1_prsnt, pcie3_prsnt, ssbi, mdio, spmi, NA, NA, NA),
-+ PINGROUP(12, gsbi4, pcie2_pwren_n, pcie1_pwren_n, pcie3_pwren_n, pcie2_pwren, pcie1_pwren, pcie3_pwren, NA, NA, NA),
-+ PINGROUP(13, gsbi4, pcie2_pwrflt, pcie1_pwrflt, pcie3_pwrflt, NA, NA, NA, NA, NA, NA),
-+ PINGROUP(14, audio_pcm, nss_spi, NA, NA, NA, NA, NA, NA, NA, NA),
-+ PINGROUP(15, audio_pcm, nss_spi, NA, NA, NA, NA, NA, NA, NA, NA),
-+ PINGROUP(16, audio_pcm, nss_spi, pdm, NA, NA, NA, NA, NA, NA, NA),
-+ PINGROUP(17, audio_pcm, nss_spi, pdm, NA, NA, NA, NA, NA, NA, NA),
-+ PINGROUP(18, gsbi5, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-+ PINGROUP(19, gsbi5, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-+ PINGROUP(20, gsbi5, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-+ PINGROUP(21, gsbi5, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-+ PINGROUP(22, gsbi2, pdm, NA, NA, NA, NA, NA, NA, NA, NA),
-+ PINGROUP(23, gsbi2, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-+ PINGROUP(24, gsbi2, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-+ PINGROUP(25, gsbi2, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-+ PINGROUP(26, ps_hold, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-+ PINGROUP(27, mi2s, rgmii2, gsbi6, NA, NA, NA, NA, NA, NA, NA),
-+ PINGROUP(28, mi2s, rgmii2, gsbi6, NA, NA, NA, NA, NA, NA, NA),
-+ PINGROUP(29, mi2s, rgmii2, gsbi6, NA, NA, NA, NA, NA, NA, NA),
-+ PINGROUP(30, mi2s, rgmii2, gsbi6, pdm, NA, NA, NA, NA, NA, NA),
-+ PINGROUP(31, mi2s, rgmii2, pdm, NA, NA, NA, NA, NA, NA, NA),
-+ PINGROUP(32, mi2s, rgmii2, NA, NA, NA, NA, NA, NA, NA, NA),
-+ PINGROUP(33, mi2s, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-+ PINGROUP(34, nand, pdm, NA, NA, NA, NA, NA, NA, NA, NA),
-+ PINGROUP(35, nand, pdm, NA, NA, NA, NA, NA, NA, NA, NA),
-+ PINGROUP(36, nand, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-+ PINGROUP(37, nand, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-+ PINGROUP(38, nand, sdc1, NA, NA, NA, NA, NA, NA, NA, NA),
-+ PINGROUP(39, nand, sdc1, NA, NA, NA, NA, NA, NA, NA, NA),
-+ PINGROUP(40, nand, sdc1, NA, NA, NA, NA, NA, NA, NA, NA),
-+ PINGROUP(41, nand, sdc1, NA, NA, NA, NA, NA, NA, NA, NA),
-+ PINGROUP(42, nand, sdc1, NA, NA, NA, NA, NA, NA, NA, NA),
-+ PINGROUP(43, nand, sdc1, NA, NA, NA, NA, NA, NA, NA, NA),
-+ PINGROUP(44, nand, sdc1, NA, NA, NA, NA, NA, NA, NA, NA),
-+ PINGROUP(45, nand, sdc1, NA, NA, NA, NA, NA, NA, NA, NA),
-+ PINGROUP(46, nand, sdc1, NA, NA, NA, NA, NA, NA, NA, NA),
-+ PINGROUP(47, nand, sdc1, NA, NA, NA, NA, NA, NA, NA, NA),
-+ PINGROUP(48, pcie2_rst, spdif, NA, NA, NA, NA, NA, NA, NA, NA),
-+ PINGROUP(49, pcie2_pwren_n, pcie2_pwren, NA, NA, NA, NA, NA, NA, NA, NA),
-+ PINGROUP(50, pcie2_clk_req, pcie2_pwrflt, NA, NA, NA, NA, NA, NA, NA, NA),
-+ PINGROUP(51, gsbi1, rgmii2, NA, NA, NA, NA, NA, NA, NA, NA),
-+ PINGROUP(52, gsbi1, rgmii2, pdm, NA, NA, NA, NA, NA, NA, NA),
-+ PINGROUP(53, gsbi1, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-+ PINGROUP(54, gsbi1, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-+ PINGROUP(55, tsif1, mi2s, gsbi6, pdm, nss_spi, NA, NA, NA, NA, NA),
-+ PINGROUP(56, tsif1, mi2s, gsbi6, pdm, nss_spi, NA, NA, NA, NA, NA),
-+ PINGROUP(57, tsif1, mi2s, gsbi6, nss_spi, NA, NA, NA, NA, NA, NA),
-+ PINGROUP(58, tsif1, mi2s, gsbi6, pdm, nss_spi, NA, NA, NA, NA, NA),
-+ PINGROUP(59, tsif2, rgmii2, pdm, NA, NA, NA, NA, NA, NA, NA),
-+ PINGROUP(60, tsif2, rgmii2, NA, NA, NA, NA, NA, NA, NA, NA),
-+ PINGROUP(61, tsif2, rgmii2, gsbi5_spi_cs1, NA, NA, NA, NA, NA, NA, NA),
-+ PINGROUP(62, tsif2, rgmii2, gsbi5_spi_cs2, NA, NA, NA, NA, NA, NA, NA),
-+ PINGROUP(63, pcie3_rst, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-+ PINGROUP(64, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-+ PINGROUP(65, pcie3_clk_req, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-+ PINGROUP(66, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-+ PINGROUP(67, usb2_hsic, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-+ PINGROUP(68, usb2_hsic, NA, NA, NA, NA, NA, NA, NA, NA, NA),
-+ SDC_PINGROUP(sdc3_clk, 0x204a, 14, 6),
-+ SDC_PINGROUP(sdc3_cmd, 0x204a, 11, 3),
-+ SDC_PINGROUP(sdc3_data, 0x204a, 9, 0),
-+};
-+
-+#define NUM_GPIO_PINGROUPS 69
-+
-+static const struct msm_pinctrl_soc_data ipq8064_pinctrl = {
-+ .pins = ipq8064_pins,
-+ .npins = ARRAY_SIZE(ipq8064_pins),
-+ .functions = ipq8064_functions,
-+ .nfunctions = ARRAY_SIZE(ipq8064_functions),
-+ .groups = ipq8064_groups,
-+ .ngroups = ARRAY_SIZE(ipq8064_groups),
-+ .ngpios = NUM_GPIO_PINGROUPS,
-+};
-+
-+static int ipq8064_pinctrl_probe(struct platform_device *pdev)
-+{
-+ return msm_pinctrl_probe(pdev, &ipq8064_pinctrl);
-+}
-+
-+static const struct of_device_id ipq8064_pinctrl_of_match[] = {
-+ { .compatible = "qcom,ipq8064-pinctrl", },
-+ { },
-+};
-+
-+static struct platform_driver ipq8064_pinctrl_driver = {
-+ .driver = {
-+ .name = "ipq8064-pinctrl",
-+ .owner = THIS_MODULE,
-+ .of_match_table = ipq8064_pinctrl_of_match,
-+ },
-+ .probe = ipq8064_pinctrl_probe,
-+ .remove = msm_pinctrl_remove,
-+};
-+
-+static int __init ipq8064_pinctrl_init(void)
-+{
-+ return platform_driver_register(&ipq8064_pinctrl_driver);
-+}
-+arch_initcall(ipq8064_pinctrl_init);
-+
-+static void __exit ipq8064_pinctrl_exit(void)
-+{
-+ platform_driver_unregister(&ipq8064_pinctrl_driver);
-+}
-+module_exit(ipq8064_pinctrl_exit);
-+
-+MODULE_AUTHOR("Andy Gross <agross@codeaurora.org>");
-+MODULE_DESCRIPTION("Qualcomm IPQ8064 pinctrl driver");
-+MODULE_LICENSE("GPL v2");
-+MODULE_DEVICE_TABLE(of, ipq8064_pinctrl_of_match);
diff --git a/target/linux/ipq806x/patches/0041-dt-Document-Qualcomm-IPQ8064-pinctrl-binding.patch b/target/linux/ipq806x/patches/0041-dt-Document-Qualcomm-IPQ8064-pinctrl-binding.patch
deleted file mode 100644
index c1adc99..0000000
--- a/target/linux/ipq806x/patches/0041-dt-Document-Qualcomm-IPQ8064-pinctrl-binding.patch
+++ /dev/null
@@ -1,114 +0,0 @@
-From 425015979d3b1600d14403be7d6d64ba1238e58d Mon Sep 17 00:00:00 2001
-From: Andy Gross <agross@codeaurora.org>
-Date: Mon, 14 Apr 2014 22:10:36 -0500
-Subject: [PATCH 041/182] dt: Document Qualcomm IPQ8064 pinctrl binding
-
-Define a new binding for the Qualcomm TLMMv2 based pin controller inside the
-IPQ8064.
-
-Signed-off-by: Andy Gross <agross@codeaurora.org>
-Reviewed-by: Bjorn Andersson <bjorn.andersson@sonymobile.com>
-Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
----
- .../bindings/pinctrl/qcom,ipq8064-pinctrl.txt | 95 ++++++++++++++++++++
- 1 file changed, 95 insertions(+)
- create mode 100644 Documentation/devicetree/bindings/pinctrl/qcom,ipq8064-pinctrl.txt
-
---- /dev/null
-+++ b/Documentation/devicetree/bindings/pinctrl/qcom,ipq8064-pinctrl.txt
-@@ -0,0 +1,95 @@
-+Qualcomm IPQ8064 TLMM block
-+
-+Required properties:
-+- compatible: "qcom,ipq8064-pinctrl"
-+- reg: Should be the base address and length of the TLMM block.
-+- interrupts: Should be the parent IRQ of the TLMM block.
-+- interrupt-controller: Marks the device node as an interrupt controller.
-+- #interrupt-cells: Should be two.
-+- gpio-controller: Marks the device node as a GPIO controller.
-+- #gpio-cells : Should be two.
-+ The first cell is the gpio pin number and the
-+ second cell is used for optional parameters.
-+
-+Please refer to ../gpio/gpio.txt and ../interrupt-controller/interrupts.txt for
-+a general description of GPIO and interrupt bindings.
-+
-+Please refer to pinctrl-bindings.txt in this directory for details of the
-+common pinctrl bindings used by client devices, including the meaning of the
-+phrase "pin configuration node".
-+
-+Qualcomm's pin configuration nodes act as a container for an abitrary number of
-+subnodes. Each of these subnodes represents some desired configuration for a
-+pin, a group, or a list of pins or groups. This configuration can include the
-+mux function to select on those pin(s)/group(s), and various pin configuration
-+parameters, such as pull-up, drive strength, etc.
-+
-+The name of each subnode is not important; all subnodes should be enumerated
-+and processed purely based on their content.
-+
-+Each subnode only affects those parameters that are explicitly listed. In
-+other words, a subnode that lists a mux function but no pin configuration
-+parameters implies no information about any pin configuration parameters.
-+Similarly, a pin subnode that describes a pullup parameter implies no
-+information about e.g. the mux function.
-+
-+
-+The following generic properties as defined in pinctrl-bindings.txt are valid
-+to specify in a pin configuration subnode:
-+
-+ pins, function, bias-disable, bias-pull-down, bias-pull,up, drive-strength,
-+ output-low, output-high.
-+
-+Non-empty subnodes must specify the 'pins' property.
-+
-+Valid values for qcom,pins are:
-+ gpio0-gpio68
-+ Supports mux, bias, and drive-strength
-+
-+ sdc3_clk, sdc3_cmd, sdc3_data
-+ Supports bias and drive-strength
-+
-+
-+Valid values for function are:
-+ mdio, mi2s, pdm, ssbi, spmi, audio_pcm, gsbi1, gsbi2, gsbi4, gsbi5,
-+ gsbi5_spi_cs1, gsbi5_spi_cs2, gsbi5_spi_cs3, gsbi6, gsbi7, nss_spi, sdc1,
-+ spdif, nand, tsif1, tsif2, usb_fs_n, usb_fs, usb2_hsic, rgmii2, sata,
-+ pcie1_rst, pcie1_prsnt, pcie1_pwren_n, pcie1_pwren, pcie1_pwrflt,
-+ pcie1_clk_req, pcie2_rst, pcie2_prsnt, pcie2_pwren_n, pcie2_pwren,
-+ pcie2_pwrflt, pcie2_clk_req, pcie3_rst, pcie3_prsnt, pcie3_pwren_n,
-+ pcie3_pwren, pcie3_pwrflt, pcie3_clk_req, ps_hold
-+
-+Example:
-+
-+ pinmux: pinctrl@800000 {
-+ compatible = "qcom,ipq8064-pinctrl";
-+ reg = <0x800000 0x4000>;
-+
-+ gpio-controller;
-+ #gpio-cells = <2>;
-+ interrupt-controller;
-+ #interrupt-cells = <2>;
-+ interrupts = <0 32 0x4>;
-+
-+ pinctrl-names = "default";
-+ pinctrl-0 = <&gsbi5_uart_default>;
-+
-+ gsbi5_uart_default: gsbi5_uart_default {
-+ mux {
-+ pins = "gpio18", "gpio19";
-+ function = "gsbi5";
-+ };
-+
-+ tx {
-+ pins = "gpio18";
-+ drive-strength = <4>;
-+ bias-disable;
-+ };
-+
-+ rx {
-+ pins = "gpio19";
-+ drive-strength = <2>;
-+ bias-pull-up;
-+ };
-+ };
-+ };
diff --git a/target/linux/ipq806x/patches/0042-ARM-qcom-Select-PINCTRL-by-default-for-ARCH_QCOM.patch b/target/linux/ipq806x/patches/0042-ARM-qcom-Select-PINCTRL-by-default-for-ARCH_QCOM.patch
deleted file mode 100644
index cbccbc2..0000000
--- a/target/linux/ipq806x/patches/0042-ARM-qcom-Select-PINCTRL-by-default-for-ARCH_QCOM.patch
+++ /dev/null
@@ -1,24 +0,0 @@
-From add2c1451495ccc4e67ced3dd12d4286500f1672 Mon Sep 17 00:00:00 2001
-From: Andy Gross <agross@codeaurora.org>
-Date: Mon, 14 Apr 2014 22:10:37 -0500
-Subject: [PATCH 042/182] ARM: qcom: Select PINCTRL by default for ARCH_QCOM
-
-Add missing PINCTRL selection. This enables selection of pinctrollers for
-Qualcomm processors.
-
-Signed-off-by: Andy Gross <agross@codeaurora.org>
-Acked-by: Linus Walleij <linus.walleij@linaro.org>
----
- arch/arm/mach-qcom/Kconfig | 1 +
- 1 file changed, 1 insertion(+)
-
---- a/arch/arm/mach-qcom/Kconfig
-+++ b/arch/arm/mach-qcom/Kconfig
-@@ -5,6 +5,7 @@ config ARCH_QCOM
- select CLKSRC_OF
- select GENERIC_CLOCKEVENTS
- select HAVE_SMP
-+ select PINCTRL
- select QCOM_SCM if SMP
- help
- Support for Qualcomm's devicetree based systems.
diff --git a/target/linux/ipq806x/patches/0043-pinctrl-qcom-Correct-name-for-pin-0.patch b/target/linux/ipq806x/patches/0043-pinctrl-qcom-Correct-name-for-pin-0.patch
deleted file mode 100644
index 03896ec..0000000
--- a/target/linux/ipq806x/patches/0043-pinctrl-qcom-Correct-name-for-pin-0.patch
+++ /dev/null
@@ -1,23 +0,0 @@
-From 4cf6d61dc3441f50d1d56bfd72280dbcd2b584a6 Mon Sep 17 00:00:00 2001
-From: Andy Gross <agross@codeaurora.org>
-Date: Fri, 25 Apr 2014 15:41:55 -0500
-Subject: [PATCH 043/182] pinctrl: qcom: Correct name for pin 0
-
-Fix copy/paste error in pinctrl_pin_desc for pin 0.
-
-Signed-off-by: Andy Gross <agross@codeaurora.org>
----
- drivers/pinctrl/pinctrl-ipq8064.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/drivers/pinctrl/pinctrl-ipq8064.c
-+++ b/drivers/pinctrl/pinctrl-ipq8064.c
-@@ -20,7 +20,7 @@
- #include "pinctrl-msm.h"
-
- static const struct pinctrl_pin_desc ipq8064_pins[] = {
-- PINCTRL_PIN(0, "GPIO_1"),
-+ PINCTRL_PIN(0, "GPIO_0"),
- PINCTRL_PIN(1, "GPIO_1"),
- PINCTRL_PIN(2, "GPIO_2"),
- PINCTRL_PIN(3, "GPIO_3"),
diff --git a/target/linux/ipq806x/patches/0044-dmaengine-qcom_bam_dma-Add-device-tree-binding.patch b/target/linux/ipq806x/patches/0044-dmaengine-qcom_bam_dma-Add-device-tree-binding.patch
deleted file mode 100644
index e77d05f..0000000
--- a/target/linux/ipq806x/patches/0044-dmaengine-qcom_bam_dma-Add-device-tree-binding.patch
+++ /dev/null
@@ -1,59 +0,0 @@
-From b5e19b657e352d565c5ddeae5f6dfd542de9d7e5 Mon Sep 17 00:00:00 2001
-From: Andy Gross <agross@codeaurora.org>
-Date: Mon, 10 Mar 2014 16:40:19 -0500
-Subject: [PATCH 044/182] dmaengine: qcom_bam_dma: Add device tree binding
-
-Add device tree binding support for the QCOM BAM DMA driver.
-
-Acked-by: Kumar Gala <galak@codeaurora.org>
-Signed-off-by: Andy Gross <agross@codeaurora.org>
-Signed-off-by: Vinod Koul <vinod.koul@intel.com>
----
- .../devicetree/bindings/dma/qcom_bam_dma.txt | 41 ++++++++++++++++++++
- 1 file changed, 41 insertions(+)
- create mode 100644 Documentation/devicetree/bindings/dma/qcom_bam_dma.txt
-
---- /dev/null
-+++ b/Documentation/devicetree/bindings/dma/qcom_bam_dma.txt
-@@ -0,0 +1,41 @@
-+QCOM BAM DMA controller
-+
-+Required properties:
-+- compatible: must contain "qcom,bam-v1.4.0" for MSM8974
-+- reg: Address range for DMA registers
-+- interrupts: Should contain the one interrupt shared by all channels
-+- #dma-cells: must be <1>, the cell in the dmas property of the client device
-+ represents the channel number
-+- clocks: required clock
-+- clock-names: must contain "bam_clk" entry
-+- qcom,ee : indicates the active Execution Environment identifier (0-7) used in
-+ the secure world.
-+
-+Example:
-+
-+ uart-bam: dma@f9984000 = {
-+ compatible = "qcom,bam-v1.4.0";
-+ reg = <0xf9984000 0x15000>;
-+ interrupts = <0 94 0>;
-+ clocks = <&gcc GCC_BAM_DMA_AHB_CLK>;
-+ clock-names = "bam_clk";
-+ #dma-cells = <1>;
-+ qcom,ee = <0>;
-+ };
-+
-+DMA clients must use the format described in the dma.txt file, using a two cell
-+specifier for each channel.
-+
-+Example:
-+ serial@f991e000 {
-+ compatible = "qcom,msm-uart";
-+ reg = <0xf991e000 0x1000>
-+ <0xf9944000 0x19000>;
-+ interrupts = <0 108 0>;
-+ clocks = <&gcc GCC_BLSP1_UART2_APPS_CLK>,
-+ <&gcc GCC_BLSP1_AHB_CLK>;
-+ clock-names = "core", "iface";
-+
-+ dmas = <&uart-bam 0>, <&uart-bam 1>;
-+ dma-names = "rx", "tx";
-+ };
diff --git a/target/linux/ipq806x/patches/0045-dmaengine-add-Qualcomm-BAM-dma-driver.patch b/target/linux/ipq806x/patches/0045-dmaengine-add-Qualcomm-BAM-dma-driver.patch
deleted file mode 100644
index 98c71db..0000000
--- a/target/linux/ipq806x/patches/0045-dmaengine-add-Qualcomm-BAM-dma-driver.patch
+++ /dev/null
@@ -1,1164 +0,0 @@
-From 23dd43da9c885789b3d5aceed3e401345f8e8106 Mon Sep 17 00:00:00 2001
-From: Andy Gross <agross@codeaurora.org>
-Date: Sat, 29 Mar 2014 18:53:16 +0530
-Subject: [PATCH 045/182] dmaengine: add Qualcomm BAM dma driver
-
-Add the DMA engine driver for the QCOM Bus Access Manager (BAM) DMA controller
-found in the MSM 8x74 platforms.
-
-Each BAM DMA device is associated with a specific on-chip peripheral. Each
-channel provides a uni-directional data transfer engine that is capable of
-transferring data between the peripheral and system memory (System mode), or
-between two peripherals (BAM2BAM).
-
-The initial release of this driver only supports slave transfers between
-peripherals and system memory.
-
-Signed-off-by: Andy Gross <agross@codeaurora.org>
-Tested-by: Stanimir Varbanov <svarbanov@mm-sol.com>
-Signed-off-by: Vinod Koul <vinod.koul@intel.com>
----
- drivers/dma/Kconfig | 9 +
- drivers/dma/Makefile | 2 +
- drivers/dma/qcom_bam_dma.c | 1111 ++++++++++++++++++++++++++++++++++++++++++++
- 3 files changed, 1122 insertions(+)
- create mode 100644 drivers/dma/qcom_bam_dma.c
-
---- a/drivers/dma/Kconfig
-+++ b/drivers/dma/Kconfig
-@@ -401,4 +401,13 @@ config DMATEST
- config DMA_ENGINE_RAID
- bool
-
-+config QCOM_BAM_DMA
-+ tristate "QCOM BAM DMA support"
-+ depends on ARCH_QCOM || (COMPILE_TEST && OF && ARM)
-+ select DMA_ENGINE
-+ select DMA_VIRTUAL_CHANNELS
-+ ---help---
-+ Enable support for the QCOM BAM DMA controller. This controller
-+ provides DMA capabilities for a variety of on-chip devices.
-+
- endif
---- a/drivers/dma/Makefile
-+++ b/drivers/dma/Makefile
-@@ -44,3 +44,5 @@ obj-$(CONFIG_DMA_JZ4740) += dma-jz4740.o
- obj-$(CONFIG_TI_CPPI41) += cppi41.o
- obj-$(CONFIG_K3_DMA) += k3dma.o
- obj-$(CONFIG_MOXART_DMA) += moxart-dma.o
-+obj-$(CONFIG_FSL_EDMA) += fsl-edma.o
-+obj-$(CONFIG_QCOM_BAM_DMA) += qcom_bam_dma.o
---- /dev/null
-+++ b/drivers/dma/qcom_bam_dma.c
-@@ -0,0 +1,1111 @@
-+/*
-+ * Copyright (c) 2013-2014, The Linux Foundation. All rights reserved.
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 and
-+ * only version 2 as published by the Free Software Foundation.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ * GNU General Public License for more details.
-+ *
-+ */
-+/*
-+ * QCOM BAM DMA engine driver
-+ *
-+ * QCOM BAM DMA blocks are distributed amongst a number of the on-chip
-+ * peripherals on the MSM 8x74. The configuration of the channels are dependent
-+ * on the way they are hard wired to that specific peripheral. The peripheral
-+ * device tree entries specify the configuration of each channel.
-+ *
-+ * The DMA controller requires the use of external memory for storage of the
-+ * hardware descriptors for each channel. The descriptor FIFO is accessed as a
-+ * circular buffer and operations are managed according to the offset within the
-+ * FIFO. After pipe/channel reset, all of the pipe registers and internal state
-+ * are back to defaults.
-+ *
-+ * During DMA operations, we write descriptors to the FIFO, being careful to
-+ * handle wrapping and then write the last FIFO offset to that channel's
-+ * P_EVNT_REG register to kick off the transaction. The P_SW_OFSTS register
-+ * indicates the current FIFO offset that is being processed, so there is some
-+ * indication of where the hardware is currently working.
-+ */
-+
-+#include <linux/kernel.h>
-+#include <linux/io.h>
-+#include <linux/init.h>
-+#include <linux/slab.h>
-+#include <linux/module.h>
-+#include <linux/interrupt.h>
-+#include <linux/dma-mapping.h>
-+#include <linux/scatterlist.h>
-+#include <linux/device.h>
-+#include <linux/platform_device.h>
-+#include <linux/of.h>
-+#include <linux/of_address.h>
-+#include <linux/of_irq.h>
-+#include <linux/of_dma.h>
-+#include <linux/clk.h>
-+#include <linux/dmaengine.h>
-+
-+#include "dmaengine.h"
-+#include "virt-dma.h"
-+
-+struct bam_desc_hw {
-+ u32 addr; /* Buffer physical address */
-+ u16 size; /* Buffer size in bytes */
-+ u16 flags;
-+};
-+
-+#define DESC_FLAG_INT BIT(15)
-+#define DESC_FLAG_EOT BIT(14)
-+#define DESC_FLAG_EOB BIT(13)
-+
-+struct bam_async_desc {
-+ struct virt_dma_desc vd;
-+
-+ u32 num_desc;
-+ u32 xfer_len;
-+ struct bam_desc_hw *curr_desc;
-+
-+ enum dma_transfer_direction dir;
-+ size_t length;
-+ struct bam_desc_hw desc[0];
-+};
-+
-+#define BAM_CTRL 0x0000
-+#define BAM_REVISION 0x0004
-+#define BAM_SW_REVISION 0x0080
-+#define BAM_NUM_PIPES 0x003C
-+#define BAM_TIMER 0x0040
-+#define BAM_TIMER_CTRL 0x0044
-+#define BAM_DESC_CNT_TRSHLD 0x0008
-+#define BAM_IRQ_SRCS 0x000C
-+#define BAM_IRQ_SRCS_MSK 0x0010
-+#define BAM_IRQ_SRCS_UNMASKED 0x0030
-+#define BAM_IRQ_STTS 0x0014
-+#define BAM_IRQ_CLR 0x0018
-+#define BAM_IRQ_EN 0x001C
-+#define BAM_CNFG_BITS 0x007C
-+#define BAM_IRQ_SRCS_EE(ee) (0x0800 + ((ee) * 0x80))
-+#define BAM_IRQ_SRCS_MSK_EE(ee) (0x0804 + ((ee) * 0x80))
-+#define BAM_P_CTRL(pipe) (0x1000 + ((pipe) * 0x1000))
-+#define BAM_P_RST(pipe) (0x1004 + ((pipe) * 0x1000))
-+#define BAM_P_HALT(pipe) (0x1008 + ((pipe) * 0x1000))
-+#define BAM_P_IRQ_STTS(pipe) (0x1010 + ((pipe) * 0x1000))
-+#define BAM_P_IRQ_CLR(pipe) (0x1014 + ((pipe) * 0x1000))
-+#define BAM_P_IRQ_EN(pipe) (0x1018 + ((pipe) * 0x1000))
-+#define BAM_P_EVNT_DEST_ADDR(pipe) (0x182C + ((pipe) * 0x1000))
-+#define BAM_P_EVNT_REG(pipe) (0x1818 + ((pipe) * 0x1000))
-+#define BAM_P_SW_OFSTS(pipe) (0x1800 + ((pipe) * 0x1000))
-+#define BAM_P_DATA_FIFO_ADDR(pipe) (0x1824 + ((pipe) * 0x1000))
-+#define BAM_P_DESC_FIFO_ADDR(pipe) (0x181C + ((pipe) * 0x1000))
-+#define BAM_P_EVNT_TRSHLD(pipe) (0x1828 + ((pipe) * 0x1000))
-+#define BAM_P_FIFO_SIZES(pipe) (0x1820 + ((pipe) * 0x1000))
-+
-+/* BAM CTRL */
-+#define BAM_SW_RST BIT(0)
-+#define BAM_EN BIT(1)
-+#define BAM_EN_ACCUM BIT(4)
-+#define BAM_TESTBUS_SEL_SHIFT 5
-+#define BAM_TESTBUS_SEL_MASK 0x3F
-+#define BAM_DESC_CACHE_SEL_SHIFT 13
-+#define BAM_DESC_CACHE_SEL_MASK 0x3
-+#define BAM_CACHED_DESC_STORE BIT(15)
-+#define IBC_DISABLE BIT(16)
-+
-+/* BAM REVISION */
-+#define REVISION_SHIFT 0
-+#define REVISION_MASK 0xFF
-+#define NUM_EES_SHIFT 8
-+#define NUM_EES_MASK 0xF
-+#define CE_BUFFER_SIZE BIT(13)
-+#define AXI_ACTIVE BIT(14)
-+#define USE_VMIDMT BIT(15)
-+#define SECURED BIT(16)
-+#define BAM_HAS_NO_BYPASS BIT(17)
-+#define HIGH_FREQUENCY_BAM BIT(18)
-+#define INACTIV_TMRS_EXST BIT(19)
-+#define NUM_INACTIV_TMRS BIT(20)
-+#define DESC_CACHE_DEPTH_SHIFT 21
-+#define DESC_CACHE_DEPTH_1 (0 << DESC_CACHE_DEPTH_SHIFT)
-+#define DESC_CACHE_DEPTH_2 (1 << DESC_CACHE_DEPTH_SHIFT)
-+#define DESC_CACHE_DEPTH_3 (2 << DESC_CACHE_DEPTH_SHIFT)
-+#define DESC_CACHE_DEPTH_4 (3 << DESC_CACHE_DEPTH_SHIFT)
-+#define CMD_DESC_EN BIT(23)
-+#define INACTIV_TMR_BASE_SHIFT 24
-+#define INACTIV_TMR_BASE_MASK 0xFF
-+
-+/* BAM NUM PIPES */
-+#define BAM_NUM_PIPES_SHIFT 0
-+#define BAM_NUM_PIPES_MASK 0xFF
-+#define PERIPH_NON_PIPE_GRP_SHIFT 16
-+#define PERIPH_NON_PIP_GRP_MASK 0xFF
-+#define BAM_NON_PIPE_GRP_SHIFT 24
-+#define BAM_NON_PIPE_GRP_MASK 0xFF
-+
-+/* BAM CNFG BITS */
-+#define BAM_PIPE_CNFG BIT(2)
-+#define BAM_FULL_PIPE BIT(11)
-+#define BAM_NO_EXT_P_RST BIT(12)
-+#define BAM_IBC_DISABLE BIT(13)
-+#define BAM_SB_CLK_REQ BIT(14)
-+#define BAM_PSM_CSW_REQ BIT(15)
-+#define BAM_PSM_P_RES BIT(16)
-+#define BAM_AU_P_RES BIT(17)
-+#define BAM_SI_P_RES BIT(18)
-+#define BAM_WB_P_RES BIT(19)
-+#define BAM_WB_BLK_CSW BIT(20)
-+#define BAM_WB_CSW_ACK_IDL BIT(21)
-+#define BAM_WB_RETR_SVPNT BIT(22)
-+#define BAM_WB_DSC_AVL_P_RST BIT(23)
-+#define BAM_REG_P_EN BIT(24)
-+#define BAM_PSM_P_HD_DATA BIT(25)
-+#define BAM_AU_ACCUMED BIT(26)
-+#define BAM_CMD_ENABLE BIT(27)
-+
-+#define BAM_CNFG_BITS_DEFAULT (BAM_PIPE_CNFG | \
-+ BAM_NO_EXT_P_RST | \
-+ BAM_IBC_DISABLE | \
-+ BAM_SB_CLK_REQ | \
-+ BAM_PSM_CSW_REQ | \
-+ BAM_PSM_P_RES | \
-+ BAM_AU_P_RES | \
-+ BAM_SI_P_RES | \
-+ BAM_WB_P_RES | \
-+ BAM_WB_BLK_CSW | \
-+ BAM_WB_CSW_ACK_IDL | \
-+ BAM_WB_RETR_SVPNT | \
-+ BAM_WB_DSC_AVL_P_RST | \
-+ BAM_REG_P_EN | \
-+ BAM_PSM_P_HD_DATA | \
-+ BAM_AU_ACCUMED | \
-+ BAM_CMD_ENABLE)
-+
-+/* PIPE CTRL */
-+#define P_EN BIT(1)
-+#define P_DIRECTION BIT(3)
-+#define P_SYS_STRM BIT(4)
-+#define P_SYS_MODE BIT(5)
-+#define P_AUTO_EOB BIT(6)
-+#define P_AUTO_EOB_SEL_SHIFT 7
-+#define P_AUTO_EOB_SEL_512 (0 << P_AUTO_EOB_SEL_SHIFT)
-+#define P_AUTO_EOB_SEL_256 (1 << P_AUTO_EOB_SEL_SHIFT)
-+#define P_AUTO_EOB_SEL_128 (2 << P_AUTO_EOB_SEL_SHIFT)
-+#define P_AUTO_EOB_SEL_64 (3 << P_AUTO_EOB_SEL_SHIFT)
-+#define P_PREFETCH_LIMIT_SHIFT 9
-+#define P_PREFETCH_LIMIT_32 (0 << P_PREFETCH_LIMIT_SHIFT)
-+#define P_PREFETCH_LIMIT_16 (1 << P_PREFETCH_LIMIT_SHIFT)
-+#define P_PREFETCH_LIMIT_4 (2 << P_PREFETCH_LIMIT_SHIFT)
-+#define P_WRITE_NWD BIT(11)
-+#define P_LOCK_GROUP_SHIFT 16
-+#define P_LOCK_GROUP_MASK 0x1F
-+
-+/* BAM_DESC_CNT_TRSHLD */
-+#define CNT_TRSHLD 0xffff
-+#define DEFAULT_CNT_THRSHLD 0x4
-+
-+/* BAM_IRQ_SRCS */
-+#define BAM_IRQ BIT(31)
-+#define P_IRQ 0x7fffffff
-+
-+/* BAM_IRQ_SRCS_MSK */
-+#define BAM_IRQ_MSK BAM_IRQ
-+#define P_IRQ_MSK P_IRQ
-+
-+/* BAM_IRQ_STTS */
-+#define BAM_TIMER_IRQ BIT(4)
-+#define BAM_EMPTY_IRQ BIT(3)
-+#define BAM_ERROR_IRQ BIT(2)
-+#define BAM_HRESP_ERR_IRQ BIT(1)
-+
-+/* BAM_IRQ_CLR */
-+#define BAM_TIMER_CLR BIT(4)
-+#define BAM_EMPTY_CLR BIT(3)
-+#define BAM_ERROR_CLR BIT(2)
-+#define BAM_HRESP_ERR_CLR BIT(1)
-+
-+/* BAM_IRQ_EN */
-+#define BAM_TIMER_EN BIT(4)
-+#define BAM_EMPTY_EN BIT(3)
-+#define BAM_ERROR_EN BIT(2)
-+#define BAM_HRESP_ERR_EN BIT(1)
-+
-+/* BAM_P_IRQ_EN */
-+#define P_PRCSD_DESC_EN BIT(0)
-+#define P_TIMER_EN BIT(1)
-+#define P_WAKE_EN BIT(2)
-+#define P_OUT_OF_DESC_EN BIT(3)
-+#define P_ERR_EN BIT(4)
-+#define P_TRNSFR_END_EN BIT(5)
-+#define P_DEFAULT_IRQS_EN (P_PRCSD_DESC_EN | P_ERR_EN | P_TRNSFR_END_EN)
-+
-+/* BAM_P_SW_OFSTS */
-+#define P_SW_OFSTS_MASK 0xffff
-+
-+#define BAM_DESC_FIFO_SIZE SZ_32K
-+#define MAX_DESCRIPTORS (BAM_DESC_FIFO_SIZE / sizeof(struct bam_desc_hw) - 1)
-+#define BAM_MAX_DATA_SIZE (SZ_32K - 8)
-+
-+struct bam_chan {
-+ struct virt_dma_chan vc;
-+
-+ struct bam_device *bdev;
-+
-+ /* configuration from device tree */
-+ u32 id;
-+
-+ struct bam_async_desc *curr_txd; /* current running dma */
-+
-+ /* runtime configuration */
-+ struct dma_slave_config slave;
-+
-+ /* fifo storage */
-+ struct bam_desc_hw *fifo_virt;
-+ dma_addr_t fifo_phys;
-+
-+ /* fifo markers */
-+ unsigned short head; /* start of active descriptor entries */
-+ unsigned short tail; /* end of active descriptor entries */
-+
-+ unsigned int initialized; /* is the channel hw initialized? */
-+ unsigned int paused; /* is the channel paused? */
-+ unsigned int reconfigure; /* new slave config? */
-+
-+ struct list_head node;
-+};
-+
-+static inline struct bam_chan *to_bam_chan(struct dma_chan *common)
-+{
-+ return container_of(common, struct bam_chan, vc.chan);
-+}
-+
-+struct bam_device {
-+ void __iomem *regs;
-+ struct device *dev;
-+ struct dma_device common;
-+ struct device_dma_parameters dma_parms;
-+ struct bam_chan *channels;
-+ u32 num_channels;
-+
-+ /* execution environment ID, from DT */
-+ u32 ee;
-+
-+ struct clk *bamclk;
-+ int irq;
-+
-+ /* dma start transaction tasklet */
-+ struct tasklet_struct task;
-+};
-+
-+/**
-+ * bam_reset_channel - Reset individual BAM DMA channel
-+ * @bchan: bam channel
-+ *
-+ * This function resets a specific BAM channel
-+ */
-+static void bam_reset_channel(struct bam_chan *bchan)
-+{
-+ struct bam_device *bdev = bchan->bdev;
-+
-+ lockdep_assert_held(&bchan->vc.lock);
-+
-+ /* reset channel */
-+ writel_relaxed(1, bdev->regs + BAM_P_RST(bchan->id));
-+ writel_relaxed(0, bdev->regs + BAM_P_RST(bchan->id));
-+
-+ /* don't allow cpu to reorder BAM register accesses done after this */
-+ wmb();
-+
-+ /* make sure hw is initialized when channel is used the first time */
-+ bchan->initialized = 0;
-+}
-+
-+/**
-+ * bam_chan_init_hw - Initialize channel hardware
-+ * @bchan: bam channel
-+ *
-+ * This function resets and initializes the BAM channel
-+ */
-+static void bam_chan_init_hw(struct bam_chan *bchan,
-+ enum dma_transfer_direction dir)
-+{
-+ struct bam_device *bdev = bchan->bdev;
-+ u32 val;
-+
-+ /* Reset the channel to clear internal state of the FIFO */
-+ bam_reset_channel(bchan);
-+
-+ /*
-+ * write out 8 byte aligned address. We have enough space for this
-+ * because we allocated 1 more descriptor (8 bytes) than we can use
-+ */
-+ writel_relaxed(ALIGN(bchan->fifo_phys, sizeof(struct bam_desc_hw)),
-+ bdev->regs + BAM_P_DESC_FIFO_ADDR(bchan->id));
-+ writel_relaxed(BAM_DESC_FIFO_SIZE, bdev->regs +
-+ BAM_P_FIFO_SIZES(bchan->id));
-+
-+ /* enable the per pipe interrupts, enable EOT, ERR, and INT irqs */
-+ writel_relaxed(P_DEFAULT_IRQS_EN, bdev->regs + BAM_P_IRQ_EN(bchan->id));
-+
-+ /* unmask the specific pipe and EE combo */
-+ val = readl_relaxed(bdev->regs + BAM_IRQ_SRCS_MSK_EE(bdev->ee));
-+ val |= BIT(bchan->id);
-+ writel_relaxed(val, bdev->regs + BAM_IRQ_SRCS_MSK_EE(bdev->ee));
-+
-+ /* don't allow cpu to reorder the channel enable done below */
-+ wmb();
-+
-+ /* set fixed direction and mode, then enable channel */
-+ val = P_EN | P_SYS_MODE;
-+ if (dir == DMA_DEV_TO_MEM)
-+ val |= P_DIRECTION;
-+
-+ writel_relaxed(val, bdev->regs + BAM_P_CTRL(bchan->id));
-+
-+ bchan->initialized = 1;
-+
-+ /* init FIFO pointers */
-+ bchan->head = 0;
-+ bchan->tail = 0;
-+}
-+
-+/**
-+ * bam_alloc_chan - Allocate channel resources for DMA channel.
-+ * @chan: specified channel
-+ *
-+ * This function allocates the FIFO descriptor memory
-+ */
-+static int bam_alloc_chan(struct dma_chan *chan)
-+{
-+ struct bam_chan *bchan = to_bam_chan(chan);
-+ struct bam_device *bdev = bchan->bdev;
-+
-+ if (bchan->fifo_virt)
-+ return 0;
-+
-+ /* allocate FIFO descriptor space, but only if necessary */
-+ bchan->fifo_virt = dma_alloc_writecombine(bdev->dev, BAM_DESC_FIFO_SIZE,
-+ &bchan->fifo_phys, GFP_KERNEL);
-+
-+ if (!bchan->fifo_virt) {
-+ dev_err(bdev->dev, "Failed to allocate desc fifo\n");
-+ return -ENOMEM;
-+ }
-+
-+ return 0;
-+}
-+
-+/**
-+ * bam_free_chan - Frees dma resources associated with specific channel
-+ * @chan: specified channel
-+ *
-+ * Free the allocated fifo descriptor memory and channel resources
-+ *
-+ */
-+static void bam_free_chan(struct dma_chan *chan)
-+{
-+ struct bam_chan *bchan = to_bam_chan(chan);
-+ struct bam_device *bdev = bchan->bdev;
-+ u32 val;
-+ unsigned long flags;
-+
-+ vchan_free_chan_resources(to_virt_chan(chan));
-+
-+ if (bchan->curr_txd) {
-+ dev_err(bchan->bdev->dev, "Cannot free busy channel\n");
-+ return;
-+ }
-+
-+ spin_lock_irqsave(&bchan->vc.lock, flags);
-+ bam_reset_channel(bchan);
-+ spin_unlock_irqrestore(&bchan->vc.lock, flags);
-+
-+ dma_free_writecombine(bdev->dev, BAM_DESC_FIFO_SIZE, bchan->fifo_virt,
-+ bchan->fifo_phys);
-+ bchan->fifo_virt = NULL;
-+
-+ /* mask irq for pipe/channel */
-+ val = readl_relaxed(bdev->regs + BAM_IRQ_SRCS_MSK_EE(bdev->ee));
-+ val &= ~BIT(bchan->id);
-+ writel_relaxed(val, bdev->regs + BAM_IRQ_SRCS_MSK_EE(bdev->ee));
-+
-+ /* disable irq */
-+ writel_relaxed(0, bdev->regs + BAM_P_IRQ_EN(bchan->id));
-+}
-+
-+/**
-+ * bam_slave_config - set slave configuration for channel
-+ * @chan: dma channel
-+ * @cfg: slave configuration
-+ *
-+ * Sets slave configuration for channel
-+ *
-+ */
-+static void bam_slave_config(struct bam_chan *bchan,
-+ struct dma_slave_config *cfg)
-+{
-+ memcpy(&bchan->slave, cfg, sizeof(*cfg));
-+ bchan->reconfigure = 1;
-+}
-+
-+/**
-+ * bam_prep_slave_sg - Prep slave sg transaction
-+ *
-+ * @chan: dma channel
-+ * @sgl: scatter gather list
-+ * @sg_len: length of sg
-+ * @direction: DMA transfer direction
-+ * @flags: DMA flags
-+ * @context: transfer context (unused)
-+ */
-+static struct dma_async_tx_descriptor *bam_prep_slave_sg(struct dma_chan *chan,
-+ struct scatterlist *sgl, unsigned int sg_len,
-+ enum dma_transfer_direction direction, unsigned long flags,
-+ void *context)
-+{
-+ struct bam_chan *bchan = to_bam_chan(chan);
-+ struct bam_device *bdev = bchan->bdev;
-+ struct bam_async_desc *async_desc;
-+ struct scatterlist *sg;
-+ u32 i;
-+ struct bam_desc_hw *desc;
-+ unsigned int num_alloc = 0;
-+
-+
-+ if (!is_slave_direction(direction)) {
-+ dev_err(bdev->dev, "invalid dma direction\n");
-+ return NULL;
-+ }
-+
-+ /* calculate number of required entries */
-+ for_each_sg(sgl, sg, sg_len, i)
-+ num_alloc += DIV_ROUND_UP(sg_dma_len(sg), BAM_MAX_DATA_SIZE);
-+
-+ /* allocate enough room to accomodate the number of entries */
-+ async_desc = kzalloc(sizeof(*async_desc) +
-+ (num_alloc * sizeof(struct bam_desc_hw)), GFP_NOWAIT);
-+
-+ if (!async_desc)
-+ goto err_out;
-+
-+ async_desc->num_desc = num_alloc;
-+ async_desc->curr_desc = async_desc->desc;
-+ async_desc->dir = direction;
-+
-+ /* fill in temporary descriptors */
-+ desc = async_desc->desc;
-+ for_each_sg(sgl, sg, sg_len, i) {
-+ unsigned int remainder = sg_dma_len(sg);
-+ unsigned int curr_offset = 0;
-+
-+ do {
-+ desc->addr = sg_dma_address(sg) + curr_offset;
-+
-+ if (remainder > BAM_MAX_DATA_SIZE) {
-+ desc->size = BAM_MAX_DATA_SIZE;
-+ remainder -= BAM_MAX_DATA_SIZE;
-+ curr_offset += BAM_MAX_DATA_SIZE;
-+ } else {
-+ desc->size = remainder;
-+ remainder = 0;
-+ }
-+
-+ async_desc->length += desc->size;
-+ desc++;
-+ } while (remainder > 0);
-+ }
-+
-+ return vchan_tx_prep(&bchan->vc, &async_desc->vd, flags);
-+
-+err_out:
-+ kfree(async_desc);
-+ return NULL;
-+}
-+
-+/**
-+ * bam_dma_terminate_all - terminate all transactions on a channel
-+ * @bchan: bam dma channel
-+ *
-+ * Dequeues and frees all transactions
-+ * No callbacks are done
-+ *
-+ */
-+static void bam_dma_terminate_all(struct bam_chan *bchan)
-+{
-+ unsigned long flag;
-+ LIST_HEAD(head);
-+
-+ /* remove all transactions, including active transaction */
-+ spin_lock_irqsave(&bchan->vc.lock, flag);
-+ if (bchan->curr_txd) {
-+ list_add(&bchan->curr_txd->vd.node, &bchan->vc.desc_issued);
-+ bchan->curr_txd = NULL;
-+ }
-+
-+ vchan_get_all_descriptors(&bchan->vc, &head);
-+ spin_unlock_irqrestore(&bchan->vc.lock, flag);
-+
-+ vchan_dma_desc_free_list(&bchan->vc, &head);
-+}
-+
-+/**
-+ * bam_control - DMA device control
-+ * @chan: dma channel
-+ * @cmd: control cmd
-+ * @arg: cmd argument
-+ *
-+ * Perform DMA control command
-+ *
-+ */
-+static int bam_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd,
-+ unsigned long arg)
-+{
-+ struct bam_chan *bchan = to_bam_chan(chan);
-+ struct bam_device *bdev = bchan->bdev;
-+ int ret = 0;
-+ unsigned long flag;
-+
-+ switch (cmd) {
-+ case DMA_PAUSE:
-+ spin_lock_irqsave(&bchan->vc.lock, flag);
-+ writel_relaxed(1, bdev->regs + BAM_P_HALT(bchan->id));
-+ bchan->paused = 1;
-+ spin_unlock_irqrestore(&bchan->vc.lock, flag);
-+ break;
-+
-+ case DMA_RESUME:
-+ spin_lock_irqsave(&bchan->vc.lock, flag);
-+ writel_relaxed(0, bdev->regs + BAM_P_HALT(bchan->id));
-+ bchan->paused = 0;
-+ spin_unlock_irqrestore(&bchan->vc.lock, flag);
-+ break;
-+
-+ case DMA_TERMINATE_ALL:
-+ bam_dma_terminate_all(bchan);
-+ break;
-+
-+ case DMA_SLAVE_CONFIG:
-+ spin_lock_irqsave(&bchan->vc.lock, flag);
-+ bam_slave_config(bchan, (struct dma_slave_config *)arg);
-+ spin_unlock_irqrestore(&bchan->vc.lock, flag);
-+ break;
-+
-+ default:
-+ ret = -ENXIO;
-+ break;
-+ }
-+
-+ return ret;
-+}
-+
-+/**
-+ * process_channel_irqs - processes the channel interrupts
-+ * @bdev: bam controller
-+ *
-+ * This function processes the channel interrupts
-+ *
-+ */
-+static u32 process_channel_irqs(struct bam_device *bdev)
-+{
-+ u32 i, srcs, pipe_stts;
-+ unsigned long flags;
-+ struct bam_async_desc *async_desc;
-+
-+ srcs = readl_relaxed(bdev->regs + BAM_IRQ_SRCS_EE(bdev->ee));
-+
-+ /* return early if no pipe/channel interrupts are present */
-+ if (!(srcs & P_IRQ))
-+ return srcs;
-+
-+ for (i = 0; i < bdev->num_channels; i++) {
-+ struct bam_chan *bchan = &bdev->channels[i];
-+
-+ if (!(srcs & BIT(i)))
-+ continue;
-+
-+ /* clear pipe irq */
-+ pipe_stts = readl_relaxed(bdev->regs +
-+ BAM_P_IRQ_STTS(i));
-+
-+ writel_relaxed(pipe_stts, bdev->regs +
-+ BAM_P_IRQ_CLR(i));
-+
-+ spin_lock_irqsave(&bchan->vc.lock, flags);
-+ async_desc = bchan->curr_txd;
-+
-+ if (async_desc) {
-+ async_desc->num_desc -= async_desc->xfer_len;
-+ async_desc->curr_desc += async_desc->xfer_len;
-+ bchan->curr_txd = NULL;
-+
-+ /* manage FIFO */
-+ bchan->head += async_desc->xfer_len;
-+ bchan->head %= MAX_DESCRIPTORS;
-+
-+ /*
-+ * if complete, process cookie. Otherwise
-+ * push back to front of desc_issued so that
-+ * it gets restarted by the tasklet
-+ */
-+ if (!async_desc->num_desc)
-+ vchan_cookie_complete(&async_desc->vd);
-+ else
-+ list_add(&async_desc->vd.node,
-+ &bchan->vc.desc_issued);
-+ }
-+
-+ spin_unlock_irqrestore(&bchan->vc.lock, flags);
-+ }
-+
-+ return srcs;
-+}
-+
-+/**
-+ * bam_dma_irq - irq handler for bam controller
-+ * @irq: IRQ of interrupt
-+ * @data: callback data
-+ *
-+ * IRQ handler for the bam controller
-+ */
-+static irqreturn_t bam_dma_irq(int irq, void *data)
-+{
-+ struct bam_device *bdev = data;
-+ u32 clr_mask = 0, srcs = 0;
-+
-+ srcs |= process_channel_irqs(bdev);
-+
-+ /* kick off tasklet to start next dma transfer */
-+ if (srcs & P_IRQ)
-+ tasklet_schedule(&bdev->task);
-+
-+ if (srcs & BAM_IRQ)
-+ clr_mask = readl_relaxed(bdev->regs + BAM_IRQ_STTS);
-+
-+ /* don't allow reorder of the various accesses to the BAM registers */
-+ mb();
-+
-+ writel_relaxed(clr_mask, bdev->regs + BAM_IRQ_CLR);
-+
-+ return IRQ_HANDLED;
-+}
-+
-+/**
-+ * bam_tx_status - returns status of transaction
-+ * @chan: dma channel
-+ * @cookie: transaction cookie
-+ * @txstate: DMA transaction state
-+ *
-+ * Return status of dma transaction
-+ */
-+static enum dma_status bam_tx_status(struct dma_chan *chan, dma_cookie_t cookie,
-+ struct dma_tx_state *txstate)
-+{
-+ struct bam_chan *bchan = to_bam_chan(chan);
-+ struct virt_dma_desc *vd;
-+ int ret;
-+ size_t residue = 0;
-+ unsigned int i;
-+ unsigned long flags;
-+
-+ ret = dma_cookie_status(chan, cookie, txstate);
-+ if (ret == DMA_COMPLETE)
-+ return ret;
-+
-+ if (!txstate)
-+ return bchan->paused ? DMA_PAUSED : ret;
-+
-+ spin_lock_irqsave(&bchan->vc.lock, flags);
-+ vd = vchan_find_desc(&bchan->vc, cookie);
-+ if (vd)
-+ residue = container_of(vd, struct bam_async_desc, vd)->length;
-+ else if (bchan->curr_txd && bchan->curr_txd->vd.tx.cookie == cookie)
-+ for (i = 0; i < bchan->curr_txd->num_desc; i++)
-+ residue += bchan->curr_txd->curr_desc[i].size;
-+
-+ spin_unlock_irqrestore(&bchan->vc.lock, flags);
-+
-+ dma_set_residue(txstate, residue);
-+
-+ if (ret == DMA_IN_PROGRESS && bchan->paused)
-+ ret = DMA_PAUSED;
-+
-+ return ret;
-+}
-+
-+/**
-+ * bam_apply_new_config
-+ * @bchan: bam dma channel
-+ * @dir: DMA direction
-+ */
-+static void bam_apply_new_config(struct bam_chan *bchan,
-+ enum dma_transfer_direction dir)
-+{
-+ struct bam_device *bdev = bchan->bdev;
-+ u32 maxburst;
-+
-+ if (dir == DMA_DEV_TO_MEM)
-+ maxburst = bchan->slave.src_maxburst;
-+ else
-+ maxburst = bchan->slave.dst_maxburst;
-+
-+ writel_relaxed(maxburst, bdev->regs + BAM_DESC_CNT_TRSHLD);
-+
-+ bchan->reconfigure = 0;
-+}
-+
-+/**
-+ * bam_start_dma - start next transaction
-+ * @bchan - bam dma channel
-+ */
-+static void bam_start_dma(struct bam_chan *bchan)
-+{
-+ struct virt_dma_desc *vd = vchan_next_desc(&bchan->vc);
-+ struct bam_device *bdev = bchan->bdev;
-+ struct bam_async_desc *async_desc;
-+ struct bam_desc_hw *desc;
-+ struct bam_desc_hw *fifo = PTR_ALIGN(bchan->fifo_virt,
-+ sizeof(struct bam_desc_hw));
-+
-+ lockdep_assert_held(&bchan->vc.lock);
-+
-+ if (!vd)
-+ return;
-+
-+ list_del(&vd->node);
-+
-+ async_desc = container_of(vd, struct bam_async_desc, vd);
-+ bchan->curr_txd = async_desc;
-+
-+ /* on first use, initialize the channel hardware */
-+ if (!bchan->initialized)
-+ bam_chan_init_hw(bchan, async_desc->dir);
-+
-+ /* apply new slave config changes, if necessary */
-+ if (bchan->reconfigure)
-+ bam_apply_new_config(bchan, async_desc->dir);
-+
-+ desc = bchan->curr_txd->curr_desc;
-+
-+ if (async_desc->num_desc > MAX_DESCRIPTORS)
-+ async_desc->xfer_len = MAX_DESCRIPTORS;
-+ else
-+ async_desc->xfer_len = async_desc->num_desc;
-+
-+ /* set INT on last descriptor */
-+ desc[async_desc->xfer_len - 1].flags |= DESC_FLAG_INT;
-+
-+ if (bchan->tail + async_desc->xfer_len > MAX_DESCRIPTORS) {
-+ u32 partial = MAX_DESCRIPTORS - bchan->tail;
-+
-+ memcpy(&fifo[bchan->tail], desc,
-+ partial * sizeof(struct bam_desc_hw));
-+ memcpy(fifo, &desc[partial], (async_desc->xfer_len - partial) *
-+ sizeof(struct bam_desc_hw));
-+ } else {
-+ memcpy(&fifo[bchan->tail], desc,
-+ async_desc->xfer_len * sizeof(struct bam_desc_hw));
-+ }
-+
-+ bchan->tail += async_desc->xfer_len;
-+ bchan->tail %= MAX_DESCRIPTORS;
-+
-+ /* ensure descriptor writes and dma start not reordered */
-+ wmb();
-+ writel_relaxed(bchan->tail * sizeof(struct bam_desc_hw),
-+ bdev->regs + BAM_P_EVNT_REG(bchan->id));
-+}
-+
-+/**
-+ * dma_tasklet - DMA IRQ tasklet
-+ * @data: tasklet argument (bam controller structure)
-+ *
-+ * Sets up next DMA operation and then processes all completed transactions
-+ */
-+static void dma_tasklet(unsigned long data)
-+{
-+ struct bam_device *bdev = (struct bam_device *)data;
-+ struct bam_chan *bchan;
-+ unsigned long flags;
-+ unsigned int i;
-+
-+ /* go through the channels and kick off transactions */
-+ for (i = 0; i < bdev->num_channels; i++) {
-+ bchan = &bdev->channels[i];
-+ spin_lock_irqsave(&bchan->vc.lock, flags);
-+
-+ if (!list_empty(&bchan->vc.desc_issued) && !bchan->curr_txd)
-+ bam_start_dma(bchan);
-+ spin_unlock_irqrestore(&bchan->vc.lock, flags);
-+ }
-+}
-+
-+/**
-+ * bam_issue_pending - starts pending transactions
-+ * @chan: dma channel
-+ *
-+ * Calls tasklet directly which in turn starts any pending transactions
-+ */
-+static void bam_issue_pending(struct dma_chan *chan)
-+{
-+ struct bam_chan *bchan = to_bam_chan(chan);
-+ unsigned long flags;
-+
-+ spin_lock_irqsave(&bchan->vc.lock, flags);
-+
-+ /* if work pending and idle, start a transaction */
-+ if (vchan_issue_pending(&bchan->vc) && !bchan->curr_txd)
-+ bam_start_dma(bchan);
-+
-+ spin_unlock_irqrestore(&bchan->vc.lock, flags);
-+}
-+
-+/**
-+ * bam_dma_free_desc - free descriptor memory
-+ * @vd: virtual descriptor
-+ *
-+ */
-+static void bam_dma_free_desc(struct virt_dma_desc *vd)
-+{
-+ struct bam_async_desc *async_desc = container_of(vd,
-+ struct bam_async_desc, vd);
-+
-+ kfree(async_desc);
-+}
-+
-+static struct dma_chan *bam_dma_xlate(struct of_phandle_args *dma_spec,
-+ struct of_dma *of)
-+{
-+ struct bam_device *bdev = container_of(of->of_dma_data,
-+ struct bam_device, common);
-+ unsigned int request;
-+
-+ if (dma_spec->args_count != 1)
-+ return NULL;
-+
-+ request = dma_spec->args[0];
-+ if (request >= bdev->num_channels)
-+ return NULL;
-+
-+ return dma_get_slave_channel(&(bdev->channels[request].vc.chan));
-+}
-+
-+/**
-+ * bam_init
-+ * @bdev: bam device
-+ *
-+ * Initialization helper for global bam registers
-+ */
-+static int bam_init(struct bam_device *bdev)
-+{
-+ u32 val;
-+
-+ /* read revision and configuration information */
-+ val = readl_relaxed(bdev->regs + BAM_REVISION) >> NUM_EES_SHIFT;
-+ val &= NUM_EES_MASK;
-+
-+ /* check that configured EE is within range */
-+ if (bdev->ee >= val)
-+ return -EINVAL;
-+
-+ val = readl_relaxed(bdev->regs + BAM_NUM_PIPES);
-+ bdev->num_channels = val & BAM_NUM_PIPES_MASK;
-+
-+ /* s/w reset bam */
-+ /* after reset all pipes are disabled and idle */
-+ val = readl_relaxed(bdev->regs + BAM_CTRL);
-+ val |= BAM_SW_RST;
-+ writel_relaxed(val, bdev->regs + BAM_CTRL);
-+ val &= ~BAM_SW_RST;
-+ writel_relaxed(val, bdev->regs + BAM_CTRL);
-+
-+ /* make sure previous stores are visible before enabling BAM */
-+ wmb();
-+
-+ /* enable bam */
-+ val |= BAM_EN;
-+ writel_relaxed(val, bdev->regs + BAM_CTRL);
-+
-+ /* set descriptor threshhold, start with 4 bytes */
-+ writel_relaxed(DEFAULT_CNT_THRSHLD, bdev->regs + BAM_DESC_CNT_TRSHLD);
-+
-+ /* Enable default set of h/w workarounds, ie all except BAM_FULL_PIPE */
-+ writel_relaxed(BAM_CNFG_BITS_DEFAULT, bdev->regs + BAM_CNFG_BITS);
-+
-+ /* enable irqs for errors */
-+ writel_relaxed(BAM_ERROR_EN | BAM_HRESP_ERR_EN,
-+ bdev->regs + BAM_IRQ_EN);
-+
-+ /* unmask global bam interrupt */
-+ writel_relaxed(BAM_IRQ_MSK, bdev->regs + BAM_IRQ_SRCS_MSK_EE(bdev->ee));
-+
-+ return 0;
-+}
-+
-+static void bam_channel_init(struct bam_device *bdev, struct bam_chan *bchan,
-+ u32 index)
-+{
-+ bchan->id = index;
-+ bchan->bdev = bdev;
-+
-+ vchan_init(&bchan->vc, &bdev->common);
-+ bchan->vc.desc_free = bam_dma_free_desc;
-+}
-+
-+static int bam_dma_probe(struct platform_device *pdev)
-+{
-+ struct bam_device *bdev;
-+ struct resource *iores;
-+ int ret, i;
-+
-+ bdev = devm_kzalloc(&pdev->dev, sizeof(*bdev), GFP_KERNEL);
-+ if (!bdev)
-+ return -ENOMEM;
-+
-+ bdev->dev = &pdev->dev;
-+
-+ iores = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-+ bdev->regs = devm_ioremap_resource(&pdev->dev, iores);
-+ if (IS_ERR(bdev->regs))
-+ return PTR_ERR(bdev->regs);
-+
-+ bdev->irq = platform_get_irq(pdev, 0);
-+ if (bdev->irq < 0)
-+ return bdev->irq;
-+
-+ ret = of_property_read_u32(pdev->dev.of_node, "qcom,ee", &bdev->ee);
-+ if (ret) {
-+ dev_err(bdev->dev, "Execution environment unspecified\n");
-+ return ret;
-+ }
-+
-+ bdev->bamclk = devm_clk_get(bdev->dev, "bam_clk");
-+ if (IS_ERR(bdev->bamclk))
-+ return PTR_ERR(bdev->bamclk);
-+
-+ ret = clk_prepare_enable(bdev->bamclk);
-+ if (ret) {
-+ dev_err(bdev->dev, "failed to prepare/enable clock\n");
-+ return ret;
-+ }
-+
-+ ret = bam_init(bdev);
-+ if (ret)
-+ goto err_disable_clk;
-+
-+ tasklet_init(&bdev->task, dma_tasklet, (unsigned long)bdev);
-+
-+ bdev->channels = devm_kcalloc(bdev->dev, bdev->num_channels,
-+ sizeof(*bdev->channels), GFP_KERNEL);
-+
-+ if (!bdev->channels) {
-+ ret = -ENOMEM;
-+ goto err_disable_clk;
-+ }
-+
-+ /* allocate and initialize channels */
-+ INIT_LIST_HEAD(&bdev->common.channels);
-+
-+ for (i = 0; i < bdev->num_channels; i++)
-+ bam_channel_init(bdev, &bdev->channels[i], i);
-+
-+ ret = devm_request_irq(bdev->dev, bdev->irq, bam_dma_irq,
-+ IRQF_TRIGGER_HIGH, "bam_dma", bdev);
-+ if (ret)
-+ goto err_disable_clk;
-+
-+ /* set max dma segment size */
-+ bdev->common.dev = bdev->dev;
-+ bdev->common.dev->dma_parms = &bdev->dma_parms;
-+ ret = dma_set_max_seg_size(bdev->common.dev, BAM_MAX_DATA_SIZE);
-+ if (ret) {
-+ dev_err(bdev->dev, "cannot set maximum segment size\n");
-+ goto err_disable_clk;
-+ }
-+
-+ platform_set_drvdata(pdev, bdev);
-+
-+ /* set capabilities */
-+ dma_cap_zero(bdev->common.cap_mask);
-+ dma_cap_set(DMA_SLAVE, bdev->common.cap_mask);
-+
-+ /* initialize dmaengine apis */
-+ bdev->common.device_alloc_chan_resources = bam_alloc_chan;
-+ bdev->common.device_free_chan_resources = bam_free_chan;
-+ bdev->common.device_prep_slave_sg = bam_prep_slave_sg;
-+ bdev->common.device_control = bam_control;
-+ bdev->common.device_issue_pending = bam_issue_pending;
-+ bdev->common.device_tx_status = bam_tx_status;
-+ bdev->common.dev = bdev->dev;
-+
-+ ret = dma_async_device_register(&bdev->common);
-+ if (ret) {
-+ dev_err(bdev->dev, "failed to register dma async device\n");
-+ goto err_disable_clk;
-+ }
-+
-+ ret = of_dma_controller_register(pdev->dev.of_node, bam_dma_xlate,
-+ &bdev->common);
-+ if (ret)
-+ goto err_unregister_dma;
-+
-+ return 0;
-+
-+err_unregister_dma:
-+ dma_async_device_unregister(&bdev->common);
-+err_disable_clk:
-+ clk_disable_unprepare(bdev->bamclk);
-+ return ret;
-+}
-+
-+static int bam_dma_remove(struct platform_device *pdev)
-+{
-+ struct bam_device *bdev = platform_get_drvdata(pdev);
-+ u32 i;
-+
-+ of_dma_controller_free(pdev->dev.of_node);
-+ dma_async_device_unregister(&bdev->common);
-+
-+ /* mask all interrupts for this execution environment */
-+ writel_relaxed(0, bdev->regs + BAM_IRQ_SRCS_MSK_EE(bdev->ee));
-+
-+ devm_free_irq(bdev->dev, bdev->irq, bdev);
-+
-+ for (i = 0; i < bdev->num_channels; i++) {
-+ bam_dma_terminate_all(&bdev->channels[i]);
-+ tasklet_kill(&bdev->channels[i].vc.task);
-+
-+ dma_free_writecombine(bdev->dev, BAM_DESC_FIFO_SIZE,
-+ bdev->channels[i].fifo_virt,
-+ bdev->channels[i].fifo_phys);
-+ }
-+
-+ tasklet_kill(&bdev->task);
-+
-+ clk_disable_unprepare(bdev->bamclk);
-+
-+ return 0;
-+}
-+
-+static const struct of_device_id bam_of_match[] = {
-+ { .compatible = "qcom,bam-v1.4.0", },
-+ {}
-+};
-+MODULE_DEVICE_TABLE(of, bam_of_match);
-+
-+static struct platform_driver bam_dma_driver = {
-+ .probe = bam_dma_probe,
-+ .remove = bam_dma_remove,
-+ .driver = {
-+ .name = "bam-dma-engine",
-+ .owner = THIS_MODULE,
-+ .of_match_table = bam_of_match,
-+ },
-+};
-+
-+module_platform_driver(bam_dma_driver);
-+
-+MODULE_AUTHOR("Andy Gross <agross@codeaurora.org>");
-+MODULE_DESCRIPTION("QCOM BAM DMA engine driver");
-+MODULE_LICENSE("GPL v2");
diff --git a/target/linux/ipq806x/patches/0046-mmc-sdhci-msm-Qualcomm-SDHCI-binding-documentation.patch b/target/linux/ipq806x/patches/0046-mmc-sdhci-msm-Qualcomm-SDHCI-binding-documentation.patch
deleted file mode 100644
index 65c5347..0000000
--- a/target/linux/ipq806x/patches/0046-mmc-sdhci-msm-Qualcomm-SDHCI-binding-documentation.patch
+++ /dev/null
@@ -1,75 +0,0 @@
-From 8a70c89b2fbb635a8d4fec302165343827aeed9f Mon Sep 17 00:00:00 2001
-From: Georgi Djakov <gdjakov@mm-sol.com>
-Date: Mon, 10 Mar 2014 17:37:11 +0200
-Subject: [PATCH 046/182] mmc: sdhci-msm: Qualcomm SDHCI binding documentation
-
-This patch adds the device-tree binding documentation for Qualcomm
-SDHCI driver. It contains the differences between the core properties
-in mmc.txt and the properties used by the sdhci-msm driver.
-
-Signed-off-by: Georgi Djakov <gdjakov@mm-sol.com>
-Acked-by: Ulf Hansson <ulf.hansson@linaro.org>
-Signed-off-by: Chris Ball <chris@printf.net>
----
- .../devicetree/bindings/mmc/sdhci-msm.txt | 55 ++++++++++++++++++++
- 1 file changed, 55 insertions(+)
- create mode 100644 Documentation/devicetree/bindings/mmc/sdhci-msm.txt
-
---- /dev/null
-+++ b/Documentation/devicetree/bindings/mmc/sdhci-msm.txt
-@@ -0,0 +1,55 @@
-+* Qualcomm SDHCI controller (sdhci-msm)
-+
-+This file documents differences between the core properties in mmc.txt
-+and the properties used by the sdhci-msm driver.
-+
-+Required properties:
-+- compatible: Should contain "qcom,sdhci-msm-v4".
-+- reg: Base address and length of the register in the following order:
-+ - Host controller register map (required)
-+ - SD Core register map (required)
-+- interrupts: Should contain an interrupt-specifiers for the interrupts:
-+ - Host controller interrupt (required)
-+- pinctrl-names: Should contain only one value - "default".
-+- pinctrl-0: Should specify pin control groups used for this controller.
-+- clocks: A list of phandle + clock-specifier pairs for the clocks listed in clock-names.
-+- clock-names: Should contain the following:
-+ "iface" - Main peripheral bus clock (PCLK/HCLK - AHB Bus clock) (required)
-+ "core" - SDC MMC clock (MCLK) (required)
-+ "bus" - SDCC bus voter clock (optional)
-+
-+Example:
-+
-+ sdhc_1: sdhci@f9824900 {
-+ compatible = "qcom,sdhci-msm-v4";
-+ reg = <0xf9824900 0x11c>, <0xf9824000 0x800>;
-+ interrupts = <0 123 0>;
-+ bus-width = <8>;
-+ non-removable;
-+
-+ vmmc = <&pm8941_l20>;
-+ vqmmc = <&pm8941_s3>;
-+
-+ pinctrl-names = "default";
-+ pinctrl-0 = <&sdc1_clk &sdc1_cmd &sdc1_data>;
-+
-+ clocks = <&gcc GCC_SDCC1_APPS_CLK>, <&gcc GCC_SDCC1_AHB_CLK>;
-+ clock-names = "core", "iface";
-+ };
-+
-+ sdhc_2: sdhci@f98a4900 {
-+ compatible = "qcom,sdhci-msm-v4";
-+ reg = <0xf98a4900 0x11c>, <0xf98a4000 0x800>;
-+ interrupts = <0 125 0>;
-+ bus-width = <4>;
-+ cd-gpios = <&msmgpio 62 0x1>;
-+
-+ vmmc = <&pm8941_l21>;
-+ vqmmc = <&pm8941_l13>;
-+
-+ pinctrl-names = "default";
-+ pinctrl-0 = <&sdc2_clk &sdc2_cmd &sdc2_data>;
-+
-+ clocks = <&gcc GCC_SDCC2_APPS_CLK>, <&gcc GCC_SDCC2_AHB_CLK>;
-+ clock-names = "core", "iface";
-+ };
diff --git a/target/linux/ipq806x/patches/0047-mmc-sdhci-msm-Initial-support-for-Qualcomm-chipsets.patch b/target/linux/ipq806x/patches/0047-mmc-sdhci-msm-Initial-support-for-Qualcomm-chipsets.patch
deleted file mode 100644
index 9417e1d..0000000
--- a/target/linux/ipq806x/patches/0047-mmc-sdhci-msm-Initial-support-for-Qualcomm-chipsets.patch
+++ /dev/null
@@ -1,265 +0,0 @@
-From 5a8f026acb4a7a6c6d0c868cc1790363640b9b8f Mon Sep 17 00:00:00 2001
-From: Georgi Djakov <gdjakov@mm-sol.com>
-Date: Mon, 10 Mar 2014 17:37:12 +0200
-Subject: [PATCH 047/182] mmc: sdhci-msm: Initial support for Qualcomm
- chipsets
-
-This platform driver adds the initial support of Secure Digital Host
-Controller Interface compliant controller found in Qualcomm chipsets.
-
-Signed-off-by: Asutosh Das <asutoshd@codeaurora.org>
-Signed-off-by: Venkat Gopalakrishnan <venkatg@codeaurora.org>
-Tested-by: Ivan T. Ivanov <iivanov@mm-sol.com>
-Signed-off-by: Georgi Djakov <gdjakov@mm-sol.com>
-Acked-by: Ulf Hansson <ulf.hansson@linaro.org>
-Signed-off-by: Chris Ball <chris@printf.net>
----
- drivers/mmc/host/Kconfig | 13 +++
- drivers/mmc/host/Makefile | 1 +
- drivers/mmc/host/sdhci-msm.c | 208 ++++++++++++++++++++++++++++++++++++++++++
- 3 files changed, 222 insertions(+)
- create mode 100644 drivers/mmc/host/sdhci-msm.c
-
---- a/drivers/mmc/host/Kconfig
-+++ b/drivers/mmc/host/Kconfig
-@@ -334,6 +334,19 @@ config MMC_ATMELMCI
-
- If unsure, say N.
-
-+config MMC_SDHCI_MSM
-+ tristate "Qualcomm SDHCI Controller Support"
-+ depends on ARCH_QCOM
-+ depends on MMC_SDHCI_PLTFM
-+ help
-+ This selects the Secure Digital Host Controller Interface (SDHCI)
-+ support present in Qualcomm SOCs. The controller supports
-+ SD/MMC/SDIO devices.
-+
-+ If you have a controller with this interface, say Y or M here.
-+
-+ If unsure, say N.
-+
- config MMC_MSM
- tristate "Qualcomm SDCC Controller Support"
- depends on MMC && (ARCH_MSM7X00A || ARCH_MSM7X30 || ARCH_QSD8X50)
---- a/drivers/mmc/host/Makefile
-+++ b/drivers/mmc/host/Makefile
-@@ -65,6 +65,7 @@ obj-$(CONFIG_MMC_SDHCI_OF_ESDHC) += sdhc
- obj-$(CONFIG_MMC_SDHCI_OF_HLWD) += sdhci-of-hlwd.o
- obj-$(CONFIG_MMC_SDHCI_BCM_KONA) += sdhci-bcm-kona.o
- obj-$(CONFIG_MMC_SDHCI_BCM2835) += sdhci-bcm2835.o
-+obj-$(CONFIG_MMC_SDHCI_MSM) += sdhci-msm.o
-
- ifeq ($(CONFIG_CB710_DEBUG),y)
- CFLAGS-cb710-mmc += -DDEBUG
---- /dev/null
-+++ b/drivers/mmc/host/sdhci-msm.c
-@@ -0,0 +1,208 @@
-+/*
-+ * drivers/mmc/host/sdhci-msm.c - Qualcomm SDHCI Platform driver
-+ *
-+ * Copyright (c) 2013-2014, The Linux Foundation. All rights reserved.
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 and
-+ * only version 2 as published by the Free Software Foundation.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ * GNU General Public License for more details.
-+ *
-+ */
-+
-+#include <linux/module.h>
-+#include <linux/of_device.h>
-+#include <linux/regulator/consumer.h>
-+#include <linux/delay.h>
-+
-+#include "sdhci-pltfm.h"
-+
-+#define CORE_HC_MODE 0x78
-+#define HC_MODE_EN 0x1
-+#define CORE_POWER 0x0
-+#define CORE_SW_RST BIT(7)
-+
-+
-+struct sdhci_msm_host {
-+ struct platform_device *pdev;
-+ void __iomem *core_mem; /* MSM SDCC mapped address */
-+ struct clk *clk; /* main SD/MMC bus clock */
-+ struct clk *pclk; /* SDHC peripheral bus clock */
-+ struct clk *bus_clk; /* SDHC bus voter clock */
-+ struct mmc_host *mmc;
-+ struct sdhci_pltfm_data sdhci_msm_pdata;
-+};
-+
-+/* Platform specific tuning */
-+static int sdhci_msm_execute_tuning(struct sdhci_host *host, u32 opcode)
-+{
-+ /*
-+ * Tuning is required for SDR104, HS200 and HS400 cards and if the clock
-+ * frequency greater than 100MHz in those modes. The standard tuning
-+ * procedure should not be executed, but a custom implementation will be
-+ * added here instead.
-+ */
-+ return 0;
-+}
-+
-+static const struct of_device_id sdhci_msm_dt_match[] = {
-+ { .compatible = "qcom,sdhci-msm-v4" },
-+ {},
-+};
-+
-+MODULE_DEVICE_TABLE(of, sdhci_msm_dt_match);
-+
-+static struct sdhci_ops sdhci_msm_ops = {
-+ .platform_execute_tuning = sdhci_msm_execute_tuning,
-+};
-+
-+static int sdhci_msm_probe(struct platform_device *pdev)
-+{
-+ struct sdhci_host *host;
-+ struct sdhci_pltfm_host *pltfm_host;
-+ struct sdhci_msm_host *msm_host;
-+ struct resource *core_memres;
-+ int ret;
-+ u16 host_version;
-+
-+ msm_host = devm_kzalloc(&pdev->dev, sizeof(*msm_host), GFP_KERNEL);
-+ if (!msm_host)
-+ return -ENOMEM;
-+
-+ msm_host->sdhci_msm_pdata.ops = &sdhci_msm_ops;
-+ host = sdhci_pltfm_init(pdev, &msm_host->sdhci_msm_pdata, 0);
-+ if (IS_ERR(host))
-+ return PTR_ERR(host);
-+
-+ pltfm_host = sdhci_priv(host);
-+ pltfm_host->priv = msm_host;
-+ msm_host->mmc = host->mmc;
-+ msm_host->pdev = pdev;
-+
-+ ret = mmc_of_parse(host->mmc);
-+ if (ret)
-+ goto pltfm_free;
-+
-+ sdhci_get_of_property(pdev);
-+
-+ /* Setup SDCC bus voter clock. */
-+ msm_host->bus_clk = devm_clk_get(&pdev->dev, "bus");
-+ if (!IS_ERR(msm_host->bus_clk)) {
-+ /* Vote for max. clk rate for max. performance */
-+ ret = clk_set_rate(msm_host->bus_clk, INT_MAX);
-+ if (ret)
-+ goto pltfm_free;
-+ ret = clk_prepare_enable(msm_host->bus_clk);
-+ if (ret)
-+ goto pltfm_free;
-+ }
-+
-+ /* Setup main peripheral bus clock */
-+ msm_host->pclk = devm_clk_get(&pdev->dev, "iface");
-+ if (IS_ERR(msm_host->pclk)) {
-+ ret = PTR_ERR(msm_host->pclk);
-+ dev_err(&pdev->dev, "Perpheral clk setup failed (%d)\n", ret);
-+ goto bus_clk_disable;
-+ }
-+
-+ ret = clk_prepare_enable(msm_host->pclk);
-+ if (ret)
-+ goto bus_clk_disable;
-+
-+ /* Setup SDC MMC clock */
-+ msm_host->clk = devm_clk_get(&pdev->dev, "core");
-+ if (IS_ERR(msm_host->clk)) {
-+ ret = PTR_ERR(msm_host->clk);
-+ dev_err(&pdev->dev, "SDC MMC clk setup failed (%d)\n", ret);
-+ goto pclk_disable;
-+ }
-+
-+ ret = clk_prepare_enable(msm_host->clk);
-+ if (ret)
-+ goto pclk_disable;
-+
-+ core_memres = platform_get_resource(pdev, IORESOURCE_MEM, 1);
-+ msm_host->core_mem = devm_ioremap_resource(&pdev->dev, core_memres);
-+
-+ if (IS_ERR(msm_host->core_mem)) {
-+ dev_err(&pdev->dev, "Failed to remap registers\n");
-+ ret = PTR_ERR(msm_host->core_mem);
-+ goto clk_disable;
-+ }
-+
-+ /* Reset the core and Enable SDHC mode */
-+ writel_relaxed(readl_relaxed(msm_host->core_mem + CORE_POWER) |
-+ CORE_SW_RST, msm_host->core_mem + CORE_POWER);
-+
-+ /* SW reset can take upto 10HCLK + 15MCLK cycles. (min 40us) */
-+ usleep_range(1000, 5000);
-+ if (readl(msm_host->core_mem + CORE_POWER) & CORE_SW_RST) {
-+ dev_err(&pdev->dev, "Stuck in reset\n");
-+ ret = -ETIMEDOUT;
-+ goto clk_disable;
-+ }
-+
-+ /* Set HC_MODE_EN bit in HC_MODE register */
-+ writel_relaxed(HC_MODE_EN, (msm_host->core_mem + CORE_HC_MODE));
-+
-+ host->quirks |= SDHCI_QUIRK_BROKEN_CARD_DETECTION;
-+ host->quirks |= SDHCI_QUIRK_SINGLE_POWER_WRITE;
-+
-+ host_version = readw_relaxed((host->ioaddr + SDHCI_HOST_VERSION));
-+ dev_dbg(&pdev->dev, "Host Version: 0x%x Vendor Version 0x%x\n",
-+ host_version, ((host_version & SDHCI_VENDOR_VER_MASK) >>
-+ SDHCI_VENDOR_VER_SHIFT));
-+
-+ ret = sdhci_add_host(host);
-+ if (ret)
-+ goto clk_disable;
-+
-+ return 0;
-+
-+clk_disable:
-+ clk_disable_unprepare(msm_host->clk);
-+pclk_disable:
-+ clk_disable_unprepare(msm_host->pclk);
-+bus_clk_disable:
-+ if (!IS_ERR(msm_host->bus_clk))
-+ clk_disable_unprepare(msm_host->bus_clk);
-+pltfm_free:
-+ sdhci_pltfm_free(pdev);
-+ return ret;
-+}
-+
-+static int sdhci_msm_remove(struct platform_device *pdev)
-+{
-+ struct sdhci_host *host = platform_get_drvdata(pdev);
-+ struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
-+ struct sdhci_msm_host *msm_host = pltfm_host->priv;
-+ int dead = (readl_relaxed(host->ioaddr + SDHCI_INT_STATUS) ==
-+ 0xffffffff);
-+
-+ sdhci_remove_host(host, dead);
-+ sdhci_pltfm_free(pdev);
-+ clk_disable_unprepare(msm_host->clk);
-+ clk_disable_unprepare(msm_host->pclk);
-+ if (!IS_ERR(msm_host->bus_clk))
-+ clk_disable_unprepare(msm_host->bus_clk);
-+ return 0;
-+}
-+
-+static struct platform_driver sdhci_msm_driver = {
-+ .probe = sdhci_msm_probe,
-+ .remove = sdhci_msm_remove,
-+ .driver = {
-+ .name = "sdhci_msm",
-+ .owner = THIS_MODULE,
-+ .of_match_table = sdhci_msm_dt_match,
-+ },
-+};
-+
-+module_platform_driver(sdhci_msm_driver);
-+
-+MODULE_DESCRIPTION("Qualcomm Secure Digital Host Controller Interface driver");
-+MODULE_LICENSE("GPL v2");
diff --git a/target/linux/ipq806x/patches/0048-mmc-sdhci-msm-Add-platform_execute_tuning-implementa.patch b/target/linux/ipq806x/patches/0048-mmc-sdhci-msm-Add-platform_execute_tuning-implementa.patch
deleted file mode 100644
index e2c34bf..0000000
--- a/target/linux/ipq806x/patches/0048-mmc-sdhci-msm-Add-platform_execute_tuning-implementa.patch
+++ /dev/null
@@ -1,467 +0,0 @@
-From c2a237b3e467c8bb349c4624b71ec400abaf8ad1 Mon Sep 17 00:00:00 2001
-From: Georgi Djakov <gdjakov@mm-sol.com>
-Date: Mon, 10 Mar 2014 17:37:13 +0200
-Subject: [PATCH 048/182] mmc: sdhci-msm: Add platform_execute_tuning
- implementation
-
-This patch adds implementation for platform specific tuning in order
-to support HS200 bus speed mode on Qualcomm SDHCI controller.
-
-Signed-off-by: Asutosh Das <asutoshd@codeaurora.org>
-Signed-off-by: Venkat Gopalakrishnan <venkatg@codeaurora.org>
-Signed-off-by: Georgi Djakov <gdjakov@mm-sol.com>
-Acked-by: Ulf Hansson <ulf.hansson@linaro.org>
-Signed-off-by: Chris Ball <chris@printf.net>
----
- drivers/mmc/host/sdhci-msm.c | 420 +++++++++++++++++++++++++++++++++++++++++-
- 1 file changed, 415 insertions(+), 5 deletions(-)
-
---- a/drivers/mmc/host/sdhci-msm.c
-+++ b/drivers/mmc/host/sdhci-msm.c
-@@ -18,6 +18,8 @@
- #include <linux/of_device.h>
- #include <linux/regulator/consumer.h>
- #include <linux/delay.h>
-+#include <linux/mmc/mmc.h>
-+#include <linux/slab.h>
-
- #include "sdhci-pltfm.h"
-
-@@ -26,6 +28,42 @@
- #define CORE_POWER 0x0
- #define CORE_SW_RST BIT(7)
-
-+#define MAX_PHASES 16
-+#define CORE_DLL_LOCK BIT(7)
-+#define CORE_DLL_EN BIT(16)
-+#define CORE_CDR_EN BIT(17)
-+#define CORE_CK_OUT_EN BIT(18)
-+#define CORE_CDR_EXT_EN BIT(19)
-+#define CORE_DLL_PDN BIT(29)
-+#define CORE_DLL_RST BIT(30)
-+#define CORE_DLL_CONFIG 0x100
-+#define CORE_DLL_STATUS 0x108
-+
-+#define CORE_VENDOR_SPEC 0x10c
-+#define CORE_CLK_PWRSAVE BIT(1)
-+
-+#define CDR_SELEXT_SHIFT 20
-+#define CDR_SELEXT_MASK (0xf << CDR_SELEXT_SHIFT)
-+#define CMUX_SHIFT_PHASE_SHIFT 24
-+#define CMUX_SHIFT_PHASE_MASK (7 << CMUX_SHIFT_PHASE_SHIFT)
-+
-+static const u32 tuning_block_64[] = {
-+ 0x00ff0fff, 0xccc3ccff, 0xffcc3cc3, 0xeffefffe,
-+ 0xddffdfff, 0xfbfffbff, 0xff7fffbf, 0xefbdf777,
-+ 0xf0fff0ff, 0x3cccfc0f, 0xcfcc33cc, 0xeeffefff,
-+ 0xfdfffdff, 0xffbfffdf, 0xfff7ffbb, 0xde7b7ff7
-+};
-+
-+static const u32 tuning_block_128[] = {
-+ 0xff00ffff, 0x0000ffff, 0xccccffff, 0xcccc33cc,
-+ 0xcc3333cc, 0xffffcccc, 0xffffeeff, 0xffeeeeff,
-+ 0xffddffff, 0xddddffff, 0xbbffffff, 0xbbffffff,
-+ 0xffffffbb, 0xffffff77, 0x77ff7777, 0xffeeddbb,
-+ 0x00ffffff, 0x00ffffff, 0xccffff00, 0xcc33cccc,
-+ 0x3333cccc, 0xffcccccc, 0xffeeffff, 0xeeeeffff,
-+ 0xddffffff, 0xddffffff, 0xffffffdd, 0xffffffbb,
-+ 0xffffbbbb, 0xffff77ff, 0xff7777ff, 0xeeddbb77
-+};
-
- struct sdhci_msm_host {
- struct platform_device *pdev;
-@@ -38,17 +76,389 @@ struct sdhci_msm_host {
- };
-
- /* Platform specific tuning */
--static int sdhci_msm_execute_tuning(struct sdhci_host *host, u32 opcode)
-+static inline int msm_dll_poll_ck_out_en(struct sdhci_host *host, u8 poll)
-+{
-+ u32 wait_cnt = 50;
-+ u8 ck_out_en;
-+ struct mmc_host *mmc = host->mmc;
-+
-+ /* Poll for CK_OUT_EN bit. max. poll time = 50us */
-+ ck_out_en = !!(readl_relaxed(host->ioaddr + CORE_DLL_CONFIG) &
-+ CORE_CK_OUT_EN);
-+
-+ while (ck_out_en != poll) {
-+ if (--wait_cnt == 0) {
-+ dev_err(mmc_dev(mmc), "%s: CK_OUT_EN bit is not %d\n",
-+ mmc_hostname(mmc), poll);
-+ return -ETIMEDOUT;
-+ }
-+ udelay(1);
-+
-+ ck_out_en = !!(readl_relaxed(host->ioaddr + CORE_DLL_CONFIG) &
-+ CORE_CK_OUT_EN);
-+ }
-+
-+ return 0;
-+}
-+
-+static int msm_config_cm_dll_phase(struct sdhci_host *host, u8 phase)
-+{
-+ int rc;
-+ static const u8 grey_coded_phase_table[] = {
-+ 0x0, 0x1, 0x3, 0x2, 0x6, 0x7, 0x5, 0x4,
-+ 0xc, 0xd, 0xf, 0xe, 0xa, 0xb, 0x9, 0x8
-+ };
-+ unsigned long flags;
-+ u32 config;
-+ struct mmc_host *mmc = host->mmc;
-+
-+ spin_lock_irqsave(&host->lock, flags);
-+
-+ config = readl_relaxed(host->ioaddr + CORE_DLL_CONFIG);
-+ config &= ~(CORE_CDR_EN | CORE_CK_OUT_EN);
-+ config |= (CORE_CDR_EXT_EN | CORE_DLL_EN);
-+ writel_relaxed(config, host->ioaddr + CORE_DLL_CONFIG);
-+
-+ /* Wait until CK_OUT_EN bit of DLL_CONFIG register becomes '0' */
-+ rc = msm_dll_poll_ck_out_en(host, 0);
-+ if (rc)
-+ goto err_out;
-+
-+ /*
-+ * Write the selected DLL clock output phase (0 ... 15)
-+ * to CDR_SELEXT bit field of DLL_CONFIG register.
-+ */
-+ config = readl_relaxed(host->ioaddr + CORE_DLL_CONFIG);
-+ config &= ~CDR_SELEXT_MASK;
-+ config |= grey_coded_phase_table[phase] << CDR_SELEXT_SHIFT;
-+ writel_relaxed(config, host->ioaddr + CORE_DLL_CONFIG);
-+
-+ /* Set CK_OUT_EN bit of DLL_CONFIG register to 1. */
-+ writel_relaxed((readl_relaxed(host->ioaddr + CORE_DLL_CONFIG)
-+ | CORE_CK_OUT_EN), host->ioaddr + CORE_DLL_CONFIG);
-+
-+ /* Wait until CK_OUT_EN bit of DLL_CONFIG register becomes '1' */
-+ rc = msm_dll_poll_ck_out_en(host, 1);
-+ if (rc)
-+ goto err_out;
-+
-+ config = readl_relaxed(host->ioaddr + CORE_DLL_CONFIG);
-+ config |= CORE_CDR_EN;
-+ config &= ~CORE_CDR_EXT_EN;
-+ writel_relaxed(config, host->ioaddr + CORE_DLL_CONFIG);
-+ goto out;
-+
-+err_out:
-+ dev_err(mmc_dev(mmc), "%s: Failed to set DLL phase: %d\n",
-+ mmc_hostname(mmc), phase);
-+out:
-+ spin_unlock_irqrestore(&host->lock, flags);
-+ return rc;
-+}
-+
-+/*
-+ * Find out the greatest range of consecuitive selected
-+ * DLL clock output phases that can be used as sampling
-+ * setting for SD3.0 UHS-I card read operation (in SDR104
-+ * timing mode) or for eMMC4.5 card read operation (in HS200
-+ * timing mode).
-+ * Select the 3/4 of the range and configure the DLL with the
-+ * selected DLL clock output phase.
-+ */
-+
-+static int msm_find_most_appropriate_phase(struct sdhci_host *host,
-+ u8 *phase_table, u8 total_phases)
-+{
-+ int ret;
-+ u8 ranges[MAX_PHASES][MAX_PHASES] = { {0}, {0} };
-+ u8 phases_per_row[MAX_PHASES] = { 0 };
-+ int row_index = 0, col_index = 0, selected_row_index = 0, curr_max = 0;
-+ int i, cnt, phase_0_raw_index = 0, phase_15_raw_index = 0;
-+ bool phase_0_found = false, phase_15_found = false;
-+ struct mmc_host *mmc = host->mmc;
-+
-+ if (!total_phases || (total_phases > MAX_PHASES)) {
-+ dev_err(mmc_dev(mmc), "%s: Invalid argument: total_phases=%d\n",
-+ mmc_hostname(mmc), total_phases);
-+ return -EINVAL;
-+ }
-+
-+ for (cnt = 0; cnt < total_phases; cnt++) {
-+ ranges[row_index][col_index] = phase_table[cnt];
-+ phases_per_row[row_index] += 1;
-+ col_index++;
-+
-+ if ((cnt + 1) == total_phases) {
-+ continue;
-+ /* check if next phase in phase_table is consecutive or not */
-+ } else if ((phase_table[cnt] + 1) != phase_table[cnt + 1]) {
-+ row_index++;
-+ col_index = 0;
-+ }
-+ }
-+
-+ if (row_index >= MAX_PHASES)
-+ return -EINVAL;
-+
-+ /* Check if phase-0 is present in first valid window? */
-+ if (!ranges[0][0]) {
-+ phase_0_found = true;
-+ phase_0_raw_index = 0;
-+ /* Check if cycle exist between 2 valid windows */
-+ for (cnt = 1; cnt <= row_index; cnt++) {
-+ if (phases_per_row[cnt]) {
-+ for (i = 0; i < phases_per_row[cnt]; i++) {
-+ if (ranges[cnt][i] == 15) {
-+ phase_15_found = true;
-+ phase_15_raw_index = cnt;
-+ break;
-+ }
-+ }
-+ }
-+ }
-+ }
-+
-+ /* If 2 valid windows form cycle then merge them as single window */
-+ if (phase_0_found && phase_15_found) {
-+ /* number of phases in raw where phase 0 is present */
-+ u8 phases_0 = phases_per_row[phase_0_raw_index];
-+ /* number of phases in raw where phase 15 is present */
-+ u8 phases_15 = phases_per_row[phase_15_raw_index];
-+
-+ if (phases_0 + phases_15 >= MAX_PHASES)
-+ /*
-+ * If there are more than 1 phase windows then total
-+ * number of phases in both the windows should not be
-+ * more than or equal to MAX_PHASES.
-+ */
-+ return -EINVAL;
-+
-+ /* Merge 2 cyclic windows */
-+ i = phases_15;
-+ for (cnt = 0; cnt < phases_0; cnt++) {
-+ ranges[phase_15_raw_index][i] =
-+ ranges[phase_0_raw_index][cnt];
-+ if (++i >= MAX_PHASES)
-+ break;
-+ }
-+
-+ phases_per_row[phase_0_raw_index] = 0;
-+ phases_per_row[phase_15_raw_index] = phases_15 + phases_0;
-+ }
-+
-+ for (cnt = 0; cnt <= row_index; cnt++) {
-+ if (phases_per_row[cnt] > curr_max) {
-+ curr_max = phases_per_row[cnt];
-+ selected_row_index = cnt;
-+ }
-+ }
-+
-+ i = (curr_max * 3) / 4;
-+ if (i)
-+ i--;
-+
-+ ret = ranges[selected_row_index][i];
-+
-+ if (ret >= MAX_PHASES) {
-+ ret = -EINVAL;
-+ dev_err(mmc_dev(mmc), "%s: Invalid phase selected=%d\n",
-+ mmc_hostname(mmc), ret);
-+ }
-+
-+ return ret;
-+}
-+
-+static inline void msm_cm_dll_set_freq(struct sdhci_host *host)
-+{
-+ u32 mclk_freq = 0, config;
-+
-+ /* Program the MCLK value to MCLK_FREQ bit field */
-+ if (host->clock <= 112000000)
-+ mclk_freq = 0;
-+ else if (host->clock <= 125000000)
-+ mclk_freq = 1;
-+ else if (host->clock <= 137000000)
-+ mclk_freq = 2;
-+ else if (host->clock <= 150000000)
-+ mclk_freq = 3;
-+ else if (host->clock <= 162000000)
-+ mclk_freq = 4;
-+ else if (host->clock <= 175000000)
-+ mclk_freq = 5;
-+ else if (host->clock <= 187000000)
-+ mclk_freq = 6;
-+ else if (host->clock <= 200000000)
-+ mclk_freq = 7;
-+
-+ config = readl_relaxed(host->ioaddr + CORE_DLL_CONFIG);
-+ config &= ~CMUX_SHIFT_PHASE_MASK;
-+ config |= mclk_freq << CMUX_SHIFT_PHASE_SHIFT;
-+ writel_relaxed(config, host->ioaddr + CORE_DLL_CONFIG);
-+}
-+
-+/* Initialize the DLL (Programmable Delay Line) */
-+static int msm_init_cm_dll(struct sdhci_host *host)
- {
-+ struct mmc_host *mmc = host->mmc;
-+ int wait_cnt = 50;
-+ unsigned long flags;
-+
-+ spin_lock_irqsave(&host->lock, flags);
-+
- /*
-- * Tuning is required for SDR104, HS200 and HS400 cards and if the clock
-- * frequency greater than 100MHz in those modes. The standard tuning
-- * procedure should not be executed, but a custom implementation will be
-- * added here instead.
-+ * Make sure that clock is always enabled when DLL
-+ * tuning is in progress. Keeping PWRSAVE ON may
-+ * turn off the clock.
- */
-+ writel_relaxed((readl_relaxed(host->ioaddr + CORE_VENDOR_SPEC)
-+ & ~CORE_CLK_PWRSAVE), host->ioaddr + CORE_VENDOR_SPEC);
-+
-+ /* Write 1 to DLL_RST bit of DLL_CONFIG register */
-+ writel_relaxed((readl_relaxed(host->ioaddr + CORE_DLL_CONFIG)
-+ | CORE_DLL_RST), host->ioaddr + CORE_DLL_CONFIG);
-+
-+ /* Write 1 to DLL_PDN bit of DLL_CONFIG register */
-+ writel_relaxed((readl_relaxed(host->ioaddr + CORE_DLL_CONFIG)
-+ | CORE_DLL_PDN), host->ioaddr + CORE_DLL_CONFIG);
-+ msm_cm_dll_set_freq(host);
-+
-+ /* Write 0 to DLL_RST bit of DLL_CONFIG register */
-+ writel_relaxed((readl_relaxed(host->ioaddr + CORE_DLL_CONFIG)
-+ & ~CORE_DLL_RST), host->ioaddr + CORE_DLL_CONFIG);
-+
-+ /* Write 0 to DLL_PDN bit of DLL_CONFIG register */
-+ writel_relaxed((readl_relaxed(host->ioaddr + CORE_DLL_CONFIG)
-+ & ~CORE_DLL_PDN), host->ioaddr + CORE_DLL_CONFIG);
-+
-+ /* Set DLL_EN bit to 1. */
-+ writel_relaxed((readl_relaxed(host->ioaddr + CORE_DLL_CONFIG)
-+ | CORE_DLL_EN), host->ioaddr + CORE_DLL_CONFIG);
-+
-+ /* Set CK_OUT_EN bit to 1. */
-+ writel_relaxed((readl_relaxed(host->ioaddr + CORE_DLL_CONFIG)
-+ | CORE_CK_OUT_EN), host->ioaddr + CORE_DLL_CONFIG);
-+
-+ /* Wait until DLL_LOCK bit of DLL_STATUS register becomes '1' */
-+ while (!(readl_relaxed(host->ioaddr + CORE_DLL_STATUS) &
-+ CORE_DLL_LOCK)) {
-+ /* max. wait for 50us sec for LOCK bit to be set */
-+ if (--wait_cnt == 0) {
-+ dev_err(mmc_dev(mmc), "%s: DLL failed to LOCK\n",
-+ mmc_hostname(mmc));
-+ spin_unlock_irqrestore(&host->lock, flags);
-+ return -ETIMEDOUT;
-+ }
-+ udelay(1);
-+ }
-+
-+ spin_unlock_irqrestore(&host->lock, flags);
- return 0;
- }
-
-+static int sdhci_msm_execute_tuning(struct sdhci_host *host, u32 opcode)
-+{
-+ int tuning_seq_cnt = 3;
-+ u8 phase, *data_buf, tuned_phases[16], tuned_phase_cnt = 0;
-+ const u32 *tuning_block_pattern = tuning_block_64;
-+ int size = sizeof(tuning_block_64); /* Pattern size in bytes */
-+ int rc;
-+ struct mmc_host *mmc = host->mmc;
-+ struct mmc_ios ios = host->mmc->ios;
-+
-+ /*
-+ * Tuning is required for SDR104, HS200 and HS400 cards and
-+ * if clock frequency is greater than 100MHz in these modes.
-+ */
-+ if (host->clock <= 100 * 1000 * 1000 ||
-+ !((ios.timing == MMC_TIMING_MMC_HS200) ||
-+ (ios.timing == MMC_TIMING_UHS_SDR104)))
-+ return 0;
-+
-+ if ((opcode == MMC_SEND_TUNING_BLOCK_HS200) &&
-+ (mmc->ios.bus_width == MMC_BUS_WIDTH_8)) {
-+ tuning_block_pattern = tuning_block_128;
-+ size = sizeof(tuning_block_128);
-+ }
-+
-+ data_buf = kmalloc(size, GFP_KERNEL);
-+ if (!data_buf)
-+ return -ENOMEM;
-+
-+retry:
-+ /* First of all reset the tuning block */
-+ rc = msm_init_cm_dll(host);
-+ if (rc)
-+ goto out;
-+
-+ phase = 0;
-+ do {
-+ struct mmc_command cmd = { 0 };
-+ struct mmc_data data = { 0 };
-+ struct mmc_request mrq = {
-+ .cmd = &cmd,
-+ .data = &data
-+ };
-+ struct scatterlist sg;
-+
-+ /* Set the phase in delay line hw block */
-+ rc = msm_config_cm_dll_phase(host, phase);
-+ if (rc)
-+ goto out;
-+
-+ cmd.opcode = opcode;
-+ cmd.flags = MMC_RSP_R1 | MMC_CMD_ADTC;
-+
-+ data.blksz = size;
-+ data.blocks = 1;
-+ data.flags = MMC_DATA_READ;
-+ data.timeout_ns = NSEC_PER_SEC; /* 1 second */
-+
-+ data.sg = &sg;
-+ data.sg_len = 1;
-+ sg_init_one(&sg, data_buf, size);
-+ memset(data_buf, 0, size);
-+ mmc_wait_for_req(mmc, &mrq);
-+
-+ if (!cmd.error && !data.error &&
-+ !memcmp(data_buf, tuning_block_pattern, size)) {
-+ /* Tuning is successful at this tuning point */
-+ tuned_phases[tuned_phase_cnt++] = phase;
-+ dev_dbg(mmc_dev(mmc), "%s: Found good phase = %d\n",
-+ mmc_hostname(mmc), phase);
-+ }
-+ } while (++phase < ARRAY_SIZE(tuned_phases));
-+
-+ if (tuned_phase_cnt) {
-+ rc = msm_find_most_appropriate_phase(host, tuned_phases,
-+ tuned_phase_cnt);
-+ if (rc < 0)
-+ goto out;
-+ else
-+ phase = rc;
-+
-+ /*
-+ * Finally set the selected phase in delay
-+ * line hw block.
-+ */
-+ rc = msm_config_cm_dll_phase(host, phase);
-+ if (rc)
-+ goto out;
-+ dev_dbg(mmc_dev(mmc), "%s: Setting the tuning phase to %d\n",
-+ mmc_hostname(mmc), phase);
-+ } else {
-+ if (--tuning_seq_cnt)
-+ goto retry;
-+ /* Tuning failed */
-+ dev_dbg(mmc_dev(mmc), "%s: No tuning point found\n",
-+ mmc_hostname(mmc));
-+ rc = -EIO;
-+ }
-+
-+out:
-+ kfree(data_buf);
-+ return rc;
-+}
-+
- static const struct of_device_id sdhci_msm_dt_match[] = {
- { .compatible = "qcom,sdhci-msm-v4" },
- {},
diff --git a/target/linux/ipq806x/patches/0049-drivers-of-add-initialization-code-for-static-reserv.patch b/target/linux/ipq806x/patches/0049-drivers-of-add-initialization-code-for-static-reserv.patch
deleted file mode 100644
index 1e304dd..0000000
--- a/target/linux/ipq806x/patches/0049-drivers-of-add-initialization-code-for-static-reserv.patch
+++ /dev/null
@@ -1,209 +0,0 @@
-From 60ee5b21ce14a7d5c269115b0751b904d0e005ed Mon Sep 17 00:00:00 2001
-From: Marek Szyprowski <m.szyprowski@samsung.com>
-Date: Fri, 28 Feb 2014 14:42:47 +0100
-Subject: [PATCH 049/182] drivers: of: add initialization code for static
- reserved memory
-
-This patch adds support for static (defined by 'reg' property) reserved
-memory regions declared in device tree.
-
-Memory blocks can be reliably reserved only during early boot. This must
-happen before the whole memory management subsystem is initialized,
-because we need to ensure that the given contiguous blocks are not yet
-allocated by kernel. Also it must happen before kernel mappings for the
-whole low memory are created, to ensure that there will be no mappings
-(for reserved blocks). Typically, all this happens before device tree
-structures are unflattened, so we need to get reserved memory layout
-directly from fdt.
-
-Based on previous code provided by Josh Cartwright <joshc@codeaurora.org>
-
-Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
-Signed-off-by: Grant Likely <grant.likely@linaro.org>
----
- drivers/of/fdt.c | 131 ++++++++++++++++++++++++++++++++++++++++++++++++
- include/linux/of_fdt.h | 4 ++
- 2 files changed, 135 insertions(+)
-
---- a/drivers/of/fdt.c
-+++ b/drivers/of/fdt.c
-@@ -15,6 +15,7 @@
- #include <linux/module.h>
- #include <linux/of.h>
- #include <linux/of_fdt.h>
-+#include <linux/sizes.h>
- #include <linux/string.h>
- #include <linux/errno.h>
- #include <linux/slab.h>
-@@ -440,6 +441,118 @@ struct boot_param_header *initial_boot_p
- #ifdef CONFIG_OF_EARLY_FLATTREE
-
- /**
-+ * res_mem_reserve_reg() - reserve all memory described in 'reg' property
-+ */
-+static int __init __reserved_mem_reserve_reg(unsigned long node,
-+ const char *uname)
-+{
-+ int t_len = (dt_root_addr_cells + dt_root_size_cells) * sizeof(__be32);
-+ phys_addr_t base, size;
-+ unsigned long len;
-+ __be32 *prop;
-+ int nomap;
-+
-+ prop = of_get_flat_dt_prop(node, "reg", &len);
-+ if (!prop)
-+ return -ENOENT;
-+
-+ if (len && len % t_len != 0) {
-+ pr_err("Reserved memory: invalid reg property in '%s', skipping node.\n",
-+ uname);
-+ return -EINVAL;
-+ }
-+
-+ nomap = of_get_flat_dt_prop(node, "no-map", NULL) != NULL;
-+
-+ while (len >= t_len) {
-+ base = dt_mem_next_cell(dt_root_addr_cells, &prop);
-+ size = dt_mem_next_cell(dt_root_size_cells, &prop);
-+
-+ if (base && size &&
-+ early_init_dt_reserve_memory_arch(base, size, nomap) == 0)
-+ pr_debug("Reserved memory: reserved region for node '%s': base %pa, size %ld MiB\n",
-+ uname, &base, (unsigned long)size / SZ_1M);
-+ else
-+ pr_info("Reserved memory: failed to reserve memory for node '%s': base %pa, size %ld MiB\n",
-+ uname, &base, (unsigned long)size / SZ_1M);
-+
-+ len -= t_len;
-+ }
-+ return 0;
-+}
-+
-+/**
-+ * __reserved_mem_check_root() - check if #size-cells, #address-cells provided
-+ * in /reserved-memory matches the values supported by the current implementation,
-+ * also check if ranges property has been provided
-+ */
-+static int __reserved_mem_check_root(unsigned long node)
-+{
-+ __be32 *prop;
-+
-+ prop = of_get_flat_dt_prop(node, "#size-cells", NULL);
-+ if (!prop || be32_to_cpup(prop) != dt_root_size_cells)
-+ return -EINVAL;
-+
-+ prop = of_get_flat_dt_prop(node, "#address-cells", NULL);
-+ if (!prop || be32_to_cpup(prop) != dt_root_addr_cells)
-+ return -EINVAL;
-+
-+ prop = of_get_flat_dt_prop(node, "ranges", NULL);
-+ if (!prop)
-+ return -EINVAL;
-+ return 0;
-+}
-+
-+/**
-+ * fdt_scan_reserved_mem() - scan a single FDT node for reserved memory
-+ */
-+static int __init __fdt_scan_reserved_mem(unsigned long node, const char *uname,
-+ int depth, void *data)
-+{
-+ static int found;
-+ const char *status;
-+
-+ if (!found && depth == 1 && strcmp(uname, "reserved-memory") == 0) {
-+ if (__reserved_mem_check_root(node) != 0) {
-+ pr_err("Reserved memory: unsupported node format, ignoring\n");
-+ /* break scan */
-+ return 1;
-+ }
-+ found = 1;
-+ /* scan next node */
-+ return 0;
-+ } else if (!found) {
-+ /* scan next node */
-+ return 0;
-+ } else if (found && depth < 2) {
-+ /* scanning of /reserved-memory has been finished */
-+ return 1;
-+ }
-+
-+ status = of_get_flat_dt_prop(node, "status", NULL);
-+ if (status && strcmp(status, "okay") != 0 && strcmp(status, "ok") != 0)
-+ return 0;
-+
-+ __reserved_mem_reserve_reg(node, uname);
-+
-+ /* scan next node */
-+ return 0;
-+}
-+
-+/**
-+ * early_init_fdt_scan_reserved_mem() - create reserved memory regions
-+ *
-+ * This function grabs memory from early allocator for device exclusive use
-+ * defined in device tree structures. It should be called by arch specific code
-+ * once the early allocator (i.e. memblock) has been fully activated.
-+ */
-+void __init early_init_fdt_scan_reserved_mem(void)
-+{
-+ of_scan_flat_dt(__fdt_scan_reserved_mem, NULL);
-+}
-+
-+/**
- * of_scan_flat_dt - scan flattened tree blob and call callback on each.
- * @it: callback function
- * @data: context data pointer
-@@ -859,6 +972,16 @@ void __init __weak early_init_dt_add_mem
- memblock_add(base, size);
- }
-
-+int __init __weak early_init_dt_reserve_memory_arch(phys_addr_t base,
-+ phys_addr_t size, bool nomap)
-+{
-+ if (memblock_is_region_reserved(base, size))
-+ return -EBUSY;
-+ if (nomap)
-+ return memblock_remove(base, size);
-+ return memblock_reserve(base, size);
-+}
-+
- /*
- * called from unflatten_device_tree() to bootstrap devicetree itself
- * Architectures can override this definition if memblock isn't used
-@@ -867,6 +990,14 @@ void * __init __weak early_init_dt_alloc
- {
- return __va(memblock_alloc(size, align));
- }
-+#else
-+int __init __weak early_init_dt_reserve_memory_arch(phys_addr_t base,
-+ phys_addr_t size, bool nomap)
-+{
-+ pr_err("Reserved memory not supported, ignoring range 0x%llx - 0x%llx%s\n",
-+ base, size, nomap ? " (nomap)" : "");
-+ return -ENOSYS;
-+}
- #endif
-
- bool __init early_init_dt_scan(void *params)
---- a/include/linux/of_fdt.h
-+++ b/include/linux/of_fdt.h
-@@ -98,7 +98,10 @@ extern int early_init_dt_scan_chosen(uns
- int depth, void *data);
- extern int early_init_dt_scan_memory(unsigned long node, const char *uname,
- int depth, void *data);
-+extern void early_init_fdt_scan_reserved_mem(void);
- extern void early_init_dt_add_memory_arch(u64 base, u64 size);
-+extern int early_init_dt_reserve_memory_arch(phys_addr_t base, phys_addr_t size,
-+ bool no_map);
- extern void * early_init_dt_alloc_memory_arch(u64 size, u64 align);
- extern u64 dt_mem_next_cell(int s, __be32 **cellp);
-
-@@ -118,6 +121,7 @@ extern void unflatten_and_copy_device_tr
- extern void early_init_devtree(void *);
- extern void early_get_first_memblock_info(void *, phys_addr_t *);
- #else /* CONFIG_OF_FLATTREE */
-+static inline void early_init_fdt_scan_reserved_mem(void) {}
- static inline const char *of_flat_dt_get_machine_name(void) { return NULL; }
- static inline void unflatten_device_tree(void) {}
- static inline void unflatten_and_copy_device_tree(void) {}
diff --git a/target/linux/ipq806x/patches/0050-drivers-of-add-initialization-code-for-dynamic-reser.patch b/target/linux/ipq806x/patches/0050-drivers-of-add-initialization-code-for-dynamic-reser.patch
deleted file mode 100644
index 4b633b5..0000000
--- a/target/linux/ipq806x/patches/0050-drivers-of-add-initialization-code-for-dynamic-reser.patch
+++ /dev/null
@@ -1,316 +0,0 @@
-From 968b497e1027ec78e986370976c76e1652aa0459 Mon Sep 17 00:00:00 2001
-From: Marek Szyprowski <m.szyprowski@samsung.com>
-Date: Fri, 28 Feb 2014 14:42:48 +0100
-Subject: [PATCH 050/182] drivers: of: add initialization code for dynamic
- reserved memory
-
-This patch adds support for dynamically allocated reserved memory regions
-declared in device tree. Such regions are defined by 'size', 'alignment'
-and 'alloc-ranges' properties.
-
-Based on previous code provided by Josh Cartwright <joshc@codeaurora.org>
-
-Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
-Signed-off-by: Grant Likely <grant.likely@linaro.org>
----
- drivers/of/Kconfig | 6 ++
- drivers/of/Makefile | 1 +
- drivers/of/fdt.c | 13 ++-
- drivers/of/of_reserved_mem.c | 188 +++++++++++++++++++++++++++++++++++++++
- include/linux/of_reserved_mem.h | 21 +++++
- 5 files changed, 227 insertions(+), 2 deletions(-)
- create mode 100644 drivers/of/of_reserved_mem.c
- create mode 100644 include/linux/of_reserved_mem.h
-
---- a/drivers/of/Kconfig
-+++ b/drivers/of/Kconfig
-@@ -75,4 +75,10 @@ config OF_MTD
- depends on MTD
- def_bool y
-
-+config OF_RESERVED_MEM
-+ depends on OF_EARLY_FLATTREE
-+ bool
-+ help
-+ Helpers to allow for reservation of memory regions
-+
- endmenu # OF
---- a/drivers/of/Makefile
-+++ b/drivers/of/Makefile
-@@ -9,3 +9,4 @@ obj-$(CONFIG_OF_MDIO) += of_mdio.o
- obj-$(CONFIG_OF_PCI) += of_pci.o
- obj-$(CONFIG_OF_PCI_IRQ) += of_pci_irq.o
- obj-$(CONFIG_OF_MTD) += of_mtd.o
-+obj-$(CONFIG_OF_RESERVED_MEM) += of_reserved_mem.o
---- a/drivers/of/fdt.c
-+++ b/drivers/of/fdt.c
-@@ -15,6 +15,7 @@
- #include <linux/module.h>
- #include <linux/of.h>
- #include <linux/of_fdt.h>
-+#include <linux/of_reserved_mem.h>
- #include <linux/sizes.h>
- #include <linux/string.h>
- #include <linux/errno.h>
-@@ -450,7 +451,7 @@ static int __init __reserved_mem_reserve
- phys_addr_t base, size;
- unsigned long len;
- __be32 *prop;
-- int nomap;
-+ int nomap, first = 1;
-
- prop = of_get_flat_dt_prop(node, "reg", &len);
- if (!prop)
-@@ -477,6 +478,10 @@ static int __init __reserved_mem_reserve
- uname, &base, (unsigned long)size / SZ_1M);
-
- len -= t_len;
-+ if (first) {
-+ fdt_reserved_mem_save_node(node, uname, base, size);
-+ first = 0;
-+ }
- }
- return 0;
- }
-@@ -512,6 +517,7 @@ static int __init __fdt_scan_reserved_me
- {
- static int found;
- const char *status;
-+ int err;
-
- if (!found && depth == 1 && strcmp(uname, "reserved-memory") == 0) {
- if (__reserved_mem_check_root(node) != 0) {
-@@ -534,7 +540,9 @@ static int __init __fdt_scan_reserved_me
- if (status && strcmp(status, "okay") != 0 && strcmp(status, "ok") != 0)
- return 0;
-
-- __reserved_mem_reserve_reg(node, uname);
-+ err = __reserved_mem_reserve_reg(node, uname);
-+ if (err == -ENOENT && of_get_flat_dt_prop(node, "size", NULL))
-+ fdt_reserved_mem_save_node(node, uname, 0, 0);
-
- /* scan next node */
- return 0;
-@@ -550,6 +558,7 @@ static int __init __fdt_scan_reserved_me
- void __init early_init_fdt_scan_reserved_mem(void)
- {
- of_scan_flat_dt(__fdt_scan_reserved_mem, NULL);
-+ fdt_init_reserved_mem();
- }
-
- /**
---- /dev/null
-+++ b/drivers/of/of_reserved_mem.c
-@@ -0,0 +1,188 @@
-+/*
-+ * Device tree based initialization code for reserved memory.
-+ *
-+ * Copyright (c) 2013, The Linux Foundation. All Rights Reserved.
-+ * Copyright (c) 2013,2014 Samsung Electronics Co., Ltd.
-+ * http://www.samsung.com
-+ * Author: Marek Szyprowski <m.szyprowski@samsung.com>
-+ * Author: Josh Cartwright <joshc@codeaurora.org>
-+ *
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU General Public License as
-+ * published by the Free Software Foundation; either version 2 of the
-+ * License or (at your optional) any later version of the license.
-+ */
-+
-+#include <linux/err.h>
-+#include <linux/of.h>
-+#include <linux/of_fdt.h>
-+#include <linux/of_platform.h>
-+#include <linux/mm.h>
-+#include <linux/sizes.h>
-+#include <linux/of_reserved_mem.h>
-+
-+#define MAX_RESERVED_REGIONS 16
-+static struct reserved_mem reserved_mem[MAX_RESERVED_REGIONS];
-+static int reserved_mem_count;
-+
-+#if defined(CONFIG_HAVE_MEMBLOCK)
-+#include <linux/memblock.h>
-+int __init __weak early_init_dt_alloc_reserved_memory_arch(phys_addr_t size,
-+ phys_addr_t align, phys_addr_t start, phys_addr_t end, bool nomap,
-+ phys_addr_t *res_base)
-+{
-+ /*
-+ * We use __memblock_alloc_base() because memblock_alloc_base()
-+ * panic()s on allocation failure.
-+ */
-+ phys_addr_t base = __memblock_alloc_base(size, align, end);
-+ if (!base)
-+ return -ENOMEM;
-+
-+ /*
-+ * Check if the allocated region fits in to start..end window
-+ */
-+ if (base < start) {
-+ memblock_free(base, size);
-+ return -ENOMEM;
-+ }
-+
-+ *res_base = base;
-+ if (nomap)
-+ return memblock_remove(base, size);
-+ return 0;
-+}
-+#else
-+int __init __weak early_init_dt_alloc_reserved_memory_arch(phys_addr_t size,
-+ phys_addr_t align, phys_addr_t start, phys_addr_t end, bool nomap,
-+ phys_addr_t *res_base)
-+{
-+ pr_err("Reserved memory not supported, ignoring region 0x%llx%s\n",
-+ size, nomap ? " (nomap)" : "");
-+ return -ENOSYS;
-+}
-+#endif
-+
-+/**
-+ * res_mem_save_node() - save fdt node for second pass initialization
-+ */
-+void __init fdt_reserved_mem_save_node(unsigned long node, const char *uname,
-+ phys_addr_t base, phys_addr_t size)
-+{
-+ struct reserved_mem *rmem = &reserved_mem[reserved_mem_count];
-+
-+ if (reserved_mem_count == ARRAY_SIZE(reserved_mem)) {
-+ pr_err("Reserved memory: not enough space all defined regions.\n");
-+ return;
-+ }
-+
-+ rmem->fdt_node = node;
-+ rmem->name = uname;
-+ rmem->base = base;
-+ rmem->size = size;
-+
-+ reserved_mem_count++;
-+ return;
-+}
-+
-+/**
-+ * res_mem_alloc_size() - allocate reserved memory described by 'size', 'align'
-+ * and 'alloc-ranges' properties
-+ */
-+static int __init __reserved_mem_alloc_size(unsigned long node,
-+ const char *uname, phys_addr_t *res_base, phys_addr_t *res_size)
-+{
-+ int t_len = (dt_root_addr_cells + dt_root_size_cells) * sizeof(__be32);
-+ phys_addr_t start = 0, end = 0;
-+ phys_addr_t base = 0, align = 0, size;
-+ unsigned long len;
-+ __be32 *prop;
-+ int nomap;
-+ int ret;
-+
-+ prop = of_get_flat_dt_prop(node, "size", &len);
-+ if (!prop)
-+ return -EINVAL;
-+
-+ if (len != dt_root_size_cells * sizeof(__be32)) {
-+ pr_err("Reserved memory: invalid size property in '%s' node.\n",
-+ uname);
-+ return -EINVAL;
-+ }
-+ size = dt_mem_next_cell(dt_root_size_cells, &prop);
-+
-+ nomap = of_get_flat_dt_prop(node, "no-map", NULL) != NULL;
-+
-+ prop = of_get_flat_dt_prop(node, "alignment", &len);
-+ if (prop) {
-+ if (len != dt_root_addr_cells * sizeof(__be32)) {
-+ pr_err("Reserved memory: invalid alignment property in '%s' node.\n",
-+ uname);
-+ return -EINVAL;
-+ }
-+ align = dt_mem_next_cell(dt_root_addr_cells, &prop);
-+ }
-+
-+ prop = of_get_flat_dt_prop(node, "alloc-ranges", &len);
-+ if (prop) {
-+
-+ if (len % t_len != 0) {
-+ pr_err("Reserved memory: invalid alloc-ranges property in '%s', skipping node.\n",
-+ uname);
-+ return -EINVAL;
-+ }
-+
-+ base = 0;
-+
-+ while (len > 0) {
-+ start = dt_mem_next_cell(dt_root_addr_cells, &prop);
-+ end = start + dt_mem_next_cell(dt_root_size_cells,
-+ &prop);
-+
-+ ret = early_init_dt_alloc_reserved_memory_arch(size,
-+ align, start, end, nomap, &base);
-+ if (ret == 0) {
-+ pr_debug("Reserved memory: allocated memory for '%s' node: base %pa, size %ld MiB\n",
-+ uname, &base,
-+ (unsigned long)size / SZ_1M);
-+ break;
-+ }
-+ len -= t_len;
-+ }
-+
-+ } else {
-+ ret = early_init_dt_alloc_reserved_memory_arch(size, align,
-+ 0, 0, nomap, &base);
-+ if (ret == 0)
-+ pr_debug("Reserved memory: allocated memory for '%s' node: base %pa, size %ld MiB\n",
-+ uname, &base, (unsigned long)size / SZ_1M);
-+ }
-+
-+ if (base == 0) {
-+ pr_info("Reserved memory: failed to allocate memory for node '%s'\n",
-+ uname);
-+ return -ENOMEM;
-+ }
-+
-+ *res_base = base;
-+ *res_size = size;
-+
-+ return 0;
-+}
-+
-+/**
-+ * fdt_init_reserved_mem - allocate and init all saved reserved memory regions
-+ */
-+void __init fdt_init_reserved_mem(void)
-+{
-+ int i;
-+ for (i = 0; i < reserved_mem_count; i++) {
-+ struct reserved_mem *rmem = &reserved_mem[i];
-+ unsigned long node = rmem->fdt_node;
-+ int err = 0;
-+
-+ if (rmem->size == 0)
-+ err = __reserved_mem_alloc_size(node, rmem->name,
-+ &rmem->base, &rmem->size);
-+ }
-+}
---- /dev/null
-+++ b/include/linux/of_reserved_mem.h
-@@ -0,0 +1,21 @@
-+#ifndef __OF_RESERVED_MEM_H
-+#define __OF_RESERVED_MEM_H
-+
-+struct reserved_mem {
-+ const char *name;
-+ unsigned long fdt_node;
-+ phys_addr_t base;
-+ phys_addr_t size;
-+};
-+
-+#ifdef CONFIG_OF_RESERVED_MEM
-+void fdt_init_reserved_mem(void);
-+void fdt_reserved_mem_save_node(unsigned long node, const char *uname,
-+ phys_addr_t base, phys_addr_t size);
-+#else
-+static inline void fdt_init_reserved_mem(void) { }
-+static inline void fdt_reserved_mem_save_node(unsigned long node,
-+ const char *uname, phys_addr_t base, phys_addr_t size) { }
-+#endif
-+
-+#endif /* __OF_RESERVED_MEM_H */
diff --git a/target/linux/ipq806x/patches/0051-drivers-of-add-support-for-custom-reserved-memory-dr.patch b/target/linux/ipq806x/patches/0051-drivers-of-add-support-for-custom-reserved-memory-dr.patch
deleted file mode 100644
index 48ad8ac..0000000
--- a/target/linux/ipq806x/patches/0051-drivers-of-add-support-for-custom-reserved-memory-dr.patch
+++ /dev/null
@@ -1,147 +0,0 @@
-From fc9e25ed9db2fcfbf16a9cbbf5a1f449da78f1d9 Mon Sep 17 00:00:00 2001
-From: Marek Szyprowski <m.szyprowski@samsung.com>
-Date: Fri, 28 Feb 2014 14:42:49 +0100
-Subject: [PATCH 051/182] drivers: of: add support for custom reserved memory
- drivers
-
-Add support for custom reserved memory drivers. Call their init() function
-for each reserved region and prepare for using operations provided by them
-with by the reserved_mem->ops array.
-
-Based on previous code provided by Josh Cartwright <joshc@codeaurora.org>
-
-Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
-Signed-off-by: Grant Likely <grant.likely@linaro.org>
----
- drivers/of/of_reserved_mem.c | 29 +++++++++++++++++++++++++++++
- include/asm-generic/vmlinux.lds.h | 11 +++++++++++
- include/linux/of_reserved_mem.h | 32 ++++++++++++++++++++++++++++++++
- 3 files changed, 72 insertions(+)
-
---- a/drivers/of/of_reserved_mem.c
-+++ b/drivers/of/of_reserved_mem.c
-@@ -170,6 +170,33 @@ static int __init __reserved_mem_alloc_s
- return 0;
- }
-
-+static const struct of_device_id __rmem_of_table_sentinel
-+ __used __section(__reservedmem_of_table_end);
-+
-+/**
-+ * res_mem_init_node() - call region specific reserved memory init code
-+ */
-+static int __init __reserved_mem_init_node(struct reserved_mem *rmem)
-+{
-+ extern const struct of_device_id __reservedmem_of_table[];
-+ const struct of_device_id *i;
-+
-+ for (i = __reservedmem_of_table; i < &__rmem_of_table_sentinel; i++) {
-+ reservedmem_of_init_fn initfn = i->data;
-+ const char *compat = i->compatible;
-+
-+ if (!of_flat_dt_is_compatible(rmem->fdt_node, compat))
-+ continue;
-+
-+ if (initfn(rmem, rmem->fdt_node, rmem->name) == 0) {
-+ pr_info("Reserved memory: initialized node %s, compatible id %s\n",
-+ rmem->name, compat);
-+ return 0;
-+ }
-+ }
-+ return -ENOENT;
-+}
-+
- /**
- * fdt_init_reserved_mem - allocate and init all saved reserved memory regions
- */
-@@ -184,5 +211,7 @@ void __init fdt_init_reserved_mem(void)
- if (rmem->size == 0)
- err = __reserved_mem_alloc_size(node, rmem->name,
- &rmem->base, &rmem->size);
-+ if (err == 0)
-+ __reserved_mem_init_node(rmem);
- }
- }
---- a/include/asm-generic/vmlinux.lds.h
-+++ b/include/asm-generic/vmlinux.lds.h
-@@ -177,6 +177,16 @@
- #define CLK_OF_TABLES()
- #endif
-
-+#ifdef CONFIG_OF_RESERVED_MEM
-+#define RESERVEDMEM_OF_TABLES() \
-+ . = ALIGN(8); \
-+ VMLINUX_SYMBOL(__reservedmem_of_table) = .; \
-+ *(__reservedmem_of_table) \
-+ *(__reservedmem_of_table_end)
-+#else
-+#define RESERVEDMEM_OF_TABLES()
-+#endif
-+
- #ifdef CONFIG_SMP
- #define CPU_METHOD_OF_TABLES() . = ALIGN(8); \
- VMLINUX_SYMBOL(__cpu_method_of_table_begin) = .; \
-@@ -510,6 +520,7 @@
- TRACE_SYSCALLS() \
- MEM_DISCARD(init.rodata) \
- CLK_OF_TABLES() \
-+ RESERVEDMEM_OF_TABLES() \
- CLKSRC_OF_TABLES() \
- CPU_METHOD_OF_TABLES() \
- KERNEL_DTB() \
---- a/include/linux/of_reserved_mem.h
-+++ b/include/linux/of_reserved_mem.h
-@@ -1,21 +1,53 @@
- #ifndef __OF_RESERVED_MEM_H
- #define __OF_RESERVED_MEM_H
-
-+struct device;
-+struct of_phandle_args;
-+struct reserved_mem_ops;
-+
- struct reserved_mem {
- const char *name;
- unsigned long fdt_node;
-+ const struct reserved_mem_ops *ops;
- phys_addr_t base;
- phys_addr_t size;
-+ void *priv;
-+};
-+
-+struct reserved_mem_ops {
-+ void (*device_init)(struct reserved_mem *rmem,
-+ struct device *dev);
-+ void (*device_release)(struct reserved_mem *rmem,
-+ struct device *dev);
- };
-
-+typedef int (*reservedmem_of_init_fn)(struct reserved_mem *rmem,
-+ unsigned long node, const char *uname);
-+
- #ifdef CONFIG_OF_RESERVED_MEM
- void fdt_init_reserved_mem(void);
- void fdt_reserved_mem_save_node(unsigned long node, const char *uname,
- phys_addr_t base, phys_addr_t size);
-+
-+#define RESERVEDMEM_OF_DECLARE(name, compat, init) \
-+ static const struct of_device_id __reservedmem_of_table_##name \
-+ __used __section(__reservedmem_of_table) \
-+ = { .compatible = compat, \
-+ .data = (init == (reservedmem_of_init_fn)NULL) ? \
-+ init : init }
-+
- #else
- static inline void fdt_init_reserved_mem(void) { }
- static inline void fdt_reserved_mem_save_node(unsigned long node,
- const char *uname, phys_addr_t base, phys_addr_t size) { }
-+
-+#define RESERVEDMEM_OF_DECLARE(name, compat, init) \
-+ static const struct of_device_id __reservedmem_of_table_##name \
-+ __attribute__((unused)) \
-+ = { .compatible = compat, \
-+ .data = (init == (reservedmem_of_init_fn)NULL) ? \
-+ init : init }
-+
- #endif
-
- #endif /* __OF_RESERVED_MEM_H */
diff --git a/target/linux/ipq806x/patches/0052-arm-add-support-for-reserved-memory-defined-by-devic.patch b/target/linux/ipq806x/patches/0052-arm-add-support-for-reserved-memory-defined-by-devic.patch
deleted file mode 100644
index 7e90e2d..0000000
--- a/target/linux/ipq806x/patches/0052-arm-add-support-for-reserved-memory-defined-by-devic.patch
+++ /dev/null
@@ -1,36 +0,0 @@
-From 95c831bca9181df62230171fd66286d08ea886a8 Mon Sep 17 00:00:00 2001
-From: Marek Szyprowski <m.szyprowski@samsung.com>
-Date: Fri, 28 Feb 2014 14:42:54 +0100
-Subject: [PATCH 052/182] arm: add support for reserved memory defined by
- device tree
-
-Enable reserved memory initialization from device tree.
-
-Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
-Signed-off-by: Grant Likely <grant.likely@linaro.org>
----
- arch/arm/Kconfig | 1 +
- arch/arm/mm/init.c | 2 ++
- 2 files changed, 3 insertions(+)
-
---- a/arch/arm/Kconfig
-+++ b/arch/arm/Kconfig
-@@ -1923,6 +1923,7 @@ config USE_OF
- select IRQ_DOMAIN
- select OF
- select OF_EARLY_FLATTREE
-+ select OF_RESERVED_MEM
- help
- Include support for flattened device tree machine descriptions.
-
---- a/arch/arm/mm/init.c
-+++ b/arch/arm/mm/init.c
-@@ -323,6 +323,8 @@ void __init arm_memblock_init(struct mem
- if (mdesc->reserve)
- mdesc->reserve();
-
-+ early_init_fdt_scan_reserved_mem();
-+
- /*
- * reserve memory for DMA contigouos allocations,
- * must come from DMA area inside low memory
diff --git a/target/linux/ipq806x/patches/0053-of-document-bindings-for-reserved-memory-nodes.patch b/target/linux/ipq806x/patches/0053-of-document-bindings-for-reserved-memory-nodes.patch
deleted file mode 100644
index 5363b70..0000000
--- a/target/linux/ipq806x/patches/0053-of-document-bindings-for-reserved-memory-nodes.patch
+++ /dev/null
@@ -1,158 +0,0 @@
-From 060a8e3db75ef98fb296b03b8fb0cdfcbcc76c6e Mon Sep 17 00:00:00 2001
-From: Grant Likely <grant.likely@linaro.org>
-Date: Fri, 28 Feb 2014 14:42:46 +0100
-Subject: [PATCH 053/182] of: document bindings for reserved-memory nodes
-
-Reserved memory nodes allow for the reservation of static (fixed
-address) regions, or dynamically allocated regions for a specific
-purpose.
-
-[joshc: Based on binding document proposed (in non-patch form) here:
- http://lkml.kernel.org/g/20131030134702.19B57C402A0@trevor.secretlab.ca
- adapted to support #memory-region-cells]
-Signed-off-by: Josh Cartwright <joshc@codeaurora.org>
-[mszyprow: removed #memory-region-cells property]
-Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
-[grant.likely: removed residual #memory-region-cells example]
-Signed-off-by: Grant Likely <grant.likely@linaro.org>
----
- .../bindings/reserved-memory/reserved-memory.txt | 133 ++++++++++++++++++++
- 1 file changed, 133 insertions(+)
- create mode 100644 Documentation/devicetree/bindings/reserved-memory/reserved-memory.txt
-
---- /dev/null
-+++ b/Documentation/devicetree/bindings/reserved-memory/reserved-memory.txt
-@@ -0,0 +1,133 @@
-+*** Reserved memory regions ***
-+
-+Reserved memory is specified as a node under the /reserved-memory node.
-+The operating system shall exclude reserved memory from normal usage
-+one can create child nodes describing particular reserved (excluded from
-+normal use) memory regions. Such memory regions are usually designed for
-+the special usage by various device drivers.
-+
-+Parameters for each memory region can be encoded into the device tree
-+with the following nodes:
-+
-+/reserved-memory node
-+---------------------
-+#address-cells, #size-cells (required) - standard definition
-+ - Should use the same values as the root node
-+ranges (required) - standard definition
-+ - Should be empty
-+
-+/reserved-memory/ child nodes
-+-----------------------------
-+Each child of the reserved-memory node specifies one or more regions of
-+reserved memory. Each child node may either use a 'reg' property to
-+specify a specific range of reserved memory, or a 'size' property with
-+optional constraints to request a dynamically allocated block of memory.
-+
-+Following the generic-names recommended practice, node names should
-+reflect the purpose of the node (ie. "framebuffer" or "dma-pool"). Unit
-+address (@<address>) should be appended to the name if the node is a
-+static allocation.
-+
-+Properties:
-+Requires either a) or b) below.
-+a) static allocation
-+ reg (required) - standard definition
-+b) dynamic allocation
-+ size (required) - length based on parent's #size-cells
-+ - Size in bytes of memory to reserve.
-+ alignment (optional) - length based on parent's #size-cells
-+ - Address boundary for alignment of allocation.
-+ alloc-ranges (optional) - prop-encoded-array (address, length pairs).
-+ - Specifies regions of memory that are
-+ acceptable to allocate from.
-+
-+If both reg and size are present, then the reg property takes precedence
-+and size is ignored.
-+
-+Additional properties:
-+compatible (optional) - standard definition
-+ - may contain the following strings:
-+ - shared-dma-pool: This indicates a region of memory meant to be
-+ used as a shared pool of DMA buffers for a set of devices. It can
-+ be used by an operating system to instanciate the necessary pool
-+ management subsystem if necessary.
-+ - vendor specific string in the form <vendor>,[<device>-]<usage>
-+no-map (optional) - empty property
-+ - Indicates the operating system must not create a virtual mapping
-+ of the region as part of its standard mapping of system memory,
-+ nor permit speculative access to it under any circumstances other
-+ than under the control of the device driver using the region.
-+reusable (optional) - empty property
-+ - The operating system can use the memory in this region with the
-+ limitation that the device driver(s) owning the region need to be
-+ able to reclaim it back. Typically that means that the operating
-+ system can use that region to store volatile or cached data that
-+ can be otherwise regenerated or migrated elsewhere.
-+
-+Linux implementation note:
-+- If a "linux,cma-default" property is present, then Linux will use the
-+ region for the default pool of the contiguous memory allocator.
-+
-+Device node references to reserved memory
-+-----------------------------------------
-+Regions in the /reserved-memory node may be referenced by other device
-+nodes by adding a memory-region property to the device node.
-+
-+memory-region (optional) - phandle, specifier pairs to children of /reserved-memory
-+
-+Example
-+-------
-+This example defines 3 contiguous regions are defined for Linux kernel:
-+one default of all device drivers (named linux,cma@72000000 and 64MiB in size),
-+one dedicated to the framebuffer device (named framebuffer@78000000, 8MiB), and
-+one for multimedia processing (named multimedia-memory@77000000, 64MiB).
-+
-+/ {
-+ #address-cells = <1>;
-+ #size-cells = <1>;
-+
-+ memory {
-+ reg = <0x40000000 0x40000000>;
-+ };
-+
-+ reserved-memory {
-+ #address-cells = <1>;
-+ #size-cells = <1>;
-+ ranges;
-+
-+ /* global autoconfigured region for contiguous allocations */
-+ linux,cma {
-+ compatible = "shared-dma-pool";
-+ reusable;
-+ size = <0x4000000>;
-+ alignment = <0x2000>;
-+ linux,cma-default;
-+ };
-+
-+ display_reserved: framebuffer@78000000 {
-+ reg = <0x78000000 0x800000>;
-+ };
-+
-+ multimedia_reserved: multimedia@77000000 {
-+ compatible = "acme,multimedia-memory";
-+ reg = <0x77000000 0x4000000>;
-+ };
-+ };
-+
-+ /* ... */
-+
-+ fb0: video@12300000 {
-+ memory-region = <&display_reserved>;
-+ /* ... */
-+ };
-+
-+ scaler: scaler@12500000 {
-+ memory-region = <&multimedia_reserved>;
-+ /* ... */
-+ };
-+
-+ codec: codec@12600000 {
-+ memory-region = <&multimedia_reserved>;
-+ /* ... */
-+ };
-+};
diff --git a/target/linux/ipq806x/patches/0054-of-only-scan-for-reserved-mem-when-fdt-present.patch b/target/linux/ipq806x/patches/0054-of-only-scan-for-reserved-mem-when-fdt-present.patch
deleted file mode 100644
index 6efcf38..0000000
--- a/target/linux/ipq806x/patches/0054-of-only-scan-for-reserved-mem-when-fdt-present.patch
+++ /dev/null
@@ -1,30 +0,0 @@
-From 884ab569aec3a0847702dff0dad133bfb67e234c Mon Sep 17 00:00:00 2001
-From: Josh Cartwright <joshc@codeaurora.org>
-Date: Thu, 13 Mar 2014 16:36:36 -0500
-Subject: [PATCH 054/182] of: only scan for reserved mem when fdt present
-
-When the reserved memory patches hit -next, several legacy (non-DT) boot
-failures were detected and bisected down to that commit. There needs to
-be some sanity checking whether a DT is even present before parsing the
-reserved ranges.
-
-Reported-by: Kevin Hilman <khilman@linaro.org>
-Signed-off-by: Josh Cartwright <joshc@codeaurora.org>
-Tested-by: Kevin Hilman <khilman@linaro.org>
-Signed-off-by: Grant Likely <grant.likely@linaro.org>
----
- drivers/of/fdt.c | 3 +++
- 1 file changed, 3 insertions(+)
-
---- a/drivers/of/fdt.c
-+++ b/drivers/of/fdt.c
-@@ -557,6 +557,9 @@ static int __init __fdt_scan_reserved_me
- */
- void __init early_init_fdt_scan_reserved_mem(void)
- {
-+ if (!initial_boot_params)
-+ return;
-+
- of_scan_flat_dt(__fdt_scan_reserved_mem, NULL);
- fdt_init_reserved_mem();
- }
diff --git a/target/linux/ipq806x/patches/0055-spmi-Linux-driver-framework-for-SPMI.patch b/target/linux/ipq806x/patches/0055-spmi-Linux-driver-framework-for-SPMI.patch
deleted file mode 100644
index 80d3b6c..0000000
--- a/target/linux/ipq806x/patches/0055-spmi-Linux-driver-framework-for-SPMI.patch
+++ /dev/null
@@ -1,919 +0,0 @@
-From 1b0018dfd6295cbcc87738601b84bf49f3004419 Mon Sep 17 00:00:00 2001
-From: Kenneth Heitke <kheitke@codeaurora.org>
-Date: Wed, 12 Feb 2014 13:44:22 -0600
-Subject: [PATCH 055/182] spmi: Linux driver framework for SPMI
-
-System Power Management Interface (SPMI) is a specification
-developed by the MIPI (Mobile Industry Process Interface) Alliance
-optimized for the real time control of Power Management ICs (PMIC).
-
-SPMI is a two-wire serial interface that supports up to 4 master
-devices and up to 16 logical slaves.
-
-The framework supports message APIs, multiple busses (1 controller
-per bus) and multiple clients/slave devices per controller.
-
-Signed-off-by: Kenneth Heitke <kheitke@codeaurora.org>
-Signed-off-by: Michael Bohan <mbohan@codeaurora.org>
-Signed-off-by: Josh Cartwright <joshc@codeaurora.org>
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/Kconfig | 2 +
- drivers/Makefile | 1 +
- drivers/spmi/Kconfig | 9 +
- drivers/spmi/Makefile | 4 +
- drivers/spmi/spmi.c | 609 +++++++++++++++++++++++++++++++++++++++
- include/dt-bindings/spmi/spmi.h | 18 ++
- include/linux/mod_devicetable.h | 8 +
- include/linux/spmi.h | 191 ++++++++++++
- 8 files changed, 842 insertions(+)
- create mode 100644 drivers/spmi/Kconfig
- create mode 100644 drivers/spmi/Makefile
- create mode 100644 drivers/spmi/spmi.c
- create mode 100644 include/dt-bindings/spmi/spmi.h
- create mode 100644 include/linux/spmi.h
-
---- a/drivers/Kconfig
-+++ b/drivers/Kconfig
-@@ -52,6 +52,8 @@ source "drivers/i2c/Kconfig"
-
- source "drivers/spi/Kconfig"
-
-+source "drivers/spmi/Kconfig"
-+
- source "drivers/hsi/Kconfig"
-
- source "drivers/pps/Kconfig"
---- a/drivers/Makefile
-+++ b/drivers/Makefile
-@@ -66,6 +66,7 @@ obj-$(CONFIG_ATA) += ata/
- obj-$(CONFIG_TARGET_CORE) += target/
- obj-$(CONFIG_MTD) += mtd/
- obj-$(CONFIG_SPI) += spi/
-+obj-$(CONFIG_SPMI) += spmi/
- obj-y += hsi/
- obj-y += net/
- obj-$(CONFIG_ATM) += atm/
---- /dev/null
-+++ b/drivers/spmi/Kconfig
-@@ -0,0 +1,9 @@
-+#
-+# SPMI driver configuration
-+#
-+menuconfig SPMI
-+ tristate "SPMI support"
-+ help
-+ SPMI (System Power Management Interface) is a two-wire
-+ serial interface between baseband and application processors
-+ and Power Management Integrated Circuits (PMIC).
---- /dev/null
-+++ b/drivers/spmi/Makefile
-@@ -0,0 +1,4 @@
-+#
-+# Makefile for kernel SPMI framework.
-+#
-+obj-$(CONFIG_SPMI) += spmi.o
---- /dev/null
-+++ b/drivers/spmi/spmi.c
-@@ -0,0 +1,609 @@
-+/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 and
-+ * only version 2 as published by the Free Software Foundation.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ * GNU General Public License for more details.
-+ */
-+#include <linux/kernel.h>
-+#include <linux/errno.h>
-+#include <linux/idr.h>
-+#include <linux/slab.h>
-+#include <linux/module.h>
-+#include <linux/of.h>
-+#include <linux/of_device.h>
-+#include <linux/platform_device.h>
-+#include <linux/spmi.h>
-+#include <linux/module.h>
-+#include <linux/pm_runtime.h>
-+
-+#include <dt-bindings/spmi/spmi.h>
-+
-+static DEFINE_IDA(ctrl_ida);
-+
-+static void spmi_dev_release(struct device *dev)
-+{
-+ struct spmi_device *sdev = to_spmi_device(dev);
-+ kfree(sdev);
-+}
-+
-+static const struct device_type spmi_dev_type = {
-+ .release = spmi_dev_release,
-+};
-+
-+static void spmi_ctrl_release(struct device *dev)
-+{
-+ struct spmi_controller *ctrl = to_spmi_controller(dev);
-+ ida_simple_remove(&ctrl_ida, ctrl->nr);
-+ kfree(ctrl);
-+}
-+
-+static const struct device_type spmi_ctrl_type = {
-+ .release = spmi_ctrl_release,
-+};
-+
-+#ifdef CONFIG_PM_RUNTIME
-+static int spmi_runtime_suspend(struct device *dev)
-+{
-+ struct spmi_device *sdev = to_spmi_device(dev);
-+ int err;
-+
-+ err = pm_generic_runtime_suspend(dev);
-+ if (err)
-+ return err;
-+
-+ return spmi_command_sleep(sdev);
-+}
-+
-+static int spmi_runtime_resume(struct device *dev)
-+{
-+ struct spmi_device *sdev = to_spmi_device(dev);
-+ int err;
-+
-+ err = spmi_command_wakeup(sdev);
-+ if (err)
-+ return err;
-+
-+ return pm_generic_runtime_resume(dev);
-+}
-+#endif
-+
-+static const struct dev_pm_ops spmi_pm_ops = {
-+ SET_RUNTIME_PM_OPS(
-+ spmi_runtime_suspend,
-+ spmi_runtime_resume,
-+ NULL
-+ )
-+};
-+
-+static int spmi_device_match(struct device *dev, struct device_driver *drv)
-+{
-+ if (of_driver_match_device(dev, drv))
-+ return 1;
-+
-+ if (drv->name)
-+ return strncmp(dev_name(dev), drv->name,
-+ SPMI_NAME_SIZE) == 0;
-+
-+ return 0;
-+}
-+
-+/**
-+ * spmi_device_add() - add a device previously constructed via spmi_device_alloc()
-+ * @sdev: spmi_device to be added
-+ */
-+int spmi_device_add(struct spmi_device *sdev)
-+{
-+ struct spmi_controller *ctrl = sdev->ctrl;
-+ int err;
-+
-+ dev_set_name(&sdev->dev, "%d-%02x", ctrl->nr, sdev->usid);
-+
-+ err = device_add(&sdev->dev);
-+ if (err < 0) {
-+ dev_err(&sdev->dev, "Can't add %s, status %d\n",
-+ dev_name(&sdev->dev), err);
-+ goto err_device_add;
-+ }
-+
-+ dev_dbg(&sdev->dev, "device %s registered\n", dev_name(&sdev->dev));
-+
-+err_device_add:
-+ return err;
-+}
-+EXPORT_SYMBOL_GPL(spmi_device_add);
-+
-+/**
-+ * spmi_device_remove(): remove an SPMI device
-+ * @sdev: spmi_device to be removed
-+ */
-+void spmi_device_remove(struct spmi_device *sdev)
-+{
-+ device_unregister(&sdev->dev);
-+}
-+EXPORT_SYMBOL_GPL(spmi_device_remove);
-+
-+static inline int
-+spmi_cmd(struct spmi_controller *ctrl, u8 opcode, u8 sid)
-+{
-+ if (!ctrl || !ctrl->cmd || ctrl->dev.type != &spmi_ctrl_type)
-+ return -EINVAL;
-+
-+ return ctrl->cmd(ctrl, opcode, sid);
-+}
-+
-+static inline int spmi_read_cmd(struct spmi_controller *ctrl, u8 opcode,
-+ u8 sid, u16 addr, u8 *buf, size_t len)
-+{
-+ if (!ctrl || !ctrl->read_cmd || ctrl->dev.type != &spmi_ctrl_type)
-+ return -EINVAL;
-+
-+ return ctrl->read_cmd(ctrl, opcode, sid, addr, buf, len);
-+}
-+
-+static inline int spmi_write_cmd(struct spmi_controller *ctrl, u8 opcode,
-+ u8 sid, u16 addr, const u8 *buf, size_t len)
-+{
-+ if (!ctrl || !ctrl->write_cmd || ctrl->dev.type != &spmi_ctrl_type)
-+ return -EINVAL;
-+
-+ return ctrl->write_cmd(ctrl, opcode, sid, addr, buf, len);
-+}
-+
-+/**
-+ * spmi_register_read() - register read
-+ * @sdev: SPMI device.
-+ * @addr: slave register address (5-bit address).
-+ * @buf: buffer to be populated with data from the Slave.
-+ *
-+ * Reads 1 byte of data from a Slave device register.
-+ */
-+int spmi_register_read(struct spmi_device *sdev, u8 addr, u8 *buf)
-+{
-+ /* 5-bit register address */
-+ if (addr > 0x1F)
-+ return -EINVAL;
-+
-+ return spmi_read_cmd(sdev->ctrl, SPMI_CMD_READ, sdev->usid, addr,
-+ buf, 1);
-+}
-+EXPORT_SYMBOL_GPL(spmi_register_read);
-+
-+/**
-+ * spmi_ext_register_read() - extended register read
-+ * @sdev: SPMI device.
-+ * @addr: slave register address (8-bit address).
-+ * @buf: buffer to be populated with data from the Slave.
-+ * @len: the request number of bytes to read (up to 16 bytes).
-+ *
-+ * Reads up to 16 bytes of data from the extended register space on a
-+ * Slave device.
-+ */
-+int spmi_ext_register_read(struct spmi_device *sdev, u8 addr, u8 *buf,
-+ size_t len)
-+{
-+ /* 8-bit register address, up to 16 bytes */
-+ if (len == 0 || len > 16)
-+ return -EINVAL;
-+
-+ return spmi_read_cmd(sdev->ctrl, SPMI_CMD_EXT_READ, sdev->usid, addr,
-+ buf, len);
-+}
-+EXPORT_SYMBOL_GPL(spmi_ext_register_read);
-+
-+/**
-+ * spmi_ext_register_readl() - extended register read long
-+ * @sdev: SPMI device.
-+ * @addr: slave register address (16-bit address).
-+ * @buf: buffer to be populated with data from the Slave.
-+ * @len: the request number of bytes to read (up to 8 bytes).
-+ *
-+ * Reads up to 8 bytes of data from the extended register space on a
-+ * Slave device using 16-bit address.
-+ */
-+int spmi_ext_register_readl(struct spmi_device *sdev, u16 addr, u8 *buf,
-+ size_t len)
-+{
-+ /* 16-bit register address, up to 8 bytes */
-+ if (len == 0 || len > 8)
-+ return -EINVAL;
-+
-+ return spmi_read_cmd(sdev->ctrl, SPMI_CMD_EXT_READL, sdev->usid, addr,
-+ buf, len);
-+}
-+EXPORT_SYMBOL_GPL(spmi_ext_register_readl);
-+
-+/**
-+ * spmi_register_write() - register write
-+ * @sdev: SPMI device
-+ * @addr: slave register address (5-bit address).
-+ * @data: buffer containing the data to be transferred to the Slave.
-+ *
-+ * Writes 1 byte of data to a Slave device register.
-+ */
-+int spmi_register_write(struct spmi_device *sdev, u8 addr, u8 data)
-+{
-+ /* 5-bit register address */
-+ if (addr > 0x1F)
-+ return -EINVAL;
-+
-+ return spmi_write_cmd(sdev->ctrl, SPMI_CMD_WRITE, sdev->usid, addr,
-+ &data, 1);
-+}
-+EXPORT_SYMBOL_GPL(spmi_register_write);
-+
-+/**
-+ * spmi_register_zero_write() - register zero write
-+ * @sdev: SPMI device.
-+ * @data: the data to be written to register 0 (7-bits).
-+ *
-+ * Writes data to register 0 of the Slave device.
-+ */
-+int spmi_register_zero_write(struct spmi_device *sdev, u8 data)
-+{
-+ return spmi_write_cmd(sdev->ctrl, SPMI_CMD_ZERO_WRITE, sdev->usid, 0,
-+ &data, 1);
-+}
-+EXPORT_SYMBOL_GPL(spmi_register_zero_write);
-+
-+/**
-+ * spmi_ext_register_write() - extended register write
-+ * @sdev: SPMI device.
-+ * @addr: slave register address (8-bit address).
-+ * @buf: buffer containing the data to be transferred to the Slave.
-+ * @len: the request number of bytes to read (up to 16 bytes).
-+ *
-+ * Writes up to 16 bytes of data to the extended register space of a
-+ * Slave device.
-+ */
-+int spmi_ext_register_write(struct spmi_device *sdev, u8 addr, const u8 *buf,
-+ size_t len)
-+{
-+ /* 8-bit register address, up to 16 bytes */
-+ if (len == 0 || len > 16)
-+ return -EINVAL;
-+
-+ return spmi_write_cmd(sdev->ctrl, SPMI_CMD_EXT_WRITE, sdev->usid, addr,
-+ buf, len);
-+}
-+EXPORT_SYMBOL_GPL(spmi_ext_register_write);
-+
-+/**
-+ * spmi_ext_register_writel() - extended register write long
-+ * @sdev: SPMI device.
-+ * @addr: slave register address (16-bit address).
-+ * @buf: buffer containing the data to be transferred to the Slave.
-+ * @len: the request number of bytes to read (up to 8 bytes).
-+ *
-+ * Writes up to 8 bytes of data to the extended register space of a
-+ * Slave device using 16-bit address.
-+ */
-+int spmi_ext_register_writel(struct spmi_device *sdev, u16 addr, const u8 *buf,
-+ size_t len)
-+{
-+ /* 4-bit Slave Identifier, 16-bit register address, up to 8 bytes */
-+ if (len == 0 || len > 8)
-+ return -EINVAL;
-+
-+ return spmi_write_cmd(sdev->ctrl, SPMI_CMD_EXT_WRITEL, sdev->usid,
-+ addr, buf, len);
-+}
-+EXPORT_SYMBOL_GPL(spmi_ext_register_writel);
-+
-+/**
-+ * spmi_command_reset() - sends RESET command to the specified slave
-+ * @sdev: SPMI device.
-+ *
-+ * The Reset command initializes the Slave and forces all registers to
-+ * their reset values. The Slave shall enter the STARTUP state after
-+ * receiving a Reset command.
-+ */
-+int spmi_command_reset(struct spmi_device *sdev)
-+{
-+ return spmi_cmd(sdev->ctrl, SPMI_CMD_RESET, sdev->usid);
-+}
-+EXPORT_SYMBOL_GPL(spmi_command_reset);
-+
-+/**
-+ * spmi_command_sleep() - sends SLEEP command to the specified SPMI device
-+ * @sdev: SPMI device.
-+ *
-+ * The Sleep command causes the Slave to enter the user defined SLEEP state.
-+ */
-+int spmi_command_sleep(struct spmi_device *sdev)
-+{
-+ return spmi_cmd(sdev->ctrl, SPMI_CMD_SLEEP, sdev->usid);
-+}
-+EXPORT_SYMBOL_GPL(spmi_command_sleep);
-+
-+/**
-+ * spmi_command_wakeup() - sends WAKEUP command to the specified SPMI device
-+ * @sdev: SPMI device.
-+ *
-+ * The Wakeup command causes the Slave to move from the SLEEP state to
-+ * the ACTIVE state.
-+ */
-+int spmi_command_wakeup(struct spmi_device *sdev)
-+{
-+ return spmi_cmd(sdev->ctrl, SPMI_CMD_WAKEUP, sdev->usid);
-+}
-+EXPORT_SYMBOL_GPL(spmi_command_wakeup);
-+
-+/**
-+ * spmi_command_shutdown() - sends SHUTDOWN command to the specified SPMI device
-+ * @sdev: SPMI device.
-+ *
-+ * The Shutdown command causes the Slave to enter the SHUTDOWN state.
-+ */
-+int spmi_command_shutdown(struct spmi_device *sdev)
-+{
-+ return spmi_cmd(sdev->ctrl, SPMI_CMD_SHUTDOWN, sdev->usid);
-+}
-+EXPORT_SYMBOL_GPL(spmi_command_shutdown);
-+
-+static int spmi_drv_probe(struct device *dev)
-+{
-+ const struct spmi_driver *sdrv = to_spmi_driver(dev->driver);
-+ struct spmi_device *sdev = to_spmi_device(dev);
-+ int err;
-+
-+ /* Ensure the slave is in ACTIVE state */
-+ err = spmi_command_wakeup(sdev);
-+ if (err)
-+ goto fail_wakeup;
-+
-+ pm_runtime_get_noresume(dev);
-+ pm_runtime_set_active(dev);
-+ pm_runtime_enable(dev);
-+
-+ err = sdrv->probe(sdev);
-+ if (err)
-+ goto fail_probe;
-+
-+ return 0;
-+
-+fail_probe:
-+ pm_runtime_disable(dev);
-+ pm_runtime_set_suspended(dev);
-+ pm_runtime_put_noidle(dev);
-+fail_wakeup:
-+ return err;
-+}
-+
-+static int spmi_drv_remove(struct device *dev)
-+{
-+ const struct spmi_driver *sdrv = to_spmi_driver(dev->driver);
-+
-+ pm_runtime_get_sync(dev);
-+ sdrv->remove(to_spmi_device(dev));
-+ pm_runtime_put_noidle(dev);
-+
-+ pm_runtime_disable(dev);
-+ pm_runtime_set_suspended(dev);
-+ pm_runtime_put_noidle(dev);
-+ return 0;
-+}
-+
-+static struct bus_type spmi_bus_type = {
-+ .name = "spmi",
-+ .match = spmi_device_match,
-+ .pm = &spmi_pm_ops,
-+ .probe = spmi_drv_probe,
-+ .remove = spmi_drv_remove,
-+};
-+
-+/**
-+ * spmi_controller_alloc() - Allocate a new SPMI device
-+ * @ctrl: associated controller
-+ *
-+ * Caller is responsible for either calling spmi_device_add() to add the
-+ * newly allocated controller, or calling spmi_device_put() to discard it.
-+ */
-+struct spmi_device *spmi_device_alloc(struct spmi_controller *ctrl)
-+{
-+ struct spmi_device *sdev;
-+
-+ sdev = kzalloc(sizeof(*sdev), GFP_KERNEL);
-+ if (!sdev)
-+ return NULL;
-+
-+ sdev->ctrl = ctrl;
-+ device_initialize(&sdev->dev);
-+ sdev->dev.parent = &ctrl->dev;
-+ sdev->dev.bus = &spmi_bus_type;
-+ sdev->dev.type = &spmi_dev_type;
-+ return sdev;
-+}
-+EXPORT_SYMBOL_GPL(spmi_device_alloc);
-+
-+/**
-+ * spmi_controller_alloc() - Allocate a new SPMI controller
-+ * @parent: parent device
-+ * @size: size of private data
-+ *
-+ * Caller is responsible for either calling spmi_controller_add() to add the
-+ * newly allocated controller, or calling spmi_controller_put() to discard it.
-+ * The allocated private data region may be accessed via
-+ * spmi_controller_get_drvdata()
-+ */
-+struct spmi_controller *spmi_controller_alloc(struct device *parent,
-+ size_t size)
-+{
-+ struct spmi_controller *ctrl;
-+ int id;
-+
-+ if (WARN_ON(!parent))
-+ return NULL;
-+
-+ ctrl = kzalloc(sizeof(*ctrl) + size, GFP_KERNEL);
-+ if (!ctrl)
-+ return NULL;
-+
-+ device_initialize(&ctrl->dev);
-+ ctrl->dev.type = &spmi_ctrl_type;
-+ ctrl->dev.bus = &spmi_bus_type;
-+ ctrl->dev.parent = parent;
-+ ctrl->dev.of_node = parent->of_node;
-+ spmi_controller_set_drvdata(ctrl, &ctrl[1]);
-+
-+ id = ida_simple_get(&ctrl_ida, 0, 0, GFP_KERNEL);
-+ if (id < 0) {
-+ dev_err(parent,
-+ "unable to allocate SPMI controller identifier.\n");
-+ spmi_controller_put(ctrl);
-+ return NULL;
-+ }
-+
-+ ctrl->nr = id;
-+ dev_set_name(&ctrl->dev, "spmi-%d", id);
-+
-+ dev_dbg(&ctrl->dev, "allocated controller 0x%p id %d\n", ctrl, id);
-+ return ctrl;
-+}
-+EXPORT_SYMBOL_GPL(spmi_controller_alloc);
-+
-+static void of_spmi_register_devices(struct spmi_controller *ctrl)
-+{
-+ struct device_node *node;
-+ int err;
-+
-+ if (!ctrl->dev.of_node)
-+ return;
-+
-+ for_each_available_child_of_node(ctrl->dev.of_node, node) {
-+ struct spmi_device *sdev;
-+ u32 reg[2];
-+
-+ dev_dbg(&ctrl->dev, "adding child %s\n", node->full_name);
-+
-+ err = of_property_read_u32_array(node, "reg", reg, 2);
-+ if (err) {
-+ dev_err(&ctrl->dev,
-+ "node %s err (%d) does not have 'reg' property\n",
-+ node->full_name, err);
-+ continue;
-+ }
-+
-+ if (reg[1] != SPMI_USID) {
-+ dev_err(&ctrl->dev,
-+ "node %s contains unsupported 'reg' entry\n",
-+ node->full_name);
-+ continue;
-+ }
-+
-+ if (reg[0] >= SPMI_MAX_SLAVE_ID) {
-+ dev_err(&ctrl->dev,
-+ "invalid usid on node %s\n",
-+ node->full_name);
-+ continue;
-+ }
-+
-+ dev_dbg(&ctrl->dev, "read usid %02x\n", reg[0]);
-+
-+ sdev = spmi_device_alloc(ctrl);
-+ if (!sdev)
-+ continue;
-+
-+ sdev->dev.of_node = node;
-+ sdev->usid = (u8) reg[0];
-+
-+ err = spmi_device_add(sdev);
-+ if (err) {
-+ dev_err(&sdev->dev,
-+ "failure adding device. status %d\n", err);
-+ spmi_device_put(sdev);
-+ }
-+ }
-+}
-+
-+/**
-+ * spmi_controller_add() - Add an SPMI controller
-+ * @ctrl: controller to be registered.
-+ *
-+ * Register a controller previously allocated via spmi_controller_alloc() with
-+ * the SPMI core.
-+ */
-+int spmi_controller_add(struct spmi_controller *ctrl)
-+{
-+ int ret;
-+
-+ /* Can't register until after driver model init */
-+ if (WARN_ON(!spmi_bus_type.p))
-+ return -EAGAIN;
-+
-+ ret = device_add(&ctrl->dev);
-+ if (ret)
-+ return ret;
-+
-+ if (IS_ENABLED(CONFIG_OF))
-+ of_spmi_register_devices(ctrl);
-+
-+ dev_dbg(&ctrl->dev, "spmi-%d registered: dev:%p\n",
-+ ctrl->nr, &ctrl->dev);
-+
-+ return 0;
-+};
-+EXPORT_SYMBOL_GPL(spmi_controller_add);
-+
-+/* Remove a device associated with a controller */
-+static int spmi_ctrl_remove_device(struct device *dev, void *data)
-+{
-+ struct spmi_device *spmidev = to_spmi_device(dev);
-+ if (dev->type == &spmi_dev_type)
-+ spmi_device_remove(spmidev);
-+ return 0;
-+}
-+
-+/**
-+ * spmi_controller_remove(): remove an SPMI controller
-+ * @ctrl: controller to remove
-+ *
-+ * Remove a SPMI controller. Caller is responsible for calling
-+ * spmi_controller_put() to discard the allocated controller.
-+ */
-+void spmi_controller_remove(struct spmi_controller *ctrl)
-+{
-+ int dummy;
-+
-+ if (!ctrl)
-+ return;
-+
-+ dummy = device_for_each_child(&ctrl->dev, NULL,
-+ spmi_ctrl_remove_device);
-+ device_del(&ctrl->dev);
-+}
-+EXPORT_SYMBOL_GPL(spmi_controller_remove);
-+
-+/**
-+ * spmi_driver_register() - Register client driver with SPMI core
-+ * @sdrv: client driver to be associated with client-device.
-+ *
-+ * This API will register the client driver with the SPMI framework.
-+ * It is typically called from the driver's module-init function.
-+ */
-+int spmi_driver_register(struct spmi_driver *sdrv)
-+{
-+ sdrv->driver.bus = &spmi_bus_type;
-+ return driver_register(&sdrv->driver);
-+}
-+EXPORT_SYMBOL_GPL(spmi_driver_register);
-+
-+static void __exit spmi_exit(void)
-+{
-+ bus_unregister(&spmi_bus_type);
-+}
-+module_exit(spmi_exit);
-+
-+static int __init spmi_init(void)
-+{
-+ return bus_register(&spmi_bus_type);
-+}
-+postcore_initcall(spmi_init);
-+
-+MODULE_LICENSE("GPL v2");
-+MODULE_DESCRIPTION("SPMI module");
-+MODULE_ALIAS("platform:spmi");
---- /dev/null
-+++ b/include/dt-bindings/spmi/spmi.h
-@@ -0,0 +1,18 @@
-+/* Copyright (c) 2013, The Linux Foundation. All rights reserved.
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 and
-+ * only version 2 as published by the Free Software Foundation.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ * GNU General Public License for more details.
-+ */
-+#ifndef __DT_BINDINGS_SPMI_H
-+#define __DT_BINDINGS_SPMI_H
-+
-+#define SPMI_USID 0
-+#define SPMI_GSID 1
-+
-+#endif
---- a/include/linux/mod_devicetable.h
-+++ b/include/linux/mod_devicetable.h
-@@ -432,6 +432,14 @@ struct spi_device_id {
- kernel_ulong_t driver_data; /* Data private to the driver */
- };
-
-+#define SPMI_NAME_SIZE 32
-+#define SPMI_MODULE_PREFIX "spmi:"
-+
-+struct spmi_device_id {
-+ char name[SPMI_NAME_SIZE];
-+ kernel_ulong_t driver_data; /* Data private to the driver */
-+};
-+
- /* dmi */
- enum dmi_field {
- DMI_NONE,
---- /dev/null
-+++ b/include/linux/spmi.h
-@@ -0,0 +1,191 @@
-+/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 and
-+ * only version 2 as published by the Free Software Foundation.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ * GNU General Public License for more details.
-+ */
-+#ifndef _LINUX_SPMI_H
-+#define _LINUX_SPMI_H
-+
-+#include <linux/types.h>
-+#include <linux/device.h>
-+#include <linux/mod_devicetable.h>
-+
-+/* Maximum slave identifier */
-+#define SPMI_MAX_SLAVE_ID 16
-+
-+/* SPMI Commands */
-+#define SPMI_CMD_EXT_WRITE 0x00
-+#define SPMI_CMD_RESET 0x10
-+#define SPMI_CMD_SLEEP 0x11
-+#define SPMI_CMD_SHUTDOWN 0x12
-+#define SPMI_CMD_WAKEUP 0x13
-+#define SPMI_CMD_AUTHENTICATE 0x14
-+#define SPMI_CMD_MSTR_READ 0x15
-+#define SPMI_CMD_MSTR_WRITE 0x16
-+#define SPMI_CMD_TRANSFER_BUS_OWNERSHIP 0x1A
-+#define SPMI_CMD_DDB_MASTER_READ 0x1B
-+#define SPMI_CMD_DDB_SLAVE_READ 0x1C
-+#define SPMI_CMD_EXT_READ 0x20
-+#define SPMI_CMD_EXT_WRITEL 0x30
-+#define SPMI_CMD_EXT_READL 0x38
-+#define SPMI_CMD_WRITE 0x40
-+#define SPMI_CMD_READ 0x60
-+#define SPMI_CMD_ZERO_WRITE 0x80
-+
-+/**
-+ * struct spmi_device - Basic representation of an SPMI device
-+ * @dev: Driver model representation of the device.
-+ * @ctrl: SPMI controller managing the bus hosting this device.
-+ * @usid: This devices' Unique Slave IDentifier.
-+ */
-+struct spmi_device {
-+ struct device dev;
-+ struct spmi_controller *ctrl;
-+ u8 usid;
-+};
-+
-+static inline struct spmi_device *to_spmi_device(struct device *d)
-+{
-+ return container_of(d, struct spmi_device, dev);
-+}
-+
-+static inline void *spmi_device_get_drvdata(const struct spmi_device *sdev)
-+{
-+ return dev_get_drvdata(&sdev->dev);
-+}
-+
-+static inline void spmi_device_set_drvdata(struct spmi_device *sdev, void *data)
-+{
-+ dev_set_drvdata(&sdev->dev, data);
-+}
-+
-+struct spmi_device *spmi_device_alloc(struct spmi_controller *ctrl);
-+
-+static inline void spmi_device_put(struct spmi_device *sdev)
-+{
-+ if (sdev)
-+ put_device(&sdev->dev);
-+}
-+
-+int spmi_device_add(struct spmi_device *sdev);
-+
-+void spmi_device_remove(struct spmi_device *sdev);
-+
-+/**
-+ * struct spmi_controller - interface to the SPMI master controller
-+ * @dev: Driver model representation of the device.
-+ * @nr: board-specific number identifier for this controller/bus
-+ * @cmd: sends a non-data command sequence on the SPMI bus.
-+ * @read_cmd: sends a register read command sequence on the SPMI bus.
-+ * @write_cmd: sends a register write command sequence on the SPMI bus.
-+ */
-+struct spmi_controller {
-+ struct device dev;
-+ unsigned int nr;
-+ int (*cmd)(struct spmi_controller *ctrl, u8 opcode, u8 sid);
-+ int (*read_cmd)(struct spmi_controller *ctrl, u8 opcode,
-+ u8 sid, u16 addr, u8 *buf, size_t len);
-+ int (*write_cmd)(struct spmi_controller *ctrl, u8 opcode,
-+ u8 sid, u16 addr, const u8 *buf, size_t len);
-+};
-+
-+static inline struct spmi_controller *to_spmi_controller(struct device *d)
-+{
-+ return container_of(d, struct spmi_controller, dev);
-+}
-+
-+static inline
-+void *spmi_controller_get_drvdata(const struct spmi_controller *ctrl)
-+{
-+ return dev_get_drvdata(&ctrl->dev);
-+}
-+
-+static inline void spmi_controller_set_drvdata(struct spmi_controller *ctrl,
-+ void *data)
-+{
-+ dev_set_drvdata(&ctrl->dev, data);
-+}
-+
-+struct spmi_controller *spmi_controller_alloc(struct device *parent,
-+ size_t size);
-+
-+/**
-+ * spmi_controller_put() - decrement controller refcount
-+ * @ctrl SPMI controller.
-+ */
-+static inline void spmi_controller_put(struct spmi_controller *ctrl)
-+{
-+ if (ctrl)
-+ put_device(&ctrl->dev);
-+}
-+
-+int spmi_controller_add(struct spmi_controller *ctrl);
-+void spmi_controller_remove(struct spmi_controller *ctrl);
-+
-+/**
-+ * struct spmi_driver - SPMI slave device driver
-+ * @driver: SPMI device drivers should initialize name and owner field of
-+ * this structure.
-+ * @probe: binds this driver to a SPMI device.
-+ * @remove: unbinds this driver from the SPMI device.
-+ * @shutdown: standard shutdown callback used during powerdown/halt.
-+ * @suspend: standard suspend callback used during system suspend.
-+ * @resume: standard resume callback used during system resume.
-+ *
-+ * If PM runtime support is desired for a slave, a device driver can call
-+ * pm_runtime_put() from their probe() routine (and a balancing
-+ * pm_runtime_get() in remove()). PM runtime support for a slave is
-+ * implemented by issuing a SLEEP command to the slave on runtime_suspend(),
-+ * transitioning the slave into the SLEEP state. On runtime_resume(), a WAKEUP
-+ * command is sent to the slave to bring it back to ACTIVE.
-+ */
-+struct spmi_driver {
-+ struct device_driver driver;
-+ int (*probe)(struct spmi_device *sdev);
-+ void (*remove)(struct spmi_device *sdev);
-+};
-+
-+static inline struct spmi_driver *to_spmi_driver(struct device_driver *d)
-+{
-+ return container_of(d, struct spmi_driver, driver);
-+}
-+
-+int spmi_driver_register(struct spmi_driver *sdrv);
-+
-+/**
-+ * spmi_driver_unregister() - unregister an SPMI client driver
-+ * @sdrv: the driver to unregister
-+ */
-+static inline void spmi_driver_unregister(struct spmi_driver *sdrv)
-+{
-+ if (sdrv)
-+ driver_unregister(&sdrv->driver);
-+}
-+
-+#define module_spmi_driver(__spmi_driver) \
-+ module_driver(__spmi_driver, spmi_driver_register, \
-+ spmi_driver_unregister)
-+
-+int spmi_register_read(struct spmi_device *sdev, u8 addr, u8 *buf);
-+int spmi_ext_register_read(struct spmi_device *sdev, u8 addr, u8 *buf,
-+ size_t len);
-+int spmi_ext_register_readl(struct spmi_device *sdev, u16 addr, u8 *buf,
-+ size_t len);
-+int spmi_register_write(struct spmi_device *sdev, u8 addr, u8 data);
-+int spmi_register_zero_write(struct spmi_device *sdev, u8 data);
-+int spmi_ext_register_write(struct spmi_device *sdev, u8 addr,
-+ const u8 *buf, size_t len);
-+int spmi_ext_register_writel(struct spmi_device *sdev, u16 addr,
-+ const u8 *buf, size_t len);
-+int spmi_command_reset(struct spmi_device *sdev);
-+int spmi_command_sleep(struct spmi_device *sdev);
-+int spmi_command_wakeup(struct spmi_device *sdev);
-+int spmi_command_shutdown(struct spmi_device *sdev);
-+
-+#endif
diff --git a/target/linux/ipq806x/patches/0056-spmi-Add-MSM-PMIC-Arbiter-SPMI-controller.patch b/target/linux/ipq806x/patches/0056-spmi-Add-MSM-PMIC-Arbiter-SPMI-controller.patch
deleted file mode 100644
index e2fde2d..0000000
--- a/target/linux/ipq806x/patches/0056-spmi-Add-MSM-PMIC-Arbiter-SPMI-controller.patch
+++ /dev/null
@@ -1,467 +0,0 @@
-From 1e1f53fbc2848b23af572c16d19e8004f6a7c9c1 Mon Sep 17 00:00:00 2001
-From: Kenneth Heitke <kheitke@codeaurora.org>
-Date: Wed, 12 Feb 2014 13:44:24 -0600
-Subject: [PATCH 056/182] spmi: Add MSM PMIC Arbiter SPMI controller
-
-Qualcomm's PMIC Arbiter SPMI controller functions as a bus master and
-is used to communication with one or more PMIC (slave) devices on the
-SPMI bus. The PMIC Arbiter is actually a hardware wrapper around the
-SPMI controller that provides concurrent and autonomous PMIC access
-to various entities that need to communicate with the PMIC.
-
-The SPMI controller hardware handles all of the SPMI bus activity (bus
-arbitration, sequence start condition, transmission of frames, etc).
-This software driver uses the PMIC Arbiter register interface to
-initiate command sequences on the SPMI bus. The status register is
-read to determine when the command sequence has completed and whether
-or not it completed successfully.
-
-Signed-off-by: Kenneth Heitke <kheitke@codeaurora.org>
-Signed-off-by: Josh Cartwright <joshc@codeaurora.org>
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/spmi/Kconfig | 17 ++
- drivers/spmi/Makefile | 2 +
- drivers/spmi/spmi-pmic-arb.c | 405 ++++++++++++++++++++++++++++++++++++++++++
- 3 files changed, 424 insertions(+)
- create mode 100644 drivers/spmi/spmi-pmic-arb.c
-
---- a/drivers/spmi/Kconfig
-+++ b/drivers/spmi/Kconfig
-@@ -7,3 +7,20 @@ menuconfig SPMI
- SPMI (System Power Management Interface) is a two-wire
- serial interface between baseband and application processors
- and Power Management Integrated Circuits (PMIC).
-+
-+if SPMI
-+
-+config SPMI_MSM_PMIC_ARB
-+ tristate "Qualcomm MSM SPMI Controller (PMIC Arbiter)"
-+ depends on ARM
-+ depends on ARCH_MSM || COMPILE_TEST
-+ default ARCH_MSM
-+ help
-+ If you say yes to this option, support will be included for the
-+ built-in SPMI PMIC Arbiter interface on Qualcomm MSM family
-+ processors.
-+
-+ This is required for communicating with Qualcomm PMICs and
-+ other devices that have the SPMI interface.
-+
-+endif
---- a/drivers/spmi/Makefile
-+++ b/drivers/spmi/Makefile
-@@ -2,3 +2,5 @@
- # Makefile for kernel SPMI framework.
- #
- obj-$(CONFIG_SPMI) += spmi.o
-+
-+obj-$(CONFIG_SPMI_MSM_PMIC_ARB) += spmi-pmic-arb.o
---- /dev/null
-+++ b/drivers/spmi/spmi-pmic-arb.c
-@@ -0,0 +1,405 @@
-+/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 and
-+ * only version 2 as published by the Free Software Foundation.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ * GNU General Public License for more details.
-+ */
-+#include <linux/delay.h>
-+#include <linux/err.h>
-+#include <linux/interrupt.h>
-+#include <linux/io.h>
-+#include <linux/kernel.h>
-+#include <linux/module.h>
-+#include <linux/of.h>
-+#include <linux/platform_device.h>
-+#include <linux/slab.h>
-+#include <linux/spmi.h>
-+
-+/* PMIC Arbiter configuration registers */
-+#define PMIC_ARB_VERSION 0x0000
-+#define PMIC_ARB_INT_EN 0x0004
-+
-+/* PMIC Arbiter channel registers */
-+#define PMIC_ARB_CMD(N) (0x0800 + (0x80 * (N)))
-+#define PMIC_ARB_CONFIG(N) (0x0804 + (0x80 * (N)))
-+#define PMIC_ARB_STATUS(N) (0x0808 + (0x80 * (N)))
-+#define PMIC_ARB_WDATA0(N) (0x0810 + (0x80 * (N)))
-+#define PMIC_ARB_WDATA1(N) (0x0814 + (0x80 * (N)))
-+#define PMIC_ARB_RDATA0(N) (0x0818 + (0x80 * (N)))
-+#define PMIC_ARB_RDATA1(N) (0x081C + (0x80 * (N)))
-+
-+/* Interrupt Controller */
-+#define SPMI_PIC_OWNER_ACC_STATUS(M, N) (0x0000 + ((32 * (M)) + (4 * (N))))
-+#define SPMI_PIC_ACC_ENABLE(N) (0x0200 + (4 * (N)))
-+#define SPMI_PIC_IRQ_STATUS(N) (0x0600 + (4 * (N)))
-+#define SPMI_PIC_IRQ_CLEAR(N) (0x0A00 + (4 * (N)))
-+
-+/* Mapping Table */
-+#define SPMI_MAPPING_TABLE_REG(N) (0x0B00 + (4 * (N)))
-+#define SPMI_MAPPING_BIT_INDEX(X) (((X) >> 18) & 0xF)
-+#define SPMI_MAPPING_BIT_IS_0_FLAG(X) (((X) >> 17) & 0x1)
-+#define SPMI_MAPPING_BIT_IS_0_RESULT(X) (((X) >> 9) & 0xFF)
-+#define SPMI_MAPPING_BIT_IS_1_FLAG(X) (((X) >> 8) & 0x1)
-+#define SPMI_MAPPING_BIT_IS_1_RESULT(X) (((X) >> 0) & 0xFF)
-+
-+#define SPMI_MAPPING_TABLE_LEN 255
-+#define SPMI_MAPPING_TABLE_TREE_DEPTH 16 /* Maximum of 16-bits */
-+
-+/* Ownership Table */
-+#define SPMI_OWNERSHIP_TABLE_REG(N) (0x0700 + (4 * (N)))
-+#define SPMI_OWNERSHIP_PERIPH2OWNER(X) ((X) & 0x7)
-+
-+/* Channel Status fields */
-+enum pmic_arb_chnl_status {
-+ PMIC_ARB_STATUS_DONE = (1 << 0),
-+ PMIC_ARB_STATUS_FAILURE = (1 << 1),
-+ PMIC_ARB_STATUS_DENIED = (1 << 2),
-+ PMIC_ARB_STATUS_DROPPED = (1 << 3),
-+};
-+
-+/* Command register fields */
-+#define PMIC_ARB_CMD_MAX_BYTE_COUNT 8
-+
-+/* Command Opcodes */
-+enum pmic_arb_cmd_op_code {
-+ PMIC_ARB_OP_EXT_WRITEL = 0,
-+ PMIC_ARB_OP_EXT_READL = 1,
-+ PMIC_ARB_OP_EXT_WRITE = 2,
-+ PMIC_ARB_OP_RESET = 3,
-+ PMIC_ARB_OP_SLEEP = 4,
-+ PMIC_ARB_OP_SHUTDOWN = 5,
-+ PMIC_ARB_OP_WAKEUP = 6,
-+ PMIC_ARB_OP_AUTHENTICATE = 7,
-+ PMIC_ARB_OP_MSTR_READ = 8,
-+ PMIC_ARB_OP_MSTR_WRITE = 9,
-+ PMIC_ARB_OP_EXT_READ = 13,
-+ PMIC_ARB_OP_WRITE = 14,
-+ PMIC_ARB_OP_READ = 15,
-+ PMIC_ARB_OP_ZERO_WRITE = 16,
-+};
-+
-+/* Maximum number of support PMIC peripherals */
-+#define PMIC_ARB_MAX_PERIPHS 256
-+#define PMIC_ARB_PERIPH_ID_VALID (1 << 15)
-+#define PMIC_ARB_TIMEOUT_US 100
-+#define PMIC_ARB_MAX_TRANS_BYTES (8)
-+
-+#define PMIC_ARB_APID_MASK 0xFF
-+#define PMIC_ARB_PPID_MASK 0xFFF
-+
-+/* interrupt enable bit */
-+#define SPMI_PIC_ACC_ENABLE_BIT BIT(0)
-+
-+/**
-+ * spmi_pmic_arb_dev - SPMI PMIC Arbiter object
-+ *
-+ * @base: address of the PMIC Arbiter core registers.
-+ * @intr: address of the SPMI interrupt control registers.
-+ * @cnfg: address of the PMIC Arbiter configuration registers.
-+ * @lock: lock to synchronize accesses.
-+ * @channel: which channel to use for accesses.
-+ */
-+struct spmi_pmic_arb_dev {
-+ void __iomem *base;
-+ void __iomem *intr;
-+ void __iomem *cnfg;
-+ raw_spinlock_t lock;
-+ u8 channel;
-+};
-+
-+static inline u32 pmic_arb_base_read(struct spmi_pmic_arb_dev *dev, u32 offset)
-+{
-+ return readl_relaxed(dev->base + offset);
-+}
-+
-+static inline void pmic_arb_base_write(struct spmi_pmic_arb_dev *dev,
-+ u32 offset, u32 val)
-+{
-+ writel_relaxed(val, dev->base + offset);
-+}
-+
-+/**
-+ * pa_read_data: reads pmic-arb's register and copy 1..4 bytes to buf
-+ * @bc: byte count -1. range: 0..3
-+ * @reg: register's address
-+ * @buf: output parameter, length must be bc + 1
-+ */
-+static void pa_read_data(struct spmi_pmic_arb_dev *dev, u8 *buf, u32 reg, u8 bc)
-+{
-+ u32 data = pmic_arb_base_read(dev, reg);
-+ memcpy(buf, &data, (bc & 3) + 1);
-+}
-+
-+/**
-+ * pa_write_data: write 1..4 bytes from buf to pmic-arb's register
-+ * @bc: byte-count -1. range: 0..3.
-+ * @reg: register's address.
-+ * @buf: buffer to write. length must be bc + 1.
-+ */
-+static void
-+pa_write_data(struct spmi_pmic_arb_dev *dev, const u8 *buf, u32 reg, u8 bc)
-+{
-+ u32 data = 0;
-+ memcpy(&data, buf, (bc & 3) + 1);
-+ pmic_arb_base_write(dev, reg, data);
-+}
-+
-+static int pmic_arb_wait_for_done(struct spmi_controller *ctrl)
-+{
-+ struct spmi_pmic_arb_dev *dev = spmi_controller_get_drvdata(ctrl);
-+ u32 status = 0;
-+ u32 timeout = PMIC_ARB_TIMEOUT_US;
-+ u32 offset = PMIC_ARB_STATUS(dev->channel);
-+
-+ while (timeout--) {
-+ status = pmic_arb_base_read(dev, offset);
-+
-+ if (status & PMIC_ARB_STATUS_DONE) {
-+ if (status & PMIC_ARB_STATUS_DENIED) {
-+ dev_err(&ctrl->dev,
-+ "%s: transaction denied (0x%x)\n",
-+ __func__, status);
-+ return -EPERM;
-+ }
-+
-+ if (status & PMIC_ARB_STATUS_FAILURE) {
-+ dev_err(&ctrl->dev,
-+ "%s: transaction failed (0x%x)\n",
-+ __func__, status);
-+ return -EIO;
-+ }
-+
-+ if (status & PMIC_ARB_STATUS_DROPPED) {
-+ dev_err(&ctrl->dev,
-+ "%s: transaction dropped (0x%x)\n",
-+ __func__, status);
-+ return -EIO;
-+ }
-+
-+ return 0;
-+ }
-+ udelay(1);
-+ }
-+
-+ dev_err(&ctrl->dev,
-+ "%s: timeout, status 0x%x\n",
-+ __func__, status);
-+ return -ETIMEDOUT;
-+}
-+
-+/* Non-data command */
-+static int pmic_arb_cmd(struct spmi_controller *ctrl, u8 opc, u8 sid)
-+{
-+ struct spmi_pmic_arb_dev *pmic_arb = spmi_controller_get_drvdata(ctrl);
-+ unsigned long flags;
-+ u32 cmd;
-+ int rc;
-+
-+ /* Check for valid non-data command */
-+ if (opc < SPMI_CMD_RESET || opc > SPMI_CMD_WAKEUP)
-+ return -EINVAL;
-+
-+ cmd = ((opc | 0x40) << 27) | ((sid & 0xf) << 20);
-+
-+ raw_spin_lock_irqsave(&pmic_arb->lock, flags);
-+ pmic_arb_base_write(pmic_arb, PMIC_ARB_CMD(pmic_arb->channel), cmd);
-+ rc = pmic_arb_wait_for_done(ctrl);
-+ raw_spin_unlock_irqrestore(&pmic_arb->lock, flags);
-+
-+ return rc;
-+}
-+
-+static int pmic_arb_read_cmd(struct spmi_controller *ctrl, u8 opc, u8 sid,
-+ u16 addr, u8 *buf, size_t len)
-+{
-+ struct spmi_pmic_arb_dev *pmic_arb = spmi_controller_get_drvdata(ctrl);
-+ unsigned long flags;
-+ u8 bc = len - 1;
-+ u32 cmd;
-+ int rc;
-+
-+ if (bc >= PMIC_ARB_MAX_TRANS_BYTES) {
-+ dev_err(&ctrl->dev,
-+ "pmic-arb supports 1..%d bytes per trans, but %d requested",
-+ PMIC_ARB_MAX_TRANS_BYTES, len);
-+ return -EINVAL;
-+ }
-+
-+ /* Check the opcode */
-+ if (opc >= 0x60 && opc <= 0x7F)
-+ opc = PMIC_ARB_OP_READ;
-+ else if (opc >= 0x20 && opc <= 0x2F)
-+ opc = PMIC_ARB_OP_EXT_READ;
-+ else if (opc >= 0x38 && opc <= 0x3F)
-+ opc = PMIC_ARB_OP_EXT_READL;
-+ else
-+ return -EINVAL;
-+
-+ cmd = (opc << 27) | ((sid & 0xf) << 20) | (addr << 4) | (bc & 0x7);
-+
-+ raw_spin_lock_irqsave(&pmic_arb->lock, flags);
-+ pmic_arb_base_write(pmic_arb, PMIC_ARB_CMD(pmic_arb->channel), cmd);
-+ rc = pmic_arb_wait_for_done(ctrl);
-+ if (rc)
-+ goto done;
-+
-+ pa_read_data(pmic_arb, buf, PMIC_ARB_RDATA0(pmic_arb->channel),
-+ min_t(u8, bc, 3));
-+
-+ if (bc > 3)
-+ pa_read_data(pmic_arb, buf + 4,
-+ PMIC_ARB_RDATA1(pmic_arb->channel), bc - 4);
-+
-+done:
-+ raw_spin_unlock_irqrestore(&pmic_arb->lock, flags);
-+ return rc;
-+}
-+
-+static int pmic_arb_write_cmd(struct spmi_controller *ctrl, u8 opc, u8 sid,
-+ u16 addr, const u8 *buf, size_t len)
-+{
-+ struct spmi_pmic_arb_dev *pmic_arb = spmi_controller_get_drvdata(ctrl);
-+ unsigned long flags;
-+ u8 bc = len - 1;
-+ u32 cmd;
-+ int rc;
-+
-+ if (bc >= PMIC_ARB_MAX_TRANS_BYTES) {
-+ dev_err(&ctrl->dev,
-+ "pmic-arb supports 1..%d bytes per trans, but:%d requested",
-+ PMIC_ARB_MAX_TRANS_BYTES, len);
-+ return -EINVAL;
-+ }
-+
-+ /* Check the opcode */
-+ if (opc >= 0x40 && opc <= 0x5F)
-+ opc = PMIC_ARB_OP_WRITE;
-+ else if (opc >= 0x00 && opc <= 0x0F)
-+ opc = PMIC_ARB_OP_EXT_WRITE;
-+ else if (opc >= 0x30 && opc <= 0x37)
-+ opc = PMIC_ARB_OP_EXT_WRITEL;
-+ else if (opc >= 0x80 && opc <= 0xFF)
-+ opc = PMIC_ARB_OP_ZERO_WRITE;
-+ else
-+ return -EINVAL;
-+
-+ cmd = (opc << 27) | ((sid & 0xf) << 20) | (addr << 4) | (bc & 0x7);
-+
-+ /* Write data to FIFOs */
-+ raw_spin_lock_irqsave(&pmic_arb->lock, flags);
-+ pa_write_data(pmic_arb, buf, PMIC_ARB_WDATA0(pmic_arb->channel)
-+ , min_t(u8, bc, 3));
-+ if (bc > 3)
-+ pa_write_data(pmic_arb, buf + 4,
-+ PMIC_ARB_WDATA1(pmic_arb->channel), bc - 4);
-+
-+ /* Start the transaction */
-+ pmic_arb_base_write(pmic_arb, PMIC_ARB_CMD(pmic_arb->channel), cmd);
-+ rc = pmic_arb_wait_for_done(ctrl);
-+ raw_spin_unlock_irqrestore(&pmic_arb->lock, flags);
-+
-+ return rc;
-+}
-+
-+static int spmi_pmic_arb_probe(struct platform_device *pdev)
-+{
-+ struct spmi_pmic_arb_dev *pa;
-+ struct spmi_controller *ctrl;
-+ struct resource *res;
-+ u32 channel;
-+ int err, i;
-+
-+ ctrl = spmi_controller_alloc(&pdev->dev, sizeof(*pa));
-+ if (!ctrl)
-+ return -ENOMEM;
-+
-+ pa = spmi_controller_get_drvdata(ctrl);
-+
-+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "core");
-+ pa->base = devm_ioremap_resource(&ctrl->dev, res);
-+ if (IS_ERR(pa->base)) {
-+ err = PTR_ERR(pa->base);
-+ goto err_put_ctrl;
-+ }
-+
-+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "intr");
-+ pa->intr = devm_ioremap_resource(&ctrl->dev, res);
-+ if (IS_ERR(pa->intr)) {
-+ err = PTR_ERR(pa->intr);
-+ goto err_put_ctrl;
-+ }
-+
-+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "cnfg");
-+ pa->cnfg = devm_ioremap_resource(&ctrl->dev, res);
-+ if (IS_ERR(pa->cnfg)) {
-+ err = PTR_ERR(pa->cnfg);
-+ goto err_put_ctrl;
-+ }
-+
-+ err = of_property_read_u32(pdev->dev.of_node, "qcom,channel", &channel);
-+ if (err) {
-+ dev_err(&pdev->dev, "channel unspecified.\n");
-+ goto err_put_ctrl;
-+ }
-+
-+ if (channel > 5) {
-+ dev_err(&pdev->dev, "invalid channel (%u) specified.\n",
-+ channel);
-+ goto err_put_ctrl;
-+ }
-+
-+ pa->channel = channel;
-+
-+ platform_set_drvdata(pdev, ctrl);
-+ raw_spin_lock_init(&pa->lock);
-+
-+ ctrl->cmd = pmic_arb_cmd;
-+ ctrl->read_cmd = pmic_arb_read_cmd;
-+ ctrl->write_cmd = pmic_arb_write_cmd;
-+
-+ err = spmi_controller_add(ctrl);
-+ if (err)
-+ goto err_put_ctrl;
-+
-+ dev_dbg(&ctrl->dev, "PMIC Arb Version 0x%x\n",
-+ pmic_arb_base_read(pa, PMIC_ARB_VERSION));
-+
-+ return 0;
-+
-+err_put_ctrl:
-+ spmi_controller_put(ctrl);
-+ return err;
-+}
-+
-+static int spmi_pmic_arb_remove(struct platform_device *pdev)
-+{
-+ struct spmi_controller *ctrl = platform_get_drvdata(pdev);
-+ spmi_controller_remove(ctrl);
-+ spmi_controller_put(ctrl);
-+ return 0;
-+}
-+
-+static const struct of_device_id spmi_pmic_arb_match_table[] = {
-+ { .compatible = "qcom,spmi-pmic-arb", },
-+ {},
-+};
-+MODULE_DEVICE_TABLE(of, spmi_pmic_arb_match_table);
-+
-+static struct platform_driver spmi_pmic_arb_driver = {
-+ .probe = spmi_pmic_arb_probe,
-+ .remove = spmi_pmic_arb_remove,
-+ .driver = {
-+ .name = "spmi_pmic_arb",
-+ .owner = THIS_MODULE,
-+ .of_match_table = spmi_pmic_arb_match_table,
-+ },
-+};
-+module_platform_driver(spmi_pmic_arb_driver);
-+
-+MODULE_LICENSE("GPL v2");
-+MODULE_ALIAS("platform:spmi_pmic_arb");
diff --git a/target/linux/ipq806x/patches/0057-spmi-pmic_arb-add-support-for-interrupt-handling.patch b/target/linux/ipq806x/patches/0057-spmi-pmic_arb-add-support-for-interrupt-handling.patch
deleted file mode 100644
index b1420b4..0000000
--- a/target/linux/ipq806x/patches/0057-spmi-pmic_arb-add-support-for-interrupt-handling.patch
+++ /dev/null
@@ -1,487 +0,0 @@
-From b5bc51d44485c7ce0ca180a8c5de11a206f686e8 Mon Sep 17 00:00:00 2001
-From: Josh Cartwright <joshc@codeaurora.org>
-Date: Wed, 12 Feb 2014 13:44:25 -0600
-Subject: [PATCH 057/182] spmi: pmic_arb: add support for interrupt handling
-
-The Qualcomm PMIC Arbiter, in addition to being a basic SPMI controller,
-also implements interrupt handling for slave devices. Note, this is
-outside the scope of SPMI, as SPMI leaves interrupt handling completely
-unspecified.
-
-Extend the driver to provide a irq_chip implementation and chained irq
-handling which allows for these interrupts to be used.
-
-Cc: Thomas Gleixner <tglx@linutronix.de>
-Signed-off-by: Josh Cartwright <joshc@codeaurora.org>
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/spmi/Kconfig | 1 +
- drivers/spmi/spmi-pmic-arb.c | 377 +++++++++++++++++++++++++++++++++++++++++-
- 2 files changed, 376 insertions(+), 2 deletions(-)
-
---- a/drivers/spmi/Kconfig
-+++ b/drivers/spmi/Kconfig
-@@ -13,6 +13,7 @@ if SPMI
- config SPMI_MSM_PMIC_ARB
- tristate "Qualcomm MSM SPMI Controller (PMIC Arbiter)"
- depends on ARM
-+ depends on IRQ_DOMAIN
- depends on ARCH_MSM || COMPILE_TEST
- default ARCH_MSM
- help
---- a/drivers/spmi/spmi-pmic-arb.c
-+++ b/drivers/spmi/spmi-pmic-arb.c
-@@ -13,6 +13,9 @@
- #include <linux/err.h>
- #include <linux/interrupt.h>
- #include <linux/io.h>
-+#include <linux/irqchip/chained_irq.h>
-+#include <linux/irqdomain.h>
-+#include <linux/irq.h>
- #include <linux/kernel.h>
- #include <linux/module.h>
- #include <linux/of.h>
-@@ -103,6 +106,14 @@ enum pmic_arb_cmd_op_code {
- * @cnfg: address of the PMIC Arbiter configuration registers.
- * @lock: lock to synchronize accesses.
- * @channel: which channel to use for accesses.
-+ * @irq: PMIC ARB interrupt.
-+ * @ee: the current Execution Environment
-+ * @min_apid: minimum APID (used for bounding IRQ search)
-+ * @max_apid: maximum APID
-+ * @mapping_table: in-memory copy of PPID -> APID mapping table.
-+ * @domain: irq domain object for PMIC IRQ domain
-+ * @spmic: SPMI controller object
-+ * @apid_to_ppid: cached mapping from APID to PPID
- */
- struct spmi_pmic_arb_dev {
- void __iomem *base;
-@@ -110,6 +121,14 @@ struct spmi_pmic_arb_dev {
- void __iomem *cnfg;
- raw_spinlock_t lock;
- u8 channel;
-+ int irq;
-+ u8 ee;
-+ u8 min_apid;
-+ u8 max_apid;
-+ u32 mapping_table[SPMI_MAPPING_TABLE_LEN];
-+ struct irq_domain *domain;
-+ struct spmi_controller *spmic;
-+ u16 apid_to_ppid[256];
- };
-
- static inline u32 pmic_arb_base_read(struct spmi_pmic_arb_dev *dev, u32 offset)
-@@ -306,12 +325,316 @@ static int pmic_arb_write_cmd(struct spm
- return rc;
- }
-
-+enum qpnpint_regs {
-+ QPNPINT_REG_RT_STS = 0x10,
-+ QPNPINT_REG_SET_TYPE = 0x11,
-+ QPNPINT_REG_POLARITY_HIGH = 0x12,
-+ QPNPINT_REG_POLARITY_LOW = 0x13,
-+ QPNPINT_REG_LATCHED_CLR = 0x14,
-+ QPNPINT_REG_EN_SET = 0x15,
-+ QPNPINT_REG_EN_CLR = 0x16,
-+ QPNPINT_REG_LATCHED_STS = 0x18,
-+};
-+
-+struct spmi_pmic_arb_qpnpint_type {
-+ u8 type; /* 1 -> edge */
-+ u8 polarity_high;
-+ u8 polarity_low;
-+} __packed;
-+
-+/* Simplified accessor functions for irqchip callbacks */
-+static void qpnpint_spmi_write(struct irq_data *d, u8 reg, void *buf,
-+ size_t len)
-+{
-+ struct spmi_pmic_arb_dev *pa = irq_data_get_irq_chip_data(d);
-+ u8 sid = d->hwirq >> 24;
-+ u8 per = d->hwirq >> 16;
-+
-+ if (pmic_arb_write_cmd(pa->spmic, SPMI_CMD_EXT_WRITEL, sid,
-+ (per << 8) + reg, buf, len))
-+ dev_err_ratelimited(&pa->spmic->dev,
-+ "failed irqchip transaction on %x\n",
-+ d->irq);
-+}
-+
-+static void qpnpint_spmi_read(struct irq_data *d, u8 reg, void *buf, size_t len)
-+{
-+ struct spmi_pmic_arb_dev *pa = irq_data_get_irq_chip_data(d);
-+ u8 sid = d->hwirq >> 24;
-+ u8 per = d->hwirq >> 16;
-+
-+ if (pmic_arb_read_cmd(pa->spmic, SPMI_CMD_EXT_READL, sid,
-+ (per << 8) + reg, buf, len))
-+ dev_err_ratelimited(&pa->spmic->dev,
-+ "failed irqchip transaction on %x\n",
-+ d->irq);
-+}
-+
-+static void periph_interrupt(struct spmi_pmic_arb_dev *pa, u8 apid)
-+{
-+ unsigned int irq;
-+ u32 status;
-+ int id;
-+
-+ status = readl_relaxed(pa->intr + SPMI_PIC_IRQ_STATUS(apid));
-+ while (status) {
-+ id = ffs(status) - 1;
-+ status &= ~(1 << id);
-+ irq = irq_find_mapping(pa->domain,
-+ pa->apid_to_ppid[apid] << 16
-+ | id << 8
-+ | apid);
-+ generic_handle_irq(irq);
-+ }
-+}
-+
-+static void pmic_arb_chained_irq(unsigned int irq, struct irq_desc *desc)
-+{
-+ struct spmi_pmic_arb_dev *pa = irq_get_handler_data(irq);
-+ struct irq_chip *chip = irq_get_chip(irq);
-+ void __iomem *intr = pa->intr;
-+ int first = pa->min_apid >> 5;
-+ int last = pa->max_apid >> 5;
-+ u32 status;
-+ int i, id;
-+
-+ chained_irq_enter(chip, desc);
-+
-+ for (i = first; i <= last; ++i) {
-+ status = readl_relaxed(intr +
-+ SPMI_PIC_OWNER_ACC_STATUS(pa->ee, i));
-+ while (status) {
-+ id = ffs(status) - 1;
-+ status &= ~(1 << id);
-+ periph_interrupt(pa, id + i * 32);
-+ }
-+ }
-+
-+ chained_irq_exit(chip, desc);
-+}
-+
-+static void qpnpint_irq_ack(struct irq_data *d)
-+{
-+ struct spmi_pmic_arb_dev *pa = irq_data_get_irq_chip_data(d);
-+ u8 irq = d->hwirq >> 8;
-+ u8 apid = d->hwirq;
-+ unsigned long flags;
-+ u8 data;
-+
-+ raw_spin_lock_irqsave(&pa->lock, flags);
-+ writel_relaxed(1 << irq, pa->intr + SPMI_PIC_IRQ_CLEAR(apid));
-+ raw_spin_unlock_irqrestore(&pa->lock, flags);
-+
-+ data = 1 << irq;
-+ qpnpint_spmi_write(d, QPNPINT_REG_LATCHED_CLR, &data, 1);
-+}
-+
-+static void qpnpint_irq_mask(struct irq_data *d)
-+{
-+ struct spmi_pmic_arb_dev *pa = irq_data_get_irq_chip_data(d);
-+ u8 irq = d->hwirq >> 8;
-+ u8 apid = d->hwirq;
-+ unsigned long flags;
-+ u32 status;
-+ u8 data;
-+
-+ raw_spin_lock_irqsave(&pa->lock, flags);
-+ status = readl_relaxed(pa->intr + SPMI_PIC_ACC_ENABLE(apid));
-+ if (status & SPMI_PIC_ACC_ENABLE_BIT) {
-+ status = status & ~SPMI_PIC_ACC_ENABLE_BIT;
-+ writel_relaxed(status, pa->intr + SPMI_PIC_ACC_ENABLE(apid));
-+ }
-+ raw_spin_unlock_irqrestore(&pa->lock, flags);
-+
-+ data = 1 << irq;
-+ qpnpint_spmi_write(d, QPNPINT_REG_EN_CLR, &data, 1);
-+}
-+
-+static void qpnpint_irq_unmask(struct irq_data *d)
-+{
-+ struct spmi_pmic_arb_dev *pa = irq_data_get_irq_chip_data(d);
-+ u8 irq = d->hwirq >> 8;
-+ u8 apid = d->hwirq;
-+ unsigned long flags;
-+ u32 status;
-+ u8 data;
-+
-+ raw_spin_lock_irqsave(&pa->lock, flags);
-+ status = readl_relaxed(pa->intr + SPMI_PIC_ACC_ENABLE(apid));
-+ if (!(status & SPMI_PIC_ACC_ENABLE_BIT)) {
-+ writel_relaxed(status | SPMI_PIC_ACC_ENABLE_BIT,
-+ pa->intr + SPMI_PIC_ACC_ENABLE(apid));
-+ }
-+ raw_spin_unlock_irqrestore(&pa->lock, flags);
-+
-+ data = 1 << irq;
-+ qpnpint_spmi_write(d, QPNPINT_REG_EN_SET, &data, 1);
-+}
-+
-+static void qpnpint_irq_enable(struct irq_data *d)
-+{
-+ u8 irq = d->hwirq >> 8;
-+ u8 data;
-+
-+ qpnpint_irq_unmask(d);
-+
-+ data = 1 << irq;
-+ qpnpint_spmi_write(d, QPNPINT_REG_LATCHED_CLR, &data, 1);
-+}
-+
-+static int qpnpint_irq_set_type(struct irq_data *d, unsigned int flow_type)
-+{
-+ struct spmi_pmic_arb_qpnpint_type type;
-+ u8 irq = d->hwirq >> 8;
-+
-+ qpnpint_spmi_read(d, QPNPINT_REG_SET_TYPE, &type, sizeof(type));
-+
-+ if (flow_type & (IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING)) {
-+ type.type |= 1 << irq;
-+ if (flow_type & IRQF_TRIGGER_RISING)
-+ type.polarity_high |= 1 << irq;
-+ if (flow_type & IRQF_TRIGGER_FALLING)
-+ type.polarity_low |= 1 << irq;
-+ } else {
-+ if ((flow_type & (IRQF_TRIGGER_HIGH)) &&
-+ (flow_type & (IRQF_TRIGGER_LOW)))
-+ return -EINVAL;
-+
-+ type.type &= ~(1 << irq); /* level trig */
-+ if (flow_type & IRQF_TRIGGER_HIGH)
-+ type.polarity_high |= 1 << irq;
-+ else
-+ type.polarity_low |= 1 << irq;
-+ }
-+
-+ qpnpint_spmi_write(d, QPNPINT_REG_SET_TYPE, &type, sizeof(type));
-+ return 0;
-+}
-+
-+static struct irq_chip pmic_arb_irqchip = {
-+ .name = "pmic_arb",
-+ .irq_enable = qpnpint_irq_enable,
-+ .irq_ack = qpnpint_irq_ack,
-+ .irq_mask = qpnpint_irq_mask,
-+ .irq_unmask = qpnpint_irq_unmask,
-+ .irq_set_type = qpnpint_irq_set_type,
-+ .flags = IRQCHIP_MASK_ON_SUSPEND
-+ | IRQCHIP_SKIP_SET_WAKE,
-+};
-+
-+struct spmi_pmic_arb_irq_spec {
-+ unsigned slave:4;
-+ unsigned per:8;
-+ unsigned irq:3;
-+};
-+
-+static int search_mapping_table(struct spmi_pmic_arb_dev *pa,
-+ struct spmi_pmic_arb_irq_spec *spec,
-+ u8 *apid)
-+{
-+ u16 ppid = spec->slave << 8 | spec->per;
-+ u32 *mapping_table = pa->mapping_table;
-+ int index = 0, i;
-+ u32 data;
-+
-+ for (i = 0; i < SPMI_MAPPING_TABLE_TREE_DEPTH; ++i) {
-+ data = mapping_table[index];
-+
-+ if (ppid & (1 << SPMI_MAPPING_BIT_INDEX(data))) {
-+ if (SPMI_MAPPING_BIT_IS_1_FLAG(data)) {
-+ index = SPMI_MAPPING_BIT_IS_1_RESULT(data);
-+ } else {
-+ *apid = SPMI_MAPPING_BIT_IS_1_RESULT(data);
-+ return 0;
-+ }
-+ } else {
-+ if (SPMI_MAPPING_BIT_IS_0_FLAG(data)) {
-+ index = SPMI_MAPPING_BIT_IS_0_RESULT(data);
-+ } else {
-+ *apid = SPMI_MAPPING_BIT_IS_0_RESULT(data);
-+ return 0;
-+ }
-+ }
-+ }
-+
-+ return -ENODEV;
-+}
-+
-+static int qpnpint_irq_domain_dt_translate(struct irq_domain *d,
-+ struct device_node *controller,
-+ const u32 *intspec,
-+ unsigned int intsize,
-+ unsigned long *out_hwirq,
-+ unsigned int *out_type)
-+{
-+ struct spmi_pmic_arb_dev *pa = d->host_data;
-+ struct spmi_pmic_arb_irq_spec spec;
-+ int err;
-+ u8 apid;
-+
-+ dev_dbg(&pa->spmic->dev,
-+ "intspec[0] 0x%1x intspec[1] 0x%02x intspec[2] 0x%02x\n",
-+ intspec[0], intspec[1], intspec[2]);
-+
-+ if (d->of_node != controller)
-+ return -EINVAL;
-+ if (intsize != 4)
-+ return -EINVAL;
-+ if (intspec[0] > 0xF || intspec[1] > 0xFF || intspec[2] > 0x7)
-+ return -EINVAL;
-+
-+ spec.slave = intspec[0];
-+ spec.per = intspec[1];
-+ spec.irq = intspec[2];
-+
-+ err = search_mapping_table(pa, &spec, &apid);
-+ if (err)
-+ return err;
-+
-+ pa->apid_to_ppid[apid] = spec.slave << 8 | spec.per;
-+
-+ /* Keep track of {max,min}_apid for bounding search during interrupt */
-+ if (apid > pa->max_apid)
-+ pa->max_apid = apid;
-+ if (apid < pa->min_apid)
-+ pa->min_apid = apid;
-+
-+ *out_hwirq = spec.slave << 24
-+ | spec.per << 16
-+ | spec.irq << 8
-+ | apid;
-+ *out_type = intspec[3] & IRQ_TYPE_SENSE_MASK;
-+
-+ dev_dbg(&pa->spmic->dev, "out_hwirq = %lu\n", *out_hwirq);
-+
-+ return 0;
-+}
-+
-+static int qpnpint_irq_domain_map(struct irq_domain *d,
-+ unsigned int virq,
-+ irq_hw_number_t hwirq)
-+{
-+ struct spmi_pmic_arb_dev *pa = d->host_data;
-+
-+ dev_dbg(&pa->spmic->dev, "virq = %u, hwirq = %lu\n", virq, hwirq);
-+
-+ irq_set_chip_and_handler(virq, &pmic_arb_irqchip, handle_level_irq);
-+ irq_set_chip_data(virq, d->host_data);
-+ irq_set_noprobe(virq);
-+ return 0;
-+}
-+
-+static const struct irq_domain_ops pmic_arb_irq_domain_ops = {
-+ .map = qpnpint_irq_domain_map,
-+ .xlate = qpnpint_irq_domain_dt_translate,
-+};
-+
- static int spmi_pmic_arb_probe(struct platform_device *pdev)
- {
- struct spmi_pmic_arb_dev *pa;
- struct spmi_controller *ctrl;
- struct resource *res;
-- u32 channel;
-+ u32 channel, ee;
- int err, i;
-
- ctrl = spmi_controller_alloc(&pdev->dev, sizeof(*pa));
-@@ -319,6 +642,7 @@ static int spmi_pmic_arb_probe(struct pl
- return -ENOMEM;
-
- pa = spmi_controller_get_drvdata(ctrl);
-+ pa->spmic = ctrl;
-
- res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "core");
- pa->base = devm_ioremap_resource(&ctrl->dev, res);
-@@ -341,6 +665,12 @@ static int spmi_pmic_arb_probe(struct pl
- goto err_put_ctrl;
- }
-
-+ pa->irq = platform_get_irq_byname(pdev, "periph_irq");
-+ if (pa->irq < 0) {
-+ err = pa->irq;
-+ goto err_put_ctrl;
-+ }
-+
- err = of_property_read_u32(pdev->dev.of_node, "qcom,channel", &channel);
- if (err) {
- dev_err(&pdev->dev, "channel unspecified.\n");
-@@ -355,6 +685,29 @@ static int spmi_pmic_arb_probe(struct pl
-
- pa->channel = channel;
-
-+ err = of_property_read_u32(pdev->dev.of_node, "qcom,ee", &ee);
-+ if (err) {
-+ dev_err(&pdev->dev, "EE unspecified.\n");
-+ goto err_put_ctrl;
-+ }
-+
-+ if (ee > 5) {
-+ dev_err(&pdev->dev, "invalid EE (%u) specified\n", ee);
-+ err = -EINVAL;
-+ goto err_put_ctrl;
-+ }
-+
-+ pa->ee = ee;
-+
-+ for (i = 0; i < ARRAY_SIZE(pa->mapping_table); ++i)
-+ pa->mapping_table[i] = readl_relaxed(
-+ pa->cnfg + SPMI_MAPPING_TABLE_REG(i));
-+
-+ /* Initialize max_apid/min_apid to the opposite bounds, during
-+ * the irq domain translation, we are sure to update these */
-+ pa->max_apid = 0;
-+ pa->min_apid = PMIC_ARB_MAX_PERIPHS - 1;
-+
- platform_set_drvdata(pdev, ctrl);
- raw_spin_lock_init(&pa->lock);
-
-@@ -362,15 +715,31 @@ static int spmi_pmic_arb_probe(struct pl
- ctrl->read_cmd = pmic_arb_read_cmd;
- ctrl->write_cmd = pmic_arb_write_cmd;
-
-+ dev_dbg(&pdev->dev, "adding irq domain\n");
-+ pa->domain = irq_domain_add_tree(pdev->dev.of_node,
-+ &pmic_arb_irq_domain_ops, pa);
-+ if (!pa->domain) {
-+ dev_err(&pdev->dev, "unable to create irq_domain\n");
-+ err = -ENOMEM;
-+ goto err_put_ctrl;
-+ }
-+
-+ irq_set_handler_data(pa->irq, pa);
-+ irq_set_chained_handler(pa->irq, pmic_arb_chained_irq);
-+
- err = spmi_controller_add(ctrl);
- if (err)
-- goto err_put_ctrl;
-+ goto err_domain_remove;
-
- dev_dbg(&ctrl->dev, "PMIC Arb Version 0x%x\n",
- pmic_arb_base_read(pa, PMIC_ARB_VERSION));
-
- return 0;
-
-+err_domain_remove:
-+ irq_set_chained_handler(pa->irq, NULL);
-+ irq_set_handler_data(pa->irq, NULL);
-+ irq_domain_remove(pa->domain);
- err_put_ctrl:
- spmi_controller_put(ctrl);
- return err;
-@@ -379,7 +748,11 @@ err_put_ctrl:
- static int spmi_pmic_arb_remove(struct platform_device *pdev)
- {
- struct spmi_controller *ctrl = platform_get_drvdata(pdev);
-+ struct spmi_pmic_arb_dev *pa = spmi_controller_get_drvdata(ctrl);
- spmi_controller_remove(ctrl);
-+ irq_set_chained_handler(pa->irq, NULL);
-+ irq_set_handler_data(pa->irq, NULL);
-+ irq_domain_remove(pa->domain);
- spmi_controller_put(ctrl);
- return 0;
- }
diff --git a/target/linux/ipq806x/patches/0058-spmi-pmic_arb-make-selectable-on-ARCH_QCOM.patch b/target/linux/ipq806x/patches/0058-spmi-pmic_arb-make-selectable-on-ARCH_QCOM.patch
deleted file mode 100644
index 0df3780..0000000
--- a/target/linux/ipq806x/patches/0058-spmi-pmic_arb-make-selectable-on-ARCH_QCOM.patch
+++ /dev/null
@@ -1,29 +0,0 @@
-From 840fe915072597b5ba9599c4579f014f47b9638e Mon Sep 17 00:00:00 2001
-From: Josh Cartwright <joshc@codeaurora.org>
-Date: Mon, 3 Mar 2014 10:49:43 -0600
-Subject: [PATCH 058/182] spmi: pmic_arb: make selectable on ARCH_QCOM
-
-With the split of Qualcomm MSM support into legacy and multiplatform,
-the SPMI PMIC arb driver is only relevant on the multiplatform supported
-SoCs. Switch the Kconfig depends to ARCH_QCOM.
-
-Acked-by: Kumar Gala <galak@codeaurora.org>
-Signed-off-by: Josh Cartwright <joshc@codeaurora.org>
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/spmi/Kconfig | 4 ++--
- 1 file changed, 2 insertions(+), 2 deletions(-)
-
---- a/drivers/spmi/Kconfig
-+++ b/drivers/spmi/Kconfig
-@@ -14,8 +14,8 @@ config SPMI_MSM_PMIC_ARB
- tristate "Qualcomm MSM SPMI Controller (PMIC Arbiter)"
- depends on ARM
- depends on IRQ_DOMAIN
-- depends on ARCH_MSM || COMPILE_TEST
-- default ARCH_MSM
-+ depends on ARCH_QCOM || COMPILE_TEST
-+ default ARCH_QCOM
- help
- If you say yes to this option, support will be included for the
- built-in SPMI PMIC Arbiter interface on Qualcomm MSM family
diff --git a/target/linux/ipq806x/patches/0059-spmi-pm-drop-bus-level-PM-suspend-resume-routines.patch b/target/linux/ipq806x/patches/0059-spmi-pm-drop-bus-level-PM-suspend-resume-routines.patch
deleted file mode 100644
index b8bb48c..0000000
--- a/target/linux/ipq806x/patches/0059-spmi-pm-drop-bus-level-PM-suspend-resume-routines.patch
+++ /dev/null
@@ -1,69 +0,0 @@
-From 9d13f01e2ec45253adaae1a330cdc4eb881c7377 Mon Sep 17 00:00:00 2001
-From: Josh Cartwright <joshc@codeaurora.org>
-Date: Mon, 3 Mar 2014 10:49:44 -0600
-Subject: [PATCH 059/182] spmi: pm: drop bus-level PM suspend/resume routines
-
-SPMI defines the behavior of a device in the "SLEEP" state as being
-"user-defined or specified by the device manufacturer". Without
-clearly-defined bus-level semantics for low-power states, push the
-responsibility of transitioning a device into/out of "SLEEP" into SPMI
-device drivers.
-
-Cc: Felipe Balbi <balbi@ti.com>
-Signed-off-by: Josh Cartwright <joshc@codeaurora.org>
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/spmi/spmi.c | 35 -----------------------------------
- 1 file changed, 35 deletions(-)
-
---- a/drivers/spmi/spmi.c
-+++ b/drivers/spmi/spmi.c
-@@ -46,40 +46,6 @@ static const struct device_type spmi_ctr
- .release = spmi_ctrl_release,
- };
-
--#ifdef CONFIG_PM_RUNTIME
--static int spmi_runtime_suspend(struct device *dev)
--{
-- struct spmi_device *sdev = to_spmi_device(dev);
-- int err;
--
-- err = pm_generic_runtime_suspend(dev);
-- if (err)
-- return err;
--
-- return spmi_command_sleep(sdev);
--}
--
--static int spmi_runtime_resume(struct device *dev)
--{
-- struct spmi_device *sdev = to_spmi_device(dev);
-- int err;
--
-- err = spmi_command_wakeup(sdev);
-- if (err)
-- return err;
--
-- return pm_generic_runtime_resume(dev);
--}
--#endif
--
--static const struct dev_pm_ops spmi_pm_ops = {
-- SET_RUNTIME_PM_OPS(
-- spmi_runtime_suspend,
-- spmi_runtime_resume,
-- NULL
-- )
--};
--
- static int spmi_device_match(struct device *dev, struct device_driver *drv)
- {
- if (of_driver_match_device(dev, drv))
-@@ -391,7 +357,6 @@ static int spmi_drv_remove(struct device
- static struct bus_type spmi_bus_type = {
- .name = "spmi",
- .match = spmi_device_match,
-- .pm = &spmi_pm_ops,
- .probe = spmi_drv_probe,
- .remove = spmi_drv_remove,
- };
diff --git a/target/linux/ipq806x/patches/0060-i2c-qup-New-bus-driver-for-the-Qualcomm-QUP-I2C-cont.patch b/target/linux/ipq806x/patches/0060-i2c-qup-New-bus-driver-for-the-Qualcomm-QUP-I2C-cont.patch
deleted file mode 100644
index c96fc15..0000000
--- a/target/linux/ipq806x/patches/0060-i2c-qup-New-bus-driver-for-the-Qualcomm-QUP-I2C-cont.patch
+++ /dev/null
@@ -1,825 +0,0 @@
-From 226eff10dc11af5d6b1bc31e5cedc079aa564fb3 Mon Sep 17 00:00:00 2001
-From: Bjorn Andersson <bjorn.andersson@sonymobile.com>
-Date: Thu, 13 Mar 2014 19:07:43 -0700
-Subject: [PATCH 060/182] i2c: qup: New bus driver for the Qualcomm QUP I2C
- controller
-
-This bus driver supports the QUP i2c hardware controller in the Qualcomm SOCs.
-The Qualcomm Universal Peripheral Engine (QUP) is a general purpose data path
-engine with input/output FIFOs and an embedded i2c mini-core. The driver
-supports FIFO mode (for low bandwidth applications) and block mode (interrupt
-generated for each block-size data transfer).
-
-Signed-off-by: Ivan T. Ivanov <iivanov@mm-sol.com>
-Signed-off-by: Bjorn Andersson <bjorn.andersson@sonymobile.com>
-Reviewed-by: Andy Gross <agross@codeaurora.org>
-Tested-by: Philip Elcan <pelcan@codeaurora.org>
-[wsa: removed needless IS_ERR_VALUE]
-Signed-off-by: Wolfram Sang <wsa@the-dreams.de>
----
- drivers/i2c/busses/Kconfig | 10 +
- drivers/i2c/busses/Makefile | 1 +
- drivers/i2c/busses/i2c-qup.c | 768 ++++++++++++++++++++++++++++++++++++++++++
- 3 files changed, 779 insertions(+)
- create mode 100644 drivers/i2c/busses/i2c-qup.c
-
---- a/drivers/i2c/busses/Kconfig
-+++ b/drivers/i2c/busses/Kconfig
-@@ -649,6 +649,16 @@ config I2C_PXA_SLAVE
- is necessary for systems where the PXA may be a target on the
- I2C bus.
-
-+config I2C_QUP
-+ tristate "Qualcomm QUP based I2C controller"
-+ depends on ARCH_QCOM
-+ help
-+ If you say yes to this option, support will be included for the
-+ built-in I2C interface on the Qualcomm SoCs.
-+
-+ This driver can also be built as a module. If so, the module
-+ will be called i2c-qup.
-+
- config I2C_RIIC
- tristate "Renesas RIIC adapter"
- depends on ARCH_SHMOBILE || COMPILE_TEST
---- a/drivers/i2c/busses/Makefile
-+++ b/drivers/i2c/busses/Makefile
-@@ -63,6 +63,7 @@ obj-$(CONFIG_I2C_PNX) += i2c-pnx.o
- obj-$(CONFIG_I2C_PUV3) += i2c-puv3.o
- obj-$(CONFIG_I2C_PXA) += i2c-pxa.o
- obj-$(CONFIG_I2C_PXA_PCI) += i2c-pxa-pci.o
-+obj-$(CONFIG_I2C_QUP) += i2c-qup.o
- obj-$(CONFIG_I2C_RIIC) += i2c-riic.o
- obj-$(CONFIG_I2C_S3C2410) += i2c-s3c2410.o
- obj-$(CONFIG_I2C_S6000) += i2c-s6000.o
---- /dev/null
-+++ b/drivers/i2c/busses/i2c-qup.c
-@@ -0,0 +1,768 @@
-+/*
-+ * Copyright (c) 2009-2013, The Linux Foundation. All rights reserved.
-+ * Copyright (c) 2014, Sony Mobile Communications AB.
-+ *
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 and
-+ * only version 2 as published by the Free Software Foundation.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ * GNU General Public License for more details.
-+ *
-+ */
-+
-+#include <linux/clk.h>
-+#include <linux/delay.h>
-+#include <linux/err.h>
-+#include <linux/i2c.h>
-+#include <linux/interrupt.h>
-+#include <linux/io.h>
-+#include <linux/module.h>
-+#include <linux/of.h>
-+#include <linux/platform_device.h>
-+#include <linux/pm_runtime.h>
-+
-+/* QUP Registers */
-+#define QUP_CONFIG 0x000
-+#define QUP_STATE 0x004
-+#define QUP_IO_MODE 0x008
-+#define QUP_SW_RESET 0x00c
-+#define QUP_OPERATIONAL 0x018
-+#define QUP_ERROR_FLAGS 0x01c
-+#define QUP_ERROR_FLAGS_EN 0x020
-+#define QUP_HW_VERSION 0x030
-+#define QUP_MX_OUTPUT_CNT 0x100
-+#define QUP_OUT_FIFO_BASE 0x110
-+#define QUP_MX_WRITE_CNT 0x150
-+#define QUP_MX_INPUT_CNT 0x200
-+#define QUP_MX_READ_CNT 0x208
-+#define QUP_IN_FIFO_BASE 0x218
-+#define QUP_I2C_CLK_CTL 0x400
-+#define QUP_I2C_STATUS 0x404
-+
-+/* QUP States and reset values */
-+#define QUP_RESET_STATE 0
-+#define QUP_RUN_STATE 1
-+#define QUP_PAUSE_STATE 3
-+#define QUP_STATE_MASK 3
-+
-+#define QUP_STATE_VALID BIT(2)
-+#define QUP_I2C_MAST_GEN BIT(4)
-+
-+#define QUP_OPERATIONAL_RESET 0x000ff0
-+#define QUP_I2C_STATUS_RESET 0xfffffc
-+
-+/* QUP OPERATIONAL FLAGS */
-+#define QUP_I2C_NACK_FLAG BIT(3)
-+#define QUP_OUT_NOT_EMPTY BIT(4)
-+#define QUP_IN_NOT_EMPTY BIT(5)
-+#define QUP_OUT_FULL BIT(6)
-+#define QUP_OUT_SVC_FLAG BIT(8)
-+#define QUP_IN_SVC_FLAG BIT(9)
-+#define QUP_MX_OUTPUT_DONE BIT(10)
-+#define QUP_MX_INPUT_DONE BIT(11)
-+
-+/* I2C mini core related values */
-+#define QUP_CLOCK_AUTO_GATE BIT(13)
-+#define I2C_MINI_CORE (2 << 8)
-+#define I2C_N_VAL 15
-+/* Most significant word offset in FIFO port */
-+#define QUP_MSW_SHIFT (I2C_N_VAL + 1)
-+
-+/* Packing/Unpacking words in FIFOs, and IO modes */
-+#define QUP_OUTPUT_BLK_MODE (1 << 10)
-+#define QUP_INPUT_BLK_MODE (1 << 12)
-+#define QUP_UNPACK_EN BIT(14)
-+#define QUP_PACK_EN BIT(15)
-+
-+#define QUP_REPACK_EN (QUP_UNPACK_EN | QUP_PACK_EN)
-+
-+#define QUP_OUTPUT_BLOCK_SIZE(x)(((x) >> 0) & 0x03)
-+#define QUP_OUTPUT_FIFO_SIZE(x) (((x) >> 2) & 0x07)
-+#define QUP_INPUT_BLOCK_SIZE(x) (((x) >> 5) & 0x03)
-+#define QUP_INPUT_FIFO_SIZE(x) (((x) >> 7) & 0x07)
-+
-+/* QUP tags */
-+#define QUP_TAG_START (1 << 8)
-+#define QUP_TAG_DATA (2 << 8)
-+#define QUP_TAG_STOP (3 << 8)
-+#define QUP_TAG_REC (4 << 8)
-+
-+/* Status, Error flags */
-+#define I2C_STATUS_WR_BUFFER_FULL BIT(0)
-+#define I2C_STATUS_BUS_ACTIVE BIT(8)
-+#define I2C_STATUS_ERROR_MASK 0x38000fc
-+#define QUP_STATUS_ERROR_FLAGS 0x7c
-+
-+#define QUP_READ_LIMIT 256
-+
-+struct qup_i2c_dev {
-+ struct device *dev;
-+ void __iomem *base;
-+ int irq;
-+ struct clk *clk;
-+ struct clk *pclk;
-+ struct i2c_adapter adap;
-+
-+ int clk_ctl;
-+ int out_fifo_sz;
-+ int in_fifo_sz;
-+ int out_blk_sz;
-+ int in_blk_sz;
-+
-+ unsigned long one_byte_t;
-+
-+ struct i2c_msg *msg;
-+ /* Current posion in user message buffer */
-+ int pos;
-+ /* I2C protocol errors */
-+ u32 bus_err;
-+ /* QUP core errors */
-+ u32 qup_err;
-+
-+ struct completion xfer;
-+};
-+
-+static irqreturn_t qup_i2c_interrupt(int irq, void *dev)
-+{
-+ struct qup_i2c_dev *qup = dev;
-+ u32 bus_err;
-+ u32 qup_err;
-+ u32 opflags;
-+
-+ bus_err = readl(qup->base + QUP_I2C_STATUS);
-+ qup_err = readl(qup->base + QUP_ERROR_FLAGS);
-+ opflags = readl(qup->base + QUP_OPERATIONAL);
-+
-+ if (!qup->msg) {
-+ /* Clear Error interrupt */
-+ writel(QUP_RESET_STATE, qup->base + QUP_STATE);
-+ return IRQ_HANDLED;
-+ }
-+
-+ bus_err &= I2C_STATUS_ERROR_MASK;
-+ qup_err &= QUP_STATUS_ERROR_FLAGS;
-+
-+ if (qup_err) {
-+ /* Clear Error interrupt */
-+ writel(qup_err, qup->base + QUP_ERROR_FLAGS);
-+ goto done;
-+ }
-+
-+ if (bus_err) {
-+ /* Clear Error interrupt */
-+ writel(QUP_RESET_STATE, qup->base + QUP_STATE);
-+ goto done;
-+ }
-+
-+ if (opflags & QUP_IN_SVC_FLAG)
-+ writel(QUP_IN_SVC_FLAG, qup->base + QUP_OPERATIONAL);
-+
-+ if (opflags & QUP_OUT_SVC_FLAG)
-+ writel(QUP_OUT_SVC_FLAG, qup->base + QUP_OPERATIONAL);
-+
-+done:
-+ qup->qup_err = qup_err;
-+ qup->bus_err = bus_err;
-+ complete(&qup->xfer);
-+ return IRQ_HANDLED;
-+}
-+
-+static int qup_i2c_poll_state_mask(struct qup_i2c_dev *qup,
-+ u32 req_state, u32 req_mask)
-+{
-+ int retries = 1;
-+ u32 state;
-+
-+ /*
-+ * State transition takes 3 AHB clocks cycles + 3 I2C master clock
-+ * cycles. So retry once after a 1uS delay.
-+ */
-+ do {
-+ state = readl(qup->base + QUP_STATE);
-+
-+ if (state & QUP_STATE_VALID &&
-+ (state & req_mask) == req_state)
-+ return 0;
-+
-+ udelay(1);
-+ } while (retries--);
-+
-+ return -ETIMEDOUT;
-+}
-+
-+static int qup_i2c_poll_state(struct qup_i2c_dev *qup, u32 req_state)
-+{
-+ return qup_i2c_poll_state_mask(qup, req_state, QUP_STATE_MASK);
-+}
-+
-+static int qup_i2c_poll_state_valid(struct qup_i2c_dev *qup)
-+{
-+ return qup_i2c_poll_state_mask(qup, 0, 0);
-+}
-+
-+static int qup_i2c_poll_state_i2c_master(struct qup_i2c_dev *qup)
-+{
-+ return qup_i2c_poll_state_mask(qup, QUP_I2C_MAST_GEN, QUP_I2C_MAST_GEN);
-+}
-+
-+static int qup_i2c_change_state(struct qup_i2c_dev *qup, u32 state)
-+{
-+ if (qup_i2c_poll_state_valid(qup) != 0)
-+ return -EIO;
-+
-+ writel(state, qup->base + QUP_STATE);
-+
-+ if (qup_i2c_poll_state(qup, state) != 0)
-+ return -EIO;
-+ return 0;
-+}
-+
-+static int qup_i2c_wait_writeready(struct qup_i2c_dev *qup)
-+{
-+ unsigned long timeout;
-+ u32 opflags;
-+ u32 status;
-+
-+ timeout = jiffies + HZ;
-+
-+ for (;;) {
-+ opflags = readl(qup->base + QUP_OPERATIONAL);
-+ status = readl(qup->base + QUP_I2C_STATUS);
-+
-+ if (!(opflags & QUP_OUT_NOT_EMPTY) &&
-+ !(status & I2C_STATUS_BUS_ACTIVE))
-+ return 0;
-+
-+ if (time_after(jiffies, timeout))
-+ return -ETIMEDOUT;
-+
-+ usleep_range(qup->one_byte_t, qup->one_byte_t * 2);
-+ }
-+}
-+
-+static void qup_i2c_set_write_mode(struct qup_i2c_dev *qup, struct i2c_msg *msg)
-+{
-+ /* Number of entries to shift out, including the start */
-+ int total = msg->len + 1;
-+
-+ if (total < qup->out_fifo_sz) {
-+ /* FIFO mode */
-+ writel(QUP_REPACK_EN, qup->base + QUP_IO_MODE);
-+ writel(total, qup->base + QUP_MX_WRITE_CNT);
-+ } else {
-+ /* BLOCK mode (transfer data on chunks) */
-+ writel(QUP_OUTPUT_BLK_MODE | QUP_REPACK_EN,
-+ qup->base + QUP_IO_MODE);
-+ writel(total, qup->base + QUP_MX_OUTPUT_CNT);
-+ }
-+}
-+
-+static void qup_i2c_issue_write(struct qup_i2c_dev *qup, struct i2c_msg *msg)
-+{
-+ u32 addr = msg->addr << 1;
-+ u32 qup_tag;
-+ u32 opflags;
-+ int idx;
-+ u32 val;
-+
-+ if (qup->pos == 0) {
-+ val = QUP_TAG_START | addr;
-+ idx = 1;
-+ } else {
-+ val = 0;
-+ idx = 0;
-+ }
-+
-+ while (qup->pos < msg->len) {
-+ /* Check that there's space in the FIFO for our pair */
-+ opflags = readl(qup->base + QUP_OPERATIONAL);
-+ if (opflags & QUP_OUT_FULL)
-+ break;
-+
-+ if (qup->pos == msg->len - 1)
-+ qup_tag = QUP_TAG_STOP;
-+ else
-+ qup_tag = QUP_TAG_DATA;
-+
-+ if (idx & 1)
-+ val |= (qup_tag | msg->buf[qup->pos]) << QUP_MSW_SHIFT;
-+ else
-+ val = qup_tag | msg->buf[qup->pos];
-+
-+ /* Write out the pair and the last odd value */
-+ if (idx & 1 || qup->pos == msg->len - 1)
-+ writel(val, qup->base + QUP_OUT_FIFO_BASE);
-+
-+ qup->pos++;
-+ idx++;
-+ }
-+}
-+
-+static int qup_i2c_write_one(struct qup_i2c_dev *qup, struct i2c_msg *msg)
-+{
-+ unsigned long left;
-+ int ret;
-+
-+ qup->msg = msg;
-+ qup->pos = 0;
-+
-+ enable_irq(qup->irq);
-+
-+ qup_i2c_set_write_mode(qup, msg);
-+
-+ ret = qup_i2c_change_state(qup, QUP_RUN_STATE);
-+ if (ret)
-+ goto err;
-+
-+ writel(qup->clk_ctl, qup->base + QUP_I2C_CLK_CTL);
-+
-+ do {
-+ ret = qup_i2c_change_state(qup, QUP_PAUSE_STATE);
-+ if (ret)
-+ goto err;
-+
-+ qup_i2c_issue_write(qup, msg);
-+
-+ ret = qup_i2c_change_state(qup, QUP_RUN_STATE);
-+ if (ret)
-+ goto err;
-+
-+ left = wait_for_completion_timeout(&qup->xfer, HZ);
-+ if (!left) {
-+ writel(1, qup->base + QUP_SW_RESET);
-+ ret = -ETIMEDOUT;
-+ goto err;
-+ }
-+
-+ if (qup->bus_err || qup->qup_err) {
-+ if (qup->bus_err & QUP_I2C_NACK_FLAG)
-+ dev_err(qup->dev, "NACK from %x\n", msg->addr);
-+ ret = -EIO;
-+ goto err;
-+ }
-+ } while (qup->pos < msg->len);
-+
-+ /* Wait for the outstanding data in the fifo to drain */
-+ ret = qup_i2c_wait_writeready(qup);
-+
-+err:
-+ disable_irq(qup->irq);
-+ qup->msg = NULL;
-+
-+ return ret;
-+}
-+
-+static void qup_i2c_set_read_mode(struct qup_i2c_dev *qup, int len)
-+{
-+ if (len < qup->in_fifo_sz) {
-+ /* FIFO mode */
-+ writel(QUP_REPACK_EN, qup->base + QUP_IO_MODE);
-+ writel(len, qup->base + QUP_MX_READ_CNT);
-+ } else {
-+ /* BLOCK mode (transfer data on chunks) */
-+ writel(QUP_INPUT_BLK_MODE | QUP_REPACK_EN,
-+ qup->base + QUP_IO_MODE);
-+ writel(len, qup->base + QUP_MX_INPUT_CNT);
-+ }
-+}
-+
-+static void qup_i2c_issue_read(struct qup_i2c_dev *qup, struct i2c_msg *msg)
-+{
-+ u32 addr, len, val;
-+
-+ addr = (msg->addr << 1) | 1;
-+
-+ /* 0 is used to specify a length 256 (QUP_READ_LIMIT) */
-+ len = (msg->len == QUP_READ_LIMIT) ? 0 : msg->len;
-+
-+ val = ((QUP_TAG_REC | len) << QUP_MSW_SHIFT) | QUP_TAG_START | addr;
-+ writel(val, qup->base + QUP_OUT_FIFO_BASE);
-+}
-+
-+
-+static void qup_i2c_read_fifo(struct qup_i2c_dev *qup, struct i2c_msg *msg)
-+{
-+ u32 opflags;
-+ u32 val = 0;
-+ int idx;
-+
-+ for (idx = 0; qup->pos < msg->len; idx++) {
-+ if ((idx & 1) == 0) {
-+ /* Check that FIFO have data */
-+ opflags = readl(qup->base + QUP_OPERATIONAL);
-+ if (!(opflags & QUP_IN_NOT_EMPTY))
-+ break;
-+
-+ /* Reading 2 words at time */
-+ val = readl(qup->base + QUP_IN_FIFO_BASE);
-+
-+ msg->buf[qup->pos++] = val & 0xFF;
-+ } else {
-+ msg->buf[qup->pos++] = val >> QUP_MSW_SHIFT;
-+ }
-+ }
-+}
-+
-+static int qup_i2c_read_one(struct qup_i2c_dev *qup, struct i2c_msg *msg)
-+{
-+ unsigned long left;
-+ int ret;
-+
-+ /*
-+ * The QUP block will issue a NACK and STOP on the bus when reaching
-+ * the end of the read, the length of the read is specified as one byte
-+ * which limits the possible read to 256 (QUP_READ_LIMIT) bytes.
-+ */
-+ if (msg->len > QUP_READ_LIMIT) {
-+ dev_err(qup->dev, "HW not capable of reads over %d bytes\n",
-+ QUP_READ_LIMIT);
-+ return -EINVAL;
-+ }
-+
-+ qup->msg = msg;
-+ qup->pos = 0;
-+
-+ enable_irq(qup->irq);
-+
-+ qup_i2c_set_read_mode(qup, msg->len);
-+
-+ ret = qup_i2c_change_state(qup, QUP_RUN_STATE);
-+ if (ret)
-+ goto err;
-+
-+ writel(qup->clk_ctl, qup->base + QUP_I2C_CLK_CTL);
-+
-+ ret = qup_i2c_change_state(qup, QUP_PAUSE_STATE);
-+ if (ret)
-+ goto err;
-+
-+ qup_i2c_issue_read(qup, msg);
-+
-+ ret = qup_i2c_change_state(qup, QUP_RUN_STATE);
-+ if (ret)
-+ goto err;
-+
-+ do {
-+ left = wait_for_completion_timeout(&qup->xfer, HZ);
-+ if (!left) {
-+ writel(1, qup->base + QUP_SW_RESET);
-+ ret = -ETIMEDOUT;
-+ goto err;
-+ }
-+
-+ if (qup->bus_err || qup->qup_err) {
-+ if (qup->bus_err & QUP_I2C_NACK_FLAG)
-+ dev_err(qup->dev, "NACK from %x\n", msg->addr);
-+ ret = -EIO;
-+ goto err;
-+ }
-+
-+ qup_i2c_read_fifo(qup, msg);
-+ } while (qup->pos < msg->len);
-+
-+err:
-+ disable_irq(qup->irq);
-+ qup->msg = NULL;
-+
-+ return ret;
-+}
-+
-+static int qup_i2c_xfer(struct i2c_adapter *adap,
-+ struct i2c_msg msgs[],
-+ int num)
-+{
-+ struct qup_i2c_dev *qup = i2c_get_adapdata(adap);
-+ int ret, idx;
-+
-+ ret = pm_runtime_get_sync(qup->dev);
-+ if (ret)
-+ goto out;
-+
-+ writel(1, qup->base + QUP_SW_RESET);
-+ ret = qup_i2c_poll_state(qup, QUP_RESET_STATE);
-+ if (ret)
-+ goto out;
-+
-+ /* Configure QUP as I2C mini core */
-+ writel(I2C_MINI_CORE | I2C_N_VAL, qup->base + QUP_CONFIG);
-+
-+ for (idx = 0; idx < num; idx++) {
-+ if (msgs[idx].len == 0) {
-+ ret = -EINVAL;
-+ goto out;
-+ }
-+
-+ if (qup_i2c_poll_state_i2c_master(qup)) {
-+ ret = -EIO;
-+ goto out;
-+ }
-+
-+ if (msgs[idx].flags & I2C_M_RD)
-+ ret = qup_i2c_read_one(qup, &msgs[idx]);
-+ else
-+ ret = qup_i2c_write_one(qup, &msgs[idx]);
-+
-+ if (ret)
-+ break;
-+
-+ ret = qup_i2c_change_state(qup, QUP_RESET_STATE);
-+ if (ret)
-+ break;
-+ }
-+
-+ if (ret == 0)
-+ ret = num;
-+out:
-+
-+ pm_runtime_mark_last_busy(qup->dev);
-+ pm_runtime_put_autosuspend(qup->dev);
-+
-+ return ret;
-+}
-+
-+static u32 qup_i2c_func(struct i2c_adapter *adap)
-+{
-+ return I2C_FUNC_I2C | (I2C_FUNC_SMBUS_EMUL & ~I2C_FUNC_SMBUS_QUICK);
-+}
-+
-+static const struct i2c_algorithm qup_i2c_algo = {
-+ .master_xfer = qup_i2c_xfer,
-+ .functionality = qup_i2c_func,
-+};
-+
-+static void qup_i2c_enable_clocks(struct qup_i2c_dev *qup)
-+{
-+ clk_prepare_enable(qup->clk);
-+ clk_prepare_enable(qup->pclk);
-+}
-+
-+static void qup_i2c_disable_clocks(struct qup_i2c_dev *qup)
-+{
-+ u32 config;
-+
-+ qup_i2c_change_state(qup, QUP_RESET_STATE);
-+ clk_disable_unprepare(qup->clk);
-+ config = readl(qup->base + QUP_CONFIG);
-+ config |= QUP_CLOCK_AUTO_GATE;
-+ writel(config, qup->base + QUP_CONFIG);
-+ clk_disable_unprepare(qup->pclk);
-+}
-+
-+static int qup_i2c_probe(struct platform_device *pdev)
-+{
-+ static const int blk_sizes[] = {4, 16, 32};
-+ struct device_node *node = pdev->dev.of_node;
-+ struct qup_i2c_dev *qup;
-+ unsigned long one_bit_t;
-+ struct resource *res;
-+ u32 io_mode, hw_ver, size;
-+ int ret, fs_div, hs_div;
-+ int src_clk_freq;
-+ int clk_freq = 100000;
-+
-+ qup = devm_kzalloc(&pdev->dev, sizeof(*qup), GFP_KERNEL);
-+ if (!qup)
-+ return -ENOMEM;
-+
-+ qup->dev = &pdev->dev;
-+ init_completion(&qup->xfer);
-+ platform_set_drvdata(pdev, qup);
-+
-+ of_property_read_u32(node, "clock-frequency", &clk_freq);
-+
-+ /* We support frequencies up to FAST Mode (400KHz) */
-+ if (!clk_freq || clk_freq > 400000) {
-+ dev_err(qup->dev, "clock frequency not supported %d\n",
-+ clk_freq);
-+ return -EINVAL;
-+ }
-+
-+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-+ qup->base = devm_ioremap_resource(qup->dev, res);
-+ if (IS_ERR(qup->base))
-+ return PTR_ERR(qup->base);
-+
-+ qup->irq = platform_get_irq(pdev, 0);
-+ if (qup->irq < 0) {
-+ dev_err(qup->dev, "No IRQ defined\n");
-+ return qup->irq;
-+ }
-+
-+ qup->clk = devm_clk_get(qup->dev, "core");
-+ if (IS_ERR(qup->clk)) {
-+ dev_err(qup->dev, "Could not get core clock\n");
-+ return PTR_ERR(qup->clk);
-+ }
-+
-+ qup->pclk = devm_clk_get(qup->dev, "iface");
-+ if (IS_ERR(qup->pclk)) {
-+ dev_err(qup->dev, "Could not get iface clock\n");
-+ return PTR_ERR(qup->pclk);
-+ }
-+
-+ qup_i2c_enable_clocks(qup);
-+
-+ /*
-+ * Bootloaders might leave a pending interrupt on certain QUP's,
-+ * so we reset the core before registering for interrupts.
-+ */
-+ writel(1, qup->base + QUP_SW_RESET);
-+ ret = qup_i2c_poll_state_valid(qup);
-+ if (ret)
-+ goto fail;
-+
-+ ret = devm_request_irq(qup->dev, qup->irq, qup_i2c_interrupt,
-+ IRQF_TRIGGER_HIGH, "i2c_qup", qup);
-+ if (ret) {
-+ dev_err(qup->dev, "Request %d IRQ failed\n", qup->irq);
-+ goto fail;
-+ }
-+ disable_irq(qup->irq);
-+
-+ hw_ver = readl(qup->base + QUP_HW_VERSION);
-+ dev_dbg(qup->dev, "Revision %x\n", hw_ver);
-+
-+ io_mode = readl(qup->base + QUP_IO_MODE);
-+
-+ /*
-+ * The block/fifo size w.r.t. 'actual data' is 1/2 due to 'tag'
-+ * associated with each byte written/received
-+ */
-+ size = QUP_OUTPUT_BLOCK_SIZE(io_mode);
-+ if (size > ARRAY_SIZE(blk_sizes))
-+ return -EIO;
-+ qup->out_blk_sz = blk_sizes[size] / 2;
-+
-+ size = QUP_INPUT_BLOCK_SIZE(io_mode);
-+ if (size > ARRAY_SIZE(blk_sizes))
-+ return -EIO;
-+ qup->in_blk_sz = blk_sizes[size] / 2;
-+
-+ size = QUP_OUTPUT_FIFO_SIZE(io_mode);
-+ qup->out_fifo_sz = qup->out_blk_sz * (2 << size);
-+
-+ size = QUP_INPUT_FIFO_SIZE(io_mode);
-+ qup->in_fifo_sz = qup->in_blk_sz * (2 << size);
-+
-+ src_clk_freq = clk_get_rate(qup->clk);
-+ fs_div = ((src_clk_freq / clk_freq) / 2) - 3;
-+ hs_div = 3;
-+ qup->clk_ctl = (hs_div << 8) | (fs_div & 0xff);
-+
-+ /*
-+ * Time it takes for a byte to be clocked out on the bus.
-+ * Each byte takes 9 clock cycles (8 bits + 1 ack).
-+ */
-+ one_bit_t = (USEC_PER_SEC / clk_freq) + 1;
-+ qup->one_byte_t = one_bit_t * 9;
-+
-+ dev_dbg(qup->dev, "IN:block:%d, fifo:%d, OUT:block:%d, fifo:%d\n",
-+ qup->in_blk_sz, qup->in_fifo_sz,
-+ qup->out_blk_sz, qup->out_fifo_sz);
-+
-+ i2c_set_adapdata(&qup->adap, qup);
-+ qup->adap.algo = &qup_i2c_algo;
-+ qup->adap.dev.parent = qup->dev;
-+ qup->adap.dev.of_node = pdev->dev.of_node;
-+ strlcpy(qup->adap.name, "QUP I2C adapter", sizeof(qup->adap.name));
-+
-+ ret = i2c_add_adapter(&qup->adap);
-+ if (ret)
-+ goto fail;
-+
-+ pm_runtime_set_autosuspend_delay(qup->dev, MSEC_PER_SEC);
-+ pm_runtime_use_autosuspend(qup->dev);
-+ pm_runtime_set_active(qup->dev);
-+ pm_runtime_enable(qup->dev);
-+ return 0;
-+
-+fail:
-+ qup_i2c_disable_clocks(qup);
-+ return ret;
-+}
-+
-+static int qup_i2c_remove(struct platform_device *pdev)
-+{
-+ struct qup_i2c_dev *qup = platform_get_drvdata(pdev);
-+
-+ disable_irq(qup->irq);
-+ qup_i2c_disable_clocks(qup);
-+ i2c_del_adapter(&qup->adap);
-+ pm_runtime_disable(qup->dev);
-+ pm_runtime_set_suspended(qup->dev);
-+ return 0;
-+}
-+
-+#ifdef CONFIG_PM
-+static int qup_i2c_pm_suspend_runtime(struct device *device)
-+{
-+ struct qup_i2c_dev *qup = dev_get_drvdata(device);
-+
-+ dev_dbg(device, "pm_runtime: suspending...\n");
-+ qup_i2c_disable_clocks(qup);
-+ return 0;
-+}
-+
-+static int qup_i2c_pm_resume_runtime(struct device *device)
-+{
-+ struct qup_i2c_dev *qup = dev_get_drvdata(device);
-+
-+ dev_dbg(device, "pm_runtime: resuming...\n");
-+ qup_i2c_enable_clocks(qup);
-+ return 0;
-+}
-+#endif
-+
-+#ifdef CONFIG_PM_SLEEP
-+static int qup_i2c_suspend(struct device *device)
-+{
-+ qup_i2c_pm_suspend_runtime(device);
-+ return 0;
-+}
-+
-+static int qup_i2c_resume(struct device *device)
-+{
-+ qup_i2c_pm_resume_runtime(device);
-+ pm_runtime_mark_last_busy(device);
-+ pm_request_autosuspend(device);
-+ return 0;
-+}
-+#endif
-+
-+static const struct dev_pm_ops qup_i2c_qup_pm_ops = {
-+ SET_SYSTEM_SLEEP_PM_OPS(
-+ qup_i2c_suspend,
-+ qup_i2c_resume)
-+ SET_RUNTIME_PM_OPS(
-+ qup_i2c_pm_suspend_runtime,
-+ qup_i2c_pm_resume_runtime,
-+ NULL)
-+};
-+
-+static const struct of_device_id qup_i2c_dt_match[] = {
-+ { .compatible = "qcom,i2c-qup-v1.1.1" },
-+ { .compatible = "qcom,i2c-qup-v2.1.1" },
-+ { .compatible = "qcom,i2c-qup-v2.2.1" },
-+ {}
-+};
-+MODULE_DEVICE_TABLE(of, qup_i2c_dt_match);
-+
-+static struct platform_driver qup_i2c_driver = {
-+ .probe = qup_i2c_probe,
-+ .remove = qup_i2c_remove,
-+ .driver = {
-+ .name = "i2c_qup",
-+ .owner = THIS_MODULE,
-+ .pm = &qup_i2c_qup_pm_ops,
-+ .of_match_table = qup_i2c_dt_match,
-+ },
-+};
-+
-+module_platform_driver(qup_i2c_driver);
-+
-+MODULE_LICENSE("GPL v2");
-+MODULE_ALIAS("platform:i2c_qup");
diff --git a/target/linux/ipq806x/patches/0061-i2c-qup-Add-device-tree-bindings-information.patch b/target/linux/ipq806x/patches/0061-i2c-qup-Add-device-tree-bindings-information.patch
deleted file mode 100644
index 2f9ee58..0000000
--- a/target/linux/ipq806x/patches/0061-i2c-qup-Add-device-tree-bindings-information.patch
+++ /dev/null
@@ -1,65 +0,0 @@
-From 81480a89c72d811376e9e040729721705b2a984d Mon Sep 17 00:00:00 2001
-From: "Ivan T. Ivanov" <iivanov@mm-sol.com>
-Date: Thu, 13 Mar 2014 19:07:42 -0700
-Subject: [PATCH 061/182] i2c: qup: Add device tree bindings information
-
-The Qualcomm Universal Peripherial (QUP) wraps I2C mini-core and
-provide input and output FIFO's for it. I2C controller can operate
-as master with supported bus speeds of 100Kbps and 400Kbps.
-
-Signed-off-by: Ivan T. Ivanov <iivanov@mm-sol.com>
-[bjorn: reformulated part of binding description
- added version to compatible
- cleaned up example]
-Signed-off-by: Bjorn Andersson <bjorn.andersson@sonymobile.com>
-Acked-by: Rob Herring <robh@kernel.org>
-[wsa: removed the dummy child node which was a confusing example]
-Signed-off-by: Wolfram Sang <wsa@the-dreams.de>
----
- .../devicetree/bindings/i2c/qcom,i2c-qup.txt | 40 ++++++++++++++++++++
- 1 file changed, 40 insertions(+)
- create mode 100644 Documentation/devicetree/bindings/i2c/qcom,i2c-qup.txt
-
---- /dev/null
-+++ b/Documentation/devicetree/bindings/i2c/qcom,i2c-qup.txt
-@@ -0,0 +1,40 @@
-+Qualcomm Universal Peripheral (QUP) I2C controller
-+
-+Required properties:
-+ - compatible: Should be:
-+ * "qcom,i2c-qup-v1.1.1" for 8660, 8960 and 8064.
-+ * "qcom,i2c-qup-v2.1.1" for 8974 v1.
-+ * "qcom,i2c-qup-v2.2.1" for 8974 v2 and later.
-+ - reg: Should contain QUP register address and length.
-+ - interrupts: Should contain I2C interrupt.
-+
-+ - clocks: A list of phandles + clock-specifiers, one for each entry in
-+ clock-names.
-+ - clock-names: Should contain:
-+ * "core" for the core clock
-+ * "iface" for the AHB clock
-+
-+ - #address-cells: Should be <1> Address cells for i2c device address
-+ - #size-cells: Should be <0> as i2c addresses have no size component
-+
-+Optional properties:
-+ - clock-frequency: Should specify the desired i2c bus clock frequency in Hz,
-+ defaults to 100kHz if omitted.
-+
-+Child nodes should conform to i2c bus binding.
-+
-+Example:
-+
-+ i2c@f9924000 {
-+ compatible = "qcom,i2c-qup-v2.2.1";
-+ reg = <0xf9924000 0x1000>;
-+ interrupts = <0 96 0>;
-+
-+ clocks = <&gcc GCC_BLSP1_QUP2_I2C_APPS_CLK>, <&gcc GCC_BLSP1_AHB_CLK>;
-+ clock-names = "core", "iface";
-+
-+ clock-frequency = <355000>;
-+
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+ };
diff --git a/target/linux/ipq806x/patches/0062-i2c-qup-off-by-ones-in-qup_i2c_probe.patch b/target/linux/ipq806x/patches/0062-i2c-qup-off-by-ones-in-qup_i2c_probe.patch
deleted file mode 100644
index 3feef66..0000000
--- a/target/linux/ipq806x/patches/0062-i2c-qup-off-by-ones-in-qup_i2c_probe.patch
+++ /dev/null
@@ -1,31 +0,0 @@
-From aa50d1b0d81e4a9509f15894ec64013aa5190b59 Mon Sep 17 00:00:00 2001
-From: Dan Carpenter <dan.carpenter@oracle.com>
-Date: Thu, 3 Apr 2014 10:22:54 +0300
-Subject: [PATCH 062/182] i2c: qup: off by ones in qup_i2c_probe()
-
-These should ">= ARRAY_SIZE()" instead of "> ARRAY_SIZE()".
-
-Fixes: 10c5a8425968 ('i2c: qup: New bus driver for the Qualcomm QUP I2C controller')
-Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
-Signed-off-by: Wolfram Sang <wsa@the-dreams.de>
----
- drivers/i2c/busses/i2c-qup.c | 4 ++--
- 1 file changed, 2 insertions(+), 2 deletions(-)
-
---- a/drivers/i2c/busses/i2c-qup.c
-+++ b/drivers/i2c/busses/i2c-qup.c
-@@ -633,12 +633,12 @@ static int qup_i2c_probe(struct platform
- * associated with each byte written/received
- */
- size = QUP_OUTPUT_BLOCK_SIZE(io_mode);
-- if (size > ARRAY_SIZE(blk_sizes))
-+ if (size >= ARRAY_SIZE(blk_sizes))
- return -EIO;
- qup->out_blk_sz = blk_sizes[size] / 2;
-
- size = QUP_INPUT_BLOCK_SIZE(io_mode);
-- if (size > ARRAY_SIZE(blk_sizes))
-+ if (size >= ARRAY_SIZE(blk_sizes))
- return -EIO;
- qup->in_blk_sz = blk_sizes[size] / 2;
-
diff --git a/target/linux/ipq806x/patches/0063-i2c-qup-use-proper-type-fro-clk_freq.patch b/target/linux/ipq806x/patches/0063-i2c-qup-use-proper-type-fro-clk_freq.patch
deleted file mode 100644
index 13ffab4..0000000
--- a/target/linux/ipq806x/patches/0063-i2c-qup-use-proper-type-fro-clk_freq.patch
+++ /dev/null
@@ -1,25 +0,0 @@
-From 62bdf6c11c9120543ba4831f0226bf51db1d1fc0 Mon Sep 17 00:00:00 2001
-From: Wolfram Sang <wsa@the-dreams.de>
-Date: Thu, 3 Apr 2014 11:30:33 +0200
-Subject: [PATCH 063/182] i2c: qup: use proper type fro clk_freq
-
-It is used with of_property_read_u32(), so it should be u32.
-
-Signed-off-by: Wolfram Sang <wsa@the-dreams.de>
-Acked-by: Bjorn Andersson <bjorn.andersson@sonymobile.com>
-Fixes: 10c5a8425968 ('i2c: qup: New bus driver for the Qualcomm QUP I2C controller')
----
- drivers/i2c/busses/i2c-qup.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/drivers/i2c/busses/i2c-qup.c
-+++ b/drivers/i2c/busses/i2c-qup.c
-@@ -562,7 +562,7 @@ static int qup_i2c_probe(struct platform
- u32 io_mode, hw_ver, size;
- int ret, fs_div, hs_div;
- int src_clk_freq;
-- int clk_freq = 100000;
-+ u32 clk_freq = 100000;
-
- qup = devm_kzalloc(&pdev->dev, sizeof(*qup), GFP_KERNEL);
- if (!qup)
diff --git a/target/linux/ipq806x/patches/0064-i2c-qup-Fix-pm_runtime_get_sync-usage.patch b/target/linux/ipq806x/patches/0064-i2c-qup-Fix-pm_runtime_get_sync-usage.patch
deleted file mode 100644
index 497b57e..0000000
--- a/target/linux/ipq806x/patches/0064-i2c-qup-Fix-pm_runtime_get_sync-usage.patch
+++ /dev/null
@@ -1,26 +0,0 @@
-From 82f2e53f207019c0d364d92515410be8dffd7524 Mon Sep 17 00:00:00 2001
-From: Andy Gross <agross@codeaurora.org>
-Date: Fri, 2 May 2014 20:54:29 -0500
-Subject: [PATCH 064/182] i2c: qup: Fix pm_runtime_get_sync usage
-
-This patch corrects the error check on the call to pm_runtime_get_sync.
-
-Signed-off-by: Andy Gross <agross@codeaurora.org>
-Reviewed-by: Ivan T. Ivanov <iivanov@mm-sol.com>
-Acked-by: Bjorn Andersson <bjorn.andersson@sonymobile.com>
-Signed-off-by: Wolfram Sang <wsa@the-dreams.de>
----
- drivers/i2c/busses/i2c-qup.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/drivers/i2c/busses/i2c-qup.c
-+++ b/drivers/i2c/busses/i2c-qup.c
-@@ -479,7 +479,7 @@ static int qup_i2c_xfer(struct i2c_adapt
- int ret, idx;
-
- ret = pm_runtime_get_sync(qup->dev);
-- if (ret)
-+ if (ret < 0)
- goto out;
-
- writel(1, qup->base + QUP_SW_RESET);
diff --git a/target/linux/ipq806x/patches/0065-spi-Add-Qualcomm-QUP-SPI-controller-support.patch b/target/linux/ipq806x/patches/0065-spi-Add-Qualcomm-QUP-SPI-controller-support.patch
deleted file mode 100644
index 3c52f24..0000000
--- a/target/linux/ipq806x/patches/0065-spi-Add-Qualcomm-QUP-SPI-controller-support.patch
+++ /dev/null
@@ -1,897 +0,0 @@
-From 24884115a6029995dba2561b1ee810f28a34271a Mon Sep 17 00:00:00 2001
-From: "Ivan T. Ivanov" <iivanov@mm-sol.com>
-Date: Thu, 13 Feb 2014 18:21:38 +0200
-Subject: [PATCH 065/182] spi: Add Qualcomm QUP SPI controller support
-
-Qualcomm Universal Peripheral (QUP) core is an AHB slave that
-provides a common data path (an output FIFO and an input FIFO)
-for serial peripheral interface (SPI) mini-core. SPI in master
-mode supports up to 50MHz, up to four chip selects, programmable
-data path from 4 bits to 32 bits and numerous protocol variants.
-
-Cc: Alok Chauhan <alokc@codeaurora.org>
-Cc: Gilad Avidov <gavidov@codeaurora.org>
-Cc: Kiran Gunda <kgunda@codeaurora.org>
-Cc: Sagar Dharia <sdharia@codeaurora.org>
-Cc: dsneddon@codeaurora.org
-Signed-off-by: Ivan T. Ivanov <iivanov@mm-sol.com>
-Signed-off-by: Mark Brown <broonie@linaro.org>
----
- drivers/spi/Kconfig | 13 +
- drivers/spi/Makefile | 1 +
- drivers/spi/spi-qup.c | 837 +++++++++++++++++++++++++++++++++++++++++++++++++
- 3 files changed, 851 insertions(+)
- create mode 100644 drivers/spi/spi-qup.c
-
---- a/drivers/spi/Kconfig
-+++ b/drivers/spi/Kconfig
-@@ -390,6 +390,19 @@ config SPI_RSPI
- help
- SPI driver for Renesas RSPI and QSPI blocks.
-
-+config SPI_QUP
-+ tristate "Qualcomm SPI controller with QUP interface"
-+ depends on ARCH_MSM_DT
-+ help
-+ Qualcomm Universal Peripheral (QUP) core is an AHB slave that
-+ provides a common data path (an output FIFO and an input FIFO)
-+ for serial peripheral interface (SPI) mini-core. SPI in master
-+ mode supports up to 50MHz, up to four chip selects, programmable
-+ data path from 4 bits to 32 bits and numerous protocol variants.
-+
-+ This driver can also be built as a module. If so, the module
-+ will be called spi_qup.
-+
- config SPI_S3C24XX
- tristate "Samsung S3C24XX series SPI"
- depends on ARCH_S3C24XX
---- a/drivers/spi/Makefile
-+++ b/drivers/spi/Makefile
-@@ -60,6 +60,7 @@ spi-pxa2xx-platform-$(CONFIG_SPI_PXA2XX_
- spi-pxa2xx-platform-$(CONFIG_SPI_PXA2XX_DMA) += spi-pxa2xx-dma.o
- obj-$(CONFIG_SPI_PXA2XX) += spi-pxa2xx-platform.o
- obj-$(CONFIG_SPI_PXA2XX_PCI) += spi-pxa2xx-pci.o
-+obj-$(CONFIG_SPI_QUP) += spi-qup.o
- obj-$(CONFIG_SPI_RSPI) += spi-rspi.o
- obj-$(CONFIG_SPI_S3C24XX) += spi-s3c24xx-hw.o
- spi-s3c24xx-hw-y := spi-s3c24xx.o
---- /dev/null
-+++ b/drivers/spi/spi-qup.c
-@@ -0,0 +1,837 @@
-+/*
-+ * Copyright (c) 2008-2014, The Linux foundation. All rights reserved.
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License rev 2 and
-+ * only rev 2 as published by the free Software foundation.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or fITNESS fOR A PARTICULAR PURPOSE. See the
-+ * GNU General Public License for more details.
-+ */
-+
-+#include <linux/clk.h>
-+#include <linux/delay.h>
-+#include <linux/err.h>
-+#include <linux/interrupt.h>
-+#include <linux/io.h>
-+#include <linux/list.h>
-+#include <linux/module.h>
-+#include <linux/of.h>
-+#include <linux/platform_device.h>
-+#include <linux/pm_runtime.h>
-+#include <linux/spi/spi.h>
-+
-+#define QUP_CONFIG 0x0000
-+#define QUP_STATE 0x0004
-+#define QUP_IO_M_MODES 0x0008
-+#define QUP_SW_RESET 0x000c
-+#define QUP_OPERATIONAL 0x0018
-+#define QUP_ERROR_FLAGS 0x001c
-+#define QUP_ERROR_FLAGS_EN 0x0020
-+#define QUP_OPERATIONAL_MASK 0x0028
-+#define QUP_HW_VERSION 0x0030
-+#define QUP_MX_OUTPUT_CNT 0x0100
-+#define QUP_OUTPUT_FIFO 0x0110
-+#define QUP_MX_WRITE_CNT 0x0150
-+#define QUP_MX_INPUT_CNT 0x0200
-+#define QUP_MX_READ_CNT 0x0208
-+#define QUP_INPUT_FIFO 0x0218
-+
-+#define SPI_CONFIG 0x0300
-+#define SPI_IO_CONTROL 0x0304
-+#define SPI_ERROR_FLAGS 0x0308
-+#define SPI_ERROR_FLAGS_EN 0x030c
-+
-+/* QUP_CONFIG fields */
-+#define QUP_CONFIG_SPI_MODE (1 << 8)
-+#define QUP_CONFIG_CLOCK_AUTO_GATE BIT(13)
-+#define QUP_CONFIG_NO_INPUT BIT(7)
-+#define QUP_CONFIG_NO_OUTPUT BIT(6)
-+#define QUP_CONFIG_N 0x001f
-+
-+/* QUP_STATE fields */
-+#define QUP_STATE_VALID BIT(2)
-+#define QUP_STATE_RESET 0
-+#define QUP_STATE_RUN 1
-+#define QUP_STATE_PAUSE 3
-+#define QUP_STATE_MASK 3
-+#define QUP_STATE_CLEAR 2
-+
-+#define QUP_HW_VERSION_2_1_1 0x20010001
-+
-+/* QUP_IO_M_MODES fields */
-+#define QUP_IO_M_PACK_EN BIT(15)
-+#define QUP_IO_M_UNPACK_EN BIT(14)
-+#define QUP_IO_M_INPUT_MODE_MASK_SHIFT 12
-+#define QUP_IO_M_OUTPUT_MODE_MASK_SHIFT 10
-+#define QUP_IO_M_INPUT_MODE_MASK (3 << QUP_IO_M_INPUT_MODE_MASK_SHIFT)
-+#define QUP_IO_M_OUTPUT_MODE_MASK (3 << QUP_IO_M_OUTPUT_MODE_MASK_SHIFT)
-+
-+#define QUP_IO_M_OUTPUT_BLOCK_SIZE(x) (((x) & (0x03 << 0)) >> 0)
-+#define QUP_IO_M_OUTPUT_FIFO_SIZE(x) (((x) & (0x07 << 2)) >> 2)
-+#define QUP_IO_M_INPUT_BLOCK_SIZE(x) (((x) & (0x03 << 5)) >> 5)
-+#define QUP_IO_M_INPUT_FIFO_SIZE(x) (((x) & (0x07 << 7)) >> 7)
-+
-+#define QUP_IO_M_MODE_FIFO 0
-+#define QUP_IO_M_MODE_BLOCK 1
-+#define QUP_IO_M_MODE_DMOV 2
-+#define QUP_IO_M_MODE_BAM 3
-+
-+/* QUP_OPERATIONAL fields */
-+#define QUP_OP_MAX_INPUT_DONE_FLAG BIT(11)
-+#define QUP_OP_MAX_OUTPUT_DONE_FLAG BIT(10)
-+#define QUP_OP_IN_SERVICE_FLAG BIT(9)
-+#define QUP_OP_OUT_SERVICE_FLAG BIT(8)
-+#define QUP_OP_IN_FIFO_FULL BIT(7)
-+#define QUP_OP_OUT_FIFO_FULL BIT(6)
-+#define QUP_OP_IN_FIFO_NOT_EMPTY BIT(5)
-+#define QUP_OP_OUT_FIFO_NOT_EMPTY BIT(4)
-+
-+/* QUP_ERROR_FLAGS and QUP_ERROR_FLAGS_EN fields */
-+#define QUP_ERROR_OUTPUT_OVER_RUN BIT(5)
-+#define QUP_ERROR_INPUT_UNDER_RUN BIT(4)
-+#define QUP_ERROR_OUTPUT_UNDER_RUN BIT(3)
-+#define QUP_ERROR_INPUT_OVER_RUN BIT(2)
-+
-+/* SPI_CONFIG fields */
-+#define SPI_CONFIG_HS_MODE BIT(10)
-+#define SPI_CONFIG_INPUT_FIRST BIT(9)
-+#define SPI_CONFIG_LOOPBACK BIT(8)
-+
-+/* SPI_IO_CONTROL fields */
-+#define SPI_IO_C_FORCE_CS BIT(11)
-+#define SPI_IO_C_CLK_IDLE_HIGH BIT(10)
-+#define SPI_IO_C_MX_CS_MODE BIT(8)
-+#define SPI_IO_C_CS_N_POLARITY_0 BIT(4)
-+#define SPI_IO_C_CS_SELECT(x) (((x) & 3) << 2)
-+#define SPI_IO_C_CS_SELECT_MASK 0x000c
-+#define SPI_IO_C_TRISTATE_CS BIT(1)
-+#define SPI_IO_C_NO_TRI_STATE BIT(0)
-+
-+/* SPI_ERROR_FLAGS and SPI_ERROR_FLAGS_EN fields */
-+#define SPI_ERROR_CLK_OVER_RUN BIT(1)
-+#define SPI_ERROR_CLK_UNDER_RUN BIT(0)
-+
-+#define SPI_NUM_CHIPSELECTS 4
-+
-+/* high speed mode is when bus rate is greater then 26MHz */
-+#define SPI_HS_MIN_RATE 26000000
-+#define SPI_MAX_RATE 50000000
-+
-+#define SPI_DELAY_THRESHOLD 1
-+#define SPI_DELAY_RETRY 10
-+
-+struct spi_qup_device {
-+ int select;
-+ u16 mode;
-+};
-+
-+struct spi_qup {
-+ void __iomem *base;
-+ struct device *dev;
-+ struct clk *cclk; /* core clock */
-+ struct clk *iclk; /* interface clock */
-+ int irq;
-+ u32 max_speed_hz;
-+ spinlock_t lock;
-+
-+ int in_fifo_sz;
-+ int out_fifo_sz;
-+ int in_blk_sz;
-+ int out_blk_sz;
-+
-+ struct spi_transfer *xfer;
-+ struct completion done;
-+ int error;
-+ int w_size; /* bytes per SPI word */
-+ int tx_bytes;
-+ int rx_bytes;
-+};
-+
-+
-+static inline bool spi_qup_is_valid_state(struct spi_qup *controller)
-+{
-+ u32 opstate = readl_relaxed(controller->base + QUP_STATE);
-+
-+ return opstate & QUP_STATE_VALID;
-+}
-+
-+static int spi_qup_set_state(struct spi_qup *controller, u32 state)
-+{
-+ unsigned long loop;
-+ u32 cur_state;
-+
-+ loop = 0;
-+ while (!spi_qup_is_valid_state(controller)) {
-+
-+ usleep_range(SPI_DELAY_THRESHOLD, SPI_DELAY_THRESHOLD * 2);
-+
-+ if (++loop > SPI_DELAY_RETRY)
-+ return -EIO;
-+ }
-+
-+ if (loop)
-+ dev_dbg(controller->dev, "invalid state for %ld,us %d\n",
-+ loop, state);
-+
-+ cur_state = readl_relaxed(controller->base + QUP_STATE);
-+ /*
-+ * Per spec: for PAUSE_STATE to RESET_STATE, two writes
-+ * of (b10) are required
-+ */
-+ if (((cur_state & QUP_STATE_MASK) == QUP_STATE_PAUSE) &&
-+ (state == QUP_STATE_RESET)) {
-+ writel_relaxed(QUP_STATE_CLEAR, controller->base + QUP_STATE);
-+ writel_relaxed(QUP_STATE_CLEAR, controller->base + QUP_STATE);
-+ } else {
-+ cur_state &= ~QUP_STATE_MASK;
-+ cur_state |= state;
-+ writel_relaxed(cur_state, controller->base + QUP_STATE);
-+ }
-+
-+ loop = 0;
-+ while (!spi_qup_is_valid_state(controller)) {
-+
-+ usleep_range(SPI_DELAY_THRESHOLD, SPI_DELAY_THRESHOLD * 2);
-+
-+ if (++loop > SPI_DELAY_RETRY)
-+ return -EIO;
-+ }
-+
-+ return 0;
-+}
-+
-+
-+static void spi_qup_fifo_read(struct spi_qup *controller,
-+ struct spi_transfer *xfer)
-+{
-+ u8 *rx_buf = xfer->rx_buf;
-+ u32 word, state;
-+ int idx, shift, w_size;
-+
-+ w_size = controller->w_size;
-+
-+ while (controller->rx_bytes < xfer->len) {
-+
-+ state = readl_relaxed(controller->base + QUP_OPERATIONAL);
-+ if (0 == (state & QUP_OP_IN_FIFO_NOT_EMPTY))
-+ break;
-+
-+ word = readl_relaxed(controller->base + QUP_INPUT_FIFO);
-+
-+ if (!rx_buf) {
-+ controller->rx_bytes += w_size;
-+ continue;
-+ }
-+
-+ for (idx = 0; idx < w_size; idx++, controller->rx_bytes++) {
-+ /*
-+ * The data format depends on bytes per SPI word:
-+ * 4 bytes: 0x12345678
-+ * 2 bytes: 0x00001234
-+ * 1 byte : 0x00000012
-+ */
-+ shift = BITS_PER_BYTE;
-+ shift *= (w_size - idx - 1);
-+ rx_buf[controller->rx_bytes] = word >> shift;
-+ }
-+ }
-+}
-+
-+static void spi_qup_fifo_write(struct spi_qup *controller,
-+ struct spi_transfer *xfer)
-+{
-+ const u8 *tx_buf = xfer->tx_buf;
-+ u32 word, state, data;
-+ int idx, w_size;
-+
-+ w_size = controller->w_size;
-+
-+ while (controller->tx_bytes < xfer->len) {
-+
-+ state = readl_relaxed(controller->base + QUP_OPERATIONAL);
-+ if (state & QUP_OP_OUT_FIFO_FULL)
-+ break;
-+
-+ word = 0;
-+ for (idx = 0; idx < w_size; idx++, controller->tx_bytes++) {
-+
-+ if (!tx_buf) {
-+ controller->tx_bytes += w_size;
-+ break;
-+ }
-+
-+ data = tx_buf[controller->tx_bytes];
-+ word |= data << (BITS_PER_BYTE * (3 - idx));
-+ }
-+
-+ writel_relaxed(word, controller->base + QUP_OUTPUT_FIFO);
-+ }
-+}
-+
-+static irqreturn_t spi_qup_qup_irq(int irq, void *dev_id)
-+{
-+ struct spi_qup *controller = dev_id;
-+ struct spi_transfer *xfer;
-+ u32 opflags, qup_err, spi_err;
-+ unsigned long flags;
-+ int error = 0;
-+
-+ spin_lock_irqsave(&controller->lock, flags);
-+ xfer = controller->xfer;
-+ controller->xfer = NULL;
-+ spin_unlock_irqrestore(&controller->lock, flags);
-+
-+ qup_err = readl_relaxed(controller->base + QUP_ERROR_FLAGS);
-+ spi_err = readl_relaxed(controller->base + SPI_ERROR_FLAGS);
-+ opflags = readl_relaxed(controller->base + QUP_OPERATIONAL);
-+
-+ writel_relaxed(qup_err, controller->base + QUP_ERROR_FLAGS);
-+ writel_relaxed(spi_err, controller->base + SPI_ERROR_FLAGS);
-+ writel_relaxed(opflags, controller->base + QUP_OPERATIONAL);
-+
-+ if (!xfer) {
-+ dev_err_ratelimited(controller->dev, "unexpected irq %x08 %x08 %x08\n",
-+ qup_err, spi_err, opflags);
-+ return IRQ_HANDLED;
-+ }
-+
-+ if (qup_err) {
-+ if (qup_err & QUP_ERROR_OUTPUT_OVER_RUN)
-+ dev_warn(controller->dev, "OUTPUT_OVER_RUN\n");
-+ if (qup_err & QUP_ERROR_INPUT_UNDER_RUN)
-+ dev_warn(controller->dev, "INPUT_UNDER_RUN\n");
-+ if (qup_err & QUP_ERROR_OUTPUT_UNDER_RUN)
-+ dev_warn(controller->dev, "OUTPUT_UNDER_RUN\n");
-+ if (qup_err & QUP_ERROR_INPUT_OVER_RUN)
-+ dev_warn(controller->dev, "INPUT_OVER_RUN\n");
-+
-+ error = -EIO;
-+ }
-+
-+ if (spi_err) {
-+ if (spi_err & SPI_ERROR_CLK_OVER_RUN)
-+ dev_warn(controller->dev, "CLK_OVER_RUN\n");
-+ if (spi_err & SPI_ERROR_CLK_UNDER_RUN)
-+ dev_warn(controller->dev, "CLK_UNDER_RUN\n");
-+
-+ error = -EIO;
-+ }
-+
-+ if (opflags & QUP_OP_IN_SERVICE_FLAG)
-+ spi_qup_fifo_read(controller, xfer);
-+
-+ if (opflags & QUP_OP_OUT_SERVICE_FLAG)
-+ spi_qup_fifo_write(controller, xfer);
-+
-+ spin_lock_irqsave(&controller->lock, flags);
-+ controller->error = error;
-+ controller->xfer = xfer;
-+ spin_unlock_irqrestore(&controller->lock, flags);
-+
-+ if (controller->rx_bytes == xfer->len || error)
-+ complete(&controller->done);
-+
-+ return IRQ_HANDLED;
-+}
-+
-+
-+/* set clock freq ... bits per word */
-+static int spi_qup_io_config(struct spi_qup *controller,
-+ struct spi_qup_device *chip,
-+ struct spi_transfer *xfer)
-+{
-+ u32 config, iomode, mode;
-+ int ret, n_words, w_size;
-+
-+ if (chip->mode & SPI_LOOP && xfer->len > controller->in_fifo_sz) {
-+ dev_err(controller->dev, "too big size for loopback %d > %d\n",
-+ xfer->len, controller->in_fifo_sz);
-+ return -EIO;
-+ }
-+
-+ ret = clk_set_rate(controller->cclk, xfer->speed_hz);
-+ if (ret) {
-+ dev_err(controller->dev, "fail to set frequency %d",
-+ xfer->speed_hz);
-+ return -EIO;
-+ }
-+
-+ if (spi_qup_set_state(controller, QUP_STATE_RESET)) {
-+ dev_err(controller->dev, "cannot set RESET state\n");
-+ return -EIO;
-+ }
-+
-+ w_size = 4;
-+ if (xfer->bits_per_word <= 8)
-+ w_size = 1;
-+ else if (xfer->bits_per_word <= 16)
-+ w_size = 2;
-+
-+ n_words = xfer->len / w_size;
-+ controller->w_size = w_size;
-+
-+ if (n_words <= controller->in_fifo_sz) {
-+ mode = QUP_IO_M_MODE_FIFO;
-+ writel_relaxed(n_words, controller->base + QUP_MX_READ_CNT);
-+ writel_relaxed(n_words, controller->base + QUP_MX_WRITE_CNT);
-+ /* must be zero for FIFO */
-+ writel_relaxed(0, controller->base + QUP_MX_INPUT_CNT);
-+ writel_relaxed(0, controller->base + QUP_MX_OUTPUT_CNT);
-+ } else {
-+ mode = QUP_IO_M_MODE_BLOCK;
-+ writel_relaxed(n_words, controller->base + QUP_MX_INPUT_CNT);
-+ writel_relaxed(n_words, controller->base + QUP_MX_OUTPUT_CNT);
-+ /* must be zero for BLOCK and BAM */
-+ writel_relaxed(0, controller->base + QUP_MX_READ_CNT);
-+ writel_relaxed(0, controller->base + QUP_MX_WRITE_CNT);
-+ }
-+
-+ iomode = readl_relaxed(controller->base + QUP_IO_M_MODES);
-+ /* Set input and output transfer mode */
-+ iomode &= ~(QUP_IO_M_INPUT_MODE_MASK | QUP_IO_M_OUTPUT_MODE_MASK);
-+ iomode &= ~(QUP_IO_M_PACK_EN | QUP_IO_M_UNPACK_EN);
-+ iomode |= (mode << QUP_IO_M_OUTPUT_MODE_MASK_SHIFT);
-+ iomode |= (mode << QUP_IO_M_INPUT_MODE_MASK_SHIFT);
-+
-+ writel_relaxed(iomode, controller->base + QUP_IO_M_MODES);
-+
-+ config = readl_relaxed(controller->base + SPI_CONFIG);
-+
-+ if (chip->mode & SPI_LOOP)
-+ config |= SPI_CONFIG_LOOPBACK;
-+ else
-+ config &= ~SPI_CONFIG_LOOPBACK;
-+
-+ if (chip->mode & SPI_CPHA)
-+ config &= ~SPI_CONFIG_INPUT_FIRST;
-+ else
-+ config |= SPI_CONFIG_INPUT_FIRST;
-+
-+ /*
-+ * HS_MODE improves signal stability for spi-clk high rates,
-+ * but is invalid in loop back mode.
-+ */
-+ if ((xfer->speed_hz >= SPI_HS_MIN_RATE) && !(chip->mode & SPI_LOOP))
-+ config |= SPI_CONFIG_HS_MODE;
-+ else
-+ config &= ~SPI_CONFIG_HS_MODE;
-+
-+ writel_relaxed(config, controller->base + SPI_CONFIG);
-+
-+ config = readl_relaxed(controller->base + QUP_CONFIG);
-+ config &= ~(QUP_CONFIG_NO_INPUT | QUP_CONFIG_NO_OUTPUT | QUP_CONFIG_N);
-+ config |= xfer->bits_per_word - 1;
-+ config |= QUP_CONFIG_SPI_MODE;
-+ writel_relaxed(config, controller->base + QUP_CONFIG);
-+
-+ writel_relaxed(0, controller->base + QUP_OPERATIONAL_MASK);
-+ return 0;
-+}
-+
-+static void spi_qup_set_cs(struct spi_device *spi, bool enable)
-+{
-+ struct spi_qup *controller = spi_master_get_devdata(spi->master);
-+ struct spi_qup_device *chip = spi_get_ctldata(spi);
-+
-+ u32 iocontol, mask;
-+
-+ iocontol = readl_relaxed(controller->base + SPI_IO_CONTROL);
-+
-+ /* Disable auto CS toggle and use manual */
-+ iocontol &= ~SPI_IO_C_MX_CS_MODE;
-+ iocontol |= SPI_IO_C_FORCE_CS;
-+
-+ iocontol &= ~SPI_IO_C_CS_SELECT_MASK;
-+ iocontol |= SPI_IO_C_CS_SELECT(chip->select);
-+
-+ mask = SPI_IO_C_CS_N_POLARITY_0 << chip->select;
-+
-+ if (enable)
-+ iocontol |= mask;
-+ else
-+ iocontol &= ~mask;
-+
-+ writel_relaxed(iocontol, controller->base + SPI_IO_CONTROL);
-+}
-+
-+static int spi_qup_transfer_one(struct spi_master *master,
-+ struct spi_device *spi,
-+ struct spi_transfer *xfer)
-+{
-+ struct spi_qup *controller = spi_master_get_devdata(master);
-+ struct spi_qup_device *chip = spi_get_ctldata(spi);
-+ unsigned long timeout, flags;
-+ int ret = -EIO;
-+
-+ ret = spi_qup_io_config(controller, chip, xfer);
-+ if (ret)
-+ return ret;
-+
-+ timeout = DIV_ROUND_UP(xfer->speed_hz, MSEC_PER_SEC);
-+ timeout = DIV_ROUND_UP(xfer->len * 8, timeout);
-+ timeout = 100 * msecs_to_jiffies(timeout);
-+
-+ reinit_completion(&controller->done);
-+
-+ spin_lock_irqsave(&controller->lock, flags);
-+ controller->xfer = xfer;
-+ controller->error = 0;
-+ controller->rx_bytes = 0;
-+ controller->tx_bytes = 0;
-+ spin_unlock_irqrestore(&controller->lock, flags);
-+
-+ if (spi_qup_set_state(controller, QUP_STATE_RUN)) {
-+ dev_warn(controller->dev, "cannot set RUN state\n");
-+ goto exit;
-+ }
-+
-+ if (spi_qup_set_state(controller, QUP_STATE_PAUSE)) {
-+ dev_warn(controller->dev, "cannot set PAUSE state\n");
-+ goto exit;
-+ }
-+
-+ spi_qup_fifo_write(controller, xfer);
-+
-+ if (spi_qup_set_state(controller, QUP_STATE_RUN)) {
-+ dev_warn(controller->dev, "cannot set EXECUTE state\n");
-+ goto exit;
-+ }
-+
-+ if (!wait_for_completion_timeout(&controller->done, timeout))
-+ ret = -ETIMEDOUT;
-+exit:
-+ spi_qup_set_state(controller, QUP_STATE_RESET);
-+ spin_lock_irqsave(&controller->lock, flags);
-+ controller->xfer = NULL;
-+ if (!ret)
-+ ret = controller->error;
-+ spin_unlock_irqrestore(&controller->lock, flags);
-+ return ret;
-+}
-+
-+static int spi_qup_setup(struct spi_device *spi)
-+{
-+ struct spi_qup *controller = spi_master_get_devdata(spi->master);
-+ struct spi_qup_device *chip = spi_get_ctldata(spi);
-+
-+ if (spi->chip_select >= spi->master->num_chipselect) {
-+ dev_err(controller->dev, "invalid chip_select %d\n",
-+ spi->chip_select);
-+ return -EINVAL;
-+ }
-+
-+ if (spi->max_speed_hz > controller->max_speed_hz) {
-+ dev_err(controller->dev, "invalid max_speed_hz %d\n",
-+ spi->max_speed_hz);
-+ return -EINVAL;
-+ }
-+
-+ if (!chip) {
-+ /* First setup */
-+ chip = kzalloc(sizeof(*chip), GFP_KERNEL);
-+ if (!chip) {
-+ dev_err(controller->dev, "no memory for chip data\n");
-+ return -ENOMEM;
-+ }
-+
-+ chip->mode = spi->mode;
-+ chip->select = spi->chip_select;
-+ spi_set_ctldata(spi, chip);
-+ }
-+
-+ return 0;
-+}
-+
-+static void spi_qup_cleanup(struct spi_device *spi)
-+{
-+ struct spi_qup_device *chip = spi_get_ctldata(spi);
-+
-+ if (!chip)
-+ return;
-+
-+ spi_set_ctldata(spi, NULL);
-+ kfree(chip);
-+}
-+
-+static int spi_qup_probe(struct platform_device *pdev)
-+{
-+ struct spi_master *master;
-+ struct clk *iclk, *cclk;
-+ struct spi_qup *controller;
-+ struct resource *res;
-+ struct device *dev;
-+ void __iomem *base;
-+ u32 data, max_freq, iomode;
-+ int ret, irq, size;
-+
-+ dev = &pdev->dev;
-+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-+ base = devm_ioremap_resource(dev, res);
-+ if (IS_ERR(base))
-+ return PTR_ERR(base);
-+
-+ irq = platform_get_irq(pdev, 0);
-+
-+ if (irq < 0)
-+ return irq;
-+
-+ cclk = devm_clk_get(dev, "core");
-+ if (IS_ERR(cclk))
-+ return PTR_ERR(cclk);
-+
-+ iclk = devm_clk_get(dev, "iface");
-+ if (IS_ERR(iclk))
-+ return PTR_ERR(iclk);
-+
-+ /* This is optional parameter */
-+ if (of_property_read_u32(dev->of_node, "spi-max-frequency", &max_freq))
-+ max_freq = SPI_MAX_RATE;
-+
-+ if (!max_freq || max_freq > SPI_MAX_RATE) {
-+ dev_err(dev, "invalid clock frequency %d\n", max_freq);
-+ return -ENXIO;
-+ }
-+
-+ ret = clk_prepare_enable(cclk);
-+ if (ret) {
-+ dev_err(dev, "cannot enable core clock\n");
-+ return ret;
-+ }
-+
-+ ret = clk_prepare_enable(iclk);
-+ if (ret) {
-+ clk_disable_unprepare(cclk);
-+ dev_err(dev, "cannot enable iface clock\n");
-+ return ret;
-+ }
-+
-+ data = readl_relaxed(base + QUP_HW_VERSION);
-+
-+ if (data < QUP_HW_VERSION_2_1_1) {
-+ clk_disable_unprepare(cclk);
-+ clk_disable_unprepare(iclk);
-+ dev_err(dev, "v.%08x is not supported\n", data);
-+ return -ENXIO;
-+ }
-+
-+ master = spi_alloc_master(dev, sizeof(struct spi_qup));
-+ if (!master) {
-+ clk_disable_unprepare(cclk);
-+ clk_disable_unprepare(iclk);
-+ dev_err(dev, "cannot allocate master\n");
-+ return -ENOMEM;
-+ }
-+
-+ master->bus_num = pdev->id;
-+ master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH | SPI_LOOP;
-+ master->num_chipselect = SPI_NUM_CHIPSELECTS;
-+ master->bits_per_word_mask = SPI_BPW_RANGE_MASK(4, 32);
-+ master->setup = spi_qup_setup;
-+ master->cleanup = spi_qup_cleanup;
-+ master->set_cs = spi_qup_set_cs;
-+ master->transfer_one = spi_qup_transfer_one;
-+ master->dev.of_node = pdev->dev.of_node;
-+ master->auto_runtime_pm = true;
-+
-+ platform_set_drvdata(pdev, master);
-+
-+ controller = spi_master_get_devdata(master);
-+
-+ controller->dev = dev;
-+ controller->base = base;
-+ controller->iclk = iclk;
-+ controller->cclk = cclk;
-+ controller->irq = irq;
-+ controller->max_speed_hz = max_freq;
-+
-+ spin_lock_init(&controller->lock);
-+ init_completion(&controller->done);
-+
-+ iomode = readl_relaxed(base + QUP_IO_M_MODES);
-+
-+ size = QUP_IO_M_OUTPUT_BLOCK_SIZE(iomode);
-+ if (size)
-+ controller->out_blk_sz = size * 16;
-+ else
-+ controller->out_blk_sz = 4;
-+
-+ size = QUP_IO_M_INPUT_BLOCK_SIZE(iomode);
-+ if (size)
-+ controller->in_blk_sz = size * 16;
-+ else
-+ controller->in_blk_sz = 4;
-+
-+ size = QUP_IO_M_OUTPUT_FIFO_SIZE(iomode);
-+ controller->out_fifo_sz = controller->out_blk_sz * (2 << size);
-+
-+ size = QUP_IO_M_INPUT_FIFO_SIZE(iomode);
-+ controller->in_fifo_sz = controller->in_blk_sz * (2 << size);
-+
-+ dev_info(dev, "v.%08x IN:block:%d, fifo:%d, OUT:block:%d, fifo:%d\n",
-+ data, controller->in_blk_sz, controller->in_fifo_sz,
-+ controller->out_blk_sz, controller->out_fifo_sz);
-+
-+ writel_relaxed(1, base + QUP_SW_RESET);
-+
-+ ret = spi_qup_set_state(controller, QUP_STATE_RESET);
-+ if (ret) {
-+ dev_err(dev, "cannot set RESET state\n");
-+ goto error;
-+ }
-+
-+ writel_relaxed(0, base + QUP_OPERATIONAL);
-+ writel_relaxed(0, base + QUP_IO_M_MODES);
-+ writel_relaxed(0, base + QUP_OPERATIONAL_MASK);
-+ writel_relaxed(SPI_ERROR_CLK_UNDER_RUN | SPI_ERROR_CLK_OVER_RUN,
-+ base + SPI_ERROR_FLAGS_EN);
-+
-+ writel_relaxed(0, base + SPI_CONFIG);
-+ writel_relaxed(SPI_IO_C_NO_TRI_STATE, base + SPI_IO_CONTROL);
-+
-+ ret = devm_request_irq(dev, irq, spi_qup_qup_irq,
-+ IRQF_TRIGGER_HIGH, pdev->name, controller);
-+ if (ret)
-+ goto error;
-+
-+ ret = devm_spi_register_master(dev, master);
-+ if (ret)
-+ goto error;
-+
-+ pm_runtime_set_autosuspend_delay(dev, MSEC_PER_SEC);
-+ pm_runtime_use_autosuspend(dev);
-+ pm_runtime_set_active(dev);
-+ pm_runtime_enable(dev);
-+ return 0;
-+
-+error:
-+ clk_disable_unprepare(cclk);
-+ clk_disable_unprepare(iclk);
-+ spi_master_put(master);
-+ return ret;
-+}
-+
-+#ifdef CONFIG_PM_RUNTIME
-+static int spi_qup_pm_suspend_runtime(struct device *device)
-+{
-+ struct spi_master *master = dev_get_drvdata(device);
-+ struct spi_qup *controller = spi_master_get_devdata(master);
-+ u32 config;
-+
-+ /* Enable clocks auto gaiting */
-+ config = readl(controller->base + QUP_CONFIG);
-+ config |= QUP_CLOCK_AUTO_GATE;
-+ writel_relaxed(config, controller->base + QUP_CONFIG);
-+ return 0;
-+}
-+
-+static int spi_qup_pm_resume_runtime(struct device *device)
-+{
-+ struct spi_master *master = dev_get_drvdata(device);
-+ struct spi_qup *controller = spi_master_get_devdata(master);
-+ u32 config;
-+
-+ /* Disable clocks auto gaiting */
-+ config = readl_relaxed(controller->base + QUP_CONFIG);
-+ config &= ~QUP_CLOCK_AUTO_GATE;
-+ writel_relaxed(config, controller->base + QUP_CONFIG);
-+ return 0;
-+}
-+#endif /* CONFIG_PM_RUNTIME */
-+
-+#ifdef CONFIG_PM_SLEEP
-+static int spi_qup_suspend(struct device *device)
-+{
-+ struct spi_master *master = dev_get_drvdata(device);
-+ struct spi_qup *controller = spi_master_get_devdata(master);
-+ int ret;
-+
-+ ret = spi_master_suspend(master);
-+ if (ret)
-+ return ret;
-+
-+ ret = spi_qup_set_state(controller, QUP_STATE_RESET);
-+ if (ret)
-+ return ret;
-+
-+ clk_disable_unprepare(controller->cclk);
-+ clk_disable_unprepare(controller->iclk);
-+ return 0;
-+}
-+
-+static int spi_qup_resume(struct device *device)
-+{
-+ struct spi_master *master = dev_get_drvdata(device);
-+ struct spi_qup *controller = spi_master_get_devdata(master);
-+ int ret;
-+
-+ ret = clk_prepare_enable(controller->iclk);
-+ if (ret)
-+ return ret;
-+
-+ ret = clk_prepare_enable(controller->cclk);
-+ if (ret)
-+ return ret;
-+
-+ ret = spi_qup_set_state(controller, QUP_STATE_RESET);
-+ if (ret)
-+ return ret;
-+
-+ return spi_master_resume(master);
-+}
-+#endif /* CONFIG_PM_SLEEP */
-+
-+static int spi_qup_remove(struct platform_device *pdev)
-+{
-+ struct spi_master *master = dev_get_drvdata(&pdev->dev);
-+ struct spi_qup *controller = spi_master_get_devdata(master);
-+ int ret;
-+
-+ ret = pm_runtime_get_sync(&pdev->dev);
-+ if (ret)
-+ return ret;
-+
-+ ret = spi_qup_set_state(controller, QUP_STATE_RESET);
-+ if (ret)
-+ return ret;
-+
-+ clk_disable_unprepare(controller->cclk);
-+ clk_disable_unprepare(controller->iclk);
-+
-+ pm_runtime_put_noidle(&pdev->dev);
-+ pm_runtime_disable(&pdev->dev);
-+ spi_master_put(master);
-+ return 0;
-+}
-+
-+static struct of_device_id spi_qup_dt_match[] = {
-+ { .compatible = "qcom,spi-qup-v2.1.1", },
-+ { .compatible = "qcom,spi-qup-v2.2.1", },
-+ { }
-+};
-+MODULE_DEVICE_TABLE(of, spi_qup_dt_match);
-+
-+static const struct dev_pm_ops spi_qup_dev_pm_ops = {
-+ SET_SYSTEM_SLEEP_PM_OPS(spi_qup_suspend, spi_qup_resume)
-+ SET_RUNTIME_PM_OPS(spi_qup_pm_suspend_runtime,
-+ spi_qup_pm_resume_runtime,
-+ NULL)
-+};
-+
-+static struct platform_driver spi_qup_driver = {
-+ .driver = {
-+ .name = "spi_qup",
-+ .owner = THIS_MODULE,
-+ .pm = &spi_qup_dev_pm_ops,
-+ .of_match_table = spi_qup_dt_match,
-+ },
-+ .probe = spi_qup_probe,
-+ .remove = spi_qup_remove,
-+};
-+module_platform_driver(spi_qup_driver);
-+
-+MODULE_LICENSE("GPL v2");
-+MODULE_VERSION("0.4");
-+MODULE_ALIAS("platform:spi_qup");
diff --git a/target/linux/ipq806x/patches/0066-spi-qup-Add-device-tree-bindings-information.patch b/target/linux/ipq806x/patches/0066-spi-qup-Add-device-tree-bindings-information.patch
deleted file mode 100644
index 079d59f..0000000
--- a/target/linux/ipq806x/patches/0066-spi-qup-Add-device-tree-bindings-information.patch
+++ /dev/null
@@ -1,105 +0,0 @@
-From a8e8c90a3cc81c6a7a44ff7fb18ceb71978c9155 Mon Sep 17 00:00:00 2001
-From: "Ivan T. Ivanov" <iivanov@mm-sol.com>
-Date: Thu, 13 Feb 2014 18:21:23 +0200
-Subject: [PATCH 066/182] spi: qup: Add device tree bindings information
-
-The Qualcomm Universal Peripheral (QUP) core is an
-AHB slave that provides a common data path (an output
-FIFO and an input FIFO) for serial peripheral interface
-(SPI) mini-core.
-
-Signed-off-by: Ivan T. Ivanov <iivanov@mm-sol.com>
-Signed-off-by: Mark Brown <broonie@linaro.org>
----
- .../devicetree/bindings/spi/qcom,spi-qup.txt | 85 ++++++++++++++++++++
- 1 file changed, 85 insertions(+)
- create mode 100644 Documentation/devicetree/bindings/spi/qcom,spi-qup.txt
-
---- /dev/null
-+++ b/Documentation/devicetree/bindings/spi/qcom,spi-qup.txt
-@@ -0,0 +1,85 @@
-+Qualcomm Universal Peripheral (QUP) Serial Peripheral Interface (SPI)
-+
-+The QUP core is an AHB slave that provides a common data path (an output FIFO
-+and an input FIFO) for serial peripheral interface (SPI) mini-core.
-+
-+SPI in master mode supports up to 50MHz, up to four chip selects, programmable
-+data path from 4 bits to 32 bits and numerous protocol variants.
-+
-+Required properties:
-+- compatible: Should contain "qcom,spi-qup-v2.1.1" or "qcom,spi-qup-v2.2.1"
-+- reg: Should contain base register location and length
-+- interrupts: Interrupt number used by this controller
-+
-+- clocks: Should contain the core clock and the AHB clock.
-+- clock-names: Should be "core" for the core clock and "iface" for the
-+ AHB clock.
-+
-+- #address-cells: Number of cells required to define a chip select
-+ address on the SPI bus. Should be set to 1.
-+- #size-cells: Should be zero.
-+
-+Optional properties:
-+- spi-max-frequency: Specifies maximum SPI clock frequency,
-+ Units - Hz. Definition as per
-+ Documentation/devicetree/bindings/spi/spi-bus.txt
-+
-+SPI slave nodes must be children of the SPI master node and can contain
-+properties described in Documentation/devicetree/bindings/spi/spi-bus.txt
-+
-+Example:
-+
-+ spi_8: spi@f9964000 { /* BLSP2 QUP2 */
-+
-+ compatible = "qcom,spi-qup-v2";
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+ reg = <0xf9964000 0x1000>;
-+ interrupts = <0 102 0>;
-+ spi-max-frequency = <19200000>;
-+
-+ clocks = <&gcc GCC_BLSP2_QUP2_SPI_APPS_CLK>, <&gcc GCC_BLSP2_AHB_CLK>;
-+ clock-names = "core", "iface";
-+
-+ pinctrl-names = "default";
-+ pinctrl-0 = <&spi8_default>;
-+
-+ device@0 {
-+ compatible = "arm,pl022-dummy";
-+ #address-cells = <1>;
-+ #size-cells = <1>;
-+ reg = <0>; /* Chip select 0 */
-+ spi-max-frequency = <19200000>;
-+ spi-cpol;
-+ };
-+
-+ device@1 {
-+ compatible = "arm,pl022-dummy";
-+ #address-cells = <1>;
-+ #size-cells = <1>;
-+ reg = <1>; /* Chip select 1 */
-+ spi-max-frequency = <9600000>;
-+ spi-cpha;
-+ };
-+
-+ device@2 {
-+ compatible = "arm,pl022-dummy";
-+ #address-cells = <1>;
-+ #size-cells = <1>;
-+ reg = <2>; /* Chip select 2 */
-+ spi-max-frequency = <19200000>;
-+ spi-cpol;
-+ spi-cpha;
-+ };
-+
-+ device@3 {
-+ compatible = "arm,pl022-dummy";
-+ #address-cells = <1>;
-+ #size-cells = <1>;
-+ reg = <3>; /* Chip select 3 */
-+ spi-max-frequency = <19200000>;
-+ spi-cpol;
-+ spi-cpha;
-+ spi-cs-high;
-+ };
-+ };
diff --git a/target/linux/ipq806x/patches/0067-spi-qup-Remove-spi_master_put-in-spi_qup_remove.patch b/target/linux/ipq806x/patches/0067-spi-qup-Remove-spi_master_put-in-spi_qup_remove.patch
deleted file mode 100644
index 128eb23..0000000
--- a/target/linux/ipq806x/patches/0067-spi-qup-Remove-spi_master_put-in-spi_qup_remove.patch
+++ /dev/null
@@ -1,25 +0,0 @@
-From c6a3f7bda60cfd78c2b05e8b2ec0fbf0d39da9ea Mon Sep 17 00:00:00 2001
-From: Axel Lin <axel.lin@ingics.com>
-Date: Fri, 21 Feb 2014 09:33:16 +0800
-Subject: [PATCH 067/182] spi: qup: Remove spi_master_put in spi_qup_remove
-
-This driver uses devm_spi_register_master() so don't explicitly call
-spi_master_put() in spi_qup_remove().
-
-Signed-off-by: Axel Lin <axel.lin@ingics.com>
-Acked-by: Ivan T. Ivanov <iivanov@mm-sol.com>
-Signed-off-by: Mark Brown <broonie@linaro.org>
----
- drivers/spi/spi-qup.c | 1 -
- 1 file changed, 1 deletion(-)
-
---- a/drivers/spi/spi-qup.c
-+++ b/drivers/spi/spi-qup.c
-@@ -802,7 +802,6 @@ static int spi_qup_remove(struct platfor
-
- pm_runtime_put_noidle(&pdev->dev);
- pm_runtime_disable(&pdev->dev);
-- spi_master_put(master);
- return 0;
- }
-
diff --git a/target/linux/ipq806x/patches/0068-spi-qup-Convert-ot-let-spi-core-handle-checking-tran.patch b/target/linux/ipq806x/patches/0068-spi-qup-Convert-ot-let-spi-core-handle-checking-tran.patch
deleted file mode 100644
index 4b025b5..0000000
--- a/target/linux/ipq806x/patches/0068-spi-qup-Convert-ot-let-spi-core-handle-checking-tran.patch
+++ /dev/null
@@ -1,64 +0,0 @@
-From a4b122f945c564e47a42a9665b484785e86648de Mon Sep 17 00:00:00 2001
-From: Axel Lin <axel.lin@ingics.com>
-Date: Fri, 21 Feb 2014 09:34:16 +0800
-Subject: [PATCH 068/182] spi: qup: Convert ot let spi core handle checking
- transfer speed
-
-Set master->max_speed_hz then spi core will handle checking transfer speed.
-So we can remove the same checking in this driver.
-
-Also remove checking spi->chip_select in spi_qup_setup(), the checking is done
-by spi core.
-
-Signed-off-by: Axel Lin <axel.lin@ingics.com>
-Acked-by: Ivan T. Ivanov <iivanov@mm-sol.com>
-Signed-off-by: Mark Brown <broonie@linaro.org>
----
- drivers/spi/spi-qup.c | 15 +--------------
- 1 file changed, 1 insertion(+), 14 deletions(-)
-
---- a/drivers/spi/spi-qup.c
-+++ b/drivers/spi/spi-qup.c
-@@ -134,7 +134,6 @@ struct spi_qup {
- struct clk *cclk; /* core clock */
- struct clk *iclk; /* interface clock */
- int irq;
-- u32 max_speed_hz;
- spinlock_t lock;
-
- int in_fifo_sz;
-@@ -517,18 +516,6 @@ static int spi_qup_setup(struct spi_devi
- struct spi_qup *controller = spi_master_get_devdata(spi->master);
- struct spi_qup_device *chip = spi_get_ctldata(spi);
-
-- if (spi->chip_select >= spi->master->num_chipselect) {
-- dev_err(controller->dev, "invalid chip_select %d\n",
-- spi->chip_select);
-- return -EINVAL;
-- }
--
-- if (spi->max_speed_hz > controller->max_speed_hz) {
-- dev_err(controller->dev, "invalid max_speed_hz %d\n",
-- spi->max_speed_hz);
-- return -EINVAL;
-- }
--
- if (!chip) {
- /* First setup */
- chip = kzalloc(sizeof(*chip), GFP_KERNEL);
-@@ -629,6 +616,7 @@ static int spi_qup_probe(struct platform
- master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH | SPI_LOOP;
- master->num_chipselect = SPI_NUM_CHIPSELECTS;
- master->bits_per_word_mask = SPI_BPW_RANGE_MASK(4, 32);
-+ master->max_speed_hz = max_freq;
- master->setup = spi_qup_setup;
- master->cleanup = spi_qup_cleanup;
- master->set_cs = spi_qup_set_cs;
-@@ -645,7 +633,6 @@ static int spi_qup_probe(struct platform
- controller->iclk = iclk;
- controller->cclk = cclk;
- controller->irq = irq;
-- controller->max_speed_hz = max_freq;
-
- spin_lock_init(&controller->lock);
- init_completion(&controller->done);
diff --git a/target/linux/ipq806x/patches/0069-spi-qup-Fix-build-error-due-to-a-typo.patch b/target/linux/ipq806x/patches/0069-spi-qup-Fix-build-error-due-to-a-typo.patch
deleted file mode 100644
index 4209485..0000000
--- a/target/linux/ipq806x/patches/0069-spi-qup-Fix-build-error-due-to-a-typo.patch
+++ /dev/null
@@ -1,43 +0,0 @@
-From df7444fdd808111f7df507b00d357b44d3259376 Mon Sep 17 00:00:00 2001
-From: Axel Lin <axel.lin@ingics.com>
-Date: Sun, 23 Feb 2014 13:27:16 +0800
-Subject: [PATCH 069/182] spi: qup: Fix build error due to a typo
-
-Fix below build error when CONFIG_PM_RUNTIME=y:
-
-C [M] drivers/spi/spi-qup.o
-drivers/spi/spi-qup.c: In function 'spi_qup_pm_suspend_runtime':
-drivers/spi/spi-qup.c:712:12: error: 'QUP_CLOCK_AUTO_GATE' undeclared (first use in this function)
-drivers/spi/spi-qup.c:712:12: note: each undeclared identifier is reported only once for each function it appears in
-drivers/spi/spi-qup.c: In function 'spi_qup_pm_resume_runtime':
-drivers/spi/spi-qup.c:725:13: error: 'QUP_CLOCK_AUTO_GATE' undeclared (first use in this function)
-make[2]: *** [drivers/spi/spi-qup.o] Error 1
-make[1]: *** [drivers/spi] Error 2
-make: *** [drivers] Error 2
-
-Signed-off-by: Axel Lin <axel.lin@ingics.com>
-Signed-off-by: Mark Brown <broonie@linaro.org>
----
- drivers/spi/spi-qup.c | 4 ++--
- 1 file changed, 2 insertions(+), 2 deletions(-)
-
---- a/drivers/spi/spi-qup.c
-+++ b/drivers/spi/spi-qup.c
-@@ -709,7 +709,7 @@ static int spi_qup_pm_suspend_runtime(st
-
- /* Enable clocks auto gaiting */
- config = readl(controller->base + QUP_CONFIG);
-- config |= QUP_CLOCK_AUTO_GATE;
-+ config |= QUP_CONFIG_CLOCK_AUTO_GATE;
- writel_relaxed(config, controller->base + QUP_CONFIG);
- return 0;
- }
-@@ -722,7 +722,7 @@ static int spi_qup_pm_resume_runtime(str
-
- /* Disable clocks auto gaiting */
- config = readl_relaxed(controller->base + QUP_CONFIG);
-- config &= ~QUP_CLOCK_AUTO_GATE;
-+ config &= ~QUP_CONFIG_CLOCK_AUTO_GATE;
- writel_relaxed(config, controller->base + QUP_CONFIG);
- return 0;
- }
diff --git a/target/linux/ipq806x/patches/0070-spi-qup-Enable-driver-compilation-with-COMPILE_TEST.patch b/target/linux/ipq806x/patches/0070-spi-qup-Enable-driver-compilation-with-COMPILE_TEST.patch
deleted file mode 100644
index 0058992..0000000
--- a/target/linux/ipq806x/patches/0070-spi-qup-Enable-driver-compilation-with-COMPILE_TEST.patch
+++ /dev/null
@@ -1,25 +0,0 @@
-From 4706cb5844e0f1a08ab25e103f6415fde5328ddc Mon Sep 17 00:00:00 2001
-From: Axel Lin <axel.lin@ingics.com>
-Date: Sun, 23 Feb 2014 13:28:33 +0800
-Subject: [PATCH 070/182] spi: qup: Enable driver compilation with
- COMPILE_TEST
-
-This helps increasing build testing coverage.
-
-Signed-off-by: Axel Lin <axel.lin@ingics.com>
-Signed-off-by: Mark Brown <broonie@linaro.org>
----
- drivers/spi/Kconfig | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/drivers/spi/Kconfig
-+++ b/drivers/spi/Kconfig
-@@ -392,7 +392,7 @@ config SPI_RSPI
-
- config SPI_QUP
- tristate "Qualcomm SPI controller with QUP interface"
-- depends on ARCH_MSM_DT
-+ depends on ARCH_MSM_DT || COMPILE_TEST
- help
- Qualcomm Universal Peripheral (QUP) core is an AHB slave that
- provides a common data path (an output FIFO and an input FIFO)
diff --git a/target/linux/ipq806x/patches/0071-spi-qup-Depend-on-ARM-COMPILE_TEST-to-avoid-build-er.patch b/target/linux/ipq806x/patches/0071-spi-qup-Depend-on-ARM-COMPILE_TEST-to-avoid-build-er.patch
deleted file mode 100644
index 2711a2a..0000000
--- a/target/linux/ipq806x/patches/0071-spi-qup-Depend-on-ARM-COMPILE_TEST-to-avoid-build-er.patch
+++ /dev/null
@@ -1,35 +0,0 @@
-From 7137376bc6415ab9b2f0c5983245a1273812e8b9 Mon Sep 17 00:00:00 2001
-From: Axel Lin <axel.lin@ingics.com>
-Date: Mon, 24 Feb 2014 12:07:51 +0800
-Subject: [PATCH 071/182] spi: qup: Depend on ARM && COMPILE_TEST to avoid
- build error
-
-This driver uses writel_relaxed() which does not exist in x86, ppc, etc.
-Make it depend on ARM && COMPILE_TEST to avoid below build error:
-
- CC [M] drivers/spi/spi-qup.o
-drivers/spi/spi-qup.c: In function 'spi_qup_set_state':
-drivers/spi/spi-qup.c:180:3: error: implicit declaration of function 'writel_relaxed' [-Werror=implicit-function-declaration]
-cc1: some warnings being treated as errors
-make[2]: *** [drivers/spi/spi-qup.o] Error 1
-make[1]: *** [drivers/spi] Error 2
-make: *** [drivers] Error 2
-
-Reported-by: Stephen Rothwell <sfr@canb.auug.org.au>
-Signed-off-by: Axel Lin <axel.lin@ingics.com>
-Signed-off-by: Mark Brown <broonie@linaro.org>
----
- drivers/spi/Kconfig | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/drivers/spi/Kconfig
-+++ b/drivers/spi/Kconfig
-@@ -392,7 +392,7 @@ config SPI_RSPI
-
- config SPI_QUP
- tristate "Qualcomm SPI controller with QUP interface"
-- depends on ARCH_MSM_DT || COMPILE_TEST
-+ depends on ARCH_MSM_DT || (ARM && COMPILE_TEST)
- help
- Qualcomm Universal Peripheral (QUP) core is an AHB slave that
- provides a common data path (an output FIFO and an input FIFO)
diff --git a/target/linux/ipq806x/patches/0072-spi-qup-Remove-module-version.patch b/target/linux/ipq806x/patches/0072-spi-qup-Remove-module-version.patch
deleted file mode 100644
index 6708238..0000000
--- a/target/linux/ipq806x/patches/0072-spi-qup-Remove-module-version.patch
+++ /dev/null
@@ -1,23 +0,0 @@
-From 7b8e00404cfc652abbd538df1365a8046ed0d782 Mon Sep 17 00:00:00 2001
-From: Axel Lin <axel.lin@ingics.com>
-Date: Mon, 24 Feb 2014 13:48:12 +0800
-Subject: [PATCH 072/182] spi: qup: Remove module version
-
-The module version is unlikely to be updated, use kernel version should be
-enough.
-
-Signed-off-by: Axel Lin <axel.lin@ingics.com>
-Acked-by: Ivan T. Ivanov <iivanov@mm-sol.com>
-Signed-off-by: Mark Brown <broonie@linaro.org>
----
- drivers/spi/spi-qup.c | 1 -
- 1 file changed, 1 deletion(-)
-
---- a/drivers/spi/spi-qup.c
-+++ b/drivers/spi/spi-qup.c
-@@ -819,5 +819,4 @@ static struct platform_driver spi_qup_dr
- module_platform_driver(spi_qup_driver);
-
- MODULE_LICENSE("GPL v2");
--MODULE_VERSION("0.4");
- MODULE_ALIAS("platform:spi_qup");
diff --git a/target/linux/ipq806x/patches/0073-spi-qup-Get-rid-of-using-struct-spi_qup_device.patch b/target/linux/ipq806x/patches/0073-spi-qup-Get-rid-of-using-struct-spi_qup_device.patch
deleted file mode 100644
index b527af9..0000000
--- a/target/linux/ipq806x/patches/0073-spi-qup-Get-rid-of-using-struct-spi_qup_device.patch
+++ /dev/null
@@ -1,162 +0,0 @@
-From 3027505ab8c8cb17291e53bca1d7bd770539d468 Mon Sep 17 00:00:00 2001
-From: Axel Lin <axel.lin@ingics.com>
-Date: Mon, 24 Feb 2014 23:07:36 +0800
-Subject: [PATCH 073/182] spi: qup: Get rid of using struct spi_qup_device
-
-Current code uses struct spi_qup_device to store spi->mode and spi->chip_select
-settings. We can get these settings in spi_qup_transfer_one and spi_qup_set_cs
-without using struct spi_qup_device. Refactor the code a bit to remove
-spi_qup_setup(), spi_qup_cleanup(), and struct spi_qup_device.
-
-Signed-off-by: Axel Lin <axel.lin@ingics.com>
-Tested-by: Ivan T. Ivanov <iivanov@mm-sol.com>
-Signed-off-by: Mark Brown <broonie@linaro.org>
----
- drivers/spi/spi-qup.c | 61 ++++++++-----------------------------------------
- 1 file changed, 9 insertions(+), 52 deletions(-)
-
---- a/drivers/spi/spi-qup.c
-+++ b/drivers/spi/spi-qup.c
-@@ -123,11 +123,6 @@
- #define SPI_DELAY_THRESHOLD 1
- #define SPI_DELAY_RETRY 10
-
--struct spi_qup_device {
-- int select;
-- u16 mode;
--};
--
- struct spi_qup {
- void __iomem *base;
- struct device *dev;
-@@ -338,14 +333,13 @@ static irqreturn_t spi_qup_qup_irq(int i
-
-
- /* set clock freq ... bits per word */
--static int spi_qup_io_config(struct spi_qup *controller,
-- struct spi_qup_device *chip,
-- struct spi_transfer *xfer)
-+static int spi_qup_io_config(struct spi_device *spi, struct spi_transfer *xfer)
- {
-+ struct spi_qup *controller = spi_master_get_devdata(spi->master);
- u32 config, iomode, mode;
- int ret, n_words, w_size;
-
-- if (chip->mode & SPI_LOOP && xfer->len > controller->in_fifo_sz) {
-+ if (spi->mode & SPI_LOOP && xfer->len > controller->in_fifo_sz) {
- dev_err(controller->dev, "too big size for loopback %d > %d\n",
- xfer->len, controller->in_fifo_sz);
- return -EIO;
-@@ -399,12 +393,12 @@ static int spi_qup_io_config(struct spi_
-
- config = readl_relaxed(controller->base + SPI_CONFIG);
-
-- if (chip->mode & SPI_LOOP)
-+ if (spi->mode & SPI_LOOP)
- config |= SPI_CONFIG_LOOPBACK;
- else
- config &= ~SPI_CONFIG_LOOPBACK;
-
-- if (chip->mode & SPI_CPHA)
-+ if (spi->mode & SPI_CPHA)
- config &= ~SPI_CONFIG_INPUT_FIRST;
- else
- config |= SPI_CONFIG_INPUT_FIRST;
-@@ -413,7 +407,7 @@ static int spi_qup_io_config(struct spi_
- * HS_MODE improves signal stability for spi-clk high rates,
- * but is invalid in loop back mode.
- */
-- if ((xfer->speed_hz >= SPI_HS_MIN_RATE) && !(chip->mode & SPI_LOOP))
-+ if ((xfer->speed_hz >= SPI_HS_MIN_RATE) && !(spi->mode & SPI_LOOP))
- config |= SPI_CONFIG_HS_MODE;
- else
- config &= ~SPI_CONFIG_HS_MODE;
-@@ -433,7 +427,6 @@ static int spi_qup_io_config(struct spi_
- static void spi_qup_set_cs(struct spi_device *spi, bool enable)
- {
- struct spi_qup *controller = spi_master_get_devdata(spi->master);
-- struct spi_qup_device *chip = spi_get_ctldata(spi);
-
- u32 iocontol, mask;
-
-@@ -444,9 +437,9 @@ static void spi_qup_set_cs(struct spi_de
- iocontol |= SPI_IO_C_FORCE_CS;
-
- iocontol &= ~SPI_IO_C_CS_SELECT_MASK;
-- iocontol |= SPI_IO_C_CS_SELECT(chip->select);
-+ iocontol |= SPI_IO_C_CS_SELECT(spi->chip_select);
-
-- mask = SPI_IO_C_CS_N_POLARITY_0 << chip->select;
-+ mask = SPI_IO_C_CS_N_POLARITY_0 << spi->chip_select;
-
- if (enable)
- iocontol |= mask;
-@@ -461,11 +454,10 @@ static int spi_qup_transfer_one(struct s
- struct spi_transfer *xfer)
- {
- struct spi_qup *controller = spi_master_get_devdata(master);
-- struct spi_qup_device *chip = spi_get_ctldata(spi);
- unsigned long timeout, flags;
- int ret = -EIO;
-
-- ret = spi_qup_io_config(controller, chip, xfer);
-+ ret = spi_qup_io_config(spi, xfer);
- if (ret)
- return ret;
-
-@@ -511,38 +503,6 @@ exit:
- return ret;
- }
-
--static int spi_qup_setup(struct spi_device *spi)
--{
-- struct spi_qup *controller = spi_master_get_devdata(spi->master);
-- struct spi_qup_device *chip = spi_get_ctldata(spi);
--
-- if (!chip) {
-- /* First setup */
-- chip = kzalloc(sizeof(*chip), GFP_KERNEL);
-- if (!chip) {
-- dev_err(controller->dev, "no memory for chip data\n");
-- return -ENOMEM;
-- }
--
-- chip->mode = spi->mode;
-- chip->select = spi->chip_select;
-- spi_set_ctldata(spi, chip);
-- }
--
-- return 0;
--}
--
--static void spi_qup_cleanup(struct spi_device *spi)
--{
-- struct spi_qup_device *chip = spi_get_ctldata(spi);
--
-- if (!chip)
-- return;
--
-- spi_set_ctldata(spi, NULL);
-- kfree(chip);
--}
--
- static int spi_qup_probe(struct platform_device *pdev)
- {
- struct spi_master *master;
-@@ -561,7 +521,6 @@ static int spi_qup_probe(struct platform
- return PTR_ERR(base);
-
- irq = platform_get_irq(pdev, 0);
--
- if (irq < 0)
- return irq;
-
-@@ -617,8 +576,6 @@ static int spi_qup_probe(struct platform
- master->num_chipselect = SPI_NUM_CHIPSELECTS;
- master->bits_per_word_mask = SPI_BPW_RANGE_MASK(4, 32);
- master->max_speed_hz = max_freq;
-- master->setup = spi_qup_setup;
-- master->cleanup = spi_qup_cleanup;
- master->set_cs = spi_qup_set_cs;
- master->transfer_one = spi_qup_transfer_one;
- master->dev.of_node = pdev->dev.of_node;
diff --git a/target/linux/ipq806x/patches/0074-spi-qup-Depend-on-ARCH_QCOM.patch b/target/linux/ipq806x/patches/0074-spi-qup-Depend-on-ARCH_QCOM.patch
deleted file mode 100644
index 7b924f1..0000000
--- a/target/linux/ipq806x/patches/0074-spi-qup-Depend-on-ARCH_QCOM.patch
+++ /dev/null
@@ -1,31 +0,0 @@
-From 5148138d2b879c7b024fa3865fb3980c6dc84fcc Mon Sep 17 00:00:00 2001
-From: Paul Bolle <pebolle@tiscali.nl>
-Date: Mon, 7 Apr 2014 16:15:45 +0200
-Subject: [PATCH 074/182] spi: qup: Depend on ARCH_QCOM
-
-Commit 8fc1b0f87d9f ("ARM: qcom: Split Qualcomm support into legacy and
-multiplatform") removed Kconfig symbol ARCH_MSM_DT. But that commit
-left one (optional) dependency on ARCH_MSM_DT untouched.
-
-Three Kconfig symbols used to depend on ARCH_MSM_DT: ARCH_MSM8X60,
-ARCH_MSM8960, and ARCH_MSM8974. These three symbols now depend on
-ARCH_QCOM. So it appears this driver needs to depend on ARCH_QCOM too.
-
-Signed-off-by: Paul Bolle <pebolle@tiscali.nl>
-Reviewed-by: Stephen Boyd <sboyd@codeaurora.org>
-Signed-off-by: Mark Brown <broonie@linaro.org>
----
- drivers/spi/Kconfig | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/drivers/spi/Kconfig
-+++ b/drivers/spi/Kconfig
-@@ -392,7 +392,7 @@ config SPI_RSPI
-
- config SPI_QUP
- tristate "Qualcomm SPI controller with QUP interface"
-- depends on ARCH_MSM_DT || (ARM && COMPILE_TEST)
-+ depends on ARCH_QCOM || (ARM && COMPILE_TEST)
- help
- Qualcomm Universal Peripheral (QUP) core is an AHB slave that
- provides a common data path (an output FIFO and an input FIFO)
diff --git a/target/linux/ipq806x/patches/0075-spi-qup-Correct-selection-of-FIFO-Block-mode.patch b/target/linux/ipq806x/patches/0075-spi-qup-Correct-selection-of-FIFO-Block-mode.patch
deleted file mode 100644
index 0fd095a..0000000
--- a/target/linux/ipq806x/patches/0075-spi-qup-Correct-selection-of-FIFO-Block-mode.patch
+++ /dev/null
@@ -1,34 +0,0 @@
-From e8e77359524e6629bac68db4183694fccffaed8e Mon Sep 17 00:00:00 2001
-From: Andy Gross <agross@codeaurora.org>
-Date: Tue, 13 May 2014 16:34:42 -0500
-Subject: [PATCH 075/182] spi: qup: Correct selection of FIFO/Block mode
-
-This patch fixes the calculation for determining whether to use FIFO or BLOCK
-mode.
-
-Signed-off-by: Andy Gross <agross@codeaurora.org>
-Signed-off-by: Mark Brown <broonie@linaro.org>
----
- drivers/spi/spi-qup.c | 4 ++--
- 1 file changed, 2 insertions(+), 2 deletions(-)
-
---- a/drivers/spi/spi-qup.c
-+++ b/drivers/spi/spi-qup.c
-@@ -287,7 +287,7 @@ static irqreturn_t spi_qup_qup_irq(int i
- writel_relaxed(opflags, controller->base + QUP_OPERATIONAL);
-
- if (!xfer) {
-- dev_err_ratelimited(controller->dev, "unexpected irq %x08 %x08 %x08\n",
-+ dev_err_ratelimited(controller->dev, "unexpected irq %08x %08x %08x\n",
- qup_err, spi_err, opflags);
- return IRQ_HANDLED;
- }
-@@ -366,7 +366,7 @@ static int spi_qup_io_config(struct spi_
- n_words = xfer->len / w_size;
- controller->w_size = w_size;
-
-- if (n_words <= controller->in_fifo_sz) {
-+ if (n_words <= (controller->in_fifo_sz / sizeof(u32))) {
- mode = QUP_IO_M_MODE_FIFO;
- writel_relaxed(n_words, controller->base + QUP_MX_READ_CNT);
- writel_relaxed(n_words, controller->base + QUP_MX_WRITE_CNT);
diff --git a/target/linux/ipq806x/patches/0078-clk-qcom-Consolidate-common-probe-code.patch b/target/linux/ipq806x/patches/0078-clk-qcom-Consolidate-common-probe-code.patch
deleted file mode 100644
index 25b6ac2..0000000
--- a/target/linux/ipq806x/patches/0078-clk-qcom-Consolidate-common-probe-code.patch
+++ /dev/null
@@ -1,734 +0,0 @@
-From d79cb0c583772f38a9367af106d61bcf8bfa08e4 Mon Sep 17 00:00:00 2001
-From: Stephen Boyd <sboyd@codeaurora.org>
-Date: Fri, 21 Mar 2014 17:59:37 -0700
-Subject: [PATCH 078/182] clk: qcom: Consolidate common probe code
-
-Most of the probe code is the same between all the different
-clock controllers. Consolidate the code into a common.c file.
-This makes changes to the common probe parts easier and reduces
-chances for bugs.
-
-Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
-Signed-off-by: Kumar Gala <galak@codeaurora.org>
----
- drivers/clk/qcom/Makefile | 1 +
- drivers/clk/qcom/common.c | 99 +++++++++++++++++++++++++++++++++++++++
- drivers/clk/qcom/common.h | 34 ++++++++++++++
- drivers/clk/qcom/gcc-msm8660.c | 87 +++++-----------------------------
- drivers/clk/qcom/gcc-msm8960.c | 77 +++++-------------------------
- drivers/clk/qcom/gcc-msm8974.c | 77 +++++-------------------------
- drivers/clk/qcom/mmcc-msm8960.c | 78 +++++-------------------------
- drivers/clk/qcom/mmcc-msm8974.c | 80 +++++++------------------------
- 8 files changed, 196 insertions(+), 337 deletions(-)
- create mode 100644 drivers/clk/qcom/common.c
- create mode 100644 drivers/clk/qcom/common.h
-
---- a/drivers/clk/qcom/Makefile
-+++ b/drivers/clk/qcom/Makefile
-@@ -1,5 +1,6 @@
- obj-$(CONFIG_COMMON_CLK_QCOM) += clk-qcom.o
-
-+clk-qcom-y += common.o
- clk-qcom-y += clk-regmap.o
- clk-qcom-y += clk-pll.o
- clk-qcom-y += clk-rcg.o
---- /dev/null
-+++ b/drivers/clk/qcom/common.c
-@@ -0,0 +1,99 @@
-+/*
-+ * Copyright (c) 2013-2014, The Linux Foundation. All rights reserved.
-+ *
-+ * This software is licensed under the terms of the GNU General Public
-+ * License version 2, as published by the Free Software Foundation, and
-+ * may be copied, distributed, and modified under those terms.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ * GNU General Public License for more details.
-+ */
-+
-+#include <linux/export.h>
-+#include <linux/regmap.h>
-+#include <linux/platform_device.h>
-+#include <linux/clk-provider.h>
-+#include <linux/reset-controller.h>
-+
-+#include "common.h"
-+#include "clk-regmap.h"
-+#include "reset.h"
-+
-+struct qcom_cc {
-+ struct qcom_reset_controller reset;
-+ struct clk_onecell_data data;
-+ struct clk *clks[];
-+};
-+
-+int qcom_cc_probe(struct platform_device *pdev, const struct qcom_cc_desc *desc)
-+{
-+ void __iomem *base;
-+ struct resource *res;
-+ int i, ret;
-+ struct device *dev = &pdev->dev;
-+ struct clk *clk;
-+ struct clk_onecell_data *data;
-+ struct clk **clks;
-+ struct regmap *regmap;
-+ struct qcom_reset_controller *reset;
-+ struct qcom_cc *cc;
-+ size_t num_clks = desc->num_clks;
-+ struct clk_regmap **rclks = desc->clks;
-+
-+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-+ base = devm_ioremap_resource(dev, res);
-+ if (IS_ERR(base))
-+ return PTR_ERR(base);
-+
-+ regmap = devm_regmap_init_mmio(dev, base, desc->config);
-+ if (IS_ERR(regmap))
-+ return PTR_ERR(regmap);
-+
-+ cc = devm_kzalloc(dev, sizeof(*cc) + sizeof(*clks) * num_clks,
-+ GFP_KERNEL);
-+ if (!cc)
-+ return -ENOMEM;
-+
-+ clks = cc->clks;
-+ data = &cc->data;
-+ data->clks = clks;
-+ data->clk_num = num_clks;
-+
-+ for (i = 0; i < num_clks; i++) {
-+ if (!rclks[i])
-+ continue;
-+ clk = devm_clk_register_regmap(dev, rclks[i]);
-+ if (IS_ERR(clk))
-+ return PTR_ERR(clk);
-+ clks[i] = clk;
-+ }
-+
-+ ret = of_clk_add_provider(dev->of_node, of_clk_src_onecell_get, data);
-+ if (ret)
-+ return ret;
-+
-+ reset = &cc->reset;
-+ reset->rcdev.of_node = dev->of_node;
-+ reset->rcdev.ops = &qcom_reset_ops;
-+ reset->rcdev.owner = dev->driver->owner;
-+ reset->rcdev.nr_resets = desc->num_resets;
-+ reset->regmap = regmap;
-+ reset->reset_map = desc->resets;
-+ platform_set_drvdata(pdev, &reset->rcdev);
-+
-+ ret = reset_controller_register(&reset->rcdev);
-+ if (ret)
-+ of_clk_del_provider(dev->of_node);
-+
-+ return ret;
-+}
-+EXPORT_SYMBOL_GPL(qcom_cc_probe);
-+
-+void qcom_cc_remove(struct platform_device *pdev)
-+{
-+ of_clk_del_provider(pdev->dev.of_node);
-+ reset_controller_unregister(platform_get_drvdata(pdev));
-+}
-+EXPORT_SYMBOL_GPL(qcom_cc_remove);
---- /dev/null
-+++ b/drivers/clk/qcom/common.h
-@@ -0,0 +1,34 @@
-+/*
-+ * Copyright (c) 2014, The Linux Foundation. All rights reserved.
-+ *
-+ * This software is licensed under the terms of the GNU General Public
-+ * License version 2, as published by the Free Software Foundation, and
-+ * may be copied, distributed, and modified under those terms.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ * GNU General Public License for more details.
-+ */
-+#ifndef __QCOM_CLK_COMMON_H__
-+#define __QCOM_CLK_COMMON_H__
-+
-+struct platform_device;
-+struct regmap_config;
-+struct clk_regmap;
-+struct qcom_reset_map;
-+
-+struct qcom_cc_desc {
-+ const struct regmap_config *config;
-+ struct clk_regmap **clks;
-+ size_t num_clks;
-+ const struct qcom_reset_map *resets;
-+ size_t num_resets;
-+};
-+
-+extern int qcom_cc_probe(struct platform_device *pdev,
-+ const struct qcom_cc_desc *desc);
-+
-+extern void qcom_cc_remove(struct platform_device *pdev);
-+
-+#endif
---- a/drivers/clk/qcom/gcc-msm8660.c
-+++ b/drivers/clk/qcom/gcc-msm8660.c
-@@ -25,6 +25,7 @@
- #include <dt-bindings/clock/qcom,gcc-msm8660.h>
- #include <dt-bindings/reset/qcom,gcc-msm8660.h>
-
-+#include "common.h"
- #include "clk-regmap.h"
- #include "clk-pll.h"
- #include "clk-rcg.h"
-@@ -2701,94 +2702,28 @@ static const struct regmap_config gcc_ms
- .fast_io = true,
- };
-
-+static const struct qcom_cc_desc gcc_msm8660_desc = {
-+ .config = &gcc_msm8660_regmap_config,
-+ .clks = gcc_msm8660_clks,
-+ .num_clks = ARRAY_SIZE(gcc_msm8660_clks),
-+ .resets = gcc_msm8660_resets,
-+ .num_resets = ARRAY_SIZE(gcc_msm8660_resets),
-+};
-+
- static const struct of_device_id gcc_msm8660_match_table[] = {
- { .compatible = "qcom,gcc-msm8660" },
- { }
- };
- MODULE_DEVICE_TABLE(of, gcc_msm8660_match_table);
-
--struct qcom_cc {
-- struct qcom_reset_controller reset;
-- struct clk_onecell_data data;
-- struct clk *clks[];
--};
--
- static int gcc_msm8660_probe(struct platform_device *pdev)
- {
-- void __iomem *base;
-- struct resource *res;
-- int i, ret;
-- struct device *dev = &pdev->dev;
-- struct clk *clk;
-- struct clk_onecell_data *data;
-- struct clk **clks;
-- struct regmap *regmap;
-- size_t num_clks;
-- struct qcom_reset_controller *reset;
-- struct qcom_cc *cc;
--
-- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-- base = devm_ioremap_resource(dev, res);
-- if (IS_ERR(base))
-- return PTR_ERR(base);
--
-- regmap = devm_regmap_init_mmio(dev, base, &gcc_msm8660_regmap_config);
-- if (IS_ERR(regmap))
-- return PTR_ERR(regmap);
--
-- num_clks = ARRAY_SIZE(gcc_msm8660_clks);
-- cc = devm_kzalloc(dev, sizeof(*cc) + sizeof(*clks) * num_clks,
-- GFP_KERNEL);
-- if (!cc)
-- return -ENOMEM;
--
-- clks = cc->clks;
-- data = &cc->data;
-- data->clks = clks;
-- data->clk_num = num_clks;
--
-- /* Temporary until RPM clocks supported */
-- clk = clk_register_fixed_rate(dev, "cxo", NULL, CLK_IS_ROOT, 19200000);
-- if (IS_ERR(clk))
-- return PTR_ERR(clk);
--
-- clk = clk_register_fixed_rate(dev, "pxo", NULL, CLK_IS_ROOT, 27000000);
-- if (IS_ERR(clk))
-- return PTR_ERR(clk);
--
-- for (i = 0; i < num_clks; i++) {
-- if (!gcc_msm8660_clks[i])
-- continue;
-- clk = devm_clk_register_regmap(dev, gcc_msm8660_clks[i]);
-- if (IS_ERR(clk))
-- return PTR_ERR(clk);
-- clks[i] = clk;
-- }
--
-- ret = of_clk_add_provider(dev->of_node, of_clk_src_onecell_get, data);
-- if (ret)
-- return ret;
--
-- reset = &cc->reset;
-- reset->rcdev.of_node = dev->of_node;
-- reset->rcdev.ops = &qcom_reset_ops,
-- reset->rcdev.owner = THIS_MODULE,
-- reset->rcdev.nr_resets = ARRAY_SIZE(gcc_msm8660_resets),
-- reset->regmap = regmap;
-- reset->reset_map = gcc_msm8660_resets,
-- platform_set_drvdata(pdev, &reset->rcdev);
--
-- ret = reset_controller_register(&reset->rcdev);
-- if (ret)
-- of_clk_del_provider(dev->of_node);
--
-- return ret;
-+ return qcom_cc_probe(pdev, &gcc_msm8660_desc);
- }
-
- static int gcc_msm8660_remove(struct platform_device *pdev)
- {
-- of_clk_del_provider(pdev->dev.of_node);
-- reset_controller_unregister(platform_get_drvdata(pdev));
-+ qcom_cc_remove(pdev);
- return 0;
- }
-
---- a/drivers/clk/qcom/gcc-msm8960.c
-+++ b/drivers/clk/qcom/gcc-msm8960.c
-@@ -25,6 +25,7 @@
- #include <dt-bindings/clock/qcom,gcc-msm8960.h>
- #include <dt-bindings/reset/qcom,gcc-msm8960.h>
-
-+#include "common.h"
- #include "clk-regmap.h"
- #include "clk-pll.h"
- #include "clk-rcg.h"
-@@ -2875,51 +2876,24 @@ static const struct regmap_config gcc_ms
- .fast_io = true,
- };
-
-+static const struct qcom_cc_desc gcc_msm8960_desc = {
-+ .config = &gcc_msm8960_regmap_config,
-+ .clks = gcc_msm8960_clks,
-+ .num_clks = ARRAY_SIZE(gcc_msm8960_clks),
-+ .resets = gcc_msm8960_resets,
-+ .num_resets = ARRAY_SIZE(gcc_msm8960_resets),
-+};
-+
- static const struct of_device_id gcc_msm8960_match_table[] = {
- { .compatible = "qcom,gcc-msm8960" },
- { }
- };
- MODULE_DEVICE_TABLE(of, gcc_msm8960_match_table);
-
--struct qcom_cc {
-- struct qcom_reset_controller reset;
-- struct clk_onecell_data data;
-- struct clk *clks[];
--};
--
- static int gcc_msm8960_probe(struct platform_device *pdev)
- {
-- void __iomem *base;
-- struct resource *res;
-- int i, ret;
-- struct device *dev = &pdev->dev;
- struct clk *clk;
-- struct clk_onecell_data *data;
-- struct clk **clks;
-- struct regmap *regmap;
-- size_t num_clks;
-- struct qcom_reset_controller *reset;
-- struct qcom_cc *cc;
--
-- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-- base = devm_ioremap_resource(dev, res);
-- if (IS_ERR(base))
-- return PTR_ERR(base);
--
-- regmap = devm_regmap_init_mmio(dev, base, &gcc_msm8960_regmap_config);
-- if (IS_ERR(regmap))
-- return PTR_ERR(regmap);
--
-- num_clks = ARRAY_SIZE(gcc_msm8960_clks);
-- cc = devm_kzalloc(dev, sizeof(*cc) + sizeof(*clks) * num_clks,
-- GFP_KERNEL);
-- if (!cc)
-- return -ENOMEM;
--
-- clks = cc->clks;
-- data = &cc->data;
-- data->clks = clks;
-- data->clk_num = num_clks;
-+ struct device *dev = &pdev->dev;
-
- /* Temporary until RPM clocks supported */
- clk = clk_register_fixed_rate(dev, "cxo", NULL, CLK_IS_ROOT, 19200000);
-@@ -2930,39 +2904,12 @@ static int gcc_msm8960_probe(struct plat
- if (IS_ERR(clk))
- return PTR_ERR(clk);
-
-- for (i = 0; i < num_clks; i++) {
-- if (!gcc_msm8960_clks[i])
-- continue;
-- clk = devm_clk_register_regmap(dev, gcc_msm8960_clks[i]);
-- if (IS_ERR(clk))
-- return PTR_ERR(clk);
-- clks[i] = clk;
-- }
--
-- ret = of_clk_add_provider(dev->of_node, of_clk_src_onecell_get, data);
-- if (ret)
-- return ret;
--
-- reset = &cc->reset;
-- reset->rcdev.of_node = dev->of_node;
-- reset->rcdev.ops = &qcom_reset_ops,
-- reset->rcdev.owner = THIS_MODULE,
-- reset->rcdev.nr_resets = ARRAY_SIZE(gcc_msm8960_resets),
-- reset->regmap = regmap;
-- reset->reset_map = gcc_msm8960_resets,
-- platform_set_drvdata(pdev, &reset->rcdev);
--
-- ret = reset_controller_register(&reset->rcdev);
-- if (ret)
-- of_clk_del_provider(dev->of_node);
--
-- return ret;
-+ return qcom_cc_probe(pdev, &gcc_msm8960_desc);
- }
-
- static int gcc_msm8960_remove(struct platform_device *pdev)
- {
-- of_clk_del_provider(pdev->dev.of_node);
-- reset_controller_unregister(platform_get_drvdata(pdev));
-+ qcom_cc_remove(pdev);
- return 0;
- }
-
---- a/drivers/clk/qcom/gcc-msm8974.c
-+++ b/drivers/clk/qcom/gcc-msm8974.c
-@@ -25,6 +25,7 @@
- #include <dt-bindings/clock/qcom,gcc-msm8974.h>
- #include <dt-bindings/reset/qcom,gcc-msm8974.h>
-
-+#include "common.h"
- #include "clk-regmap.h"
- #include "clk-pll.h"
- #include "clk-rcg.h"
-@@ -2574,51 +2575,24 @@ static const struct regmap_config gcc_ms
- .fast_io = true,
- };
-
-+static const struct qcom_cc_desc gcc_msm8974_desc = {
-+ .config = &gcc_msm8974_regmap_config,
-+ .clks = gcc_msm8974_clocks,
-+ .num_clks = ARRAY_SIZE(gcc_msm8974_clocks),
-+ .resets = gcc_msm8974_resets,
-+ .num_resets = ARRAY_SIZE(gcc_msm8974_resets),
-+};
-+
- static const struct of_device_id gcc_msm8974_match_table[] = {
- { .compatible = "qcom,gcc-msm8974" },
- { }
- };
- MODULE_DEVICE_TABLE(of, gcc_msm8974_match_table);
-
--struct qcom_cc {
-- struct qcom_reset_controller reset;
-- struct clk_onecell_data data;
-- struct clk *clks[];
--};
--
- static int gcc_msm8974_probe(struct platform_device *pdev)
- {
-- void __iomem *base;
-- struct resource *res;
-- int i, ret;
-- struct device *dev = &pdev->dev;
- struct clk *clk;
-- struct clk_onecell_data *data;
-- struct clk **clks;
-- struct regmap *regmap;
-- size_t num_clks;
-- struct qcom_reset_controller *reset;
-- struct qcom_cc *cc;
--
-- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-- base = devm_ioremap_resource(dev, res);
-- if (IS_ERR(base))
-- return PTR_ERR(base);
--
-- regmap = devm_regmap_init_mmio(dev, base, &gcc_msm8974_regmap_config);
-- if (IS_ERR(regmap))
-- return PTR_ERR(regmap);
--
-- num_clks = ARRAY_SIZE(gcc_msm8974_clocks);
-- cc = devm_kzalloc(dev, sizeof(*cc) + sizeof(*clks) * num_clks,
-- GFP_KERNEL);
-- if (!cc)
-- return -ENOMEM;
--
-- clks = cc->clks;
-- data = &cc->data;
-- data->clks = clks;
-- data->clk_num = num_clks;
-+ struct device *dev = &pdev->dev;
-
- /* Temporary until RPM clocks supported */
- clk = clk_register_fixed_rate(dev, "xo", NULL, CLK_IS_ROOT, 19200000);
-@@ -2631,39 +2605,12 @@ static int gcc_msm8974_probe(struct plat
- if (IS_ERR(clk))
- return PTR_ERR(clk);
-
-- for (i = 0; i < num_clks; i++) {
-- if (!gcc_msm8974_clocks[i])
-- continue;
-- clk = devm_clk_register_regmap(dev, gcc_msm8974_clocks[i]);
-- if (IS_ERR(clk))
-- return PTR_ERR(clk);
-- clks[i] = clk;
-- }
--
-- ret = of_clk_add_provider(dev->of_node, of_clk_src_onecell_get, data);
-- if (ret)
-- return ret;
--
-- reset = &cc->reset;
-- reset->rcdev.of_node = dev->of_node;
-- reset->rcdev.ops = &qcom_reset_ops,
-- reset->rcdev.owner = THIS_MODULE,
-- reset->rcdev.nr_resets = ARRAY_SIZE(gcc_msm8974_resets),
-- reset->regmap = regmap;
-- reset->reset_map = gcc_msm8974_resets,
-- platform_set_drvdata(pdev, &reset->rcdev);
--
-- ret = reset_controller_register(&reset->rcdev);
-- if (ret)
-- of_clk_del_provider(dev->of_node);
--
-- return ret;
-+ return qcom_cc_probe(pdev, &gcc_msm8974_desc);
- }
-
- static int gcc_msm8974_remove(struct platform_device *pdev)
- {
-- of_clk_del_provider(pdev->dev.of_node);
-- reset_controller_unregister(platform_get_drvdata(pdev));
-+ qcom_cc_remove(pdev);
- return 0;
- }
-
---- a/drivers/clk/qcom/mmcc-msm8960.c
-+++ b/drivers/clk/qcom/mmcc-msm8960.c
-@@ -26,6 +26,7 @@
- #include <dt-bindings/clock/qcom,mmcc-msm8960.h>
- #include <dt-bindings/reset/qcom,mmcc-msm8960.h>
-
-+#include "common.h"
- #include "clk-regmap.h"
- #include "clk-pll.h"
- #include "clk-rcg.h"
-@@ -2224,85 +2225,28 @@ static const struct regmap_config mmcc_m
- .fast_io = true,
- };
-
-+static const struct qcom_cc_desc mmcc_msm8960_desc = {
-+ .config = &mmcc_msm8960_regmap_config,
-+ .clks = mmcc_msm8960_clks,
-+ .num_clks = ARRAY_SIZE(mmcc_msm8960_clks),
-+ .resets = mmcc_msm8960_resets,
-+ .num_resets = ARRAY_SIZE(mmcc_msm8960_resets),
-+};
-+
- static const struct of_device_id mmcc_msm8960_match_table[] = {
- { .compatible = "qcom,mmcc-msm8960" },
- { }
- };
- MODULE_DEVICE_TABLE(of, mmcc_msm8960_match_table);
-
--struct qcom_cc {
-- struct qcom_reset_controller reset;
-- struct clk_onecell_data data;
-- struct clk *clks[];
--};
--
- static int mmcc_msm8960_probe(struct platform_device *pdev)
- {
-- void __iomem *base;
-- struct resource *res;
-- int i, ret;
-- struct device *dev = &pdev->dev;
-- struct clk *clk;
-- struct clk_onecell_data *data;
-- struct clk **clks;
-- struct regmap *regmap;
-- size_t num_clks;
-- struct qcom_reset_controller *reset;
-- struct qcom_cc *cc;
--
-- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-- base = devm_ioremap_resource(dev, res);
-- if (IS_ERR(base))
-- return PTR_ERR(base);
--
-- regmap = devm_regmap_init_mmio(dev, base, &mmcc_msm8960_regmap_config);
-- if (IS_ERR(regmap))
-- return PTR_ERR(regmap);
--
-- num_clks = ARRAY_SIZE(mmcc_msm8960_clks);
-- cc = devm_kzalloc(dev, sizeof(*cc) + sizeof(*clks) * num_clks,
-- GFP_KERNEL);
-- if (!cc)
-- return -ENOMEM;
--
-- clks = cc->clks;
-- data = &cc->data;
-- data->clks = clks;
-- data->clk_num = num_clks;
--
-- for (i = 0; i < num_clks; i++) {
-- if (!mmcc_msm8960_clks[i])
-- continue;
-- clk = devm_clk_register_regmap(dev, mmcc_msm8960_clks[i]);
-- if (IS_ERR(clk))
-- return PTR_ERR(clk);
-- clks[i] = clk;
-- }
--
-- ret = of_clk_add_provider(dev->of_node, of_clk_src_onecell_get, data);
-- if (ret)
-- return ret;
--
-- reset = &cc->reset;
-- reset->rcdev.of_node = dev->of_node;
-- reset->rcdev.ops = &qcom_reset_ops,
-- reset->rcdev.owner = THIS_MODULE,
-- reset->rcdev.nr_resets = ARRAY_SIZE(mmcc_msm8960_resets),
-- reset->regmap = regmap;
-- reset->reset_map = mmcc_msm8960_resets,
-- platform_set_drvdata(pdev, &reset->rcdev);
--
-- ret = reset_controller_register(&reset->rcdev);
-- if (ret)
-- of_clk_del_provider(dev->of_node);
--
-- return ret;
-+ return qcom_cc_probe(pdev, &mmcc_msm8960_desc);
- }
-
- static int mmcc_msm8960_remove(struct platform_device *pdev)
- {
-- of_clk_del_provider(pdev->dev.of_node);
-- reset_controller_unregister(platform_get_drvdata(pdev));
-+ qcom_cc_remove(pdev);
- return 0;
- }
-
---- a/drivers/clk/qcom/mmcc-msm8974.c
-+++ b/drivers/clk/qcom/mmcc-msm8974.c
-@@ -25,6 +25,7 @@
- #include <dt-bindings/clock/qcom,mmcc-msm8974.h>
- #include <dt-bindings/reset/qcom,mmcc-msm8974.h>
-
-+#include "common.h"
- #include "clk-regmap.h"
- #include "clk-pll.h"
- #include "clk-rcg.h"
-@@ -2527,88 +2528,39 @@ static const struct regmap_config mmcc_m
- .fast_io = true,
- };
-
-+static const struct qcom_cc_desc mmcc_msm8974_desc = {
-+ .config = &mmcc_msm8974_regmap_config,
-+ .clks = mmcc_msm8974_clocks,
-+ .num_clks = ARRAY_SIZE(mmcc_msm8974_clocks),
-+ .resets = mmcc_msm8974_resets,
-+ .num_resets = ARRAY_SIZE(mmcc_msm8974_resets),
-+};
-+
- static const struct of_device_id mmcc_msm8974_match_table[] = {
- { .compatible = "qcom,mmcc-msm8974" },
- { }
- };
- MODULE_DEVICE_TABLE(of, mmcc_msm8974_match_table);
-
--struct qcom_cc {
-- struct qcom_reset_controller reset;
-- struct clk_onecell_data data;
-- struct clk *clks[];
--};
--
- static int mmcc_msm8974_probe(struct platform_device *pdev)
- {
-- void __iomem *base;
-- struct resource *res;
-- int i, ret;
-- struct device *dev = &pdev->dev;
-- struct clk *clk;
-- struct clk_onecell_data *data;
-- struct clk **clks;
-+ int ret;
- struct regmap *regmap;
-- size_t num_clks;
-- struct qcom_reset_controller *reset;
-- struct qcom_cc *cc;
--
-- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-- base = devm_ioremap_resource(dev, res);
-- if (IS_ERR(base))
-- return PTR_ERR(base);
--
-- regmap = devm_regmap_init_mmio(dev, base, &mmcc_msm8974_regmap_config);
-- if (IS_ERR(regmap))
-- return PTR_ERR(regmap);
--
-- num_clks = ARRAY_SIZE(mmcc_msm8974_clocks);
-- cc = devm_kzalloc(dev, sizeof(*cc) + sizeof(*clks) * num_clks,
-- GFP_KERNEL);
-- if (!cc)
-- return -ENOMEM;
--
-- clks = cc->clks;
-- data = &cc->data;
-- data->clks = clks;
-- data->clk_num = num_clks;
--
-- clk_pll_configure_sr_hpm_lp(&mmpll1, regmap, &mmpll1_config, true);
-- clk_pll_configure_sr_hpm_lp(&mmpll3, regmap, &mmpll3_config, false);
-
-- for (i = 0; i < num_clks; i++) {
-- if (!mmcc_msm8974_clocks[i])
-- continue;
-- clk = devm_clk_register_regmap(dev, mmcc_msm8974_clocks[i]);
-- if (IS_ERR(clk))
-- return PTR_ERR(clk);
-- clks[i] = clk;
-- }
--
-- ret = of_clk_add_provider(dev->of_node, of_clk_src_onecell_get, data);
-+ ret = qcom_cc_probe(pdev, &mmcc_msm8974_desc);
- if (ret)
- return ret;
-
-- reset = &cc->reset;
-- reset->rcdev.of_node = dev->of_node;
-- reset->rcdev.ops = &qcom_reset_ops,
-- reset->rcdev.owner = THIS_MODULE,
-- reset->rcdev.nr_resets = ARRAY_SIZE(mmcc_msm8974_resets),
-- reset->regmap = regmap;
-- reset->reset_map = mmcc_msm8974_resets,
-- platform_set_drvdata(pdev, &reset->rcdev);
--
-- ret = reset_controller_register(&reset->rcdev);
-- if (ret)
-- of_clk_del_provider(dev->of_node);
-+ regmap = dev_get_regmap(&pdev->dev, NULL);
-+ clk_pll_configure_sr_hpm_lp(&mmpll1, regmap, &mmpll1_config, true);
-+ clk_pll_configure_sr_hpm_lp(&mmpll3, regmap, &mmpll3_config, false);
-
-- return ret;
-+ return 0;
- }
-
- static int mmcc_msm8974_remove(struct platform_device *pdev)
- {
-- of_clk_del_provider(pdev->dev.of_node);
-- reset_controller_unregister(platform_get_drvdata(pdev));
-+ qcom_cc_remove(pdev);
- return 0;
- }
-
diff --git a/target/linux/ipq806x/patches/0079-clk-qcom-Add-basic-support-for-APQ8064-global-clock-.patch b/target/linux/ipq806x/patches/0079-clk-qcom-Add-basic-support-for-APQ8064-global-clock-.patch
deleted file mode 100644
index 307e797..0000000
--- a/target/linux/ipq806x/patches/0079-clk-qcom-Add-basic-support-for-APQ8064-global-clock-.patch
+++ /dev/null
@@ -1,114 +0,0 @@
-From 0f171b8a6e1723f0ce6f98f8b3fba7d2583088c1 Mon Sep 17 00:00:00 2001
-From: Kumar Gala <galak@codeaurora.org>
-Date: Fri, 4 Apr 2014 11:31:29 -0500
-Subject: [PATCH 079/182] clk: qcom: Add basic support for APQ8064 global
- clock controller clocks
-
-The APQ8064 and MSM8960 share a significant amount of clock data and
-code between the two SoCs. Rather than duplicating the data we just add
-support for a unqiue APQ8064 clock table into the MSM8960 code.
-
-For now add just enough clocks to get a basic serial port going on an
-APQ8064 device.
-
-Signed-off-by: Kumar Gala <galak@codeaurora.org>
-Reviewed-by: Stephen Boyd <sboyd@codeaurora.org>
-Signed-off-by: Mike Turquette <mturquette@linaro.org>
-[mturquette@linaro.org: trivial conflict due to missing ipq8064 support]
----
- .../devicetree/bindings/clock/qcom,gcc.txt | 1 +
- drivers/clk/qcom/Kconfig | 4 +--
- drivers/clk/qcom/gcc-msm8960.c | 30 ++++++++++++++++++--
- 3 files changed, 30 insertions(+), 5 deletions(-)
-
---- a/Documentation/devicetree/bindings/clock/qcom,gcc.txt
-+++ b/Documentation/devicetree/bindings/clock/qcom,gcc.txt
-@@ -4,6 +4,7 @@ Qualcomm Global Clock & Reset Controller
- Required properties :
- - compatible : shall contain only one of the following:
-
-+ "qcom,gcc-apq8064"
- "qcom,gcc-msm8660"
- "qcom,gcc-msm8960"
- "qcom,gcc-msm8974"
---- a/drivers/clk/qcom/Kconfig
-+++ b/drivers/clk/qcom/Kconfig
-@@ -13,10 +13,10 @@ config MSM_GCC_8660
- i2c, USB, SD/eMMC, etc.
-
- config MSM_GCC_8960
-- tristate "MSM8960 Global Clock Controller"
-+ tristate "APQ8064/MSM8960 Global Clock Controller"
- depends on COMMON_CLK_QCOM
- help
-- Support for the global clock controller on msm8960 devices.
-+ Support for the global clock controller on apq8064/msm8960 devices.
- Say Y if you want to use peripheral devices such as UART, SPI,
- i2c, USB, SD/eMMC, SATA, PCIe, etc.
-
---- a/drivers/clk/qcom/gcc-msm8960.c
-+++ b/drivers/clk/qcom/gcc-msm8960.c
-@@ -1,5 +1,5 @@
- /*
-- * Copyright (c) 2013, The Linux Foundation. All rights reserved.
-+ * Copyright (c) 2013-2014, The Linux Foundation. All rights reserved.
- *
- * This software is licensed under the terms of the GNU General Public
- * License version 2, as published by the Free Software Foundation, and
-@@ -2868,6 +2868,16 @@ static const struct qcom_reset_map gcc_m
- [RIVA_RESET] = { 0x35e0 },
- };
-
-+static struct clk_regmap *gcc_apq8064_clks[] = {
-+ [PLL8] = &pll8.clkr,
-+ [PLL8_VOTE] = &pll8_vote,
-+ [GSBI7_UART_SRC] = &gsbi7_uart_src.clkr,
-+ [GSBI7_UART_CLK] = &gsbi7_uart_clk.clkr,
-+ [GSBI7_QUP_SRC] = &gsbi7_qup_src.clkr,
-+ [GSBI7_QUP_CLK] = &gsbi7_qup_clk.clkr,
-+ [GSBI7_H_CLK] = &gsbi7_h_clk.clkr,
-+};
-+
- static const struct regmap_config gcc_msm8960_regmap_config = {
- .reg_bits = 32,
- .reg_stride = 4,
-@@ -2884,8 +2894,17 @@ static const struct qcom_cc_desc gcc_msm
- .num_resets = ARRAY_SIZE(gcc_msm8960_resets),
- };
-
-+static const struct qcom_cc_desc gcc_apq8064_desc = {
-+ .config = &gcc_msm8960_regmap_config,
-+ .clks = gcc_apq8064_clks,
-+ .num_clks = ARRAY_SIZE(gcc_apq8064_clks),
-+ .resets = gcc_msm8960_resets,
-+ .num_resets = ARRAY_SIZE(gcc_msm8960_resets),
-+};
-+
- static const struct of_device_id gcc_msm8960_match_table[] = {
-- { .compatible = "qcom,gcc-msm8960" },
-+ { .compatible = "qcom,gcc-msm8960", .data = &gcc_msm8960_desc },
-+ { .compatible = "qcom,gcc-apq8064", .data = &gcc_apq8064_desc },
- { }
- };
- MODULE_DEVICE_TABLE(of, gcc_msm8960_match_table);
-@@ -2894,6 +2913,11 @@ static int gcc_msm8960_probe(struct plat
- {
- struct clk *clk;
- struct device *dev = &pdev->dev;
-+ const struct of_device_id *match;
-+
-+ match = of_match_device(gcc_msm8960_match_table, &pdev->dev);
-+ if (!match)
-+ return -EINVAL;
-
- /* Temporary until RPM clocks supported */
- clk = clk_register_fixed_rate(dev, "cxo", NULL, CLK_IS_ROOT, 19200000);
-@@ -2904,7 +2928,7 @@ static int gcc_msm8960_probe(struct plat
- if (IS_ERR(clk))
- return PTR_ERR(clk);
-
-- return qcom_cc_probe(pdev, &gcc_msm8960_desc);
-+ return qcom_cc_probe(pdev, match->data);
- }
-
- static int gcc_msm8960_remove(struct platform_device *pdev)
diff --git a/target/linux/ipq806x/patches/0080-clk-qcom-Various-fixes-for-MSM8960-s-global-clock-co.patch b/target/linux/ipq806x/patches/0080-clk-qcom-Various-fixes-for-MSM8960-s-global-clock-co.patch
deleted file mode 100644
index 9731771..0000000
--- a/target/linux/ipq806x/patches/0080-clk-qcom-Various-fixes-for-MSM8960-s-global-clock-co.patch
+++ /dev/null
@@ -1,92 +0,0 @@
-From 7456451e9df88d4c33479e3d4ea124d8a91ceb57 Mon Sep 17 00:00:00 2001
-From: Kumar Gala <galak@codeaurora.org>
-Date: Fri, 4 Apr 2014 11:32:56 -0500
-Subject: [PATCH 080/182] clk: qcom: Various fixes for MSM8960's global clock
- controller
-
-* Remove CE2_SLEEP_CLK, doesn't exist on 8960 family SoCs
-* Fix incorrect offset for PMIC_SSBI2_RESET
-* Fix typo:
- SIC_TIC -> SPS_TIC_H
- SFAB_ADM0_M2_A_CLK -> SFAB_ADM0_M2_H_CLK
-* Fix naming convention:
- SFAB_CFPB_S_HCLK -> SFAB_CFPB_S_H_CLK
- SATA_SRC_CLK -> SATA_CLK_SRC
-
-Signed-off-by: Kumar Gala <galak@codeaurora.org>
-Reviewed-by: Stephen Boyd <sboyd@codeaurora.org>
-Signed-off-by: Mike Turquette <mturquette@linaro.org>
----
- drivers/clk/qcom/gcc-msm8960.c | 4 ++--
- include/dt-bindings/clock/qcom,gcc-msm8960.h | 7 +++----
- include/dt-bindings/reset/qcom,gcc-msm8960.h | 2 +-
- 3 files changed, 6 insertions(+), 7 deletions(-)
-
---- a/drivers/clk/qcom/gcc-msm8960.c
-+++ b/drivers/clk/qcom/gcc-msm8960.c
-@@ -2810,7 +2810,7 @@ static const struct qcom_reset_map gcc_m
- [PPSS_PROC_RESET] = { 0x2594, 1 },
- [PPSS_RESET] = { 0x2594},
- [DMA_BAM_RESET] = { 0x25c0, 7 },
-- [SIC_TIC_RESET] = { 0x2600, 7 },
-+ [SPS_TIC_H_RESET] = { 0x2600, 7 },
- [SLIMBUS_H_RESET] = { 0x2620, 7 },
- [SFAB_CFPB_M_RESET] = { 0x2680, 7 },
- [SFAB_CFPB_S_RESET] = { 0x26c0, 7 },
-@@ -2823,7 +2823,7 @@ static const struct qcom_reset_map gcc_m
- [SFAB_SFPB_M_RESET] = { 0x2780, 7 },
- [SFAB_SFPB_S_RESET] = { 0x27a0, 7 },
- [RPM_PROC_RESET] = { 0x27c0, 7 },
-- [PMIC_SSBI2_RESET] = { 0x270c, 12 },
-+ [PMIC_SSBI2_RESET] = { 0x280c, 12 },
- [SDC1_RESET] = { 0x2830 },
- [SDC2_RESET] = { 0x2850 },
- [SDC3_RESET] = { 0x2870 },
---- a/include/dt-bindings/clock/qcom,gcc-msm8960.h
-+++ b/include/dt-bindings/clock/qcom,gcc-msm8960.h
-@@ -51,7 +51,7 @@
- #define QDSS_TSCTR_CLK 34
- #define SFAB_ADM0_M0_A_CLK 35
- #define SFAB_ADM0_M1_A_CLK 36
--#define SFAB_ADM0_M2_A_CLK 37
-+#define SFAB_ADM0_M2_H_CLK 37
- #define ADM0_CLK 38
- #define ADM0_PBUS_CLK 39
- #define MSS_XPU_CLK 40
-@@ -99,7 +99,7 @@
- #define CFPB2_H_CLK 82
- #define SFAB_CFPB_M_H_CLK 83
- #define CFPB_MASTER_H_CLK 84
--#define SFAB_CFPB_S_HCLK 85
-+#define SFAB_CFPB_S_H_CLK 85
- #define CFPB_SPLITTER_H_CLK 86
- #define TSIF_H_CLK 87
- #define TSIF_INACTIVITY_TIMERS_CLK 88
-@@ -110,7 +110,6 @@
- #define CE1_SLEEP_CLK 93
- #define CE2_H_CLK 94
- #define CE2_CORE_CLK 95
--#define CE2_SLEEP_CLK 96
- #define SFPB_H_CLK_SRC 97
- #define SFPB_H_CLK 98
- #define SFAB_SFPB_M_H_CLK 99
-@@ -252,7 +251,7 @@
- #define MSS_S_H_CLK 235
- #define MSS_CXO_SRC_CLK 236
- #define SATA_H_CLK 237
--#define SATA_SRC_CLK 238
-+#define SATA_CLK_SRC 238
- #define SATA_RXOOB_CLK 239
- #define SATA_PMALIVE_CLK 240
- #define SATA_PHY_REF_CLK 241
---- a/include/dt-bindings/reset/qcom,gcc-msm8960.h
-+++ b/include/dt-bindings/reset/qcom,gcc-msm8960.h
-@@ -58,7 +58,7 @@
- #define PPSS_PROC_RESET 41
- #define PPSS_RESET 42
- #define DMA_BAM_RESET 43
--#define SIC_TIC_RESET 44
-+#define SPS_TIC_H_RESET 44
- #define SLIMBUS_H_RESET 45
- #define SFAB_CFPB_M_RESET 46
- #define SFAB_CFPB_S_RESET 47
diff --git a/target/linux/ipq806x/patches/0081-ARM-config-Add-qcom_defconfig.patch b/target/linux/ipq806x/patches/0081-ARM-config-Add-qcom_defconfig.patch
deleted file mode 100644
index dd87c1f..0000000
--- a/target/linux/ipq806x/patches/0081-ARM-config-Add-qcom_defconfig.patch
+++ /dev/null
@@ -1,184 +0,0 @@
-From e1f51c2d41c8936b8383cf4ac53c1ff05b0e2e2f Mon Sep 17 00:00:00 2001
-From: Stephen Boyd <sboyd@codeaurora.org>
-Date: Thu, 27 Feb 2014 12:54:24 -0800
-Subject: [PATCH 081/182] ARM: config: Add qcom_defconfig
-
-Add a defconfig for mach-qcom platforms (copied from msm_defconfig).
-Although these platforms are part of the multi-platform kernel, it's
-useful to have a stripped down version of the defconfig that just
-selects the DT based Qualcomm platforms and drivers.
-
-Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
-Signed-off-by: Kumar Gala <galak@codeaurora.org>
----
- arch/arm/configs/qcom_defconfig | 164 +++++++++++++++++++++++++++++++++++++++
- 1 file changed, 164 insertions(+)
- create mode 100644 arch/arm/configs/qcom_defconfig
-
---- /dev/null
-+++ b/arch/arm/configs/qcom_defconfig
-@@ -0,0 +1,164 @@
-+CONFIG_SYSVIPC=y
-+CONFIG_NO_HZ=y
-+CONFIG_HIGH_RES_TIMERS=y
-+CONFIG_IKCONFIG=y
-+CONFIG_IKCONFIG_PROC=y
-+CONFIG_BLK_DEV_INITRD=y
-+CONFIG_SYSCTL_SYSCALL=y
-+CONFIG_KALLSYMS_ALL=y
-+CONFIG_EMBEDDED=y
-+# CONFIG_SLUB_DEBUG is not set
-+# CONFIG_COMPAT_BRK is not set
-+CONFIG_PROFILING=y
-+CONFIG_OPROFILE=y
-+CONFIG_KPROBES=y
-+CONFIG_MODULES=y
-+CONFIG_MODULE_UNLOAD=y
-+CONFIG_MODULE_FORCE_UNLOAD=y
-+CONFIG_MODVERSIONS=y
-+CONFIG_PARTITION_ADVANCED=y
-+CONFIG_ARCH_QCOM=y
-+CONFIG_ARCH_MSM8X60=y
-+CONFIG_ARCH_MSM8960=y
-+CONFIG_ARCH_MSM8974=y
-+CONFIG_SMP=y
-+CONFIG_PREEMPT=y
-+CONFIG_AEABI=y
-+CONFIG_HIGHMEM=y
-+CONFIG_HIGHPTE=y
-+CONFIG_CLEANCACHE=y
-+CONFIG_ARM_APPENDED_DTB=y
-+CONFIG_ARM_ATAG_DTB_COMPAT=y
-+CONFIG_VFP=y
-+CONFIG_NEON=y
-+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
-+CONFIG_NET=y
-+CONFIG_PACKET=y
-+CONFIG_UNIX=y
-+CONFIG_INET=y
-+CONFIG_IP_ADVANCED_ROUTER=y
-+CONFIG_IP_MULTIPLE_TABLES=y
-+CONFIG_IP_ROUTE_VERBOSE=y
-+CONFIG_IP_PNP=y
-+CONFIG_IP_PNP_DHCP=y
-+# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
-+# CONFIG_INET_XFRM_MODE_TUNNEL is not set
-+# CONFIG_INET_XFRM_MODE_BEET is not set
-+# CONFIG_INET_LRO is not set
-+# CONFIG_IPV6 is not set
-+CONFIG_CFG80211=y
-+CONFIG_RFKILL=y
-+CONFIG_DEVTMPFS=y
-+CONFIG_DEVTMPFS_MOUNT=y
-+CONFIG_MTD=y
-+CONFIG_MTD_BLOCK=y
-+CONFIG_MTD_M25P80=y
-+CONFIG_BLK_DEV_LOOP=y
-+CONFIG_BLK_DEV_RAM=y
-+CONFIG_SCSI=y
-+CONFIG_SCSI_TGT=y
-+CONFIG_BLK_DEV_SD=y
-+CONFIG_CHR_DEV_SG=y
-+CONFIG_CHR_DEV_SCH=y
-+CONFIG_SCSI_MULTI_LUN=y
-+CONFIG_SCSI_CONSTANTS=y
-+CONFIG_SCSI_LOGGING=y
-+CONFIG_SCSI_SCAN_ASYNC=y
-+CONFIG_NETDEVICES=y
-+CONFIG_DUMMY=y
-+CONFIG_MDIO_BITBANG=y
-+CONFIG_MDIO_GPIO=y
-+CONFIG_SLIP=y
-+CONFIG_SLIP_COMPRESSED=y
-+CONFIG_SLIP_MODE_SLIP6=y
-+CONFIG_USB_USBNET=y
-+# CONFIG_USB_NET_AX8817X is not set
-+# CONFIG_USB_NET_ZAURUS is not set
-+CONFIG_INPUT_EVDEV=y
-+# CONFIG_KEYBOARD_ATKBD is not set
-+# CONFIG_MOUSE_PS2 is not set
-+CONFIG_INPUT_JOYSTICK=y
-+CONFIG_INPUT_TOUCHSCREEN=y
-+CONFIG_INPUT_MISC=y
-+CONFIG_INPUT_UINPUT=y
-+CONFIG_SERIO_LIBPS2=y
-+# CONFIG_LEGACY_PTYS is not set
-+CONFIG_SERIAL_MSM=y
-+CONFIG_SERIAL_MSM_CONSOLE=y
-+CONFIG_HW_RANDOM=y
-+CONFIG_HW_RANDOM_MSM=y
-+CONFIG_I2C=y
-+CONFIG_I2C_CHARDEV=y
-+CONFIG_I2C_QUP=y
-+CONFIG_SPI=y
-+CONFIG_SPI_QUP=y
-+CONFIG_SPMI=y
-+CONFIG_PINCTRL_APQ8064=y
-+CONFIG_PINCTRL_IPQ8064=y
-+CONFIG_PINCTRL_MSM8X74=y
-+CONFIG_DEBUG_GPIO=y
-+CONFIG_GPIO_SYSFS=y
-+CONFIG_POWER_SUPPLY=y
-+CONFIG_POWER_RESET=y
-+CONFIG_POWER_RESET_MSM=y
-+CONFIG_THERMAL=y
-+CONFIG_REGULATOR=y
-+CONFIG_MEDIA_SUPPORT=y
-+CONFIG_FB=y
-+CONFIG_SOUND=y
-+CONFIG_SND=y
-+CONFIG_SND_DYNAMIC_MINORS=y
-+# CONFIG_SND_ARM is not set
-+# CONFIG_SND_SPI is not set
-+# CONFIG_SND_USB is not set
-+CONFIG_SND_SOC=y
-+CONFIG_HID_BATTERY_STRENGTH=y
-+CONFIG_USB=y
-+CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
-+CONFIG_USB_MON=y
-+CONFIG_USB_EHCI_HCD=y
-+CONFIG_USB_ACM=y
-+CONFIG_USB_SERIAL=y
-+CONFIG_USB_GADGET=y
-+CONFIG_USB_GADGET_DEBUG_FILES=y
-+CONFIG_USB_GADGET_VBUS_DRAW=500
-+CONFIG_MMC=y
-+CONFIG_MMC_BLOCK_MINORS=16
-+CONFIG_MMC_SDHCI=y
-+CONFIG_MMC_SDHCI_PLTFM=y
-+CONFIG_MMC_SDHCI_MSM=y
-+CONFIG_RTC_CLASS=y
-+CONFIG_DMADEVICES=y
-+CONFIG_QCOM_BAM_DMA=y
-+CONFIG_STAGING=y
-+CONFIG_COMMON_CLK_QCOM=y
-+CONFIG_MSM_GCC_8660=y
-+CONFIG_MSM_MMCC_8960=y
-+CONFIG_MSM_MMCC_8974=y
-+CONFIG_MSM_IOMMU=y
-+CONFIG_GENERIC_PHY=y
-+CONFIG_EXT2_FS=y
-+CONFIG_EXT2_FS_XATTR=y
-+CONFIG_EXT3_FS=y
-+# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
-+CONFIG_EXT4_FS=y
-+CONFIG_FUSE_FS=y
-+CONFIG_VFAT_FS=y
-+CONFIG_TMPFS=y
-+CONFIG_JFFS2_FS=y
-+CONFIG_NFS_FS=y
-+CONFIG_NFS_V3_ACL=y
-+CONFIG_NFS_V4=y
-+CONFIG_CIFS=y
-+CONFIG_NLS_CODEPAGE_437=y
-+CONFIG_NLS_ASCII=y
-+CONFIG_NLS_ISO8859_1=y
-+CONFIG_NLS_UTF8=y
-+CONFIG_PRINTK_TIME=y
-+CONFIG_DYNAMIC_DEBUG=y
-+CONFIG_DEBUG_INFO=y
-+CONFIG_MAGIC_SYSRQ=y
-+CONFIG_LOCKUP_DETECTOR=y
-+# CONFIG_DETECT_HUNG_TASK is not set
-+# CONFIG_SCHED_DEBUG is not set
-+CONFIG_TIMER_STATS=y
diff --git a/target/linux/ipq806x/patches/0082-ARM-qcom-Enable-GSBI-driver-in-defconfig.patch b/target/linux/ipq806x/patches/0082-ARM-qcom-Enable-GSBI-driver-in-defconfig.patch
deleted file mode 100644
index 180f102..0000000
--- a/target/linux/ipq806x/patches/0082-ARM-qcom-Enable-GSBI-driver-in-defconfig.patch
+++ /dev/null
@@ -1,20 +0,0 @@
-From d247fb8a019e4cc5a607c7fff9922e8e98c2c660 Mon Sep 17 00:00:00 2001
-From: Kumar Gala <galak@codeaurora.org>
-Date: Thu, 29 May 2014 11:25:24 -0500
-Subject: [PATCH 082/182] ARM: qcom: Enable GSBI driver in defconfig
-
-Signed-off-by: Kumar Gala <galak@codeaurora.org>
----
- arch/arm/configs/qcom_defconfig | 1 +
- 1 file changed, 1 insertion(+)
-
---- a/arch/arm/configs/qcom_defconfig
-+++ b/arch/arm/configs/qcom_defconfig
-@@ -131,6 +131,7 @@ CONFIG_RTC_CLASS=y
- CONFIG_DMADEVICES=y
- CONFIG_QCOM_BAM_DMA=y
- CONFIG_STAGING=y
-+CONFIG_QCOM_GSBI=y
- CONFIG_COMMON_CLK_QCOM=y
- CONFIG_MSM_GCC_8660=y
- CONFIG_MSM_MMCC_8960=y
diff --git a/target/linux/ipq806x/patches/0083-soc-Introduce-drivers-soc-place-holder-for-SOC-speci.patch b/target/linux/ipq806x/patches/0083-soc-Introduce-drivers-soc-place-holder-for-SOC-speci.patch
deleted file mode 100644
index 5f173fb..0000000
--- a/target/linux/ipq806x/patches/0083-soc-Introduce-drivers-soc-place-holder-for-SOC-speci.patch
+++ /dev/null
@@ -1,58 +0,0 @@
-From 2dac9498966c79a6abb09764419ffd42a44c78cf Mon Sep 17 00:00:00 2001
-From: Santosh Shilimkar <santosh.shilimkar@ti.com>
-Date: Wed, 23 Apr 2014 19:46:17 -0400
-Subject: [PATCH 083/182] soc: Introduce drivers/soc place-holder for SOC
- specific drivers
-
-Based on earlier thread "https://lkml.org/lkml/2013/10/7/662" and
-discussion at Kernel Summit'2013, it was agreed to create
-'driver/soc' for drivers which are quite SOC specific.
-
-Further discussion on the subject is in response to
-the earlier version of the patch is here:
- http://lwn.net/Articles/588942/
-
-Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-Cc: Kumar Gala <galak@codeaurora.org>
-Cc: Paul Walmsley <paul@pwsan.com>
-Cc: Olof Johansson <olof@lixom.net>
-Cc: Arnd Bergmann <arnd@arndb.de>
-Signed-off-by: Sandeep Nair <sandeep_n@ti.com>
-Signed-off-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
-Signed-off-by: Kumar Gala <galak@codeaurora.org>
----
- drivers/Kconfig | 2 ++
- drivers/Makefile | 3 +++
- drivers/soc/Kconfig | 3 +++
- 3 files changed, 8 insertions(+)
- create mode 100644 drivers/soc/Kconfig
-
---- a/drivers/Kconfig
-+++ b/drivers/Kconfig
-@@ -132,6 +132,8 @@ source "drivers/staging/Kconfig"
-
- source "drivers/platform/Kconfig"
-
-+source "drivers/soc/Kconfig"
-+
- source "drivers/clk/Kconfig"
-
- source "drivers/hwspinlock/Kconfig"
---- a/drivers/Makefile
-+++ b/drivers/Makefile
-@@ -33,6 +33,9 @@ obj-y += amba/
- # really early.
- obj-$(CONFIG_DMADEVICES) += dma/
-
-+# SOC specific infrastructure drivers.
-+obj-y += soc/
-+
- obj-$(CONFIG_VIRTIO) += virtio/
- obj-$(CONFIG_XEN) += xen/
-
---- /dev/null
-+++ b/drivers/soc/Kconfig
-@@ -0,0 +1,3 @@
-+menu "SOC (System On Chip) specific Drivers"
-+
-+endmenu
diff --git a/target/linux/ipq806x/patches/0084-soc-qcom-Add-GSBI-driver.patch b/target/linux/ipq806x/patches/0084-soc-qcom-Add-GSBI-driver.patch
deleted file mode 100644
index 545c4be..0000000
--- a/target/linux/ipq806x/patches/0084-soc-qcom-Add-GSBI-driver.patch
+++ /dev/null
@@ -1,145 +0,0 @@
-From a2f0fc20ea49e5dbbdbb21444683ea760fbdd38f Mon Sep 17 00:00:00 2001
-From: Andy Gross <agross@codeaurora.org>
-Date: Thu, 24 Apr 2014 11:31:21 -0500
-Subject: [PATCH 084/182] soc: qcom: Add GSBI driver
-
-The GSBI (General Serial Bus Interface) driver controls the overarching
-configuration of the shared serial bus infrastructure on APQ8064, IPQ8064, and
-earlier QCOM processors. The GSBI supports UART, I2C, SPI, and UIM
-functionality in various combinations.
-
-Signed-off-by: Andy Gross <agross@codeaurora.org>
-Signed-off-by: Kumar Gala <galak@codeaurora.org>
----
- drivers/soc/Kconfig | 2 +
- drivers/soc/Makefile | 5 +++
- drivers/soc/qcom/Kconfig | 11 ++++++
- drivers/soc/qcom/Makefile | 1 +
- drivers/soc/qcom/qcom_gsbi.c | 84 ++++++++++++++++++++++++++++++++++++++++++
- 5 files changed, 103 insertions(+)
- create mode 100644 drivers/soc/Makefile
- create mode 100644 drivers/soc/qcom/Kconfig
- create mode 100644 drivers/soc/qcom/Makefile
- create mode 100644 drivers/soc/qcom/qcom_gsbi.c
-
---- a/drivers/soc/Kconfig
-+++ b/drivers/soc/Kconfig
-@@ -1,3 +1,5 @@
- menu "SOC (System On Chip) specific Drivers"
-
-+source "drivers/soc/qcom/Kconfig"
-+
- endmenu
---- /dev/null
-+++ b/drivers/soc/Makefile
-@@ -0,0 +1,5 @@
-+#
-+# Makefile for the Linux Kernel SOC specific device drivers.
-+#
-+
-+obj-$(CONFIG_ARCH_QCOM) += qcom/
---- /dev/null
-+++ b/drivers/soc/qcom/Kconfig
-@@ -0,0 +1,11 @@
-+#
-+# QCOM Soc drivers
-+#
-+config QCOM_GSBI
-+ tristate "QCOM General Serial Bus Interface"
-+ depends on ARCH_QCOM
-+ help
-+ Say y here to enable GSBI support. The GSBI provides control
-+ functions for connecting the underlying serial UART, SPI, and I2C
-+ devices to the output pins.
-+
---- /dev/null
-+++ b/drivers/soc/qcom/Makefile
-@@ -0,0 +1 @@
-+obj-$(CONFIG_QCOM_GSBI) += qcom_gsbi.o
---- /dev/null
-+++ b/drivers/soc/qcom/qcom_gsbi.c
-@@ -0,0 +1,84 @@
-+/*
-+ * Copyright (c) 2014, The Linux foundation. All rights reserved.
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License rev 2 and
-+ * only rev 2 as published by the free Software foundation.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or fITNESS fOR A PARTICULAR PURPOSE. See the
-+ * GNU General Public License for more details.
-+ */
-+
-+#include <linux/clk.h>
-+#include <linux/err.h>
-+#include <linux/io.h>
-+#include <linux/module.h>
-+#include <linux/of.h>
-+#include <linux/of_platform.h>
-+#include <linux/platform_device.h>
-+
-+#define GSBI_CTRL_REG 0x0000
-+#define GSBI_PROTOCOL_SHIFT 4
-+
-+static int gsbi_probe(struct platform_device *pdev)
-+{
-+ struct device_node *node = pdev->dev.of_node;
-+ struct resource *res;
-+ void __iomem *base;
-+ struct clk *hclk;
-+ u32 mode, crci = 0;
-+
-+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-+ base = devm_ioremap_resource(&pdev->dev, res);
-+ if (IS_ERR(base))
-+ return PTR_ERR(base);
-+
-+ if (of_property_read_u32(node, "qcom,mode", &mode)) {
-+ dev_err(&pdev->dev, "missing mode configuration\n");
-+ return -EINVAL;
-+ }
-+
-+ /* not required, so default to 0 if not present */
-+ of_property_read_u32(node, "qcom,crci", &crci);
-+
-+ dev_info(&pdev->dev, "GSBI port protocol: %d crci: %d\n", mode, crci);
-+
-+ hclk = devm_clk_get(&pdev->dev, "iface");
-+ if (IS_ERR(hclk))
-+ return PTR_ERR(hclk);
-+
-+ clk_prepare_enable(hclk);
-+
-+ writel_relaxed((mode << GSBI_PROTOCOL_SHIFT) | crci,
-+ base + GSBI_CTRL_REG);
-+
-+ /* make sure the gsbi control write is not reordered */
-+ wmb();
-+
-+ clk_disable_unprepare(hclk);
-+
-+ return of_platform_populate(pdev->dev.of_node, NULL, NULL, &pdev->dev);
-+}
-+
-+static const struct of_device_id gsbi_dt_match[] = {
-+ { .compatible = "qcom,gsbi-v1.0.0", },
-+};
-+
-+MODULE_DEVICE_TABLE(of, gsbi_dt_match);
-+
-+static struct platform_driver gsbi_driver = {
-+ .driver = {
-+ .name = "gsbi",
-+ .owner = THIS_MODULE,
-+ .of_match_table = gsbi_dt_match,
-+ },
-+ .probe = gsbi_probe,
-+};
-+
-+module_platform_driver(gsbi_driver);
-+
-+MODULE_AUTHOR("Andy Gross <agross@codeaurora.org>");
-+MODULE_DESCRIPTION("QCOM GSBI driver");
-+MODULE_LICENSE("GPL v2");
diff --git a/target/linux/ipq806x/patches/0085-soc-qcom-fix-of_device_id-table.patch b/target/linux/ipq806x/patches/0085-soc-qcom-fix-of_device_id-table.patch
deleted file mode 100644
index 3c58107..0000000
--- a/target/linux/ipq806x/patches/0085-soc-qcom-fix-of_device_id-table.patch
+++ /dev/null
@@ -1,23 +0,0 @@
-From 8efaabc573e58f4b891340f4aedb34f9d0656067 Mon Sep 17 00:00:00 2001
-From: Arnd Bergmann <arnd@arndb.de>
-Date: Mon, 26 May 2014 18:07:05 +0200
-Subject: [PATCH 085/182] soc: qcom: fix of_device_id table
-
-The match tables must be zero-terminated, and Kbuild now helpfully
-fails to link the kernel if that isn't the case.
-
-Signed-off-by: Arnd Bergmann <arnd@arndb.de>
----
- drivers/soc/qcom/qcom_gsbi.c | 1 +
- 1 file changed, 1 insertion(+)
-
---- a/drivers/soc/qcom/qcom_gsbi.c
-+++ b/drivers/soc/qcom/qcom_gsbi.c
-@@ -64,6 +64,7 @@ static int gsbi_probe(struct platform_de
-
- static const struct of_device_id gsbi_dt_match[] = {
- { .compatible = "qcom,gsbi-v1.0.0", },
-+ { },
- };
-
- MODULE_DEVICE_TABLE(of, gsbi_dt_match);
diff --git a/target/linux/ipq806x/patches/0086-msm_serial-Add-support-for-poll_-get-put-_char.patch b/target/linux/ipq806x/patches/0086-msm_serial-Add-support-for-poll_-get-put-_char.patch
deleted file mode 100644
index 68204c5..0000000
--- a/target/linux/ipq806x/patches/0086-msm_serial-Add-support-for-poll_-get-put-_char.patch
+++ /dev/null
@@ -1,239 +0,0 @@
-From 48ab619dd6e308c57dac3e5d022a3099806bf79e Mon Sep 17 00:00:00 2001
-From: Stephen Boyd <sboyd@codeaurora.org>
-Date: Tue, 14 Jan 2014 12:34:55 -0800
-Subject: [PATCH 086/182] msm_serial: Add support for poll_{get,put}_char()
-
-Implement the polling functionality for the MSM serial driver.
-This allows us to use KGDB on this hardware.
-
-Cc: David Brown <davidb@codeaurora.org>
-Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/tty/serial/msm_serial.c | 140 ++++++++++++++++++++++++++++++++++++++-
- drivers/tty/serial/msm_serial.h | 9 +++
- 2 files changed, 146 insertions(+), 3 deletions(-)
-
---- a/drivers/tty/serial/msm_serial.c
-+++ b/drivers/tty/serial/msm_serial.c
-@@ -39,6 +39,13 @@
-
- #include "msm_serial.h"
-
-+enum {
-+ UARTDM_1P1 = 1,
-+ UARTDM_1P2,
-+ UARTDM_1P3,
-+ UARTDM_1P4,
-+};
-+
- struct msm_port {
- struct uart_port uart;
- char name[16];
-@@ -309,6 +316,8 @@ static unsigned int msm_get_mctrl(struct
-
- static void msm_reset(struct uart_port *port)
- {
-+ struct msm_port *msm_port = UART_TO_MSM(port);
-+
- /* reset everything */
- msm_write(port, UART_CR_CMD_RESET_RX, UART_CR);
- msm_write(port, UART_CR_CMD_RESET_TX, UART_CR);
-@@ -316,6 +325,10 @@ static void msm_reset(struct uart_port *
- msm_write(port, UART_CR_CMD_RESET_BREAK_INT, UART_CR);
- msm_write(port, UART_CR_CMD_RESET_CTS, UART_CR);
- msm_write(port, UART_CR_CMD_SET_RFR, UART_CR);
-+
-+ /* Disable DM modes */
-+ if (msm_port->is_uartdm)
-+ msm_write(port, 0, UARTDM_DMEN);
- }
-
- static void msm_set_mctrl(struct uart_port *port, unsigned int mctrl)
-@@ -711,6 +724,117 @@ static void msm_power(struct uart_port *
- }
- }
-
-+#ifdef CONFIG_CONSOLE_POLL
-+static int msm_poll_init(struct uart_port *port)
-+{
-+ struct msm_port *msm_port = UART_TO_MSM(port);
-+
-+ /* Enable single character mode on RX FIFO */
-+ if (msm_port->is_uartdm >= UARTDM_1P4)
-+ msm_write(port, UARTDM_DMEN_RX_SC_ENABLE, UARTDM_DMEN);
-+
-+ return 0;
-+}
-+
-+static int msm_poll_get_char_single(struct uart_port *port)
-+{
-+ struct msm_port *msm_port = UART_TO_MSM(port);
-+ unsigned int rf_reg = msm_port->is_uartdm ? UARTDM_RF : UART_RF;
-+
-+ if (!(msm_read(port, UART_SR) & UART_SR_RX_READY))
-+ return NO_POLL_CHAR;
-+ else
-+ return msm_read(port, rf_reg) & 0xff;
-+}
-+
-+static int msm_poll_get_char_dm_1p3(struct uart_port *port)
-+{
-+ int c;
-+ static u32 slop;
-+ static int count;
-+ unsigned char *sp = (unsigned char *)&slop;
-+
-+ /* Check if a previous read had more than one char */
-+ if (count) {
-+ c = sp[sizeof(slop) - count];
-+ count--;
-+ /* Or if FIFO is empty */
-+ } else if (!(msm_read(port, UART_SR) & UART_SR_RX_READY)) {
-+ /*
-+ * If RX packing buffer has less than a word, force stale to
-+ * push contents into RX FIFO
-+ */
-+ count = msm_read(port, UARTDM_RXFS);
-+ count = (count >> UARTDM_RXFS_BUF_SHIFT) & UARTDM_RXFS_BUF_MASK;
-+ if (count) {
-+ msm_write(port, UART_CR_CMD_FORCE_STALE, UART_CR);
-+ slop = msm_read(port, UARTDM_RF);
-+ c = sp[0];
-+ count--;
-+ } else {
-+ c = NO_POLL_CHAR;
-+ }
-+ /* FIFO has a word */
-+ } else {
-+ slop = msm_read(port, UARTDM_RF);
-+ c = sp[0];
-+ count = sizeof(slop) - 1;
-+ }
-+
-+ return c;
-+}
-+
-+static int msm_poll_get_char(struct uart_port *port)
-+{
-+ u32 imr;
-+ int c;
-+ struct msm_port *msm_port = UART_TO_MSM(port);
-+
-+ /* Disable all interrupts */
-+ imr = msm_read(port, UART_IMR);
-+ msm_write(port, 0, UART_IMR);
-+
-+ if (msm_port->is_uartdm == UARTDM_1P3)
-+ c = msm_poll_get_char_dm_1p3(port);
-+ else
-+ c = msm_poll_get_char_single(port);
-+
-+ /* Enable interrupts */
-+ msm_write(port, imr, UART_IMR);
-+
-+ return c;
-+}
-+
-+static void msm_poll_put_char(struct uart_port *port, unsigned char c)
-+{
-+ u32 imr;
-+ struct msm_port *msm_port = UART_TO_MSM(port);
-+
-+ /* Disable all interrupts */
-+ imr = msm_read(port, UART_IMR);
-+ msm_write(port, 0, UART_IMR);
-+
-+ if (msm_port->is_uartdm)
-+ reset_dm_count(port, 1);
-+
-+ /* Wait until FIFO is empty */
-+ while (!(msm_read(port, UART_SR) & UART_SR_TX_READY))
-+ cpu_relax();
-+
-+ /* Write a character */
-+ msm_write(port, c, msm_port->is_uartdm ? UARTDM_TF : UART_TF);
-+
-+ /* Wait until FIFO is empty */
-+ while (!(msm_read(port, UART_SR) & UART_SR_TX_READY))
-+ cpu_relax();
-+
-+ /* Enable interrupts */
-+ msm_write(port, imr, UART_IMR);
-+
-+ return;
-+}
-+#endif
-+
- static struct uart_ops msm_uart_pops = {
- .tx_empty = msm_tx_empty,
- .set_mctrl = msm_set_mctrl,
-@@ -729,6 +853,11 @@ static struct uart_ops msm_uart_pops = {
- .config_port = msm_config_port,
- .verify_port = msm_verify_port,
- .pm = msm_power,
-+#ifdef CONFIG_CONSOLE_POLL
-+ .poll_init = msm_poll_init,
-+ .poll_get_char = msm_poll_get_char,
-+ .poll_put_char = msm_poll_put_char,
-+#endif
- };
-
- static struct msm_port msm_uart_ports[] = {
-@@ -900,7 +1029,10 @@ static struct uart_driver msm_uart_drive
- static atomic_t msm_uart_next_id = ATOMIC_INIT(0);
-
- static const struct of_device_id msm_uartdm_table[] = {
-- { .compatible = "qcom,msm-uartdm" },
-+ { .compatible = "qcom,msm-uartdm-v1.1", .data = (void *)UARTDM_1P1 },
-+ { .compatible = "qcom,msm-uartdm-v1.2", .data = (void *)UARTDM_1P2 },
-+ { .compatible = "qcom,msm-uartdm-v1.3", .data = (void *)UARTDM_1P3 },
-+ { .compatible = "qcom,msm-uartdm-v1.4", .data = (void *)UARTDM_1P4 },
- { }
- };
-
-@@ -909,6 +1041,7 @@ static int __init msm_serial_probe(struc
- struct msm_port *msm_port;
- struct resource *resource;
- struct uart_port *port;
-+ const struct of_device_id *id;
- int irq;
-
- if (pdev->id == -1)
-@@ -923,8 +1056,9 @@ static int __init msm_serial_probe(struc
- port->dev = &pdev->dev;
- msm_port = UART_TO_MSM(port);
-
-- if (of_match_device(msm_uartdm_table, &pdev->dev))
-- msm_port->is_uartdm = 1;
-+ id = of_match_device(msm_uartdm_table, &pdev->dev);
-+ if (id)
-+ msm_port->is_uartdm = (unsigned long)id->data;
- else
- msm_port->is_uartdm = 0;
-
---- a/drivers/tty/serial/msm_serial.h
-+++ b/drivers/tty/serial/msm_serial.h
-@@ -59,6 +59,7 @@
- #define UART_CR_CMD_RESET_RFR (14 << 4)
- #define UART_CR_CMD_PROTECTION_EN (16 << 4)
- #define UART_CR_CMD_STALE_EVENT_ENABLE (80 << 4)
-+#define UART_CR_CMD_FORCE_STALE (4 << 8)
- #define UART_CR_CMD_RESET_TX_READY (3 << 8)
- #define UART_CR_TX_DISABLE (1 << 3)
- #define UART_CR_TX_ENABLE (1 << 2)
-@@ -113,6 +114,14 @@
- #define GSBI_PROTOCOL_UART 0x40
- #define GSBI_PROTOCOL_IDLE 0x0
-
-+#define UARTDM_RXFS 0x50
-+#define UARTDM_RXFS_BUF_SHIFT 0x7
-+#define UARTDM_RXFS_BUF_MASK 0x7
-+
-+#define UARTDM_DMEN 0x3C
-+#define UARTDM_DMEN_RX_SC_ENABLE BIT(5)
-+#define UARTDM_DMEN_TX_SC_ENABLE BIT(4)
-+
- #define UARTDM_DMRX 0x34
- #define UARTDM_NCF_TX 0x40
- #define UARTDM_RX_TOTAL_SNAP 0x38
diff --git a/target/linux/ipq806x/patches/0087-tty-serial-msm-Remove-direct-access-to-GSBI.patch b/target/linux/ipq806x/patches/0087-tty-serial-msm-Remove-direct-access-to-GSBI.patch
deleted file mode 100644
index 9eb7138..0000000
--- a/target/linux/ipq806x/patches/0087-tty-serial-msm-Remove-direct-access-to-GSBI.patch
+++ /dev/null
@@ -1,144 +0,0 @@
-From 025909cbf933cc20c2ff5ea9f87de8e17a739a08 Mon Sep 17 00:00:00 2001
-From: Andy Gross <agross@codeaurora.org>
-Date: Thu, 24 Apr 2014 11:31:22 -0500
-Subject: [PATCH 087/182] tty: serial: msm: Remove direct access to GSBI
-
-This patch removes direct access of the GSBI registers. GSBI configuration
-should be done through the GSBI driver directly.
-
-Signed-off-by: Andy Gross <agross@codeaurora.org>
-Signed-off-by: Kumar Gala <galak@codeaurora.org>
----
- drivers/tty/serial/msm_serial.c | 48 ++-------------------------------------
- drivers/tty/serial/msm_serial.h | 5 ----
- 2 files changed, 2 insertions(+), 51 deletions(-)
-
---- a/drivers/tty/serial/msm_serial.c
-+++ b/drivers/tty/serial/msm_serial.c
-@@ -52,7 +52,6 @@ struct msm_port {
- struct clk *clk;
- struct clk *pclk;
- unsigned int imr;
-- void __iomem *gsbi_base;
- int is_uartdm;
- unsigned int old_snap_state;
- };
-@@ -599,9 +598,7 @@ static const char *msm_type(struct uart_
- static void msm_release_port(struct uart_port *port)
- {
- struct platform_device *pdev = to_platform_device(port->dev);
-- struct msm_port *msm_port = UART_TO_MSM(port);
- struct resource *uart_resource;
-- struct resource *gsbi_resource;
- resource_size_t size;
-
- uart_resource = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-@@ -612,28 +609,12 @@ static void msm_release_port(struct uart
- release_mem_region(port->mapbase, size);
- iounmap(port->membase);
- port->membase = NULL;
--
-- if (msm_port->gsbi_base) {
-- writel_relaxed(GSBI_PROTOCOL_IDLE,
-- msm_port->gsbi_base + GSBI_CONTROL);
--
-- gsbi_resource = platform_get_resource(pdev, IORESOURCE_MEM, 1);
-- if (unlikely(!gsbi_resource))
-- return;
--
-- size = resource_size(gsbi_resource);
-- release_mem_region(gsbi_resource->start, size);
-- iounmap(msm_port->gsbi_base);
-- msm_port->gsbi_base = NULL;
-- }
- }
-
- static int msm_request_port(struct uart_port *port)
- {
-- struct msm_port *msm_port = UART_TO_MSM(port);
- struct platform_device *pdev = to_platform_device(port->dev);
- struct resource *uart_resource;
-- struct resource *gsbi_resource;
- resource_size_t size;
- int ret;
-
-@@ -652,30 +633,8 @@ static int msm_request_port(struct uart_
- goto fail_release_port;
- }
-
-- gsbi_resource = platform_get_resource(pdev, IORESOURCE_MEM, 1);
-- /* Is this a GSBI-based port? */
-- if (gsbi_resource) {
-- size = resource_size(gsbi_resource);
--
-- if (!request_mem_region(gsbi_resource->start, size,
-- "msm_serial")) {
-- ret = -EBUSY;
-- goto fail_release_port_membase;
-- }
--
-- msm_port->gsbi_base = ioremap(gsbi_resource->start, size);
-- if (!msm_port->gsbi_base) {
-- ret = -EBUSY;
-- goto fail_release_gsbi;
-- }
-- }
--
- return 0;
-
--fail_release_gsbi:
-- release_mem_region(gsbi_resource->start, size);
--fail_release_port_membase:
-- iounmap(port->membase);
- fail_release_port:
- release_mem_region(port->mapbase, size);
- return ret;
-@@ -683,7 +642,6 @@ fail_release_port:
-
- static void msm_config_port(struct uart_port *port, int flags)
- {
-- struct msm_port *msm_port = UART_TO_MSM(port);
- int ret;
- if (flags & UART_CONFIG_TYPE) {
- port->type = PORT_MSM;
-@@ -691,9 +649,6 @@ static void msm_config_port(struct uart_
- if (ret)
- return;
- }
-- if (msm_port->gsbi_base)
-- writel_relaxed(GSBI_PROTOCOL_UART,
-- msm_port->gsbi_base + GSBI_CONTROL);
- }
-
- static int msm_verify_port(struct uart_port *port, struct serial_struct *ser)
-@@ -1110,6 +1065,7 @@ static struct of_device_id msm_match_tab
-
- static struct platform_driver msm_platform_driver = {
- .remove = msm_serial_remove,
-+ .probe = msm_serial_probe,
- .driver = {
- .name = "msm_serial",
- .owner = THIS_MODULE,
-@@ -1125,7 +1081,7 @@ static int __init msm_serial_init(void)
- if (unlikely(ret))
- return ret;
-
-- ret = platform_driver_probe(&msm_platform_driver, msm_serial_probe);
-+ ret = platform_driver_register(&msm_platform_driver);
- if (unlikely(ret))
- uart_unregister_driver(&msm_uart_driver);
-
---- a/drivers/tty/serial/msm_serial.h
-+++ b/drivers/tty/serial/msm_serial.h
-@@ -109,11 +109,6 @@
- #define UART_ISR 0x0014
- #define UART_ISR_TX_READY (1 << 7)
-
--#define GSBI_CONTROL 0x0
--#define GSBI_PROTOCOL_CODE 0x30
--#define GSBI_PROTOCOL_UART 0x40
--#define GSBI_PROTOCOL_IDLE 0x0
--
- #define UARTDM_RXFS 0x50
- #define UARTDM_RXFS_BUF_SHIFT 0x7
- #define UARTDM_RXFS_BUF_MASK 0x7
diff --git a/target/linux/ipq806x/patches/0088-soc-qcom-Add-device-tree-binding-for-GSBI.patch b/target/linux/ipq806x/patches/0088-soc-qcom-Add-device-tree-binding-for-GSBI.patch
deleted file mode 100644
index 523d5cb..0000000
--- a/target/linux/ipq806x/patches/0088-soc-qcom-Add-device-tree-binding-for-GSBI.patch
+++ /dev/null
@@ -1,126 +0,0 @@
-From 5a58dbf4d82c29f7e6d89abc3520bed1aa2af05c Mon Sep 17 00:00:00 2001
-From: Andy Gross <agross@codeaurora.org>
-Date: Thu, 24 Apr 2014 11:31:20 -0500
-Subject: [PATCH 088/182] soc: qcom: Add device tree binding for GSBI
-
-Add device tree binding support for the QCOM GSBI driver.
-
-Signed-off-by: Andy Gross <agross@codeaurora.org>
-Signed-off-by: Kumar Gala <galak@codeaurora.org>
----
- .../devicetree/bindings/soc/qcom/qcom,gsbi.txt | 78 ++++++++++++++++++++
- include/dt-bindings/soc/qcom,gsbi.h | 26 +++++++
- 2 files changed, 104 insertions(+)
- create mode 100644 Documentation/devicetree/bindings/soc/qcom/qcom,gsbi.txt
- create mode 100644 include/dt-bindings/soc/qcom,gsbi.h
-
---- /dev/null
-+++ b/Documentation/devicetree/bindings/soc/qcom/qcom,gsbi.txt
-@@ -0,0 +1,78 @@
-+QCOM GSBI (General Serial Bus Interface) Driver
-+
-+The GSBI controller is modeled as a node with zero or more child nodes, each
-+representing a serial sub-node device that is mux'd as part of the GSBI
-+configuration settings. The mode setting will govern the input/output mode of
-+the 4 GSBI IOs.
-+
-+Required properties:
-+- compatible: must contain "qcom,gsbi-v1.0.0" for APQ8064/IPQ8064
-+- reg: Address range for GSBI registers
-+- clocks: required clock
-+- clock-names: must contain "iface" entry
-+- qcom,mode : indicates MUX value for configuration of the serial interface.
-+ Please reference dt-bindings/soc/qcom,gsbi.h for valid mux values.
-+
-+Optional properties:
-+- qcom,crci : indicates CRCI MUX value for QUP CRCI ports. Please reference
-+ dt-bindings/soc/qcom,gsbi.h for valid CRCI mux values.
-+
-+Required properties if child node exists:
-+- #address-cells: Must be 1
-+- #size-cells: Must be 1
-+- ranges: Must be present
-+
-+Properties for children:
-+
-+A GSBI controller node can contain 0 or more child nodes representing serial
-+devices. These serial devices can be a QCOM UART, I2C controller, spi
-+controller, or some combination of aforementioned devices.
-+
-+See the following for child node definitions:
-+Documentation/devicetree/bindings/i2c/qcom,i2c-qup.txt
-+Documentation/devicetree/bindings/spi/qcom,spi-qup.txt
-+Documentation/devicetree/bindings/serial/qcom,msm-uartdm.txt
-+
-+Example for APQ8064:
-+
-+#include <dt-bindings/soc/qcom,gsbi.h>
-+
-+ gsbi4@16300000 {
-+ compatible = "qcom,gsbi-v1.0.0";
-+ reg = <0x16300000 0x100>;
-+ clocks = <&gcc GSBI4_H_CLK>;
-+ clock-names = "iface";
-+ #address-cells = <1>;
-+ #size-cells = <1>;
-+ ranges;
-+ qcom,mode = <GSBI_PROT_I2C_UART>;
-+ qcom,crci = <GSBI_CRCI_QUP>;
-+
-+ /* child nodes go under here */
-+
-+ i2c_qup4: i2c@16380000 {
-+ compatible = "qcom,i2c-qup-v1.1.1";
-+ reg = <0x16380000 0x1000>;
-+ interrupts = <0 153 0>;
-+
-+ clocks = <&gcc GSBI4_QUP_CLK>, <&gcc GSBI4_H_CLK>;
-+ clock-names = "core", "iface";
-+
-+ clock-frequency = <200000>;
-+
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+
-+ };
-+
-+ uart4: serial@16340000 {
-+ compatible = "qcom,msm-uartdm-v1.3", "qcom,msm-uartdm";
-+ reg = <0x16340000 0x1000>,
-+ <0x16300000 0x1000>;
-+ interrupts = <0 152 0x0>;
-+ clocks = <&gcc GSBI4_UART_CLK>, <&gcc GSBI4_H_CLK>;
-+ clock-names = "core", "iface";
-+ status = "ok";
-+ };
-+ };
-+
---- /dev/null
-+++ b/include/dt-bindings/soc/qcom,gsbi.h
-@@ -0,0 +1,26 @@
-+/* Copyright (c) 2013, The Linux Foundation. All rights reserved.
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 and
-+ * only version 2 as published by the Free Software Foundation.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ * GNU General Public License for more details.
-+ */
-+#ifndef __DT_BINDINGS_QCOM_GSBI_H
-+#define __DT_BINDINGS_QCOM_GSBI_H
-+
-+#define GSBI_PROT_IDLE 0
-+#define GSBI_PROT_I2C_UIM 1
-+#define GSBI_PROT_I2C 2
-+#define GSBI_PROT_SPI 3
-+#define GSBI_PROT_UART_W_FC 4
-+#define GSBI_PROT_UIM 5
-+#define GSBI_PROT_I2C_UART 6
-+
-+#define GSBI_CRCI_QUP 0
-+#define GSBI_CRCI_UART 1
-+
-+#endif
diff --git a/target/linux/ipq806x/patches/0089-ARM-dts-MSM8974-Add-pinctrl-node.patch b/target/linux/ipq806x/patches/0089-ARM-dts-MSM8974-Add-pinctrl-node.patch
deleted file mode 100644
index ca06428..0000000
--- a/target/linux/ipq806x/patches/0089-ARM-dts-MSM8974-Add-pinctrl-node.patch
+++ /dev/null
@@ -1,52 +0,0 @@
-From b3a77c7cab10272988231482e2c654c5f10a910c Mon Sep 17 00:00:00 2001
-From: "Ivan T. Ivanov" <iivanov@mm-sol.com>
-Date: Thu, 6 Feb 2014 17:28:49 +0200
-Subject: [PATCH 089/182] ARM: dts: MSM8974: Add pinctrl node
-
-Add the pin control node and pin definitions of SPI8.
-
-Signed-off-by: Ivan T. Ivanov <iivanov@mm-sol.com>
-Reviewed-by: Bjorn Andersson <bjorn.andersson@sonymobile.com>
-Acked-by: Linus Walleij <linus.walleij@linaro.org>
-Signed-off-by: Kumar Gala <galak@codeaurora.org>
----
- arch/arm/boot/dts/qcom-msm8974.dtsi | 29 +++++++++++++++++++++++++++++
- 1 file changed, 29 insertions(+)
-
---- a/arch/arm/boot/dts/qcom-msm8974.dtsi
-+++ b/arch/arm/boot/dts/qcom-msm8974.dtsi
-@@ -198,5 +198,34 @@
- clocks = <&gcc GCC_PRNG_AHB_CLK>;
- clock-names = "core";
- };
-+
-+ msmgpio: pinctrl@fd510000 {
-+ compatible = "qcom,msm8974-pinctrl";
-+ reg = <0xfd510000 0x4000>;
-+ gpio-controller;
-+ #gpio-cells = <2>;
-+ interrupt-controller;
-+ #interrupt-cells = <2>;
-+ interrupts = <0 208 0>;
-+
-+ spi8_default: spi8_default {
-+ mosi {
-+ pins = "gpio45";
-+ function = "blsp_spi8";
-+ };
-+ miso {
-+ pins = "gpio46";
-+ function = "blsp_spi8";
-+ };
-+ cs {
-+ pins = "gpio47";
-+ function = "blsp_spi8";
-+ };
-+ clk {
-+ pins = "gpio48";
-+ function = "blsp_spi8";
-+ };
-+ };
-+ };
- };
- };
diff --git a/target/linux/ipq806x/patches/0090-ARM-dts-msm-Add-SDHC-controller-nodes-for-MSM8974-an.patch b/target/linux/ipq806x/patches/0090-ARM-dts-msm-Add-SDHC-controller-nodes-for-MSM8974-an.patch
deleted file mode 100644
index 7788f8a..0000000
--- a/target/linux/ipq806x/patches/0090-ARM-dts-msm-Add-SDHC-controller-nodes-for-MSM8974-an.patch
+++ /dev/null
@@ -1,68 +0,0 @@
-From 6632619d49f0f90c4d74caad67749864f154cae4 Mon Sep 17 00:00:00 2001
-From: Georgi Djakov <gdjakov@mm-sol.com>
-Date: Fri, 31 Jan 2014 16:21:56 +0200
-Subject: [PATCH 090/182] ARM: dts: msm: Add SDHC controller nodes for MSM8974
- and DB8074 board
-
-Add support for the 2 SDHC controllers on the DB8074 board. The first
-controller (at 0xf9824900) is connected to an on board soldered eMMC.
-The second controller (at 0xf98a4900) is connected to a uSD card slot.
-
-Signed-off-by: Georgi Djakov <gdjakov@mm-sol.com>
-Signed-off-by: Kumar Gala <galak@codeaurora.org>
----
- arch/arm/boot/dts/qcom-apq8074-dragonboard.dts | 13 +++++++++++++
- arch/arm/boot/dts/qcom-msm8974.dtsi | 22 ++++++++++++++++++++++
- 2 files changed, 35 insertions(+)
-
---- a/arch/arm/boot/dts/qcom-apq8074-dragonboard.dts
-+++ b/arch/arm/boot/dts/qcom-apq8074-dragonboard.dts
-@@ -3,4 +3,17 @@
- / {
- model = "Qualcomm APQ8074 Dragonboard";
- compatible = "qcom,apq8074-dragonboard", "qcom,apq8074";
-+
-+ soc: soc {
-+ sdhci@f9824900 {
-+ bus-width = <8>;
-+ non-removable;
-+ status = "ok";
-+ };
-+
-+ sdhci@f98a4900 {
-+ cd-gpios = <&msmgpio 62 0x1>;
-+ bus-width = <4>;
-+ };
-+ };
- };
---- a/arch/arm/boot/dts/qcom-msm8974.dtsi
-+++ b/arch/arm/boot/dts/qcom-msm8974.dtsi
-@@ -192,6 +192,28 @@
- clock-names = "core", "iface";
- };
-
-+ sdhci@f9824900 {
-+ compatible = "qcom,sdhci-msm-v4";
-+ reg = <0xf9824900 0x11c>, <0xf9824000 0x800>;
-+ reg-names = "hc_mem", "core_mem";
-+ interrupts = <0 123 0>, <0 138 0>;
-+ interrupt-names = "hc_irq", "pwr_irq";
-+ clocks = <&gcc GCC_SDCC1_APPS_CLK>, <&gcc GCC_SDCC1_AHB_CLK>;
-+ clock-names = "core", "iface";
-+ status = "disabled";
-+ };
-+
-+ sdhci@f98a4900 {
-+ compatible = "qcom,sdhci-msm-v4";
-+ reg = <0xf98a4900 0x11c>, <0xf98a4000 0x800>;
-+ reg-names = "hc_mem", "core_mem";
-+ interrupts = <0 125 0>, <0 221 0>;
-+ interrupt-names = "hc_irq", "pwr_irq";
-+ clocks = <&gcc GCC_SDCC2_APPS_CLK>, <&gcc GCC_SDCC2_AHB_CLK>;
-+ clock-names = "core", "iface";
-+ status = "disabled";
-+ };
-+
- rng@f9bff000 {
- compatible = "qcom,prng";
- reg = <0xf9bff000 0x200>;
diff --git a/target/linux/ipq806x/patches/0091-ARM-dts-qcom-Update-msm8974-apq8074-device-trees.patch b/target/linux/ipq806x/patches/0091-ARM-dts-qcom-Update-msm8974-apq8074-device-trees.patch
deleted file mode 100644
index 0f6764d..0000000
--- a/target/linux/ipq806x/patches/0091-ARM-dts-qcom-Update-msm8974-apq8074-device-trees.patch
+++ /dev/null
@@ -1,179 +0,0 @@
-From 63495b04141e60ceb40d4632a41b7cd4a3d23dd2 Mon Sep 17 00:00:00 2001
-From: Kumar Gala <galak@codeaurora.org>
-Date: Wed, 28 May 2014 12:01:29 -0500
-Subject: [PATCH 091/182] ARM: dts: qcom: Update msm8974/apq8074 device trees
-
-* Move SoC peripherals into an SoC container node
-* Move serial enabling into board file (qcom-apq8074-dragonboard.dts)
-* Move spi pinctrl into board file
-* Cleanup cpu node to match binding spec, enable-method and compatible
- should be per cpu, not part of the container
-* Drop interrupts property from l2-cache node as its not part of the
- binding spec
-* Move timer node out of SoC container
-
-Signed-off-by: Kumar Gala <galak@codeaurora.org>
----
- arch/arm/boot/dts/qcom-apq8074-dragonboard.dts | 28 +++++++++++++-
- arch/arm/boot/dts/qcom-msm8974.dtsi | 49 +++++++++---------------
- 2 files changed, 45 insertions(+), 32 deletions(-)
-
---- a/arch/arm/boot/dts/qcom-apq8074-dragonboard.dts
-+++ b/arch/arm/boot/dts/qcom-apq8074-dragonboard.dts
-@@ -4,7 +4,11 @@
- model = "Qualcomm APQ8074 Dragonboard";
- compatible = "qcom,apq8074-dragonboard", "qcom,apq8074";
-
-- soc: soc {
-+ soc {
-+ serial@f991e000 {
-+ status = "ok";
-+ };
-+
- sdhci@f9824900 {
- bus-width = <8>;
- non-removable;
-@@ -15,5 +19,27 @@
- cd-gpios = <&msmgpio 62 0x1>;
- bus-width = <4>;
- };
-+
-+
-+ pinctrl@fd510000 {
-+ spi8_default: spi8_default {
-+ mosi {
-+ pins = "gpio45";
-+ function = "blsp_spi8";
-+ };
-+ miso {
-+ pins = "gpio46";
-+ function = "blsp_spi8";
-+ };
-+ cs {
-+ pins = "gpio47";
-+ function = "blsp_spi8";
-+ };
-+ clk {
-+ pins = "gpio48";
-+ function = "blsp_spi8";
-+ };
-+ };
-+ };
- };
- };
---- a/arch/arm/boot/dts/qcom-msm8974.dtsi
-+++ b/arch/arm/boot/dts/qcom-msm8974.dtsi
-@@ -13,10 +13,10 @@
- #address-cells = <1>;
- #size-cells = <0>;
- interrupts = <1 9 0xf04>;
-- compatible = "qcom,krait";
-- enable-method = "qcom,kpss-acc-v2";
-
- cpu@0 {
-+ compatible = "qcom,krait";
-+ enable-method = "qcom,kpss-acc-v2";
- device_type = "cpu";
- reg = <0>;
- next-level-cache = <&L2>;
-@@ -24,6 +24,8 @@
- };
-
- cpu@1 {
-+ compatible = "qcom,krait";
-+ enable-method = "qcom,kpss-acc-v2";
- device_type = "cpu";
- reg = <1>;
- next-level-cache = <&L2>;
-@@ -31,6 +33,8 @@
- };
-
- cpu@2 {
-+ compatible = "qcom,krait";
-+ enable-method = "qcom,kpss-acc-v2";
- device_type = "cpu";
- reg = <2>;
- next-level-cache = <&L2>;
-@@ -38,6 +42,8 @@
- };
-
- cpu@3 {
-+ compatible = "qcom,krait";
-+ enable-method = "qcom,kpss-acc-v2";
- device_type = "cpu";
- reg = <3>;
- next-level-cache = <&L2>;
-@@ -47,7 +53,6 @@
- L2: l2-cache {
- compatible = "cache";
- cache-level = <2>;
-- interrupts = <0 2 0x4>;
- qcom,saw = <&saw_l2>;
- };
- };
-@@ -57,6 +62,15 @@
- interrupts = <1 7 0xf04>;
- };
-
-+ timer {
-+ compatible = "arm,armv7-timer";
-+ interrupts = <1 2 0xf08>,
-+ <1 3 0xf08>,
-+ <1 4 0xf08>,
-+ <1 1 0xf08>;
-+ clock-frequency = <19200000>;
-+ };
-+
- soc: soc {
- #address-cells = <1>;
- #size-cells = <1>;
-@@ -71,15 +85,6 @@
- <0xf9002000 0x1000>;
- };
-
-- timer {
-- compatible = "arm,armv7-timer";
-- interrupts = <1 2 0xf08>,
-- <1 3 0xf08>,
-- <1 4 0xf08>,
-- <1 1 0xf08>;
-- clock-frequency = <19200000>;
-- };
--
- timer@f9020000 {
- #address-cells = <1>;
- #size-cells = <1>;
-@@ -190,6 +195,7 @@
- interrupts = <0 108 0x0>;
- clocks = <&gcc GCC_BLSP1_UART2_APPS_CLK>, <&gcc GCC_BLSP1_AHB_CLK>;
- clock-names = "core", "iface";
-+ status = "disabled";
- };
-
- sdhci@f9824900 {
-@@ -229,25 +235,6 @@
- interrupt-controller;
- #interrupt-cells = <2>;
- interrupts = <0 208 0>;
--
-- spi8_default: spi8_default {
-- mosi {
-- pins = "gpio45";
-- function = "blsp_spi8";
-- };
-- miso {
-- pins = "gpio46";
-- function = "blsp_spi8";
-- };
-- cs {
-- pins = "gpio47";
-- function = "blsp_spi8";
-- };
-- clk {
-- pins = "gpio48";
-- function = "blsp_spi8";
-- };
-- };
- };
- };
- };
diff --git a/target/linux/ipq806x/patches/0092-ARM-dts-qcom-Update-msm8960-device-trees.patch b/target/linux/ipq806x/patches/0092-ARM-dts-qcom-Update-msm8960-device-trees.patch
deleted file mode 100644
index 5b24b4a..0000000
--- a/target/linux/ipq806x/patches/0092-ARM-dts-qcom-Update-msm8960-device-trees.patch
+++ /dev/null
@@ -1,261 +0,0 @@
-From 881200420e6ece87d9abbb13c0653d26455cdbdd Mon Sep 17 00:00:00 2001
-From: Kumar Gala <galak@codeaurora.org>
-Date: Wed, 28 May 2014 12:09:53 -0500
-Subject: [PATCH 092/182] ARM: dts: qcom: Update msm8960 device trees
-
-* Move SoC peripherals into an SoC container node
-* Move serial enabling into board file (qcom-msm8960-cdp.dts)
-* Cleanup cpu node to match binding spec, enable-method and compatible
- should be per cpu, not part of the container
-* Drop interrupts property from l2-cache node as its not part of the
- binding spec
-* Add GSBI node and configuration of GSBI controller
-
-Signed-off-by: Kumar Gala <galak@codeaurora.org>
----
- arch/arm/boot/dts/qcom-msm8960-cdp.dts | 10 ++
- arch/arm/boot/dts/qcom-msm8960.dtsi | 176 ++++++++++++++++++--------------
- 2 files changed, 108 insertions(+), 78 deletions(-)
-
---- a/arch/arm/boot/dts/qcom-msm8960-cdp.dts
-+++ b/arch/arm/boot/dts/qcom-msm8960-cdp.dts
-@@ -3,4 +3,14 @@
- / {
- model = "Qualcomm MSM8960 CDP";
- compatible = "qcom,msm8960-cdp", "qcom,msm8960";
-+
-+ soc {
-+ gsbi@16400000 {
-+ status = "ok";
-+ qcom,mode = <GSBI_PROT_I2C_UART>;
-+ serial@16440000 {
-+ status = "ok";
-+ };
-+ };
-+ };
- };
---- a/arch/arm/boot/dts/qcom-msm8960.dtsi
-+++ b/arch/arm/boot/dts/qcom-msm8960.dtsi
-@@ -3,6 +3,7 @@
- /include/ "skeleton.dtsi"
-
- #include <dt-bindings/clock/qcom,gcc-msm8960.h>
-+#include <dt-bindings/soc/qcom,gsbi.h>
-
- / {
- model = "Qualcomm MSM8960";
-@@ -13,10 +14,10 @@
- #address-cells = <1>;
- #size-cells = <0>;
- interrupts = <1 14 0x304>;
-- compatible = "qcom,krait";
-- enable-method = "qcom,kpss-acc-v1";
-
- cpu@0 {
-+ compatible = "qcom,krait";
-+ enable-method = "qcom,kpss-acc-v1";
- device_type = "cpu";
- reg = <0>;
- next-level-cache = <&L2>;
-@@ -25,6 +26,8 @@
- };
-
- cpu@1 {
-+ compatible = "qcom,krait";
-+ enable-method = "qcom,kpss-acc-v1";
- device_type = "cpu";
- reg = <1>;
- next-level-cache = <&L2>;
-@@ -35,7 +38,6 @@
- L2: l2-cache {
- compatible = "cache";
- cache-level = <2>;
-- interrupts = <0 2 0x4>;
- };
- };
-
-@@ -45,91 +47,109 @@
- qcom,no-pc-write;
- };
-
-- intc: interrupt-controller@2000000 {
-- compatible = "qcom,msm-qgic2";
-- interrupt-controller;
-- #interrupt-cells = <3>;
-- reg = < 0x02000000 0x1000 >,
-- < 0x02002000 0x1000 >;
-- };
-+ soc: soc {
-+ #address-cells = <1>;
-+ #size-cells = <1>;
-+ ranges;
-+ compatible = "simple-bus";
-+
-+ intc: interrupt-controller@2000000 {
-+ compatible = "qcom,msm-qgic2";
-+ interrupt-controller;
-+ #interrupt-cells = <3>;
-+ reg = <0x02000000 0x1000>,
-+ <0x02002000 0x1000>;
-+ };
-
-- timer@200a000 {
-- compatible = "qcom,kpss-timer", "qcom,msm-timer";
-- interrupts = <1 1 0x301>,
-- <1 2 0x301>,
-- <1 3 0x301>;
-- reg = <0x0200a000 0x100>;
-- clock-frequency = <27000000>,
-- <32768>;
-- cpu-offset = <0x80000>;
-- };
-+ timer@200a000 {
-+ compatible = "qcom,kpss-timer", "qcom,msm-timer";
-+ interrupts = <1 1 0x301>,
-+ <1 2 0x301>,
-+ <1 3 0x301>;
-+ reg = <0x0200a000 0x100>;
-+ clock-frequency = <27000000>,
-+ <32768>;
-+ cpu-offset = <0x80000>;
-+ };
-
-- msmgpio: gpio@800000 {
-- compatible = "qcom,msm-gpio";
-- gpio-controller;
-- #gpio-cells = <2>;
-- ngpio = <150>;
-- interrupts = <0 16 0x4>;
-- interrupt-controller;
-- #interrupt-cells = <2>;
-- reg = <0x800000 0x4000>;
-- };
-+ msmgpio: gpio@800000 {
-+ compatible = "qcom,msm-gpio";
-+ gpio-controller;
-+ #gpio-cells = <2>;
-+ ngpio = <150>;
-+ interrupts = <0 16 0x4>;
-+ interrupt-controller;
-+ #interrupt-cells = <2>;
-+ reg = <0x800000 0x4000>;
-+ };
-
-- gcc: clock-controller@900000 {
-- compatible = "qcom,gcc-msm8960";
-- #clock-cells = <1>;
-- #reset-cells = <1>;
-- reg = <0x900000 0x4000>;
-- };
-+ gcc: clock-controller@900000 {
-+ compatible = "qcom,gcc-msm8960";
-+ #clock-cells = <1>;
-+ #reset-cells = <1>;
-+ reg = <0x900000 0x4000>;
-+ };
-
-- clock-controller@4000000 {
-- compatible = "qcom,mmcc-msm8960";
-- reg = <0x4000000 0x1000>;
-- #clock-cells = <1>;
-- #reset-cells = <1>;
-- };
-+ clock-controller@4000000 {
-+ compatible = "qcom,mmcc-msm8960";
-+ reg = <0x4000000 0x1000>;
-+ #clock-cells = <1>;
-+ #reset-cells = <1>;
-+ };
-
-- acc0: clock-controller@2088000 {
-- compatible = "qcom,kpss-acc-v1";
-- reg = <0x02088000 0x1000>, <0x02008000 0x1000>;
-- };
-+ acc0: clock-controller@2088000 {
-+ compatible = "qcom,kpss-acc-v1";
-+ reg = <0x02088000 0x1000>, <0x02008000 0x1000>;
-+ };
-
-- acc1: clock-controller@2098000 {
-- compatible = "qcom,kpss-acc-v1";
-- reg = <0x02098000 0x1000>, <0x02008000 0x1000>;
-- };
-+ acc1: clock-controller@2098000 {
-+ compatible = "qcom,kpss-acc-v1";
-+ reg = <0x02098000 0x1000>, <0x02008000 0x1000>;
-+ };
-
-- saw0: regulator@2089000 {
-- compatible = "qcom,saw2";
-- reg = <0x02089000 0x1000>, <0x02009000 0x1000>;
-- regulator;
-- };
-+ saw0: regulator@2089000 {
-+ compatible = "qcom,saw2";
-+ reg = <0x02089000 0x1000>, <0x02009000 0x1000>;
-+ regulator;
-+ };
-
-- saw1: regulator@2099000 {
-- compatible = "qcom,saw2";
-- reg = <0x02099000 0x1000>, <0x02009000 0x1000>;
-- regulator;
-- };
-+ saw1: regulator@2099000 {
-+ compatible = "qcom,saw2";
-+ reg = <0x02099000 0x1000>, <0x02009000 0x1000>;
-+ regulator;
-+ };
-
-- serial@16440000 {
-- compatible = "qcom,msm-uartdm-v1.3", "qcom,msm-uartdm";
-- reg = <0x16440000 0x1000>,
-- <0x16400000 0x1000>;
-- interrupts = <0 154 0x0>;
-- clocks = <&gcc GSBI5_UART_CLK>, <&gcc GSBI5_H_CLK>;
-- clock-names = "core", "iface";
-- };
-+ gsbi5: gsbi@16400000 {
-+ compatible = "qcom,gsbi-v1.0.0";
-+ reg = <0x16400000 0x100>;
-+ clocks = <&gcc GSBI5_H_CLK>;
-+ clock-names = "iface";
-+ #address-cells = <1>;
-+ #size-cells = <1>;
-+ ranges;
-+
-+ serial@16440000 {
-+ compatible = "qcom,msm-uartdm-v1.3", "qcom,msm-uartdm";
-+ reg = <0x16440000 0x1000>,
-+ <0x16400000 0x1000>;
-+ interrupts = <0 154 0x0>;
-+ clocks = <&gcc GSBI5_UART_CLK>, <&gcc GSBI5_H_CLK>;
-+ clock-names = "core", "iface";
-+ status = "disabled";
-+ };
-+ };
-
-- qcom,ssbi@500000 {
-- compatible = "qcom,ssbi";
-- reg = <0x500000 0x1000>;
-- qcom,controller-type = "pmic-arbiter";
-- };
-+ qcom,ssbi@500000 {
-+ compatible = "qcom,ssbi";
-+ reg = <0x500000 0x1000>;
-+ qcom,controller-type = "pmic-arbiter";
-+ };
-
-- rng@1a500000 {
-- compatible = "qcom,prng";
-- reg = <0x1a500000 0x200>;
-- clocks = <&gcc PRNG_CLK>;
-- clock-names = "core";
-+ rng@1a500000 {
-+ compatible = "qcom,prng";
-+ reg = <0x1a500000 0x200>;
-+ clocks = <&gcc PRNG_CLK>;
-+ clock-names = "core";
-+ };
- };
- };
diff --git a/target/linux/ipq806x/patches/0093-ARM-dts-qcom-Update-msm8660-device-trees.patch b/target/linux/ipq806x/patches/0093-ARM-dts-qcom-Update-msm8660-device-trees.patch
deleted file mode 100644
index 8359faf..0000000
--- a/target/linux/ipq806x/patches/0093-ARM-dts-qcom-Update-msm8660-device-trees.patch
+++ /dev/null
@@ -1,184 +0,0 @@
-From 355bf7c6410f5b6e37b5c2b28ebe59bb701c42d6 Mon Sep 17 00:00:00 2001
-From: Kumar Gala <galak@codeaurora.org>
-Date: Wed, 28 May 2014 12:12:40 -0500
-Subject: [PATCH 093/182] ARM: dts: qcom: Update msm8660 device trees
-
-* Move SoC peripherals into an SoC container node
-* Move serial enabling into board file (qcom-msm8660-surf.dts)
-* Cleanup cpu node to match binding spec, enable-method and compatible
- should be per cpu, not part of the container
-* Add GSBI node and configuration of GSBI controller
-
-Signed-off-by: Kumar Gala <galak@codeaurora.org>
----
- arch/arm/boot/dts/qcom-msm8660-surf.dts | 10 +++
- arch/arm/boot/dts/qcom-msm8660.dtsi | 115 ++++++++++++++++++-------------
- 2 files changed, 78 insertions(+), 47 deletions(-)
-
---- a/arch/arm/boot/dts/qcom-msm8660-surf.dts
-+++ b/arch/arm/boot/dts/qcom-msm8660-surf.dts
-@@ -3,4 +3,14 @@
- / {
- model = "Qualcomm MSM8660 SURF";
- compatible = "qcom,msm8660-surf", "qcom,msm8660";
-+
-+ soc {
-+ gsbi@19c00000 {
-+ status = "ok";
-+ qcom,mode = <GSBI_PROT_I2C_UART>;
-+ serial@19c40000 {
-+ status = "ok";
-+ };
-+ };
-+ };
- };
---- a/arch/arm/boot/dts/qcom-msm8660.dtsi
-+++ b/arch/arm/boot/dts/qcom-msm8660.dtsi
-@@ -3,6 +3,7 @@
- /include/ "skeleton.dtsi"
-
- #include <dt-bindings/clock/qcom,gcc-msm8660.h>
-+#include <dt-bindings/soc/qcom,gsbi.h>
-
- / {
- model = "Qualcomm MSM8660";
-@@ -12,16 +13,18 @@
- cpus {
- #address-cells = <1>;
- #size-cells = <0>;
-- compatible = "qcom,scorpion";
-- enable-method = "qcom,gcc-msm8660";
-
- cpu@0 {
-+ compatible = "qcom,scorpion";
-+ enable-method = "qcom,gcc-msm8660";
- device_type = "cpu";
- reg = <0>;
- next-level-cache = <&L2>;
- };
-
- cpu@1 {
-+ compatible = "qcom,scorpion";
-+ enable-method = "qcom,gcc-msm8660";
- device_type = "cpu";
- reg = <1>;
- next-level-cache = <&L2>;
-@@ -33,55 +36,73 @@
- };
- };
-
-- intc: interrupt-controller@2080000 {
-- compatible = "qcom,msm-8660-qgic";
-- interrupt-controller;
-- #interrupt-cells = <3>;
-- reg = < 0x02080000 0x1000 >,
-- < 0x02081000 0x1000 >;
-- };
-+ soc: soc {
-+ #address-cells = <1>;
-+ #size-cells = <1>;
-+ ranges;
-+ compatible = "simple-bus";
-+
-+ intc: interrupt-controller@2080000 {
-+ compatible = "qcom,msm-8660-qgic";
-+ interrupt-controller;
-+ #interrupt-cells = <3>;
-+ reg = < 0x02080000 0x1000 >,
-+ < 0x02081000 0x1000 >;
-+ };
-
-- timer@2000000 {
-- compatible = "qcom,scss-timer", "qcom,msm-timer";
-- interrupts = <1 0 0x301>,
-- <1 1 0x301>,
-- <1 2 0x301>;
-- reg = <0x02000000 0x100>;
-- clock-frequency = <27000000>,
-- <32768>;
-- cpu-offset = <0x40000>;
-- };
-+ timer@2000000 {
-+ compatible = "qcom,scss-timer", "qcom,msm-timer";
-+ interrupts = <1 0 0x301>,
-+ <1 1 0x301>,
-+ <1 2 0x301>;
-+ reg = <0x02000000 0x100>;
-+ clock-frequency = <27000000>,
-+ <32768>;
-+ cpu-offset = <0x40000>;
-+ };
-
-- msmgpio: gpio@800000 {
-- compatible = "qcom,msm-gpio";
-- reg = <0x00800000 0x4000>;
-- gpio-controller;
-- #gpio-cells = <2>;
-- ngpio = <173>;
-- interrupts = <0 16 0x4>;
-- interrupt-controller;
-- #interrupt-cells = <2>;
-- };
-+ msmgpio: gpio@800000 {
-+ compatible = "qcom,msm-gpio";
-+ reg = <0x00800000 0x4000>;
-+ gpio-controller;
-+ #gpio-cells = <2>;
-+ ngpio = <173>;
-+ interrupts = <0 16 0x4>;
-+ interrupt-controller;
-+ #interrupt-cells = <2>;
-+ };
-
-- gcc: clock-controller@900000 {
-- compatible = "qcom,gcc-msm8660";
-- #clock-cells = <1>;
-- #reset-cells = <1>;
-- reg = <0x900000 0x4000>;
-- };
-+ gcc: clock-controller@900000 {
-+ compatible = "qcom,gcc-msm8660";
-+ #clock-cells = <1>;
-+ #reset-cells = <1>;
-+ reg = <0x900000 0x4000>;
-+ };
-
-- serial@19c40000 {
-- compatible = "qcom,msm-uartdm-v1.3", "qcom,msm-uartdm";
-- reg = <0x19c40000 0x1000>,
-- <0x19c00000 0x1000>;
-- interrupts = <0 195 0x0>;
-- clocks = <&gcc GSBI12_UART_CLK>, <&gcc GSBI12_H_CLK>;
-- clock-names = "core", "iface";
-- };
-+ gsbi12: gsbi@19c00000 {
-+ compatible = "qcom,gsbi-v1.0.0";
-+ reg = <0x19c00000 0x100>;
-+ clocks = <&gcc GSBI12_H_CLK>;
-+ clock-names = "iface";
-+ #address-cells = <1>;
-+ #size-cells = <1>;
-+ ranges;
-+
-+ serial@19c40000 {
-+ compatible = "qcom,msm-uartdm-v1.3", "qcom,msm-uartdm";
-+ reg = <0x19c40000 0x1000>,
-+ <0x19c00000 0x1000>;
-+ interrupts = <0 195 0x0>;
-+ clocks = <&gcc GSBI12_UART_CLK>, <&gcc GSBI12_H_CLK>;
-+ clock-names = "core", "iface";
-+ status = "disabled";
-+ };
-+ };
-
-- qcom,ssbi@500000 {
-- compatible = "qcom,ssbi";
-- reg = <0x500000 0x1000>;
-- qcom,controller-type = "pmic-arbiter";
-+ qcom,ssbi@500000 {
-+ compatible = "qcom,ssbi";
-+ reg = <0x500000 0x1000>;
-+ qcom,controller-type = "pmic-arbiter";
-+ };
- };
- };
diff --git a/target/linux/ipq806x/patches/0094-ARM-dts-qcom-Add-initial-APQ8064-SoC-and-IFC6410-boa.patch b/target/linux/ipq806x/patches/0094-ARM-dts-qcom-Add-initial-APQ8064-SoC-and-IFC6410-boa.patch
deleted file mode 100644
index fb2910b..0000000
--- a/target/linux/ipq806x/patches/0094-ARM-dts-qcom-Add-initial-APQ8064-SoC-and-IFC6410-boa.patch
+++ /dev/null
@@ -1,249 +0,0 @@
-From 07d7d95706c1bf373bd6b30c42f95c7b8dc8b9ce Mon Sep 17 00:00:00 2001
-From: Kumar Gala <galak@codeaurora.org>
-Date: Thu, 3 Apr 2014 14:48:22 -0500
-Subject: [PATCH 094/182] ARM: dts: qcom: Add initial APQ8064 SoC and IFC6410
- board device trees
-
-Add basic APQ8064 SoC include device tree and support for basic booting on
-the IFC6410 board. Also, keep dtb build list and qcom_dt_match in sorted
-order.
-
-Signed-off-by: Kumar Gala <galak@codeaurora.org>
----
- arch/arm/boot/dts/Makefile | 8 +-
- arch/arm/boot/dts/qcom-apq8064-ifc6410.dts | 16 +++
- arch/arm/boot/dts/qcom-apq8064-v2.0.dtsi | 1 +
- arch/arm/boot/dts/qcom-apq8064.dtsi | 170 ++++++++++++++++++++++++++++
- arch/arm/mach-qcom/board.c | 3 +-
- 5 files changed, 194 insertions(+), 4 deletions(-)
- create mode 100644 arch/arm/boot/dts/qcom-apq8064-ifc6410.dts
- create mode 100644 arch/arm/boot/dts/qcom-apq8064-v2.0.dtsi
- create mode 100644 arch/arm/boot/dts/qcom-apq8064.dtsi
-
---- a/arch/arm/boot/dts/Makefile
-+++ b/arch/arm/boot/dts/Makefile
-@@ -231,9 +231,11 @@ dtb-$(CONFIG_ARCH_OMAP2PLUS) += omap2420
- dra7-evm.dtb
- dtb-$(CONFIG_ARCH_ORION5X) += orion5x-lacie-ethernet-disk-mini-v2.dtb
- dtb-$(CONFIG_ARCH_PRIMA2) += prima2-evb.dtb
--dtb-$(CONFIG_ARCH_QCOM) += qcom-msm8660-surf.dtb \
-- qcom-msm8960-cdp.dtb \
-- qcom-apq8074-dragonboard.dtb
-+dtb-$(CONFIG_ARCH_QCOM) += \
-+ qcom-apq8064-ifc6410.dtb \
-+ qcom-apq8074-dragonboard.dtb \
-+ qcom-msm8660-surf.dtb \
-+ qcom-msm8960-cdp.dtb
- dtb-$(CONFIG_ARCH_U8500) += ste-snowball.dtb \
- ste-hrefprev60-stuib.dtb \
- ste-hrefprev60-tvk.dtb \
---- /dev/null
-+++ b/arch/arm/boot/dts/qcom-apq8064-ifc6410.dts
-@@ -0,0 +1,16 @@
-+#include "qcom-apq8064-v2.0.dtsi"
-+
-+/ {
-+ model = "Qualcomm APQ8064/IFC6410";
-+ compatible = "qcom,apq8064-ifc6410", "qcom,apq8064";
-+
-+ soc {
-+ gsbi@16600000 {
-+ status = "ok";
-+ qcom,mode = <GSBI_PROT_I2C_UART>;
-+ serial@16640000 {
-+ status = "ok";
-+ };
-+ };
-+ };
-+};
---- /dev/null
-+++ b/arch/arm/boot/dts/qcom-apq8064-v2.0.dtsi
-@@ -0,0 +1 @@
-+#include "qcom-apq8064.dtsi"
---- /dev/null
-+++ b/arch/arm/boot/dts/qcom-apq8064.dtsi
-@@ -0,0 +1,170 @@
-+/dts-v1/;
-+
-+#include "skeleton.dtsi"
-+#include <dt-bindings/clock/qcom,gcc-msm8960.h>
-+#include <dt-bindings/soc/qcom,gsbi.h>
-+
-+/ {
-+ model = "Qualcomm APQ8064";
-+ compatible = "qcom,apq8064";
-+ interrupt-parent = <&intc>;
-+
-+ cpus {
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+
-+ cpu@0 {
-+ compatible = "qcom,krait";
-+ enable-method = "qcom,kpss-acc-v1";
-+ device_type = "cpu";
-+ reg = <0>;
-+ next-level-cache = <&L2>;
-+ qcom,acc = <&acc0>;
-+ qcom,saw = <&saw0>;
-+ };
-+
-+ cpu@1 {
-+ compatible = "qcom,krait";
-+ enable-method = "qcom,kpss-acc-v1";
-+ device_type = "cpu";
-+ reg = <1>;
-+ next-level-cache = <&L2>;
-+ qcom,acc = <&acc1>;
-+ qcom,saw = <&saw1>;
-+ };
-+
-+ cpu@2 {
-+ compatible = "qcom,krait";
-+ enable-method = "qcom,kpss-acc-v1";
-+ device_type = "cpu";
-+ reg = <2>;
-+ next-level-cache = <&L2>;
-+ qcom,acc = <&acc2>;
-+ qcom,saw = <&saw2>;
-+ };
-+
-+ cpu@3 {
-+ compatible = "qcom,krait";
-+ enable-method = "qcom,kpss-acc-v1";
-+ device_type = "cpu";
-+ reg = <3>;
-+ next-level-cache = <&L2>;
-+ qcom,acc = <&acc3>;
-+ qcom,saw = <&saw3>;
-+ };
-+
-+ L2: l2-cache {
-+ compatible = "cache";
-+ cache-level = <2>;
-+ };
-+ };
-+
-+ cpu-pmu {
-+ compatible = "qcom,krait-pmu";
-+ interrupts = <1 10 0x304>;
-+ };
-+
-+ soc: soc {
-+ #address-cells = <1>;
-+ #size-cells = <1>;
-+ ranges;
-+ compatible = "simple-bus";
-+
-+ intc: interrupt-controller@2000000 {
-+ compatible = "qcom,msm-qgic2";
-+ interrupt-controller;
-+ #interrupt-cells = <3>;
-+ reg = <0x02000000 0x1000>,
-+ <0x02002000 0x1000>;
-+ };
-+
-+ timer@200a000 {
-+ compatible = "qcom,kpss-timer", "qcom,msm-timer";
-+ interrupts = <1 1 0x301>,
-+ <1 2 0x301>,
-+ <1 3 0x301>;
-+ reg = <0x0200a000 0x100>;
-+ clock-frequency = <27000000>,
-+ <32768>;
-+ cpu-offset = <0x80000>;
-+ };
-+
-+ acc0: clock-controller@2088000 {
-+ compatible = "qcom,kpss-acc-v1";
-+ reg = <0x02088000 0x1000>, <0x02008000 0x1000>;
-+ };
-+
-+ acc1: clock-controller@2098000 {
-+ compatible = "qcom,kpss-acc-v1";
-+ reg = <0x02098000 0x1000>, <0x02008000 0x1000>;
-+ };
-+
-+ acc2: clock-controller@20a8000 {
-+ compatible = "qcom,kpss-acc-v1";
-+ reg = <0x020a8000 0x1000>, <0x02008000 0x1000>;
-+ };
-+
-+ acc3: clock-controller@20b8000 {
-+ compatible = "qcom,kpss-acc-v1";
-+ reg = <0x020b8000 0x1000>, <0x02008000 0x1000>;
-+ };
-+
-+ saw0: regulator@2089000 {
-+ compatible = "qcom,saw2";
-+ reg = <0x02089000 0x1000>, <0x02009000 0x1000>;
-+ regulator;
-+ };
-+
-+ saw1: regulator@2099000 {
-+ compatible = "qcom,saw2";
-+ reg = <0x02099000 0x1000>, <0x02009000 0x1000>;
-+ regulator;
-+ };
-+
-+ saw2: regulator@20a9000 {
-+ compatible = "qcom,saw2";
-+ reg = <0x020a9000 0x1000>, <0x02009000 0x1000>;
-+ regulator;
-+ };
-+
-+ saw3: regulator@20b9000 {
-+ compatible = "qcom,saw2";
-+ reg = <0x020b9000 0x1000>, <0x02009000 0x1000>;
-+ regulator;
-+ };
-+
-+ gsbi7: gsbi@16600000 {
-+ status = "disabled";
-+ compatible = "qcom,gsbi-v1.0.0";
-+ reg = <0x16600000 0x100>;
-+ clocks = <&gcc GSBI7_H_CLK>;
-+ clock-names = "iface";
-+ #address-cells = <1>;
-+ #size-cells = <1>;
-+ ranges;
-+
-+ serial@16640000 {
-+ compatible = "qcom,msm-uartdm-v1.3", "qcom,msm-uartdm";
-+ reg = <0x16640000 0x1000>,
-+ <0x16600000 0x1000>;
-+ interrupts = <0 158 0x0>;
-+ clocks = <&gcc GSBI7_UART_CLK>, <&gcc GSBI7_H_CLK>;
-+ clock-names = "core", "iface";
-+ status = "disabled";
-+ };
-+ };
-+
-+ qcom,ssbi@500000 {
-+ compatible = "qcom,ssbi";
-+ reg = <0x00500000 0x1000>;
-+ qcom,controller-type = "pmic-arbiter";
-+ };
-+
-+ gcc: clock-controller@900000 {
-+ compatible = "qcom,gcc-apq8064";
-+ reg = <0x00900000 0x4000>;
-+ #clock-cells = <1>;
-+ #reset-cells = <1>;
-+ };
-+ };
-+};
---- a/arch/arm/mach-qcom/board.c
-+++ b/arch/arm/mach-qcom/board.c
-@@ -15,9 +15,10 @@
- #include <asm/mach/arch.h>
-
- static const char * const qcom_dt_match[] __initconst = {
-+ "qcom,apq8064",
-+ "qcom,apq8074-dragonboard",
- "qcom,msm8660-surf",
- "qcom,msm8960-cdp",
-- "qcom,apq8074-dragonboard",
- NULL
- };
-
diff --git a/target/linux/ipq806x/patches/0095-ARM-dts-qcom-Add-APQ8084-MTP-board-support.patch b/target/linux/ipq806x/patches/0095-ARM-dts-qcom-Add-APQ8084-MTP-board-support.patch
deleted file mode 100644
index 3c4f221..0000000
--- a/target/linux/ipq806x/patches/0095-ARM-dts-qcom-Add-APQ8084-MTP-board-support.patch
+++ /dev/null
@@ -1,35 +0,0 @@
-From 9b06bc14f21463cf687ac6fdd07ca04b99c15466 Mon Sep 17 00:00:00 2001
-From: Georgi Djakov <gdjakov@mm-sol.com>
-Date: Fri, 23 May 2014 18:12:30 +0300
-Subject: [PATCH 095/182] ARM: dts: qcom: Add APQ8084-MTP board support
-
-Add device-tree file for APQ8084-MTP board, which belongs
-to the Snapdragon 805 family.
-
-Signed-off-by: Georgi Djakov <gdjakov@mm-sol.com>
-Signed-off-by: Kumar Gala <galak@codeaurora.org>
----
- arch/arm/boot/dts/Makefile | 1 +
- arch/arm/boot/dts/qcom-apq8084-mtp.dts | 6 ++++++
- 2 files changed, 7 insertions(+)
- create mode 100644 arch/arm/boot/dts/qcom-apq8084-mtp.dts
-
---- a/arch/arm/boot/dts/Makefile
-+++ b/arch/arm/boot/dts/Makefile
-@@ -234,6 +234,7 @@ dtb-$(CONFIG_ARCH_PRIMA2) += prima2-evb.
- dtb-$(CONFIG_ARCH_QCOM) += \
- qcom-apq8064-ifc6410.dtb \
- qcom-apq8074-dragonboard.dtb \
-+ qcom-apq8084-mtp.dtb \
- qcom-msm8660-surf.dtb \
- qcom-msm8960-cdp.dtb
- dtb-$(CONFIG_ARCH_U8500) += ste-snowball.dtb \
---- /dev/null
-+++ b/arch/arm/boot/dts/qcom-apq8084-mtp.dts
-@@ -0,0 +1,6 @@
-+#include "qcom-apq8084.dtsi"
-+
-+/ {
-+ model = "Qualcomm APQ 8084-MTP";
-+ compatible = "qcom,apq8084-mtp", "qcom,apq8084";
-+};
diff --git a/target/linux/ipq806x/patches/0096-ARM-dts-qcom-Add-APQ8084-SoC-support.patch b/target/linux/ipq806x/patches/0096-ARM-dts-qcom-Add-APQ8084-SoC-support.patch
deleted file mode 100644
index 1863059..0000000
--- a/target/linux/ipq806x/patches/0096-ARM-dts-qcom-Add-APQ8084-SoC-support.patch
+++ /dev/null
@@ -1,208 +0,0 @@
-From 8c52931421759b70fc37771be3390813a2a2f9f5 Mon Sep 17 00:00:00 2001
-From: Georgi Djakov <gdjakov@mm-sol.com>
-Date: Fri, 23 May 2014 18:12:29 +0300
-Subject: [PATCH 096/182] ARM: dts: qcom: Add APQ8084 SoC support
-
-Add support for the Qualcomm Snapdragon 805 APQ8084 SoC. It is
-used on APQ8084-MTP and other boards.
-
-Signed-off-by: Georgi Djakov <gdjakov@mm-sol.com>
-Signed-off-by: Kumar Gala <galak@codeaurora.org>
----
- arch/arm/boot/dts/qcom-apq8084.dtsi | 179 +++++++++++++++++++++++++++++++++++
- arch/arm/mach-qcom/board.c | 1 +
- 2 files changed, 180 insertions(+)
- create mode 100644 arch/arm/boot/dts/qcom-apq8084.dtsi
-
---- /dev/null
-+++ b/arch/arm/boot/dts/qcom-apq8084.dtsi
-@@ -0,0 +1,179 @@
-+/dts-v1/;
-+
-+#include "skeleton.dtsi"
-+
-+/ {
-+ model = "Qualcomm APQ 8084";
-+ compatible = "qcom,apq8084";
-+ interrupt-parent = <&intc>;
-+
-+ cpus {
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+
-+ cpu@0 {
-+ device_type = "cpu";
-+ compatible = "qcom,krait";
-+ reg = <0>;
-+ enable-method = "qcom,kpss-acc-v2";
-+ next-level-cache = <&L2>;
-+ qcom,acc = <&acc0>;
-+ };
-+
-+ cpu@1 {
-+ device_type = "cpu";
-+ compatible = "qcom,krait";
-+ reg = <1>;
-+ enable-method = "qcom,kpss-acc-v2";
-+ next-level-cache = <&L2>;
-+ qcom,acc = <&acc1>;
-+ };
-+
-+ cpu@2 {
-+ device_type = "cpu";
-+ compatible = "qcom,krait";
-+ reg = <2>;
-+ enable-method = "qcom,kpss-acc-v2";
-+ next-level-cache = <&L2>;
-+ qcom,acc = <&acc2>;
-+ };
-+
-+ cpu@3 {
-+ device_type = "cpu";
-+ compatible = "qcom,krait";
-+ reg = <3>;
-+ enable-method = "qcom,kpss-acc-v2";
-+ next-level-cache = <&L2>;
-+ qcom,acc = <&acc3>;
-+ };
-+
-+ L2: l2-cache {
-+ compatible = "qcom,arch-cache";
-+ cache-level = <2>;
-+ qcom,saw = <&saw_l2>;
-+ };
-+ };
-+
-+ cpu-pmu {
-+ compatible = "qcom,krait-pmu";
-+ interrupts = <1 7 0xf04>;
-+ };
-+
-+ timer {
-+ compatible = "arm,armv7-timer";
-+ interrupts = <1 2 0xf08>,
-+ <1 3 0xf08>,
-+ <1 4 0xf08>,
-+ <1 1 0xf08>;
-+ clock-frequency = <19200000>;
-+ };
-+
-+ soc: soc {
-+ #address-cells = <1>;
-+ #size-cells = <1>;
-+ ranges;
-+ compatible = "simple-bus";
-+
-+ intc: interrupt-controller@f9000000 {
-+ compatible = "qcom,msm-qgic2";
-+ interrupt-controller;
-+ #interrupt-cells = <3>;
-+ reg = <0xf9000000 0x1000>,
-+ <0xf9002000 0x1000>;
-+ };
-+
-+ timer@f9020000 {
-+ #address-cells = <1>;
-+ #size-cells = <1>;
-+ ranges;
-+ compatible = "arm,armv7-timer-mem";
-+ reg = <0xf9020000 0x1000>;
-+ clock-frequency = <19200000>;
-+
-+ frame@f9021000 {
-+ frame-number = <0>;
-+ interrupts = <0 8 0x4>,
-+ <0 7 0x4>;
-+ reg = <0xf9021000 0x1000>,
-+ <0xf9022000 0x1000>;
-+ };
-+
-+ frame@f9023000 {
-+ frame-number = <1>;
-+ interrupts = <0 9 0x4>;
-+ reg = <0xf9023000 0x1000>;
-+ status = "disabled";
-+ };
-+
-+ frame@f9024000 {
-+ frame-number = <2>;
-+ interrupts = <0 10 0x4>;
-+ reg = <0xf9024000 0x1000>;
-+ status = "disabled";
-+ };
-+
-+ frame@f9025000 {
-+ frame-number = <3>;
-+ interrupts = <0 11 0x4>;
-+ reg = <0xf9025000 0x1000>;
-+ status = "disabled";
-+ };
-+
-+ frame@f9026000 {
-+ frame-number = <4>;
-+ interrupts = <0 12 0x4>;
-+ reg = <0xf9026000 0x1000>;
-+ status = "disabled";
-+ };
-+
-+ frame@f9027000 {
-+ frame-number = <5>;
-+ interrupts = <0 13 0x4>;
-+ reg = <0xf9027000 0x1000>;
-+ status = "disabled";
-+ };
-+
-+ frame@f9028000 {
-+ frame-number = <6>;
-+ interrupts = <0 14 0x4>;
-+ reg = <0xf9028000 0x1000>;
-+ status = "disabled";
-+ };
-+ };
-+
-+ saw_l2: regulator@f9012000 {
-+ compatible = "qcom,saw2";
-+ reg = <0xf9012000 0x1000>;
-+ regulator;
-+ };
-+
-+ acc0: clock-controller@f9088000 {
-+ compatible = "qcom,kpss-acc-v2";
-+ reg = <0xf9088000 0x1000>,
-+ <0xf9008000 0x1000>;
-+ };
-+
-+ acc1: clock-controller@f9098000 {
-+ compatible = "qcom,kpss-acc-v2";
-+ reg = <0xf9098000 0x1000>,
-+ <0xf9008000 0x1000>;
-+ };
-+
-+ acc2: clock-controller@f90a8000 {
-+ compatible = "qcom,kpss-acc-v2";
-+ reg = <0xf90a8000 0x1000>,
-+ <0xf9008000 0x1000>;
-+ };
-+
-+ acc3: clock-controller@f90b8000 {
-+ compatible = "qcom,kpss-acc-v2";
-+ reg = <0xf90b8000 0x1000>,
-+ <0xf9008000 0x1000>;
-+ };
-+
-+ restart@fc4ab000 {
-+ compatible = "qcom,pshold";
-+ reg = <0xfc4ab000 0x4>;
-+ };
-+ };
-+};
---- a/arch/arm/mach-qcom/board.c
-+++ b/arch/arm/mach-qcom/board.c
-@@ -17,6 +17,7 @@
- static const char * const qcom_dt_match[] __initconst = {
- "qcom,apq8064",
- "qcom,apq8074-dragonboard",
-+ "qcom,apq8084",
- "qcom,msm8660-surf",
- "qcom,msm8960-cdp",
- NULL
diff --git a/target/linux/ipq806x/patches/0097-ARM-debug-qcom-make-UART-address-selection-configura.patch b/target/linux/ipq806x/patches/0097-ARM-debug-qcom-make-UART-address-selection-configura.patch
deleted file mode 100644
index 1c67fb7..0000000
--- a/target/linux/ipq806x/patches/0097-ARM-debug-qcom-make-UART-address-selection-configura.patch
+++ /dev/null
@@ -1,258 +0,0 @@
-From 48167d4a55890a783cc8b1590bc8071253ae4b83 Mon Sep 17 00:00:00 2001
-From: "Ivan T. Ivanov" <iivanov@mm-sol.com>
-Date: Mon, 14 Apr 2014 16:47:34 +0300
-Subject: [PATCH 097/182] ARM: debug: qcom: make UART address selection
- configuration option
-
-Separate Qualcomm low-level debugging UART to two options.
-
-DEBUG_MSM_UART is used in earlier non-multi platform arches,
-like MSM7X00A, QSD8X50 and MSM7X30.
-
-DEBUG_QCOM_UARTDM is used in multi-plafrom arches and have
-embedded data mover.
-
-Make DEBUG_UART_PHYS and DEBUG_UART_BASE user adjustable by
-Kconfig menu.
-
-Signed-off-by: Ivan T. Ivanov <iivanov@mm-sol.com>
-Reviewed-by: Stephen Boyd <sboyd@codeaurora.org>
-Tested-by: Stephen Boyd <sboyd@codeaurora.org>
-Signed-off-by: Kumar Gala <galak@codeaurora.org>
----
- arch/arm/Kconfig.debug | 81 +++++++++++++++++-------------------------
- arch/arm/include/debug/msm.S | 46 +++---------------------
- arch/arm/mach-msm/Kconfig | 3 --
- 3 files changed, 38 insertions(+), 92 deletions(-)
-
---- a/arch/arm/Kconfig.debug
-+++ b/arch/arm/Kconfig.debug
-@@ -353,56 +353,39 @@ choice
- Say Y here if you want kernel low-level debugging support
- on MMP UART3.
-
-- config DEBUG_MSM_UART1
-- bool "Kernel low-level debugging messages via MSM UART1"
-- depends on ARCH_MSM7X00A || ARCH_MSM7X30 || ARCH_QSD8X50
-- select DEBUG_MSM_UART
-+ config DEBUG_MSM_UART
-+ bool "Kernel low-level debugging messages via MSM UART"
-+ depends on ARCH_MSM
- help
- Say Y here if you want the debug print routines to direct
-- their output to the first serial port on MSM devices.
-+ their output to the serial port on MSM devices.
-
-- config DEBUG_MSM_UART2
-- bool "Kernel low-level debugging messages via MSM UART2"
-- depends on ARCH_MSM7X00A || ARCH_MSM7X30 || ARCH_QSD8X50
-- select DEBUG_MSM_UART
-- help
-- Say Y here if you want the debug print routines to direct
-- their output to the second serial port on MSM devices.
-+ ARCH DEBUG_UART_PHYS DEBUG_UART_BASE #
-+ MSM7X00A, QSD8X50 0xa9a00000 0xe1000000 UART1
-+ MSM7X00A, QSD8X50 0xa9b00000 0xe1000000 UART2
-+ MSM7X00A, QSD8X50 0xa9c00000 0xe1000000 UART3
-
-- config DEBUG_MSM_UART3
-- bool "Kernel low-level debugging messages via MSM UART3"
-- depends on ARCH_MSM7X00A || ARCH_MSM7X30 || ARCH_QSD8X50
-- select DEBUG_MSM_UART
-- help
-- Say Y here if you want the debug print routines to direct
-- their output to the third serial port on MSM devices.
-+ MSM7X30 0xaca00000 0xe1000000 UART1
-+ MSM7X30 0xacb00000 0xe1000000 UART2
-+ MSM7X30 0xacc00000 0xe1000000 UART3
-
-- config DEBUG_MSM8660_UART
-- bool "Kernel low-level debugging messages via MSM 8660 UART"
-- depends on ARCH_MSM8X60
-- select MSM_HAS_DEBUG_UART_HS
-- select DEBUG_MSM_UART
-- help
-- Say Y here if you want the debug print routines to direct
-- their output to the serial port on MSM 8660 devices.
-+ Please adjust DEBUG_UART_PHYS and DEBUG_UART_BASE configuration
-+ options based on your needs.
-
-- config DEBUG_MSM8960_UART
-- bool "Kernel low-level debugging messages via MSM 8960 UART"
-- depends on ARCH_MSM8960
-- select MSM_HAS_DEBUG_UART_HS
-- select DEBUG_MSM_UART
-+ config DEBUG_QCOM_UARTDM
-+ bool "Kernel low-level debugging messages via QCOM UARTDM"
-+ depends on ARCH_QCOM
- help
- Say Y here if you want the debug print routines to direct
-- their output to the serial port on MSM 8960 devices.
-+ their output to the serial port on Qualcomm devices.
-
-- config DEBUG_MSM8974_UART
-- bool "Kernel low-level debugging messages via MSM 8974 UART"
-- depends on ARCH_MSM8974
-- select MSM_HAS_DEBUG_UART_HS
-- select DEBUG_MSM_UART
-- help
-- Say Y here if you want the debug print routines to direct
-- their output to the serial port on MSM 8974 devices.
-+ ARCH DEBUG_UART_PHYS DEBUG_UART_BASE
-+ MSM8X60 0x19c40000 0xf0040000
-+ MSM8960 0x16440000 0xf0040000
-+ MSM8974 0xf991e000 0xfa71e000
-+
-+ Please adjust DEBUG_UART_PHYS and DEBUG_UART_BASE configuration
-+ options based on your needs.
-
- config DEBUG_MVEBU_UART
- bool "Kernel low-level debugging messages via MVEBU UART (old bootloaders)"
-@@ -954,10 +937,6 @@ config DEBUG_STI_UART
- bool
- depends on ARCH_STI
-
--config DEBUG_MSM_UART
-- bool
-- depends on ARCH_MSM || ARCH_QCOM
--
- config DEBUG_LL_INCLUDE
- string
- default "debug/8250.S" if DEBUG_LL_UART_8250 || DEBUG_UART_8250
-@@ -975,7 +954,7 @@ config DEBUG_LL_INCLUDE
- DEBUG_IMX53_UART ||\
- DEBUG_IMX6Q_UART || \
- DEBUG_IMX6SL_UART
-- default "debug/msm.S" if DEBUG_MSM_UART
-+ default "debug/msm.S" if DEBUG_MSM_UART || DEBUG_QCOM_UARTDM
- default "debug/omap2plus.S" if DEBUG_OMAP2PLUS_UART
- default "debug/sirf.S" if DEBUG_SIRFPRIMA2_UART1 || DEBUG_SIRFMARCO_UART1
- default "debug/sti.S" if DEBUG_STI_UART
-@@ -1039,6 +1018,7 @@ config DEBUG_UART_PHYS
- default 0x80074000 if DEBUG_IMX28_UART
- default 0x808c0000 if ARCH_EP93XX
- default 0x90020000 if DEBUG_NSPIRE_CLASSIC_UART || DEBUG_NSPIRE_CX_UART
-+ default 0xa9a00000 if DEBUG_MSM_UART
- default 0xb0090000 if DEBUG_VEXPRESS_UART0_CRX
- default 0xc0013000 if DEBUG_U300_UART
- default 0xc8000000 if ARCH_IXP4XX && !CPU_BIG_ENDIAN
-@@ -1054,6 +1034,7 @@ config DEBUG_UART_PHYS
- ARCH_ORION5X
- default 0xf7fc9000 if DEBUG_BERLIN_UART
- default 0xf8b00000 if DEBUG_HI3716_UART
-+ default 0xf991e000 if DEBUG_QCOM_UARTDM
- default 0xfcb00000 if DEBUG_HI3620_UART
- default 0xfe800000 if ARCH_IOP32X
- default 0xffc02000 if DEBUG_SOCFPGA_UART
-@@ -1062,11 +1043,13 @@ config DEBUG_UART_PHYS
- default 0xfffff700 if ARCH_IOP33X
- depends on DEBUG_LL_UART_8250 || DEBUG_LL_UART_PL01X || \
- DEBUG_LL_UART_EFM32 || \
-- DEBUG_UART_8250 || DEBUG_UART_PL01X
-+ DEBUG_UART_8250 || DEBUG_UART_PL01X || \
-+ DEBUG_MSM_UART || DEBUG_QCOM_UARTDM
-
- config DEBUG_UART_VIRT
- hex "Virtual base address of debug UART"
- default 0xe0010fe0 if ARCH_RPC
-+ default 0xe1000000 if DEBUG_MSM_UART
- default 0xf0000be0 if ARCH_EBSA110
- default 0xf0009000 if DEBUG_CNS3XXX
- default 0xf01fb000 if DEBUG_NOMADIK_UART
-@@ -1081,6 +1064,7 @@ config DEBUG_UART_VIRT
- default 0xf7fc9000 if DEBUG_BERLIN_UART
- default 0xf8009000 if DEBUG_VEXPRESS_UART0_CA9
- default 0xf8090000 if DEBUG_VEXPRESS_UART0_RS1
-+ default 0xfa71e000 if DEBUG_QCOM_UARTDM
- default 0xfb009000 if DEBUG_REALVIEW_STD_PORT
- default 0xfb10c000 if DEBUG_REALVIEW_PB1176_PORT
- default 0xfd000000 if ARCH_SPEAR3XX || ARCH_SPEAR6XX
-@@ -1120,7 +1104,8 @@ config DEBUG_UART_VIRT
- default 0xff003000 if DEBUG_U300_UART
- default DEBUG_UART_PHYS if !MMU
- depends on DEBUG_LL_UART_8250 || DEBUG_LL_UART_PL01X || \
-- DEBUG_UART_8250 || DEBUG_UART_PL01X
-+ DEBUG_UART_8250 || DEBUG_UART_PL01X || \
-+ DEBUG_MSM_UART || DEBUG_QCOM_UARTDM
-
- config DEBUG_UART_8250_SHIFT
- int "Register offset shift for the 8250 debug UART"
---- a/arch/arm/include/debug/msm.S
-+++ b/arch/arm/include/debug/msm.S
-@@ -15,51 +15,15 @@
- *
- */
-
--#if defined(CONFIG_ARCH_MSM7X00A) || defined(CONFIG_ARCH_QSD8X50)
--#define MSM_UART1_PHYS 0xA9A00000
--#define MSM_UART2_PHYS 0xA9B00000
--#define MSM_UART3_PHYS 0xA9C00000
--#elif defined(CONFIG_ARCH_MSM7X30)
--#define MSM_UART1_PHYS 0xACA00000
--#define MSM_UART2_PHYS 0xACB00000
--#define MSM_UART3_PHYS 0xACC00000
--#endif
--
--#if defined(CONFIG_DEBUG_MSM_UART1)
--#define MSM_DEBUG_UART_BASE 0xE1000000
--#define MSM_DEBUG_UART_PHYS MSM_UART1_PHYS
--#elif defined(CONFIG_DEBUG_MSM_UART2)
--#define MSM_DEBUG_UART_BASE 0xE1000000
--#define MSM_DEBUG_UART_PHYS MSM_UART2_PHYS
--#elif defined(CONFIG_DEBUG_MSM_UART3)
--#define MSM_DEBUG_UART_BASE 0xE1000000
--#define MSM_DEBUG_UART_PHYS MSM_UART3_PHYS
--#endif
--
--#ifdef CONFIG_DEBUG_MSM8660_UART
--#define MSM_DEBUG_UART_BASE 0xF0040000
--#define MSM_DEBUG_UART_PHYS 0x19C40000
--#endif
--
--#ifdef CONFIG_DEBUG_MSM8960_UART
--#define MSM_DEBUG_UART_BASE 0xF0040000
--#define MSM_DEBUG_UART_PHYS 0x16440000
--#endif
--
--#ifdef CONFIG_DEBUG_MSM8974_UART
--#define MSM_DEBUG_UART_BASE 0xFA71E000
--#define MSM_DEBUG_UART_PHYS 0xF991E000
--#endif
--
- .macro addruart, rp, rv, tmp
--#ifdef MSM_DEBUG_UART_PHYS
-- ldr \rp, =MSM_DEBUG_UART_PHYS
-- ldr \rv, =MSM_DEBUG_UART_BASE
-+#ifdef CONFIG_DEBUG_UART_PHYS
-+ ldr \rp, =CONFIG_DEBUG_UART_PHYS
-+ ldr \rv, =CONFIG_DEBUG_UART_VIRT
- #endif
- .endm
-
- .macro senduart, rd, rx
--#ifdef CONFIG_MSM_HAS_DEBUG_UART_HS
-+#ifdef CONFIG_DEBUG_QCOM_UARTDM
- @ Write the 1 character to UARTDM_TF
- str \rd, [\rx, #0x70]
- #else
-@@ -68,7 +32,7 @@
- .endm
-
- .macro waituart, rd, rx
--#ifdef CONFIG_MSM_HAS_DEBUG_UART_HS
-+#ifdef CONFIG_DEBUG_QCOM_UARTDM
- @ check for TX_EMT in UARTDM_SR
- ldr \rd, [\rx, #0x08]
- tst \rd, #0x08
---- a/arch/arm/mach-msm/Kconfig
-+++ b/arch/arm/mach-msm/Kconfig
-@@ -42,9 +42,6 @@ config ARCH_QSD8X50
-
- endchoice
-
--config MSM_HAS_DEBUG_UART_HS
-- bool
--
- config MSM_SOC_REV_A
- bool
-
diff --git a/target/linux/ipq806x/patches/0098-ARM-debug-qcom-add-UART-addresses-to-Kconfig-help-fo.patch b/target/linux/ipq806x/patches/0098-ARM-debug-qcom-add-UART-addresses-to-Kconfig-help-fo.patch
deleted file mode 100644
index a94a7c9..0000000
--- a/target/linux/ipq806x/patches/0098-ARM-debug-qcom-add-UART-addresses-to-Kconfig-help-fo.patch
+++ /dev/null
@@ -1,25 +0,0 @@
-From 0a551e04e9a36ca1f8332071787b0e26bc5f8ecc Mon Sep 17 00:00:00 2001
-From: Georgi Djakov <gdjakov@mm-sol.com>
-Date: Fri, 23 May 2014 18:12:32 +0300
-Subject: [PATCH 098/182] ARM: debug: qcom: add UART addresses to Kconfig help
- for APQ8084
-
-Add information about the APQ8084 debug UART physical and virtual
-addresses in the DEBUG_QCOM_UARTDM Kconfig help section.
-
-Signed-off-by: Georgi Djakov <gdjakov@mm-sol.com>
-Signed-off-by: Kumar Gala <galak@codeaurora.org>
----
- arch/arm/Kconfig.debug | 1 +
- 1 file changed, 1 insertion(+)
-
---- a/arch/arm/Kconfig.debug
-+++ b/arch/arm/Kconfig.debug
-@@ -380,6 +380,7 @@ choice
- their output to the serial port on Qualcomm devices.
-
- ARCH DEBUG_UART_PHYS DEBUG_UART_BASE
-+ APQ8084 0xf995e000 0xfa75e000
- MSM8X60 0x19c40000 0xf0040000
- MSM8960 0x16440000 0xf0040000
- MSM8974 0xf991e000 0xfa71e000
diff --git a/target/linux/ipq806x/patches/0099-ARM-qcom-Enable-ARM_AMBA-option-for-Qualcomm-SOCs.patch b/target/linux/ipq806x/patches/0099-ARM-qcom-Enable-ARM_AMBA-option-for-Qualcomm-SOCs.patch
deleted file mode 100644
index 1212da2..0000000
--- a/target/linux/ipq806x/patches/0099-ARM-qcom-Enable-ARM_AMBA-option-for-Qualcomm-SOCs.patch
+++ /dev/null
@@ -1,26 +0,0 @@
-From b6ee2071ec3af3ec90d93b8b70aa17d741590148 Mon Sep 17 00:00:00 2001
-From: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
-Date: Thu, 15 May 2014 11:08:55 +0100
-Subject: [PATCH 099/182] ARM: qcom: Enable ARM_AMBA option for Qualcomm SOCs.
-
-As some of the IPs on Qualcomm SOCs are based on ARM PrimeCell IPs.
-For example SDCC controller is PrimeCell MCI pl180. Adding this option will
-give flexibility to reuse the existing drivers as it is without major
-modifications.
-
-Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
-Signed-off-by: Kumar Gala <galak@codeaurora.org>
----
- arch/arm/mach-qcom/Kconfig | 1 +
- 1 file changed, 1 insertion(+)
-
---- a/arch/arm/mach-qcom/Kconfig
-+++ b/arch/arm/mach-qcom/Kconfig
-@@ -2,6 +2,7 @@ config ARCH_QCOM
- bool "Qualcomm Support" if ARCH_MULTI_V7
- select ARCH_REQUIRE_GPIOLIB
- select ARM_GIC
-+ select ARM_AMBA
- select CLKSRC_OF
- select GENERIC_CLOCKEVENTS
- select HAVE_SMP
diff --git a/target/linux/ipq806x/patches/0100-clk-qcom-Fix-msm8660-GCC-probe.patch b/target/linux/ipq806x/patches/0100-clk-qcom-Fix-msm8660-GCC-probe.patch
deleted file mode 100644
index f1f1445..0000000
--- a/target/linux/ipq806x/patches/0100-clk-qcom-Fix-msm8660-GCC-probe.patch
+++ /dev/null
@@ -1,37 +0,0 @@
-From d54996ddc69b69fe21f776e1de1eace04bca01c3 Mon Sep 17 00:00:00 2001
-From: Stephen Boyd <sboyd@codeaurora.org>
-Date: Fri, 16 May 2014 10:05:14 -0700
-Subject: [PATCH 100/182] clk: qcom: Fix msm8660 GCC probe
-
-When consolidating the msm8660 GCC probe code I forgot to keep
-around these temporary clock registrations. Put them back so the
-clock tree is not entirely orphaned.
-
-Fixes: 49fc825f0cc2 (clk: qcom: Consolidate common probe code)
-Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
-Signed-off-by: Mike Turquette <mturquette@linaro.org>
----
- drivers/clk/qcom/gcc-msm8660.c | 12 ++++++++++++
- 1 file changed, 12 insertions(+)
-
---- a/drivers/clk/qcom/gcc-msm8660.c
-+++ b/drivers/clk/qcom/gcc-msm8660.c
-@@ -2718,6 +2718,18 @@ MODULE_DEVICE_TABLE(of, gcc_msm8660_matc
-
- static int gcc_msm8660_probe(struct platform_device *pdev)
- {
-+ struct clk *clk;
-+ struct device *dev = &pdev->dev;
-+
-+ /* Temporary until RPM clocks supported */
-+ clk = clk_register_fixed_rate(dev, "cxo", NULL, CLK_IS_ROOT, 19200000);
-+ if (IS_ERR(clk))
-+ return PTR_ERR(clk);
-+
-+ clk = clk_register_fixed_rate(dev, "pxo", NULL, CLK_IS_ROOT, 27000000);
-+ if (IS_ERR(clk))
-+ return PTR_ERR(clk);
-+
- return qcom_cc_probe(pdev, &gcc_msm8660_desc);
- }
-
diff --git a/target/linux/ipq806x/patches/0101-clk-qcom-Fix-blsp2_ahb_clk-register-offset.patch b/target/linux/ipq806x/patches/0101-clk-qcom-Fix-blsp2_ahb_clk-register-offset.patch
deleted file mode 100644
index 705582f..0000000
--- a/target/linux/ipq806x/patches/0101-clk-qcom-Fix-blsp2_ahb_clk-register-offset.patch
+++ /dev/null
@@ -1,25 +0,0 @@
-From b11c02becb4dadf5c375fef4b98f92af67106f18 Mon Sep 17 00:00:00 2001
-From: Georgi Djakov <gdjakov@mm-sol.com>
-Date: Tue, 20 May 2014 19:50:54 +0300
-Subject: [PATCH 101/182] clk: qcom: Fix blsp2_ahb_clk register offset
-
-The address of the blsp2_ahb_clk register is incorrect. Fix it.
-
-Signed-off-by: Georgi Djakov <gdjakov@mm-sol.com>
-Reviewed-by: Stephen Boyd <sboyd@codeaurora.org>
-Signed-off-by: Mike Turquette <mturquette@linaro.org>
----
- drivers/clk/qcom/gcc-msm8974.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/drivers/clk/qcom/gcc-msm8974.c
-+++ b/drivers/clk/qcom/gcc-msm8974.c
-@@ -1341,7 +1341,7 @@ static struct clk_branch gcc_blsp1_uart6
- };
-
- static struct clk_branch gcc_blsp2_ahb_clk = {
-- .halt_reg = 0x05c4,
-+ .halt_reg = 0x0944,
- .halt_check = BRANCH_HALT_VOTED,
- .clkr = {
- .enable_reg = 0x1484,
diff --git a/target/linux/ipq806x/patches/0104-clk-qcom-Return-highest-rate-when-round_rate-exceeds.patch b/target/linux/ipq806x/patches/0104-clk-qcom-Return-highest-rate-when-round_rate-exceeds.patch
deleted file mode 100644
index 3312f2f..0000000
--- a/target/linux/ipq806x/patches/0104-clk-qcom-Return-highest-rate-when-round_rate-exceeds.patch
+++ /dev/null
@@ -1,31 +0,0 @@
-From 6417bb8469eb495d7f4e4b6b0ac08cbc1b8606cb Mon Sep 17 00:00:00 2001
-From: Stephen Boyd <sboyd@codeaurora.org>
-Date: Fri, 16 May 2014 16:07:10 -0700
-Subject: [PATCH 104/182] clk: qcom: Return highest rate when round_rate()
- exceeds plan
-
-Some drivers may want to call clk_set_rate() with a very large
-number to force the clock to go as fast as it possibly can
-without having to know the range between the highest rate and
-second highest rate. Add support for this by defaulting to the
-highest rate in the frequency table if we can't find a frequency
-greater than what is requested.
-
-Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
-Signed-off-by: Mike Turquette <mturquette@linaro.org>
----
- drivers/clk/qcom/clk-rcg2.c | 3 ++-
- 1 file changed, 2 insertions(+), 1 deletion(-)
-
---- a/drivers/clk/qcom/clk-rcg2.c
-+++ b/drivers/clk/qcom/clk-rcg2.c
-@@ -181,7 +181,8 @@ struct freq_tbl *find_freq(const struct
- if (rate <= f->freq)
- return f;
-
-- return NULL;
-+ /* Default to our fastest rate */
-+ return f - 1;
- }
-
- static long _freq_tbl_determine_rate(struct clk_hw *hw,
diff --git a/target/linux/ipq806x/patches/0105-clk-qcom-Support-display-RCG-clocks.patch b/target/linux/ipq806x/patches/0105-clk-qcom-Support-display-RCG-clocks.patch
deleted file mode 100644
index befdfeb..0000000
--- a/target/linux/ipq806x/patches/0105-clk-qcom-Support-display-RCG-clocks.patch
+++ /dev/null
@@ -1,371 +0,0 @@
-From 3123079878e29eb8c541111e30de4d1bb42ac6f9 Mon Sep 17 00:00:00 2001
-From: Stephen Boyd <sboyd@codeaurora.org>
-Date: Fri, 16 May 2014 16:07:11 -0700
-Subject: [PATCH 105/182] clk: qcom: Support display RCG clocks
-
-Add support for the DSI/EDP/HDMI RCG clocks. With the proper
-display driver in place this should allow us to support display
-clocks on msm8974 based devices.
-
-Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
-Signed-off-by: Mike Turquette <mturquette@linaro.org>
----
- drivers/clk/qcom/clk-rcg.h | 3 +
- drivers/clk/qcom/clk-rcg2.c | 299 ++++++++++++++++++++++++++++++++++++++++---
- 2 files changed, 287 insertions(+), 15 deletions(-)
-
---- a/drivers/clk/qcom/clk-rcg.h
-+++ b/drivers/clk/qcom/clk-rcg.h
-@@ -155,5 +155,8 @@ struct clk_rcg2 {
- #define to_clk_rcg2(_hw) container_of(to_clk_regmap(_hw), struct clk_rcg2, clkr)
-
- extern const struct clk_ops clk_rcg2_ops;
-+extern const struct clk_ops clk_edp_pixel_ops;
-+extern const struct clk_ops clk_byte_ops;
-+extern const struct clk_ops clk_pixel_ops;
-
- #endif
---- a/drivers/clk/qcom/clk-rcg2.c
-+++ b/drivers/clk/qcom/clk-rcg2.c
-@@ -19,6 +19,7 @@
- #include <linux/clk-provider.h>
- #include <linux/delay.h>
- #include <linux/regmap.h>
-+#include <linux/math64.h>
-
- #include <asm/div64.h>
-
-@@ -225,31 +226,25 @@ static long clk_rcg2_determine_rate(stru
- return _freq_tbl_determine_rate(hw, rcg->freq_tbl, rate, p_rate, p);
- }
-
--static int __clk_rcg2_set_rate(struct clk_hw *hw, unsigned long rate)
-+static int clk_rcg2_configure(struct clk_rcg2 *rcg, const struct freq_tbl *f)
- {
-- struct clk_rcg2 *rcg = to_clk_rcg2(hw);
-- const struct freq_tbl *f;
- u32 cfg, mask;
- int ret;
-
-- f = find_freq(rcg->freq_tbl, rate);
-- if (!f)
-- return -EINVAL;
--
- if (rcg->mnd_width && f->n) {
- mask = BIT(rcg->mnd_width) - 1;
-- ret = regmap_update_bits(rcg->clkr.regmap, rcg->cmd_rcgr + M_REG,
-- mask, f->m);
-+ ret = regmap_update_bits(rcg->clkr.regmap,
-+ rcg->cmd_rcgr + M_REG, mask, f->m);
- if (ret)
- return ret;
-
-- ret = regmap_update_bits(rcg->clkr.regmap, rcg->cmd_rcgr + N_REG,
-- mask, ~(f->n - f->m));
-+ ret = regmap_update_bits(rcg->clkr.regmap,
-+ rcg->cmd_rcgr + N_REG, mask, ~(f->n - f->m));
- if (ret)
- return ret;
-
-- ret = regmap_update_bits(rcg->clkr.regmap, rcg->cmd_rcgr + D_REG,
-- mask, ~f->n);
-+ ret = regmap_update_bits(rcg->clkr.regmap,
-+ rcg->cmd_rcgr + D_REG, mask, ~f->n);
- if (ret)
- return ret;
- }
-@@ -260,14 +255,26 @@ static int __clk_rcg2_set_rate(struct cl
- cfg |= rcg->parent_map[f->src] << CFG_SRC_SEL_SHIFT;
- if (rcg->mnd_width && f->n)
- cfg |= CFG_MODE_DUAL_EDGE;
-- ret = regmap_update_bits(rcg->clkr.regmap, rcg->cmd_rcgr + CFG_REG, mask,
-- cfg);
-+ ret = regmap_update_bits(rcg->clkr.regmap,
-+ rcg->cmd_rcgr + CFG_REG, mask, cfg);
- if (ret)
- return ret;
-
- return update_config(rcg);
- }
-
-+static int __clk_rcg2_set_rate(struct clk_hw *hw, unsigned long rate)
-+{
-+ struct clk_rcg2 *rcg = to_clk_rcg2(hw);
-+ const struct freq_tbl *f;
-+
-+ f = find_freq(rcg->freq_tbl, rate);
-+ if (!f)
-+ return -EINVAL;
-+
-+ return clk_rcg2_configure(rcg, f);
-+}
-+
- static int clk_rcg2_set_rate(struct clk_hw *hw, unsigned long rate,
- unsigned long parent_rate)
- {
-@@ -290,3 +297,265 @@ const struct clk_ops clk_rcg2_ops = {
- .set_rate_and_parent = clk_rcg2_set_rate_and_parent,
- };
- EXPORT_SYMBOL_GPL(clk_rcg2_ops);
-+
-+struct frac_entry {
-+ int num;
-+ int den;
-+};
-+
-+static const struct frac_entry frac_table_675m[] = { /* link rate of 270M */
-+ { 52, 295 }, /* 119 M */
-+ { 11, 57 }, /* 130.25 M */
-+ { 63, 307 }, /* 138.50 M */
-+ { 11, 50 }, /* 148.50 M */
-+ { 47, 206 }, /* 154 M */
-+ { 31, 100 }, /* 205.25 M */
-+ { 107, 269 }, /* 268.50 M */
-+ { },
-+};
-+
-+static struct frac_entry frac_table_810m[] = { /* Link rate of 162M */
-+ { 31, 211 }, /* 119 M */
-+ { 32, 199 }, /* 130.25 M */
-+ { 63, 307 }, /* 138.50 M */
-+ { 11, 60 }, /* 148.50 M */
-+ { 50, 263 }, /* 154 M */
-+ { 31, 120 }, /* 205.25 M */
-+ { 119, 359 }, /* 268.50 M */
-+ { },
-+};
-+
-+static int clk_edp_pixel_set_rate(struct clk_hw *hw, unsigned long rate,
-+ unsigned long parent_rate)
-+{
-+ struct clk_rcg2 *rcg = to_clk_rcg2(hw);
-+ struct freq_tbl f = *rcg->freq_tbl;
-+ const struct frac_entry *frac;
-+ int delta = 100000;
-+ s64 src_rate = parent_rate;
-+ s64 request;
-+ u32 mask = BIT(rcg->hid_width) - 1;
-+ u32 hid_div;
-+
-+ if (src_rate == 810000000)
-+ frac = frac_table_810m;
-+ else
-+ frac = frac_table_675m;
-+
-+ for (; frac->num; frac++) {
-+ request = rate;
-+ request *= frac->den;
-+ request = div_s64(request, frac->num);
-+ if ((src_rate < (request - delta)) ||
-+ (src_rate > (request + delta)))
-+ continue;
-+
-+ regmap_read(rcg->clkr.regmap, rcg->cmd_rcgr + CFG_REG,
-+ &hid_div);
-+ f.pre_div = hid_div;
-+ f.pre_div >>= CFG_SRC_DIV_SHIFT;
-+ f.pre_div &= mask;
-+ f.m = frac->num;
-+ f.n = frac->den;
-+
-+ return clk_rcg2_configure(rcg, &f);
-+ }
-+
-+ return -EINVAL;
-+}
-+
-+static int clk_edp_pixel_set_rate_and_parent(struct clk_hw *hw,
-+ unsigned long rate, unsigned long parent_rate, u8 index)
-+{
-+ /* Parent index is set statically in frequency table */
-+ return clk_edp_pixel_set_rate(hw, rate, parent_rate);
-+}
-+
-+static long clk_edp_pixel_determine_rate(struct clk_hw *hw, unsigned long rate,
-+ unsigned long *p_rate, struct clk **p)
-+{
-+ struct clk_rcg2 *rcg = to_clk_rcg2(hw);
-+ const struct freq_tbl *f = rcg->freq_tbl;
-+ const struct frac_entry *frac;
-+ int delta = 100000;
-+ s64 src_rate = *p_rate;
-+ s64 request;
-+ u32 mask = BIT(rcg->hid_width) - 1;
-+ u32 hid_div;
-+
-+ /* Force the correct parent */
-+ *p = clk_get_parent_by_index(hw->clk, f->src);
-+
-+ if (src_rate == 810000000)
-+ frac = frac_table_810m;
-+ else
-+ frac = frac_table_675m;
-+
-+ for (; frac->num; frac++) {
-+ request = rate;
-+ request *= frac->den;
-+ request = div_s64(request, frac->num);
-+ if ((src_rate < (request - delta)) ||
-+ (src_rate > (request + delta)))
-+ continue;
-+
-+ regmap_read(rcg->clkr.regmap, rcg->cmd_rcgr + CFG_REG,
-+ &hid_div);
-+ hid_div >>= CFG_SRC_DIV_SHIFT;
-+ hid_div &= mask;
-+
-+ return calc_rate(src_rate, frac->num, frac->den, !!frac->den,
-+ hid_div);
-+ }
-+
-+ return -EINVAL;
-+}
-+
-+const struct clk_ops clk_edp_pixel_ops = {
-+ .is_enabled = clk_rcg2_is_enabled,
-+ .get_parent = clk_rcg2_get_parent,
-+ .set_parent = clk_rcg2_set_parent,
-+ .recalc_rate = clk_rcg2_recalc_rate,
-+ .set_rate = clk_edp_pixel_set_rate,
-+ .set_rate_and_parent = clk_edp_pixel_set_rate_and_parent,
-+ .determine_rate = clk_edp_pixel_determine_rate,
-+};
-+EXPORT_SYMBOL_GPL(clk_edp_pixel_ops);
-+
-+static long clk_byte_determine_rate(struct clk_hw *hw, unsigned long rate,
-+ unsigned long *p_rate, struct clk **p)
-+{
-+ struct clk_rcg2 *rcg = to_clk_rcg2(hw);
-+ const struct freq_tbl *f = rcg->freq_tbl;
-+ unsigned long parent_rate, div;
-+ u32 mask = BIT(rcg->hid_width) - 1;
-+
-+ if (rate == 0)
-+ return -EINVAL;
-+
-+ *p = clk_get_parent_by_index(hw->clk, f->src);
-+ *p_rate = parent_rate = __clk_round_rate(*p, rate);
-+
-+ div = DIV_ROUND_UP((2 * parent_rate), rate) - 1;
-+ div = min_t(u32, div, mask);
-+
-+ return calc_rate(parent_rate, 0, 0, 0, div);
-+}
-+
-+static int clk_byte_set_rate(struct clk_hw *hw, unsigned long rate,
-+ unsigned long parent_rate)
-+{
-+ struct clk_rcg2 *rcg = to_clk_rcg2(hw);
-+ struct freq_tbl f = *rcg->freq_tbl;
-+ unsigned long div;
-+ u32 mask = BIT(rcg->hid_width) - 1;
-+
-+ div = DIV_ROUND_UP((2 * parent_rate), rate) - 1;
-+ div = min_t(u32, div, mask);
-+
-+ f.pre_div = div;
-+
-+ return clk_rcg2_configure(rcg, &f);
-+}
-+
-+static int clk_byte_set_rate_and_parent(struct clk_hw *hw,
-+ unsigned long rate, unsigned long parent_rate, u8 index)
-+{
-+ /* Parent index is set statically in frequency table */
-+ return clk_byte_set_rate(hw, rate, parent_rate);
-+}
-+
-+const struct clk_ops clk_byte_ops = {
-+ .is_enabled = clk_rcg2_is_enabled,
-+ .get_parent = clk_rcg2_get_parent,
-+ .set_parent = clk_rcg2_set_parent,
-+ .recalc_rate = clk_rcg2_recalc_rate,
-+ .set_rate = clk_byte_set_rate,
-+ .set_rate_and_parent = clk_byte_set_rate_and_parent,
-+ .determine_rate = clk_byte_determine_rate,
-+};
-+EXPORT_SYMBOL_GPL(clk_byte_ops);
-+
-+static const struct frac_entry frac_table_pixel[] = {
-+ { 3, 8 },
-+ { 2, 9 },
-+ { 4, 9 },
-+ { 1, 1 },
-+ { }
-+};
-+
-+static long clk_pixel_determine_rate(struct clk_hw *hw, unsigned long rate,
-+ unsigned long *p_rate, struct clk **p)
-+{
-+ struct clk_rcg2 *rcg = to_clk_rcg2(hw);
-+ unsigned long request, src_rate;
-+ int delta = 100000;
-+ const struct freq_tbl *f = rcg->freq_tbl;
-+ const struct frac_entry *frac = frac_table_pixel;
-+ struct clk *parent = *p = clk_get_parent_by_index(hw->clk, f->src);
-+
-+ for (; frac->num; frac++) {
-+ request = (rate * frac->den) / frac->num;
-+
-+ src_rate = __clk_round_rate(parent, request);
-+ if ((src_rate < (request - delta)) ||
-+ (src_rate > (request + delta)))
-+ continue;
-+
-+ *p_rate = src_rate;
-+ return (src_rate * frac->num) / frac->den;
-+ }
-+
-+ return -EINVAL;
-+}
-+
-+static int clk_pixel_set_rate(struct clk_hw *hw, unsigned long rate,
-+ unsigned long parent_rate)
-+{
-+ struct clk_rcg2 *rcg = to_clk_rcg2(hw);
-+ struct freq_tbl f = *rcg->freq_tbl;
-+ const struct frac_entry *frac = frac_table_pixel;
-+ unsigned long request, src_rate;
-+ int delta = 100000;
-+ u32 mask = BIT(rcg->hid_width) - 1;
-+ u32 hid_div;
-+ struct clk *parent = clk_get_parent_by_index(hw->clk, f.src);
-+
-+ for (; frac->num; frac++) {
-+ request = (rate * frac->den) / frac->num;
-+
-+ src_rate = __clk_round_rate(parent, request);
-+ if ((src_rate < (request - delta)) ||
-+ (src_rate > (request + delta)))
-+ continue;
-+
-+ regmap_read(rcg->clkr.regmap, rcg->cmd_rcgr + CFG_REG,
-+ &hid_div);
-+ f.pre_div = hid_div;
-+ f.pre_div >>= CFG_SRC_DIV_SHIFT;
-+ f.pre_div &= mask;
-+ f.m = frac->num;
-+ f.n = frac->den;
-+
-+ return clk_rcg2_configure(rcg, &f);
-+ }
-+ return -EINVAL;
-+}
-+
-+static int clk_pixel_set_rate_and_parent(struct clk_hw *hw, unsigned long rate,
-+ unsigned long parent_rate, u8 index)
-+{
-+ /* Parent index is set statically in frequency table */
-+ return clk_pixel_set_rate(hw, rate, parent_rate);
-+}
-+
-+const struct clk_ops clk_pixel_ops = {
-+ .is_enabled = clk_rcg2_is_enabled,
-+ .get_parent = clk_rcg2_get_parent,
-+ .set_parent = clk_rcg2_set_parent,
-+ .recalc_rate = clk_rcg2_recalc_rate,
-+ .set_rate = clk_pixel_set_rate,
-+ .set_rate_and_parent = clk_pixel_set_rate_and_parent,
-+ .determine_rate = clk_pixel_determine_rate,
-+};
-+EXPORT_SYMBOL_GPL(clk_pixel_ops);
diff --git a/target/linux/ipq806x/patches/0106-clk-qcom-Properly-support-display-clocks-on-msm8974.patch b/target/linux/ipq806x/patches/0106-clk-qcom-Properly-support-display-clocks-on-msm8974.patch
deleted file mode 100644
index c798917..0000000
--- a/target/linux/ipq806x/patches/0106-clk-qcom-Properly-support-display-clocks-on-msm8974.patch
+++ /dev/null
@@ -1,254 +0,0 @@
-From 4ccbe584ecb970f86bab58c0ca93998cccc9e810 Mon Sep 17 00:00:00 2001
-From: Stephen Boyd <sboyd@codeaurora.org>
-Date: Fri, 16 May 2014 16:07:12 -0700
-Subject: [PATCH 106/182] clk: qcom: Properly support display clocks on
- msm8974
-
-The display clocks all source from dedicated phy PLLs within their
-respective multimedia hardware block. Hook up these PLLs to the
-display clocks with the appropriate parent mappings, clock flags,
-and the appropriate clock ops. This should allow the display
-clocks to work once the appropriate phy PLL driver registers their
-PLL clocks.
-
-Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
-Signed-off-by: Mike Turquette <mturquette@linaro.org>
----
- drivers/clk/qcom/mmcc-msm8974.c | 105 ++++++++++++++++++++-------------------
- 1 file changed, 54 insertions(+), 51 deletions(-)
-
---- a/drivers/clk/qcom/mmcc-msm8974.c
-+++ b/drivers/clk/qcom/mmcc-msm8974.c
-@@ -41,9 +41,11 @@
- #define P_EDPVCO 3
- #define P_GPLL1 4
- #define P_DSI0PLL 4
-+#define P_DSI0PLL_BYTE 4
- #define P_MMPLL2 4
- #define P_MMPLL3 4
- #define P_DSI1PLL 5
-+#define P_DSI1PLL_BYTE 5
-
- static const u8 mmcc_xo_mmpll0_mmpll1_gpll0_map[] = {
- [P_XO] = 0,
-@@ -161,6 +163,24 @@ static const char *mmcc_xo_dsi_hdmi_edp_
- "dsi1pll",
- };
-
-+static const u8 mmcc_xo_dsibyte_hdmi_edp_gpll0_map[] = {
-+ [P_XO] = 0,
-+ [P_EDPLINK] = 4,
-+ [P_HDMIPLL] = 3,
-+ [P_GPLL0] = 5,
-+ [P_DSI0PLL_BYTE] = 1,
-+ [P_DSI1PLL_BYTE] = 2,
-+};
-+
-+static const char *mmcc_xo_dsibyte_hdmi_edp_gpll0[] = {
-+ "xo",
-+ "edp_link_clk",
-+ "hdmipll",
-+ "gpll0_vote",
-+ "dsi0pllbyte",
-+ "dsi1pllbyte",
-+};
-+
- #define F(f, s, h, m, n) { (f), (s), (2 * (h) - 1), (m), (n) }
-
- static struct clk_pll mmpll0 = {
-@@ -500,15 +520,8 @@ static struct clk_rcg2 jpeg2_clk_src = {
- },
- };
-
--static struct freq_tbl ftbl_mdss_pclk0_clk[] = {
-- F(125000000, P_DSI0PLL, 2, 0, 0),
-- F(250000000, P_DSI0PLL, 1, 0, 0),
-- { }
--};
--
--static struct freq_tbl ftbl_mdss_pclk1_clk[] = {
-- F(125000000, P_DSI1PLL, 2, 0, 0),
-- F(250000000, P_DSI1PLL, 1, 0, 0),
-+static struct freq_tbl pixel_freq_tbl[] = {
-+ { .src = P_DSI0PLL },
- { }
- };
-
-@@ -517,12 +530,13 @@ static struct clk_rcg2 pclk0_clk_src = {
- .mnd_width = 8,
- .hid_width = 5,
- .parent_map = mmcc_xo_dsi_hdmi_edp_gpll0_map,
-- .freq_tbl = ftbl_mdss_pclk0_clk,
-+ .freq_tbl = pixel_freq_tbl,
- .clkr.hw.init = &(struct clk_init_data){
- .name = "pclk0_clk_src",
- .parent_names = mmcc_xo_dsi_hdmi_edp_gpll0,
- .num_parents = 6,
-- .ops = &clk_rcg2_ops,
-+ .ops = &clk_pixel_ops,
-+ .flags = CLK_SET_RATE_PARENT,
- },
- };
-
-@@ -531,12 +545,13 @@ static struct clk_rcg2 pclk1_clk_src = {
- .mnd_width = 8,
- .hid_width = 5,
- .parent_map = mmcc_xo_dsi_hdmi_edp_gpll0_map,
-- .freq_tbl = ftbl_mdss_pclk1_clk,
-+ .freq_tbl = pixel_freq_tbl,
- .clkr.hw.init = &(struct clk_init_data){
- .name = "pclk1_clk_src",
- .parent_names = mmcc_xo_dsi_hdmi_edp_gpll0,
- .num_parents = 6,
-- .ops = &clk_rcg2_ops,
-+ .ops = &clk_pixel_ops,
-+ .flags = CLK_SET_RATE_PARENT,
- },
- };
-
-@@ -754,41 +769,36 @@ static struct clk_rcg2 cpp_clk_src = {
- },
- };
-
--static struct freq_tbl ftbl_mdss_byte0_clk[] = {
-- F(93750000, P_DSI0PLL, 8, 0, 0),
-- F(187500000, P_DSI0PLL, 4, 0, 0),
-- { }
--};
--
--static struct freq_tbl ftbl_mdss_byte1_clk[] = {
-- F(93750000, P_DSI1PLL, 8, 0, 0),
-- F(187500000, P_DSI1PLL, 4, 0, 0),
-+static struct freq_tbl byte_freq_tbl[] = {
-+ { .src = P_DSI0PLL_BYTE },
- { }
- };
-
- static struct clk_rcg2 byte0_clk_src = {
- .cmd_rcgr = 0x2120,
- .hid_width = 5,
-- .parent_map = mmcc_xo_dsi_hdmi_edp_gpll0_map,
-- .freq_tbl = ftbl_mdss_byte0_clk,
-+ .parent_map = mmcc_xo_dsibyte_hdmi_edp_gpll0_map,
-+ .freq_tbl = byte_freq_tbl,
- .clkr.hw.init = &(struct clk_init_data){
- .name = "byte0_clk_src",
-- .parent_names = mmcc_xo_dsi_hdmi_edp_gpll0,
-+ .parent_names = mmcc_xo_dsibyte_hdmi_edp_gpll0,
- .num_parents = 6,
-- .ops = &clk_rcg2_ops,
-+ .ops = &clk_byte_ops,
-+ .flags = CLK_SET_RATE_PARENT,
- },
- };
-
- static struct clk_rcg2 byte1_clk_src = {
- .cmd_rcgr = 0x2140,
- .hid_width = 5,
-- .parent_map = mmcc_xo_dsi_hdmi_edp_gpll0_map,
-- .freq_tbl = ftbl_mdss_byte1_clk,
-+ .parent_map = mmcc_xo_dsibyte_hdmi_edp_gpll0_map,
-+ .freq_tbl = byte_freq_tbl,
- .clkr.hw.init = &(struct clk_init_data){
- .name = "byte1_clk_src",
-- .parent_names = mmcc_xo_dsi_hdmi_edp_gpll0,
-+ .parent_names = mmcc_xo_dsibyte_hdmi_edp_gpll0,
- .num_parents = 6,
-- .ops = &clk_rcg2_ops,
-+ .ops = &clk_byte_ops,
-+ .flags = CLK_SET_RATE_PARENT,
- },
- };
-
-@@ -826,12 +836,12 @@ static struct clk_rcg2 edplink_clk_src =
- .parent_names = mmcc_xo_dsi_hdmi_edp_gpll0,
- .num_parents = 6,
- .ops = &clk_rcg2_ops,
-+ .flags = CLK_SET_RATE_PARENT,
- },
- };
-
--static struct freq_tbl ftbl_mdss_edppixel_clk[] = {
-- F(175000000, P_EDPVCO, 2, 0, 0),
-- F(350000000, P_EDPVCO, 11, 0, 0),
-+static struct freq_tbl edp_pixel_freq_tbl[] = {
-+ { .src = P_EDPVCO },
- { }
- };
-
-@@ -840,12 +850,12 @@ static struct clk_rcg2 edppixel_clk_src
- .mnd_width = 8,
- .hid_width = 5,
- .parent_map = mmcc_xo_dsi_hdmi_edp_map,
-- .freq_tbl = ftbl_mdss_edppixel_clk,
-+ .freq_tbl = edp_pixel_freq_tbl,
- .clkr.hw.init = &(struct clk_init_data){
- .name = "edppixel_clk_src",
- .parent_names = mmcc_xo_dsi_hdmi_edp,
- .num_parents = 6,
-- .ops = &clk_rcg2_ops,
-+ .ops = &clk_edp_pixel_ops,
- },
- };
-
-@@ -857,11 +867,11 @@ static struct freq_tbl ftbl_mdss_esc0_1_
- static struct clk_rcg2 esc0_clk_src = {
- .cmd_rcgr = 0x2160,
- .hid_width = 5,
-- .parent_map = mmcc_xo_dsi_hdmi_edp_gpll0_map,
-+ .parent_map = mmcc_xo_dsibyte_hdmi_edp_gpll0_map,
- .freq_tbl = ftbl_mdss_esc0_1_clk,
- .clkr.hw.init = &(struct clk_init_data){
- .name = "esc0_clk_src",
-- .parent_names = mmcc_xo_dsi_hdmi_edp_gpll0,
-+ .parent_names = mmcc_xo_dsibyte_hdmi_edp_gpll0,
- .num_parents = 6,
- .ops = &clk_rcg2_ops,
- },
-@@ -870,26 +880,18 @@ static struct clk_rcg2 esc0_clk_src = {
- static struct clk_rcg2 esc1_clk_src = {
- .cmd_rcgr = 0x2180,
- .hid_width = 5,
-- .parent_map = mmcc_xo_dsi_hdmi_edp_gpll0_map,
-+ .parent_map = mmcc_xo_dsibyte_hdmi_edp_gpll0_map,
- .freq_tbl = ftbl_mdss_esc0_1_clk,
- .clkr.hw.init = &(struct clk_init_data){
- .name = "esc1_clk_src",
-- .parent_names = mmcc_xo_dsi_hdmi_edp_gpll0,
-+ .parent_names = mmcc_xo_dsibyte_hdmi_edp_gpll0,
- .num_parents = 6,
- .ops = &clk_rcg2_ops,
- },
- };
-
--static struct freq_tbl ftbl_mdss_extpclk_clk[] = {
-- F(25200000, P_HDMIPLL, 1, 0, 0),
-- F(27000000, P_HDMIPLL, 1, 0, 0),
-- F(27030000, P_HDMIPLL, 1, 0, 0),
-- F(65000000, P_HDMIPLL, 1, 0, 0),
-- F(74250000, P_HDMIPLL, 1, 0, 0),
-- F(108000000, P_HDMIPLL, 1, 0, 0),
-- F(148500000, P_HDMIPLL, 1, 0, 0),
-- F(268500000, P_HDMIPLL, 1, 0, 0),
-- F(297000000, P_HDMIPLL, 1, 0, 0),
-+static struct freq_tbl extpclk_freq_tbl[] = {
-+ { .src = P_HDMIPLL },
- { }
- };
-
-@@ -897,12 +899,13 @@ static struct clk_rcg2 extpclk_clk_src =
- .cmd_rcgr = 0x2060,
- .hid_width = 5,
- .parent_map = mmcc_xo_dsi_hdmi_edp_gpll0_map,
-- .freq_tbl = ftbl_mdss_extpclk_clk,
-+ .freq_tbl = extpclk_freq_tbl,
- .clkr.hw.init = &(struct clk_init_data){
- .name = "extpclk_clk_src",
- .parent_names = mmcc_xo_dsi_hdmi_edp_gpll0,
- .num_parents = 6,
-- .ops = &clk_rcg2_ops,
-+ .ops = &clk_byte_ops,
-+ .flags = CLK_SET_RATE_PARENT,
- },
- };
-
diff --git a/target/linux/ipq806x/patches/0107-clk-qcom-Support-msm8974pro-global-clock-control-har.patch b/target/linux/ipq806x/patches/0107-clk-qcom-Support-msm8974pro-global-clock-control-har.patch
deleted file mode 100644
index 670acad..0000000
--- a/target/linux/ipq806x/patches/0107-clk-qcom-Support-msm8974pro-global-clock-control-har.patch
+++ /dev/null
@@ -1,236 +0,0 @@
-From a740d2b024c5b71c6f9989976049f03b634bb13d Mon Sep 17 00:00:00 2001
-From: Stephen Boyd <sboyd@codeaurora.org>
-Date: Fri, 16 May 2014 16:07:13 -0700
-Subject: [PATCH 107/182] clk: qcom: Support msm8974pro global clock control
- hardware
-
-A new PLL (gpll4) is added on msm8974 PRO devices to support a
-faster sdc1 clock rate. Add support for this and the two new sdcc
-cal clocks.
-
-Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
-Signed-off-by: Mike Turquette <mturquette@linaro.org>
----
- .../devicetree/bindings/clock/qcom,gcc.txt | 2 +
- drivers/clk/qcom/gcc-msm8974.c | 130 +++++++++++++++++++-
- include/dt-bindings/clock/qcom,gcc-msm8974.h | 4 +
- 3 files changed, 130 insertions(+), 6 deletions(-)
-
---- a/Documentation/devicetree/bindings/clock/qcom,gcc.txt
-+++ b/Documentation/devicetree/bindings/clock/qcom,gcc.txt
-@@ -8,6 +8,8 @@ Required properties :
- "qcom,gcc-msm8660"
- "qcom,gcc-msm8960"
- "qcom,gcc-msm8974"
-+ "qcom,gcc-msm8974pro"
-+ "qcom,gcc-msm8974pro-ac"
-
- - reg : shall contain base register location and length
- - #clock-cells : shall contain 1
---- a/drivers/clk/qcom/gcc-msm8974.c
-+++ b/drivers/clk/qcom/gcc-msm8974.c
-@@ -35,6 +35,7 @@
- #define P_XO 0
- #define P_GPLL0 1
- #define P_GPLL1 1
-+#define P_GPLL4 2
-
- static const u8 gcc_xo_gpll0_map[] = {
- [P_XO] = 0,
-@@ -46,6 +47,18 @@ static const char *gcc_xo_gpll0[] = {
- "gpll0_vote",
- };
-
-+static const u8 gcc_xo_gpll0_gpll4_map[] = {
-+ [P_XO] = 0,
-+ [P_GPLL0] = 1,
-+ [P_GPLL4] = 5,
-+};
-+
-+static const char *gcc_xo_gpll0_gpll4[] = {
-+ "xo",
-+ "gpll0_vote",
-+ "gpll4_vote",
-+};
-+
- #define F(f, s, h, m, n) { (f), (s), (2 * (h) - 1), (m), (n) }
-
- static struct clk_pll gpll0 = {
-@@ -138,6 +151,33 @@ static struct clk_regmap gpll1_vote = {
- },
- };
-
-+static struct clk_pll gpll4 = {
-+ .l_reg = 0x1dc4,
-+ .m_reg = 0x1dc8,
-+ .n_reg = 0x1dcc,
-+ .config_reg = 0x1dd4,
-+ .mode_reg = 0x1dc0,
-+ .status_reg = 0x1ddc,
-+ .status_bit = 17,
-+ .clkr.hw.init = &(struct clk_init_data){
-+ .name = "gpll4",
-+ .parent_names = (const char *[]){ "xo" },
-+ .num_parents = 1,
-+ .ops = &clk_pll_ops,
-+ },
-+};
-+
-+static struct clk_regmap gpll4_vote = {
-+ .enable_reg = 0x1480,
-+ .enable_mask = BIT(4),
-+ .hw.init = &(struct clk_init_data){
-+ .name = "gpll4_vote",
-+ .parent_names = (const char *[]){ "gpll4" },
-+ .num_parents = 1,
-+ .ops = &clk_pll_vote_ops,
-+ },
-+};
-+
- static const struct freq_tbl ftbl_gcc_usb30_master_clk[] = {
- F(125000000, P_GPLL0, 1, 5, 24),
- { }
-@@ -812,18 +852,33 @@ static const struct freq_tbl ftbl_gcc_sd
- { }
- };
-
-+static const struct freq_tbl ftbl_gcc_sdcc1_apps_clk_pro[] = {
-+ F(144000, P_XO, 16, 3, 25),
-+ F(400000, P_XO, 12, 1, 4),
-+ F(20000000, P_GPLL0, 15, 1, 2),
-+ F(25000000, P_GPLL0, 12, 1, 2),
-+ F(50000000, P_GPLL0, 12, 0, 0),
-+ F(100000000, P_GPLL0, 6, 0, 0),
-+ F(192000000, P_GPLL4, 4, 0, 0),
-+ F(200000000, P_GPLL0, 3, 0, 0),
-+ F(384000000, P_GPLL4, 2, 0, 0),
-+ { }
-+};
-+
-+static struct clk_init_data sdcc1_apps_clk_src_init = {
-+ .name = "sdcc1_apps_clk_src",
-+ .parent_names = gcc_xo_gpll0,
-+ .num_parents = 2,
-+ .ops = &clk_rcg2_ops,
-+};
-+
- static struct clk_rcg2 sdcc1_apps_clk_src = {
- .cmd_rcgr = 0x04d0,
- .mnd_width = 8,
- .hid_width = 5,
- .parent_map = gcc_xo_gpll0_map,
- .freq_tbl = ftbl_gcc_sdcc1_4_apps_clk,
-- .clkr.hw.init = &(struct clk_init_data){
-- .name = "sdcc1_apps_clk_src",
-- .parent_names = gcc_xo_gpll0,
-- .num_parents = 2,
-- .ops = &clk_rcg2_ops,
-- },
-+ .clkr.hw.init = &sdcc1_apps_clk_src_init,
- };
-
- static struct clk_rcg2 sdcc2_apps_clk_src = {
-@@ -1995,6 +2050,38 @@ static struct clk_branch gcc_sdcc1_apps_
- },
- };
-
-+static struct clk_branch gcc_sdcc1_cdccal_ff_clk = {
-+ .halt_reg = 0x04e8,
-+ .clkr = {
-+ .enable_reg = 0x04e8,
-+ .enable_mask = BIT(0),
-+ .hw.init = &(struct clk_init_data){
-+ .name = "gcc_sdcc1_cdccal_ff_clk",
-+ .parent_names = (const char *[]){
-+ "xo"
-+ },
-+ .num_parents = 1,
-+ .ops = &clk_branch2_ops,
-+ },
-+ },
-+};
-+
-+static struct clk_branch gcc_sdcc1_cdccal_sleep_clk = {
-+ .halt_reg = 0x04e4,
-+ .clkr = {
-+ .enable_reg = 0x04e4,
-+ .enable_mask = BIT(0),
-+ .hw.init = &(struct clk_init_data){
-+ .name = "gcc_sdcc1_cdccal_sleep_clk",
-+ .parent_names = (const char *[]){
-+ "sleep_clk_src"
-+ },
-+ .num_parents = 1,
-+ .ops = &clk_branch2_ops,
-+ },
-+ },
-+};
-+
- static struct clk_branch gcc_sdcc2_ahb_clk = {
- .halt_reg = 0x0508,
- .clkr = {
-@@ -2484,6 +2571,10 @@ static struct clk_regmap *gcc_msm8974_cl
- [GCC_USB_HSIC_IO_CAL_SLEEP_CLK] = &gcc_usb_hsic_io_cal_sleep_clk.clkr,
- [GCC_USB_HSIC_SYSTEM_CLK] = &gcc_usb_hsic_system_clk.clkr,
- [GCC_MMSS_GPLL0_CLK_SRC] = &gcc_mmss_gpll0_clk_src,
-+ [GPLL4] = NULL,
-+ [GPLL4_VOTE] = NULL,
-+ [GCC_SDCC1_CDCCAL_SLEEP_CLK] = NULL,
-+ [GCC_SDCC1_CDCCAL_FF_CLK] = NULL,
- };
-
- static const struct qcom_reset_map gcc_msm8974_resets[] = {
-@@ -2585,14 +2676,41 @@ static const struct qcom_cc_desc gcc_msm
-
- static const struct of_device_id gcc_msm8974_match_table[] = {
- { .compatible = "qcom,gcc-msm8974" },
-+ { .compatible = "qcom,gcc-msm8974pro" , .data = (void *)1UL },
-+ { .compatible = "qcom,gcc-msm8974pro-ac", .data = (void *)1UL },
- { }
- };
- MODULE_DEVICE_TABLE(of, gcc_msm8974_match_table);
-
-+static void msm8974_pro_clock_override(void)
-+{
-+ sdcc1_apps_clk_src_init.parent_names = gcc_xo_gpll0_gpll4;
-+ sdcc1_apps_clk_src_init.num_parents = 3;
-+ sdcc1_apps_clk_src.freq_tbl = ftbl_gcc_sdcc1_apps_clk_pro;
-+ sdcc1_apps_clk_src.parent_map = gcc_xo_gpll0_gpll4_map;
-+
-+ gcc_msm8974_clocks[GPLL4] = &gpll4.clkr;
-+ gcc_msm8974_clocks[GPLL4_VOTE] = &gpll4_vote;
-+ gcc_msm8974_clocks[GCC_SDCC1_CDCCAL_SLEEP_CLK] =
-+ &gcc_sdcc1_cdccal_sleep_clk.clkr;
-+ gcc_msm8974_clocks[GCC_SDCC1_CDCCAL_FF_CLK] =
-+ &gcc_sdcc1_cdccal_ff_clk.clkr;
-+}
-+
- static int gcc_msm8974_probe(struct platform_device *pdev)
- {
- struct clk *clk;
- struct device *dev = &pdev->dev;
-+ bool pro;
-+ const struct of_device_id *id;
-+
-+ id = of_match_device(gcc_msm8974_match_table, dev);
-+ if (!id)
-+ return -ENODEV;
-+ pro = !!(id->data);
-+
-+ if (pro)
-+ msm8974_pro_clock_override();
-
- /* Temporary until RPM clocks supported */
- clk = clk_register_fixed_rate(dev, "xo", NULL, CLK_IS_ROOT, 19200000);
---- a/include/dt-bindings/clock/qcom,gcc-msm8974.h
-+++ b/include/dt-bindings/clock/qcom,gcc-msm8974.h
-@@ -316,5 +316,9 @@
- #define GCC_CE2_CLK_SLEEP_ENA 299
- #define GCC_CE2_AXI_CLK_SLEEP_ENA 300
- #define GCC_CE2_AHB_CLK_SLEEP_ENA 301
-+#define GPLL4 302
-+#define GPLL4_VOTE 303
-+#define GCC_SDCC1_CDCCAL_SLEEP_CLK 304
-+#define GCC_SDCC1_CDCCAL_FF_CLK 305
-
- #endif
diff --git a/target/linux/ipq806x/patches/0108-clk-qcom-Return-error-pointers-for-unimplemented-clo.patch b/target/linux/ipq806x/patches/0108-clk-qcom-Return-error-pointers-for-unimplemented-clo.patch
deleted file mode 100644
index 52d497f..0000000
--- a/target/linux/ipq806x/patches/0108-clk-qcom-Return-error-pointers-for-unimplemented-clo.patch
+++ /dev/null
@@ -1,32 +0,0 @@
-From 77b7f864b03d6b49c143a9c8c19432feef3032b5 Mon Sep 17 00:00:00 2001
-From: Stephen Boyd <sboyd@codeaurora.org>
-Date: Fri, 16 May 2014 16:07:14 -0700
-Subject: [PATCH 108/182] clk: qcom: Return error pointers for unimplemented
- clocks
-
-Not all clocks are implemented but client drivers can still
-request them. Currently we will return a NULL pointer to them if
-the clock isn't implemented in software but NULL pointers are
-valid clock pointers. Return an error pointer so that driver's
-don't proceed without a clock they may actually need.
-
-Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
-Signed-off-by: Mike Turquette <mturquette@linaro.org>
----
- drivers/clk/qcom/common.c | 4 +++-
- 1 file changed, 3 insertions(+), 1 deletion(-)
-
---- a/drivers/clk/qcom/common.c
-+++ b/drivers/clk/qcom/common.c
-@@ -62,8 +62,10 @@ int qcom_cc_probe(struct platform_device
- data->clk_num = num_clks;
-
- for (i = 0; i < num_clks; i++) {
-- if (!rclks[i])
-+ if (!rclks[i]) {
-+ clks[i] = ERR_PTR(-ENOENT);
- continue;
-+ }
- clk = devm_clk_register_regmap(dev, rclks[i]);
- if (IS_ERR(clk))
- return PTR_ERR(clk);
diff --git a/target/linux/ipq806x/patches/0109-libahci-Allow-drivers-to-override-start_engine.patch b/target/linux/ipq806x/patches/0109-libahci-Allow-drivers-to-override-start_engine.patch
deleted file mode 100644
index aa2fee6..0000000
--- a/target/linux/ipq806x/patches/0109-libahci-Allow-drivers-to-override-start_engine.patch
+++ /dev/null
@@ -1,212 +0,0 @@
-From 10f3c772363e549c3dbd3cc3755d270c5656d5b8 Mon Sep 17 00:00:00 2001
-From: Hans de Goede <hdegoede@redhat.com>
-Date: Sat, 22 Feb 2014 16:53:30 +0100
-Subject: [PATCH 109/182] libahci: Allow drivers to override start_engine
-
-Allwinner A10 and A20 ARM SoCs have an AHCI sata controller which needs a
-special register to be poked before starting the DMA engine.
-
-This register gets reset on an ahci_stop_engine call, so there is no other
-place then ahci_start_engine where this poking can be done.
-
-This commit allows drivers to override ahci_start_engine behavior for use by
-the Allwinner AHCI driver (and potentially other drivers in the future).
-
-Signed-off-by: Hans de Goede <hdegoede@redhat.com>
-Signed-off-by: Tejun Heo <tj@kernel.org>
----
- drivers/ata/ahci.c | 6 ++++--
- drivers/ata/ahci.h | 6 ++++++
- drivers/ata/libahci.c | 26 +++++++++++++++++++-------
- drivers/ata/sata_highbank.c | 3 ++-
- 4 files changed, 31 insertions(+), 10 deletions(-)
-
---- a/drivers/ata/ahci.c
-+++ b/drivers/ata/ahci.c
-@@ -606,6 +606,7 @@ static int ahci_vt8251_hardreset(struct
- unsigned long deadline)
- {
- struct ata_port *ap = link->ap;
-+ struct ahci_host_priv *hpriv = ap->host->private_data;
- bool online;
- int rc;
-
-@@ -616,7 +617,7 @@ static int ahci_vt8251_hardreset(struct
- rc = sata_link_hardreset(link, sata_ehc_deb_timing(&link->eh_context),
- deadline, &online, NULL);
-
-- ahci_start_engine(ap);
-+ hpriv->start_engine(ap);
-
- DPRINTK("EXIT, rc=%d, class=%u\n", rc, *class);
-
-@@ -631,6 +632,7 @@ static int ahci_p5wdh_hardreset(struct a
- {
- struct ata_port *ap = link->ap;
- struct ahci_port_priv *pp = ap->private_data;
-+ struct ahci_host_priv *hpriv = ap->host->private_data;
- u8 *d2h_fis = pp->rx_fis + RX_FIS_D2H_REG;
- struct ata_taskfile tf;
- bool online;
-@@ -646,7 +648,7 @@ static int ahci_p5wdh_hardreset(struct a
- rc = sata_link_hardreset(link, sata_ehc_deb_timing(&link->eh_context),
- deadline, &online, NULL);
-
-- ahci_start_engine(ap);
-+ hpriv->start_engine(ap);
-
- /* The pseudo configuration device on SIMG4726 attached to
- * ASUS P5W-DH Deluxe doesn't send signature FIS after
---- a/drivers/ata/ahci.h
-+++ b/drivers/ata/ahci.h
-@@ -324,6 +324,12 @@ struct ahci_host_priv {
- u32 em_msg_type; /* EM message type */
- struct clk *clk; /* Only for platforms supporting clk */
- void *plat_data; /* Other platform data */
-+ /*
-+ * Optional ahci_start_engine override, if not set this gets set to the
-+ * default ahci_start_engine during ahci_save_initial_config, this can
-+ * be overridden anytime before the host is activated.
-+ */
-+ void (*start_engine)(struct ata_port *ap);
- };
-
- extern int ahci_ignore_sss;
---- a/drivers/ata/libahci.c
-+++ b/drivers/ata/libahci.c
-@@ -394,6 +394,9 @@ static ssize_t ahci_show_em_supported(st
- *
- * If inconsistent, config values are fixed up by this function.
- *
-+ * If it is not set already this function sets hpriv->start_engine to
-+ * ahci_start_engine.
-+ *
- * LOCKING:
- * None.
- */
-@@ -500,6 +503,9 @@ void ahci_save_initial_config(struct dev
- hpriv->cap = cap;
- hpriv->cap2 = cap2;
- hpriv->port_map = port_map;
-+
-+ if (!hpriv->start_engine)
-+ hpriv->start_engine = ahci_start_engine;
- }
- EXPORT_SYMBOL_GPL(ahci_save_initial_config);
-
-@@ -766,7 +772,7 @@ static void ahci_start_port(struct ata_p
-
- /* enable DMA */
- if (!(hpriv->flags & AHCI_HFLAG_DELAY_ENGINE))
-- ahci_start_engine(ap);
-+ hpriv->start_engine(ap);
-
- /* turn on LEDs */
- if (ap->flags & ATA_FLAG_EM) {
-@@ -1234,7 +1240,7 @@ int ahci_kick_engine(struct ata_port *ap
-
- /* restart engine */
- out_restart:
-- ahci_start_engine(ap);
-+ hpriv->start_engine(ap);
- return rc;
- }
- EXPORT_SYMBOL_GPL(ahci_kick_engine);
-@@ -1426,6 +1432,7 @@ static int ahci_hardreset(struct ata_lin
- const unsigned long *timing = sata_ehc_deb_timing(&link->eh_context);
- struct ata_port *ap = link->ap;
- struct ahci_port_priv *pp = ap->private_data;
-+ struct ahci_host_priv *hpriv = ap->host->private_data;
- u8 *d2h_fis = pp->rx_fis + RX_FIS_D2H_REG;
- struct ata_taskfile tf;
- bool online;
-@@ -1443,7 +1450,7 @@ static int ahci_hardreset(struct ata_lin
- rc = sata_link_hardreset(link, timing, deadline, &online,
- ahci_check_ready);
-
-- ahci_start_engine(ap);
-+ hpriv->start_engine(ap);
-
- if (online)
- *class = ahci_dev_classify(ap);
-@@ -2007,10 +2014,12 @@ static void ahci_thaw(struct ata_port *a
-
- void ahci_error_handler(struct ata_port *ap)
- {
-+ struct ahci_host_priv *hpriv = ap->host->private_data;
-+
- if (!(ap->pflags & ATA_PFLAG_FROZEN)) {
- /* restart engine */
- ahci_stop_engine(ap);
-- ahci_start_engine(ap);
-+ hpriv->start_engine(ap);
- }
-
- sata_pmp_error_handler(ap);
-@@ -2031,6 +2040,7 @@ static void ahci_post_internal_cmd(struc
-
- static void ahci_set_aggressive_devslp(struct ata_port *ap, bool sleep)
- {
-+ struct ahci_host_priv *hpriv = ap->host->private_data;
- void __iomem *port_mmio = ahci_port_base(ap);
- struct ata_device *dev = ap->link.device;
- u32 devslp, dm, dito, mdat, deto;
-@@ -2094,7 +2104,7 @@ static void ahci_set_aggressive_devslp(s
- PORT_DEVSLP_ADSE);
- writel(devslp, port_mmio + PORT_DEVSLP);
-
-- ahci_start_engine(ap);
-+ hpriv->start_engine(ap);
-
- /* enable device sleep feature for the drive */
- err_mask = ata_dev_set_feature(dev,
-@@ -2106,6 +2116,7 @@ static void ahci_set_aggressive_devslp(s
-
- static void ahci_enable_fbs(struct ata_port *ap)
- {
-+ struct ahci_host_priv *hpriv = ap->host->private_data;
- struct ahci_port_priv *pp = ap->private_data;
- void __iomem *port_mmio = ahci_port_base(ap);
- u32 fbs;
-@@ -2134,11 +2145,12 @@ static void ahci_enable_fbs(struct ata_p
- } else
- dev_err(ap->host->dev, "Failed to enable FBS\n");
-
-- ahci_start_engine(ap);
-+ hpriv->start_engine(ap);
- }
-
- static void ahci_disable_fbs(struct ata_port *ap)
- {
-+ struct ahci_host_priv *hpriv = ap->host->private_data;
- struct ahci_port_priv *pp = ap->private_data;
- void __iomem *port_mmio = ahci_port_base(ap);
- u32 fbs;
-@@ -2166,7 +2178,7 @@ static void ahci_disable_fbs(struct ata_
- pp->fbs_enabled = false;
- }
-
-- ahci_start_engine(ap);
-+ hpriv->start_engine(ap);
- }
-
- static void ahci_pmp_attach(struct ata_port *ap)
---- a/drivers/ata/sata_highbank.c
-+++ b/drivers/ata/sata_highbank.c
-@@ -403,6 +403,7 @@ static int ahci_highbank_hardreset(struc
- static const unsigned long timing[] = { 5, 100, 500};
- struct ata_port *ap = link->ap;
- struct ahci_port_priv *pp = ap->private_data;
-+ struct ahci_host_priv *hpriv = ap->host->private_data;
- u8 *d2h_fis = pp->rx_fis + RX_FIS_D2H_REG;
- struct ata_taskfile tf;
- bool online;
-@@ -431,7 +432,7 @@ static int ahci_highbank_hardreset(struc
- break;
- } while (!online && retry--);
-
-- ahci_start_engine(ap);
-+ hpriv->start_engine(ap);
-
- if (online)
- *class = ahci_dev_classify(ap);
diff --git a/target/linux/ipq806x/patches/0110-ahci-platform-Add-support-for-devices-with-more-then.patch b/target/linux/ipq806x/patches/0110-ahci-platform-Add-support-for-devices-with-more-then.patch
deleted file mode 100644
index 54f84ee..0000000
--- a/target/linux/ipq806x/patches/0110-ahci-platform-Add-support-for-devices-with-more-then.patch
+++ /dev/null
@@ -1,242 +0,0 @@
-From b7ad421c184b827806c7f65be3a980cfc855b589 Mon Sep 17 00:00:00 2001
-From: Hans de Goede <hdegoede@redhat.com>
-Date: Sat, 22 Feb 2014 16:53:31 +0100
-Subject: [PATCH 110/182] ahci-platform: Add support for devices with more
- then 1 clock
-
-The allwinner-sun4i AHCI controller needs 2 clocks to be enabled and the
-imx AHCI controller needs 3 clocks to be enabled.
-
-tj: Minor comment formatting updates.
-
-Signed-off-by: Hans de Goede <hdegoede@redhat.com>
-Signed-off-by: Tejun Heo <tj@kernel.org>
----
- .../devicetree/bindings/ata/ahci-platform.txt | 1 +
- drivers/ata/ahci.h | 3 +-
- drivers/ata/ahci_platform.c | 113 +++++++++++++++-----
- include/linux/ahci_platform.h | 4 +
- 4 files changed, 93 insertions(+), 28 deletions(-)
-
---- a/Documentation/devicetree/bindings/ata/ahci-platform.txt
-+++ b/Documentation/devicetree/bindings/ata/ahci-platform.txt
-@@ -10,6 +10,7 @@ Required properties:
-
- Optional properties:
- - dma-coherent : Present if dma operations are coherent
-+- clocks : a list of phandle + clock specifier pairs
-
- Example:
- sata@ffe08000 {
---- a/drivers/ata/ahci.h
-+++ b/drivers/ata/ahci.h
-@@ -51,6 +51,7 @@
-
- enum {
- AHCI_MAX_PORTS = 32,
-+ AHCI_MAX_CLKS = 3,
- AHCI_MAX_SG = 168, /* hardware max is 64K */
- AHCI_DMA_BOUNDARY = 0xffffffff,
- AHCI_MAX_CMDS = 32,
-@@ -322,7 +323,7 @@ struct ahci_host_priv {
- u32 em_loc; /* enclosure management location */
- u32 em_buf_sz; /* EM buffer size in byte */
- u32 em_msg_type; /* EM message type */
-- struct clk *clk; /* Only for platforms supporting clk */
-+ struct clk *clks[AHCI_MAX_CLKS]; /* Optional */
- void *plat_data; /* Other platform data */
- /*
- * Optional ahci_start_engine override, if not set this gets set to the
---- a/drivers/ata/ahci_platform.c
-+++ b/drivers/ata/ahci_platform.c
-@@ -87,6 +87,60 @@ static struct scsi_host_template ahci_pl
- AHCI_SHT("ahci_platform"),
- };
-
-+/**
-+ * ahci_platform_enable_clks - Enable platform clocks
-+ * @hpriv: host private area to store config values
-+ *
-+ * This function enables all the clks found in hpriv->clks, starting at
-+ * index 0. If any clk fails to enable it disables all the clks already
-+ * enabled in reverse order, and then returns an error.
-+ *
-+ * RETURNS:
-+ * 0 on success otherwise a negative error code
-+ */
-+int ahci_platform_enable_clks(struct ahci_host_priv *hpriv)
-+{
-+ int c, rc;
-+
-+ for (c = 0; c < AHCI_MAX_CLKS && hpriv->clks[c]; c++) {
-+ rc = clk_prepare_enable(hpriv->clks[c]);
-+ if (rc)
-+ goto disable_unprepare_clk;
-+ }
-+ return 0;
-+
-+disable_unprepare_clk:
-+ while (--c >= 0)
-+ clk_disable_unprepare(hpriv->clks[c]);
-+ return rc;
-+}
-+EXPORT_SYMBOL_GPL(ahci_platform_enable_clks);
-+
-+/**
-+ * ahci_platform_disable_clks - Disable platform clocks
-+ * @hpriv: host private area to store config values
-+ *
-+ * This function disables all the clks found in hpriv->clks, in reverse
-+ * order of ahci_platform_enable_clks (starting at the end of the array).
-+ */
-+void ahci_platform_disable_clks(struct ahci_host_priv *hpriv)
-+{
-+ int c;
-+
-+ for (c = AHCI_MAX_CLKS - 1; c >= 0; c--)
-+ if (hpriv->clks[c])
-+ clk_disable_unprepare(hpriv->clks[c]);
-+}
-+EXPORT_SYMBOL_GPL(ahci_platform_disable_clks);
-+
-+static void ahci_put_clks(struct ahci_host_priv *hpriv)
-+{
-+ int c;
-+
-+ for (c = 0; c < AHCI_MAX_CLKS && hpriv->clks[c]; c++)
-+ clk_put(hpriv->clks[c]);
-+}
-+
- static int ahci_probe(struct platform_device *pdev)
- {
- struct device *dev = &pdev->dev;
-@@ -97,6 +151,7 @@ static int ahci_probe(struct platform_de
- struct ahci_host_priv *hpriv;
- struct ata_host *host;
- struct resource *mem;
-+ struct clk *clk;
- int irq;
- int n_ports;
- int i;
-@@ -131,17 +186,31 @@ static int ahci_probe(struct platform_de
- return -ENOMEM;
- }
-
-- hpriv->clk = clk_get(dev, NULL);
-- if (IS_ERR(hpriv->clk)) {
-- dev_err(dev, "can't get clock\n");
-- } else {
-- rc = clk_prepare_enable(hpriv->clk);
-- if (rc) {
-- dev_err(dev, "clock prepare enable failed");
-- goto free_clk;
-+ for (i = 0; i < AHCI_MAX_CLKS; i++) {
-+ /*
-+ * For now we must use clk_get(dev, NULL) for the first clock,
-+ * because some platforms (da850, spear13xx) are not yet
-+ * converted to use devicetree for clocks. For new platforms
-+ * this is equivalent to of_clk_get(dev->of_node, 0).
-+ */
-+ if (i == 0)
-+ clk = clk_get(dev, NULL);
-+ else
-+ clk = of_clk_get(dev->of_node, i);
-+
-+ if (IS_ERR(clk)) {
-+ rc = PTR_ERR(clk);
-+ if (rc == -EPROBE_DEFER)
-+ goto free_clk;
-+ break;
- }
-+ hpriv->clks[i] = clk;
- }
-
-+ rc = ahci_enable_clks(dev, hpriv);
-+ if (rc)
-+ goto free_clk;
-+
- /*
- * Some platforms might need to prepare for mmio region access,
- * which could be done in the following init call. So, the mmio
-@@ -222,11 +291,9 @@ pdata_exit:
- if (pdata && pdata->exit)
- pdata->exit(dev);
- disable_unprepare_clk:
-- if (!IS_ERR(hpriv->clk))
-- clk_disable_unprepare(hpriv->clk);
-+ ahci_disable_clks(hpriv);
- free_clk:
-- if (!IS_ERR(hpriv->clk))
-- clk_put(hpriv->clk);
-+ ahci_put_clks(hpriv);
- return rc;
- }
-
-@@ -239,10 +306,8 @@ static void ahci_host_stop(struct ata_ho
- if (pdata && pdata->exit)
- pdata->exit(dev);
-
-- if (!IS_ERR(hpriv->clk)) {
-- clk_disable_unprepare(hpriv->clk);
-- clk_put(hpriv->clk);
-- }
-+ ahci_disable_clks(hpriv);
-+ ahci_put_clks(hpriv);
- }
-
- #ifdef CONFIG_PM_SLEEP
-@@ -277,8 +342,7 @@ static int ahci_suspend(struct device *d
- if (pdata && pdata->suspend)
- return pdata->suspend(dev);
-
-- if (!IS_ERR(hpriv->clk))
-- clk_disable_unprepare(hpriv->clk);
-+ ahci_disable_clks(hpriv);
-
- return 0;
- }
-@@ -290,13 +354,9 @@ static int ahci_resume(struct device *de
- struct ahci_host_priv *hpriv = host->private_data;
- int rc;
-
-- if (!IS_ERR(hpriv->clk)) {
-- rc = clk_prepare_enable(hpriv->clk);
-- if (rc) {
-- dev_err(dev, "clock prepare enable failed");
-- return rc;
-- }
-- }
-+ rc = ahci_enable_clks(dev, hpriv);
-+ if (rc)
-+ return rc;
-
- if (pdata && pdata->resume) {
- rc = pdata->resume(dev);
-@@ -317,8 +377,7 @@ static int ahci_resume(struct device *de
- return 0;
-
- disable_unprepare_clk:
-- if (!IS_ERR(hpriv->clk))
-- clk_disable_unprepare(hpriv->clk);
-+ ahci_disable_clks(hpriv);
-
- return rc;
- }
---- a/include/linux/ahci_platform.h
-+++ b/include/linux/ahci_platform.h
-@@ -19,6 +19,7 @@
-
- struct device;
- struct ata_port_info;
-+struct ahci_host_priv;
-
- struct ahci_platform_data {
- int (*init)(struct device *dev, void __iomem *addr);
-@@ -30,4 +31,7 @@ struct ahci_platform_data {
- unsigned int mask_port_map;
- };
-
-+int ahci_platform_enable_clks(struct ahci_host_priv *hpriv);
-+void ahci_platform_disable_clks(struct ahci_host_priv *hpriv);
-+
- #endif /* _AHCI_PLATFORM_H */
diff --git a/target/linux/ipq806x/patches/0111-ahci-platform-Add-support-for-an-optional-regulator-.patch b/target/linux/ipq806x/patches/0111-ahci-platform-Add-support-for-an-optional-regulator-.patch
deleted file mode 100644
index a8b1c6f..0000000
--- a/target/linux/ipq806x/patches/0111-ahci-platform-Add-support-for-an-optional-regulator-.patch
+++ /dev/null
@@ -1,133 +0,0 @@
-From 967f4a7821a3356d9d3c8b641537cd6d5eb15439 Mon Sep 17 00:00:00 2001
-From: Hans de Goede <hdegoede@redhat.com>
-Date: Sat, 22 Feb 2014 16:53:32 +0100
-Subject: [PATCH 111/182] ahci-platform: Add support for an optional regulator
- for sata-target power
-
-Signed-off-by: Hans de Goede <hdegoede@redhat.com>
-Signed-off-by: Tejun Heo <tj@kernel.org>
----
- .../devicetree/bindings/ata/ahci-platform.txt | 1 +
- drivers/ata/ahci.h | 2 ++
- drivers/ata/ahci_platform.c | 36 ++++++++++++++++++--
- 3 files changed, 37 insertions(+), 2 deletions(-)
-
---- a/Documentation/devicetree/bindings/ata/ahci-platform.txt
-+++ b/Documentation/devicetree/bindings/ata/ahci-platform.txt
-@@ -11,6 +11,7 @@ Required properties:
- Optional properties:
- - dma-coherent : Present if dma operations are coherent
- - clocks : a list of phandle + clock specifier pairs
-+- target-supply : regulator for SATA target power
-
- Example:
- sata@ffe08000 {
---- a/drivers/ata/ahci.h
-+++ b/drivers/ata/ahci.h
-@@ -37,6 +37,7 @@
-
- #include <linux/clk.h>
- #include <linux/libata.h>
-+#include <linux/regulator/consumer.h>
-
- /* Enclosure Management Control */
- #define EM_CTRL_MSG_TYPE 0x000f0000
-@@ -324,6 +325,7 @@ struct ahci_host_priv {
- u32 em_buf_sz; /* EM buffer size in byte */
- u32 em_msg_type; /* EM message type */
- struct clk *clks[AHCI_MAX_CLKS]; /* Optional */
-+ struct regulator *target_pwr; /* Optional */
- void *plat_data; /* Other platform data */
- /*
- * Optional ahci_start_engine override, if not set this gets set to the
---- a/drivers/ata/ahci_platform.c
-+++ b/drivers/ata/ahci_platform.c
-@@ -186,6 +186,14 @@ static int ahci_probe(struct platform_de
- return -ENOMEM;
- }
-
-+ hpriv->target_pwr = devm_regulator_get_optional(dev, "target");
-+ if (IS_ERR(hpriv->target_pwr)) {
-+ rc = PTR_ERR(hpriv->target_pwr);
-+ if (rc == -EPROBE_DEFER)
-+ return -EPROBE_DEFER;
-+ hpriv->target_pwr = NULL;
-+ }
-+
- for (i = 0; i < AHCI_MAX_CLKS; i++) {
- /*
- * For now we must use clk_get(dev, NULL) for the first clock,
-@@ -207,9 +215,15 @@ static int ahci_probe(struct platform_de
- hpriv->clks[i] = clk;
- }
-
-+ if (hpriv->target_pwr) {
-+ rc = regulator_enable(hpriv->target_pwr);
-+ if (rc)
-+ goto free_clk;
-+ }
-+
- rc = ahci_enable_clks(dev, hpriv);
- if (rc)
-- goto free_clk;
-+ goto disable_regulator;
-
- /*
- * Some platforms might need to prepare for mmio region access,
-@@ -292,6 +306,9 @@ pdata_exit:
- pdata->exit(dev);
- disable_unprepare_clk:
- ahci_disable_clks(hpriv);
-+disable_regulator:
-+ if (hpriv->target_pwr)
-+ regulator_disable(hpriv->target_pwr);
- free_clk:
- ahci_put_clks(hpriv);
- return rc;
-@@ -308,6 +325,9 @@ static void ahci_host_stop(struct ata_ho
-
- ahci_disable_clks(hpriv);
- ahci_put_clks(hpriv);
-+
-+ if (hpriv->target_pwr)
-+ regulator_disable(hpriv->target_pwr);
- }
-
- #ifdef CONFIG_PM_SLEEP
-@@ -344,6 +364,9 @@ static int ahci_suspend(struct device *d
-
- ahci_disable_clks(hpriv);
-
-+ if (hpriv->target_pwr)
-+ regulator_disable(hpriv->target_pwr);
-+
- return 0;
- }
-
-@@ -354,9 +377,15 @@ static int ahci_resume(struct device *de
- struct ahci_host_priv *hpriv = host->private_data;
- int rc;
-
-+ if (hpriv->target_pwr) {
-+ rc = regulator_enable(hpriv->target_pwr);
-+ if (rc)
-+ return rc;
-+ }
-+
- rc = ahci_enable_clks(dev, hpriv);
- if (rc)
-- return rc;
-+ goto disable_regulator;
-
- if (pdata && pdata->resume) {
- rc = pdata->resume(dev);
-@@ -378,6 +407,9 @@ static int ahci_resume(struct device *de
-
- disable_unprepare_clk:
- ahci_disable_clks(hpriv);
-+disable_regulator:
-+ if (hpriv->target_pwr)
-+ regulator_disable(hpriv->target_pwr);
-
- return rc;
- }
diff --git a/target/linux/ipq806x/patches/0112-ahci-platform-Add-enable_-disable_resources-helper-f.patch b/target/linux/ipq806x/patches/0112-ahci-platform-Add-enable_-disable_resources-helper-f.patch
deleted file mode 100644
index 888ee32..0000000
--- a/target/linux/ipq806x/patches/0112-ahci-platform-Add-enable_-disable_resources-helper-f.patch
+++ /dev/null
@@ -1,201 +0,0 @@
-From 3b2df84624b38362cb84c2d4c6d1d3540c5069d3 Mon Sep 17 00:00:00 2001
-From: Hans de Goede <hdegoede@redhat.com>
-Date: Sat, 22 Feb 2014 16:53:33 +0100
-Subject: [PATCH 112/182] ahci-platform: Add enable_ / disable_resources
- helper functions
-
-tj: Minor comment formatting updates.
-
-Signed-off-by: Hans de Goede <hdegoede@redhat.com>
-Signed-off-by: Tejun Heo <tj@kernel.org>
----
- drivers/ata/ahci_platform.c | 106 +++++++++++++++++++++++++++--------------
- include/linux/ahci_platform.h | 2 +
- 2 files changed, 71 insertions(+), 37 deletions(-)
-
---- a/drivers/ata/ahci_platform.c
-+++ b/drivers/ata/ahci_platform.c
-@@ -133,6 +133,62 @@ void ahci_platform_disable_clks(struct a
- }
- EXPORT_SYMBOL_GPL(ahci_platform_disable_clks);
-
-+/**
-+ * ahci_platform_enable_resources - Enable platform resources
-+ * @hpriv: host private area to store config values
-+ *
-+ * This function enables all ahci_platform managed resources in the
-+ * following order:
-+ * 1) Regulator
-+ * 2) Clocks (through ahci_platform_enable_clks)
-+ *
-+ * If resource enabling fails at any point the previous enabled resources
-+ * are disabled in reverse order.
-+ *
-+ * RETURNS:
-+ * 0 on success otherwise a negative error code
-+ */
-+int ahci_platform_enable_resources(struct ahci_host_priv *hpriv)
-+{
-+ int rc;
-+
-+ if (hpriv->target_pwr) {
-+ rc = regulator_enable(hpriv->target_pwr);
-+ if (rc)
-+ return rc;
-+ }
-+
-+ rc = ahci_platform_enable_clks(hpriv);
-+ if (rc)
-+ goto disable_regulator;
-+
-+ return 0;
-+
-+disable_regulator:
-+ if (hpriv->target_pwr)
-+ regulator_disable(hpriv->target_pwr);
-+ return rc;
-+}
-+EXPORT_SYMBOL_GPL(ahci_platform_enable_resources);
-+
-+/**
-+ * ahci_platform_disable_resources - Disable platform resources
-+ * @hpriv: host private area to store config values
-+ *
-+ * This function disables all ahci_platform managed resources in the
-+ * following order:
-+ * 1) Clocks (through ahci_platform_disable_clks)
-+ * 2) Regulator
-+ */
-+void ahci_platform_disable_resources(struct ahci_host_priv *hpriv)
-+{
-+ ahci_platform_disable_clks(hpriv);
-+
-+ if (hpriv->target_pwr)
-+ regulator_disable(hpriv->target_pwr);
-+}
-+EXPORT_SYMBOL_GPL(ahci_platform_disable_resources);
-+
- static void ahci_put_clks(struct ahci_host_priv *hpriv)
- {
- int c;
-@@ -215,15 +271,9 @@ static int ahci_probe(struct platform_de
- hpriv->clks[i] = clk;
- }
-
-- if (hpriv->target_pwr) {
-- rc = regulator_enable(hpriv->target_pwr);
-- if (rc)
-- goto free_clk;
-- }
--
-- rc = ahci_enable_clks(dev, hpriv);
-+ rc = ahci_platform_enable_resources(hpriv);
- if (rc)
-- goto disable_regulator;
-+ goto free_clk;
-
- /*
- * Some platforms might need to prepare for mmio region access,
-@@ -234,7 +284,7 @@ static int ahci_probe(struct platform_de
- if (pdata && pdata->init) {
- rc = pdata->init(dev, hpriv->mmio);
- if (rc)
-- goto disable_unprepare_clk;
-+ goto disable_resources;
- }
-
- ahci_save_initial_config(dev, hpriv,
-@@ -304,11 +354,8 @@ static int ahci_probe(struct platform_de
- pdata_exit:
- if (pdata && pdata->exit)
- pdata->exit(dev);
--disable_unprepare_clk:
-- ahci_disable_clks(hpriv);
--disable_regulator:
-- if (hpriv->target_pwr)
-- regulator_disable(hpriv->target_pwr);
-+disable_resources:
-+ ahci_platform_disable_resources(hpriv);
- free_clk:
- ahci_put_clks(hpriv);
- return rc;
-@@ -323,11 +370,8 @@ static void ahci_host_stop(struct ata_ho
- if (pdata && pdata->exit)
- pdata->exit(dev);
-
-- ahci_disable_clks(hpriv);
-+ ahci_platform_disable_resources(hpriv);
- ahci_put_clks(hpriv);
--
-- if (hpriv->target_pwr)
-- regulator_disable(hpriv->target_pwr);
- }
-
- #ifdef CONFIG_PM_SLEEP
-@@ -362,10 +406,7 @@ static int ahci_suspend(struct device *d
- if (pdata && pdata->suspend)
- return pdata->suspend(dev);
-
-- ahci_disable_clks(hpriv);
--
-- if (hpriv->target_pwr)
-- regulator_disable(hpriv->target_pwr);
-+ ahci_platform_disable_resources(hpriv);
-
- return 0;
- }
-@@ -377,26 +418,20 @@ static int ahci_resume(struct device *de
- struct ahci_host_priv *hpriv = host->private_data;
- int rc;
-
-- if (hpriv->target_pwr) {
-- rc = regulator_enable(hpriv->target_pwr);
-- if (rc)
-- return rc;
-- }
--
-- rc = ahci_enable_clks(dev, hpriv);
-+ rc = ahci_platform_enable_resources(hpriv);
- if (rc)
-- goto disable_regulator;
-+ return rc;
-
- if (pdata && pdata->resume) {
- rc = pdata->resume(dev);
- if (rc)
-- goto disable_unprepare_clk;
-+ goto disable_resources;
- }
-
- if (dev->power.power_state.event == PM_EVENT_SUSPEND) {
- rc = ahci_reset_controller(host);
- if (rc)
-- goto disable_unprepare_clk;
-+ goto disable_resources;
-
- ahci_init_controller(host);
- }
-@@ -405,11 +440,8 @@ static int ahci_resume(struct device *de
-
- return 0;
-
--disable_unprepare_clk:
-- ahci_disable_clks(hpriv);
--disable_regulator:
-- if (hpriv->target_pwr)
-- regulator_disable(hpriv->target_pwr);
-+disable_resources:
-+ ahci_platform_disable_resources(hpriv);
-
- return rc;
- }
---- a/include/linux/ahci_platform.h
-+++ b/include/linux/ahci_platform.h
-@@ -33,5 +33,7 @@ struct ahci_platform_data {
-
- int ahci_platform_enable_clks(struct ahci_host_priv *hpriv);
- void ahci_platform_disable_clks(struct ahci_host_priv *hpriv);
-+int ahci_platform_enable_resources(struct ahci_host_priv *hpriv);
-+void ahci_platform_disable_resources(struct ahci_host_priv *hpriv);
-
- #endif /* _AHCI_PLATFORM_H */
diff --git a/target/linux/ipq806x/patches/0113-ata-delete-non-required-instances-of-include-linux-i.patch b/target/linux/ipq806x/patches/0113-ata-delete-non-required-instances-of-include-linux-i.patch
deleted file mode 100644
index 18e034e..0000000
--- a/target/linux/ipq806x/patches/0113-ata-delete-non-required-instances-of-include-linux-i.patch
+++ /dev/null
@@ -1,765 +0,0 @@
-From 01b380db3c35bbd87cb3765573fd049bce3d7640 Mon Sep 17 00:00:00 2001
-From: Paul Gortmaker <paul.gortmaker@windriver.com>
-Date: Tue, 21 Jan 2014 16:22:51 -0500
-Subject: [PATCH 113/182] ata: delete non-required instances of include
- <linux/init.h>
-
-None of these files are actually using any __init type directives
-and hence don't need to include <linux/init.h>. Most are just a
-left over from __devinit and __cpuinit removal, or simply due to
-code getting copied from one driver to the next.
-
-Cc: linux-ide@vger.kernel.org
-Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com>
-Signed-off-by: Tejun Heo <tj@kernel.org>
----
- drivers/ata/acard-ahci.c | 1 -
- drivers/ata/ahci.c | 1 -
- drivers/ata/ahci_platform.c | 1 -
- drivers/ata/ata_generic.c | 1 -
- drivers/ata/libahci.c | 1 -
- drivers/ata/pata_acpi.c | 1 -
- drivers/ata/pata_amd.c | 1 -
- drivers/ata/pata_artop.c | 1 -
- drivers/ata/pata_at91.c | 1 -
- drivers/ata/pata_atiixp.c | 1 -
- drivers/ata/pata_atp867x.c | 1 -
- drivers/ata/pata_cmd640.c | 1 -
- drivers/ata/pata_cmd64x.c | 1 -
- drivers/ata/pata_cs5520.c | 1 -
- drivers/ata/pata_cs5530.c | 1 -
- drivers/ata/pata_cs5535.c | 1 -
- drivers/ata/pata_cs5536.c | 1 -
- drivers/ata/pata_cypress.c | 1 -
- drivers/ata/pata_efar.c | 1 -
- drivers/ata/pata_ep93xx.c | 1 -
- drivers/ata/pata_hpt366.c | 1 -
- drivers/ata/pata_hpt37x.c | 1 -
- drivers/ata/pata_hpt3x2n.c | 1 -
- drivers/ata/pata_hpt3x3.c | 1 -
- drivers/ata/pata_imx.c | 1 -
- drivers/ata/pata_it8213.c | 1 -
- drivers/ata/pata_it821x.c | 1 -
- drivers/ata/pata_jmicron.c | 1 -
- drivers/ata/pata_marvell.c | 1 -
- drivers/ata/pata_mpiix.c | 1 -
- drivers/ata/pata_netcell.c | 1 -
- drivers/ata/pata_ninja32.c | 1 -
- drivers/ata/pata_ns87410.c | 1 -
- drivers/ata/pata_ns87415.c | 1 -
- drivers/ata/pata_oldpiix.c | 1 -
- drivers/ata/pata_opti.c | 1 -
- drivers/ata/pata_optidma.c | 1 -
- drivers/ata/pata_pcmcia.c | 1 -
- drivers/ata/pata_pdc2027x.c | 1 -
- drivers/ata/pata_pdc202xx_old.c | 1 -
- drivers/ata/pata_piccolo.c | 1 -
- drivers/ata/pata_platform.c | 1 -
- drivers/ata/pata_pxa.c | 1 -
- drivers/ata/pata_radisys.c | 1 -
- drivers/ata/pata_rdc.c | 1 -
- drivers/ata/pata_rz1000.c | 1 -
- drivers/ata/pata_sc1200.c | 1 -
- drivers/ata/pata_scc.c | 1 -
- drivers/ata/pata_sch.c | 1 -
- drivers/ata/pata_serverworks.c | 1 -
- drivers/ata/pata_sil680.c | 1 -
- drivers/ata/pata_sis.c | 1 -
- drivers/ata/pata_sl82c105.c | 1 -
- drivers/ata/pata_triflex.c | 1 -
- drivers/ata/pata_via.c | 1 -
- drivers/ata/pdc_adma.c | 1 -
- drivers/ata/sata_dwc_460ex.c | 1 -
- drivers/ata/sata_highbank.c | 1 -
- drivers/ata/sata_nv.c | 1 -
- drivers/ata/sata_promise.c | 1 -
- drivers/ata/sata_qstor.c | 1 -
- drivers/ata/sata_sil.c | 1 -
- drivers/ata/sata_sis.c | 1 -
- drivers/ata/sata_svw.c | 1 -
- drivers/ata/sata_sx4.c | 1 -
- drivers/ata/sata_uli.c | 1 -
- drivers/ata/sata_via.c | 1 -
- drivers/ata/sata_vsc.c | 1 -
- 68 files changed, 68 deletions(-)
-
---- a/drivers/ata/acard-ahci.c
-+++ b/drivers/ata/acard-ahci.c
-@@ -36,7 +36,6 @@
- #include <linux/kernel.h>
- #include <linux/module.h>
- #include <linux/pci.h>
--#include <linux/init.h>
- #include <linux/blkdev.h>
- #include <linux/delay.h>
- #include <linux/interrupt.h>
---- a/drivers/ata/ahci.c
-+++ b/drivers/ata/ahci.c
-@@ -35,7 +35,6 @@
- #include <linux/kernel.h>
- #include <linux/module.h>
- #include <linux/pci.h>
--#include <linux/init.h>
- #include <linux/blkdev.h>
- #include <linux/delay.h>
- #include <linux/interrupt.h>
---- a/drivers/ata/ahci_platform.c
-+++ b/drivers/ata/ahci_platform.c
-@@ -17,7 +17,6 @@
- #include <linux/gfp.h>
- #include <linux/module.h>
- #include <linux/pm.h>
--#include <linux/init.h>
- #include <linux/interrupt.h>
- #include <linux/device.h>
- #include <linux/platform_device.h>
---- a/drivers/ata/ata_generic.c
-+++ b/drivers/ata/ata_generic.c
-@@ -19,7 +19,6 @@
- #include <linux/kernel.h>
- #include <linux/module.h>
- #include <linux/pci.h>
--#include <linux/init.h>
- #include <linux/blkdev.h>
- #include <linux/delay.h>
- #include <scsi/scsi_host.h>
---- a/drivers/ata/libahci.c
-+++ b/drivers/ata/libahci.c
-@@ -35,7 +35,6 @@
- #include <linux/kernel.h>
- #include <linux/gfp.h>
- #include <linux/module.h>
--#include <linux/init.h>
- #include <linux/blkdev.h>
- #include <linux/delay.h>
- #include <linux/interrupt.h>
---- a/drivers/ata/pata_acpi.c
-+++ b/drivers/ata/pata_acpi.c
-@@ -7,7 +7,6 @@
- #include <linux/kernel.h>
- #include <linux/module.h>
- #include <linux/pci.h>
--#include <linux/init.h>
- #include <linux/blkdev.h>
- #include <linux/delay.h>
- #include <linux/device.h>
---- a/drivers/ata/pata_amd.c
-+++ b/drivers/ata/pata_amd.c
-@@ -17,7 +17,6 @@
- #include <linux/kernel.h>
- #include <linux/module.h>
- #include <linux/pci.h>
--#include <linux/init.h>
- #include <linux/blkdev.h>
- #include <linux/delay.h>
- #include <scsi/scsi_host.h>
---- a/drivers/ata/pata_artop.c
-+++ b/drivers/ata/pata_artop.c
-@@ -19,7 +19,6 @@
- #include <linux/kernel.h>
- #include <linux/module.h>
- #include <linux/pci.h>
--#include <linux/init.h>
- #include <linux/blkdev.h>
- #include <linux/delay.h>
- #include <linux/device.h>
---- a/drivers/ata/pata_at91.c
-+++ b/drivers/ata/pata_at91.c
-@@ -18,7 +18,6 @@
-
- #include <linux/kernel.h>
- #include <linux/module.h>
--#include <linux/init.h>
- #include <linux/blkdev.h>
- #include <linux/gfp.h>
- #include <scsi/scsi_host.h>
---- a/drivers/ata/pata_atiixp.c
-+++ b/drivers/ata/pata_atiixp.c
-@@ -15,7 +15,6 @@
- #include <linux/kernel.h>
- #include <linux/module.h>
- #include <linux/pci.h>
--#include <linux/init.h>
- #include <linux/blkdev.h>
- #include <linux/delay.h>
- #include <scsi/scsi_host.h>
---- a/drivers/ata/pata_atp867x.c
-+++ b/drivers/ata/pata_atp867x.c
-@@ -29,7 +29,6 @@
- #include <linux/kernel.h>
- #include <linux/module.h>
- #include <linux/pci.h>
--#include <linux/init.h>
- #include <linux/blkdev.h>
- #include <linux/delay.h>
- #include <linux/device.h>
---- a/drivers/ata/pata_cmd640.c
-+++ b/drivers/ata/pata_cmd640.c
-@@ -15,7 +15,6 @@
- #include <linux/kernel.h>
- #include <linux/module.h>
- #include <linux/pci.h>
--#include <linux/init.h>
- #include <linux/blkdev.h>
- #include <linux/delay.h>
- #include <linux/gfp.h>
---- a/drivers/ata/pata_cmd64x.c
-+++ b/drivers/ata/pata_cmd64x.c
-@@ -26,7 +26,6 @@
- #include <linux/kernel.h>
- #include <linux/module.h>
- #include <linux/pci.h>
--#include <linux/init.h>
- #include <linux/blkdev.h>
- #include <linux/delay.h>
- #include <scsi/scsi_host.h>
---- a/drivers/ata/pata_cs5520.c
-+++ b/drivers/ata/pata_cs5520.c
-@@ -34,7 +34,6 @@
- #include <linux/kernel.h>
- #include <linux/module.h>
- #include <linux/pci.h>
--#include <linux/init.h>
- #include <linux/blkdev.h>
- #include <linux/delay.h>
- #include <scsi/scsi_host.h>
---- a/drivers/ata/pata_cs5530.c
-+++ b/drivers/ata/pata_cs5530.c
-@@ -26,7 +26,6 @@
- #include <linux/kernel.h>
- #include <linux/module.h>
- #include <linux/pci.h>
--#include <linux/init.h>
- #include <linux/blkdev.h>
- #include <linux/delay.h>
- #include <scsi/scsi_host.h>
---- a/drivers/ata/pata_cs5535.c
-+++ b/drivers/ata/pata_cs5535.c
-@@ -31,7 +31,6 @@
- #include <linux/kernel.h>
- #include <linux/module.h>
- #include <linux/pci.h>
--#include <linux/init.h>
- #include <linux/blkdev.h>
- #include <linux/delay.h>
- #include <scsi/scsi_host.h>
---- a/drivers/ata/pata_cs5536.c
-+++ b/drivers/ata/pata_cs5536.c
-@@ -33,7 +33,6 @@
- #include <linux/kernel.h>
- #include <linux/module.h>
- #include <linux/pci.h>
--#include <linux/init.h>
- #include <linux/blkdev.h>
- #include <linux/delay.h>
- #include <linux/libata.h>
---- a/drivers/ata/pata_cypress.c
-+++ b/drivers/ata/pata_cypress.c
-@@ -11,7 +11,6 @@
- #include <linux/kernel.h>
- #include <linux/module.h>
- #include <linux/pci.h>
--#include <linux/init.h>
- #include <linux/blkdev.h>
- #include <linux/delay.h>
- #include <scsi/scsi_host.h>
---- a/drivers/ata/pata_efar.c
-+++ b/drivers/ata/pata_efar.c
-@@ -14,7 +14,6 @@
- #include <linux/kernel.h>
- #include <linux/module.h>
- #include <linux/pci.h>
--#include <linux/init.h>
- #include <linux/blkdev.h>
- #include <linux/delay.h>
- #include <linux/device.h>
---- a/drivers/ata/pata_ep93xx.c
-+++ b/drivers/ata/pata_ep93xx.c
-@@ -34,7 +34,6 @@
- #include <linux/err.h>
- #include <linux/kernel.h>
- #include <linux/module.h>
--#include <linux/init.h>
- #include <linux/blkdev.h>
- #include <scsi/scsi_host.h>
- #include <linux/ata.h>
---- a/drivers/ata/pata_hpt366.c
-+++ b/drivers/ata/pata_hpt366.c
-@@ -19,7 +19,6 @@
- #include <linux/kernel.h>
- #include <linux/module.h>
- #include <linux/pci.h>
--#include <linux/init.h>
- #include <linux/blkdev.h>
- #include <linux/delay.h>
- #include <scsi/scsi_host.h>
---- a/drivers/ata/pata_hpt37x.c
-+++ b/drivers/ata/pata_hpt37x.c
-@@ -19,7 +19,6 @@
- #include <linux/kernel.h>
- #include <linux/module.h>
- #include <linux/pci.h>
--#include <linux/init.h>
- #include <linux/blkdev.h>
- #include <linux/delay.h>
- #include <scsi/scsi_host.h>
---- a/drivers/ata/pata_hpt3x2n.c
-+++ b/drivers/ata/pata_hpt3x2n.c
-@@ -20,7 +20,6 @@
- #include <linux/kernel.h>
- #include <linux/module.h>
- #include <linux/pci.h>
--#include <linux/init.h>
- #include <linux/blkdev.h>
- #include <linux/delay.h>
- #include <scsi/scsi_host.h>
---- a/drivers/ata/pata_hpt3x3.c
-+++ b/drivers/ata/pata_hpt3x3.c
-@@ -16,7 +16,6 @@
- #include <linux/kernel.h>
- #include <linux/module.h>
- #include <linux/pci.h>
--#include <linux/init.h>
- #include <linux/blkdev.h>
- #include <linux/delay.h>
- #include <scsi/scsi_host.h>
---- a/drivers/ata/pata_imx.c
-+++ b/drivers/ata/pata_imx.c
-@@ -15,7 +15,6 @@
- */
- #include <linux/kernel.h>
- #include <linux/module.h>
--#include <linux/init.h>
- #include <linux/blkdev.h>
- #include <scsi/scsi_host.h>
- #include <linux/ata.h>
---- a/drivers/ata/pata_it8213.c
-+++ b/drivers/ata/pata_it8213.c
-@@ -10,7 +10,6 @@
- #include <linux/kernel.h>
- #include <linux/module.h>
- #include <linux/pci.h>
--#include <linux/init.h>
- #include <linux/blkdev.h>
- #include <linux/delay.h>
- #include <linux/device.h>
---- a/drivers/ata/pata_it821x.c
-+++ b/drivers/ata/pata_it821x.c
-@@ -72,7 +72,6 @@
- #include <linux/kernel.h>
- #include <linux/module.h>
- #include <linux/pci.h>
--#include <linux/init.h>
- #include <linux/blkdev.h>
- #include <linux/delay.h>
- #include <linux/slab.h>
---- a/drivers/ata/pata_jmicron.c
-+++ b/drivers/ata/pata_jmicron.c
-@@ -10,7 +10,6 @@
- #include <linux/kernel.h>
- #include <linux/module.h>
- #include <linux/pci.h>
--#include <linux/init.h>
- #include <linux/blkdev.h>
- #include <linux/delay.h>
- #include <linux/device.h>
---- a/drivers/ata/pata_marvell.c
-+++ b/drivers/ata/pata_marvell.c
-@@ -11,7 +11,6 @@
- #include <linux/kernel.h>
- #include <linux/module.h>
- #include <linux/pci.h>
--#include <linux/init.h>
- #include <linux/blkdev.h>
- #include <linux/delay.h>
- #include <linux/device.h>
---- a/drivers/ata/pata_mpiix.c
-+++ b/drivers/ata/pata_mpiix.c
-@@ -28,7 +28,6 @@
- #include <linux/kernel.h>
- #include <linux/module.h>
- #include <linux/pci.h>
--#include <linux/init.h>
- #include <linux/blkdev.h>
- #include <linux/delay.h>
- #include <scsi/scsi_host.h>
---- a/drivers/ata/pata_netcell.c
-+++ b/drivers/ata/pata_netcell.c
-@@ -7,7 +7,6 @@
- #include <linux/kernel.h>
- #include <linux/module.h>
- #include <linux/pci.h>
--#include <linux/init.h>
- #include <linux/blkdev.h>
- #include <linux/delay.h>
- #include <linux/device.h>
---- a/drivers/ata/pata_ninja32.c
-+++ b/drivers/ata/pata_ninja32.c
-@@ -37,7 +37,6 @@
- #include <linux/kernel.h>
- #include <linux/module.h>
- #include <linux/pci.h>
--#include <linux/init.h>
- #include <linux/blkdev.h>
- #include <linux/delay.h>
- #include <scsi/scsi_host.h>
---- a/drivers/ata/pata_ns87410.c
-+++ b/drivers/ata/pata_ns87410.c
-@@ -20,7 +20,6 @@
- #include <linux/kernel.h>
- #include <linux/module.h>
- #include <linux/pci.h>
--#include <linux/init.h>
- #include <linux/blkdev.h>
- #include <linux/delay.h>
- #include <scsi/scsi_host.h>
---- a/drivers/ata/pata_ns87415.c
-+++ b/drivers/ata/pata_ns87415.c
-@@ -25,7 +25,6 @@
- #include <linux/kernel.h>
- #include <linux/module.h>
- #include <linux/pci.h>
--#include <linux/init.h>
- #include <linux/blkdev.h>
- #include <linux/delay.h>
- #include <linux/device.h>
---- a/drivers/ata/pata_oldpiix.c
-+++ b/drivers/ata/pata_oldpiix.c
-@@ -16,7 +16,6 @@
- #include <linux/kernel.h>
- #include <linux/module.h>
- #include <linux/pci.h>
--#include <linux/init.h>
- #include <linux/blkdev.h>
- #include <linux/delay.h>
- #include <linux/device.h>
---- a/drivers/ata/pata_opti.c
-+++ b/drivers/ata/pata_opti.c
-@@ -26,7 +26,6 @@
- #include <linux/kernel.h>
- #include <linux/module.h>
- #include <linux/pci.h>
--#include <linux/init.h>
- #include <linux/blkdev.h>
- #include <linux/delay.h>
- #include <scsi/scsi_host.h>
---- a/drivers/ata/pata_optidma.c
-+++ b/drivers/ata/pata_optidma.c
-@@ -25,7 +25,6 @@
- #include <linux/kernel.h>
- #include <linux/module.h>
- #include <linux/pci.h>
--#include <linux/init.h>
- #include <linux/blkdev.h>
- #include <linux/delay.h>
- #include <scsi/scsi_host.h>
---- a/drivers/ata/pata_pcmcia.c
-+++ b/drivers/ata/pata_pcmcia.c
-@@ -26,7 +26,6 @@
-
- #include <linux/kernel.h>
- #include <linux/module.h>
--#include <linux/init.h>
- #include <linux/blkdev.h>
- #include <linux/delay.h>
- #include <linux/slab.h>
---- a/drivers/ata/pata_pdc2027x.c
-+++ b/drivers/ata/pata_pdc2027x.c
-@@ -25,7 +25,6 @@
- #include <linux/kernel.h>
- #include <linux/module.h>
- #include <linux/pci.h>
--#include <linux/init.h>
- #include <linux/blkdev.h>
- #include <linux/delay.h>
- #include <linux/device.h>
---- a/drivers/ata/pata_pdc202xx_old.c
-+++ b/drivers/ata/pata_pdc202xx_old.c
-@@ -15,7 +15,6 @@
- #include <linux/kernel.h>
- #include <linux/module.h>
- #include <linux/pci.h>
--#include <linux/init.h>
- #include <linux/blkdev.h>
- #include <linux/delay.h>
- #include <scsi/scsi_host.h>
---- a/drivers/ata/pata_piccolo.c
-+++ b/drivers/ata/pata_piccolo.c
-@@ -18,7 +18,6 @@
- #include <linux/kernel.h>
- #include <linux/module.h>
- #include <linux/pci.h>
--#include <linux/init.h>
- #include <linux/blkdev.h>
- #include <linux/delay.h>
- #include <scsi/scsi_host.h>
---- a/drivers/ata/pata_platform.c
-+++ b/drivers/ata/pata_platform.c
-@@ -13,7 +13,6 @@
- */
- #include <linux/kernel.h>
- #include <linux/module.h>
--#include <linux/init.h>
- #include <linux/blkdev.h>
- #include <scsi/scsi_host.h>
- #include <linux/ata.h>
---- a/drivers/ata/pata_pxa.c
-+++ b/drivers/ata/pata_pxa.c
-@@ -20,7 +20,6 @@
-
- #include <linux/kernel.h>
- #include <linux/module.h>
--#include <linux/init.h>
- #include <linux/blkdev.h>
- #include <linux/ata.h>
- #include <linux/libata.h>
---- a/drivers/ata/pata_radisys.c
-+++ b/drivers/ata/pata_radisys.c
-@@ -15,7 +15,6 @@
- #include <linux/kernel.h>
- #include <linux/module.h>
- #include <linux/pci.h>
--#include <linux/init.h>
- #include <linux/blkdev.h>
- #include <linux/delay.h>
- #include <linux/device.h>
---- a/drivers/ata/pata_rdc.c
-+++ b/drivers/ata/pata_rdc.c
-@@ -24,7 +24,6 @@
- #include <linux/kernel.h>
- #include <linux/module.h>
- #include <linux/pci.h>
--#include <linux/init.h>
- #include <linux/blkdev.h>
- #include <linux/delay.h>
- #include <linux/device.h>
---- a/drivers/ata/pata_rz1000.c
-+++ b/drivers/ata/pata_rz1000.c
-@@ -14,7 +14,6 @@
- #include <linux/kernel.h>
- #include <linux/module.h>
- #include <linux/pci.h>
--#include <linux/init.h>
- #include <linux/blkdev.h>
- #include <linux/delay.h>
- #include <scsi/scsi_host.h>
---- a/drivers/ata/pata_sc1200.c
-+++ b/drivers/ata/pata_sc1200.c
-@@ -32,7 +32,6 @@
- #include <linux/kernel.h>
- #include <linux/module.h>
- #include <linux/pci.h>
--#include <linux/init.h>
- #include <linux/blkdev.h>
- #include <linux/delay.h>
- #include <scsi/scsi_host.h>
---- a/drivers/ata/pata_scc.c
-+++ b/drivers/ata/pata_scc.c
-@@ -35,7 +35,6 @@
- #include <linux/kernel.h>
- #include <linux/module.h>
- #include <linux/pci.h>
--#include <linux/init.h>
- #include <linux/blkdev.h>
- #include <linux/delay.h>
- #include <linux/device.h>
---- a/drivers/ata/pata_sch.c
-+++ b/drivers/ata/pata_sch.c
-@@ -27,7 +27,6 @@
- #include <linux/kernel.h>
- #include <linux/module.h>
- #include <linux/pci.h>
--#include <linux/init.h>
- #include <linux/blkdev.h>
- #include <linux/delay.h>
- #include <linux/device.h>
---- a/drivers/ata/pata_serverworks.c
-+++ b/drivers/ata/pata_serverworks.c
-@@ -34,7 +34,6 @@
- #include <linux/kernel.h>
- #include <linux/module.h>
- #include <linux/pci.h>
--#include <linux/init.h>
- #include <linux/blkdev.h>
- #include <linux/delay.h>
- #include <scsi/scsi_host.h>
---- a/drivers/ata/pata_sil680.c
-+++ b/drivers/ata/pata_sil680.c
-@@ -25,7 +25,6 @@
- #include <linux/kernel.h>
- #include <linux/module.h>
- #include <linux/pci.h>
--#include <linux/init.h>
- #include <linux/blkdev.h>
- #include <linux/delay.h>
- #include <scsi/scsi_host.h>
---- a/drivers/ata/pata_sis.c
-+++ b/drivers/ata/pata_sis.c
-@@ -26,7 +26,6 @@
- #include <linux/kernel.h>
- #include <linux/module.h>
- #include <linux/pci.h>
--#include <linux/init.h>
- #include <linux/blkdev.h>
- #include <linux/delay.h>
- #include <linux/device.h>
---- a/drivers/ata/pata_sl82c105.c
-+++ b/drivers/ata/pata_sl82c105.c
-@@ -19,7 +19,6 @@
- #include <linux/kernel.h>
- #include <linux/module.h>
- #include <linux/pci.h>
--#include <linux/init.h>
- #include <linux/blkdev.h>
- #include <linux/delay.h>
- #include <scsi/scsi_host.h>
---- a/drivers/ata/pata_triflex.c
-+++ b/drivers/ata/pata_triflex.c
-@@ -36,7 +36,6 @@
- #include <linux/kernel.h>
- #include <linux/module.h>
- #include <linux/pci.h>
--#include <linux/init.h>
- #include <linux/blkdev.h>
- #include <linux/delay.h>
- #include <scsi/scsi_host.h>
---- a/drivers/ata/pata_via.c
-+++ b/drivers/ata/pata_via.c
-@@ -55,7 +55,6 @@
- #include <linux/kernel.h>
- #include <linux/module.h>
- #include <linux/pci.h>
--#include <linux/init.h>
- #include <linux/blkdev.h>
- #include <linux/delay.h>
- #include <linux/gfp.h>
---- a/drivers/ata/pdc_adma.c
-+++ b/drivers/ata/pdc_adma.c
-@@ -36,7 +36,6 @@
- #include <linux/module.h>
- #include <linux/gfp.h>
- #include <linux/pci.h>
--#include <linux/init.h>
- #include <linux/blkdev.h>
- #include <linux/delay.h>
- #include <linux/interrupt.h>
---- a/drivers/ata/sata_dwc_460ex.c
-+++ b/drivers/ata/sata_dwc_460ex.c
-@@ -29,7 +29,6 @@
-
- #include <linux/kernel.h>
- #include <linux/module.h>
--#include <linux/init.h>
- #include <linux/device.h>
- #include <linux/of_address.h>
- #include <linux/of_irq.h>
---- a/drivers/ata/sata_highbank.c
-+++ b/drivers/ata/sata_highbank.c
-@@ -19,7 +19,6 @@
- #include <linux/kernel.h>
- #include <linux/gfp.h>
- #include <linux/module.h>
--#include <linux/init.h>
- #include <linux/types.h>
- #include <linux/err.h>
- #include <linux/io.h>
---- a/drivers/ata/sata_nv.c
-+++ b/drivers/ata/sata_nv.c
-@@ -40,7 +40,6 @@
- #include <linux/module.h>
- #include <linux/gfp.h>
- #include <linux/pci.h>
--#include <linux/init.h>
- #include <linux/blkdev.h>
- #include <linux/delay.h>
- #include <linux/interrupt.h>
---- a/drivers/ata/sata_promise.c
-+++ b/drivers/ata/sata_promise.c
-@@ -35,7 +35,6 @@
- #include <linux/module.h>
- #include <linux/gfp.h>
- #include <linux/pci.h>
--#include <linux/init.h>
- #include <linux/blkdev.h>
- #include <linux/delay.h>
- #include <linux/interrupt.h>
---- a/drivers/ata/sata_qstor.c
-+++ b/drivers/ata/sata_qstor.c
-@@ -31,7 +31,6 @@
- #include <linux/module.h>
- #include <linux/gfp.h>
- #include <linux/pci.h>
--#include <linux/init.h>
- #include <linux/blkdev.h>
- #include <linux/delay.h>
- #include <linux/interrupt.h>
---- a/drivers/ata/sata_sil.c
-+++ b/drivers/ata/sata_sil.c
-@@ -37,7 +37,6 @@
- #include <linux/kernel.h>
- #include <linux/module.h>
- #include <linux/pci.h>
--#include <linux/init.h>
- #include <linux/blkdev.h>
- #include <linux/delay.h>
- #include <linux/interrupt.h>
---- a/drivers/ata/sata_sis.c
-+++ b/drivers/ata/sata_sis.c
-@@ -33,7 +33,6 @@
- #include <linux/kernel.h>
- #include <linux/module.h>
- #include <linux/pci.h>
--#include <linux/init.h>
- #include <linux/blkdev.h>
- #include <linux/delay.h>
- #include <linux/interrupt.h>
---- a/drivers/ata/sata_svw.c
-+++ b/drivers/ata/sata_svw.c
-@@ -39,7 +39,6 @@
- #include <linux/kernel.h>
- #include <linux/module.h>
- #include <linux/pci.h>
--#include <linux/init.h>
- #include <linux/blkdev.h>
- #include <linux/delay.h>
- #include <linux/interrupt.h>
---- a/drivers/ata/sata_sx4.c
-+++ b/drivers/ata/sata_sx4.c
-@@ -82,7 +82,6 @@
- #include <linux/module.h>
- #include <linux/pci.h>
- #include <linux/slab.h>
--#include <linux/init.h>
- #include <linux/blkdev.h>
- #include <linux/delay.h>
- #include <linux/interrupt.h>
---- a/drivers/ata/sata_uli.c
-+++ b/drivers/ata/sata_uli.c
-@@ -28,7 +28,6 @@
- #include <linux/module.h>
- #include <linux/gfp.h>
- #include <linux/pci.h>
--#include <linux/init.h>
- #include <linux/blkdev.h>
- #include <linux/delay.h>
- #include <linux/interrupt.h>
---- a/drivers/ata/sata_via.c
-+++ b/drivers/ata/sata_via.c
-@@ -36,7 +36,6 @@
- #include <linux/kernel.h>
- #include <linux/module.h>
- #include <linux/pci.h>
--#include <linux/init.h>
- #include <linux/blkdev.h>
- #include <linux/delay.h>
- #include <linux/device.h>
---- a/drivers/ata/sata_vsc.c
-+++ b/drivers/ata/sata_vsc.c
-@@ -37,7 +37,6 @@
- #include <linux/kernel.h>
- #include <linux/module.h>
- #include <linux/pci.h>
--#include <linux/init.h>
- #include <linux/blkdev.h>
- #include <linux/delay.h>
- #include <linux/interrupt.h>
diff --git a/target/linux/ipq806x/patches/0114-ahci-platform-Library-ise-ahci_probe-functionality.patch b/target/linux/ipq806x/patches/0114-ahci-platform-Library-ise-ahci_probe-functionality.patch
deleted file mode 100644
index 3b638d4..0000000
--- a/target/linux/ipq806x/patches/0114-ahci-platform-Library-ise-ahci_probe-functionality.patch
+++ /dev/null
@@ -1,334 +0,0 @@
-From 8be4987340a101253fb871556894a002f1afb51f Mon Sep 17 00:00:00 2001
-From: Hans de Goede <hdegoede@redhat.com>
-Date: Sat, 22 Feb 2014 16:53:34 +0100
-Subject: [PATCH 114/182] ahci-platform: "Library-ise" ahci_probe
- functionality
-
-ahci_probe consists of 3 steps:
-1) Get resources (get mmio, clks, regulator)
-2) Enable resources, handled by ahci_platform_enable_resouces
-3) The more or less standard ahci-host controller init sequence
-
-This commit refactors step 1 and 3 into separate functions, so the platform
-drivers for AHCI implementations which need a specific order in step 2,
-and / or need to do some custom register poking at some time, can re-use
-ahci-platform.c code without needing to copy and paste it.
-
-Note that ahci_platform_init_host's prototype takes the 3 non function
-members of ahci_platform_data as arguments, the idea is that drivers using
-the new exported utility functions will not use ahci_platform_data at all,
-and hopefully in the future ahci_platform_data can go away entirely.
-
-tj: Minor comment formatting updates.
-
-Signed-off-by: Hans de Goede <hdegoede@redhat.com>
-Signed-off-by: Tejun Heo <tj@kernel.org>
----
- drivers/ata/ahci_platform.c | 188 +++++++++++++++++++++++++++--------------
- include/linux/ahci_platform.h | 14 +++
- 2 files changed, 137 insertions(+), 65 deletions(-)
-
---- a/drivers/ata/ahci_platform.c
-+++ b/drivers/ata/ahci_platform.c
-@@ -188,64 +188,60 @@ void ahci_platform_disable_resources(str
- }
- EXPORT_SYMBOL_GPL(ahci_platform_disable_resources);
-
--static void ahci_put_clks(struct ahci_host_priv *hpriv)
-+static void ahci_platform_put_resources(struct device *dev, void *res)
- {
-+ struct ahci_host_priv *hpriv = res;
- int c;
-
- for (c = 0; c < AHCI_MAX_CLKS && hpriv->clks[c]; c++)
- clk_put(hpriv->clks[c]);
- }
-
--static int ahci_probe(struct platform_device *pdev)
-+/**
-+ * ahci_platform_get_resources - Get platform resources
-+ * @pdev: platform device to get resources for
-+ *
-+ * This function allocates an ahci_host_priv struct, and gets the following
-+ * resources, storing a reference to them inside the returned struct:
-+ *
-+ * 1) mmio registers (IORESOURCE_MEM 0, mandatory)
-+ * 2) regulator for controlling the targets power (optional)
-+ * 3) 0 - AHCI_MAX_CLKS clocks, as specified in the devs devicetree node,
-+ * or for non devicetree enabled platforms a single clock
-+ *
-+ * RETURNS:
-+ * The allocated ahci_host_priv on success, otherwise an ERR_PTR value
-+ */
-+struct ahci_host_priv *ahci_platform_get_resources(
-+ struct platform_device *pdev)
- {
- struct device *dev = &pdev->dev;
-- struct ahci_platform_data *pdata = dev_get_platdata(dev);
-- const struct platform_device_id *id = platform_get_device_id(pdev);
-- struct ata_port_info pi = ahci_port_info[id ? id->driver_data : 0];
-- const struct ata_port_info *ppi[] = { &pi, NULL };
- struct ahci_host_priv *hpriv;
-- struct ata_host *host;
-- struct resource *mem;
- struct clk *clk;
-- int irq;
-- int n_ports;
-- int i;
-- int rc;
-+ int i, rc = -ENOMEM;
-
-- mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-- if (!mem) {
-- dev_err(dev, "no mmio space\n");
-- return -EINVAL;
-- }
-+ if (!devres_open_group(dev, NULL, GFP_KERNEL))
-+ return ERR_PTR(-ENOMEM);
-
-- irq = platform_get_irq(pdev, 0);
-- if (irq <= 0) {
-- dev_err(dev, "no irq\n");
-- return -EINVAL;
-- }
--
-- if (pdata && pdata->ata_port_info)
-- pi = *pdata->ata_port_info;
-+ hpriv = devres_alloc(ahci_platform_put_resources, sizeof(*hpriv),
-+ GFP_KERNEL);
-+ if (!hpriv)
-+ goto err_out;
-
-- hpriv = devm_kzalloc(dev, sizeof(*hpriv), GFP_KERNEL);
-- if (!hpriv) {
-- dev_err(dev, "can't alloc ahci_host_priv\n");
-- return -ENOMEM;
-- }
-+ devres_add(dev, hpriv);
-
-- hpriv->flags |= (unsigned long)pi.private_data;
--
-- hpriv->mmio = devm_ioremap(dev, mem->start, resource_size(mem));
-+ hpriv->mmio = devm_ioremap_resource(dev,
-+ platform_get_resource(pdev, IORESOURCE_MEM, 0));
- if (!hpriv->mmio) {
-- dev_err(dev, "can't map %pR\n", mem);
-- return -ENOMEM;
-+ dev_err(dev, "no mmio space\n");
-+ goto err_out;
- }
-
- hpriv->target_pwr = devm_regulator_get_optional(dev, "target");
- if (IS_ERR(hpriv->target_pwr)) {
- rc = PTR_ERR(hpriv->target_pwr);
- if (rc == -EPROBE_DEFER)
-- return -EPROBE_DEFER;
-+ goto err_out;
- hpriv->target_pwr = NULL;
- }
-
-@@ -264,33 +260,59 @@ static int ahci_probe(struct platform_de
- if (IS_ERR(clk)) {
- rc = PTR_ERR(clk);
- if (rc == -EPROBE_DEFER)
-- goto free_clk;
-+ goto err_out;
- break;
- }
- hpriv->clks[i] = clk;
- }
-
-- rc = ahci_platform_enable_resources(hpriv);
-- if (rc)
-- goto free_clk;
-+ devres_remove_group(dev, NULL);
-+ return hpriv;
-
-- /*
-- * Some platforms might need to prepare for mmio region access,
-- * which could be done in the following init call. So, the mmio
-- * region shouldn't be accessed before init (if provided) has
-- * returned successfully.
-- */
-- if (pdata && pdata->init) {
-- rc = pdata->init(dev, hpriv->mmio);
-- if (rc)
-- goto disable_resources;
-- }
-+err_out:
-+ devres_release_group(dev, NULL);
-+ return ERR_PTR(rc);
-+}
-+EXPORT_SYMBOL_GPL(ahci_platform_get_resources);
-+
-+/**
-+ * ahci_platform_init_host - Bring up an ahci-platform host
-+ * @pdev: platform device pointer for the host
-+ * @hpriv: ahci-host private data for the host
-+ * @pi_template: template for the ata_port_info to use
-+ * @force_port_map: param passed to ahci_save_initial_config
-+ * @mask_port_map: param passed to ahci_save_initial_config
-+ *
-+ * This function does all the usual steps needed to bring up an
-+ * ahci-platform host, note any necessary resources (ie clks, phy, etc.)
-+ * must be initialized / enabled before calling this.
-+ *
-+ * RETURNS:
-+ * 0 on success otherwise a negative error code
-+ */
-+int ahci_platform_init_host(struct platform_device *pdev,
-+ struct ahci_host_priv *hpriv,
-+ const struct ata_port_info *pi_template,
-+ unsigned int force_port_map,
-+ unsigned int mask_port_map)
-+{
-+ struct device *dev = &pdev->dev;
-+ struct ata_port_info pi = *pi_template;
-+ const struct ata_port_info *ppi[] = { &pi, NULL };
-+ struct ata_host *host;
-+ int i, irq, n_ports, rc;
-
-- ahci_save_initial_config(dev, hpriv,
-- pdata ? pdata->force_port_map : 0,
-- pdata ? pdata->mask_port_map : 0);
-+ irq = platform_get_irq(pdev, 0);
-+ if (irq <= 0) {
-+ dev_err(dev, "no irq\n");
-+ return -EINVAL;
-+ }
-
- /* prepare host */
-+ hpriv->flags |= (unsigned long)pi.private_data;
-+
-+ ahci_save_initial_config(dev, hpriv, force_port_map, mask_port_map);
-+
- if (hpriv->cap & HOST_CAP_NCQ)
- pi.flags |= ATA_FLAG_NCQ;
-
-@@ -307,10 +329,8 @@ static int ahci_probe(struct platform_de
- n_ports = max(ahci_nr_ports(hpriv->cap), fls(hpriv->port_map));
-
- host = ata_host_alloc_pinfo(dev, ppi, n_ports);
-- if (!host) {
-- rc = -ENOMEM;
-- goto pdata_exit;
-- }
-+ if (!host)
-+ return -ENOMEM;
-
- host->private_data = hpriv;
-
-@@ -325,7 +345,8 @@ static int ahci_probe(struct platform_de
- for (i = 0; i < host->n_ports; i++) {
- struct ata_port *ap = host->ports[i];
-
-- ata_port_desc(ap, "mmio %pR", mem);
-+ ata_port_desc(ap, "mmio %pR",
-+ platform_get_resource(pdev, IORESOURCE_MEM, 0));
- ata_port_desc(ap, "port 0x%x", 0x100 + ap->port_no * 0x80);
-
- /* set enclosure management message type */
-@@ -339,13 +360,53 @@ static int ahci_probe(struct platform_de
-
- rc = ahci_reset_controller(host);
- if (rc)
-- goto pdata_exit;
-+ return rc;
-
- ahci_init_controller(host);
- ahci_print_info(host, "platform");
-
-- rc = ata_host_activate(host, irq, ahci_interrupt, IRQF_SHARED,
-- &ahci_platform_sht);
-+ return ata_host_activate(host, irq, ahci_interrupt, IRQF_SHARED,
-+ &ahci_platform_sht);
-+}
-+EXPORT_SYMBOL_GPL(ahci_platform_init_host);
-+
-+static int ahci_probe(struct platform_device *pdev)
-+{
-+ struct device *dev = &pdev->dev;
-+ struct ahci_platform_data *pdata = dev_get_platdata(dev);
-+ const struct platform_device_id *id = platform_get_device_id(pdev);
-+ const struct ata_port_info *pi_template;
-+ struct ahci_host_priv *hpriv;
-+ int rc;
-+
-+ hpriv = ahci_platform_get_resources(pdev);
-+ if (IS_ERR(hpriv))
-+ return PTR_ERR(hpriv);
-+
-+ rc = ahci_platform_enable_resources(hpriv);
-+ if (rc)
-+ return rc;
-+
-+ /*
-+ * Some platforms might need to prepare for mmio region access,
-+ * which could be done in the following init call. So, the mmio
-+ * region shouldn't be accessed before init (if provided) has
-+ * returned successfully.
-+ */
-+ if (pdata && pdata->init) {
-+ rc = pdata->init(dev, hpriv->mmio);
-+ if (rc)
-+ goto disable_resources;
-+ }
-+
-+ if (pdata && pdata->ata_port_info)
-+ pi_template = pdata->ata_port_info;
-+ else
-+ pi_template = &ahci_port_info[id ? id->driver_data : 0];
-+
-+ rc = ahci_platform_init_host(pdev, hpriv, pi_template,
-+ pdata ? pdata->force_port_map : 0,
-+ pdata ? pdata->mask_port_map : 0);
- if (rc)
- goto pdata_exit;
-
-@@ -355,8 +416,6 @@ pdata_exit:
- pdata->exit(dev);
- disable_resources:
- ahci_platform_disable_resources(hpriv);
--free_clk:
-- ahci_put_clks(hpriv);
- return rc;
- }
-
-@@ -370,7 +429,6 @@ static void ahci_host_stop(struct ata_ho
- pdata->exit(dev);
-
- ahci_platform_disable_resources(hpriv);
-- ahci_put_clks(hpriv);
- }
-
- #ifdef CONFIG_PM_SLEEP
---- a/include/linux/ahci_platform.h
-+++ b/include/linux/ahci_platform.h
-@@ -20,7 +20,14 @@
- struct device;
- struct ata_port_info;
- struct ahci_host_priv;
-+struct platform_device;
-
-+/*
-+ * Note ahci_platform_data is deprecated, it is only kept around for use
-+ * by the old da850 and spear13xx ahci code.
-+ * New drivers should instead declare their own platform_driver struct, and
-+ * use ahci_platform* functions in their own probe, suspend and resume methods.
-+ */
- struct ahci_platform_data {
- int (*init)(struct device *dev, void __iomem *addr);
- void (*exit)(struct device *dev);
-@@ -35,5 +42,12 @@ int ahci_platform_enable_clks(struct ahc
- void ahci_platform_disable_clks(struct ahci_host_priv *hpriv);
- int ahci_platform_enable_resources(struct ahci_host_priv *hpriv);
- void ahci_platform_disable_resources(struct ahci_host_priv *hpriv);
-+struct ahci_host_priv *ahci_platform_get_resources(
-+ struct platform_device *pdev);
-+int ahci_platform_init_host(struct platform_device *pdev,
-+ struct ahci_host_priv *hpriv,
-+ const struct ata_port_info *pi_template,
-+ unsigned int force_port_map,
-+ unsigned int mask_port_map);
-
- #endif /* _AHCI_PLATFORM_H */
diff --git a/target/linux/ipq806x/patches/0115-ahci-platform-Library-ise-suspend-resume-functionali.patch b/target/linux/ipq806x/patches/0115-ahci-platform-Library-ise-suspend-resume-functionali.patch
deleted file mode 100644
index 8cc7d7a..0000000
--- a/target/linux/ipq806x/patches/0115-ahci-platform-Library-ise-suspend-resume-functionali.patch
+++ /dev/null
@@ -1,173 +0,0 @@
-From 8121ed9c7ea2d56f5e0a98c2db396214f85d7485 Mon Sep 17 00:00:00 2001
-From: Hans de Goede <hdegoede@redhat.com>
-Date: Sat, 22 Feb 2014 16:53:35 +0100
-Subject: [PATCH 115/182] ahci-platform: "Library-ise" suspend / resume
- functionality
-
-Split suspend / resume code into host suspend / resume functionality and
-resource enable / disabling phases, and export the new suspend_ / resume_host
-functions.
-
-tj: Minor comment formatting updates.
-
-Signed-off-by: Hans de Goede <hdegoede@redhat.com>
-Signed-off-by: Tejun Heo <tj@kernel.org>
----
- drivers/ata/ahci_platform.c | 97 ++++++++++++++++++++++++++++++++++-------
- include/linux/ahci_platform.h | 5 +++
- 2 files changed, 87 insertions(+), 15 deletions(-)
-
---- a/drivers/ata/ahci_platform.c
-+++ b/drivers/ata/ahci_platform.c
-@@ -432,14 +432,23 @@ static void ahci_host_stop(struct ata_ho
- }
-
- #ifdef CONFIG_PM_SLEEP
--static int ahci_suspend(struct device *dev)
-+/**
-+ * ahci_platform_suspend_host - Suspend an ahci-platform host
-+ * @dev: device pointer for the host
-+ *
-+ * This function does all the usual steps needed to suspend an
-+ * ahci-platform host, note any necessary resources (ie clks, phy, etc.)
-+ * must be disabled after calling this.
-+ *
-+ * RETURNS:
-+ * 0 on success otherwise a negative error code
-+ */
-+int ahci_platform_suspend_host(struct device *dev)
- {
-- struct ahci_platform_data *pdata = dev_get_platdata(dev);
- struct ata_host *host = dev_get_drvdata(dev);
- struct ahci_host_priv *hpriv = host->private_data;
- void __iomem *mmio = hpriv->mmio;
- u32 ctl;
-- int rc;
-
- if (hpriv->flags & AHCI_HFLAG_NO_SUSPEND) {
- dev_err(dev, "firmware update required for suspend/resume\n");
-@@ -456,7 +465,58 @@ static int ahci_suspend(struct device *d
- writel(ctl, mmio + HOST_CTL);
- readl(mmio + HOST_CTL); /* flush */
-
-- rc = ata_host_suspend(host, PMSG_SUSPEND);
-+ return ata_host_suspend(host, PMSG_SUSPEND);
-+}
-+EXPORT_SYMBOL_GPL(ahci_platform_suspend_host);
-+
-+/**
-+ * ahci_platform_resume_host - Resume an ahci-platform host
-+ * @dev: device pointer for the host
-+ *
-+ * This function does all the usual steps needed to resume an ahci-platform
-+ * host, note any necessary resources (ie clks, phy, etc.) must be
-+ * initialized / enabled before calling this.
-+ *
-+ * RETURNS:
-+ * 0 on success otherwise a negative error code
-+ */
-+int ahci_platform_resume_host(struct device *dev)
-+{
-+ struct ata_host *host = dev_get_drvdata(dev);
-+ int rc;
-+
-+ if (dev->power.power_state.event == PM_EVENT_SUSPEND) {
-+ rc = ahci_reset_controller(host);
-+ if (rc)
-+ return rc;
-+
-+ ahci_init_controller(host);
-+ }
-+
-+ ata_host_resume(host);
-+
-+ return 0;
-+}
-+EXPORT_SYMBOL_GPL(ahci_platform_resume_host);
-+
-+/**
-+ * ahci_platform_suspend - Suspend an ahci-platform device
-+ * @dev: the platform device to suspend
-+ *
-+ * This function suspends the host associated with the device, followed by
-+ * disabling all the resources of the device.
-+ *
-+ * RETURNS:
-+ * 0 on success otherwise a negative error code
-+ */
-+int ahci_platform_suspend(struct device *dev)
-+{
-+ struct ahci_platform_data *pdata = dev_get_platdata(dev);
-+ struct ata_host *host = dev_get_drvdata(dev);
-+ struct ahci_host_priv *hpriv = host->private_data;
-+ int rc;
-+
-+ rc = ahci_platform_suspend_host(dev);
- if (rc)
- return rc;
-
-@@ -467,8 +527,19 @@ static int ahci_suspend(struct device *d
-
- return 0;
- }
-+EXPORT_SYMBOL_GPL(ahci_platform_suspend);
-
--static int ahci_resume(struct device *dev)
-+/**
-+ * ahci_platform_resume - Resume an ahci-platform device
-+ * @dev: the platform device to resume
-+ *
-+ * This function enables all the resources of the device followed by
-+ * resuming the host associated with the device.
-+ *
-+ * RETURNS:
-+ * 0 on success otherwise a negative error code
-+ */
-+int ahci_platform_resume(struct device *dev)
- {
- struct ahci_platform_data *pdata = dev_get_platdata(dev);
- struct ata_host *host = dev_get_drvdata(dev);
-@@ -485,15 +556,9 @@ static int ahci_resume(struct device *de
- goto disable_resources;
- }
-
-- if (dev->power.power_state.event == PM_EVENT_SUSPEND) {
-- rc = ahci_reset_controller(host);
-- if (rc)
-- goto disable_resources;
--
-- ahci_init_controller(host);
-- }
--
-- ata_host_resume(host);
-+ rc = ahci_platform_resume_host(dev);
-+ if (rc)
-+ goto disable_resources;
-
- return 0;
-
-@@ -502,9 +567,11 @@ disable_resources:
-
- return rc;
- }
-+EXPORT_SYMBOL_GPL(ahci_platform_resume);
- #endif
-
--static SIMPLE_DEV_PM_OPS(ahci_pm_ops, ahci_suspend, ahci_resume);
-+static SIMPLE_DEV_PM_OPS(ahci_pm_ops, ahci_platform_suspend,
-+ ahci_platform_resume);
-
- static const struct of_device_id ahci_of_match[] = {
- { .compatible = "snps,spear-ahci", },
---- a/include/linux/ahci_platform.h
-+++ b/include/linux/ahci_platform.h
-@@ -50,4 +50,9 @@ int ahci_platform_init_host(struct platf
- unsigned int force_port_map,
- unsigned int mask_port_map);
-
-+int ahci_platform_suspend_host(struct device *dev);
-+int ahci_platform_resume_host(struct device *dev);
-+int ahci_platform_suspend(struct device *dev);
-+int ahci_platform_resume(struct device *dev);
-+
- #endif /* _AHCI_PLATFORM_H */
diff --git a/target/linux/ipq806x/patches/0116-ata-ahci_platform-Add-DT-compatible-for-Synopsis-DWC.patch b/target/linux/ipq806x/patches/0116-ata-ahci_platform-Add-DT-compatible-for-Synopsis-DWC.patch
deleted file mode 100644
index e64e5c9..0000000
--- a/target/linux/ipq806x/patches/0116-ata-ahci_platform-Add-DT-compatible-for-Synopsis-DWC.patch
+++ /dev/null
@@ -1,27 +0,0 @@
-From bab3492791ade083c172a898b6f7a3692ffb89d5 Mon Sep 17 00:00:00 2001
-From: Roger Quadros <rogerq@ti.com>
-Date: Sat, 22 Feb 2014 16:53:38 +0100
-Subject: [PATCH 116/182] ata: ahci_platform: Add DT compatible for Synopsis
- DWC AHCI controller
-
-Add compatible string "snps,dwc-ahci", which should be used
-for Synopsis Designware SATA cores. e.g. on TI OMAP5 and DRA7 platforms.
-
-Signed-off-by: Roger Quadros <rogerq@ti.com>
-Reviewed-by: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com>
-Signed-off-by: Hans de Goede <hdegoede@redhat.com>
-Signed-off-by: Tejun Heo <tj@kernel.org>
----
- drivers/ata/ahci_platform.c | 1 +
- 1 file changed, 1 insertion(+)
-
---- a/drivers/ata/ahci_platform.c
-+++ b/drivers/ata/ahci_platform.c
-@@ -577,6 +577,7 @@ static const struct of_device_id ahci_of
- { .compatible = "snps,spear-ahci", },
- { .compatible = "snps,exynos5440-ahci", },
- { .compatible = "ibm,476gtr-ahci", },
-+ { .compatible = "snps,dwc-ahci", },
- {},
- };
- MODULE_DEVICE_TABLE(of, ahci_of_match);
diff --git a/target/linux/ipq806x/patches/0117-ata-ahci_platform-Manage-SATA-PHY.patch b/target/linux/ipq806x/patches/0117-ata-ahci_platform-Manage-SATA-PHY.patch
deleted file mode 100644
index 20211dc..0000000
--- a/target/linux/ipq806x/patches/0117-ata-ahci_platform-Manage-SATA-PHY.patch
+++ /dev/null
@@ -1,134 +0,0 @@
-From 05b9b8d1035944af25694d2ebe53077cf1ccb067 Mon Sep 17 00:00:00 2001
-From: Roger Quadros <rogerq@ti.com>
-Date: Sat, 22 Feb 2014 16:53:40 +0100
-Subject: [PATCH 117/182] ata: ahci_platform: Manage SATA PHY
-
-Some platforms have a PHY hooked up to the SATA controller. The PHY
-needs to be initialized and powered up for SATA to work. We do that
-using the PHY framework.
-
-tj: Minor comment formatting updates.
-
-CC: Balaji T K <balajitk@ti.com>
-Signed-off-by: Roger Quadros <rogerq@ti.com>
-Signed-off-by: Hans de Goede <hdegoede@redhat.com>
-Signed-off-by: Tejun Heo<tj@kernel.org>
----
- drivers/ata/ahci.h | 2 ++
- drivers/ata/ahci_platform.c | 47 +++++++++++++++++++++++++++++++++++++++++--
- 2 files changed, 47 insertions(+), 2 deletions(-)
-
---- a/drivers/ata/ahci.h
-+++ b/drivers/ata/ahci.h
-@@ -37,6 +37,7 @@
-
- #include <linux/clk.h>
- #include <linux/libata.h>
-+#include <linux/phy/phy.h>
- #include <linux/regulator/consumer.h>
-
- /* Enclosure Management Control */
-@@ -326,6 +327,7 @@ struct ahci_host_priv {
- u32 em_msg_type; /* EM message type */
- struct clk *clks[AHCI_MAX_CLKS]; /* Optional */
- struct regulator *target_pwr; /* Optional */
-+ struct phy *phy; /* If platform uses phy */
- void *plat_data; /* Other platform data */
- /*
- * Optional ahci_start_engine override, if not set this gets set to the
---- a/drivers/ata/ahci_platform.c
-+++ b/drivers/ata/ahci_platform.c
-@@ -22,6 +22,7 @@
- #include <linux/platform_device.h>
- #include <linux/libata.h>
- #include <linux/ahci_platform.h>
-+#include <linux/phy/phy.h>
- #include "ahci.h"
-
- static void ahci_host_stop(struct ata_host *host);
-@@ -140,6 +141,7 @@ EXPORT_SYMBOL_GPL(ahci_platform_disable_
- * following order:
- * 1) Regulator
- * 2) Clocks (through ahci_platform_enable_clks)
-+ * 3) Phy
- *
- * If resource enabling fails at any point the previous enabled resources
- * are disabled in reverse order.
-@@ -161,8 +163,23 @@ int ahci_platform_enable_resources(struc
- if (rc)
- goto disable_regulator;
-
-+ if (hpriv->phy) {
-+ rc = phy_init(hpriv->phy);
-+ if (rc)
-+ goto disable_clks;
-+
-+ rc = phy_power_on(hpriv->phy);
-+ if (rc) {
-+ phy_exit(hpriv->phy);
-+ goto disable_clks;
-+ }
-+ }
-+
- return 0;
-
-+disable_clks:
-+ ahci_platform_disable_clks(hpriv);
-+
- disable_regulator:
- if (hpriv->target_pwr)
- regulator_disable(hpriv->target_pwr);
-@@ -176,11 +193,17 @@ EXPORT_SYMBOL_GPL(ahci_platform_enable_r
- *
- * This function disables all ahci_platform managed resources in the
- * following order:
-- * 1) Clocks (through ahci_platform_disable_clks)
-- * 2) Regulator
-+ * 1) Phy
-+ * 2) Clocks (through ahci_platform_disable_clks)
-+ * 3) Regulator
- */
- void ahci_platform_disable_resources(struct ahci_host_priv *hpriv)
- {
-+ if (hpriv->phy) {
-+ phy_power_off(hpriv->phy);
-+ phy_exit(hpriv->phy);
-+ }
-+
- ahci_platform_disable_clks(hpriv);
-
- if (hpriv->target_pwr)
-@@ -208,6 +231,7 @@ static void ahci_platform_put_resources(
- * 2) regulator for controlling the targets power (optional)
- * 3) 0 - AHCI_MAX_CLKS clocks, as specified in the devs devicetree node,
- * or for non devicetree enabled platforms a single clock
-+ * 4) phy (optional)
- *
- * RETURNS:
- * The allocated ahci_host_priv on success, otherwise an ERR_PTR value
-@@ -266,6 +290,25 @@ struct ahci_host_priv *ahci_platform_get
- hpriv->clks[i] = clk;
- }
-
-+ hpriv->phy = devm_phy_get(dev, "sata-phy");
-+ if (IS_ERR(hpriv->phy)) {
-+ rc = PTR_ERR(hpriv->phy);
-+ switch (rc) {
-+ case -ENODEV:
-+ case -ENOSYS:
-+ /* continue normally */
-+ hpriv->phy = NULL;
-+ break;
-+
-+ case -EPROBE_DEFER:
-+ goto err_out;
-+
-+ default:
-+ dev_err(dev, "couldn't get sata-phy\n");
-+ goto err_out;
-+ }
-+ }
-+
- devres_remove_group(dev, NULL);
- return hpriv;
-
diff --git a/target/linux/ipq806x/patches/0118-ata-ahci_platform-runtime-resume-the-device-before-u.patch b/target/linux/ipq806x/patches/0118-ata-ahci_platform-runtime-resume-the-device-before-u.patch
deleted file mode 100644
index 6603bb9..0000000
--- a/target/linux/ipq806x/patches/0118-ata-ahci_platform-runtime-resume-the-device-before-u.patch
+++ /dev/null
@@ -1,79 +0,0 @@
-From abe309ab531f22b9b89329bd825606f6b68a95a1 Mon Sep 17 00:00:00 2001
-From: Roger Quadros <rogerq@ti.com>
-Date: Sat, 22 Feb 2014 16:53:41 +0100
-Subject: [PATCH 118/182] ata: ahci_platform: runtime resume the device before
- use
-
-On OMAP platforms the device needs to be runtime resumed before it can
-be accessed. The OMAP HWMOD framework takes care of enabling the
-module and its resources based on the device's runtime PM state.
-
-In this patch we runtime resume during .probe() and runtime suspend
-after .remove().
-
-We also update the runtime PM state during .resume().
-
-CC: Balaji T K <balajitk@ti.com>
-Signed-off-by: Roger Quadros <rogerq@ti.com>
-Signed-off-by: Hans de Goede <hdegoede@redhat.com>
-Signed-off-by: Tejun Heo <tj@kernel.org>
----
- drivers/ata/ahci.h | 1 +
- drivers/ata/ahci_platform.c | 15 +++++++++++++++
- 2 files changed, 16 insertions(+)
-
---- a/drivers/ata/ahci.h
-+++ b/drivers/ata/ahci.h
-@@ -325,6 +325,7 @@ struct ahci_host_priv {
- u32 em_loc; /* enclosure management location */
- u32 em_buf_sz; /* EM buffer size in byte */
- u32 em_msg_type; /* EM message type */
-+ bool got_runtime_pm; /* Did we do pm_runtime_get? */
- struct clk *clks[AHCI_MAX_CLKS]; /* Optional */
- struct regulator *target_pwr; /* Optional */
- struct phy *phy; /* If platform uses phy */
---- a/drivers/ata/ahci_platform.c
-+++ b/drivers/ata/ahci_platform.c
-@@ -23,6 +23,7 @@
- #include <linux/libata.h>
- #include <linux/ahci_platform.h>
- #include <linux/phy/phy.h>
-+#include <linux/pm_runtime.h>
- #include "ahci.h"
-
- static void ahci_host_stop(struct ata_host *host);
-@@ -216,6 +217,11 @@ static void ahci_platform_put_resources(
- struct ahci_host_priv *hpriv = res;
- int c;
-
-+ if (hpriv->got_runtime_pm) {
-+ pm_runtime_put_sync(dev);
-+ pm_runtime_disable(dev);
-+ }
-+
- for (c = 0; c < AHCI_MAX_CLKS && hpriv->clks[c]; c++)
- clk_put(hpriv->clks[c]);
- }
-@@ -309,6 +315,10 @@ struct ahci_host_priv *ahci_platform_get
- }
- }
-
-+ pm_runtime_enable(dev);
-+ pm_runtime_get_sync(dev);
-+ hpriv->got_runtime_pm = true;
-+
- devres_remove_group(dev, NULL);
- return hpriv;
-
-@@ -603,6 +613,11 @@ int ahci_platform_resume(struct device *
- if (rc)
- goto disable_resources;
-
-+ /* We resumed so update PM runtime state */
-+ pm_runtime_disable(dev);
-+ pm_runtime_set_active(dev);
-+ pm_runtime_enable(dev);
-+
- return 0;
-
- disable_resources:
diff --git a/target/linux/ipq806x/patches/0119-ahci_platform-Drop-support-for-ahci-strict-platform-.patch b/target/linux/ipq806x/patches/0119-ahci_platform-Drop-support-for-ahci-strict-platform-.patch
deleted file mode 100644
index 2e833ce..0000000
--- a/target/linux/ipq806x/patches/0119-ahci_platform-Drop-support-for-ahci-strict-platform-.patch
+++ /dev/null
@@ -1,49 +0,0 @@
-From 474c436aebe260b0e6e7042ce5291137b7c87b57 Mon Sep 17 00:00:00 2001
-From: Hans de Goede <hdegoede@redhat.com>
-Date: Sat, 22 Feb 2014 17:22:53 +0100
-Subject: [PATCH 119/182] ahci_platform: Drop support for ahci-strict platform
- device type
-
-I've done a grep over the entire kernel tree and nothing is using this
-(anymore?).
-
-Signed-off-by: Hans de Goede <hdegoede@redhat.com>
-Signed-off-by: Tejun Heo <tj@kernel.org>
----
- drivers/ata/ahci_platform.c | 11 -----------
- 1 file changed, 11 deletions(-)
-
---- a/drivers/ata/ahci_platform.c
-+++ b/drivers/ata/ahci_platform.c
-@@ -31,7 +31,6 @@ static void ahci_host_stop(struct ata_ho
- enum ahci_type {
- AHCI, /* standard platform ahci */
- IMX53_AHCI, /* ahci on i.mx53 */
-- STRICT_AHCI, /* delayed DMA engine start */
- };
-
- static struct platform_device_id ahci_devtype[] = {
-@@ -42,9 +41,6 @@ static struct platform_device_id ahci_de
- .name = "imx53-ahci",
- .driver_data = IMX53_AHCI,
- }, {
-- .name = "strict-ahci",
-- .driver_data = STRICT_AHCI,
-- }, {
- /* sentinel */
- }
- };
-@@ -75,13 +71,6 @@ static const struct ata_port_info ahci_p
- .udma_mask = ATA_UDMA6,
- .port_ops = &ahci_platform_retry_srst_ops,
- },
-- [STRICT_AHCI] = {
-- AHCI_HFLAGS (AHCI_HFLAG_DELAY_ENGINE),
-- .flags = AHCI_FLAG_COMMON,
-- .pio_mask = ATA_PIO4,
-- .udma_mask = ATA_UDMA6,
-- .port_ops = &ahci_platform_ops,
-- },
- };
-
- static struct scsi_host_template ahci_platform_sht = {
diff --git a/target/linux/ipq806x/patches/0120-ahci_platform-Drop-support-for-imx53-ahci-platform-d.patch b/target/linux/ipq806x/patches/0120-ahci_platform-Drop-support-for-imx53-ahci-platform-d.patch
deleted file mode 100644
index b18c04f..0000000
--- a/target/linux/ipq806x/patches/0120-ahci_platform-Drop-support-for-imx53-ahci-platform-d.patch
+++ /dev/null
@@ -1,105 +0,0 @@
-From 0d153bacb749d9291324ef0282ea9d235baca499 Mon Sep 17 00:00:00 2001
-From: Hans de Goede <hdegoede@redhat.com>
-Date: Sat, 22 Feb 2014 17:22:54 +0100
-Subject: [PATCH 120/182] ahci_platform: Drop support for imx53-ahci platform
- device type
-
-Since the 3.13 release the ahci_imx driver has proper devicetree enabled
-support for ahci on imx53 and that is used instead of the old board file
-created imx53-ahci platform device.
-
-Note this patch also complete drops the id-table, an id-table is not needed
-for a single id platform driver, the name field in the driver struct suffices.
-
-And the code already has an explicit "MODULE_ALIAS("platform:ahci");" so the
-id-table is not needed for that either.
-
-Cc: Marek Vasut <marex@denx.de>
-Signed-off-by: Hans de Goede <hdegoede@redhat.com>
-Signed-off-by: Tejun Heo <tj@kernel.org>
----
- drivers/ata/ahci_platform.c | 46 ++++++-------------------------------------
- 1 file changed, 6 insertions(+), 40 deletions(-)
-
---- a/drivers/ata/ahci_platform.c
-+++ b/drivers/ata/ahci_platform.c
-@@ -28,49 +28,17 @@
-
- static void ahci_host_stop(struct ata_host *host);
-
--enum ahci_type {
-- AHCI, /* standard platform ahci */
-- IMX53_AHCI, /* ahci on i.mx53 */
--};
--
--static struct platform_device_id ahci_devtype[] = {
-- {
-- .name = "ahci",
-- .driver_data = AHCI,
-- }, {
-- .name = "imx53-ahci",
-- .driver_data = IMX53_AHCI,
-- }, {
-- /* sentinel */
-- }
--};
--MODULE_DEVICE_TABLE(platform, ahci_devtype);
--
- struct ata_port_operations ahci_platform_ops = {
- .inherits = &ahci_ops,
- .host_stop = ahci_host_stop,
- };
- EXPORT_SYMBOL_GPL(ahci_platform_ops);
-
--static struct ata_port_operations ahci_platform_retry_srst_ops = {
-- .inherits = &ahci_pmp_retry_srst_ops,
-- .host_stop = ahci_host_stop,
--};
--
--static const struct ata_port_info ahci_port_info[] = {
-- /* by features */
-- [AHCI] = {
-- .flags = AHCI_FLAG_COMMON,
-- .pio_mask = ATA_PIO4,
-- .udma_mask = ATA_UDMA6,
-- .port_ops = &ahci_platform_ops,
-- },
-- [IMX53_AHCI] = {
-- .flags = AHCI_FLAG_COMMON,
-- .pio_mask = ATA_PIO4,
-- .udma_mask = ATA_UDMA6,
-- .port_ops = &ahci_platform_retry_srst_ops,
-- },
-+static const struct ata_port_info ahci_port_info = {
-+ .flags = AHCI_FLAG_COMMON,
-+ .pio_mask = ATA_PIO4,
-+ .udma_mask = ATA_UDMA6,
-+ .port_ops = &ahci_platform_ops,
- };
-
- static struct scsi_host_template ahci_platform_sht = {
-@@ -416,7 +384,6 @@ static int ahci_probe(struct platform_de
- {
- struct device *dev = &pdev->dev;
- struct ahci_platform_data *pdata = dev_get_platdata(dev);
-- const struct platform_device_id *id = platform_get_device_id(pdev);
- const struct ata_port_info *pi_template;
- struct ahci_host_priv *hpriv;
- int rc;
-@@ -444,7 +411,7 @@ static int ahci_probe(struct platform_de
- if (pdata && pdata->ata_port_info)
- pi_template = pdata->ata_port_info;
- else
-- pi_template = &ahci_port_info[id ? id->driver_data : 0];
-+ pi_template = &ahci_port_info;
-
- rc = ahci_platform_init_host(pdev, hpriv, pi_template,
- pdata ? pdata->force_port_map : 0,
-@@ -638,7 +605,6 @@ static struct platform_driver ahci_drive
- .of_match_table = ahci_of_match,
- .pm = &ahci_pm_ops,
- },
-- .id_table = ahci_devtype,
- };
- module_platform_driver(ahci_driver);
-
diff --git a/target/linux/ipq806x/patches/0121-ahci_platform-Drop-unused-ahci_platform_data-members.patch b/target/linux/ipq806x/patches/0121-ahci_platform-Drop-unused-ahci_platform_data-members.patch
deleted file mode 100644
index 2895a2b..0000000
--- a/target/linux/ipq806x/patches/0121-ahci_platform-Drop-unused-ahci_platform_data-members.patch
+++ /dev/null
@@ -1,55 +0,0 @@
-From 438df60c6bff1b12a407fefcfb8a2e5d9b29ac6a Mon Sep 17 00:00:00 2001
-From: Hans de Goede <hdegoede@redhat.com>
-Date: Sat, 22 Feb 2014 17:22:55 +0100
-Subject: [PATCH 121/182] ahci_platform: Drop unused ahci_platform_data
- members
-
-These members are not used anywhere, and in the future we want
-ahci_platform_data to go away entirely so there is no reason to keep these
-around.
-
-Signed-off-by: Hans de Goede <hdegoede@redhat.com>
-Signed-off-by: Tejun Heo <tj@kernel.org>
----
- drivers/ata/ahci_platform.c | 10 +---------
- include/linux/ahci_platform.h | 3 ---
- 2 files changed, 1 insertion(+), 12 deletions(-)
-
---- a/drivers/ata/ahci_platform.c
-+++ b/drivers/ata/ahci_platform.c
-@@ -384,7 +384,6 @@ static int ahci_probe(struct platform_de
- {
- struct device *dev = &pdev->dev;
- struct ahci_platform_data *pdata = dev_get_platdata(dev);
-- const struct ata_port_info *pi_template;
- struct ahci_host_priv *hpriv;
- int rc;
-
-@@ -408,14 +407,7 @@ static int ahci_probe(struct platform_de
- goto disable_resources;
- }
-
-- if (pdata && pdata->ata_port_info)
-- pi_template = pdata->ata_port_info;
-- else
-- pi_template = &ahci_port_info;
--
-- rc = ahci_platform_init_host(pdev, hpriv, pi_template,
-- pdata ? pdata->force_port_map : 0,
-- pdata ? pdata->mask_port_map : 0);
-+ rc = ahci_platform_init_host(pdev, hpriv, &ahci_port_info, 0, 0);
- if (rc)
- goto pdata_exit;
-
---- a/include/linux/ahci_platform.h
-+++ b/include/linux/ahci_platform.h
-@@ -33,9 +33,6 @@ struct ahci_platform_data {
- void (*exit)(struct device *dev);
- int (*suspend)(struct device *dev);
- int (*resume)(struct device *dev);
-- const struct ata_port_info *ata_port_info;
-- unsigned int force_port_map;
-- unsigned int mask_port_map;
- };
-
- int ahci_platform_enable_clks(struct ahci_host_priv *hpriv);
diff --git a/target/linux/ipq806x/patches/0122-ata-ahci_platform-fix-devm_ioremap_resource-return-v.patch b/target/linux/ipq806x/patches/0122-ata-ahci_platform-fix-devm_ioremap_resource-return-v.patch
deleted file mode 100644
index 322a039..0000000
--- a/target/linux/ipq806x/patches/0122-ata-ahci_platform-fix-devm_ioremap_resource-return-v.patch
+++ /dev/null
@@ -1,41 +0,0 @@
-From 0db91c83bcb5f7307aaa16c093b8c6bb3f44be52 Mon Sep 17 00:00:00 2001
-From: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com>
-Date: Fri, 14 Mar 2014 18:22:09 +0100
-Subject: [PATCH 122/182] ata: ahci_platform: fix devm_ioremap_resource()
- return value checking
-
-devm_ioremap_resource() returns a pointer to the remapped memory or
-an ERR_PTR() encoded error code on failure. Fix the check inside
-ahci_platform_get_resources() accordingly.
-
-Also while at it remove a needless line break.
-
-Signed-off-by: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com>
-Signed-off-by: Tejun Heo <tj@kernel.org>
----
- drivers/ata/ahci_platform.c | 6 +++---
- 1 file changed, 3 insertions(+), 3 deletions(-)
-
---- a/drivers/ata/ahci_platform.c
-+++ b/drivers/ata/ahci_platform.c
-@@ -199,8 +199,7 @@ static void ahci_platform_put_resources(
- * RETURNS:
- * The allocated ahci_host_priv on success, otherwise an ERR_PTR value
- */
--struct ahci_host_priv *ahci_platform_get_resources(
-- struct platform_device *pdev)
-+struct ahci_host_priv *ahci_platform_get_resources(struct platform_device *pdev)
- {
- struct device *dev = &pdev->dev;
- struct ahci_host_priv *hpriv;
-@@ -219,8 +218,9 @@ struct ahci_host_priv *ahci_platform_get
-
- hpriv->mmio = devm_ioremap_resource(dev,
- platform_get_resource(pdev, IORESOURCE_MEM, 0));
-- if (!hpriv->mmio) {
-+ if (IS_ERR(hpriv->mmio)) {
- dev_err(dev, "no mmio space\n");
-+ rc = PTR_ERR(hpriv->mmio);
- goto err_out;
- }
-
diff --git a/target/linux/ipq806x/patches/0123-ata-ahci_platform-fix-ahci_platform_data-suspend-met.patch b/target/linux/ipq806x/patches/0123-ata-ahci_platform-fix-ahci_platform_data-suspend-met.patch
deleted file mode 100644
index 1a9e6d1..0000000
--- a/target/linux/ipq806x/patches/0123-ata-ahci_platform-fix-ahci_platform_data-suspend-met.patch
+++ /dev/null
@@ -1,45 +0,0 @@
-From bc26554ffa0223015edb474a4877ec544167dfba Mon Sep 17 00:00:00 2001
-From: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com>
-Date: Tue, 25 Mar 2014 19:51:38 +0100
-Subject: [PATCH 123/182] ata: ahci_platform: fix ahci_platform_data->suspend
- method handling
-
-Looking at ST SPEAr1340 AHCI code (the only user of the deprecated
-pdata->suspend and pdata->resume) it is obvious the we should return
-after calling pdata->suspend() only if the function have returned
-non-zero return value. The code has been broken since commit 1e70c2
-("ata/ahci_platform: Add clock framework support"). Fix it.
-
-Cc: Viresh Kumar <viresh.linux@gmail.com>
-Cc: Shiraz Hashim <shiraz.hashim@st.com>
-Acked-by: Hans de Goede <hdegoede@redhat.com>
-Signed-off-by: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com>
-Signed-off-by: Tejun Heo <tj@kernel.org>
----
- drivers/ata/ahci_platform.c | 11 +++++++++--
- 1 file changed, 9 insertions(+), 2 deletions(-)
-
---- a/drivers/ata/ahci_platform.c
-+++ b/drivers/ata/ahci_platform.c
-@@ -521,12 +521,19 @@ int ahci_platform_suspend(struct device
- if (rc)
- return rc;
-
-- if (pdata && pdata->suspend)
-- return pdata->suspend(dev);
-+ if (pdata && pdata->suspend) {
-+ rc = pdata->suspend(dev);
-+ if (rc)
-+ goto resume_host;
-+ }
-
- ahci_platform_disable_resources(hpriv);
-
- return 0;
-+
-+resume_host:
-+ ahci_platform_resume_host(dev);
-+ return rc;
- }
- EXPORT_SYMBOL_GPL(ahci_platform_suspend);
-
diff --git a/target/linux/ipq806x/patches/0124-ata-move-library-code-from-ahci_platform.c-to-libahc.patch b/target/linux/ipq806x/patches/0124-ata-move-library-code-from-ahci_platform.c-to-libahc.patch
deleted file mode 100644
index eca606b..0000000
--- a/target/linux/ipq806x/patches/0124-ata-move-library-code-from-ahci_platform.c-to-libahc.patch
+++ /dev/null
@@ -1,1145 +0,0 @@
-From 04800db1047afbf6701379435bff1a6fa64215f7 Mon Sep 17 00:00:00 2001
-From: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com>
-Date: Tue, 25 Mar 2014 19:51:39 +0100
-Subject: [PATCH 124/182] ata: move library code from ahci_platform.c to
- libahci_platform.c
-
-Move AHCI platform library code from ahci_platform.c to
-libahci_platform.c and fix dependencies for ahci_st,
-ahci_imx and ahci_sunxi drivers.
-
-Acked-by: Hans de Goede <hdegoede@redhat.com>
-Signed-off-by: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com>
-Signed-off-by: Tejun Heo <tj@kernel.org>
-
-Conflicts:
- drivers/ata/Kconfig
- drivers/ata/Makefile
----
- drivers/ata/Kconfig | 2 +-
- drivers/ata/Makefile | 4 +-
- drivers/ata/ahci_platform.c | 515 --------------------------------------
- drivers/ata/libahci_platform.c | 541 ++++++++++++++++++++++++++++++++++++++++
- 4 files changed, 544 insertions(+), 518 deletions(-)
- create mode 100644 drivers/ata/libahci_platform.c
-
---- a/drivers/ata/Kconfig
-+++ b/drivers/ata/Kconfig
-@@ -115,7 +115,7 @@ config SATA_AHCI_PLATFORM
-
- config AHCI_IMX
- tristate "Freescale i.MX AHCI SATA support"
-- depends on SATA_AHCI_PLATFORM && MFD_SYSCON
-+ depends on MFD_SYSCON
- help
- This option enables support for the Freescale i.MX SoC's
- onboard AHCI SATA.
---- a/drivers/ata/Makefile
-+++ b/drivers/ata/Makefile
-@@ -4,13 +4,13 @@ obj-$(CONFIG_ATA) += libata.o
- # non-SFF interface
- obj-$(CONFIG_SATA_AHCI) += ahci.o libahci.o
- obj-$(CONFIG_SATA_ACARD_AHCI) += acard-ahci.o libahci.o
--obj-$(CONFIG_SATA_AHCI_PLATFORM) += ahci_platform.o libahci.o
-+obj-$(CONFIG_SATA_AHCI_PLATFORM) += ahci_platform.o libahci.o libahci_platform.o
- obj-$(CONFIG_SATA_FSL) += sata_fsl.o
- obj-$(CONFIG_SATA_INIC162X) += sata_inic162x.o
- obj-$(CONFIG_SATA_SIL24) += sata_sil24.o
- obj-$(CONFIG_SATA_DWC) += sata_dwc_460ex.o
- obj-$(CONFIG_SATA_HIGHBANK) += sata_highbank.o libahci.o
--obj-$(CONFIG_AHCI_IMX) += ahci_imx.o
-+obj-$(CONFIG_AHCI_IMX) += ahci_imx.o libahci.o libahci_platform.o
-
- # SFF w/ custom DMA
- obj-$(CONFIG_PDC_ADMA) += pdc_adma.o
---- a/drivers/ata/ahci_platform.c
-+++ b/drivers/ata/ahci_platform.c
-@@ -12,28 +12,15 @@
- * any later version.
- */
-
--#include <linux/clk.h>
- #include <linux/kernel.h>
--#include <linux/gfp.h>
- #include <linux/module.h>
- #include <linux/pm.h>
--#include <linux/interrupt.h>
- #include <linux/device.h>
- #include <linux/platform_device.h>
- #include <linux/libata.h>
- #include <linux/ahci_platform.h>
--#include <linux/phy/phy.h>
--#include <linux/pm_runtime.h>
- #include "ahci.h"
-
--static void ahci_host_stop(struct ata_host *host);
--
--struct ata_port_operations ahci_platform_ops = {
-- .inherits = &ahci_ops,
-- .host_stop = ahci_host_stop,
--};
--EXPORT_SYMBOL_GPL(ahci_platform_ops);
--
- static const struct ata_port_info ahci_port_info = {
- .flags = AHCI_FLAG_COMMON,
- .pio_mask = ATA_PIO4,
-@@ -41,345 +28,6 @@ static const struct ata_port_info ahci_p
- .port_ops = &ahci_platform_ops,
- };
-
--static struct scsi_host_template ahci_platform_sht = {
-- AHCI_SHT("ahci_platform"),
--};
--
--/**
-- * ahci_platform_enable_clks - Enable platform clocks
-- * @hpriv: host private area to store config values
-- *
-- * This function enables all the clks found in hpriv->clks, starting at
-- * index 0. If any clk fails to enable it disables all the clks already
-- * enabled in reverse order, and then returns an error.
-- *
-- * RETURNS:
-- * 0 on success otherwise a negative error code
-- */
--int ahci_platform_enable_clks(struct ahci_host_priv *hpriv)
--{
-- int c, rc;
--
-- for (c = 0; c < AHCI_MAX_CLKS && hpriv->clks[c]; c++) {
-- rc = clk_prepare_enable(hpriv->clks[c]);
-- if (rc)
-- goto disable_unprepare_clk;
-- }
-- return 0;
--
--disable_unprepare_clk:
-- while (--c >= 0)
-- clk_disable_unprepare(hpriv->clks[c]);
-- return rc;
--}
--EXPORT_SYMBOL_GPL(ahci_platform_enable_clks);
--
--/**
-- * ahci_platform_disable_clks - Disable platform clocks
-- * @hpriv: host private area to store config values
-- *
-- * This function disables all the clks found in hpriv->clks, in reverse
-- * order of ahci_platform_enable_clks (starting at the end of the array).
-- */
--void ahci_platform_disable_clks(struct ahci_host_priv *hpriv)
--{
-- int c;
--
-- for (c = AHCI_MAX_CLKS - 1; c >= 0; c--)
-- if (hpriv->clks[c])
-- clk_disable_unprepare(hpriv->clks[c]);
--}
--EXPORT_SYMBOL_GPL(ahci_platform_disable_clks);
--
--/**
-- * ahci_platform_enable_resources - Enable platform resources
-- * @hpriv: host private area to store config values
-- *
-- * This function enables all ahci_platform managed resources in the
-- * following order:
-- * 1) Regulator
-- * 2) Clocks (through ahci_platform_enable_clks)
-- * 3) Phy
-- *
-- * If resource enabling fails at any point the previous enabled resources
-- * are disabled in reverse order.
-- *
-- * RETURNS:
-- * 0 on success otherwise a negative error code
-- */
--int ahci_platform_enable_resources(struct ahci_host_priv *hpriv)
--{
-- int rc;
--
-- if (hpriv->target_pwr) {
-- rc = regulator_enable(hpriv->target_pwr);
-- if (rc)
-- return rc;
-- }
--
-- rc = ahci_platform_enable_clks(hpriv);
-- if (rc)
-- goto disable_regulator;
--
-- if (hpriv->phy) {
-- rc = phy_init(hpriv->phy);
-- if (rc)
-- goto disable_clks;
--
-- rc = phy_power_on(hpriv->phy);
-- if (rc) {
-- phy_exit(hpriv->phy);
-- goto disable_clks;
-- }
-- }
--
-- return 0;
--
--disable_clks:
-- ahci_platform_disable_clks(hpriv);
--
--disable_regulator:
-- if (hpriv->target_pwr)
-- regulator_disable(hpriv->target_pwr);
-- return rc;
--}
--EXPORT_SYMBOL_GPL(ahci_platform_enable_resources);
--
--/**
-- * ahci_platform_disable_resources - Disable platform resources
-- * @hpriv: host private area to store config values
-- *
-- * This function disables all ahci_platform managed resources in the
-- * following order:
-- * 1) Phy
-- * 2) Clocks (through ahci_platform_disable_clks)
-- * 3) Regulator
-- */
--void ahci_platform_disable_resources(struct ahci_host_priv *hpriv)
--{
-- if (hpriv->phy) {
-- phy_power_off(hpriv->phy);
-- phy_exit(hpriv->phy);
-- }
--
-- ahci_platform_disable_clks(hpriv);
--
-- if (hpriv->target_pwr)
-- regulator_disable(hpriv->target_pwr);
--}
--EXPORT_SYMBOL_GPL(ahci_platform_disable_resources);
--
--static void ahci_platform_put_resources(struct device *dev, void *res)
--{
-- struct ahci_host_priv *hpriv = res;
-- int c;
--
-- if (hpriv->got_runtime_pm) {
-- pm_runtime_put_sync(dev);
-- pm_runtime_disable(dev);
-- }
--
-- for (c = 0; c < AHCI_MAX_CLKS && hpriv->clks[c]; c++)
-- clk_put(hpriv->clks[c]);
--}
--
--/**
-- * ahci_platform_get_resources - Get platform resources
-- * @pdev: platform device to get resources for
-- *
-- * This function allocates an ahci_host_priv struct, and gets the following
-- * resources, storing a reference to them inside the returned struct:
-- *
-- * 1) mmio registers (IORESOURCE_MEM 0, mandatory)
-- * 2) regulator for controlling the targets power (optional)
-- * 3) 0 - AHCI_MAX_CLKS clocks, as specified in the devs devicetree node,
-- * or for non devicetree enabled platforms a single clock
-- * 4) phy (optional)
-- *
-- * RETURNS:
-- * The allocated ahci_host_priv on success, otherwise an ERR_PTR value
-- */
--struct ahci_host_priv *ahci_platform_get_resources(struct platform_device *pdev)
--{
-- struct device *dev = &pdev->dev;
-- struct ahci_host_priv *hpriv;
-- struct clk *clk;
-- int i, rc = -ENOMEM;
--
-- if (!devres_open_group(dev, NULL, GFP_KERNEL))
-- return ERR_PTR(-ENOMEM);
--
-- hpriv = devres_alloc(ahci_platform_put_resources, sizeof(*hpriv),
-- GFP_KERNEL);
-- if (!hpriv)
-- goto err_out;
--
-- devres_add(dev, hpriv);
--
-- hpriv->mmio = devm_ioremap_resource(dev,
-- platform_get_resource(pdev, IORESOURCE_MEM, 0));
-- if (IS_ERR(hpriv->mmio)) {
-- dev_err(dev, "no mmio space\n");
-- rc = PTR_ERR(hpriv->mmio);
-- goto err_out;
-- }
--
-- hpriv->target_pwr = devm_regulator_get_optional(dev, "target");
-- if (IS_ERR(hpriv->target_pwr)) {
-- rc = PTR_ERR(hpriv->target_pwr);
-- if (rc == -EPROBE_DEFER)
-- goto err_out;
-- hpriv->target_pwr = NULL;
-- }
--
-- for (i = 0; i < AHCI_MAX_CLKS; i++) {
-- /*
-- * For now we must use clk_get(dev, NULL) for the first clock,
-- * because some platforms (da850, spear13xx) are not yet
-- * converted to use devicetree for clocks. For new platforms
-- * this is equivalent to of_clk_get(dev->of_node, 0).
-- */
-- if (i == 0)
-- clk = clk_get(dev, NULL);
-- else
-- clk = of_clk_get(dev->of_node, i);
--
-- if (IS_ERR(clk)) {
-- rc = PTR_ERR(clk);
-- if (rc == -EPROBE_DEFER)
-- goto err_out;
-- break;
-- }
-- hpriv->clks[i] = clk;
-- }
--
-- hpriv->phy = devm_phy_get(dev, "sata-phy");
-- if (IS_ERR(hpriv->phy)) {
-- rc = PTR_ERR(hpriv->phy);
-- switch (rc) {
-- case -ENODEV:
-- case -ENOSYS:
-- /* continue normally */
-- hpriv->phy = NULL;
-- break;
--
-- case -EPROBE_DEFER:
-- goto err_out;
--
-- default:
-- dev_err(dev, "couldn't get sata-phy\n");
-- goto err_out;
-- }
-- }
--
-- pm_runtime_enable(dev);
-- pm_runtime_get_sync(dev);
-- hpriv->got_runtime_pm = true;
--
-- devres_remove_group(dev, NULL);
-- return hpriv;
--
--err_out:
-- devres_release_group(dev, NULL);
-- return ERR_PTR(rc);
--}
--EXPORT_SYMBOL_GPL(ahci_platform_get_resources);
--
--/**
-- * ahci_platform_init_host - Bring up an ahci-platform host
-- * @pdev: platform device pointer for the host
-- * @hpriv: ahci-host private data for the host
-- * @pi_template: template for the ata_port_info to use
-- * @force_port_map: param passed to ahci_save_initial_config
-- * @mask_port_map: param passed to ahci_save_initial_config
-- *
-- * This function does all the usual steps needed to bring up an
-- * ahci-platform host, note any necessary resources (ie clks, phy, etc.)
-- * must be initialized / enabled before calling this.
-- *
-- * RETURNS:
-- * 0 on success otherwise a negative error code
-- */
--int ahci_platform_init_host(struct platform_device *pdev,
-- struct ahci_host_priv *hpriv,
-- const struct ata_port_info *pi_template,
-- unsigned int force_port_map,
-- unsigned int mask_port_map)
--{
-- struct device *dev = &pdev->dev;
-- struct ata_port_info pi = *pi_template;
-- const struct ata_port_info *ppi[] = { &pi, NULL };
-- struct ata_host *host;
-- int i, irq, n_ports, rc;
--
-- irq = platform_get_irq(pdev, 0);
-- if (irq <= 0) {
-- dev_err(dev, "no irq\n");
-- return -EINVAL;
-- }
--
-- /* prepare host */
-- hpriv->flags |= (unsigned long)pi.private_data;
--
-- ahci_save_initial_config(dev, hpriv, force_port_map, mask_port_map);
--
-- if (hpriv->cap & HOST_CAP_NCQ)
-- pi.flags |= ATA_FLAG_NCQ;
--
-- if (hpriv->cap & HOST_CAP_PMP)
-- pi.flags |= ATA_FLAG_PMP;
--
-- ahci_set_em_messages(hpriv, &pi);
--
-- /* CAP.NP sometimes indicate the index of the last enabled
-- * port, at other times, that of the last possible port, so
-- * determining the maximum port number requires looking at
-- * both CAP.NP and port_map.
-- */
-- n_ports = max(ahci_nr_ports(hpriv->cap), fls(hpriv->port_map));
--
-- host = ata_host_alloc_pinfo(dev, ppi, n_ports);
-- if (!host)
-- return -ENOMEM;
--
-- host->private_data = hpriv;
--
-- if (!(hpriv->cap & HOST_CAP_SSS) || ahci_ignore_sss)
-- host->flags |= ATA_HOST_PARALLEL_SCAN;
-- else
-- dev_info(dev, "SSS flag set, parallel bus scan disabled\n");
--
-- if (pi.flags & ATA_FLAG_EM)
-- ahci_reset_em(host);
--
-- for (i = 0; i < host->n_ports; i++) {
-- struct ata_port *ap = host->ports[i];
--
-- ata_port_desc(ap, "mmio %pR",
-- platform_get_resource(pdev, IORESOURCE_MEM, 0));
-- ata_port_desc(ap, "port 0x%x", 0x100 + ap->port_no * 0x80);
--
-- /* set enclosure management message type */
-- if (ap->flags & ATA_FLAG_EM)
-- ap->em_message_type = hpriv->em_msg_type;
--
-- /* disabled/not-implemented port */
-- if (!(hpriv->port_map & (1 << i)))
-- ap->ops = &ata_dummy_port_ops;
-- }
--
-- rc = ahci_reset_controller(host);
-- if (rc)
-- return rc;
--
-- ahci_init_controller(host);
-- ahci_print_info(host, "platform");
--
-- return ata_host_activate(host, irq, ahci_interrupt, IRQF_SHARED,
-- &ahci_platform_sht);
--}
--EXPORT_SYMBOL_GPL(ahci_platform_init_host);
--
- static int ahci_probe(struct platform_device *pdev)
- {
- struct device *dev = &pdev->dev;
-@@ -420,169 +68,6 @@ disable_resources:
- return rc;
- }
-
--static void ahci_host_stop(struct ata_host *host)
--{
-- struct device *dev = host->dev;
-- struct ahci_platform_data *pdata = dev_get_platdata(dev);
-- struct ahci_host_priv *hpriv = host->private_data;
--
-- if (pdata && pdata->exit)
-- pdata->exit(dev);
--
-- ahci_platform_disable_resources(hpriv);
--}
--
--#ifdef CONFIG_PM_SLEEP
--/**
-- * ahci_platform_suspend_host - Suspend an ahci-platform host
-- * @dev: device pointer for the host
-- *
-- * This function does all the usual steps needed to suspend an
-- * ahci-platform host, note any necessary resources (ie clks, phy, etc.)
-- * must be disabled after calling this.
-- *
-- * RETURNS:
-- * 0 on success otherwise a negative error code
-- */
--int ahci_platform_suspend_host(struct device *dev)
--{
-- struct ata_host *host = dev_get_drvdata(dev);
-- struct ahci_host_priv *hpriv = host->private_data;
-- void __iomem *mmio = hpriv->mmio;
-- u32 ctl;
--
-- if (hpriv->flags & AHCI_HFLAG_NO_SUSPEND) {
-- dev_err(dev, "firmware update required for suspend/resume\n");
-- return -EIO;
-- }
--
-- /*
-- * AHCI spec rev1.1 section 8.3.3:
-- * Software must disable interrupts prior to requesting a
-- * transition of the HBA to D3 state.
-- */
-- ctl = readl(mmio + HOST_CTL);
-- ctl &= ~HOST_IRQ_EN;
-- writel(ctl, mmio + HOST_CTL);
-- readl(mmio + HOST_CTL); /* flush */
--
-- return ata_host_suspend(host, PMSG_SUSPEND);
--}
--EXPORT_SYMBOL_GPL(ahci_platform_suspend_host);
--
--/**
-- * ahci_platform_resume_host - Resume an ahci-platform host
-- * @dev: device pointer for the host
-- *
-- * This function does all the usual steps needed to resume an ahci-platform
-- * host, note any necessary resources (ie clks, phy, etc.) must be
-- * initialized / enabled before calling this.
-- *
-- * RETURNS:
-- * 0 on success otherwise a negative error code
-- */
--int ahci_platform_resume_host(struct device *dev)
--{
-- struct ata_host *host = dev_get_drvdata(dev);
-- int rc;
--
-- if (dev->power.power_state.event == PM_EVENT_SUSPEND) {
-- rc = ahci_reset_controller(host);
-- if (rc)
-- return rc;
--
-- ahci_init_controller(host);
-- }
--
-- ata_host_resume(host);
--
-- return 0;
--}
--EXPORT_SYMBOL_GPL(ahci_platform_resume_host);
--
--/**
-- * ahci_platform_suspend - Suspend an ahci-platform device
-- * @dev: the platform device to suspend
-- *
-- * This function suspends the host associated with the device, followed by
-- * disabling all the resources of the device.
-- *
-- * RETURNS:
-- * 0 on success otherwise a negative error code
-- */
--int ahci_platform_suspend(struct device *dev)
--{
-- struct ahci_platform_data *pdata = dev_get_platdata(dev);
-- struct ata_host *host = dev_get_drvdata(dev);
-- struct ahci_host_priv *hpriv = host->private_data;
-- int rc;
--
-- rc = ahci_platform_suspend_host(dev);
-- if (rc)
-- return rc;
--
-- if (pdata && pdata->suspend) {
-- rc = pdata->suspend(dev);
-- if (rc)
-- goto resume_host;
-- }
--
-- ahci_platform_disable_resources(hpriv);
--
-- return 0;
--
--resume_host:
-- ahci_platform_resume_host(dev);
-- return rc;
--}
--EXPORT_SYMBOL_GPL(ahci_platform_suspend);
--
--/**
-- * ahci_platform_resume - Resume an ahci-platform device
-- * @dev: the platform device to resume
-- *
-- * This function enables all the resources of the device followed by
-- * resuming the host associated with the device.
-- *
-- * RETURNS:
-- * 0 on success otherwise a negative error code
-- */
--int ahci_platform_resume(struct device *dev)
--{
-- struct ahci_platform_data *pdata = dev_get_platdata(dev);
-- struct ata_host *host = dev_get_drvdata(dev);
-- struct ahci_host_priv *hpriv = host->private_data;
-- int rc;
--
-- rc = ahci_platform_enable_resources(hpriv);
-- if (rc)
-- return rc;
--
-- if (pdata && pdata->resume) {
-- rc = pdata->resume(dev);
-- if (rc)
-- goto disable_resources;
-- }
--
-- rc = ahci_platform_resume_host(dev);
-- if (rc)
-- goto disable_resources;
--
-- /* We resumed so update PM runtime state */
-- pm_runtime_disable(dev);
-- pm_runtime_set_active(dev);
-- pm_runtime_enable(dev);
--
-- return 0;
--
--disable_resources:
-- ahci_platform_disable_resources(hpriv);
--
-- return rc;
--}
--EXPORT_SYMBOL_GPL(ahci_platform_resume);
--#endif
--
- static SIMPLE_DEV_PM_OPS(ahci_pm_ops, ahci_platform_suspend,
- ahci_platform_resume);
-
---- /dev/null
-+++ b/drivers/ata/libahci_platform.c
-@@ -0,0 +1,541 @@
-+/*
-+ * AHCI SATA platform library
-+ *
-+ * Copyright 2004-2005 Red Hat, Inc.
-+ * Jeff Garzik <jgarzik@pobox.com>
-+ * Copyright 2010 MontaVista Software, LLC.
-+ * Anton Vorontsov <avorontsov@ru.mvista.com>
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2, or (at your option)
-+ * any later version.
-+ */
-+
-+#include <linux/clk.h>
-+#include <linux/kernel.h>
-+#include <linux/gfp.h>
-+#include <linux/module.h>
-+#include <linux/pm.h>
-+#include <linux/interrupt.h>
-+#include <linux/device.h>
-+#include <linux/platform_device.h>
-+#include <linux/libata.h>
-+#include <linux/ahci_platform.h>
-+#include <linux/phy/phy.h>
-+#include <linux/pm_runtime.h>
-+#include "ahci.h"
-+
-+static void ahci_host_stop(struct ata_host *host);
-+
-+struct ata_port_operations ahci_platform_ops = {
-+ .inherits = &ahci_ops,
-+ .host_stop = ahci_host_stop,
-+};
-+EXPORT_SYMBOL_GPL(ahci_platform_ops);
-+
-+static struct scsi_host_template ahci_platform_sht = {
-+ AHCI_SHT("ahci_platform"),
-+};
-+
-+/**
-+ * ahci_platform_enable_clks - Enable platform clocks
-+ * @hpriv: host private area to store config values
-+ *
-+ * This function enables all the clks found in hpriv->clks, starting at
-+ * index 0. If any clk fails to enable it disables all the clks already
-+ * enabled in reverse order, and then returns an error.
-+ *
-+ * RETURNS:
-+ * 0 on success otherwise a negative error code
-+ */
-+int ahci_platform_enable_clks(struct ahci_host_priv *hpriv)
-+{
-+ int c, rc;
-+
-+ for (c = 0; c < AHCI_MAX_CLKS && hpriv->clks[c]; c++) {
-+ rc = clk_prepare_enable(hpriv->clks[c]);
-+ if (rc)
-+ goto disable_unprepare_clk;
-+ }
-+ return 0;
-+
-+disable_unprepare_clk:
-+ while (--c >= 0)
-+ clk_disable_unprepare(hpriv->clks[c]);
-+ return rc;
-+}
-+EXPORT_SYMBOL_GPL(ahci_platform_enable_clks);
-+
-+/**
-+ * ahci_platform_disable_clks - Disable platform clocks
-+ * @hpriv: host private area to store config values
-+ *
-+ * This function disables all the clks found in hpriv->clks, in reverse
-+ * order of ahci_platform_enable_clks (starting at the end of the array).
-+ */
-+void ahci_platform_disable_clks(struct ahci_host_priv *hpriv)
-+{
-+ int c;
-+
-+ for (c = AHCI_MAX_CLKS - 1; c >= 0; c--)
-+ if (hpriv->clks[c])
-+ clk_disable_unprepare(hpriv->clks[c]);
-+}
-+EXPORT_SYMBOL_GPL(ahci_platform_disable_clks);
-+
-+/**
-+ * ahci_platform_enable_resources - Enable platform resources
-+ * @hpriv: host private area to store config values
-+ *
-+ * This function enables all ahci_platform managed resources in the
-+ * following order:
-+ * 1) Regulator
-+ * 2) Clocks (through ahci_platform_enable_clks)
-+ * 3) Phy
-+ *
-+ * If resource enabling fails at any point the previous enabled resources
-+ * are disabled in reverse order.
-+ *
-+ * RETURNS:
-+ * 0 on success otherwise a negative error code
-+ */
-+int ahci_platform_enable_resources(struct ahci_host_priv *hpriv)
-+{
-+ int rc;
-+
-+ if (hpriv->target_pwr) {
-+ rc = regulator_enable(hpriv->target_pwr);
-+ if (rc)
-+ return rc;
-+ }
-+
-+ rc = ahci_platform_enable_clks(hpriv);
-+ if (rc)
-+ goto disable_regulator;
-+
-+ if (hpriv->phy) {
-+ rc = phy_init(hpriv->phy);
-+ if (rc)
-+ goto disable_clks;
-+
-+ rc = phy_power_on(hpriv->phy);
-+ if (rc) {
-+ phy_exit(hpriv->phy);
-+ goto disable_clks;
-+ }
-+ }
-+
-+ return 0;
-+
-+disable_clks:
-+ ahci_platform_disable_clks(hpriv);
-+
-+disable_regulator:
-+ if (hpriv->target_pwr)
-+ regulator_disable(hpriv->target_pwr);
-+ return rc;
-+}
-+EXPORT_SYMBOL_GPL(ahci_platform_enable_resources);
-+
-+/**
-+ * ahci_platform_disable_resources - Disable platform resources
-+ * @hpriv: host private area to store config values
-+ *
-+ * This function disables all ahci_platform managed resources in the
-+ * following order:
-+ * 1) Phy
-+ * 2) Clocks (through ahci_platform_disable_clks)
-+ * 3) Regulator
-+ */
-+void ahci_platform_disable_resources(struct ahci_host_priv *hpriv)
-+{
-+ if (hpriv->phy) {
-+ phy_power_off(hpriv->phy);
-+ phy_exit(hpriv->phy);
-+ }
-+
-+ ahci_platform_disable_clks(hpriv);
-+
-+ if (hpriv->target_pwr)
-+ regulator_disable(hpriv->target_pwr);
-+}
-+EXPORT_SYMBOL_GPL(ahci_platform_disable_resources);
-+
-+static void ahci_platform_put_resources(struct device *dev, void *res)
-+{
-+ struct ahci_host_priv *hpriv = res;
-+ int c;
-+
-+ if (hpriv->got_runtime_pm) {
-+ pm_runtime_put_sync(dev);
-+ pm_runtime_disable(dev);
-+ }
-+
-+ for (c = 0; c < AHCI_MAX_CLKS && hpriv->clks[c]; c++)
-+ clk_put(hpriv->clks[c]);
-+}
-+
-+/**
-+ * ahci_platform_get_resources - Get platform resources
-+ * @pdev: platform device to get resources for
-+ *
-+ * This function allocates an ahci_host_priv struct, and gets the following
-+ * resources, storing a reference to them inside the returned struct:
-+ *
-+ * 1) mmio registers (IORESOURCE_MEM 0, mandatory)
-+ * 2) regulator for controlling the targets power (optional)
-+ * 3) 0 - AHCI_MAX_CLKS clocks, as specified in the devs devicetree node,
-+ * or for non devicetree enabled platforms a single clock
-+ * 4) phy (optional)
-+ *
-+ * RETURNS:
-+ * The allocated ahci_host_priv on success, otherwise an ERR_PTR value
-+ */
-+struct ahci_host_priv *ahci_platform_get_resources(struct platform_device *pdev)
-+{
-+ struct device *dev = &pdev->dev;
-+ struct ahci_host_priv *hpriv;
-+ struct clk *clk;
-+ int i, rc = -ENOMEM;
-+
-+ if (!devres_open_group(dev, NULL, GFP_KERNEL))
-+ return ERR_PTR(-ENOMEM);
-+
-+ hpriv = devres_alloc(ahci_platform_put_resources, sizeof(*hpriv),
-+ GFP_KERNEL);
-+ if (!hpriv)
-+ goto err_out;
-+
-+ devres_add(dev, hpriv);
-+
-+ hpriv->mmio = devm_ioremap_resource(dev,
-+ platform_get_resource(pdev, IORESOURCE_MEM, 0));
-+ if (IS_ERR(hpriv->mmio)) {
-+ dev_err(dev, "no mmio space\n");
-+ rc = PTR_ERR(hpriv->mmio);
-+ goto err_out;
-+ }
-+
-+ hpriv->target_pwr = devm_regulator_get_optional(dev, "target");
-+ if (IS_ERR(hpriv->target_pwr)) {
-+ rc = PTR_ERR(hpriv->target_pwr);
-+ if (rc == -EPROBE_DEFER)
-+ goto err_out;
-+ hpriv->target_pwr = NULL;
-+ }
-+
-+ for (i = 0; i < AHCI_MAX_CLKS; i++) {
-+ /*
-+ * For now we must use clk_get(dev, NULL) for the first clock,
-+ * because some platforms (da850, spear13xx) are not yet
-+ * converted to use devicetree for clocks. For new platforms
-+ * this is equivalent to of_clk_get(dev->of_node, 0).
-+ */
-+ if (i == 0)
-+ clk = clk_get(dev, NULL);
-+ else
-+ clk = of_clk_get(dev->of_node, i);
-+
-+ if (IS_ERR(clk)) {
-+ rc = PTR_ERR(clk);
-+ if (rc == -EPROBE_DEFER)
-+ goto err_out;
-+ break;
-+ }
-+ hpriv->clks[i] = clk;
-+ }
-+
-+ hpriv->phy = devm_phy_get(dev, "sata-phy");
-+ if (IS_ERR(hpriv->phy)) {
-+ rc = PTR_ERR(hpriv->phy);
-+ switch (rc) {
-+ case -ENODEV:
-+ case -ENOSYS:
-+ /* continue normally */
-+ hpriv->phy = NULL;
-+ break;
-+
-+ case -EPROBE_DEFER:
-+ goto err_out;
-+
-+ default:
-+ dev_err(dev, "couldn't get sata-phy\n");
-+ goto err_out;
-+ }
-+ }
-+
-+ pm_runtime_enable(dev);
-+ pm_runtime_get_sync(dev);
-+ hpriv->got_runtime_pm = true;
-+
-+ devres_remove_group(dev, NULL);
-+ return hpriv;
-+
-+err_out:
-+ devres_release_group(dev, NULL);
-+ return ERR_PTR(rc);
-+}
-+EXPORT_SYMBOL_GPL(ahci_platform_get_resources);
-+
-+/**
-+ * ahci_platform_init_host - Bring up an ahci-platform host
-+ * @pdev: platform device pointer for the host
-+ * @hpriv: ahci-host private data for the host
-+ * @pi_template: template for the ata_port_info to use
-+ * @force_port_map: param passed to ahci_save_initial_config
-+ * @mask_port_map: param passed to ahci_save_initial_config
-+ *
-+ * This function does all the usual steps needed to bring up an
-+ * ahci-platform host, note any necessary resources (ie clks, phy, etc.)
-+ * must be initialized / enabled before calling this.
-+ *
-+ * RETURNS:
-+ * 0 on success otherwise a negative error code
-+ */
-+int ahci_platform_init_host(struct platform_device *pdev,
-+ struct ahci_host_priv *hpriv,
-+ const struct ata_port_info *pi_template,
-+ unsigned int force_port_map,
-+ unsigned int mask_port_map)
-+{
-+ struct device *dev = &pdev->dev;
-+ struct ata_port_info pi = *pi_template;
-+ const struct ata_port_info *ppi[] = { &pi, NULL };
-+ struct ata_host *host;
-+ int i, irq, n_ports, rc;
-+
-+ irq = platform_get_irq(pdev, 0);
-+ if (irq <= 0) {
-+ dev_err(dev, "no irq\n");
-+ return -EINVAL;
-+ }
-+
-+ /* prepare host */
-+ hpriv->flags |= (unsigned long)pi.private_data;
-+
-+ ahci_save_initial_config(dev, hpriv, force_port_map, mask_port_map);
-+
-+ if (hpriv->cap & HOST_CAP_NCQ)
-+ pi.flags |= ATA_FLAG_NCQ;
-+
-+ if (hpriv->cap & HOST_CAP_PMP)
-+ pi.flags |= ATA_FLAG_PMP;
-+
-+ ahci_set_em_messages(hpriv, &pi);
-+
-+ /* CAP.NP sometimes indicate the index of the last enabled
-+ * port, at other times, that of the last possible port, so
-+ * determining the maximum port number requires looking at
-+ * both CAP.NP and port_map.
-+ */
-+ n_ports = max(ahci_nr_ports(hpriv->cap), fls(hpriv->port_map));
-+
-+ host = ata_host_alloc_pinfo(dev, ppi, n_ports);
-+ if (!host)
-+ return -ENOMEM;
-+
-+ host->private_data = hpriv;
-+
-+ if (!(hpriv->cap & HOST_CAP_SSS) || ahci_ignore_sss)
-+ host->flags |= ATA_HOST_PARALLEL_SCAN;
-+ else
-+ dev_info(dev, "SSS flag set, parallel bus scan disabled\n");
-+
-+ if (pi.flags & ATA_FLAG_EM)
-+ ahci_reset_em(host);
-+
-+ for (i = 0; i < host->n_ports; i++) {
-+ struct ata_port *ap = host->ports[i];
-+
-+ ata_port_desc(ap, "mmio %pR",
-+ platform_get_resource(pdev, IORESOURCE_MEM, 0));
-+ ata_port_desc(ap, "port 0x%x", 0x100 + ap->port_no * 0x80);
-+
-+ /* set enclosure management message type */
-+ if (ap->flags & ATA_FLAG_EM)
-+ ap->em_message_type = hpriv->em_msg_type;
-+
-+ /* disabled/not-implemented port */
-+ if (!(hpriv->port_map & (1 << i)))
-+ ap->ops = &ata_dummy_port_ops;
-+ }
-+
-+ rc = ahci_reset_controller(host);
-+ if (rc)
-+ return rc;
-+
-+ ahci_init_controller(host);
-+ ahci_print_info(host, "platform");
-+
-+ return ata_host_activate(host, irq, ahci_interrupt, IRQF_SHARED,
-+ &ahci_platform_sht);
-+}
-+EXPORT_SYMBOL_GPL(ahci_platform_init_host);
-+
-+static void ahci_host_stop(struct ata_host *host)
-+{
-+ struct device *dev = host->dev;
-+ struct ahci_platform_data *pdata = dev_get_platdata(dev);
-+ struct ahci_host_priv *hpriv = host->private_data;
-+
-+ if (pdata && pdata->exit)
-+ pdata->exit(dev);
-+
-+ ahci_platform_disable_resources(hpriv);
-+}
-+
-+#ifdef CONFIG_PM_SLEEP
-+/**
-+ * ahci_platform_suspend_host - Suspend an ahci-platform host
-+ * @dev: device pointer for the host
-+ *
-+ * This function does all the usual steps needed to suspend an
-+ * ahci-platform host, note any necessary resources (ie clks, phy, etc.)
-+ * must be disabled after calling this.
-+ *
-+ * RETURNS:
-+ * 0 on success otherwise a negative error code
-+ */
-+int ahci_platform_suspend_host(struct device *dev)
-+{
-+ struct ata_host *host = dev_get_drvdata(dev);
-+ struct ahci_host_priv *hpriv = host->private_data;
-+ void __iomem *mmio = hpriv->mmio;
-+ u32 ctl;
-+
-+ if (hpriv->flags & AHCI_HFLAG_NO_SUSPEND) {
-+ dev_err(dev, "firmware update required for suspend/resume\n");
-+ return -EIO;
-+ }
-+
-+ /*
-+ * AHCI spec rev1.1 section 8.3.3:
-+ * Software must disable interrupts prior to requesting a
-+ * transition of the HBA to D3 state.
-+ */
-+ ctl = readl(mmio + HOST_CTL);
-+ ctl &= ~HOST_IRQ_EN;
-+ writel(ctl, mmio + HOST_CTL);
-+ readl(mmio + HOST_CTL); /* flush */
-+
-+ return ata_host_suspend(host, PMSG_SUSPEND);
-+}
-+EXPORT_SYMBOL_GPL(ahci_platform_suspend_host);
-+
-+/**
-+ * ahci_platform_resume_host - Resume an ahci-platform host
-+ * @dev: device pointer for the host
-+ *
-+ * This function does all the usual steps needed to resume an ahci-platform
-+ * host, note any necessary resources (ie clks, phy, etc.) must be
-+ * initialized / enabled before calling this.
-+ *
-+ * RETURNS:
-+ * 0 on success otherwise a negative error code
-+ */
-+int ahci_platform_resume_host(struct device *dev)
-+{
-+ struct ata_host *host = dev_get_drvdata(dev);
-+ int rc;
-+
-+ if (dev->power.power_state.event == PM_EVENT_SUSPEND) {
-+ rc = ahci_reset_controller(host);
-+ if (rc)
-+ return rc;
-+
-+ ahci_init_controller(host);
-+ }
-+
-+ ata_host_resume(host);
-+
-+ return 0;
-+}
-+EXPORT_SYMBOL_GPL(ahci_platform_resume_host);
-+
-+/**
-+ * ahci_platform_suspend - Suspend an ahci-platform device
-+ * @dev: the platform device to suspend
-+ *
-+ * This function suspends the host associated with the device, followed by
-+ * disabling all the resources of the device.
-+ *
-+ * RETURNS:
-+ * 0 on success otherwise a negative error code
-+ */
-+int ahci_platform_suspend(struct device *dev)
-+{
-+ struct ahci_platform_data *pdata = dev_get_platdata(dev);
-+ struct ata_host *host = dev_get_drvdata(dev);
-+ struct ahci_host_priv *hpriv = host->private_data;
-+ int rc;
-+
-+ rc = ahci_platform_suspend_host(dev);
-+ if (rc)
-+ return rc;
-+
-+ if (pdata && pdata->suspend) {
-+ rc = pdata->suspend(dev);
-+ if (rc)
-+ goto resume_host;
-+ }
-+
-+ ahci_platform_disable_resources(hpriv);
-+
-+ return 0;
-+
-+resume_host:
-+ ahci_platform_resume_host(dev);
-+ return rc;
-+}
-+EXPORT_SYMBOL_GPL(ahci_platform_suspend);
-+
-+/**
-+ * ahci_platform_resume - Resume an ahci-platform device
-+ * @dev: the platform device to resume
-+ *
-+ * This function enables all the resources of the device followed by
-+ * resuming the host associated with the device.
-+ *
-+ * RETURNS:
-+ * 0 on success otherwise a negative error code
-+ */
-+int ahci_platform_resume(struct device *dev)
-+{
-+ struct ahci_platform_data *pdata = dev_get_platdata(dev);
-+ struct ata_host *host = dev_get_drvdata(dev);
-+ struct ahci_host_priv *hpriv = host->private_data;
-+ int rc;
-+
-+ rc = ahci_platform_enable_resources(hpriv);
-+ if (rc)
-+ return rc;
-+
-+ if (pdata && pdata->resume) {
-+ rc = pdata->resume(dev);
-+ if (rc)
-+ goto disable_resources;
-+ }
-+
-+ rc = ahci_platform_resume_host(dev);
-+ if (rc)
-+ goto disable_resources;
-+
-+ /* We resumed so update PM runtime state */
-+ pm_runtime_disable(dev);
-+ pm_runtime_set_active(dev);
-+ pm_runtime_enable(dev);
-+
-+ return 0;
-+
-+disable_resources:
-+ ahci_platform_disable_resources(hpriv);
-+
-+ return rc;
-+}
-+EXPORT_SYMBOL_GPL(ahci_platform_resume);
-+#endif
-+
-+MODULE_DESCRIPTION("AHCI SATA platform library");
-+MODULE_AUTHOR("Anton Vorontsov <avorontsov@ru.mvista.com>");
-+MODULE_LICENSE("GPL");
diff --git a/target/linux/ipq806x/patches/0125-clk-qcom-Add-support-for-IPQ8064-s-global-clock-cont.patch b/target/linux/ipq806x/patches/0125-clk-qcom-Add-support-for-IPQ8064-s-global-clock-cont.patch
deleted file mode 100644
index 4c4e263..0000000
--- a/target/linux/ipq806x/patches/0125-clk-qcom-Add-support-for-IPQ8064-s-global-clock-cont.patch
+++ /dev/null
@@ -1,2921 +0,0 @@
-From 2e6dfaa714ba4bd70fa5dda07c525b6c15e44552 Mon Sep 17 00:00:00 2001
-From: Kumar Gala <galak@codeaurora.org>
-Date: Thu, 3 Apr 2014 13:47:07 -0500
-Subject: [PATCH 125/182] clk: qcom: Add support for IPQ8064's global clock
- controller (GCC)
-
-Add a driver for the global clock controller found on IPQ8064 based
-platforms. This should allow most non-multimedia device drivers to probe
-and control their clocks.
-
-This is currently missing clocks for USB HSIC and networking devices.
-
-Signed-off-by: Kumar Gala <galak@codeaurora.org>
-Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
----
- .../devicetree/bindings/clock/qcom,gcc.txt | 1 +
- drivers/clk/qcom/Kconfig | 8 +
- drivers/clk/qcom/Makefile | 1 +
- drivers/clk/qcom/gcc-ipq806x.c | 2424 ++++++++++++++++++++
- include/dt-bindings/clock/qcom,gcc-ipq806x.h | 293 +++
- include/dt-bindings/reset/qcom,gcc-ipq806x.h | 132 ++
- 6 files changed, 2859 insertions(+)
- create mode 100644 drivers/clk/qcom/gcc-ipq806x.c
- create mode 100644 include/dt-bindings/clock/qcom,gcc-ipq806x.h
- create mode 100644 include/dt-bindings/reset/qcom,gcc-ipq806x.h
-
---- a/Documentation/devicetree/bindings/clock/qcom,gcc.txt
-+++ b/Documentation/devicetree/bindings/clock/qcom,gcc.txt
-@@ -5,6 +5,7 @@ Required properties :
- - compatible : shall contain only one of the following:
-
- "qcom,gcc-apq8064"
-+ "qcom,gcc-ipq8064"
- "qcom,gcc-msm8660"
- "qcom,gcc-msm8960"
- "qcom,gcc-msm8974"
---- a/drivers/clk/qcom/Kconfig
-+++ b/drivers/clk/qcom/Kconfig
-@@ -4,6 +4,14 @@ config COMMON_CLK_QCOM
- select REGMAP_MMIO
- select RESET_CONTROLLER
-
-+config IPQ_GCC_806X
-+ tristate "IPQ806x Global Clock Controller"
-+ depends on COMMON_CLK_QCOM
-+ help
-+ Support for the global clock controller on ipq806x devices.
-+ Say Y if you want to use peripheral devices such as UART, SPI,
-+ i2c, USB, SD/eMMC, etc.
-+
- config MSM_GCC_8660
- tristate "MSM8660 Global Clock Controller"
- depends on COMMON_CLK_QCOM
---- a/drivers/clk/qcom/Makefile
-+++ b/drivers/clk/qcom/Makefile
-@@ -8,6 +8,7 @@ clk-qcom-y += clk-rcg2.o
- clk-qcom-y += clk-branch.o
- clk-qcom-y += reset.o
-
-+obj-$(CONFIG_IPQ_GCC_806X) += gcc-ipq806x.o
- obj-$(CONFIG_MSM_GCC_8660) += gcc-msm8660.o
- obj-$(CONFIG_MSM_GCC_8960) += gcc-msm8960.o
- obj-$(CONFIG_MSM_GCC_8974) += gcc-msm8974.o
---- /dev/null
-+++ b/drivers/clk/qcom/gcc-ipq806x.c
-@@ -0,0 +1,2424 @@
-+/*
-+ * Copyright (c) 2014, The Linux Foundation. All rights reserved.
-+ *
-+ * This software is licensed under the terms of the GNU General Public
-+ * License version 2, as published by the Free Software Foundation, and
-+ * may be copied, distributed, and modified under those terms.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ * GNU General Public License for more details.
-+ */
-+
-+#include <linux/kernel.h>
-+#include <linux/bitops.h>
-+#include <linux/err.h>
-+#include <linux/platform_device.h>
-+#include <linux/module.h>
-+#include <linux/of.h>
-+#include <linux/of_device.h>
-+#include <linux/clk-provider.h>
-+#include <linux/regmap.h>
-+#include <linux/reset-controller.h>
-+
-+#include <dt-bindings/clock/qcom,gcc-ipq806x.h>
-+#include <dt-bindings/reset/qcom,gcc-ipq806x.h>
-+
-+#include "common.h"
-+#include "clk-regmap.h"
-+#include "clk-pll.h"
-+#include "clk-rcg.h"
-+#include "clk-branch.h"
-+#include "reset.h"
-+
-+static struct clk_pll pll3 = {
-+ .l_reg = 0x3164,
-+ .m_reg = 0x3168,
-+ .n_reg = 0x316c,
-+ .config_reg = 0x3174,
-+ .mode_reg = 0x3160,
-+ .status_reg = 0x3178,
-+ .status_bit = 16,
-+ .clkr.hw.init = &(struct clk_init_data){
-+ .name = "pll3",
-+ .parent_names = (const char *[]){ "pxo" },
-+ .num_parents = 1,
-+ .ops = &clk_pll_ops,
-+ },
-+};
-+
-+static struct clk_pll pll8 = {
-+ .l_reg = 0x3144,
-+ .m_reg = 0x3148,
-+ .n_reg = 0x314c,
-+ .config_reg = 0x3154,
-+ .mode_reg = 0x3140,
-+ .status_reg = 0x3158,
-+ .status_bit = 16,
-+ .clkr.hw.init = &(struct clk_init_data){
-+ .name = "pll8",
-+ .parent_names = (const char *[]){ "pxo" },
-+ .num_parents = 1,
-+ .ops = &clk_pll_ops,
-+ },
-+};
-+
-+static struct clk_regmap pll8_vote = {
-+ .enable_reg = 0x34c0,
-+ .enable_mask = BIT(8),
-+ .hw.init = &(struct clk_init_data){
-+ .name = "pll8_vote",
-+ .parent_names = (const char *[]){ "pll8" },
-+ .num_parents = 1,
-+ .ops = &clk_pll_vote_ops,
-+ },
-+};
-+
-+static struct clk_pll pll14 = {
-+ .l_reg = 0x31c4,
-+ .m_reg = 0x31c8,
-+ .n_reg = 0x31cc,
-+ .config_reg = 0x31d4,
-+ .mode_reg = 0x31c0,
-+ .status_reg = 0x31d8,
-+ .status_bit = 16,
-+ .clkr.hw.init = &(struct clk_init_data){
-+ .name = "pll14",
-+ .parent_names = (const char *[]){ "pxo" },
-+ .num_parents = 1,
-+ .ops = &clk_pll_ops,
-+ },
-+};
-+
-+static struct clk_regmap pll14_vote = {
-+ .enable_reg = 0x34c0,
-+ .enable_mask = BIT(14),
-+ .hw.init = &(struct clk_init_data){
-+ .name = "pll14_vote",
-+ .parent_names = (const char *[]){ "pll14" },
-+ .num_parents = 1,
-+ .ops = &clk_pll_vote_ops,
-+ },
-+};
-+
-+#define P_PXO 0
-+#define P_PLL8 1
-+#define P_PLL3 1
-+#define P_PLL0 2
-+#define P_CXO 2
-+
-+static const u8 gcc_pxo_pll8_map[] = {
-+ [P_PXO] = 0,
-+ [P_PLL8] = 3,
-+};
-+
-+static const char *gcc_pxo_pll8[] = {
-+ "pxo",
-+ "pll8_vote",
-+};
-+
-+static const u8 gcc_pxo_pll8_cxo_map[] = {
-+ [P_PXO] = 0,
-+ [P_PLL8] = 3,
-+ [P_CXO] = 5,
-+};
-+
-+static const char *gcc_pxo_pll8_cxo[] = {
-+ "pxo",
-+ "pll8_vote",
-+ "cxo",
-+};
-+
-+static const u8 gcc_pxo_pll3_map[] = {
-+ [P_PXO] = 0,
-+ [P_PLL3] = 1,
-+};
-+
-+static const u8 gcc_pxo_pll3_sata_map[] = {
-+ [P_PXO] = 0,
-+ [P_PLL3] = 6,
-+};
-+
-+static const char *gcc_pxo_pll3[] = {
-+ "pxo",
-+ "pll3",
-+};
-+
-+static const u8 gcc_pxo_pll8_pll0[] = {
-+ [P_PXO] = 0,
-+ [P_PLL8] = 3,
-+ [P_PLL0] = 2,
-+};
-+
-+static const char *gcc_pxo_pll8_pll0_map[] = {
-+ "pxo",
-+ "pll8_vote",
-+ "pll0",
-+};
-+
-+static struct freq_tbl clk_tbl_gsbi_uart[] = {
-+ { 1843200, P_PLL8, 2, 6, 625 },
-+ { 3686400, P_PLL8, 2, 12, 625 },
-+ { 7372800, P_PLL8, 2, 24, 625 },
-+ { 14745600, P_PLL8, 2, 48, 625 },
-+ { 16000000, P_PLL8, 4, 1, 6 },
-+ { 24000000, P_PLL8, 4, 1, 4 },
-+ { 32000000, P_PLL8, 4, 1, 3 },
-+ { 40000000, P_PLL8, 1, 5, 48 },
-+ { 46400000, P_PLL8, 1, 29, 240 },
-+ { 48000000, P_PLL8, 4, 1, 2 },
-+ { 51200000, P_PLL8, 1, 2, 15 },
-+ { 56000000, P_PLL8, 1, 7, 48 },
-+ { 58982400, P_PLL8, 1, 96, 625 },
-+ { 64000000, P_PLL8, 2, 1, 3 },
-+ { }
-+};
-+
-+static struct clk_rcg gsbi1_uart_src = {
-+ .ns_reg = 0x29d4,
-+ .md_reg = 0x29d0,
-+ .mn = {
-+ .mnctr_en_bit = 8,
-+ .mnctr_reset_bit = 7,
-+ .mnctr_mode_shift = 5,
-+ .n_val_shift = 16,
-+ .m_val_shift = 16,
-+ .width = 16,
-+ },
-+ .p = {
-+ .pre_div_shift = 3,
-+ .pre_div_width = 2,
-+ },
-+ .s = {
-+ .src_sel_shift = 0,
-+ .parent_map = gcc_pxo_pll8_map,
-+ },
-+ .freq_tbl = clk_tbl_gsbi_uart,
-+ .clkr = {
-+ .enable_reg = 0x29d4,
-+ .enable_mask = BIT(11),
-+ .hw.init = &(struct clk_init_data){
-+ .name = "gsbi1_uart_src",
-+ .parent_names = gcc_pxo_pll8,
-+ .num_parents = 2,
-+ .ops = &clk_rcg_ops,
-+ .flags = CLK_SET_PARENT_GATE,
-+ },
-+ },
-+};
-+
-+static struct clk_branch gsbi1_uart_clk = {
-+ .halt_reg = 0x2fcc,
-+ .halt_bit = 12,
-+ .clkr = {
-+ .enable_reg = 0x29d4,
-+ .enable_mask = BIT(9),
-+ .hw.init = &(struct clk_init_data){
-+ .name = "gsbi1_uart_clk",
-+ .parent_names = (const char *[]){
-+ "gsbi1_uart_src",
-+ },
-+ .num_parents = 1,
-+ .ops = &clk_branch_ops,
-+ .flags = CLK_SET_RATE_PARENT,
-+ },
-+ },
-+};
-+
-+static struct clk_rcg gsbi2_uart_src = {
-+ .ns_reg = 0x29f4,
-+ .md_reg = 0x29f0,
-+ .mn = {
-+ .mnctr_en_bit = 8,
-+ .mnctr_reset_bit = 7,
-+ .mnctr_mode_shift = 5,
-+ .n_val_shift = 16,
-+ .m_val_shift = 16,
-+ .width = 16,
-+ },
-+ .p = {
-+ .pre_div_shift = 3,
-+ .pre_div_width = 2,
-+ },
-+ .s = {
-+ .src_sel_shift = 0,
-+ .parent_map = gcc_pxo_pll8_map,
-+ },
-+ .freq_tbl = clk_tbl_gsbi_uart,
-+ .clkr = {
-+ .enable_reg = 0x29f4,
-+ .enable_mask = BIT(11),
-+ .hw.init = &(struct clk_init_data){
-+ .name = "gsbi2_uart_src",
-+ .parent_names = gcc_pxo_pll8,
-+ .num_parents = 2,
-+ .ops = &clk_rcg_ops,
-+ .flags = CLK_SET_PARENT_GATE,
-+ },
-+ },
-+};
-+
-+static struct clk_branch gsbi2_uart_clk = {
-+ .halt_reg = 0x2fcc,
-+ .halt_bit = 8,
-+ .clkr = {
-+ .enable_reg = 0x29f4,
-+ .enable_mask = BIT(9),
-+ .hw.init = &(struct clk_init_data){
-+ .name = "gsbi2_uart_clk",
-+ .parent_names = (const char *[]){
-+ "gsbi2_uart_src",
-+ },
-+ .num_parents = 1,
-+ .ops = &clk_branch_ops,
-+ .flags = CLK_SET_RATE_PARENT,
-+ },
-+ },
-+};
-+
-+static struct clk_rcg gsbi4_uart_src = {
-+ .ns_reg = 0x2a34,
-+ .md_reg = 0x2a30,
-+ .mn = {
-+ .mnctr_en_bit = 8,
-+ .mnctr_reset_bit = 7,
-+ .mnctr_mode_shift = 5,
-+ .n_val_shift = 16,
-+ .m_val_shift = 16,
-+ .width = 16,
-+ },
-+ .p = {
-+ .pre_div_shift = 3,
-+ .pre_div_width = 2,
-+ },
-+ .s = {
-+ .src_sel_shift = 0,
-+ .parent_map = gcc_pxo_pll8_map,
-+ },
-+ .freq_tbl = clk_tbl_gsbi_uart,
-+ .clkr = {
-+ .enable_reg = 0x2a34,
-+ .enable_mask = BIT(11),
-+ .hw.init = &(struct clk_init_data){
-+ .name = "gsbi4_uart_src",
-+ .parent_names = gcc_pxo_pll8,
-+ .num_parents = 2,
-+ .ops = &clk_rcg_ops,
-+ .flags = CLK_SET_PARENT_GATE,
-+ },
-+ },
-+};
-+
-+static struct clk_branch gsbi4_uart_clk = {
-+ .halt_reg = 0x2fd0,
-+ .halt_bit = 26,
-+ .clkr = {
-+ .enable_reg = 0x2a34,
-+ .enable_mask = BIT(9),
-+ .hw.init = &(struct clk_init_data){
-+ .name = "gsbi4_uart_clk",
-+ .parent_names = (const char *[]){
-+ "gsbi4_uart_src",
-+ },
-+ .num_parents = 1,
-+ .ops = &clk_branch_ops,
-+ .flags = CLK_SET_RATE_PARENT,
-+ },
-+ },
-+};
-+
-+static struct clk_rcg gsbi5_uart_src = {
-+ .ns_reg = 0x2a54,
-+ .md_reg = 0x2a50,
-+ .mn = {
-+ .mnctr_en_bit = 8,
-+ .mnctr_reset_bit = 7,
-+ .mnctr_mode_shift = 5,
-+ .n_val_shift = 16,
-+ .m_val_shift = 16,
-+ .width = 16,
-+ },
-+ .p = {
-+ .pre_div_shift = 3,
-+ .pre_div_width = 2,
-+ },
-+ .s = {
-+ .src_sel_shift = 0,
-+ .parent_map = gcc_pxo_pll8_map,
-+ },
-+ .freq_tbl = clk_tbl_gsbi_uart,
-+ .clkr = {
-+ .enable_reg = 0x2a54,
-+ .enable_mask = BIT(11),
-+ .hw.init = &(struct clk_init_data){
-+ .name = "gsbi5_uart_src",
-+ .parent_names = gcc_pxo_pll8,
-+ .num_parents = 2,
-+ .ops = &clk_rcg_ops,
-+ .flags = CLK_SET_PARENT_GATE,
-+ },
-+ },
-+};
-+
-+static struct clk_branch gsbi5_uart_clk = {
-+ .halt_reg = 0x2fd0,
-+ .halt_bit = 22,
-+ .clkr = {
-+ .enable_reg = 0x2a54,
-+ .enable_mask = BIT(9),
-+ .hw.init = &(struct clk_init_data){
-+ .name = "gsbi5_uart_clk",
-+ .parent_names = (const char *[]){
-+ "gsbi5_uart_src",
-+ },
-+ .num_parents = 1,
-+ .ops = &clk_branch_ops,
-+ .flags = CLK_SET_RATE_PARENT,
-+ },
-+ },
-+};
-+
-+static struct clk_rcg gsbi6_uart_src = {
-+ .ns_reg = 0x2a74,
-+ .md_reg = 0x2a70,
-+ .mn = {
-+ .mnctr_en_bit = 8,
-+ .mnctr_reset_bit = 7,
-+ .mnctr_mode_shift = 5,
-+ .n_val_shift = 16,
-+ .m_val_shift = 16,
-+ .width = 16,
-+ },
-+ .p = {
-+ .pre_div_shift = 3,
-+ .pre_div_width = 2,
-+ },
-+ .s = {
-+ .src_sel_shift = 0,
-+ .parent_map = gcc_pxo_pll8_map,
-+ },
-+ .freq_tbl = clk_tbl_gsbi_uart,
-+ .clkr = {
-+ .enable_reg = 0x2a74,
-+ .enable_mask = BIT(11),
-+ .hw.init = &(struct clk_init_data){
-+ .name = "gsbi6_uart_src",
-+ .parent_names = gcc_pxo_pll8,
-+ .num_parents = 2,
-+ .ops = &clk_rcg_ops,
-+ .flags = CLK_SET_PARENT_GATE,
-+ },
-+ },
-+};
-+
-+static struct clk_branch gsbi6_uart_clk = {
-+ .halt_reg = 0x2fd0,
-+ .halt_bit = 18,
-+ .clkr = {
-+ .enable_reg = 0x2a74,
-+ .enable_mask = BIT(9),
-+ .hw.init = &(struct clk_init_data){
-+ .name = "gsbi6_uart_clk",
-+ .parent_names = (const char *[]){
-+ "gsbi6_uart_src",
-+ },
-+ .num_parents = 1,
-+ .ops = &clk_branch_ops,
-+ .flags = CLK_SET_RATE_PARENT,
-+ },
-+ },
-+};
-+
-+static struct clk_rcg gsbi7_uart_src = {
-+ .ns_reg = 0x2a94,
-+ .md_reg = 0x2a90,
-+ .mn = {
-+ .mnctr_en_bit = 8,
-+ .mnctr_reset_bit = 7,
-+ .mnctr_mode_shift = 5,
-+ .n_val_shift = 16,
-+ .m_val_shift = 16,
-+ .width = 16,
-+ },
-+ .p = {
-+ .pre_div_shift = 3,
-+ .pre_div_width = 2,
-+ },
-+ .s = {
-+ .src_sel_shift = 0,
-+ .parent_map = gcc_pxo_pll8_map,
-+ },
-+ .freq_tbl = clk_tbl_gsbi_uart,
-+ .clkr = {
-+ .enable_reg = 0x2a94,
-+ .enable_mask = BIT(11),
-+ .hw.init = &(struct clk_init_data){
-+ .name = "gsbi7_uart_src",
-+ .parent_names = gcc_pxo_pll8,
-+ .num_parents = 2,
-+ .ops = &clk_rcg_ops,
-+ .flags = CLK_SET_PARENT_GATE,
-+ },
-+ },
-+};
-+
-+static struct clk_branch gsbi7_uart_clk = {
-+ .halt_reg = 0x2fd0,
-+ .halt_bit = 14,
-+ .clkr = {
-+ .enable_reg = 0x2a94,
-+ .enable_mask = BIT(9),
-+ .hw.init = &(struct clk_init_data){
-+ .name = "gsbi7_uart_clk",
-+ .parent_names = (const char *[]){
-+ "gsbi7_uart_src",
-+ },
-+ .num_parents = 1,
-+ .ops = &clk_branch_ops,
-+ .flags = CLK_SET_RATE_PARENT,
-+ },
-+ },
-+};
-+
-+static struct freq_tbl clk_tbl_gsbi_qup[] = {
-+ { 1100000, P_PXO, 1, 2, 49 },
-+ { 5400000, P_PXO, 1, 1, 5 },
-+ { 10800000, P_PXO, 1, 2, 5 },
-+ { 15060000, P_PLL8, 1, 2, 51 },
-+ { 24000000, P_PLL8, 4, 1, 4 },
-+ { 25600000, P_PLL8, 1, 1, 15 },
-+ { 27000000, P_PXO, 1, 0, 0 },
-+ { 48000000, P_PLL8, 4, 1, 2 },
-+ { 51200000, P_PLL8, 1, 2, 15 },
-+ { }
-+};
-+
-+static struct clk_rcg gsbi1_qup_src = {
-+ .ns_reg = 0x29cc,
-+ .md_reg = 0x29c8,
-+ .mn = {
-+ .mnctr_en_bit = 8,
-+ .mnctr_reset_bit = 7,
-+ .mnctr_mode_shift = 5,
-+ .n_val_shift = 16,
-+ .m_val_shift = 16,
-+ .width = 8,
-+ },
-+ .p = {
-+ .pre_div_shift = 3,
-+ .pre_div_width = 2,
-+ },
-+ .s = {
-+ .src_sel_shift = 0,
-+ .parent_map = gcc_pxo_pll8_map,
-+ },
-+ .freq_tbl = clk_tbl_gsbi_qup,
-+ .clkr = {
-+ .enable_reg = 0x29cc,
-+ .enable_mask = BIT(11),
-+ .hw.init = &(struct clk_init_data){
-+ .name = "gsbi1_qup_src",
-+ .parent_names = gcc_pxo_pll8,
-+ .num_parents = 2,
-+ .ops = &clk_rcg_ops,
-+ .flags = CLK_SET_PARENT_GATE,
-+ },
-+ },
-+};
-+
-+static struct clk_branch gsbi1_qup_clk = {
-+ .halt_reg = 0x2fcc,
-+ .halt_bit = 11,
-+ .clkr = {
-+ .enable_reg = 0x29cc,
-+ .enable_mask = BIT(9),
-+ .hw.init = &(struct clk_init_data){
-+ .name = "gsbi1_qup_clk",
-+ .parent_names = (const char *[]){ "gsbi1_qup_src" },
-+ .num_parents = 1,
-+ .ops = &clk_branch_ops,
-+ .flags = CLK_SET_RATE_PARENT,
-+ },
-+ },
-+};
-+
-+static struct clk_rcg gsbi2_qup_src = {
-+ .ns_reg = 0x29ec,
-+ .md_reg = 0x29e8,
-+ .mn = {
-+ .mnctr_en_bit = 8,
-+ .mnctr_reset_bit = 7,
-+ .mnctr_mode_shift = 5,
-+ .n_val_shift = 16,
-+ .m_val_shift = 16,
-+ .width = 8,
-+ },
-+ .p = {
-+ .pre_div_shift = 3,
-+ .pre_div_width = 2,
-+ },
-+ .s = {
-+ .src_sel_shift = 0,
-+ .parent_map = gcc_pxo_pll8_map,
-+ },
-+ .freq_tbl = clk_tbl_gsbi_qup,
-+ .clkr = {
-+ .enable_reg = 0x29ec,
-+ .enable_mask = BIT(11),
-+ .hw.init = &(struct clk_init_data){
-+ .name = "gsbi2_qup_src",
-+ .parent_names = gcc_pxo_pll8,
-+ .num_parents = 2,
-+ .ops = &clk_rcg_ops,
-+ .flags = CLK_SET_PARENT_GATE,
-+ },
-+ },
-+};
-+
-+static struct clk_branch gsbi2_qup_clk = {
-+ .halt_reg = 0x2fcc,
-+ .halt_bit = 6,
-+ .clkr = {
-+ .enable_reg = 0x29ec,
-+ .enable_mask = BIT(9),
-+ .hw.init = &(struct clk_init_data){
-+ .name = "gsbi2_qup_clk",
-+ .parent_names = (const char *[]){ "gsbi2_qup_src" },
-+ .num_parents = 1,
-+ .ops = &clk_branch_ops,
-+ .flags = CLK_SET_RATE_PARENT,
-+ },
-+ },
-+};
-+
-+static struct clk_rcg gsbi4_qup_src = {
-+ .ns_reg = 0x2a2c,
-+ .md_reg = 0x2a28,
-+ .mn = {
-+ .mnctr_en_bit = 8,
-+ .mnctr_reset_bit = 7,
-+ .mnctr_mode_shift = 5,
-+ .n_val_shift = 16,
-+ .m_val_shift = 16,
-+ .width = 8,
-+ },
-+ .p = {
-+ .pre_div_shift = 3,
-+ .pre_div_width = 2,
-+ },
-+ .s = {
-+ .src_sel_shift = 0,
-+ .parent_map = gcc_pxo_pll8_map,
-+ },
-+ .freq_tbl = clk_tbl_gsbi_qup,
-+ .clkr = {
-+ .enable_reg = 0x2a2c,
-+ .enable_mask = BIT(11),
-+ .hw.init = &(struct clk_init_data){
-+ .name = "gsbi4_qup_src",
-+ .parent_names = gcc_pxo_pll8,
-+ .num_parents = 2,
-+ .ops = &clk_rcg_ops,
-+ .flags = CLK_SET_PARENT_GATE,
-+ },
-+ },
-+};
-+
-+static struct clk_branch gsbi4_qup_clk = {
-+ .halt_reg = 0x2fd0,
-+ .halt_bit = 24,
-+ .clkr = {
-+ .enable_reg = 0x2a2c,
-+ .enable_mask = BIT(9),
-+ .hw.init = &(struct clk_init_data){
-+ .name = "gsbi4_qup_clk",
-+ .parent_names = (const char *[]){ "gsbi4_qup_src" },
-+ .num_parents = 1,
-+ .ops = &clk_branch_ops,
-+ .flags = CLK_SET_RATE_PARENT,
-+ },
-+ },
-+};
-+
-+static struct clk_rcg gsbi5_qup_src = {
-+ .ns_reg = 0x2a4c,
-+ .md_reg = 0x2a48,
-+ .mn = {
-+ .mnctr_en_bit = 8,
-+ .mnctr_reset_bit = 7,
-+ .mnctr_mode_shift = 5,
-+ .n_val_shift = 16,
-+ .m_val_shift = 16,
-+ .width = 8,
-+ },
-+ .p = {
-+ .pre_div_shift = 3,
-+ .pre_div_width = 2,
-+ },
-+ .s = {
-+ .src_sel_shift = 0,
-+ .parent_map = gcc_pxo_pll8_map,
-+ },
-+ .freq_tbl = clk_tbl_gsbi_qup,
-+ .clkr = {
-+ .enable_reg = 0x2a4c,
-+ .enable_mask = BIT(11),
-+ .hw.init = &(struct clk_init_data){
-+ .name = "gsbi5_qup_src",
-+ .parent_names = gcc_pxo_pll8,
-+ .num_parents = 2,
-+ .ops = &clk_rcg_ops,
-+ .flags = CLK_SET_PARENT_GATE,
-+ },
-+ },
-+};
-+
-+static struct clk_branch gsbi5_qup_clk = {
-+ .halt_reg = 0x2fd0,
-+ .halt_bit = 20,
-+ .clkr = {
-+ .enable_reg = 0x2a4c,
-+ .enable_mask = BIT(9),
-+ .hw.init = &(struct clk_init_data){
-+ .name = "gsbi5_qup_clk",
-+ .parent_names = (const char *[]){ "gsbi5_qup_src" },
-+ .num_parents = 1,
-+ .ops = &clk_branch_ops,
-+ .flags = CLK_SET_RATE_PARENT,
-+ },
-+ },
-+};
-+
-+static struct clk_rcg gsbi6_qup_src = {
-+ .ns_reg = 0x2a6c,
-+ .md_reg = 0x2a68,
-+ .mn = {
-+ .mnctr_en_bit = 8,
-+ .mnctr_reset_bit = 7,
-+ .mnctr_mode_shift = 5,
-+ .n_val_shift = 16,
-+ .m_val_shift = 16,
-+ .width = 8,
-+ },
-+ .p = {
-+ .pre_div_shift = 3,
-+ .pre_div_width = 2,
-+ },
-+ .s = {
-+ .src_sel_shift = 0,
-+ .parent_map = gcc_pxo_pll8_map,
-+ },
-+ .freq_tbl = clk_tbl_gsbi_qup,
-+ .clkr = {
-+ .enable_reg = 0x2a6c,
-+ .enable_mask = BIT(11),
-+ .hw.init = &(struct clk_init_data){
-+ .name = "gsbi6_qup_src",
-+ .parent_names = gcc_pxo_pll8,
-+ .num_parents = 2,
-+ .ops = &clk_rcg_ops,
-+ .flags = CLK_SET_PARENT_GATE,
-+ },
-+ },
-+};
-+
-+static struct clk_branch gsbi6_qup_clk = {
-+ .halt_reg = 0x2fd0,
-+ .halt_bit = 16,
-+ .clkr = {
-+ .enable_reg = 0x2a6c,
-+ .enable_mask = BIT(9),
-+ .hw.init = &(struct clk_init_data){
-+ .name = "gsbi6_qup_clk",
-+ .parent_names = (const char *[]){ "gsbi6_qup_src" },
-+ .num_parents = 1,
-+ .ops = &clk_branch_ops,
-+ .flags = CLK_SET_RATE_PARENT,
-+ },
-+ },
-+};
-+
-+static struct clk_rcg gsbi7_qup_src = {
-+ .ns_reg = 0x2a8c,
-+ .md_reg = 0x2a88,
-+ .mn = {
-+ .mnctr_en_bit = 8,
-+ .mnctr_reset_bit = 7,
-+ .mnctr_mode_shift = 5,
-+ .n_val_shift = 16,
-+ .m_val_shift = 16,
-+ .width = 8,
-+ },
-+ .p = {
-+ .pre_div_shift = 3,
-+ .pre_div_width = 2,
-+ },
-+ .s = {
-+ .src_sel_shift = 0,
-+ .parent_map = gcc_pxo_pll8_map,
-+ },
-+ .freq_tbl = clk_tbl_gsbi_qup,
-+ .clkr = {
-+ .enable_reg = 0x2a8c,
-+ .enable_mask = BIT(11),
-+ .hw.init = &(struct clk_init_data){
-+ .name = "gsbi7_qup_src",
-+ .parent_names = gcc_pxo_pll8,
-+ .num_parents = 2,
-+ .ops = &clk_rcg_ops,
-+ .flags = CLK_SET_PARENT_GATE,
-+ },
-+ },
-+};
-+
-+static struct clk_branch gsbi7_qup_clk = {
-+ .halt_reg = 0x2fd0,
-+ .halt_bit = 12,
-+ .clkr = {
-+ .enable_reg = 0x2a8c,
-+ .enable_mask = BIT(9),
-+ .hw.init = &(struct clk_init_data){
-+ .name = "gsbi7_qup_clk",
-+ .parent_names = (const char *[]){ "gsbi7_qup_src" },
-+ .num_parents = 1,
-+ .ops = &clk_branch_ops,
-+ .flags = CLK_SET_RATE_PARENT,
-+ },
-+ },
-+};
-+
-+static struct clk_branch gsbi1_h_clk = {
-+ .hwcg_reg = 0x29c0,
-+ .hwcg_bit = 6,
-+ .halt_reg = 0x2fcc,
-+ .halt_bit = 13,
-+ .clkr = {
-+ .enable_reg = 0x29c0,
-+ .enable_mask = BIT(4),
-+ .hw.init = &(struct clk_init_data){
-+ .name = "gsbi1_h_clk",
-+ .ops = &clk_branch_ops,
-+ .flags = CLK_IS_ROOT,
-+ },
-+ },
-+};
-+
-+static struct clk_branch gsbi2_h_clk = {
-+ .hwcg_reg = 0x29e0,
-+ .hwcg_bit = 6,
-+ .halt_reg = 0x2fcc,
-+ .halt_bit = 9,
-+ .clkr = {
-+ .enable_reg = 0x29e0,
-+ .enable_mask = BIT(4),
-+ .hw.init = &(struct clk_init_data){
-+ .name = "gsbi2_h_clk",
-+ .ops = &clk_branch_ops,
-+ .flags = CLK_IS_ROOT,
-+ },
-+ },
-+};
-+
-+static struct clk_branch gsbi4_h_clk = {
-+ .hwcg_reg = 0x2a20,
-+ .hwcg_bit = 6,
-+ .halt_reg = 0x2fd0,
-+ .halt_bit = 27,
-+ .clkr = {
-+ .enable_reg = 0x2a20,
-+ .enable_mask = BIT(4),
-+ .hw.init = &(struct clk_init_data){
-+ .name = "gsbi4_h_clk",
-+ .ops = &clk_branch_ops,
-+ .flags = CLK_IS_ROOT,
-+ },
-+ },
-+};
-+
-+static struct clk_branch gsbi5_h_clk = {
-+ .hwcg_reg = 0x2a40,
-+ .hwcg_bit = 6,
-+ .halt_reg = 0x2fd0,
-+ .halt_bit = 23,
-+ .clkr = {
-+ .enable_reg = 0x2a40,
-+ .enable_mask = BIT(4),
-+ .hw.init = &(struct clk_init_data){
-+ .name = "gsbi5_h_clk",
-+ .ops = &clk_branch_ops,
-+ .flags = CLK_IS_ROOT,
-+ },
-+ },
-+};
-+
-+static struct clk_branch gsbi6_h_clk = {
-+ .hwcg_reg = 0x2a60,
-+ .hwcg_bit = 6,
-+ .halt_reg = 0x2fd0,
-+ .halt_bit = 19,
-+ .clkr = {
-+ .enable_reg = 0x2a60,
-+ .enable_mask = BIT(4),
-+ .hw.init = &(struct clk_init_data){
-+ .name = "gsbi6_h_clk",
-+ .ops = &clk_branch_ops,
-+ .flags = CLK_IS_ROOT,
-+ },
-+ },
-+};
-+
-+static struct clk_branch gsbi7_h_clk = {
-+ .hwcg_reg = 0x2a80,
-+ .hwcg_bit = 6,
-+ .halt_reg = 0x2fd0,
-+ .halt_bit = 15,
-+ .clkr = {
-+ .enable_reg = 0x2a80,
-+ .enable_mask = BIT(4),
-+ .hw.init = &(struct clk_init_data){
-+ .name = "gsbi7_h_clk",
-+ .ops = &clk_branch_ops,
-+ .flags = CLK_IS_ROOT,
-+ },
-+ },
-+};
-+
-+static const struct freq_tbl clk_tbl_gp[] = {
-+ { 12500000, P_PXO, 2, 0, 0 },
-+ { 25000000, P_PXO, 1, 0, 0 },
-+ { 64000000, P_PLL8, 2, 1, 3 },
-+ { 76800000, P_PLL8, 1, 1, 5 },
-+ { 96000000, P_PLL8, 4, 0, 0 },
-+ { 128000000, P_PLL8, 3, 0, 0 },
-+ { 192000000, P_PLL8, 2, 0, 0 },
-+ { }
-+};
-+
-+static struct clk_rcg gp0_src = {
-+ .ns_reg = 0x2d24,
-+ .md_reg = 0x2d00,
-+ .mn = {
-+ .mnctr_en_bit = 8,
-+ .mnctr_reset_bit = 7,
-+ .mnctr_mode_shift = 5,
-+ .n_val_shift = 16,
-+ .m_val_shift = 16,
-+ .width = 8,
-+ },
-+ .p = {
-+ .pre_div_shift = 3,
-+ .pre_div_width = 2,
-+ },
-+ .s = {
-+ .src_sel_shift = 0,
-+ .parent_map = gcc_pxo_pll8_cxo_map,
-+ },
-+ .freq_tbl = clk_tbl_gp,
-+ .clkr = {
-+ .enable_reg = 0x2d24,
-+ .enable_mask = BIT(11),
-+ .hw.init = &(struct clk_init_data){
-+ .name = "gp0_src",
-+ .parent_names = gcc_pxo_pll8_cxo,
-+ .num_parents = 3,
-+ .ops = &clk_rcg_ops,
-+ .flags = CLK_SET_PARENT_GATE,
-+ },
-+ }
-+};
-+
-+static struct clk_branch gp0_clk = {
-+ .halt_reg = 0x2fd8,
-+ .halt_bit = 7,
-+ .clkr = {
-+ .enable_reg = 0x2d24,
-+ .enable_mask = BIT(9),
-+ .hw.init = &(struct clk_init_data){
-+ .name = "gp0_clk",
-+ .parent_names = (const char *[]){ "gp0_src" },
-+ .num_parents = 1,
-+ .ops = &clk_branch_ops,
-+ .flags = CLK_SET_RATE_PARENT,
-+ },
-+ },
-+};
-+
-+static struct clk_rcg gp1_src = {
-+ .ns_reg = 0x2d44,
-+ .md_reg = 0x2d40,
-+ .mn = {
-+ .mnctr_en_bit = 8,
-+ .mnctr_reset_bit = 7,
-+ .mnctr_mode_shift = 5,
-+ .n_val_shift = 16,
-+ .m_val_shift = 16,
-+ .width = 8,
-+ },
-+ .p = {
-+ .pre_div_shift = 3,
-+ .pre_div_width = 2,
-+ },
-+ .s = {
-+ .src_sel_shift = 0,
-+ .parent_map = gcc_pxo_pll8_cxo_map,
-+ },
-+ .freq_tbl = clk_tbl_gp,
-+ .clkr = {
-+ .enable_reg = 0x2d44,
-+ .enable_mask = BIT(11),
-+ .hw.init = &(struct clk_init_data){
-+ .name = "gp1_src",
-+ .parent_names = gcc_pxo_pll8_cxo,
-+ .num_parents = 3,
-+ .ops = &clk_rcg_ops,
-+ .flags = CLK_SET_RATE_GATE,
-+ },
-+ }
-+};
-+
-+static struct clk_branch gp1_clk = {
-+ .halt_reg = 0x2fd8,
-+ .halt_bit = 6,
-+ .clkr = {
-+ .enable_reg = 0x2d44,
-+ .enable_mask = BIT(9),
-+ .hw.init = &(struct clk_init_data){
-+ .name = "gp1_clk",
-+ .parent_names = (const char *[]){ "gp1_src" },
-+ .num_parents = 1,
-+ .ops = &clk_branch_ops,
-+ .flags = CLK_SET_RATE_PARENT,
-+ },
-+ },
-+};
-+
-+static struct clk_rcg gp2_src = {
-+ .ns_reg = 0x2d64,
-+ .md_reg = 0x2d60,
-+ .mn = {
-+ .mnctr_en_bit = 8,
-+ .mnctr_reset_bit = 7,
-+ .mnctr_mode_shift = 5,
-+ .n_val_shift = 16,
-+ .m_val_shift = 16,
-+ .width = 8,
-+ },
-+ .p = {
-+ .pre_div_shift = 3,
-+ .pre_div_width = 2,
-+ },
-+ .s = {
-+ .src_sel_shift = 0,
-+ .parent_map = gcc_pxo_pll8_cxo_map,
-+ },
-+ .freq_tbl = clk_tbl_gp,
-+ .clkr = {
-+ .enable_reg = 0x2d64,
-+ .enable_mask = BIT(11),
-+ .hw.init = &(struct clk_init_data){
-+ .name = "gp2_src",
-+ .parent_names = gcc_pxo_pll8_cxo,
-+ .num_parents = 3,
-+ .ops = &clk_rcg_ops,
-+ .flags = CLK_SET_RATE_GATE,
-+ },
-+ }
-+};
-+
-+static struct clk_branch gp2_clk = {
-+ .halt_reg = 0x2fd8,
-+ .halt_bit = 5,
-+ .clkr = {
-+ .enable_reg = 0x2d64,
-+ .enable_mask = BIT(9),
-+ .hw.init = &(struct clk_init_data){
-+ .name = "gp2_clk",
-+ .parent_names = (const char *[]){ "gp2_src" },
-+ .num_parents = 1,
-+ .ops = &clk_branch_ops,
-+ .flags = CLK_SET_RATE_PARENT,
-+ },
-+ },
-+};
-+
-+static struct clk_branch pmem_clk = {
-+ .hwcg_reg = 0x25a0,
-+ .hwcg_bit = 6,
-+ .halt_reg = 0x2fc8,
-+ .halt_bit = 20,
-+ .clkr = {
-+ .enable_reg = 0x25a0,
-+ .enable_mask = BIT(4),
-+ .hw.init = &(struct clk_init_data){
-+ .name = "pmem_clk",
-+ .ops = &clk_branch_ops,
-+ .flags = CLK_IS_ROOT,
-+ },
-+ },
-+};
-+
-+static struct clk_rcg prng_src = {
-+ .ns_reg = 0x2e80,
-+ .p = {
-+ .pre_div_shift = 3,
-+ .pre_div_width = 4,
-+ },
-+ .s = {
-+ .src_sel_shift = 0,
-+ .parent_map = gcc_pxo_pll8_map,
-+ },
-+ .clkr = {
-+ .hw.init = &(struct clk_init_data){
-+ .name = "prng_src",
-+ .parent_names = gcc_pxo_pll8,
-+ .num_parents = 2,
-+ .ops = &clk_rcg_ops,
-+ },
-+ },
-+};
-+
-+static struct clk_branch prng_clk = {
-+ .halt_reg = 0x2fd8,
-+ .halt_check = BRANCH_HALT_VOTED,
-+ .halt_bit = 10,
-+ .clkr = {
-+ .enable_reg = 0x3080,
-+ .enable_mask = BIT(10),
-+ .hw.init = &(struct clk_init_data){
-+ .name = "prng_clk",
-+ .parent_names = (const char *[]){ "prng_src" },
-+ .num_parents = 1,
-+ .ops = &clk_branch_ops,
-+ },
-+ },
-+};
-+
-+static const struct freq_tbl clk_tbl_sdc[] = {
-+ { 144000, P_PXO, 5, 18,625 },
-+ { 400000, P_PLL8, 4, 1, 240 },
-+ { 16000000, P_PLL8, 4, 1, 6 },
-+ { 17070000, P_PLL8, 1, 2, 45 },
-+ { 20210000, P_PLL8, 1, 1, 19 },
-+ { 24000000, P_PLL8, 4, 1, 4 },
-+ { 48000000, P_PLL8, 4, 1, 2 },
-+ { 64000000, P_PLL8, 3, 1, 2 },
-+ { 96000000, P_PLL8, 4, 0, 0 },
-+ { 192000000, P_PLL8, 2, 0, 0 },
-+ { }
-+};
-+
-+static struct clk_rcg sdc1_src = {
-+ .ns_reg = 0x282c,
-+ .md_reg = 0x2828,
-+ .mn = {
-+ .mnctr_en_bit = 8,
-+ .mnctr_reset_bit = 7,
-+ .mnctr_mode_shift = 5,
-+ .n_val_shift = 16,
-+ .m_val_shift = 16,
-+ .width = 8,
-+ },
-+ .p = {
-+ .pre_div_shift = 3,
-+ .pre_div_width = 2,
-+ },
-+ .s = {
-+ .src_sel_shift = 0,
-+ .parent_map = gcc_pxo_pll8_map,
-+ },
-+ .freq_tbl = clk_tbl_sdc,
-+ .clkr = {
-+ .enable_reg = 0x282c,
-+ .enable_mask = BIT(11),
-+ .hw.init = &(struct clk_init_data){
-+ .name = "sdc1_src",
-+ .parent_names = gcc_pxo_pll8,
-+ .num_parents = 2,
-+ .ops = &clk_rcg_ops,
-+ .flags = CLK_SET_RATE_GATE,
-+ },
-+ }
-+};
-+
-+static struct clk_branch sdc1_clk = {
-+ .halt_reg = 0x2fc8,
-+ .halt_bit = 6,
-+ .clkr = {
-+ .enable_reg = 0x282c,
-+ .enable_mask = BIT(9),
-+ .hw.init = &(struct clk_init_data){
-+ .name = "sdc1_clk",
-+ .parent_names = (const char *[]){ "sdc1_src" },
-+ .num_parents = 1,
-+ .ops = &clk_branch_ops,
-+ .flags = CLK_SET_RATE_PARENT,
-+ },
-+ },
-+};
-+
-+static struct clk_rcg sdc3_src = {
-+ .ns_reg = 0x286c,
-+ .md_reg = 0x2868,
-+ .mn = {
-+ .mnctr_en_bit = 8,
-+ .mnctr_reset_bit = 7,
-+ .mnctr_mode_shift = 5,
-+ .n_val_shift = 16,
-+ .m_val_shift = 16,
-+ .width = 8,
-+ },
-+ .p = {
-+ .pre_div_shift = 3,
-+ .pre_div_width = 2,
-+ },
-+ .s = {
-+ .src_sel_shift = 0,
-+ .parent_map = gcc_pxo_pll8_map,
-+ },
-+ .freq_tbl = clk_tbl_sdc,
-+ .clkr = {
-+ .enable_reg = 0x286c,
-+ .enable_mask = BIT(11),
-+ .hw.init = &(struct clk_init_data){
-+ .name = "sdc3_src",
-+ .parent_names = gcc_pxo_pll8,
-+ .num_parents = 2,
-+ .ops = &clk_rcg_ops,
-+ .flags = CLK_SET_RATE_GATE,
-+ },
-+ }
-+};
-+
-+static struct clk_branch sdc3_clk = {
-+ .halt_reg = 0x2fc8,
-+ .halt_bit = 4,
-+ .clkr = {
-+ .enable_reg = 0x286c,
-+ .enable_mask = BIT(9),
-+ .hw.init = &(struct clk_init_data){
-+ .name = "sdc3_clk",
-+ .parent_names = (const char *[]){ "sdc3_src" },
-+ .num_parents = 1,
-+ .ops = &clk_branch_ops,
-+ .flags = CLK_SET_RATE_PARENT,
-+ },
-+ },
-+};
-+
-+static struct clk_branch sdc1_h_clk = {
-+ .hwcg_reg = 0x2820,
-+ .hwcg_bit = 6,
-+ .halt_reg = 0x2fc8,
-+ .halt_bit = 11,
-+ .clkr = {
-+ .enable_reg = 0x2820,
-+ .enable_mask = BIT(4),
-+ .hw.init = &(struct clk_init_data){
-+ .name = "sdc1_h_clk",
-+ .ops = &clk_branch_ops,
-+ .flags = CLK_IS_ROOT,
-+ },
-+ },
-+};
-+
-+static struct clk_branch sdc3_h_clk = {
-+ .hwcg_reg = 0x2860,
-+ .hwcg_bit = 6,
-+ .halt_reg = 0x2fc8,
-+ .halt_bit = 9,
-+ .clkr = {
-+ .enable_reg = 0x2860,
-+ .enable_mask = BIT(4),
-+ .hw.init = &(struct clk_init_data){
-+ .name = "sdc3_h_clk",
-+ .ops = &clk_branch_ops,
-+ .flags = CLK_IS_ROOT,
-+ },
-+ },
-+};
-+
-+static const struct freq_tbl clk_tbl_tsif_ref[] = {
-+ { 105000, P_PXO, 1, 1, 256 },
-+ { }
-+};
-+
-+static struct clk_rcg tsif_ref_src = {
-+ .ns_reg = 0x2710,
-+ .md_reg = 0x270c,
-+ .mn = {
-+ .mnctr_en_bit = 8,
-+ .mnctr_reset_bit = 7,
-+ .mnctr_mode_shift = 5,
-+ .n_val_shift = 16,
-+ .m_val_shift = 16,
-+ .width = 16,
-+ },
-+ .p = {
-+ .pre_div_shift = 3,
-+ .pre_div_width = 2,
-+ },
-+ .s = {
-+ .src_sel_shift = 0,
-+ .parent_map = gcc_pxo_pll8_map,
-+ },
-+ .freq_tbl = clk_tbl_tsif_ref,
-+ .clkr = {
-+ .enable_reg = 0x2710,
-+ .enable_mask = BIT(11),
-+ .hw.init = &(struct clk_init_data){
-+ .name = "tsif_ref_src",
-+ .parent_names = gcc_pxo_pll8,
-+ .num_parents = 2,
-+ .ops = &clk_rcg_ops,
-+ .flags = CLK_SET_RATE_GATE,
-+ },
-+ }
-+};
-+
-+static struct clk_branch tsif_ref_clk = {
-+ .halt_reg = 0x2fd4,
-+ .halt_bit = 5,
-+ .clkr = {
-+ .enable_reg = 0x2710,
-+ .enable_mask = BIT(9),
-+ .hw.init = &(struct clk_init_data){
-+ .name = "tsif_ref_clk",
-+ .parent_names = (const char *[]){ "tsif_ref_src" },
-+ .num_parents = 1,
-+ .ops = &clk_branch_ops,
-+ .flags = CLK_SET_RATE_PARENT,
-+ },
-+ },
-+};
-+
-+static struct clk_branch tsif_h_clk = {
-+ .hwcg_reg = 0x2700,
-+ .hwcg_bit = 6,
-+ .halt_reg = 0x2fd4,
-+ .halt_bit = 7,
-+ .clkr = {
-+ .enable_reg = 0x2700,
-+ .enable_mask = BIT(4),
-+ .hw.init = &(struct clk_init_data){
-+ .name = "tsif_h_clk",
-+ .ops = &clk_branch_ops,
-+ .flags = CLK_IS_ROOT,
-+ },
-+ },
-+};
-+
-+static struct clk_branch dma_bam_h_clk = {
-+ .hwcg_reg = 0x25c0,
-+ .hwcg_bit = 6,
-+ .halt_reg = 0x2fc8,
-+ .halt_bit = 12,
-+ .clkr = {
-+ .enable_reg = 0x25c0,
-+ .enable_mask = BIT(4),
-+ .hw.init = &(struct clk_init_data){
-+ .name = "dma_bam_h_clk",
-+ .ops = &clk_branch_ops,
-+ .flags = CLK_IS_ROOT,
-+ },
-+ },
-+};
-+
-+static struct clk_branch adm0_clk = {
-+ .halt_reg = 0x2fdc,
-+ .halt_check = BRANCH_HALT_VOTED,
-+ .halt_bit = 12,
-+ .clkr = {
-+ .enable_reg = 0x3080,
-+ .enable_mask = BIT(2),
-+ .hw.init = &(struct clk_init_data){
-+ .name = "adm0_clk",
-+ .ops = &clk_branch_ops,
-+ .flags = CLK_IS_ROOT,
-+ },
-+ },
-+};
-+
-+static struct clk_branch adm0_pbus_clk = {
-+ .hwcg_reg = 0x2208,
-+ .hwcg_bit = 6,
-+ .halt_reg = 0x2fdc,
-+ .halt_check = BRANCH_HALT_VOTED,
-+ .halt_bit = 11,
-+ .clkr = {
-+ .enable_reg = 0x3080,
-+ .enable_mask = BIT(3),
-+ .hw.init = &(struct clk_init_data){
-+ .name = "adm0_pbus_clk",
-+ .ops = &clk_branch_ops,
-+ .flags = CLK_IS_ROOT,
-+ },
-+ },
-+};
-+
-+static struct clk_branch pmic_arb0_h_clk = {
-+ .halt_reg = 0x2fd8,
-+ .halt_check = BRANCH_HALT_VOTED,
-+ .halt_bit = 22,
-+ .clkr = {
-+ .enable_reg = 0x3080,
-+ .enable_mask = BIT(8),
-+ .hw.init = &(struct clk_init_data){
-+ .name = "pmic_arb0_h_clk",
-+ .ops = &clk_branch_ops,
-+ .flags = CLK_IS_ROOT,
-+ },
-+ },
-+};
-+
-+static struct clk_branch pmic_arb1_h_clk = {
-+ .halt_reg = 0x2fd8,
-+ .halt_check = BRANCH_HALT_VOTED,
-+ .halt_bit = 21,
-+ .clkr = {
-+ .enable_reg = 0x3080,
-+ .enable_mask = BIT(9),
-+ .hw.init = &(struct clk_init_data){
-+ .name = "pmic_arb1_h_clk",
-+ .ops = &clk_branch_ops,
-+ .flags = CLK_IS_ROOT,
-+ },
-+ },
-+};
-+
-+static struct clk_branch pmic_ssbi2_clk = {
-+ .halt_reg = 0x2fd8,
-+ .halt_check = BRANCH_HALT_VOTED,
-+ .halt_bit = 23,
-+ .clkr = {
-+ .enable_reg = 0x3080,
-+ .enable_mask = BIT(7),
-+ .hw.init = &(struct clk_init_data){
-+ .name = "pmic_ssbi2_clk",
-+ .ops = &clk_branch_ops,
-+ .flags = CLK_IS_ROOT,
-+ },
-+ },
-+};
-+
-+static struct clk_branch rpm_msg_ram_h_clk = {
-+ .hwcg_reg = 0x27e0,
-+ .hwcg_bit = 6,
-+ .halt_reg = 0x2fd8,
-+ .halt_check = BRANCH_HALT_VOTED,
-+ .halt_bit = 12,
-+ .clkr = {
-+ .enable_reg = 0x3080,
-+ .enable_mask = BIT(6),
-+ .hw.init = &(struct clk_init_data){
-+ .name = "rpm_msg_ram_h_clk",
-+ .ops = &clk_branch_ops,
-+ .flags = CLK_IS_ROOT,
-+ },
-+ },
-+};
-+
-+static const struct freq_tbl clk_tbl_pcie_ref[] = {
-+ { 100000000, P_PLL3, 12, 0, 0 },
-+ { }
-+};
-+
-+static struct clk_rcg pcie_ref_src = {
-+ .ns_reg = 0x3860,
-+ .p = {
-+ .pre_div_shift = 3,
-+ .pre_div_width = 4,
-+ },
-+ .s = {
-+ .src_sel_shift = 0,
-+ .parent_map = gcc_pxo_pll3_map,
-+ },
-+ .freq_tbl = clk_tbl_pcie_ref,
-+ .clkr = {
-+ .enable_reg = 0x3860,
-+ .enable_mask = BIT(11),
-+ .hw.init = &(struct clk_init_data){
-+ .name = "pcie_ref_src",
-+ .parent_names = gcc_pxo_pll3,
-+ .num_parents = 2,
-+ .ops = &clk_rcg_ops,
-+ .flags = CLK_SET_RATE_GATE,
-+ },
-+ },
-+};
-+
-+static struct clk_branch pcie_ref_src_clk = {
-+ .halt_reg = 0x2fdc,
-+ .halt_bit = 30,
-+ .clkr = {
-+ .enable_reg = 0x3860,
-+ .enable_mask = BIT(9),
-+ .hw.init = &(struct clk_init_data){
-+ .name = "pcie_ref_src_clk",
-+ .parent_names = (const char *[]){ "pcie_ref_src" },
-+ .num_parents = 1,
-+ .ops = &clk_branch_ops,
-+ .flags = CLK_SET_RATE_PARENT,
-+ },
-+ },
-+};
-+
-+static struct clk_branch pcie_a_clk = {
-+ .halt_reg = 0x2fc0,
-+ .halt_bit = 13,
-+ .clkr = {
-+ .enable_reg = 0x22c0,
-+ .enable_mask = BIT(4),
-+ .hw.init = &(struct clk_init_data){
-+ .name = "pcie_a_clk",
-+ .ops = &clk_branch_ops,
-+ .flags = CLK_IS_ROOT,
-+ },
-+ },
-+};
-+
-+static struct clk_branch pcie_aux_clk = {
-+ .halt_reg = 0x2fdc,
-+ .halt_bit = 31,
-+ .clkr = {
-+ .enable_reg = 0x22c8,
-+ .enable_mask = BIT(4),
-+ .hw.init = &(struct clk_init_data){
-+ .name = "pcie_aux_clk",
-+ .ops = &clk_branch_ops,
-+ .flags = CLK_IS_ROOT,
-+ },
-+ },
-+};
-+
-+static struct clk_branch pcie_h_clk = {
-+ .halt_reg = 0x2fd4,
-+ .halt_bit = 8,
-+ .clkr = {
-+ .enable_reg = 0x22cc,
-+ .enable_mask = BIT(4),
-+ .hw.init = &(struct clk_init_data){
-+ .name = "pcie_h_clk",
-+ .ops = &clk_branch_ops,
-+ .flags = CLK_IS_ROOT,
-+ },
-+ },
-+};
-+
-+static struct clk_branch pcie_phy_clk = {
-+ .halt_reg = 0x2fdc,
-+ .halt_bit = 29,
-+ .clkr = {
-+ .enable_reg = 0x22d0,
-+ .enable_mask = BIT(4),
-+ .hw.init = &(struct clk_init_data){
-+ .name = "pcie_phy_clk",
-+ .ops = &clk_branch_ops,
-+ .flags = CLK_IS_ROOT,
-+ },
-+ },
-+};
-+
-+static struct clk_rcg pcie1_ref_src = {
-+ .ns_reg = 0x3aa0,
-+ .p = {
-+ .pre_div_shift = 3,
-+ .pre_div_width = 4,
-+ },
-+ .s = {
-+ .src_sel_shift = 0,
-+ .parent_map = gcc_pxo_pll3_map,
-+ },
-+ .freq_tbl = clk_tbl_pcie_ref,
-+ .clkr = {
-+ .enable_reg = 0x3aa0,
-+ .enable_mask = BIT(11),
-+ .hw.init = &(struct clk_init_data){
-+ .name = "pcie1_ref_src",
-+ .parent_names = gcc_pxo_pll3,
-+ .num_parents = 2,
-+ .ops = &clk_rcg_ops,
-+ .flags = CLK_SET_RATE_GATE,
-+ },
-+ },
-+};
-+
-+static struct clk_branch pcie1_ref_src_clk = {
-+ .halt_reg = 0x2fdc,
-+ .halt_bit = 27,
-+ .clkr = {
-+ .enable_reg = 0x3aa0,
-+ .enable_mask = BIT(9),
-+ .hw.init = &(struct clk_init_data){
-+ .name = "pcie1_ref_src_clk",
-+ .parent_names = (const char *[]){ "pcie1_ref_src" },
-+ .num_parents = 1,
-+ .ops = &clk_branch_ops,
-+ .flags = CLK_SET_RATE_PARENT,
-+ },
-+ },
-+};
-+
-+static struct clk_branch pcie1_a_clk = {
-+ .halt_reg = 0x2fc0,
-+ .halt_bit = 10,
-+ .clkr = {
-+ .enable_reg = 0x3a80,
-+ .enable_mask = BIT(4),
-+ .hw.init = &(struct clk_init_data){
-+ .name = "pcie1_a_clk",
-+ .ops = &clk_branch_ops,
-+ .flags = CLK_IS_ROOT,
-+ },
-+ },
-+};
-+
-+static struct clk_branch pcie1_aux_clk = {
-+ .halt_reg = 0x2fdc,
-+ .halt_bit = 28,
-+ .clkr = {
-+ .enable_reg = 0x3a88,
-+ .enable_mask = BIT(4),
-+ .hw.init = &(struct clk_init_data){
-+ .name = "pcie1_aux_clk",
-+ .ops = &clk_branch_ops,
-+ .flags = CLK_IS_ROOT,
-+ },
-+ },
-+};
-+
-+static struct clk_branch pcie1_h_clk = {
-+ .halt_reg = 0x2fd4,
-+ .halt_bit = 9,
-+ .clkr = {
-+ .enable_reg = 0x3a8c,
-+ .enable_mask = BIT(4),
-+ .hw.init = &(struct clk_init_data){
-+ .name = "pcie1_h_clk",
-+ .ops = &clk_branch_ops,
-+ .flags = CLK_IS_ROOT,
-+ },
-+ },
-+};
-+
-+static struct clk_branch pcie1_phy_clk = {
-+ .halt_reg = 0x2fdc,
-+ .halt_bit = 26,
-+ .clkr = {
-+ .enable_reg = 0x3a90,
-+ .enable_mask = BIT(4),
-+ .hw.init = &(struct clk_init_data){
-+ .name = "pcie1_phy_clk",
-+ .ops = &clk_branch_ops,
-+ .flags = CLK_IS_ROOT,
-+ },
-+ },
-+};
-+
-+static struct clk_rcg pcie2_ref_src = {
-+ .ns_reg = 0x3ae0,
-+ .p = {
-+ .pre_div_shift = 3,
-+ .pre_div_width = 4,
-+ },
-+ .s = {
-+ .src_sel_shift = 0,
-+ .parent_map = gcc_pxo_pll3_map,
-+ },
-+ .freq_tbl = clk_tbl_pcie_ref,
-+ .clkr = {
-+ .enable_reg = 0x3ae0,
-+ .enable_mask = BIT(11),
-+ .hw.init = &(struct clk_init_data){
-+ .name = "pcie2_ref_src",
-+ .parent_names = gcc_pxo_pll3,
-+ .num_parents = 2,
-+ .ops = &clk_rcg_ops,
-+ .flags = CLK_SET_RATE_GATE,
-+ },
-+ },
-+};
-+
-+static struct clk_branch pcie2_ref_src_clk = {
-+ .halt_reg = 0x2fdc,
-+ .halt_bit = 24,
-+ .clkr = {
-+ .enable_reg = 0x3ae0,
-+ .enable_mask = BIT(9),
-+ .hw.init = &(struct clk_init_data){
-+ .name = "pcie2_ref_src_clk",
-+ .parent_names = (const char *[]){ "pcie2_ref_src" },
-+ .num_parents = 1,
-+ .ops = &clk_branch_ops,
-+ .flags = CLK_SET_RATE_PARENT,
-+ },
-+ },
-+};
-+
-+static struct clk_branch pcie2_a_clk = {
-+ .halt_reg = 0x2fc0,
-+ .halt_bit = 9,
-+ .clkr = {
-+ .enable_reg = 0x3ac0,
-+ .enable_mask = BIT(4),
-+ .hw.init = &(struct clk_init_data){
-+ .name = "pcie2_a_clk",
-+ .ops = &clk_branch_ops,
-+ .flags = CLK_IS_ROOT,
-+ },
-+ },
-+};
-+
-+static struct clk_branch pcie2_aux_clk = {
-+ .halt_reg = 0x2fdc,
-+ .halt_bit = 25,
-+ .clkr = {
-+ .enable_reg = 0x3ac8,
-+ .enable_mask = BIT(4),
-+ .hw.init = &(struct clk_init_data){
-+ .name = "pcie2_aux_clk",
-+ .ops = &clk_branch_ops,
-+ .flags = CLK_IS_ROOT,
-+ },
-+ },
-+};
-+
-+static struct clk_branch pcie2_h_clk = {
-+ .halt_reg = 0x2fd4,
-+ .halt_bit = 10,
-+ .clkr = {
-+ .enable_reg = 0x3acc,
-+ .enable_mask = BIT(4),
-+ .hw.init = &(struct clk_init_data){
-+ .name = "pcie2_h_clk",
-+ .ops = &clk_branch_ops,
-+ .flags = CLK_IS_ROOT,
-+ },
-+ },
-+};
-+
-+static struct clk_branch pcie2_phy_clk = {
-+ .halt_reg = 0x2fdc,
-+ .halt_bit = 23,
-+ .clkr = {
-+ .enable_reg = 0x3ad0,
-+ .enable_mask = BIT(4),
-+ .hw.init = &(struct clk_init_data){
-+ .name = "pcie2_phy_clk",
-+ .ops = &clk_branch_ops,
-+ .flags = CLK_IS_ROOT,
-+ },
-+ },
-+};
-+
-+static const struct freq_tbl clk_tbl_sata_ref[] = {
-+ { 100000000, P_PLL3, 12, 0, 0 },
-+ { }
-+};
-+
-+static struct clk_rcg sata_ref_src = {
-+ .ns_reg = 0x2c08,
-+ .p = {
-+ .pre_div_shift = 3,
-+ .pre_div_width = 4,
-+ },
-+ .s = {
-+ .src_sel_shift = 0,
-+ .parent_map = gcc_pxo_pll3_sata_map,
-+ },
-+ .freq_tbl = clk_tbl_sata_ref,
-+ .clkr = {
-+ .enable_reg = 0x2c08,
-+ .enable_mask = BIT(7),
-+ .hw.init = &(struct clk_init_data){
-+ .name = "sata_ref_src",
-+ .parent_names = gcc_pxo_pll3,
-+ .num_parents = 2,
-+ .ops = &clk_rcg_ops,
-+ .flags = CLK_SET_RATE_GATE,
-+ },
-+ },
-+};
-+
-+static struct clk_branch sata_rxoob_clk = {
-+ .halt_reg = 0x2fdc,
-+ .halt_bit = 20,
-+ .clkr = {
-+ .enable_reg = 0x2c0c,
-+ .enable_mask = BIT(4),
-+ .hw.init = &(struct clk_init_data){
-+ .name = "sata_rxoob_clk",
-+ .parent_names = (const char *[]){ "sata_ref_src" },
-+ .num_parents = 1,
-+ .ops = &clk_branch_ops,
-+ .flags = CLK_SET_RATE_PARENT,
-+ },
-+ },
-+};
-+
-+static struct clk_branch sata_pmalive_clk = {
-+ .halt_reg = 0x2fdc,
-+ .halt_bit = 19,
-+ .clkr = {
-+ .enable_reg = 0x2c10,
-+ .enable_mask = BIT(4),
-+ .hw.init = &(struct clk_init_data){
-+ .name = "sata_pmalive_clk",
-+ .parent_names = (const char *[]){ "sata_ref_src" },
-+ .num_parents = 1,
-+ .ops = &clk_branch_ops,
-+ .flags = CLK_SET_RATE_PARENT,
-+ },
-+ },
-+};
-+
-+static struct clk_branch sata_phy_ref_clk = {
-+ .halt_reg = 0x2fdc,
-+ .halt_bit = 18,
-+ .clkr = {
-+ .enable_reg = 0x2c14,
-+ .enable_mask = BIT(4),
-+ .hw.init = &(struct clk_init_data){
-+ .name = "sata_phy_ref_clk",
-+ .parent_names = (const char *[]){ "pxo" },
-+ .num_parents = 1,
-+ .ops = &clk_branch_ops,
-+ },
-+ },
-+};
-+
-+static struct clk_branch sata_a_clk = {
-+ .halt_reg = 0x2fc0,
-+ .halt_bit = 12,
-+ .clkr = {
-+ .enable_reg = 0x2c20,
-+ .enable_mask = BIT(4),
-+ .hw.init = &(struct clk_init_data){
-+ .name = "sata_a_clk",
-+ .ops = &clk_branch_ops,
-+ .flags = CLK_IS_ROOT,
-+ },
-+ },
-+};
-+
-+static struct clk_branch sata_h_clk = {
-+ .halt_reg = 0x2fdc,
-+ .halt_bit = 21,
-+ .clkr = {
-+ .enable_reg = 0x2c00,
-+ .enable_mask = BIT(4),
-+ .hw.init = &(struct clk_init_data){
-+ .name = "sata_h_clk",
-+ .ops = &clk_branch_ops,
-+ .flags = CLK_IS_ROOT,
-+ },
-+ },
-+};
-+
-+static struct clk_branch sfab_sata_s_h_clk = {
-+ .halt_reg = 0x2fc4,
-+ .halt_bit = 14,
-+ .clkr = {
-+ .enable_reg = 0x2480,
-+ .enable_mask = BIT(4),
-+ .hw.init = &(struct clk_init_data){
-+ .name = "sfab_sata_s_h_clk",
-+ .ops = &clk_branch_ops,
-+ .flags = CLK_IS_ROOT,
-+ },
-+ },
-+};
-+
-+static struct clk_branch sata_phy_cfg_clk = {
-+ .halt_reg = 0x2fcc,
-+ .halt_bit = 14,
-+ .clkr = {
-+ .enable_reg = 0x2c40,
-+ .enable_mask = BIT(4),
-+ .hw.init = &(struct clk_init_data){
-+ .name = "sata_phy_cfg_clk",
-+ .ops = &clk_branch_ops,
-+ .flags = CLK_IS_ROOT,
-+ },
-+ },
-+};
-+
-+static const struct freq_tbl clk_tbl_usb30_master[] = {
-+ { 125000000, P_PLL0, 1, 5, 32 },
-+ { }
-+};
-+
-+static struct clk_rcg usb30_master_clk_src = {
-+ .ns_reg = 0x3b2c,
-+ .md_reg = 0x3b28,
-+ .mn = {
-+ .mnctr_en_bit = 8,
-+ .mnctr_reset_bit = 7,
-+ .mnctr_mode_shift = 5,
-+ .n_val_shift = 16,
-+ .m_val_shift = 16,
-+ .width = 8,
-+ },
-+ .p = {
-+ .pre_div_shift = 3,
-+ .pre_div_width = 2,
-+ },
-+ .s = {
-+ .src_sel_shift = 0,
-+ .parent_map = gcc_pxo_pll8_pll0,
-+ },
-+ .freq_tbl = clk_tbl_usb30_master,
-+ .clkr = {
-+ .enable_reg = 0x3b2c,
-+ .enable_mask = BIT(11),
-+ .hw.init = &(struct clk_init_data){
-+ .name = "usb30_master_ref_src",
-+ .parent_names = gcc_pxo_pll8_pll0_map,
-+ .num_parents = 3,
-+ .ops = &clk_rcg_ops,
-+ .flags = CLK_SET_RATE_GATE,
-+ },
-+ },
-+};
-+
-+static struct clk_branch usb30_0_branch_clk = {
-+ .halt_reg = 0x2fc4,
-+ .halt_bit = 22,
-+ .clkr = {
-+ .enable_reg = 0x3b24,
-+ .enable_mask = BIT(4),
-+ .hw.init = &(struct clk_init_data){
-+ .name = "usb30_0_branch_clk",
-+ .parent_names = (const char *[]){ "usb30_master_ref_src", },
-+ .num_parents = 1,
-+ .ops = &clk_branch_ops,
-+ .flags = CLK_SET_RATE_PARENT,
-+ },
-+ },
-+};
-+
-+static struct clk_branch usb30_1_branch_clk = {
-+ .halt_reg = 0x2fc4,
-+ .halt_bit = 17,
-+ .clkr = {
-+ .enable_reg = 0x3b34,
-+ .enable_mask = BIT(4),
-+ .hw.init = &(struct clk_init_data){
-+ .name = "usb30_1_branch_clk",
-+ .parent_names = (const char *[]){ "usb30_master_ref_src", },
-+ .num_parents = 1,
-+ .ops = &clk_branch_ops,
-+ .flags = CLK_SET_RATE_PARENT,
-+ },
-+ },
-+};
-+
-+static const struct freq_tbl clk_tbl_usb30_utmi[] = {
-+ { 60000000, P_PLL0, 1, 1, 40 },
-+ { }
-+};
-+
-+static struct clk_rcg usb30_utmi_clk = {
-+ .ns_reg = 0x3b44,
-+ .md_reg = 0x3b40,
-+ .mn = {
-+ .mnctr_en_bit = 8,
-+ .mnctr_reset_bit = 7,
-+ .mnctr_mode_shift = 5,
-+ .n_val_shift = 16,
-+ .m_val_shift = 16,
-+ .width = 8,
-+ },
-+ .p = {
-+ .pre_div_shift = 3,
-+ .pre_div_width = 2,
-+ },
-+ .s = {
-+ .src_sel_shift = 0,
-+ .parent_map = gcc_pxo_pll8_pll0,
-+ },
-+ .freq_tbl = clk_tbl_usb30_utmi,
-+ .clkr = {
-+ .enable_reg = 0x3b44,
-+ .enable_mask = BIT(11),
-+ .hw.init = &(struct clk_init_data){
-+ .name = "usb30_utmi_clk",
-+ .parent_names = gcc_pxo_pll8_pll0_map,
-+ .num_parents = 3,
-+ .ops = &clk_rcg_ops,
-+ .flags = CLK_SET_RATE_GATE,
-+ },
-+ },
-+};
-+
-+static struct clk_branch usb30_0_utmi_clk_ctl = {
-+ .halt_reg = 0x2fc4,
-+ .halt_bit = 21,
-+ .clkr = {
-+ .enable_reg = 0x3b48,
-+ .enable_mask = BIT(4),
-+ .hw.init = &(struct clk_init_data){
-+ .name = "usb30_0_utmi_clk_ctl",
-+ .parent_names = (const char *[]){ "usb30_utmi_clk", },
-+ .num_parents = 1,
-+ .ops = &clk_branch_ops,
-+ .flags = CLK_SET_RATE_PARENT,
-+ },
-+ },
-+};
-+
-+static struct clk_branch usb30_1_utmi_clk_ctl = {
-+ .halt_reg = 0x2fc4,
-+ .halt_bit = 15,
-+ .clkr = {
-+ .enable_reg = 0x3b4c,
-+ .enable_mask = BIT(4),
-+ .hw.init = &(struct clk_init_data){
-+ .name = "usb30_1_utmi_clk_ctl",
-+ .parent_names = (const char *[]){ "usb30_utmi_clk", },
-+ .num_parents = 1,
-+ .ops = &clk_branch_ops,
-+ .flags = CLK_SET_RATE_PARENT,
-+ },
-+ },
-+};
-+
-+static const struct freq_tbl clk_tbl_usb[] = {
-+ { 60000000, P_PLL8, 1, 5, 32 },
-+ { }
-+};
-+
-+static struct clk_rcg usb_hs1_xcvr_clk_src = {
-+ .ns_reg = 0x290C,
-+ .md_reg = 0x2908,
-+ .mn = {
-+ .mnctr_en_bit = 8,
-+ .mnctr_reset_bit = 7,
-+ .mnctr_mode_shift = 5,
-+ .n_val_shift = 16,
-+ .m_val_shift = 16,
-+ .width = 8,
-+ },
-+ .p = {
-+ .pre_div_shift = 3,
-+ .pre_div_width = 2,
-+ },
-+ .s = {
-+ .src_sel_shift = 0,
-+ .parent_map = gcc_pxo_pll8_pll0,
-+ },
-+ .freq_tbl = clk_tbl_usb,
-+ .clkr = {
-+ .enable_reg = 0x2968,
-+ .enable_mask = BIT(11),
-+ .hw.init = &(struct clk_init_data){
-+ .name = "usb_hs1_xcvr_src",
-+ .parent_names = gcc_pxo_pll8_pll0_map,
-+ .num_parents = 3,
-+ .ops = &clk_rcg_ops,
-+ .flags = CLK_SET_RATE_GATE,
-+ },
-+ },
-+};
-+
-+static struct clk_branch usb_hs1_xcvr_clk = {
-+ .halt_reg = 0x2fcc,
-+ .halt_bit = 17,
-+ .clkr = {
-+ .enable_reg = 0x290c,
-+ .enable_mask = BIT(9),
-+ .hw.init = &(struct clk_init_data){
-+ .name = "usb_hs1_xcvr_clk",
-+ .parent_names = (const char *[]){ "usb_hs1_xcvr_src" },
-+ .num_parents = 1,
-+ .ops = &clk_branch_ops,
-+ .flags = CLK_SET_RATE_PARENT,
-+ },
-+ },
-+};
-+
-+static struct clk_branch usb_hs1_h_clk = {
-+ .hwcg_reg = 0x2900,
-+ .hwcg_bit = 6,
-+ .halt_reg = 0x2fc8,
-+ .halt_bit = 1,
-+ .clkr = {
-+ .enable_reg = 0x2900,
-+ .enable_mask = BIT(4),
-+ .hw.init = &(struct clk_init_data){
-+ .name = "usb_hs1_h_clk",
-+ .ops = &clk_branch_ops,
-+ .flags = CLK_IS_ROOT,
-+ },
-+ },
-+};
-+
-+static struct clk_rcg usb_fs1_xcvr_clk_src = {
-+ .ns_reg = 0x2968,
-+ .md_reg = 0x2964,
-+ .mn = {
-+ .mnctr_en_bit = 8,
-+ .mnctr_reset_bit = 7,
-+ .mnctr_mode_shift = 5,
-+ .n_val_shift = 16,
-+ .m_val_shift = 16,
-+ .width = 8,
-+ },
-+ .p = {
-+ .pre_div_shift = 3,
-+ .pre_div_width = 2,
-+ },
-+ .s = {
-+ .src_sel_shift = 0,
-+ .parent_map = gcc_pxo_pll8_pll0,
-+ },
-+ .freq_tbl = clk_tbl_usb,
-+ .clkr = {
-+ .enable_reg = 0x2968,
-+ .enable_mask = BIT(11),
-+ .hw.init = &(struct clk_init_data){
-+ .name = "usb_fs1_xcvr_src",
-+ .parent_names = gcc_pxo_pll8_pll0_map,
-+ .num_parents = 3,
-+ .ops = &clk_rcg_ops,
-+ .flags = CLK_SET_RATE_GATE,
-+ },
-+ },
-+};
-+
-+static struct clk_branch usb_fs1_xcvr_clk = {
-+ .halt_reg = 0x2fcc,
-+ .halt_bit = 17,
-+ .clkr = {
-+ .enable_reg = 0x2968,
-+ .enable_mask = BIT(9),
-+ .hw.init = &(struct clk_init_data){
-+ .name = "usb_fs1_xcvr_clk",
-+ .parent_names = (const char *[]){ "usb_fs1_xcvr_src", },
-+ .num_parents = 1,
-+ .ops = &clk_branch_ops,
-+ .flags = CLK_SET_RATE_PARENT,
-+ },
-+ },
-+};
-+
-+static struct clk_branch usb_fs1_sys_clk = {
-+ .halt_reg = 0x2fcc,
-+ .halt_bit = 18,
-+ .clkr = {
-+ .enable_reg = 0x296c,
-+ .enable_mask = BIT(4),
-+ .hw.init = &(struct clk_init_data){
-+ .name = "usb_fs1_sys_clk",
-+ .parent_names = (const char *[]){ "usb_fs1_xcvr_src", },
-+ .num_parents = 1,
-+ .ops = &clk_branch_ops,
-+ .flags = CLK_SET_RATE_PARENT,
-+ },
-+ },
-+};
-+
-+static struct clk_branch usb_fs1_h_clk = {
-+ .halt_reg = 0x2fcc,
-+ .halt_bit = 19,
-+ .clkr = {
-+ .enable_reg = 0x2960,
-+ .enable_mask = BIT(4),
-+ .hw.init = &(struct clk_init_data){
-+ .name = "usb_fs1_h_clk",
-+ .ops = &clk_branch_ops,
-+ .flags = CLK_IS_ROOT,
-+ },
-+ },
-+};
-+
-+static struct clk_regmap *gcc_ipq806x_clks[] = {
-+ [PLL3] = &pll3.clkr,
-+ [PLL8] = &pll8.clkr,
-+ [PLL8_VOTE] = &pll8_vote,
-+ [PLL14] = &pll14.clkr,
-+ [PLL14_VOTE] = &pll14_vote,
-+ [GSBI1_UART_SRC] = &gsbi1_uart_src.clkr,
-+ [GSBI1_UART_CLK] = &gsbi1_uart_clk.clkr,
-+ [GSBI2_UART_SRC] = &gsbi2_uart_src.clkr,
-+ [GSBI2_UART_CLK] = &gsbi2_uart_clk.clkr,
-+ [GSBI4_UART_SRC] = &gsbi4_uart_src.clkr,
-+ [GSBI4_UART_CLK] = &gsbi4_uart_clk.clkr,
-+ [GSBI5_UART_SRC] = &gsbi5_uart_src.clkr,
-+ [GSBI5_UART_CLK] = &gsbi5_uart_clk.clkr,
-+ [GSBI6_UART_SRC] = &gsbi6_uart_src.clkr,
-+ [GSBI6_UART_CLK] = &gsbi6_uart_clk.clkr,
-+ [GSBI7_UART_SRC] = &gsbi7_uart_src.clkr,
-+ [GSBI7_UART_CLK] = &gsbi7_uart_clk.clkr,
-+ [GSBI1_QUP_SRC] = &gsbi1_qup_src.clkr,
-+ [GSBI1_QUP_CLK] = &gsbi1_qup_clk.clkr,
-+ [GSBI2_QUP_SRC] = &gsbi2_qup_src.clkr,
-+ [GSBI2_QUP_CLK] = &gsbi2_qup_clk.clkr,
-+ [GSBI4_QUP_SRC] = &gsbi4_qup_src.clkr,
-+ [GSBI4_QUP_CLK] = &gsbi4_qup_clk.clkr,
-+ [GSBI5_QUP_SRC] = &gsbi5_qup_src.clkr,
-+ [GSBI5_QUP_CLK] = &gsbi5_qup_clk.clkr,
-+ [GSBI6_QUP_SRC] = &gsbi6_qup_src.clkr,
-+ [GSBI6_QUP_CLK] = &gsbi6_qup_clk.clkr,
-+ [GSBI7_QUP_SRC] = &gsbi7_qup_src.clkr,
-+ [GSBI7_QUP_CLK] = &gsbi7_qup_clk.clkr,
-+ [GP0_SRC] = &gp0_src.clkr,
-+ [GP0_CLK] = &gp0_clk.clkr,
-+ [GP1_SRC] = &gp1_src.clkr,
-+ [GP1_CLK] = &gp1_clk.clkr,
-+ [GP2_SRC] = &gp2_src.clkr,
-+ [GP2_CLK] = &gp2_clk.clkr,
-+ [PMEM_A_CLK] = &pmem_clk.clkr,
-+ [PRNG_SRC] = &prng_src.clkr,
-+ [PRNG_CLK] = &prng_clk.clkr,
-+ [SDC1_SRC] = &sdc1_src.clkr,
-+ [SDC1_CLK] = &sdc1_clk.clkr,
-+ [SDC3_SRC] = &sdc3_src.clkr,
-+ [SDC3_CLK] = &sdc3_clk.clkr,
-+ [TSIF_REF_SRC] = &tsif_ref_src.clkr,
-+ [TSIF_REF_CLK] = &tsif_ref_clk.clkr,
-+ [DMA_BAM_H_CLK] = &dma_bam_h_clk.clkr,
-+ [GSBI1_H_CLK] = &gsbi1_h_clk.clkr,
-+ [GSBI2_H_CLK] = &gsbi2_h_clk.clkr,
-+ [GSBI4_H_CLK] = &gsbi4_h_clk.clkr,
-+ [GSBI5_H_CLK] = &gsbi5_h_clk.clkr,
-+ [GSBI6_H_CLK] = &gsbi6_h_clk.clkr,
-+ [GSBI7_H_CLK] = &gsbi7_h_clk.clkr,
-+ [TSIF_H_CLK] = &tsif_h_clk.clkr,
-+ [SDC1_H_CLK] = &sdc1_h_clk.clkr,
-+ [SDC3_H_CLK] = &sdc3_h_clk.clkr,
-+ [ADM0_CLK] = &adm0_clk.clkr,
-+ [ADM0_PBUS_CLK] = &adm0_pbus_clk.clkr,
-+ [PCIE_A_CLK] = &pcie_a_clk.clkr,
-+ [PCIE_AUX_CLK] = &pcie_aux_clk.clkr,
-+ [PCIE_H_CLK] = &pcie_h_clk.clkr,
-+ [PCIE_PHY_CLK] = &pcie_phy_clk.clkr,
-+ [SFAB_SATA_S_H_CLK] = &sfab_sata_s_h_clk.clkr,
-+ [PMIC_ARB0_H_CLK] = &pmic_arb0_h_clk.clkr,
-+ [PMIC_ARB1_H_CLK] = &pmic_arb1_h_clk.clkr,
-+ [PMIC_SSBI2_CLK] = &pmic_ssbi2_clk.clkr,
-+ [RPM_MSG_RAM_H_CLK] = &rpm_msg_ram_h_clk.clkr,
-+ [SATA_H_CLK] = &sata_h_clk.clkr,
-+ [SATA_CLK_SRC] = &sata_ref_src.clkr,
-+ [SATA_RXOOB_CLK] = &sata_rxoob_clk.clkr,
-+ [SATA_PMALIVE_CLK] = &sata_pmalive_clk.clkr,
-+ [SATA_PHY_REF_CLK] = &sata_phy_ref_clk.clkr,
-+ [SATA_A_CLK] = &sata_a_clk.clkr,
-+ [SATA_PHY_CFG_CLK] = &sata_phy_cfg_clk.clkr,
-+ [PCIE_ALT_REF_SRC] = &pcie_ref_src.clkr,
-+ [PCIE_ALT_REF_CLK] = &pcie_ref_src_clk.clkr,
-+ [PCIE_1_A_CLK] = &pcie1_a_clk.clkr,
-+ [PCIE_1_AUX_CLK] = &pcie1_aux_clk.clkr,
-+ [PCIE_1_H_CLK] = &pcie1_h_clk.clkr,
-+ [PCIE_1_PHY_CLK] = &pcie1_phy_clk.clkr,
-+ [PCIE_1_ALT_REF_SRC] = &pcie1_ref_src.clkr,
-+ [PCIE_1_ALT_REF_CLK] = &pcie1_ref_src_clk.clkr,
-+ [PCIE_2_A_CLK] = &pcie2_a_clk.clkr,
-+ [PCIE_2_AUX_CLK] = &pcie2_aux_clk.clkr,
-+ [PCIE_2_H_CLK] = &pcie2_h_clk.clkr,
-+ [PCIE_2_PHY_CLK] = &pcie2_phy_clk.clkr,
-+ [PCIE_2_ALT_REF_SRC] = &pcie2_ref_src.clkr,
-+ [PCIE_2_ALT_REF_CLK] = &pcie2_ref_src_clk.clkr,
-+ [USB30_MASTER_SRC] = &usb30_master_clk_src.clkr,
-+ [USB30_0_MASTER_CLK] = &usb30_0_branch_clk.clkr,
-+ [USB30_1_MASTER_CLK] = &usb30_1_branch_clk.clkr,
-+ [USB30_UTMI_SRC] = &usb30_utmi_clk.clkr,
-+ [USB30_0_UTMI_CLK] = &usb30_0_utmi_clk_ctl.clkr,
-+ [USB30_1_UTMI_CLK] = &usb30_1_utmi_clk_ctl.clkr,
-+ [USB_HS1_H_CLK] = &usb_hs1_h_clk.clkr,
-+ [USB_HS1_XCVR_SRC] = &usb_hs1_xcvr_clk_src.clkr,
-+ [USB_HS1_XCVR_CLK] = &usb_hs1_xcvr_clk.clkr,
-+ [USB_FS1_H_CLK] = &usb_fs1_h_clk.clkr,
-+ [USB_FS1_XCVR_SRC] = &usb_fs1_xcvr_clk_src.clkr,
-+ [USB_FS1_XCVR_CLK] = &usb_fs1_xcvr_clk.clkr,
-+ [USB_FS1_SYSTEM_CLK] = &usb_fs1_sys_clk.clkr,
-+};
-+
-+static const struct qcom_reset_map gcc_ipq806x_resets[] = {
-+ [QDSS_STM_RESET] = { 0x2060, 6 },
-+ [AFAB_SMPSS_S_RESET] = { 0x20b8, 2 },
-+ [AFAB_SMPSS_M1_RESET] = { 0x20b8, 1 },
-+ [AFAB_SMPSS_M0_RESET] = { 0x20b8, 0 },
-+ [AFAB_EBI1_CH0_RESET] = { 0x20c0, 7 },
-+ [AFAB_EBI1_CH1_RESET] = { 0x20c4, 7 },
-+ [SFAB_ADM0_M0_RESET] = { 0x21e0, 7 },
-+ [SFAB_ADM0_M1_RESET] = { 0x21e4, 7 },
-+ [SFAB_ADM0_M2_RESET] = { 0x21e8, 7 },
-+ [ADM0_C2_RESET] = { 0x220c, 4 },
-+ [ADM0_C1_RESET] = { 0x220c, 3 },
-+ [ADM0_C0_RESET] = { 0x220c, 2 },
-+ [ADM0_PBUS_RESET] = { 0x220c, 1 },
-+ [ADM0_RESET] = { 0x220c, 0 },
-+ [QDSS_CLKS_SW_RESET] = { 0x2260, 5 },
-+ [QDSS_POR_RESET] = { 0x2260, 4 },
-+ [QDSS_TSCTR_RESET] = { 0x2260, 3 },
-+ [QDSS_HRESET_RESET] = { 0x2260, 2 },
-+ [QDSS_AXI_RESET] = { 0x2260, 1 },
-+ [QDSS_DBG_RESET] = { 0x2260, 0 },
-+ [SFAB_PCIE_M_RESET] = { 0x22d8, 1 },
-+ [SFAB_PCIE_S_RESET] = { 0x22d8, 0 },
-+ [PCIE_EXT_RESET] = { 0x22dc, 6 },
-+ [PCIE_PHY_RESET] = { 0x22dc, 5 },
-+ [PCIE_PCI_RESET] = { 0x22dc, 4 },
-+ [PCIE_POR_RESET] = { 0x22dc, 3 },
-+ [PCIE_HCLK_RESET] = { 0x22dc, 2 },
-+ [PCIE_ACLK_RESET] = { 0x22dc, 0 },
-+ [SFAB_LPASS_RESET] = { 0x23a0, 7 },
-+ [SFAB_AFAB_M_RESET] = { 0x23e0, 7 },
-+ [AFAB_SFAB_M0_RESET] = { 0x2420, 7 },
-+ [AFAB_SFAB_M1_RESET] = { 0x2424, 7 },
-+ [SFAB_SATA_S_RESET] = { 0x2480, 7 },
-+ [SFAB_DFAB_M_RESET] = { 0x2500, 7 },
-+ [DFAB_SFAB_M_RESET] = { 0x2520, 7 },
-+ [DFAB_SWAY0_RESET] = { 0x2540, 7 },
-+ [DFAB_SWAY1_RESET] = { 0x2544, 7 },
-+ [DFAB_ARB0_RESET] = { 0x2560, 7 },
-+ [DFAB_ARB1_RESET] = { 0x2564, 7 },
-+ [PPSS_PROC_RESET] = { 0x2594, 1 },
-+ [PPSS_RESET] = { 0x2594, 0 },
-+ [DMA_BAM_RESET] = { 0x25c0, 7 },
-+ [SPS_TIC_H_RESET] = { 0x2600, 7 },
-+ [SFAB_CFPB_M_RESET] = { 0x2680, 7 },
-+ [SFAB_CFPB_S_RESET] = { 0x26c0, 7 },
-+ [TSIF_H_RESET] = { 0x2700, 7 },
-+ [CE1_H_RESET] = { 0x2720, 7 },
-+ [CE1_CORE_RESET] = { 0x2724, 7 },
-+ [CE1_SLEEP_RESET] = { 0x2728, 7 },
-+ [CE2_H_RESET] = { 0x2740, 7 },
-+ [CE2_CORE_RESET] = { 0x2744, 7 },
-+ [SFAB_SFPB_M_RESET] = { 0x2780, 7 },
-+ [SFAB_SFPB_S_RESET] = { 0x27a0, 7 },
-+ [RPM_PROC_RESET] = { 0x27c0, 7 },
-+ [PMIC_SSBI2_RESET] = { 0x280c, 12 },
-+ [SDC1_RESET] = { 0x2830, 0 },
-+ [SDC2_RESET] = { 0x2850, 0 },
-+ [SDC3_RESET] = { 0x2870, 0 },
-+ [SDC4_RESET] = { 0x2890, 0 },
-+ [USB_HS1_RESET] = { 0x2910, 0 },
-+ [USB_HSIC_RESET] = { 0x2934, 0 },
-+ [USB_FS1_XCVR_RESET] = { 0x2974, 1 },
-+ [USB_FS1_RESET] = { 0x2974, 0 },
-+ [GSBI1_RESET] = { 0x29dc, 0 },
-+ [GSBI2_RESET] = { 0x29fc, 0 },
-+ [GSBI3_RESET] = { 0x2a1c, 0 },
-+ [GSBI4_RESET] = { 0x2a3c, 0 },
-+ [GSBI5_RESET] = { 0x2a5c, 0 },
-+ [GSBI6_RESET] = { 0x2a7c, 0 },
-+ [GSBI7_RESET] = { 0x2a9c, 0 },
-+ [SPDM_RESET] = { 0x2b6c, 0 },
-+ [SEC_CTRL_RESET] = { 0x2b80, 7 },
-+ [TLMM_H_RESET] = { 0x2ba0, 7 },
-+ [SFAB_SATA_M_RESET] = { 0x2c18, 0 },
-+ [SATA_RESET] = { 0x2c1c, 0 },
-+ [TSSC_RESET] = { 0x2ca0, 7 },
-+ [PDM_RESET] = { 0x2cc0, 12 },
-+ [MPM_H_RESET] = { 0x2da0, 7 },
-+ [MPM_RESET] = { 0x2da4, 0 },
-+ [SFAB_SMPSS_S_RESET] = { 0x2e00, 7 },
-+ [PRNG_RESET] = { 0x2e80, 12 },
-+ [SFAB_CE3_M_RESET] = { 0x36c8, 1 },
-+ [SFAB_CE3_S_RESET] = { 0x36c8, 0 },
-+ [CE3_SLEEP_RESET] = { 0x36d0, 7 },
-+ [PCIE_1_M_RESET] = { 0x3a98, 1 },
-+ [PCIE_1_S_RESET] = { 0x3a98, 0 },
-+ [PCIE_1_EXT_RESET] = { 0x3a9c, 6 },
-+ [PCIE_1_PHY_RESET] = { 0x3a9c, 5 },
-+ [PCIE_1_PCI_RESET] = { 0x3a9c, 4 },
-+ [PCIE_1_POR_RESET] = { 0x3a9c, 3 },
-+ [PCIE_1_HCLK_RESET] = { 0x3a9c, 2 },
-+ [PCIE_1_ACLK_RESET] = { 0x3a9c, 0 },
-+ [PCIE_2_M_RESET] = { 0x3ad8, 1 },
-+ [PCIE_2_S_RESET] = { 0x3ad8, 0 },
-+ [PCIE_2_EXT_RESET] = { 0x3adc, 6 },
-+ [PCIE_2_PHY_RESET] = { 0x3adc, 5 },
-+ [PCIE_2_PCI_RESET] = { 0x3adc, 4 },
-+ [PCIE_2_POR_RESET] = { 0x3adc, 3 },
-+ [PCIE_2_HCLK_RESET] = { 0x3adc, 2 },
-+ [PCIE_2_ACLK_RESET] = { 0x3adc, 0 },
-+ [SFAB_USB30_S_RESET] = { 0x3b54, 1 },
-+ [SFAB_USB30_M_RESET] = { 0x3b54, 0 },
-+ [USB30_0_PORT2_HS_PHY_RESET] = { 0x3b50, 5 },
-+ [USB30_0_MASTER_RESET] = { 0x3b50, 4 },
-+ [USB30_0_SLEEP_RESET] = { 0x3b50, 3 },
-+ [USB30_0_UTMI_PHY_RESET] = { 0x3b50, 2 },
-+ [USB30_0_POWERON_RESET] = { 0x3b50, 1 },
-+ [USB30_0_PHY_RESET] = { 0x3b50, 0 },
-+ [USB30_1_MASTER_RESET] = { 0x3b58, 4 },
-+ [USB30_1_SLEEP_RESET] = { 0x3b58, 3 },
-+ [USB30_1_UTMI_PHY_RESET] = { 0x3b58, 2 },
-+ [USB30_1_POWERON_RESET] = { 0x3b58, 1 },
-+ [USB30_1_PHY_RESET] = { 0x3b58, 0 },
-+ [NSSFB0_RESET] = { 0x3b60, 6 },
-+ [NSSFB1_RESET] = { 0x3b60, 7 },
-+};
-+
-+static const struct regmap_config gcc_ipq806x_regmap_config = {
-+ .reg_bits = 32,
-+ .reg_stride = 4,
-+ .val_bits = 32,
-+ .max_register = 0x3e40,
-+ .fast_io = true,
-+};
-+
-+static const struct qcom_cc_desc gcc_ipq806x_desc = {
-+ .config = &gcc_ipq806x_regmap_config,
-+ .clks = gcc_ipq806x_clks,
-+ .num_clks = ARRAY_SIZE(gcc_ipq806x_clks),
-+ .resets = gcc_ipq806x_resets,
-+ .num_resets = ARRAY_SIZE(gcc_ipq806x_resets),
-+};
-+
-+static const struct of_device_id gcc_ipq806x_match_table[] = {
-+ { .compatible = "qcom,gcc-ipq8064" },
-+ { }
-+};
-+MODULE_DEVICE_TABLE(of, gcc_ipq806x_match_table);
-+
-+static int gcc_ipq806x_probe(struct platform_device *pdev)
-+{
-+ struct clk *clk;
-+ struct device *dev = &pdev->dev;
-+
-+ /* Temporary until RPM clocks supported */
-+ clk = clk_register_fixed_rate(dev, "cxo", NULL, CLK_IS_ROOT, 25000000);
-+ if (IS_ERR(clk))
-+ return PTR_ERR(clk);
-+
-+ clk = clk_register_fixed_rate(dev, "pxo", NULL, CLK_IS_ROOT, 25000000);
-+ if (IS_ERR(clk))
-+ return PTR_ERR(clk);
-+
-+ return qcom_cc_probe(pdev, &gcc_ipq806x_desc);
-+}
-+
-+static int gcc_ipq806x_remove(struct platform_device *pdev)
-+{
-+ qcom_cc_remove(pdev);
-+ return 0;
-+}
-+
-+static struct platform_driver gcc_ipq806x_driver = {
-+ .probe = gcc_ipq806x_probe,
-+ .remove = gcc_ipq806x_remove,
-+ .driver = {
-+ .name = "gcc-ipq806x",
-+ .owner = THIS_MODULE,
-+ .of_match_table = gcc_ipq806x_match_table,
-+ },
-+};
-+
-+static int __init gcc_ipq806x_init(void)
-+{
-+ return platform_driver_register(&gcc_ipq806x_driver);
-+}
-+core_initcall(gcc_ipq806x_init);
-+
-+static void __exit gcc_ipq806x_exit(void)
-+{
-+ platform_driver_unregister(&gcc_ipq806x_driver);
-+}
-+module_exit(gcc_ipq806x_exit);
-+
-+MODULE_DESCRIPTION("QCOM GCC IPQ806x Driver");
-+MODULE_LICENSE("GPL v2");
-+MODULE_ALIAS("platform:gcc-ipq806x");
---- /dev/null
-+++ b/include/dt-bindings/clock/qcom,gcc-ipq806x.h
-@@ -0,0 +1,293 @@
-+/*
-+ * Copyright (c) 2014, The Linux Foundation. All rights reserved.
-+ *
-+ * This software is licensed under the terms of the GNU General Public
-+ * License version 2, as published by the Free Software Foundation, and
-+ * may be copied, distributed, and modified under those terms.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ * GNU General Public License for more details.
-+ */
-+
-+#ifndef _DT_BINDINGS_CLK_GCC_IPQ806X_H
-+#define _DT_BINDINGS_CLK_GCC_IPQ806X_H
-+
-+#define AFAB_CLK_SRC 0
-+#define QDSS_STM_CLK 1
-+#define SCSS_A_CLK 2
-+#define SCSS_H_CLK 3
-+#define AFAB_CORE_CLK 4
-+#define SCSS_XO_SRC_CLK 5
-+#define AFAB_EBI1_CH0_A_CLK 6
-+#define AFAB_EBI1_CH1_A_CLK 7
-+#define AFAB_AXI_S0_FCLK 8
-+#define AFAB_AXI_S1_FCLK 9
-+#define AFAB_AXI_S2_FCLK 10
-+#define AFAB_AXI_S3_FCLK 11
-+#define AFAB_AXI_S4_FCLK 12
-+#define SFAB_CORE_CLK 13
-+#define SFAB_AXI_S0_FCLK 14
-+#define SFAB_AXI_S1_FCLK 15
-+#define SFAB_AXI_S2_FCLK 16
-+#define SFAB_AXI_S3_FCLK 17
-+#define SFAB_AXI_S4_FCLK 18
-+#define SFAB_AXI_S5_FCLK 19
-+#define SFAB_AHB_S0_FCLK 20
-+#define SFAB_AHB_S1_FCLK 21
-+#define SFAB_AHB_S2_FCLK 22
-+#define SFAB_AHB_S3_FCLK 23
-+#define SFAB_AHB_S4_FCLK 24
-+#define SFAB_AHB_S5_FCLK 25
-+#define SFAB_AHB_S6_FCLK 26
-+#define SFAB_AHB_S7_FCLK 27
-+#define QDSS_AT_CLK_SRC 28
-+#define QDSS_AT_CLK 29
-+#define QDSS_TRACECLKIN_CLK_SRC 30
-+#define QDSS_TRACECLKIN_CLK 31
-+#define QDSS_TSCTR_CLK_SRC 32
-+#define QDSS_TSCTR_CLK 33
-+#define SFAB_ADM0_M0_A_CLK 34
-+#define SFAB_ADM0_M1_A_CLK 35
-+#define SFAB_ADM0_M2_H_CLK 36
-+#define ADM0_CLK 37
-+#define ADM0_PBUS_CLK 38
-+#define IMEM0_A_CLK 39
-+#define QDSS_H_CLK 40
-+#define PCIE_A_CLK 41
-+#define PCIE_AUX_CLK 42
-+#define PCIE_H_CLK 43
-+#define PCIE_PHY_CLK 44
-+#define SFAB_CLK_SRC 45
-+#define SFAB_LPASS_Q6_A_CLK 46
-+#define SFAB_AFAB_M_A_CLK 47
-+#define AFAB_SFAB_M0_A_CLK 48
-+#define AFAB_SFAB_M1_A_CLK 49
-+#define SFAB_SATA_S_H_CLK 50
-+#define DFAB_CLK_SRC 51
-+#define DFAB_CLK 52
-+#define SFAB_DFAB_M_A_CLK 53
-+#define DFAB_SFAB_M_A_CLK 54
-+#define DFAB_SWAY0_H_CLK 55
-+#define DFAB_SWAY1_H_CLK 56
-+#define DFAB_ARB0_H_CLK 57
-+#define DFAB_ARB1_H_CLK 58
-+#define PPSS_H_CLK 59
-+#define PPSS_PROC_CLK 60
-+#define PPSS_TIMER0_CLK 61
-+#define PPSS_TIMER1_CLK 62
-+#define PMEM_A_CLK 63
-+#define DMA_BAM_H_CLK 64
-+#define SIC_H_CLK 65
-+#define SPS_TIC_H_CLK 66
-+#define CFPB_2X_CLK_SRC 67
-+#define CFPB_CLK 68
-+#define CFPB0_H_CLK 69
-+#define CFPB1_H_CLK 70
-+#define CFPB2_H_CLK 71
-+#define SFAB_CFPB_M_H_CLK 72
-+#define CFPB_MASTER_H_CLK 73
-+#define SFAB_CFPB_S_H_CLK 74
-+#define CFPB_SPLITTER_H_CLK 75
-+#define TSIF_H_CLK 76
-+#define TSIF_INACTIVITY_TIMERS_CLK 77
-+#define TSIF_REF_SRC 78
-+#define TSIF_REF_CLK 79
-+#define CE1_H_CLK 80
-+#define CE1_CORE_CLK 81
-+#define CE1_SLEEP_CLK 82
-+#define CE2_H_CLK 83
-+#define CE2_CORE_CLK 84
-+#define SFPB_H_CLK_SRC 85
-+#define SFPB_H_CLK 86
-+#define SFAB_SFPB_M_H_CLK 87
-+#define SFAB_SFPB_S_H_CLK 88
-+#define RPM_PROC_CLK 89
-+#define RPM_BUS_H_CLK 90
-+#define RPM_SLEEP_CLK 91
-+#define RPM_TIMER_CLK 92
-+#define RPM_MSG_RAM_H_CLK 93
-+#define PMIC_ARB0_H_CLK 94
-+#define PMIC_ARB1_H_CLK 95
-+#define PMIC_SSBI2_SRC 96
-+#define PMIC_SSBI2_CLK 97
-+#define SDC1_H_CLK 98
-+#define SDC2_H_CLK 99
-+#define SDC3_H_CLK 100
-+#define SDC4_H_CLK 101
-+#define SDC1_SRC 102
-+#define SDC1_CLK 103
-+#define SDC2_SRC 104
-+#define SDC2_CLK 105
-+#define SDC3_SRC 106
-+#define SDC3_CLK 107
-+#define SDC4_SRC 108
-+#define SDC4_CLK 109
-+#define USB_HS1_H_CLK 110
-+#define USB_HS1_XCVR_SRC 111
-+#define USB_HS1_XCVR_CLK 112
-+#define USB_HSIC_H_CLK 113
-+#define USB_HSIC_XCVR_SRC 114
-+#define USB_HSIC_XCVR_CLK 115
-+#define USB_HSIC_SYSTEM_CLK_SRC 116
-+#define USB_HSIC_SYSTEM_CLK 117
-+#define CFPB0_C0_H_CLK 118
-+#define CFPB0_D0_H_CLK 119
-+#define CFPB0_C1_H_CLK 120
-+#define CFPB0_D1_H_CLK 121
-+#define USB_FS1_H_CLK 122
-+#define USB_FS1_XCVR_SRC 123
-+#define USB_FS1_XCVR_CLK 124
-+#define USB_FS1_SYSTEM_CLK 125
-+#define GSBI_COMMON_SIM_SRC 126
-+#define GSBI1_H_CLK 127
-+#define GSBI2_H_CLK 128
-+#define GSBI3_H_CLK 129
-+#define GSBI4_H_CLK 130
-+#define GSBI5_H_CLK 131
-+#define GSBI6_H_CLK 132
-+#define GSBI7_H_CLK 133
-+#define GSBI1_QUP_SRC 134
-+#define GSBI1_QUP_CLK 135
-+#define GSBI2_QUP_SRC 136
-+#define GSBI2_QUP_CLK 137
-+#define GSBI3_QUP_SRC 138
-+#define GSBI3_QUP_CLK 139
-+#define GSBI4_QUP_SRC 140
-+#define GSBI4_QUP_CLK 141
-+#define GSBI5_QUP_SRC 142
-+#define GSBI5_QUP_CLK 143
-+#define GSBI6_QUP_SRC 144
-+#define GSBI6_QUP_CLK 145
-+#define GSBI7_QUP_SRC 146
-+#define GSBI7_QUP_CLK 147
-+#define GSBI1_UART_SRC 148
-+#define GSBI1_UART_CLK 149
-+#define GSBI2_UART_SRC 150
-+#define GSBI2_UART_CLK 151
-+#define GSBI3_UART_SRC 152
-+#define GSBI3_UART_CLK 153
-+#define GSBI4_UART_SRC 154
-+#define GSBI4_UART_CLK 155
-+#define GSBI5_UART_SRC 156
-+#define GSBI5_UART_CLK 157
-+#define GSBI6_UART_SRC 158
-+#define GSBI6_UART_CLK 159
-+#define GSBI7_UART_SRC 160
-+#define GSBI7_UART_CLK 161
-+#define GSBI1_SIM_CLK 162
-+#define GSBI2_SIM_CLK 163
-+#define GSBI3_SIM_CLK 164
-+#define GSBI4_SIM_CLK 165
-+#define GSBI5_SIM_CLK 166
-+#define GSBI6_SIM_CLK 167
-+#define GSBI7_SIM_CLK 168
-+#define USB_HSIC_HSIC_CLK_SRC 169
-+#define USB_HSIC_HSIC_CLK 170
-+#define USB_HSIC_HSIO_CAL_CLK 171
-+#define SPDM_CFG_H_CLK 172
-+#define SPDM_MSTR_H_CLK 173
-+#define SPDM_FF_CLK_SRC 174
-+#define SPDM_FF_CLK 175
-+#define SEC_CTRL_CLK 176
-+#define SEC_CTRL_ACC_CLK_SRC 177
-+#define SEC_CTRL_ACC_CLK 178
-+#define TLMM_H_CLK 179
-+#define TLMM_CLK 180
-+#define SATA_H_CLK 181
-+#define SATA_CLK_SRC 182
-+#define SATA_RXOOB_CLK 183
-+#define SATA_PMALIVE_CLK 184
-+#define SATA_PHY_REF_CLK 185
-+#define SATA_A_CLK 186
-+#define SATA_PHY_CFG_CLK 187
-+#define TSSC_CLK_SRC 188
-+#define TSSC_CLK 189
-+#define PDM_SRC 190
-+#define PDM_CLK 191
-+#define GP0_SRC 192
-+#define GP0_CLK 193
-+#define GP1_SRC 194
-+#define GP1_CLK 195
-+#define GP2_SRC 196
-+#define GP2_CLK 197
-+#define MPM_CLK 198
-+#define EBI1_CLK_SRC 199
-+#define EBI1_CH0_CLK 200
-+#define EBI1_CH1_CLK 201
-+#define EBI1_2X_CLK 202
-+#define EBI1_CH0_DQ_CLK 203
-+#define EBI1_CH1_DQ_CLK 204
-+#define EBI1_CH0_CA_CLK 205
-+#define EBI1_CH1_CA_CLK 206
-+#define EBI1_XO_CLK 207
-+#define SFAB_SMPSS_S_H_CLK 208
-+#define PRNG_SRC 209
-+#define PRNG_CLK 210
-+#define PXO_SRC 211
-+#define SPDM_CY_PORT0_CLK 212
-+#define SPDM_CY_PORT1_CLK 213
-+#define SPDM_CY_PORT2_CLK 214
-+#define SPDM_CY_PORT3_CLK 215
-+#define SPDM_CY_PORT4_CLK 216
-+#define SPDM_CY_PORT5_CLK 217
-+#define SPDM_CY_PORT6_CLK 218
-+#define SPDM_CY_PORT7_CLK 219
-+#define PLL0 220
-+#define PLL0_VOTE 221
-+#define PLL3 222
-+#define PLL3_VOTE 223
-+#define PLL4 224
-+#define PLL4_VOTE 225
-+#define PLL8 226
-+#define PLL8_VOTE 227
-+#define PLL9 228
-+#define PLL10 229
-+#define PLL11 230
-+#define PLL12 231
-+#define PLL14 232
-+#define PLL14_VOTE 233
-+#define PLL18 234
-+#define CE5_SRC 235
-+#define CE5_H_CLK 236
-+#define CE5_CORE_CLK 237
-+#define CE3_SLEEP_CLK 238
-+#define SFAB_AHB_S8_FCLK 239
-+#define SPDM_CY_PORT8_CLK 246
-+#define PCIE_ALT_REF_SRC 247
-+#define PCIE_ALT_REF_CLK 248
-+#define PCIE_1_A_CLK 249
-+#define PCIE_1_AUX_CLK 250
-+#define PCIE_1_H_CLK 251
-+#define PCIE_1_PHY_CLK 252
-+#define PCIE_1_ALT_REF_SRC 253
-+#define PCIE_1_ALT_REF_CLK 254
-+#define PCIE_2_A_CLK 255
-+#define PCIE_2_AUX_CLK 256
-+#define PCIE_2_H_CLK 257
-+#define PCIE_2_PHY_CLK 258
-+#define PCIE_2_ALT_REF_SRC 259
-+#define PCIE_2_ALT_REF_CLK 260
-+#define EBI2_CLK 261
-+#define USB30_SLEEP_CLK 262
-+#define USB30_UTMI_SRC 263
-+#define USB30_0_UTMI_CLK 264
-+#define USB30_1_UTMI_CLK 264
-+#define USB30_MASTER_SRC 265
-+#define USB30_0_MASTER_CLK 266
-+#define USB30_1_MASTER_CLK 267
-+#define GMAC_CORE1_CLK_SRC 268
-+#define GMAC_CORE2_CLK_SRC 269
-+#define GMAC_CORE3_CLK_SRC 270
-+#define GMAC_CORE4_CLK_SRC 271
-+#define GMAC_CORE1_CLK 272
-+#define GMAC_CORE2_CLK 273
-+#define GMAC_CORE3_CLK 274
-+#define GMAC_CORE4_CLK 275
-+#define UBI32_CORE1_CLK_SRC 276
-+#define UBI32_CORE2_CLK_SRC 277
-+#define UBI32_CORE1_CLK 278
-+#define UBI32_CORE2_CLK 279
-+
-+#endif
---- /dev/null
-+++ b/include/dt-bindings/reset/qcom,gcc-ipq806x.h
-@@ -0,0 +1,132 @@
-+/*
-+ * Copyright (c) 2014, The Linux Foundation. All rights reserved.
-+ *
-+ * This software is licensed under the terms of the GNU General Public
-+ * License version 2, as published by the Free Software Foundation, and
-+ * may be copied, distributed, and modified under those terms.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ * GNU General Public License for more details.
-+ */
-+
-+#ifndef _DT_BINDINGS_RESET_IPQ_806X_H
-+#define _DT_BINDINGS_RESET_IPQ_806X_H
-+
-+#define QDSS_STM_RESET 0
-+#define AFAB_SMPSS_S_RESET 1
-+#define AFAB_SMPSS_M1_RESET 2
-+#define AFAB_SMPSS_M0_RESET 3
-+#define AFAB_EBI1_CH0_RESET 4
-+#define AFAB_EBI1_CH1_RESET 5
-+#define SFAB_ADM0_M0_RESET 6
-+#define SFAB_ADM0_M1_RESET 7
-+#define SFAB_ADM0_M2_RESET 8
-+#define ADM0_C2_RESET 9
-+#define ADM0_C1_RESET 10
-+#define ADM0_C0_RESET 11
-+#define ADM0_PBUS_RESET 12
-+#define ADM0_RESET 13
-+#define QDSS_CLKS_SW_RESET 14
-+#define QDSS_POR_RESET 15
-+#define QDSS_TSCTR_RESET 16
-+#define QDSS_HRESET_RESET 17
-+#define QDSS_AXI_RESET 18
-+#define QDSS_DBG_RESET 19
-+#define SFAB_PCIE_M_RESET 20
-+#define SFAB_PCIE_S_RESET 21
-+#define PCIE_EXT_RESET 22
-+#define PCIE_PHY_RESET 23
-+#define PCIE_PCI_RESET 24
-+#define PCIE_POR_RESET 25
-+#define PCIE_HCLK_RESET 26
-+#define PCIE_ACLK_RESET 27
-+#define SFAB_LPASS_RESET 28
-+#define SFAB_AFAB_M_RESET 29
-+#define AFAB_SFAB_M0_RESET 30
-+#define AFAB_SFAB_M1_RESET 31
-+#define SFAB_SATA_S_RESET 32
-+#define SFAB_DFAB_M_RESET 33
-+#define DFAB_SFAB_M_RESET 34
-+#define DFAB_SWAY0_RESET 35
-+#define DFAB_SWAY1_RESET 36
-+#define DFAB_ARB0_RESET 37
-+#define DFAB_ARB1_RESET 38
-+#define PPSS_PROC_RESET 39
-+#define PPSS_RESET 40
-+#define DMA_BAM_RESET 41
-+#define SPS_TIC_H_RESET 42
-+#define SFAB_CFPB_M_RESET 43
-+#define SFAB_CFPB_S_RESET 44
-+#define TSIF_H_RESET 45
-+#define CE1_H_RESET 46
-+#define CE1_CORE_RESET 47
-+#define CE1_SLEEP_RESET 48
-+#define CE2_H_RESET 49
-+#define CE2_CORE_RESET 50
-+#define SFAB_SFPB_M_RESET 51
-+#define SFAB_SFPB_S_RESET 52
-+#define RPM_PROC_RESET 53
-+#define PMIC_SSBI2_RESET 54
-+#define SDC1_RESET 55
-+#define SDC2_RESET 56
-+#define SDC3_RESET 57
-+#define SDC4_RESET 58
-+#define USB_HS1_RESET 59
-+#define USB_HSIC_RESET 60
-+#define USB_FS1_XCVR_RESET 61
-+#define USB_FS1_RESET 62
-+#define GSBI1_RESET 63
-+#define GSBI2_RESET 64
-+#define GSBI3_RESET 65
-+#define GSBI4_RESET 66
-+#define GSBI5_RESET 67
-+#define GSBI6_RESET 68
-+#define GSBI7_RESET 69
-+#define SPDM_RESET 70
-+#define SEC_CTRL_RESET 71
-+#define TLMM_H_RESET 72
-+#define SFAB_SATA_M_RESET 73
-+#define SATA_RESET 74
-+#define TSSC_RESET 75
-+#define PDM_RESET 76
-+#define MPM_H_RESET 77
-+#define MPM_RESET 78
-+#define SFAB_SMPSS_S_RESET 79
-+#define PRNG_RESET 80
-+#define SFAB_CE3_M_RESET 81
-+#define SFAB_CE3_S_RESET 82
-+#define CE3_SLEEP_RESET 83
-+#define PCIE_1_M_RESET 84
-+#define PCIE_1_S_RESET 85
-+#define PCIE_1_EXT_RESET 86
-+#define PCIE_1_PHY_RESET 87
-+#define PCIE_1_PCI_RESET 88
-+#define PCIE_1_POR_RESET 89
-+#define PCIE_1_HCLK_RESET 90
-+#define PCIE_1_ACLK_RESET 91
-+#define PCIE_2_M_RESET 92
-+#define PCIE_2_S_RESET 93
-+#define PCIE_2_EXT_RESET 94
-+#define PCIE_2_PHY_RESET 95
-+#define PCIE_2_PCI_RESET 96
-+#define PCIE_2_POR_RESET 97
-+#define PCIE_2_HCLK_RESET 98
-+#define PCIE_2_ACLK_RESET 99
-+#define SFAB_USB30_S_RESET 100
-+#define SFAB_USB30_M_RESET 101
-+#define USB30_0_PORT2_HS_PHY_RESET 102
-+#define USB30_0_MASTER_RESET 103
-+#define USB30_0_SLEEP_RESET 104
-+#define USB30_0_UTMI_PHY_RESET 105
-+#define USB30_0_POWERON_RESET 106
-+#define USB30_0_PHY_RESET 107
-+#define USB30_1_MASTER_RESET 108
-+#define USB30_1_SLEEP_RESET 109
-+#define USB30_1_UTMI_PHY_RESET 110
-+#define USB30_1_POWERON_RESET 111
-+#define USB30_1_PHY_RESET 112
-+#define NSSFB0_RESET 113
-+#define NSSFB1_RESET 114
-+#endif
diff --git a/target/linux/ipq806x/patches/0126-clk-Add-safe-switch-hook.patch b/target/linux/ipq806x/patches/0126-clk-Add-safe-switch-hook.patch
deleted file mode 100644
index a78319f..0000000
--- a/target/linux/ipq806x/patches/0126-clk-Add-safe-switch-hook.patch
+++ /dev/null
@@ -1,146 +0,0 @@
-From b7b3ceec506179d59e46e3a8ea8b370872cc7fcb Mon Sep 17 00:00:00 2001
-From: Stephen Boyd <sboyd@codeaurora.org>
-Date: Mon, 31 Mar 2014 16:52:29 -0700
-Subject: [PATCH 126/182] clk: Add safe switch hook
-
-Sometimes clocks can't accept their parent source turning off
-while the source is reprogrammed to a different rate. Most
-notably CPU clocks require a way to switch away from the current
-PLL they're running on, reprogram that PLL to a new rate, and
-then switch back to the PLL with the new rate once they're done.
-Add a hook that drivers can implement allowing them to return a
-'safe parent' that they can switch their parent to while the
-upstream source is reprogrammed to support this.
-
-Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
----
- drivers/clk/clk.c | 53 ++++++++++++++++++++++++++++++++++++------
- include/linux/clk-private.h | 2 ++
- include/linux/clk-provider.h | 1 +
- 3 files changed, 49 insertions(+), 7 deletions(-)
-
---- a/drivers/clk/clk.c
-+++ b/drivers/clk/clk.c
-@@ -1356,6 +1356,7 @@ static void clk_calc_subtree(struct clk
- struct clk *new_parent, u8 p_index)
- {
- struct clk *child;
-+ struct clk *parent;
-
- clk->new_rate = new_rate;
- clk->new_parent = new_parent;
-@@ -1365,6 +1366,17 @@ static void clk_calc_subtree(struct clk
- if (new_parent && new_parent != clk->parent)
- new_parent->new_child = clk;
-
-+ if (clk->ops->get_safe_parent) {
-+ parent = clk->ops->get_safe_parent(clk->hw);
-+ if (parent) {
-+ p_index = clk_fetch_parent_index(clk, parent);
-+ clk->safe_parent_index = p_index;
-+ clk->safe_parent = parent;
-+ }
-+ } else {
-+ clk->safe_parent = NULL;
-+ }
-+
- hlist_for_each_entry(child, &clk->children, child_node) {
- if (child->ops->recalc_rate)
- child->new_rate = child->ops->recalc_rate(child->hw, new_rate);
-@@ -1450,14 +1462,42 @@ out:
- static struct clk *clk_propagate_rate_change(struct clk *clk, unsigned long event)
- {
- struct clk *child, *tmp_clk, *fail_clk = NULL;
-+ struct clk *old_parent;
- int ret = NOTIFY_DONE;
-
-- if (clk->rate == clk->new_rate)
-+ if (clk->rate == clk->new_rate && event != POST_RATE_CHANGE)
- return NULL;
-
-+ switch (event) {
-+ case PRE_RATE_CHANGE:
-+ if (clk->safe_parent)
-+ clk->ops->set_parent(clk->hw, clk->safe_parent_index);
-+ break;
-+ case POST_RATE_CHANGE:
-+ if (clk->safe_parent) {
-+ old_parent = __clk_set_parent_before(clk,
-+ clk->new_parent);
-+ if (clk->ops->set_rate_and_parent) {
-+ clk->ops->set_rate_and_parent(clk->hw,
-+ clk->new_rate,
-+ clk->new_parent ?
-+ clk->new_parent->rate : 0,
-+ clk->new_parent_index);
-+ } else if (clk->ops->set_parent) {
-+ clk->ops->set_parent(clk->hw,
-+ clk->new_parent_index);
-+ }
-+ __clk_set_parent_after(clk, clk->new_parent,
-+ old_parent);
-+ }
-+ break;
-+ }
-+
- if (clk->notifier_count) {
-- ret = __clk_notify(clk, event, clk->rate, clk->new_rate);
-- if (ret & NOTIFY_STOP_MASK)
-+ if (event != POST_RATE_CHANGE)
-+ ret = __clk_notify(clk, event, clk->rate,
-+ clk->new_rate);
-+ if (ret & NOTIFY_STOP_MASK && event != POST_RATE_CHANGE)
- fail_clk = clk;
- }
-
-@@ -1500,7 +1540,8 @@ static void clk_change_rate(struct clk *
- else if (clk->parent)
- best_parent_rate = clk->parent->rate;
-
-- if (clk->new_parent && clk->new_parent != clk->parent) {
-+ if (clk->new_parent && clk->new_parent != clk->parent &&
-+ !clk->safe_parent) {
- old_parent = __clk_set_parent_before(clk, clk->new_parent);
-
- if (clk->ops->set_rate_and_parent) {
-@@ -1523,9 +1564,6 @@ static void clk_change_rate(struct clk *
- else
- clk->rate = best_parent_rate;
-
-- if (clk->notifier_count && old_rate != clk->rate)
-- __clk_notify(clk, POST_RATE_CHANGE, old_rate, clk->rate);
--
- /*
- * Use safe iteration, as change_rate can actually swap parents
- * for certain clock types.
-@@ -1603,6 +1641,7 @@ int clk_set_rate(struct clk *clk, unsign
- /* change the rates */
- clk_change_rate(top);
-
-+ clk_propagate_rate_change(top, POST_RATE_CHANGE);
- out:
- clk_prepare_unlock();
-
---- a/include/linux/clk-private.h
-+++ b/include/linux/clk-private.h
-@@ -38,8 +38,10 @@ struct clk {
- struct clk **parents;
- u8 num_parents;
- u8 new_parent_index;
-+ u8 safe_parent_index;
- unsigned long rate;
- unsigned long new_rate;
-+ struct clk *safe_parent;
- struct clk *new_parent;
- struct clk *new_child;
- unsigned long flags;
---- a/include/linux/clk-provider.h
-+++ b/include/linux/clk-provider.h
-@@ -157,6 +157,7 @@ struct clk_ops {
- struct clk **best_parent_clk);
- int (*set_parent)(struct clk_hw *hw, u8 index);
- u8 (*get_parent)(struct clk_hw *hw);
-+ struct clk *(*get_safe_parent)(struct clk_hw *hw);
- int (*set_rate)(struct clk_hw *hw, unsigned long,
- unsigned long);
- int (*set_rate_and_parent)(struct clk_hw *hw,
diff --git a/target/linux/ipq806x/patches/0127-clk-qcom-Add-support-for-setting-rates-on-PLLs.patch b/target/linux/ipq806x/patches/0127-clk-qcom-Add-support-for-setting-rates-on-PLLs.patch
deleted file mode 100644
index 07ffdac..0000000
--- a/target/linux/ipq806x/patches/0127-clk-qcom-Add-support-for-setting-rates-on-PLLs.patch
+++ /dev/null
@@ -1,148 +0,0 @@
-From fd06a2cc719296f65a280cb1533b125f63cfcb34 Mon Sep 17 00:00:00 2001
-From: Stephen Boyd <sboyd@codeaurora.org>
-Date: Mon, 28 Apr 2014 15:58:11 -0700
-Subject: [PATCH 127/182] clk: qcom: Add support for setting rates on PLLs
-
-Some PLLs may require changing their rate at runtime. Add support
-for these PLLs.
-
-Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
----
- drivers/clk/qcom/clk-pll.c | 68 +++++++++++++++++++++++++++++++++++++++++++-
- drivers/clk/qcom/clk-pll.h | 20 +++++++++++++
- 2 files changed, 87 insertions(+), 1 deletion(-)
-
---- a/drivers/clk/qcom/clk-pll.c
-+++ b/drivers/clk/qcom/clk-pll.c
-@@ -97,7 +97,7 @@ static unsigned long
- clk_pll_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)
- {
- struct clk_pll *pll = to_clk_pll(hw);
-- u32 l, m, n;
-+ u32 l, m, n, config;
- unsigned long rate;
- u64 tmp;
-
-@@ -116,13 +116,79 @@ clk_pll_recalc_rate(struct clk_hw *hw, u
- do_div(tmp, n);
- rate += tmp;
- }
-+ if (pll->post_div_width) {
-+ regmap_read(pll->clkr.regmap, pll->config_reg, &config);
-+ config >>= pll->post_div_shift;
-+ config &= BIT(pll->post_div_width) - 1;
-+ rate /= config + 1;
-+ }
-+
- return rate;
- }
-
-+static const
-+struct pll_freq_tbl *find_freq(const struct pll_freq_tbl *f, unsigned long rate)
-+{
-+ if (!f)
-+ return NULL;
-+
-+ for (; f->freq; f++)
-+ if (rate <= f->freq)
-+ return f;
-+
-+ return NULL;
-+}
-+
-+static long
-+clk_pll_determine_rate(struct clk_hw *hw, unsigned long rate,
-+ unsigned long *p_rate, struct clk **p)
-+{
-+ struct clk_pll *pll = to_clk_pll(hw);
-+ const struct pll_freq_tbl *f;
-+
-+ f = find_freq(pll->freq_tbl, rate);
-+ if (!f)
-+ return clk_pll_recalc_rate(hw, *p_rate);
-+
-+ return f->freq;
-+}
-+
-+static int
-+clk_pll_set_rate(struct clk_hw *hw, unsigned long rate, unsigned long p_rate)
-+{
-+ struct clk_pll *pll = to_clk_pll(hw);
-+ const struct pll_freq_tbl *f;
-+ bool enabled;
-+ u32 mode;
-+ u32 enable_mask = PLL_OUTCTRL | PLL_BYPASSNL | PLL_RESET_N;
-+
-+ f = find_freq(pll->freq_tbl, rate);
-+ if (!f)
-+ return -EINVAL;
-+
-+ regmap_read(pll->clkr.regmap, pll->mode_reg, &mode);
-+ enabled = (mode & enable_mask) == enable_mask;
-+
-+ if (enabled)
-+ clk_pll_disable(hw);
-+
-+ regmap_update_bits(pll->clkr.regmap, pll->l_reg, 0x3ff, f->l);
-+ regmap_update_bits(pll->clkr.regmap, pll->m_reg, 0x7ffff, f->m);
-+ regmap_update_bits(pll->clkr.regmap, pll->n_reg, 0x7ffff, f->n);
-+ regmap_write(pll->clkr.regmap, pll->config_reg, f->ibits);
-+
-+ if (enabled)
-+ clk_pll_enable(hw);
-+
-+ return 0;
-+}
-+
- const struct clk_ops clk_pll_ops = {
- .enable = clk_pll_enable,
- .disable = clk_pll_disable,
- .recalc_rate = clk_pll_recalc_rate,
-+ .determine_rate = clk_pll_determine_rate,
-+ .set_rate = clk_pll_set_rate,
- };
- EXPORT_SYMBOL_GPL(clk_pll_ops);
-
---- a/drivers/clk/qcom/clk-pll.h
-+++ b/drivers/clk/qcom/clk-pll.h
-@@ -18,6 +18,21 @@
- #include "clk-regmap.h"
-
- /**
-+ * struct pll_freq_tbl - PLL frequency table
-+ * @l: L value
-+ * @m: M value
-+ * @n: N value
-+ * @ibits: internal values
-+ */
-+struct pll_freq_tbl {
-+ unsigned long freq;
-+ u16 l;
-+ u16 m;
-+ u16 n;
-+ u32 ibits;
-+};
-+
-+/**
- * struct clk_pll - phase locked loop (PLL)
- * @l_reg: L register
- * @m_reg: M register
-@@ -26,6 +41,7 @@
- * @mode_reg: mode register
- * @status_reg: status register
- * @status_bit: ANDed with @status_reg to determine if PLL is enabled
-+ * @freq_tbl: PLL frequency table
- * @hw: handle between common and hardware-specific interfaces
- */
- struct clk_pll {
-@@ -36,6 +52,10 @@ struct clk_pll {
- u32 mode_reg;
- u32 status_reg;
- u8 status_bit;
-+ u8 post_div_width;
-+ u8 post_div_shift;
-+
-+ const struct pll_freq_tbl *freq_tbl;
-
- struct clk_regmap clkr;
- };
diff --git a/target/linux/ipq806x/patches/0128-clk-qcom-Add-support-for-banked-MD-RCGs.patch b/target/linux/ipq806x/patches/0128-clk-qcom-Add-support-for-banked-MD-RCGs.patch
deleted file mode 100644
index 38104b9..0000000
--- a/target/linux/ipq806x/patches/0128-clk-qcom-Add-support-for-banked-MD-RCGs.patch
+++ /dev/null
@@ -1,308 +0,0 @@
-From 856324d2daa3246ac62d7920d6a274e1fa35bcf5 Mon Sep 17 00:00:00 2001
-From: Stephen Boyd <sboyd@codeaurora.org>
-Date: Mon, 28 Apr 2014 15:59:16 -0700
-Subject: [PATCH 128/182] clk: qcom: Add support for banked MD RCGs
-
-The banked MD RCGs in global clock control have a different
-register layout than the ones implemented in multimedia clock
-control. Add support for these types of clocks so we can change
-the rates of the UBI32 clocks.
-
-Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
----
- drivers/clk/qcom/clk-rcg.c | 99 ++++++++++++++++++++-------------------
- drivers/clk/qcom/clk-rcg.h | 5 +-
- drivers/clk/qcom/mmcc-msm8960.c | 24 +++++++---
- 3 files changed, 73 insertions(+), 55 deletions(-)
-
---- a/drivers/clk/qcom/clk-rcg.c
-+++ b/drivers/clk/qcom/clk-rcg.c
-@@ -67,16 +67,16 @@ static u8 clk_dyn_rcg_get_parent(struct
- {
- struct clk_dyn_rcg *rcg = to_clk_dyn_rcg(hw);
- int num_parents = __clk_get_num_parents(hw->clk);
-- u32 ns, ctl;
-+ u32 ns, reg;
- int bank;
- int i;
- struct src_sel *s;
-
-- regmap_read(rcg->clkr.regmap, rcg->clkr.enable_reg, &ctl);
-- bank = reg_to_bank(rcg, ctl);
-+ regmap_read(rcg->clkr.regmap, rcg->bank_reg, &reg);
-+ bank = reg_to_bank(rcg, reg);
- s = &rcg->s[bank];
-
-- regmap_read(rcg->clkr.regmap, rcg->ns_reg, &ns);
-+ regmap_read(rcg->clkr.regmap, rcg->ns_reg[bank], &ns);
- ns = ns_to_src(s, ns);
-
- for (i = 0; i < num_parents; i++)
-@@ -192,90 +192,93 @@ static u32 mn_to_reg(struct mn *mn, u32
-
- static void configure_bank(struct clk_dyn_rcg *rcg, const struct freq_tbl *f)
- {
-- u32 ns, md, ctl, *regp;
-+ u32 ns, md, reg;
- int bank, new_bank;
- struct mn *mn;
- struct pre_div *p;
- struct src_sel *s;
- bool enabled;
-- u32 md_reg;
-- u32 bank_reg;
-+ u32 md_reg, ns_reg;
- bool banked_mn = !!rcg->mn[1].width;
-+ bool banked_p = !!rcg->p[1].pre_div_width;
- struct clk_hw *hw = &rcg->clkr.hw;
-
- enabled = __clk_is_enabled(hw->clk);
-
-- regmap_read(rcg->clkr.regmap, rcg->ns_reg, &ns);
-- regmap_read(rcg->clkr.regmap, rcg->clkr.enable_reg, &ctl);
--
-- if (banked_mn) {
-- regp = &ctl;
-- bank_reg = rcg->clkr.enable_reg;
-- } else {
-- regp = &ns;
-- bank_reg = rcg->ns_reg;
-- }
--
-- bank = reg_to_bank(rcg, *regp);
-+ regmap_read(rcg->clkr.regmap, rcg->bank_reg, &reg);
-+ bank = reg_to_bank(rcg, reg);
- new_bank = enabled ? !bank : bank;
-
-+ ns_reg = rcg->ns_reg[new_bank];
-+ regmap_read(rcg->clkr.regmap, ns_reg, &ns);
-+
- if (banked_mn) {
- mn = &rcg->mn[new_bank];
- md_reg = rcg->md_reg[new_bank];
-
- ns |= BIT(mn->mnctr_reset_bit);
-- regmap_write(rcg->clkr.regmap, rcg->ns_reg, ns);
-+ regmap_write(rcg->clkr.regmap, ns_reg, ns);
-
- regmap_read(rcg->clkr.regmap, md_reg, &md);
- md = mn_to_md(mn, f->m, f->n, md);
- regmap_write(rcg->clkr.regmap, md_reg, md);
-
- ns = mn_to_ns(mn, f->m, f->n, ns);
-- regmap_write(rcg->clkr.regmap, rcg->ns_reg, ns);
-+ regmap_write(rcg->clkr.regmap, ns_reg, ns);
-
-- ctl = mn_to_reg(mn, f->m, f->n, ctl);
-- regmap_write(rcg->clkr.regmap, rcg->clkr.enable_reg, ctl);
-+ /* Two NS registers means mode control is in NS register */
-+ if (rcg->ns_reg[0] != rcg->ns_reg[1]) {
-+ ns = mn_to_reg(mn, f->m, f->n, ns);
-+ regmap_write(rcg->clkr.regmap, ns_reg, ns);
-+ } else {
-+ reg = mn_to_reg(mn, f->m, f->n, reg);
-+ regmap_write(rcg->clkr.regmap, rcg->bank_reg, reg);
-+ }
-
- ns &= ~BIT(mn->mnctr_reset_bit);
-- regmap_write(rcg->clkr.regmap, rcg->ns_reg, ns);
-- } else {
-+ regmap_write(rcg->clkr.regmap, ns_reg, ns);
-+ }
-+
-+ if (banked_p) {
- p = &rcg->p[new_bank];
- ns = pre_div_to_ns(p, f->pre_div - 1, ns);
- }
-
- s = &rcg->s[new_bank];
- ns = src_to_ns(s, s->parent_map[f->src], ns);
-- regmap_write(rcg->clkr.regmap, rcg->ns_reg, ns);
-+ regmap_write(rcg->clkr.regmap, ns_reg, ns);
-
- if (enabled) {
-- *regp ^= BIT(rcg->mux_sel_bit);
-- regmap_write(rcg->clkr.regmap, bank_reg, *regp);
-+ regmap_read(rcg->clkr.regmap, rcg->bank_reg, &reg);
-+ reg ^= BIT(rcg->mux_sel_bit);
-+ regmap_write(rcg->clkr.regmap, rcg->bank_reg, reg);
- }
- }
-
- static int clk_dyn_rcg_set_parent(struct clk_hw *hw, u8 index)
- {
- struct clk_dyn_rcg *rcg = to_clk_dyn_rcg(hw);
-- u32 ns, ctl, md, reg;
-+ u32 ns, md, reg;
- int bank;
- struct freq_tbl f = { 0 };
- bool banked_mn = !!rcg->mn[1].width;
-+ bool banked_p = !!rcg->p[1].pre_div_width;
-
-- regmap_read(rcg->clkr.regmap, rcg->ns_reg, &ns);
-- regmap_read(rcg->clkr.regmap, rcg->clkr.enable_reg, &ctl);
-- reg = banked_mn ? ctl : ns;
--
-+ regmap_read(rcg->clkr.regmap, rcg->bank_reg, &reg);
- bank = reg_to_bank(rcg, reg);
-
-+ regmap_read(rcg->clkr.regmap, rcg->ns_reg[bank], &ns);
-+
- if (banked_mn) {
- regmap_read(rcg->clkr.regmap, rcg->md_reg[bank], &md);
- f.m = md_to_m(&rcg->mn[bank], md);
- f.n = ns_m_to_n(&rcg->mn[bank], ns, f.m);
-- } else {
-- f.pre_div = ns_to_pre_div(&rcg->p[bank], ns) + 1;
- }
-- f.src = index;
-
-+ if (banked_p)
-+ f.pre_div = ns_to_pre_div(&rcg->p[bank], ns) + 1;
-+
-+ f.src = index;
- configure_bank(rcg, &f);
-
- return 0;
-@@ -336,28 +339,30 @@ clk_dyn_rcg_recalc_rate(struct clk_hw *h
- u32 m, n, pre_div, ns, md, mode, reg;
- int bank;
- struct mn *mn;
-+ bool banked_p = !!rcg->p[1].pre_div_width;
- bool banked_mn = !!rcg->mn[1].width;
-
-- regmap_read(rcg->clkr.regmap, rcg->ns_reg, &ns);
--
-- if (banked_mn)
-- regmap_read(rcg->clkr.regmap, rcg->clkr.enable_reg, &reg);
-- else
-- reg = ns;
--
-+ regmap_read(rcg->clkr.regmap, rcg->bank_reg, &reg);
- bank = reg_to_bank(rcg, reg);
-
-+ regmap_read(rcg->clkr.regmap, rcg->ns_reg[bank], &ns);
-+ m = n = pre_div = mode = 0;
-+
- if (banked_mn) {
- mn = &rcg->mn[bank];
- regmap_read(rcg->clkr.regmap, rcg->md_reg[bank], &md);
- m = md_to_m(mn, md);
- n = ns_m_to_n(mn, ns, m);
-+ /* Two NS registers means mode control is in NS register */
-+ if (rcg->ns_reg[0] != rcg->ns_reg[1])
-+ reg = ns;
- mode = reg_to_mnctr_mode(mn, reg);
-- return calc_rate(parent_rate, m, n, mode, 0);
-- } else {
-- pre_div = ns_to_pre_div(&rcg->p[bank], ns);
-- return calc_rate(parent_rate, 0, 0, 0, pre_div);
- }
-+
-+ if (banked_p)
-+ pre_div = ns_to_pre_div(&rcg->p[bank], ns);
-+
-+ return calc_rate(parent_rate, m, n, mode, pre_div);
- }
-
- static const
---- a/drivers/clk/qcom/clk-rcg.h
-+++ b/drivers/clk/qcom/clk-rcg.h
-@@ -102,7 +102,7 @@ extern const struct clk_ops clk_rcg_ops;
- * struct clk_dyn_rcg - root clock generator with glitch free mux
- *
- * @mux_sel_bit: bit to switch glitch free mux
-- * @ns_reg: NS register
-+ * @ns_reg: NS0 and NS1 register
- * @md_reg: MD0 and MD1 register
- * @mn: mn counter (banked)
- * @s: source selector (banked)
-@@ -112,8 +112,9 @@ extern const struct clk_ops clk_rcg_ops;
- *
- */
- struct clk_dyn_rcg {
-- u32 ns_reg;
-+ u32 ns_reg[2];
- u32 md_reg[2];
-+ u32 bank_reg;
-
- u8 mux_sel_bit;
-
---- a/drivers/clk/qcom/mmcc-msm8960.c
-+++ b/drivers/clk/qcom/mmcc-msm8960.c
-@@ -728,9 +728,11 @@ static struct freq_tbl clk_tbl_gfx2d[] =
- };
-
- static struct clk_dyn_rcg gfx2d0_src = {
-- .ns_reg = 0x0070,
-+ .ns_reg[0] = 0x0070,
-+ .ns_reg[1] = 0x0070,
- .md_reg[0] = 0x0064,
- .md_reg[1] = 0x0068,
-+ .bank_reg = 0x0060,
- .mn[0] = {
- .mnctr_en_bit = 8,
- .mnctr_reset_bit = 25,
-@@ -786,9 +788,11 @@ static struct clk_branch gfx2d0_clk = {
- };
-
- static struct clk_dyn_rcg gfx2d1_src = {
-- .ns_reg = 0x007c,
-+ .ns_reg[0] = 0x007c,
-+ .ns_reg[1] = 0x007c,
- .md_reg[0] = 0x0078,
- .md_reg[1] = 0x006c,
-+ .bank_reg = 0x0074,
- .mn[0] = {
- .mnctr_en_bit = 8,
- .mnctr_reset_bit = 25,
-@@ -864,9 +868,11 @@ static struct freq_tbl clk_tbl_gfx3d[] =
- };
-
- static struct clk_dyn_rcg gfx3d_src = {
-- .ns_reg = 0x008c,
-+ .ns_reg[0] = 0x008c,
-+ .ns_reg[1] = 0x008c,
- .md_reg[0] = 0x0084,
- .md_reg[1] = 0x0088,
-+ .bank_reg = 0x0080,
- .mn[0] = {
- .mnctr_en_bit = 8,
- .mnctr_reset_bit = 25,
-@@ -1053,9 +1059,11 @@ static struct freq_tbl clk_tbl_mdp[] = {
- };
-
- static struct clk_dyn_rcg mdp_src = {
-- .ns_reg = 0x00d0,
-+ .ns_reg[0] = 0x00d0,
-+ .ns_reg[1] = 0x00d0,
- .md_reg[0] = 0x00c4,
- .md_reg[1] = 0x00c8,
-+ .bank_reg = 0x00c0,
- .mn[0] = {
- .mnctr_en_bit = 8,
- .mnctr_reset_bit = 31,
-@@ -1160,7 +1168,9 @@ static struct freq_tbl clk_tbl_rot[] = {
- };
-
- static struct clk_dyn_rcg rot_src = {
-- .ns_reg = 0x00e8,
-+ .ns_reg[0] = 0x00e8,
-+ .ns_reg[1] = 0x00e8,
-+ .bank_reg = 0x00e8,
- .p[0] = {
- .pre_div_shift = 22,
- .pre_div_width = 4,
-@@ -1357,9 +1367,11 @@ static struct freq_tbl clk_tbl_vcodec[]
- };
-
- static struct clk_dyn_rcg vcodec_src = {
-- .ns_reg = 0x0100,
-+ .ns_reg[0] = 0x0100,
-+ .ns_reg[1] = 0x0100,
- .md_reg[0] = 0x00fc,
- .md_reg[1] = 0x0128,
-+ .bank_reg = 0x00f8,
- .mn[0] = {
- .mnctr_en_bit = 5,
- .mnctr_reset_bit = 31,
diff --git a/target/linux/ipq806x/patches/0129-clk-qcom-Add-support-for-NSS-GMAC-clocks-and-resets.patch b/target/linux/ipq806x/patches/0129-clk-qcom-Add-support-for-NSS-GMAC-clocks-and-resets.patch
deleted file mode 100644
index 8b8839a..0000000
--- a/target/linux/ipq806x/patches/0129-clk-qcom-Add-support-for-NSS-GMAC-clocks-and-resets.patch
+++ /dev/null
@@ -1,860 +0,0 @@
-From 92fde23153240a6173645dabe4d99f4aa6570bb7 Mon Sep 17 00:00:00 2001
-From: Stephen Boyd <sboyd@codeaurora.org>
-Date: Mon, 28 Apr 2014 16:01:03 -0700
-Subject: [PATCH 129/182] clk: qcom: Add support for NSS/GMAC clocks and
- resets
-
-The NSS driver expects one virtual clock that actually represents
-two clocks (one for each UBI32 core). Register the ubi32 core
-clocks and also make a wrapper virtual clock called nss_core_clk
-to be used by the driver. This will properly handle switching the
-rates of both clocks at the same time like how the NSS driver
-expects it. Also add the TCM clock and the NSS resets.
-
-Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
----
- drivers/clk/qcom/gcc-ipq806x.c | 710 +++++++++++++++++++++++++-
- include/dt-bindings/clock/qcom,gcc-ipq806x.h | 3 +
- include/dt-bindings/reset/qcom,gcc-ipq806x.h | 43 ++
- 3 files changed, 755 insertions(+), 1 deletion(-)
-
---- a/drivers/clk/qcom/gcc-ipq806x.c
-+++ b/drivers/clk/qcom/gcc-ipq806x.c
-@@ -32,6 +32,33 @@
- #include "clk-branch.h"
- #include "reset.h"
-
-+static struct clk_pll pll0 = {
-+ .l_reg = 0x30c4,
-+ .m_reg = 0x30c8,
-+ .n_reg = 0x30cc,
-+ .config_reg = 0x30d4,
-+ .mode_reg = 0x30c0,
-+ .status_reg = 0x30d8,
-+ .status_bit = 16,
-+ .clkr.hw.init = &(struct clk_init_data){
-+ .name = "pll0",
-+ .parent_names = (const char *[]){ "pxo" },
-+ .num_parents = 1,
-+ .ops = &clk_pll_ops,
-+ },
-+};
-+
-+static struct clk_regmap pll0_vote = {
-+ .enable_reg = 0x34c0,
-+ .enable_mask = BIT(0),
-+ .hw.init = &(struct clk_init_data){
-+ .name = "pll0_vote",
-+ .parent_names = (const char *[]){ "pll0" },
-+ .num_parents = 1,
-+ .ops = &clk_pll_vote_ops,
-+ },
-+};
-+
- static struct clk_pll pll3 = {
- .l_reg = 0x3164,
- .m_reg = 0x3168,
-@@ -102,11 +129,46 @@ static struct clk_regmap pll14_vote = {
- },
- };
-
-+#define NSS_PLL_RATE(f, _l, _m, _n, i) \
-+ { \
-+ .freq = f, \
-+ .l = _l, \
-+ .m = _m, \
-+ .n = _n, \
-+ .ibits = i, \
-+ }
-+
-+static struct pll_freq_tbl pll18_freq_tbl[] = {
-+ NSS_PLL_RATE(550000000, 44, 0, 1, 0x01495625),
-+ NSS_PLL_RATE(733000000, 58, 16, 25, 0x014b5625),
-+};
-+
-+static struct clk_pll pll18 = {
-+ .l_reg = 0x31a4,
-+ .m_reg = 0x31a8,
-+ .n_reg = 0x31ac,
-+ .config_reg = 0x31b4,
-+ .mode_reg = 0x31a0,
-+ .status_reg = 0x31b8,
-+ .status_bit = 16,
-+ .post_div_shift = 16,
-+ .post_div_width = 1,
-+ .freq_tbl = pll18_freq_tbl,
-+ .clkr.hw.init = &(struct clk_init_data){
-+ .name = "pll18",
-+ .parent_names = (const char *[]){ "pxo" },
-+ .num_parents = 1,
-+ .ops = &clk_pll_ops,
-+ },
-+};
-+
- #define P_PXO 0
- #define P_PLL8 1
- #define P_PLL3 1
- #define P_PLL0 2
- #define P_CXO 2
-+#define P_PLL14 3
-+#define P_PLL18 4
-
- static const u8 gcc_pxo_pll8_map[] = {
- [P_PXO] = 0,
-@@ -157,6 +219,22 @@ static const char *gcc_pxo_pll8_pll0_map
- "pll0",
- };
-
-+static const u8 gcc_pxo_pll8_pll14_pll18_pll0_map[] = {
-+ [P_PXO] = 0,
-+ [P_PLL8] = 4,
-+ [P_PLL0] = 2,
-+ [P_PLL14] = 5,
-+ [P_PLL18] = 1,
-+};
-+
-+static const char *gcc_pxo_pll8_pll14_pll18_pll0[] = {
-+ "pxo",
-+ "pll8_vote",
-+ "pll0_vote",
-+ "pll14",
-+ "pll18",
-+};
-+
- static struct freq_tbl clk_tbl_gsbi_uart[] = {
- { 1843200, P_PLL8, 2, 6, 625 },
- { 3686400, P_PLL8, 2, 12, 625 },
-@@ -2132,12 +2210,567 @@ static struct clk_branch usb_fs1_h_clk =
- },
- };
-
-+static const struct freq_tbl clk_tbl_gmac[] = {
-+ { 133000000, P_PLL0, 1, 50, 301 },
-+ { }
-+};
-+
-+static struct clk_dyn_rcg gmac_core1_src = {
-+ .ns_reg[0] = 0x3cac,
-+ .ns_reg[1] = 0x3cb0,
-+ .md_reg[0] = 0x3ca4,
-+ .md_reg[1] = 0x3ca8,
-+ .bank_reg = 0x3ca0,
-+ .mn[0] = {
-+ .mnctr_en_bit = 8,
-+ .mnctr_reset_bit = 7,
-+ .mnctr_mode_shift = 5,
-+ .n_val_shift = 16,
-+ .m_val_shift = 16,
-+ .width = 8,
-+ },
-+ .mn[1] = {
-+ .mnctr_en_bit = 8,
-+ .mnctr_reset_bit = 7,
-+ .mnctr_mode_shift = 5,
-+ .n_val_shift = 16,
-+ .m_val_shift = 16,
-+ .width = 8,
-+ },
-+ .s[0] = {
-+ .src_sel_shift = 0,
-+ .parent_map = gcc_pxo_pll8_pll14_pll18_pll0_map,
-+ },
-+ .s[1] = {
-+ .src_sel_shift = 0,
-+ .parent_map = gcc_pxo_pll8_pll14_pll18_pll0_map,
-+ },
-+ .p[0] = {
-+ .pre_div_shift = 3,
-+ .pre_div_width = 2,
-+ },
-+ .p[1] = {
-+ .pre_div_shift = 3,
-+ .pre_div_width = 2,
-+ },
-+ .mux_sel_bit = 0,
-+ .freq_tbl = clk_tbl_gmac,
-+ .clkr = {
-+ .enable_reg = 0x3ca0,
-+ .enable_mask = BIT(1),
-+ .hw.init = &(struct clk_init_data){
-+ .name = "gmac_core1_src",
-+ .parent_names = gcc_pxo_pll8_pll14_pll18_pll0,
-+ .num_parents = 5,
-+ .ops = &clk_dyn_rcg_ops,
-+ },
-+ },
-+};
-+
-+static struct clk_branch gmac_core1_clk = {
-+ .halt_reg = 0x3c20,
-+ .halt_bit = 4,
-+ .hwcg_reg = 0x3cb4,
-+ .hwcg_bit = 6,
-+ .clkr = {
-+ .enable_reg = 0x3cb4,
-+ .enable_mask = BIT(4),
-+ .hw.init = &(struct clk_init_data){
-+ .name = "gmac_core1_clk",
-+ .parent_names = (const char *[]){
-+ "gmac_core1_src",
-+ },
-+ .num_parents = 1,
-+ .ops = &clk_branch_ops,
-+ .flags = CLK_SET_RATE_PARENT,
-+ },
-+ },
-+};
-+
-+static struct clk_dyn_rcg gmac_core2_src = {
-+ .ns_reg[0] = 0x3ccc,
-+ .ns_reg[1] = 0x3cd0,
-+ .md_reg[0] = 0x3cc4,
-+ .md_reg[1] = 0x3cc8,
-+ .bank_reg = 0x3ca0,
-+ .mn[0] = {
-+ .mnctr_en_bit = 8,
-+ .mnctr_reset_bit = 7,
-+ .mnctr_mode_shift = 5,
-+ .n_val_shift = 16,
-+ .m_val_shift = 16,
-+ .width = 8,
-+ },
-+ .mn[1] = {
-+ .mnctr_en_bit = 8,
-+ .mnctr_reset_bit = 7,
-+ .mnctr_mode_shift = 5,
-+ .n_val_shift = 16,
-+ .m_val_shift = 16,
-+ .width = 8,
-+ },
-+ .s[0] = {
-+ .src_sel_shift = 0,
-+ .parent_map = gcc_pxo_pll8_pll14_pll18_pll0_map,
-+ },
-+ .s[1] = {
-+ .src_sel_shift = 0,
-+ .parent_map = gcc_pxo_pll8_pll14_pll18_pll0_map,
-+ },
-+ .p[0] = {
-+ .pre_div_shift = 3,
-+ .pre_div_width = 2,
-+ },
-+ .p[1] = {
-+ .pre_div_shift = 3,
-+ .pre_div_width = 2,
-+ },
-+ .mux_sel_bit = 0,
-+ .freq_tbl = clk_tbl_gmac,
-+ .clkr = {
-+ .enable_reg = 0x3cc0,
-+ .enable_mask = BIT(1),
-+ .hw.init = &(struct clk_init_data){
-+ .name = "gmac_core2_src",
-+ .parent_names = gcc_pxo_pll8_pll14_pll18_pll0,
-+ .num_parents = 5,
-+ .ops = &clk_dyn_rcg_ops,
-+ },
-+ },
-+};
-+
-+static struct clk_branch gmac_core2_clk = {
-+ .halt_reg = 0x3c20,
-+ .halt_bit = 5,
-+ .hwcg_reg = 0x3cd4,
-+ .hwcg_bit = 6,
-+ .clkr = {
-+ .enable_reg = 0x3cd4,
-+ .enable_mask = BIT(4),
-+ .hw.init = &(struct clk_init_data){
-+ .name = "gmac_core2_clk",
-+ .parent_names = (const char *[]){
-+ "gmac_core2_src",
-+ },
-+ .num_parents = 1,
-+ .ops = &clk_branch_ops,
-+ .flags = CLK_SET_RATE_PARENT,
-+ },
-+ },
-+};
-+
-+static struct clk_dyn_rcg gmac_core3_src = {
-+ .ns_reg[0] = 0x3cec,
-+ .ns_reg[1] = 0x3cf0,
-+ .md_reg[0] = 0x3ce4,
-+ .md_reg[1] = 0x3ce8,
-+ .bank_reg = 0x3ce0,
-+ .mn[0] = {
-+ .mnctr_en_bit = 8,
-+ .mnctr_reset_bit = 7,
-+ .mnctr_mode_shift = 5,
-+ .n_val_shift = 16,
-+ .m_val_shift = 16,
-+ .width = 8,
-+ },
-+ .mn[1] = {
-+ .mnctr_en_bit = 8,
-+ .mnctr_reset_bit = 7,
-+ .mnctr_mode_shift = 5,
-+ .n_val_shift = 16,
-+ .m_val_shift = 16,
-+ .width = 8,
-+ },
-+ .s[0] = {
-+ .src_sel_shift = 0,
-+ .parent_map = gcc_pxo_pll8_pll14_pll18_pll0_map,
-+ },
-+ .s[1] = {
-+ .src_sel_shift = 0,
-+ .parent_map = gcc_pxo_pll8_pll14_pll18_pll0_map,
-+ },
-+ .p[0] = {
-+ .pre_div_shift = 3,
-+ .pre_div_width = 2,
-+ },
-+ .p[1] = {
-+ .pre_div_shift = 3,
-+ .pre_div_width = 2,
-+ },
-+ .mux_sel_bit = 0,
-+ .freq_tbl = clk_tbl_gmac,
-+ .clkr = {
-+ .enable_reg = 0x3ce0,
-+ .enable_mask = BIT(1),
-+ .hw.init = &(struct clk_init_data){
-+ .name = "gmac_core3_src",
-+ .parent_names = gcc_pxo_pll8_pll14_pll18_pll0,
-+ .num_parents = 5,
-+ .ops = &clk_dyn_rcg_ops,
-+ },
-+ },
-+};
-+
-+static struct clk_branch gmac_core3_clk = {
-+ .halt_reg = 0x3c20,
-+ .halt_bit = 6,
-+ .hwcg_reg = 0x3cf4,
-+ .hwcg_bit = 6,
-+ .clkr = {
-+ .enable_reg = 0x3cf4,
-+ .enable_mask = BIT(4),
-+ .hw.init = &(struct clk_init_data){
-+ .name = "gmac_core3_clk",
-+ .parent_names = (const char *[]){
-+ "gmac_core3_src",
-+ },
-+ .num_parents = 1,
-+ .ops = &clk_branch_ops,
-+ .flags = CLK_SET_RATE_PARENT,
-+ },
-+ },
-+};
-+
-+static struct clk_dyn_rcg gmac_core4_src = {
-+ .ns_reg[0] = 0x3d0c,
-+ .ns_reg[1] = 0x3d10,
-+ .md_reg[0] = 0x3d04,
-+ .md_reg[1] = 0x3d08,
-+ .bank_reg = 0x3d00,
-+ .mn[0] = {
-+ .mnctr_en_bit = 8,
-+ .mnctr_reset_bit = 7,
-+ .mnctr_mode_shift = 5,
-+ .n_val_shift = 16,
-+ .m_val_shift = 16,
-+ .width = 8,
-+ },
-+ .mn[1] = {
-+ .mnctr_en_bit = 8,
-+ .mnctr_reset_bit = 7,
-+ .mnctr_mode_shift = 5,
-+ .n_val_shift = 16,
-+ .m_val_shift = 16,
-+ .width = 8,
-+ },
-+ .s[0] = {
-+ .src_sel_shift = 0,
-+ .parent_map = gcc_pxo_pll8_pll14_pll18_pll0_map,
-+ },
-+ .s[1] = {
-+ .src_sel_shift = 0,
-+ .parent_map = gcc_pxo_pll8_pll14_pll18_pll0_map,
-+ },
-+ .p[0] = {
-+ .pre_div_shift = 3,
-+ .pre_div_width = 2,
-+ },
-+ .p[1] = {
-+ .pre_div_shift = 3,
-+ .pre_div_width = 2,
-+ },
-+ .mux_sel_bit = 0,
-+ .freq_tbl = clk_tbl_gmac,
-+ .clkr = {
-+ .enable_reg = 0x3d00,
-+ .enable_mask = BIT(1),
-+ .hw.init = &(struct clk_init_data){
-+ .name = "gmac_core4_src",
-+ .parent_names = gcc_pxo_pll8_pll14_pll18_pll0,
-+ .num_parents = 5,
-+ .ops = &clk_dyn_rcg_ops,
-+ },
-+ },
-+};
-+
-+static struct clk_branch gmac_core4_clk = {
-+ .halt_reg = 0x3c20,
-+ .halt_bit = 7,
-+ .hwcg_reg = 0x3d14,
-+ .hwcg_bit = 6,
-+ .clkr = {
-+ .enable_reg = 0x3d14,
-+ .enable_mask = BIT(4),
-+ .hw.init = &(struct clk_init_data){
-+ .name = "gmac_core4_clk",
-+ .parent_names = (const char *[]){
-+ "gmac_core4_src",
-+ },
-+ .num_parents = 1,
-+ .ops = &clk_branch_ops,
-+ .flags = CLK_SET_RATE_PARENT,
-+ },
-+ },
-+};
-+
-+static const struct freq_tbl clk_tbl_nss_tcm[] = {
-+ { 266000000, P_PLL0, 3, 0, 0 },
-+ { 400000000, P_PLL0, 2, 0, 0 },
-+ { }
-+};
-+
-+static struct clk_dyn_rcg nss_tcm_src = {
-+ .ns_reg[0] = 0x3dc4,
-+ .ns_reg[1] = 0x3dc8,
-+ .bank_reg = 0x3dc0,
-+ .s[0] = {
-+ .src_sel_shift = 0,
-+ .parent_map = gcc_pxo_pll8_pll14_pll18_pll0_map,
-+ },
-+ .s[1] = {
-+ .src_sel_shift = 0,
-+ .parent_map = gcc_pxo_pll8_pll14_pll18_pll0_map,
-+ },
-+ .p[0] = {
-+ .pre_div_shift = 3,
-+ .pre_div_width = 4,
-+ },
-+ .p[1] = {
-+ .pre_div_shift = 3,
-+ .pre_div_width = 4,
-+ },
-+ .mux_sel_bit = 0,
-+ .freq_tbl = clk_tbl_nss_tcm,
-+ .clkr = {
-+ .enable_reg = 0x3dc0,
-+ .enable_mask = BIT(1),
-+ .hw.init = &(struct clk_init_data){
-+ .name = "nss_tcm_src",
-+ .parent_names = gcc_pxo_pll8_pll14_pll18_pll0,
-+ .num_parents = 5,
-+ .ops = &clk_dyn_rcg_ops,
-+ },
-+ },
-+};
-+
-+static struct clk_branch nss_tcm_clk = {
-+ .halt_reg = 0x3c20,
-+ .halt_bit = 14,
-+ .clkr = {
-+ .enable_reg = 0x3dd0,
-+ .enable_mask = BIT(6) | BIT(4),
-+ .hw.init = &(struct clk_init_data){
-+ .name = "nss_tcm_clk",
-+ .parent_names = (const char *[]){
-+ "nss_tcm_src",
-+ },
-+ .num_parents = 1,
-+ .ops = &clk_branch_ops,
-+ .flags = CLK_SET_RATE_PARENT,
-+ },
-+ },
-+};
-+
-+static const struct freq_tbl clk_tbl_nss[] = {
-+ { 110000000, P_PLL18, 1, 1, 5 },
-+ { 275000000, P_PLL18, 2, 0, 0 },
-+ { 550000000, P_PLL18, 1, 0, 0 },
-+ { 733000000, P_PLL18, 1, 0, 0 },
-+ { }
-+};
-+
-+static struct clk_dyn_rcg ubi32_core1_src_clk = {
-+ .ns_reg[0] = 0x3d2c,
-+ .ns_reg[1] = 0x3d30,
-+ .md_reg[0] = 0x3d24,
-+ .md_reg[1] = 0x3d28,
-+ .bank_reg = 0x3d20,
-+ .mn[0] = {
-+ .mnctr_en_bit = 8,
-+ .mnctr_reset_bit = 7,
-+ .mnctr_mode_shift = 5,
-+ .n_val_shift = 16,
-+ .m_val_shift = 16,
-+ .width = 8,
-+ },
-+ .mn[1] = {
-+ .mnctr_en_bit = 8,
-+ .mnctr_reset_bit = 7,
-+ .mnctr_mode_shift = 5,
-+ .n_val_shift = 16,
-+ .m_val_shift = 16,
-+ .width = 8,
-+ },
-+ .s[0] = {
-+ .src_sel_shift = 0,
-+ .parent_map = gcc_pxo_pll8_pll14_pll18_pll0_map,
-+ },
-+ .s[1] = {
-+ .src_sel_shift = 0,
-+ .parent_map = gcc_pxo_pll8_pll14_pll18_pll0_map,
-+ },
-+ .p[0] = {
-+ .pre_div_shift = 3,
-+ .pre_div_width = 2,
-+ },
-+ .p[1] = {
-+ .pre_div_shift = 3,
-+ .pre_div_width = 2,
-+ },
-+ .mux_sel_bit = 0,
-+ .freq_tbl = clk_tbl_nss,
-+ .clkr = {
-+ .enable_reg = 0x3d20,
-+ .enable_mask = BIT(1),
-+ .hw.init = &(struct clk_init_data){
-+ .name = "ubi32_core1_src_clk",
-+ .parent_names = gcc_pxo_pll8_pll14_pll18_pll0,
-+ .num_parents = 5,
-+ .ops = &clk_dyn_rcg_ops,
-+ .flags = CLK_SET_RATE_PARENT | CLK_GET_RATE_NOCACHE,
-+ },
-+ },
-+};
-+
-+static struct clk_dyn_rcg ubi32_core2_src_clk = {
-+ .ns_reg[0] = 0x3d4c,
-+ .ns_reg[1] = 0x3d50,
-+ .md_reg[0] = 0x3d44,
-+ .md_reg[1] = 0x3d48,
-+ .bank_reg = 0x3d40,
-+ .mn[0] = {
-+ .mnctr_en_bit = 8,
-+ .mnctr_reset_bit = 7,
-+ .mnctr_mode_shift = 5,
-+ .n_val_shift = 16,
-+ .m_val_shift = 16,
-+ .width = 8,
-+ },
-+ .mn[1] = {
-+ .mnctr_en_bit = 8,
-+ .mnctr_reset_bit = 7,
-+ .mnctr_mode_shift = 5,
-+ .n_val_shift = 16,
-+ .m_val_shift = 16,
-+ .width = 8,
-+ },
-+ .s[0] = {
-+ .src_sel_shift = 0,
-+ .parent_map = gcc_pxo_pll8_pll14_pll18_pll0_map,
-+ },
-+ .s[1] = {
-+ .src_sel_shift = 0,
-+ .parent_map = gcc_pxo_pll8_pll14_pll18_pll0_map,
-+ },
-+ .p[0] = {
-+ .pre_div_shift = 3,
-+ .pre_div_width = 2,
-+ },
-+ .p[1] = {
-+ .pre_div_shift = 3,
-+ .pre_div_width = 2,
-+ },
-+ .mux_sel_bit = 0,
-+ .freq_tbl = clk_tbl_nss,
-+ .clkr = {
-+ .enable_reg = 0x3d40,
-+ .enable_mask = BIT(1),
-+ .hw.init = &(struct clk_init_data){
-+ .name = "ubi32_core2_src_clk",
-+ .parent_names = gcc_pxo_pll8_pll14_pll18_pll0,
-+ .num_parents = 5,
-+ .ops = &clk_dyn_rcg_ops,
-+ .flags = CLK_SET_RATE_PARENT | CLK_GET_RATE_NOCACHE,
-+ },
-+ },
-+};
-+
-+static int nss_core_clk_set_rate(struct clk_hw *hw, unsigned long rate,
-+ unsigned long parent_rate)
-+{
-+ int ret;
-+
-+ ret = clk_dyn_rcg_ops.set_rate(&ubi32_core1_src_clk.clkr.hw, rate,
-+ parent_rate);
-+ if (ret)
-+ return ret;
-+
-+ return clk_dyn_rcg_ops.set_rate(&ubi32_core2_src_clk.clkr.hw, rate,
-+ parent_rate);
-+}
-+
-+static int
-+nss_core_clk_set_rate_and_parent(struct clk_hw *hw, unsigned long rate,
-+ unsigned long parent_rate, u8 index)
-+{
-+ int ret;
-+
-+ ret = clk_dyn_rcg_ops.set_rate_and_parent(
-+ &ubi32_core1_src_clk.clkr.hw, rate, parent_rate, index);
-+ if (ret)
-+ return ret;
-+
-+ ret = clk_dyn_rcg_ops.set_rate_and_parent(
-+ &ubi32_core2_src_clk.clkr.hw, rate, parent_rate, index);
-+ return ret;
-+}
-+
-+static long nss_core_clk_determine_rate(struct clk_hw *hw, unsigned long rate,
-+ unsigned long *p_rate, struct clk **p)
-+{
-+ return clk_dyn_rcg_ops.determine_rate(&ubi32_core1_src_clk.clkr.hw,
-+ rate, p_rate, p);
-+}
-+
-+static unsigned long
-+nss_core_clk_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)
-+{
-+ return clk_dyn_rcg_ops.recalc_rate(&ubi32_core1_src_clk.clkr.hw,
-+ parent_rate);
-+}
-+
-+static u8 nss_core_clk_get_parent(struct clk_hw *hw)
-+{
-+ return clk_dyn_rcg_ops.get_parent(&ubi32_core1_src_clk.clkr.hw);
-+}
-+
-+static int nss_core_clk_set_parent(struct clk_hw *hw, u8 i)
-+{
-+ int ret;
-+
-+ ret = clk_dyn_rcg_ops.set_parent(&ubi32_core1_src_clk.clkr.hw, i);
-+ if (ret)
-+ return ret;
-+
-+ return clk_dyn_rcg_ops.set_parent(&ubi32_core2_src_clk.clkr.hw, i);
-+}
-+
-+static struct clk *nss_core_clk_get_safe_parent(struct clk_hw *hw)
-+{
-+ return clk_get_parent_by_index(hw->clk,
-+ ubi32_core2_src_clk.s[0].parent_map[P_PLL8]);
-+}
-+
-+static const struct clk_ops clk_ops_nss_core = {
-+ .set_rate = nss_core_clk_set_rate,
-+ .set_rate_and_parent = nss_core_clk_set_rate_and_parent,
-+ .determine_rate = nss_core_clk_determine_rate,
-+ .recalc_rate = nss_core_clk_recalc_rate,
-+ .get_parent = nss_core_clk_get_parent,
-+ .set_parent = nss_core_clk_set_parent,
-+ .get_safe_parent = nss_core_clk_get_safe_parent,
-+};
-+
-+/* Virtual clock for nss core clocks */
-+static struct clk_regmap nss_core_clk = {
-+ .hw.init = &(struct clk_init_data){
-+ .name = "nss_core_clk",
-+ .ops = &clk_ops_nss_core,
-+ .parent_names = gcc_pxo_pll8_pll14_pll18_pll0,
-+ .num_parents = 5,
-+ .flags = CLK_SET_RATE_PARENT,
-+ },
-+};
-+
- static struct clk_regmap *gcc_ipq806x_clks[] = {
-+ [PLL0] = &pll0.clkr,
-+ [PLL0_VOTE] = &pll0_vote,
- [PLL3] = &pll3.clkr,
- [PLL8] = &pll8.clkr,
- [PLL8_VOTE] = &pll8_vote,
- [PLL14] = &pll14.clkr,
- [PLL14_VOTE] = &pll14_vote,
-+ [PLL18] = &pll18.clkr,
- [GSBI1_UART_SRC] = &gsbi1_uart_src.clkr,
- [GSBI1_UART_CLK] = &gsbi1_uart_clk.clkr,
- [GSBI2_UART_SRC] = &gsbi2_uart_src.clkr,
-@@ -2232,6 +2865,19 @@ static struct clk_regmap *gcc_ipq806x_cl
- [USB_FS1_XCVR_SRC] = &usb_fs1_xcvr_clk_src.clkr,
- [USB_FS1_XCVR_CLK] = &usb_fs1_xcvr_clk.clkr,
- [USB_FS1_SYSTEM_CLK] = &usb_fs1_sys_clk.clkr,
-+ [GMAC_CORE1_CLK_SRC] = &gmac_core1_src.clkr,
-+ [GMAC_CORE1_CLK] = &gmac_core1_clk.clkr,
-+ [GMAC_CORE2_CLK_SRC] = &gmac_core2_src.clkr,
-+ [GMAC_CORE2_CLK] = &gmac_core2_clk.clkr,
-+ [GMAC_CORE3_CLK_SRC] = &gmac_core3_src.clkr,
-+ [GMAC_CORE3_CLK] = &gmac_core3_clk.clkr,
-+ [GMAC_CORE4_CLK_SRC] = &gmac_core4_src.clkr,
-+ [GMAC_CORE4_CLK] = &gmac_core4_clk.clkr,
-+ [UBI32_CORE1_CLK_SRC] = &ubi32_core1_src_clk.clkr,
-+ [UBI32_CORE2_CLK_SRC] = &ubi32_core2_src_clk.clkr,
-+ [NSSTCM_CLK_SRC] = &nss_tcm_src.clkr,
-+ [NSSTCM_CLK] = &nss_tcm_clk.clkr,
-+ [NSS_CORE_CLK] = &nss_core_clk,
- };
-
- static const struct qcom_reset_map gcc_ipq806x_resets[] = {
-@@ -2350,6 +2996,48 @@ static const struct qcom_reset_map gcc_i
- [USB30_1_PHY_RESET] = { 0x3b58, 0 },
- [NSSFB0_RESET] = { 0x3b60, 6 },
- [NSSFB1_RESET] = { 0x3b60, 7 },
-+ [UBI32_CORE1_CLKRST_CLAMP_RESET] = { 0x3d3c, 3},
-+ [UBI32_CORE1_CLAMP_RESET] = { 0x3d3c, 2 },
-+ [UBI32_CORE1_AHB_RESET] = { 0x3d3c, 1 },
-+ [UBI32_CORE1_AXI_RESET] = { 0x3d3c, 0 },
-+ [UBI32_CORE2_CLKRST_CLAMP_RESET] = { 0x3d5c, 3 },
-+ [UBI32_CORE2_CLAMP_RESET] = { 0x3d5c, 2 },
-+ [UBI32_CORE2_AHB_RESET] = { 0x3d5c, 1 },
-+ [UBI32_CORE2_AXI_RESET] = { 0x3d5c, 0 },
-+ [GMAC_CORE1_RESET] = { 0x3cbc, 0 },
-+ [GMAC_CORE2_RESET] = { 0x3cdc, 0 },
-+ [GMAC_CORE3_RESET] = { 0x3cfc, 0 },
-+ [GMAC_CORE4_RESET] = { 0x3d1c, 0 },
-+ [GMAC_AHB_RESET] = { 0x3e24, 0 },
-+ [NSS_CH0_RST_RX_CLK_N_RESET] = { 0x3b60, 0 },
-+ [NSS_CH0_RST_TX_CLK_N_RESET] = { 0x3b60, 1 },
-+ [NSS_CH0_RST_RX_125M_N_RESET] = { 0x3b60, 2 },
-+ [NSS_CH0_HW_RST_RX_125M_N_RESET] = { 0x3b60, 3 },
-+ [NSS_CH0_RST_TX_125M_N_RESET] = { 0x3b60, 4 },
-+ [NSS_CH1_RST_RX_CLK_N_RESET] = { 0x3b60, 5 },
-+ [NSS_CH1_RST_TX_CLK_N_RESET] = { 0x3b60, 6 },
-+ [NSS_CH1_RST_RX_125M_N_RESET] = { 0x3b60, 7 },
-+ [NSS_CH1_HW_RST_RX_125M_N_RESET] = { 0x3b60, 8 },
-+ [NSS_CH1_RST_TX_125M_N_RESET] = { 0x3b60, 9 },
-+ [NSS_CH2_RST_RX_CLK_N_RESET] = { 0x3b60, 10 },
-+ [NSS_CH2_RST_TX_CLK_N_RESET] = { 0x3b60, 11 },
-+ [NSS_CH2_RST_RX_125M_N_RESET] = { 0x3b60, 12 },
-+ [NSS_CH2_HW_RST_RX_125M_N_RESET] = { 0x3b60, 13 },
-+ [NSS_CH2_RST_TX_125M_N_RESET] = { 0x3b60, 14 },
-+ [NSS_CH3_RST_RX_CLK_N_RESET] = { 0x3b60, 15 },
-+ [NSS_CH3_RST_TX_CLK_N_RESET] = { 0x3b60, 16 },
-+ [NSS_CH3_RST_RX_125M_N_RESET] = { 0x3b60, 17 },
-+ [NSS_CH3_HW_RST_RX_125M_N_RESET] = { 0x3b60, 18 },
-+ [NSS_CH3_RST_TX_125M_N_RESET] = { 0x3b60, 19 },
-+ [NSS_RST_RX_250M_125M_N_RESET] = { 0x3b60, 20 },
-+ [NSS_RST_TX_250M_125M_N_RESET] = { 0x3b60, 21 },
-+ [NSS_QSGMII_TXPI_RST_N_RESET] = { 0x3b60, 22 },
-+ [NSS_QSGMII_CDR_RST_N_RESET] = { 0x3b60, 23 },
-+ [NSS_SGMII2_CDR_RST_N_RESET] = { 0x3b60, 24 },
-+ [NSS_SGMII3_CDR_RST_N_RESET] = { 0x3b60, 25 },
-+ [NSS_CAL_PRBS_RST_N_RESET] = { 0x3b60, 26 },
-+ [NSS_LCKDT_RST_N_RESET] = { 0x3b60, 27 },
-+ [NSS_SRDS_N_RESET] = { 0x3b60, 28 },
- };
-
- static const struct regmap_config gcc_ipq806x_regmap_config = {
-@@ -2378,6 +3066,8 @@ static int gcc_ipq806x_probe(struct plat
- {
- struct clk *clk;
- struct device *dev = &pdev->dev;
-+ struct regmap *regmap;
-+ int ret;
-
- /* Temporary until RPM clocks supported */
- clk = clk_register_fixed_rate(dev, "cxo", NULL, CLK_IS_ROOT, 25000000);
-@@ -2388,7 +3078,25 @@ static int gcc_ipq806x_probe(struct plat
- if (IS_ERR(clk))
- return PTR_ERR(clk);
-
-- return qcom_cc_probe(pdev, &gcc_ipq806x_desc);
-+ ret = qcom_cc_probe(pdev, &gcc_ipq806x_desc);
-+ if (ret)
-+ return ret;
-+
-+ regmap = dev_get_regmap(dev, NULL);
-+ if (!regmap)
-+ return -ENODEV;
-+
-+ /* Setup PLL18 static bits */
-+ regmap_update_bits(regmap, 0x31a4, 0xffffffc0, 0x40000400);
-+ regmap_write(regmap, 0x31b0, 0x3080);
-+
-+ /* Set GMAC footswitch sleep/wakeup values */
-+ regmap_write(regmap, 0x3cb8, 8);
-+ regmap_write(regmap, 0x3cd8, 8);
-+ regmap_write(regmap, 0x3cf8, 8);
-+ regmap_write(regmap, 0x3d18, 8);
-+
-+ return 0;
- }
-
- static int gcc_ipq806x_remove(struct platform_device *pdev)
---- a/include/dt-bindings/clock/qcom,gcc-ipq806x.h
-+++ b/include/dt-bindings/clock/qcom,gcc-ipq806x.h
-@@ -289,5 +289,8 @@
- #define UBI32_CORE2_CLK_SRC 277
- #define UBI32_CORE1_CLK 278
- #define UBI32_CORE2_CLK 279
-+#define NSSTCM_CLK_SRC 280
-+#define NSSTCM_CLK 281
-+#define NSS_CORE_CLK 282 /* Virtual */
-
- #endif
---- a/include/dt-bindings/reset/qcom,gcc-ipq806x.h
-+++ b/include/dt-bindings/reset/qcom,gcc-ipq806x.h
-@@ -129,4 +129,47 @@
- #define USB30_1_PHY_RESET 112
- #define NSSFB0_RESET 113
- #define NSSFB1_RESET 114
-+#define UBI32_CORE1_CLKRST_CLAMP_RESET 115
-+#define UBI32_CORE1_CLAMP_RESET 116
-+#define UBI32_CORE1_AHB_RESET 117
-+#define UBI32_CORE1_AXI_RESET 118
-+#define UBI32_CORE2_CLKRST_CLAMP_RESET 119
-+#define UBI32_CORE2_CLAMP_RESET 120
-+#define UBI32_CORE2_AHB_RESET 121
-+#define UBI32_CORE2_AXI_RESET 122
-+#define GMAC_CORE1_RESET 123
-+#define GMAC_CORE2_RESET 124
-+#define GMAC_CORE3_RESET 125
-+#define GMAC_CORE4_RESET 126
-+#define GMAC_AHB_RESET 127
-+#define NSS_CH0_RST_RX_CLK_N_RESET 128
-+#define NSS_CH0_RST_TX_CLK_N_RESET 129
-+#define NSS_CH0_RST_RX_125M_N_RESET 130
-+#define NSS_CH0_HW_RST_RX_125M_N_RESET 131
-+#define NSS_CH0_RST_TX_125M_N_RESET 132
-+#define NSS_CH1_RST_RX_CLK_N_RESET 133
-+#define NSS_CH1_RST_TX_CLK_N_RESET 134
-+#define NSS_CH1_RST_RX_125M_N_RESET 135
-+#define NSS_CH1_HW_RST_RX_125M_N_RESET 136
-+#define NSS_CH1_RST_TX_125M_N_RESET 137
-+#define NSS_CH2_RST_RX_CLK_N_RESET 138
-+#define NSS_CH2_RST_TX_CLK_N_RESET 139
-+#define NSS_CH2_RST_RX_125M_N_RESET 140
-+#define NSS_CH2_HW_RST_RX_125M_N_RESET 141
-+#define NSS_CH2_RST_TX_125M_N_RESET 142
-+#define NSS_CH3_RST_RX_CLK_N_RESET 143
-+#define NSS_CH3_RST_TX_CLK_N_RESET 144
-+#define NSS_CH3_RST_RX_125M_N_RESET 145
-+#define NSS_CH3_HW_RST_RX_125M_N_RESET 146
-+#define NSS_CH3_RST_TX_125M_N_RESET 147
-+#define NSS_RST_RX_250M_125M_N_RESET 148
-+#define NSS_RST_TX_250M_125M_N_RESET 149
-+#define NSS_QSGMII_TXPI_RST_N_RESET 150
-+#define NSS_QSGMII_CDR_RST_N_RESET 151
-+#define NSS_SGMII2_CDR_RST_N_RESET 152
-+#define NSS_SGMII3_CDR_RST_N_RESET 153
-+#define NSS_CAL_PRBS_RST_N_RESET 154
-+#define NSS_LCKDT_RST_N_RESET 155
-+#define NSS_SRDS_N_RESET 156
-+
- #endif
diff --git a/target/linux/ipq806x/patches/0130-ARM-qcom-Add-initial-IPQ8064-SoC-and-AP148-device-tr.patch b/target/linux/ipq806x/patches/0130-ARM-qcom-Add-initial-IPQ8064-SoC-and-AP148-device-tr.patch
deleted file mode 100644
index 8fda0a1..0000000
--- a/target/linux/ipq806x/patches/0130-ARM-qcom-Add-initial-IPQ8064-SoC-and-AP148-device-tr.patch
+++ /dev/null
@@ -1,253 +0,0 @@
-From 1c6e51ffb10f5bf93a3018c7c1e04d7ed93f944e Mon Sep 17 00:00:00 2001
-From: Kumar Gala <galak@codeaurora.org>
-Date: Fri, 7 Mar 2014 10:56:59 -0600
-Subject: [PATCH 130/182] ARM: qcom: Add initial IPQ8064 SoC and AP148 device
- trees
-
-Add basic IPQ8064 SoC include device tree and support for basic booting on
-the AP148 Reference board.
-
-Signed-off-by: Kumar Gala <galak@codeaurora.org>
----
- arch/arm/boot/dts/Makefile | 1 +
- arch/arm/boot/dts/qcom-ipq8064-ap148.dts | 25 +++++
- arch/arm/boot/dts/qcom-ipq8064-v1.0.dtsi | 1 +
- arch/arm/boot/dts/qcom-ipq8064.dtsi | 176 ++++++++++++++++++++++++++++++
- arch/arm/mach-qcom/board.c | 2 +
- 5 files changed, 205 insertions(+)
- create mode 100644 arch/arm/boot/dts/qcom-ipq8064-ap148.dts
- create mode 100644 arch/arm/boot/dts/qcom-ipq8064-v1.0.dtsi
- create mode 100644 arch/arm/boot/dts/qcom-ipq8064.dtsi
-
---- a/arch/arm/boot/dts/Makefile
-+++ b/arch/arm/boot/dts/Makefile
-@@ -235,6 +235,7 @@ dtb-$(CONFIG_ARCH_QCOM) += \
- qcom-apq8064-ifc6410.dtb \
- qcom-apq8074-dragonboard.dtb \
- qcom-apq8084-mtp.dtb \
-+ qcom-ipq8064-ap148.dtb \
- qcom-msm8660-surf.dtb \
- qcom-msm8960-cdp.dtb
- dtb-$(CONFIG_ARCH_U8500) += ste-snowball.dtb \
---- /dev/null
-+++ b/arch/arm/boot/dts/qcom-ipq8064-ap148.dts
-@@ -0,0 +1,25 @@
-+#include "qcom-ipq8064-v1.0.dtsi"
-+
-+/ {
-+ model = "Qualcomm IPQ8064/AP148";
-+ compatible = "qcom,ipq8064-ap148", "qcom,ipq8064";
-+
-+ reserved-memory {
-+ #address-cells = <1>;
-+ #size-cells = <1>;
-+ rsvd@41200000 {
-+ reg = <0x41200000 0x300000>;
-+ no-map;
-+ };
-+ };
-+
-+ soc {
-+ gsbi@16300000 {
-+ qcom,mode = <GSBI_PROT_I2C_UART>;
-+ status = "ok";
-+ serial@16340000 {
-+ status = "ok";
-+ };
-+ };
-+ };
-+};
---- /dev/null
-+++ b/arch/arm/boot/dts/qcom-ipq8064-v1.0.dtsi
-@@ -0,0 +1 @@
-+#include "qcom-ipq8064.dtsi"
---- /dev/null
-+++ b/arch/arm/boot/dts/qcom-ipq8064.dtsi
-@@ -0,0 +1,176 @@
-+/dts-v1/;
-+
-+#include "skeleton.dtsi"
-+#include <dt-bindings/clock/qcom,gcc-ipq806x.h>
-+#include <dt-bindings/soc/qcom,gsbi.h>
-+
-+/ {
-+ model = "Qualcomm IPQ8064";
-+ compatible = "qcom,ipq8064";
-+ interrupt-parent = <&intc>;
-+
-+ cpus {
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+
-+ cpu@0 {
-+ compatible = "qcom,krait";
-+ enable-method = "qcom,kpss-acc-v1";
-+ device_type = "cpu";
-+ reg = <0>;
-+ next-level-cache = <&L2>;
-+ qcom,acc = <&acc0>;
-+ qcom,saw = <&saw0>;
-+ };
-+
-+ cpu@1 {
-+ compatible = "qcom,krait";
-+ enable-method = "qcom,kpss-acc-v1";
-+ device_type = "cpu";
-+ reg = <1>;
-+ next-level-cache = <&L2>;
-+ qcom,acc = <&acc1>;
-+ qcom,saw = <&saw1>;
-+ };
-+
-+ L2: l2-cache {
-+ compatible = "cache";
-+ cache-level = <2>;
-+ };
-+ };
-+
-+ cpu-pmu {
-+ compatible = "qcom,krait-pmu";
-+ interrupts = <1 10 0x304>;
-+ };
-+
-+ reserved-memory {
-+ #address-cells = <1>;
-+ #size-cells = <1>;
-+ ranges;
-+
-+ nss@40000000 {
-+ reg = <0x40000000 0x1000000>;
-+ no-map;
-+ };
-+
-+ smem@41000000 {
-+ reg = <0x41000000 0x200000>;
-+ no-map;
-+ };
-+ };
-+
-+ soc: soc {
-+ #address-cells = <1>;
-+ #size-cells = <1>;
-+ ranges;
-+ compatible = "simple-bus";
-+
-+ qcom_pinmux: pinmux@800000 {
-+ compatible = "qcom,ipq8064-pinctrl";
-+ reg = <0x800000 0x4000>;
-+
-+ gpio-controller;
-+ #gpio-cells = <2>;
-+ interrupt-controller;
-+ #interrupt-cells = <2>;
-+ interrupts = <0 32 0x4>;
-+ };
-+
-+ intc: interrupt-controller@2000000 {
-+ compatible = "qcom,msm-qgic2";
-+ interrupt-controller;
-+ #interrupt-cells = <3>;
-+ reg = <0x02000000 0x1000>,
-+ <0x02002000 0x1000>;
-+ };
-+
-+ timer@200a000 {
-+ compatible = "qcom,kpss-timer", "qcom,msm-timer";
-+ interrupts = <1 1 0x301>,
-+ <1 2 0x301>,
-+ <1 3 0x301>;
-+ reg = <0x0200a000 0x100>;
-+ clock-frequency = <25000000>,
-+ <32768>;
-+ cpu-offset = <0x80000>;
-+ };
-+
-+ acc0: clock-controller@2088000 {
-+ compatible = "qcom,kpss-acc-v1";
-+ reg = <0x02088000 0x1000>, <0x02008000 0x1000>;
-+ };
-+
-+ acc1: clock-controller@2098000 {
-+ compatible = "qcom,kpss-acc-v1";
-+ reg = <0x02098000 0x1000>, <0x02008000 0x1000>;
-+ };
-+
-+ saw0: regulator@2089000 {
-+ compatible = "qcom,saw2";
-+ reg = <0x02089000 0x1000>, <0x02009000 0x1000>;
-+ regulator;
-+ };
-+
-+ saw1: regulator@2099000 {
-+ compatible = "qcom,saw2";
-+ reg = <0x02099000 0x1000>, <0x02009000 0x1000>;
-+ regulator;
-+ };
-+
-+ gsbi2: gsbi@12480000 {
-+ compatible = "qcom,gsbi-v1.0.0";
-+ reg = <0x12480000 0x100>;
-+ clocks = <&gcc GSBI2_H_CLK>;
-+ clock-names = "iface";
-+ #address-cells = <1>;
-+ #size-cells = <1>;
-+ ranges;
-+ status = "disabled";
-+
-+ serial@12490000 {
-+ compatible = "qcom,msm-uartdm-v1.3", "qcom,msm-uartdm";
-+ reg = <0x12490000 0x1000>,
-+ <0x12480000 0x1000>;
-+ interrupts = <0 195 0x0>;
-+ clocks = <&gcc GSBI2_UART_CLK>, <&gcc GSBI2_H_CLK>;
-+ clock-names = "core", "iface";
-+ status = "disabled";
-+ };
-+ };
-+
-+ gsbi4: gsbi@16300000 {
-+ compatible = "qcom,gsbi-v1.0.0";
-+ reg = <0x16300000 0x100>;
-+ clocks = <&gcc GSBI4_H_CLK>;
-+ clock-names = "iface";
-+ #address-cells = <1>;
-+ #size-cells = <1>;
-+ ranges;
-+ status = "disabled";
-+
-+ serial@16340000 {
-+ compatible = "qcom,msm-uartdm-v1.3", "qcom,msm-uartdm";
-+ reg = <0x16340000 0x1000>,
-+ <0x16300000 0x1000>;
-+ interrupts = <0 152 0x0>;
-+ clocks = <&gcc GSBI4_UART_CLK>, <&gcc GSBI4_H_CLK>;
-+ clock-names = "core", "iface";
-+ status = "disabled";
-+ };
-+ };
-+
-+ qcom,ssbi@500000 {
-+ compatible = "qcom,ssbi";
-+ reg = <0x00500000 0x1000>;
-+ qcom,controller-type = "pmic-arbiter";
-+ };
-+
-+ gcc: clock-controller@900000 {
-+ compatible = "qcom,gcc-ipq8064";
-+ reg = <0x00900000 0x4000>;
-+ #clock-cells = <1>;
-+ #reset-cells = <1>;
-+ };
-+ };
-+};
---- a/arch/arm/mach-qcom/board.c
-+++ b/arch/arm/mach-qcom/board.c
-@@ -18,6 +18,8 @@ static const char * const qcom_dt_match[
- "qcom,apq8064",
- "qcom,apq8074-dragonboard",
- "qcom,apq8084",
-+ "qcom,ipq8062",
-+ "qcom,ipq8064",
- "qcom,msm8660-surf",
- "qcom,msm8960-cdp",
- NULL
diff --git a/target/linux/ipq806x/patches/0131-ARM-qcom-config-Enable-IPQ806x-support.patch b/target/linux/ipq806x/patches/0131-ARM-qcom-config-Enable-IPQ806x-support.patch
deleted file mode 100644
index 3a0e3ea..0000000
--- a/target/linux/ipq806x/patches/0131-ARM-qcom-config-Enable-IPQ806x-support.patch
+++ /dev/null
@@ -1,20 +0,0 @@
-From df1564829c4abe206d354f7c1b745cc1e864f4bd Mon Sep 17 00:00:00 2001
-From: Kumar Gala <galak@codeaurora.org>
-Date: Fri, 11 Apr 2014 14:18:29 -0500
-Subject: [PATCH 131/182] ARM: qcom: config: Enable IPQ806x support
-
-Signed-off-by: Kumar Gala <galak@codeaurora.org>
----
- arch/arm/configs/qcom_defconfig | 1 +
- 1 file changed, 1 insertion(+)
-
---- a/arch/arm/configs/qcom_defconfig
-+++ b/arch/arm/configs/qcom_defconfig
-@@ -133,6 +133,7 @@ CONFIG_QCOM_BAM_DMA=y
- CONFIG_STAGING=y
- CONFIG_QCOM_GSBI=y
- CONFIG_COMMON_CLK_QCOM=y
-+CONFIG_IPQ_GCC_806X=y
- CONFIG_MSM_GCC_8660=y
- CONFIG_MSM_MMCC_8960=y
- CONFIG_MSM_MMCC_8974=y
diff --git a/target/linux/ipq806x/patches/0132-XXX-Add-boot-support-for-u-boot.ipq-image.patch b/target/linux/ipq806x/patches/0132-XXX-Add-boot-support-for-u-boot.ipq-image.patch
deleted file mode 100644
index c09c3a6..0000000
--- a/target/linux/ipq806x/patches/0132-XXX-Add-boot-support-for-u-boot.ipq-image.patch
+++ /dev/null
@@ -1,48 +0,0 @@
-From 776fff11c1bf57e564a386521e56c277287a568c Mon Sep 17 00:00:00 2001
-From: Kumar Gala <galak@codeaurora.org>
-Date: Thu, 8 May 2014 13:40:16 -0500
-Subject: [PATCH 132/182] XXX: Add boot support for u-boot.ipq image
-
----
- arch/arm/Makefile | 2 +-
- arch/arm/boot/Makefile | 11 ++++++++++-
- 2 files changed, 11 insertions(+), 2 deletions(-)
-
---- a/arch/arm/Makefile
-+++ b/arch/arm/Makefile
-@@ -302,7 +302,7 @@ archprepare:
- # Convert bzImage to zImage
- bzImage: zImage
-
--BOOT_TARGETS = zImage Image xipImage bootpImage uImage
-+BOOT_TARGETS = zImage Image xipImage bootpImage uImage uImage.ipq Image.gz
- INSTALL_TARGETS = zinstall uinstall install
-
- PHONY += bzImage $(BOOT_TARGETS) $(INSTALL_TARGETS)
---- a/arch/arm/boot/Makefile
-+++ b/arch/arm/boot/Makefile
-@@ -25,7 +25,7 @@ INITRD_PHYS := $(initrd_phys-y)
-
- export ZRELADDR INITRD_PHYS PARAMS_PHYS
-
--targets := Image zImage xipImage bootpImage uImage
-+targets := Image zImage xipImage bootpImage uImage uImage.ipq Image.gz
-
- ifeq ($(CONFIG_XIP_KERNEL),y)
-
-@@ -80,6 +80,15 @@ $(obj)/uImage: $(obj)/zImage FORCE
- $(call if_changed,uimage)
- @$(kecho) ' Image $@ is ready'
-
-+$(obj)/uImage.ipq: $(obj)/Image.gz FORCE
-+ @$(check_for_multiple_loadaddr)
-+ $(call if_changed,uimage,gzip)
-+ @$(kecho) ' Image $@ is ready'
-+
-+$(obj)/Image.gz: $(obj)/Image FORCE
-+ $(call if_changed,gzip)
-+ @$(kecho) ' Image $@ is ready'
-+
- $(obj)/bootp/bootp: $(obj)/zImage initrd FORCE
- $(Q)$(MAKE) $(build)=$(obj)/bootp $@
- @:
diff --git a/target/linux/ipq806x/patches/0133-spi-qup-Remove-chip-select-function.patch b/target/linux/ipq806x/patches/0133-spi-qup-Remove-chip-select-function.patch
deleted file mode 100644
index 14ae782..0000000
--- a/target/linux/ipq806x/patches/0133-spi-qup-Remove-chip-select-function.patch
+++ /dev/null
@@ -1,83 +0,0 @@
-From 9bc674f40f22596ef8c2ff6d7f9e53da0baa57e9 Mon Sep 17 00:00:00 2001
-From: Andy Gross <agross@codeaurora.org>
-Date: Thu, 12 Jun 2014 14:34:10 -0500
-Subject: [PATCH 133/182] spi: qup: Remove chip select function
-
-This patch removes the chip select function. Chip select should instead be
-supported using GPIOs, defining the DT entry "cs-gpios", and letting the SPI
-core assert/deassert the chip select as it sees fit.
-
-Signed-off-by: Andy Gross <agross@codeaurora.org>
----
- .../devicetree/bindings/spi/qcom,spi-qup.txt | 6 ++++
- drivers/spi/spi-qup.c | 33 ++++----------------
- 2 files changed, 12 insertions(+), 27 deletions(-)
-
---- a/Documentation/devicetree/bindings/spi/qcom,spi-qup.txt
-+++ b/Documentation/devicetree/bindings/spi/qcom,spi-qup.txt
-@@ -23,6 +23,12 @@ Optional properties:
- - spi-max-frequency: Specifies maximum SPI clock frequency,
- Units - Hz. Definition as per
- Documentation/devicetree/bindings/spi/spi-bus.txt
-+- num-cs: total number of chipselects
-+- cs-gpios: should specify GPIOs used for chipselects.
-+ The gpios will be referred to as reg = <index> in the SPI child
-+ nodes. If unspecified, a single SPI device without a chip
-+ select can be used.
-+
-
- SPI slave nodes must be children of the SPI master node and can contain
- properties described in Documentation/devicetree/bindings/spi/spi-bus.txt
---- a/drivers/spi/spi-qup.c
-+++ b/drivers/spi/spi-qup.c
-@@ -424,31 +424,6 @@ static int spi_qup_io_config(struct spi_
- return 0;
- }
-
--static void spi_qup_set_cs(struct spi_device *spi, bool enable)
--{
-- struct spi_qup *controller = spi_master_get_devdata(spi->master);
--
-- u32 iocontol, mask;
--
-- iocontol = readl_relaxed(controller->base + SPI_IO_CONTROL);
--
-- /* Disable auto CS toggle and use manual */
-- iocontol &= ~SPI_IO_C_MX_CS_MODE;
-- iocontol |= SPI_IO_C_FORCE_CS;
--
-- iocontol &= ~SPI_IO_C_CS_SELECT_MASK;
-- iocontol |= SPI_IO_C_CS_SELECT(spi->chip_select);
--
-- mask = SPI_IO_C_CS_N_POLARITY_0 << spi->chip_select;
--
-- if (enable)
-- iocontol |= mask;
-- else
-- iocontol &= ~mask;
--
-- writel_relaxed(iocontol, controller->base + SPI_IO_CONTROL);
--}
--
- static int spi_qup_transfer_one(struct spi_master *master,
- struct spi_device *spi,
- struct spi_transfer *xfer)
-@@ -571,12 +546,16 @@ static int spi_qup_probe(struct platform
- return -ENOMEM;
- }
-
-+ /* use num-cs unless not present or out of range */
-+ if (of_property_read_u16(dev->of_node, "num-cs",
-+ &master->num_chipselect) ||
-+ (master->num_chipselect > SPI_NUM_CHIPSELECTS))
-+ master->num_chipselect = SPI_NUM_CHIPSELECTS;
-+
- master->bus_num = pdev->id;
- master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH | SPI_LOOP;
-- master->num_chipselect = SPI_NUM_CHIPSELECTS;
- master->bits_per_word_mask = SPI_BPW_RANGE_MASK(4, 32);
- master->max_speed_hz = max_freq;
-- master->set_cs = spi_qup_set_cs;
- master->transfer_one = spi_qup_transfer_one;
- master->dev.of_node = pdev->dev.of_node;
- master->auto_runtime_pm = true;
diff --git a/target/linux/ipq806x/patches/0134-spi-qup-Fix-order-of-spi_register_master.patch b/target/linux/ipq806x/patches/0134-spi-qup-Fix-order-of-spi_register_master.patch
deleted file mode 100644
index 93afe28..0000000
--- a/target/linux/ipq806x/patches/0134-spi-qup-Fix-order-of-spi_register_master.patch
+++ /dev/null
@@ -1,41 +0,0 @@
-From a7357be131e30fd1fb987b2cb343bc81db487f96 Mon Sep 17 00:00:00 2001
-From: Andy Gross <agross@codeaurora.org>
-Date: Thu, 12 Jun 2014 14:34:11 -0500
-Subject: [PATCH 134/182] spi: qup: Fix order of spi_register_master
-
-This patch moves the devm_spi_register_master below the initialization of the
-runtime_pm. If done in the wrong order, the spi_register_master fails if any
-probed slave devices issue SPI transactions.
-
-Signed-off-by: Andy Gross <agross@codeaurora.org>
-Acked-by: Ivan T. Ivanov <iivanov@mm-sol.com>
----
- drivers/spi/spi-qup.c | 11 +++++++----
- 1 file changed, 7 insertions(+), 4 deletions(-)
-
---- a/drivers/spi/spi-qup.c
-+++ b/drivers/spi/spi-qup.c
-@@ -619,16 +619,19 @@ static int spi_qup_probe(struct platform
- if (ret)
- goto error;
-
-- ret = devm_spi_register_master(dev, master);
-- if (ret)
-- goto error;
--
- pm_runtime_set_autosuspend_delay(dev, MSEC_PER_SEC);
- pm_runtime_use_autosuspend(dev);
- pm_runtime_set_active(dev);
- pm_runtime_enable(dev);
-+
-+ ret = devm_spi_register_master(dev, master);
-+ if (ret)
-+ goto disable_pm;
-+
- return 0;
-
-+disable_pm:
-+ pm_runtime_disable(&pdev->dev);
- error:
- clk_disable_unprepare(cclk);
- clk_disable_unprepare(iclk);
diff --git a/target/linux/ipq806x/patches/0135-spi-qup-Add-support-for-v1.1.1.patch b/target/linux/ipq806x/patches/0135-spi-qup-Add-support-for-v1.1.1.patch
deleted file mode 100644
index 86cce61..0000000
--- a/target/linux/ipq806x/patches/0135-spi-qup-Add-support-for-v1.1.1.patch
+++ /dev/null
@@ -1,125 +0,0 @@
-From 8b9de04ef3aaa154f30baf1ac703a2d3b474ad4e Mon Sep 17 00:00:00 2001
-From: Andy Gross <agross@codeaurora.org>
-Date: Thu, 12 Jun 2014 14:34:12 -0500
-Subject: [PATCH 135/182] spi: qup: Add support for v1.1.1
-
-This patch adds support for v1.1.1 of the SPI QUP controller.
-
-Signed-off-by: Andy Gross <agross@codeaurora.org>
----
- .../devicetree/bindings/spi/qcom,spi-qup.txt | 6 +++-
- drivers/spi/spi-qup.c | 36 ++++++++++++--------
- 2 files changed, 27 insertions(+), 15 deletions(-)
-
---- a/Documentation/devicetree/bindings/spi/qcom,spi-qup.txt
-+++ b/Documentation/devicetree/bindings/spi/qcom,spi-qup.txt
-@@ -7,7 +7,11 @@ SPI in master mode supports up to 50MHz,
- data path from 4 bits to 32 bits and numerous protocol variants.
-
- Required properties:
--- compatible: Should contain "qcom,spi-qup-v2.1.1" or "qcom,spi-qup-v2.2.1"
-+- compatible: Should contain:
-+ "qcom,spi-qup-v1.1.1" for 8660, 8960 and 8064.
-+ "qcom,spi-qup-v2.1.1" for 8974 and later
-+ "qcom,spi-qup-v2.2.1" for 8974 v2 and later.
-+
- - reg: Should contain base register location and length
- - interrupts: Interrupt number used by this controller
-
---- a/drivers/spi/spi-qup.c
-+++ b/drivers/spi/spi-qup.c
-@@ -142,6 +142,7 @@ struct spi_qup {
- int w_size; /* bytes per SPI word */
- int tx_bytes;
- int rx_bytes;
-+ int qup_v1;
- };
-
-
-@@ -420,7 +421,9 @@ static int spi_qup_io_config(struct spi_
- config |= QUP_CONFIG_SPI_MODE;
- writel_relaxed(config, controller->base + QUP_CONFIG);
-
-- writel_relaxed(0, controller->base + QUP_OPERATIONAL_MASK);
-+ /* only write to OPERATIONAL_MASK when register is present */
-+ if (!controller->qup_v1)
-+ writel_relaxed(0, controller->base + QUP_OPERATIONAL_MASK);
- return 0;
- }
-
-@@ -486,7 +489,7 @@ static int spi_qup_probe(struct platform
- struct resource *res;
- struct device *dev;
- void __iomem *base;
-- u32 data, max_freq, iomode;
-+ u32 max_freq, iomode;
- int ret, irq, size;
-
- dev = &pdev->dev;
-@@ -529,15 +532,6 @@ static int spi_qup_probe(struct platform
- return ret;
- }
-
-- data = readl_relaxed(base + QUP_HW_VERSION);
--
-- if (data < QUP_HW_VERSION_2_1_1) {
-- clk_disable_unprepare(cclk);
-- clk_disable_unprepare(iclk);
-- dev_err(dev, "v.%08x is not supported\n", data);
-- return -ENXIO;
-- }
--
- master = spi_alloc_master(dev, sizeof(struct spi_qup));
- if (!master) {
- clk_disable_unprepare(cclk);
-@@ -570,6 +564,10 @@ static int spi_qup_probe(struct platform
- controller->cclk = cclk;
- controller->irq = irq;
-
-+ /* set v1 flag if device is version 1 */
-+ if (of_device_is_compatible(dev->of_node, "qcom,spi-qup-v1.1.1"))
-+ controller->qup_v1 = 1;
-+
- spin_lock_init(&controller->lock);
- init_completion(&controller->done);
-
-@@ -593,8 +591,8 @@ static int spi_qup_probe(struct platform
- size = QUP_IO_M_INPUT_FIFO_SIZE(iomode);
- controller->in_fifo_sz = controller->in_blk_sz * (2 << size);
-
-- dev_info(dev, "v.%08x IN:block:%d, fifo:%d, OUT:block:%d, fifo:%d\n",
-- data, controller->in_blk_sz, controller->in_fifo_sz,
-+ dev_info(dev, "IN:block:%d, fifo:%d, OUT:block:%d, fifo:%d\n",
-+ controller->in_blk_sz, controller->in_fifo_sz,
- controller->out_blk_sz, controller->out_fifo_sz);
-
- writel_relaxed(1, base + QUP_SW_RESET);
-@@ -607,10 +605,19 @@ static int spi_qup_probe(struct platform
-
- writel_relaxed(0, base + QUP_OPERATIONAL);
- writel_relaxed(0, base + QUP_IO_M_MODES);
-- writel_relaxed(0, base + QUP_OPERATIONAL_MASK);
-+
-+ if (!controller->qup_v1)
-+ writel_relaxed(0, base + QUP_OPERATIONAL_MASK);
-+
- writel_relaxed(SPI_ERROR_CLK_UNDER_RUN | SPI_ERROR_CLK_OVER_RUN,
- base + SPI_ERROR_FLAGS_EN);
-
-+ /* if earlier version of the QUP, disable INPUT_OVERRUN */
-+ if (controller->qup_v1)
-+ writel_relaxed(QUP_ERROR_OUTPUT_OVER_RUN |
-+ QUP_ERROR_INPUT_UNDER_RUN | QUP_ERROR_OUTPUT_UNDER_RUN,
-+ base + QUP_ERROR_FLAGS_EN);
-+
- writel_relaxed(0, base + SPI_CONFIG);
- writel_relaxed(SPI_IO_C_NO_TRI_STATE, base + SPI_IO_CONTROL);
-
-@@ -732,6 +739,7 @@ static int spi_qup_remove(struct platfor
- }
-
- static struct of_device_id spi_qup_dt_match[] = {
-+ { .compatible = "qcom,spi-qup-v1.1.1", },
- { .compatible = "qcom,spi-qup-v2.1.1", },
- { .compatible = "qcom,spi-qup-v2.2.1", },
- { }
diff --git a/target/linux/ipq806x/patches/0136-ARM-ipq8064-ap148-Add-i2c-pinctrl-nodes.patch b/target/linux/ipq806x/patches/0136-ARM-ipq8064-ap148-Add-i2c-pinctrl-nodes.patch
deleted file mode 100644
index 7e9776e..0000000
--- a/target/linux/ipq806x/patches/0136-ARM-ipq8064-ap148-Add-i2c-pinctrl-nodes.patch
+++ /dev/null
@@ -1,86 +0,0 @@
-From e93b9480667cbd0e3a4276e8749279693fe239f4 Mon Sep 17 00:00:00 2001
-From: Andy Gross <agross@codeaurora.org>
-Date: Wed, 14 May 2014 22:49:03 -0500
-Subject: [PATCH 136/182] ARM: ipq8064-ap148: Add i2c pinctrl nodes
-
-Signed-off-by: Andy Gross <agross@codeaurora.org>
----
- arch/arm/boot/dts/qcom-ipq8064-ap148.dts | 17 +++++++++++++++++
- arch/arm/boot/dts/qcom-ipq8064.dtsi | 27 +++++++++++++++++++++++++++
- 2 files changed, 44 insertions(+)
-
---- a/arch/arm/boot/dts/qcom-ipq8064-ap148.dts
-+++ b/arch/arm/boot/dts/qcom-ipq8064-ap148.dts
-@@ -14,12 +14,29 @@
- };
-
- soc {
-+ pinmux@800000 {
-+ i2c4_pins: i2c4_pinmux {
-+ pins = "gpio12", "gpio13";
-+ function = "gsbi4";
-+ bias-disable;
-+ };
-+ };
-+
- gsbi@16300000 {
- qcom,mode = <GSBI_PROT_I2C_UART>;
- status = "ok";
- serial@16340000 {
- status = "ok";
- };
-+
-+ i2c4: i2c@16380000 {
-+ status = "ok";
-+
-+ clock-frequency = <200000>;
-+
-+ pinctrl-0 = <&i2c4_pins>;
-+ pinctrl-names = "default";
-+ };
- };
- };
- };
---- a/arch/arm/boot/dts/qcom-ipq8064.dtsi
-+++ b/arch/arm/boot/dts/qcom-ipq8064.dtsi
-@@ -137,6 +137,20 @@
- clock-names = "core", "iface";
- status = "disabled";
- };
-+
-+ i2c@124a0000 {
-+ compatible = "qcom,i2c-qup-v1.1.1";
-+ reg = <0x124a0000 0x1000>;
-+ interrupts = <0 196 0>;
-+
-+ clocks = <&gcc GSBI2_QUP_CLK>, <&gcc GSBI2_H_CLK>;
-+ clock-names = "core", "iface";
-+ status = "disabled";
-+
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+ };
-+
- };
-
- gsbi4: gsbi@16300000 {
-@@ -158,6 +172,19 @@
- clock-names = "core", "iface";
- status = "disabled";
- };
-+
-+ i2c@16380000 {
-+ compatible = "qcom,i2c-qup-v1.1.1";
-+ reg = <0x16380000 0x1000>;
-+ interrupts = <0 153 0>;
-+
-+ clocks = <&gcc GSBI4_QUP_CLK>, <&gcc GSBI4_H_CLK>;
-+ clock-names = "core", "iface";
-+ status = "disabled";
-+
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+ };
- };
-
- qcom,ssbi@500000 {
diff --git a/target/linux/ipq806x/patches/0137-ARM-qcom-ipq8064-ap148-Add-SPI-related-bindings.patch b/target/linux/ipq806x/patches/0137-ARM-qcom-ipq8064-ap148-Add-SPI-related-bindings.patch
deleted file mode 100644
index f72446e..0000000
--- a/target/linux/ipq806x/patches/0137-ARM-qcom-ipq8064-ap148-Add-SPI-related-bindings.patch
+++ /dev/null
@@ -1,124 +0,0 @@
-From b9eaa80146abb09bcc7e6d8b33fca476453c839c Mon Sep 17 00:00:00 2001
-From: Andy Gross <agross@codeaurora.org>
-Date: Wed, 14 May 2014 22:01:16 -0500
-Subject: [PATCH 137/182] ARM: qcom-ipq8064-ap148: Add SPI related bindings
-
-Signed-off-by: Andy Gross <agross@codeaurora.org>
----
- arch/arm/boot/dts/qcom-ipq8064-ap148.dts | 42 ++++++++++++++++++++++++++
- arch/arm/boot/dts/qcom-ipq8064.dtsi | 47 ++++++++++++++++++++++++++++++
- 2 files changed, 89 insertions(+)
-
---- a/arch/arm/boot/dts/qcom-ipq8064-ap148.dts
-+++ b/arch/arm/boot/dts/qcom-ipq8064-ap148.dts
-@@ -20,6 +20,15 @@
- function = "gsbi4";
- bias-disable;
- };
-+
-+ spi_pins: spi_pins {
-+ mux {
-+ pins = "gpio18", "gpio19", "gpio21";
-+ function = "gsbi5";
-+ drive-strength = <10>;
-+ bias-none;
-+ };
-+ };
- };
-
- gsbi@16300000 {
-@@ -38,5 +47,38 @@
- pinctrl-names = "default";
- };
- };
-+
-+ gsbi5: gsbi@1a200000 {
-+ qcom,mode = <GSBI_PROT_SPI>;
-+ status = "ok";
-+
-+ spi4: spi@1a280000 {
-+ status = "ok";
-+ spi-max-frequency = <50000000>;
-+
-+ pinctrl-0 = <&spi_pins>;
-+ pinctrl-names = "default";
-+
-+ cs-gpios = <&qcom_pinmux 20 0>;
-+
-+ flash: m25p80@0 {
-+ compatible = "s25fl256s1";
-+ #address-cells = <1>;
-+ #size-cells = <1>;
-+ spi-max-frequency = <50000000>;
-+ reg = <0>;
-+
-+ partition@0 {
-+ label = "rootfs";
-+ reg = <0x0 0x1000000>;
-+ };
-+
-+ partition@1 {
-+ label = "scratch";
-+ reg = <0x1000000 0x1000000>;
-+ };
-+ };
-+ };
-+ };
- };
- };
---- a/arch/arm/boot/dts/qcom-ipq8064.dtsi
-+++ b/arch/arm/boot/dts/qcom-ipq8064.dtsi
-@@ -187,6 +187,53 @@
- };
- };
-
-+ gsbi5: gsbi@1a200000 {
-+ compatible = "qcom,gsbi-v1.0.0";
-+ reg = <0x1a200000 0x100>;
-+ clocks = <&gcc GSBI5_H_CLK>;
-+ clock-names = "iface";
-+ #address-cells = <1>;
-+ #size-cells = <1>;
-+ ranges;
-+ status = "disabled";
-+
-+ serial@1a240000 {
-+ compatible = "qcom,msm-uartdm-v1.3", "qcom,msm-uartdm";
-+ reg = <0x1a240000 0x1000>,
-+ <0x1a200000 0x1000>;
-+ interrupts = <0 154 0x0>;
-+ clocks = <&gcc GSBI5_UART_CLK>, <&gcc GSBI5_H_CLK>;
-+ clock-names = "core", "iface";
-+ status = "disabled";
-+ };
-+
-+ i2c@1a280000 {
-+ compatible = "qcom,i2c-qup-v1.1.1";
-+ reg = <0x1a280000 0x1000>;
-+ interrupts = <0 155 0>;
-+
-+ clocks = <&gcc GSBI5_QUP_CLK>, <&gcc GSBI5_H_CLK>;
-+ clock-names = "core", "iface";
-+ status = "disabled";
-+
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+ };
-+
-+ spi@1a280000 {
-+ compatible = "qcom,spi-qup-v1.1.1";
-+ reg = <0x1a280000 0x1000>;
-+ interrupts = <0 155 0>;
-+
-+ clocks = <&gcc GSBI5_QUP_CLK>, <&gcc GSBI5_H_CLK>;
-+ clock-names = "core", "iface";
-+ status = "disabled";
-+
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+ };
-+ };
-+
- qcom,ssbi@500000 {
- compatible = "qcom,ssbi";
- reg = <0x00500000 0x1000>;
diff --git a/target/linux/ipq806x/patches/0138-PCI-qcom-Add-support-for-pcie-controllers-on-IPQ8064.patch b/target/linux/ipq806x/patches/0138-PCI-qcom-Add-support-for-pcie-controllers-on-IPQ8064.patch
deleted file mode 100644
index 8aaa766..0000000
--- a/target/linux/ipq806x/patches/0138-PCI-qcom-Add-support-for-pcie-controllers-on-IPQ8064.patch
+++ /dev/null
@@ -1,716 +0,0 @@
-From 98567c99b4dcd80fc9e5dd97229ebb9a7f6dab03 Mon Sep 17 00:00:00 2001
-From: Kumar Gala <galak@codeaurora.org>
-Date: Fri, 16 May 2014 11:53:23 -0500
-Subject: [PATCH 138/182] PCI: qcom: Add support for pcie controllers on
- IPQ8064
-
----
- arch/arm/mach-qcom/Kconfig | 2 +
- drivers/pci/host/Makefile | 1 +
- drivers/pci/host/pci-qcom.c | 682 +++++++++++++++++++++++++++++++++++++++++++
- 3 files changed, 685 insertions(+)
- create mode 100644 drivers/pci/host/pci-qcom.c
-
---- a/arch/arm/mach-qcom/Kconfig
-+++ b/arch/arm/mach-qcom/Kconfig
-@@ -7,6 +7,8 @@ config ARCH_QCOM
- select GENERIC_CLOCKEVENTS
- select HAVE_SMP
- select PINCTRL
-+ select MIGHT_HAVE_PCI
-+ select PCI_DOMAINS if PCI
- select QCOM_SCM if SMP
- help
- Support for Qualcomm's devicetree based systems.
---- a/drivers/pci/host/Makefile
-+++ b/drivers/pci/host/Makefile
-@@ -4,3 +4,4 @@ obj-$(CONFIG_PCI_IMX6) += pci-imx6.o
- obj-$(CONFIG_PCI_MVEBU) += pci-mvebu.o
- obj-$(CONFIG_PCI_TEGRA) += pci-tegra.o
- obj-$(CONFIG_PCI_RCAR_GEN2) += pci-rcar-gen2.o
-+obj-$(CONFIG_ARCH_QCOM) += pci-qcom.o
---- /dev/null
-+++ b/drivers/pci/host/pci-qcom.c
-@@ -0,0 +1,682 @@
-+/* Copyright (c) 2012-2014, The Linux Foundation. All rights reserved.
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 and
-+ * only version 2 as published by the Free Software Foundation.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ * GNU General Public License for more details.
-+ */
-+
-+/*
-+ * QCOM MSM PCIe controller driver.
-+ */
-+
-+#include <linux/kernel.h>
-+#include <linux/pci.h>
-+#include <linux/gpio.h>
-+#include <linux/of_gpio.h>
-+#include <linux/platform_device.h>
-+#include <linux/of_address.h>
-+#include <linux/clk.h>
-+#include <linux/reset.h>
-+#include <linux/delay.h>
-+
-+/* Root Complex Port vendor/device IDs */
-+#define PCIE_VENDOR_ID_RCP 0x17cb
-+#define PCIE_DEVICE_ID_RCP 0x0101
-+
-+#define __set(v, a, b) (((v) << (b)) & GENMASK(a, b))
-+
-+#define PCIE20_PARF_PCS_DEEMPH 0x34
-+#define PCIE20_PARF_PCS_DEEMPH_TX_DEEMPH_GEN1(x) __set(x, 21, 16)
-+#define PCIE20_PARF_PCS_DEEMPH_TX_DEEMPH_GEN2_3_5DB(x) __set(x, 13, 8)
-+#define PCIE20_PARF_PCS_DEEMPH_TX_DEEMPH_GEN2_6DB(x) __set(x, 5, 0)
-+
-+#define PCIE20_PARF_PCS_SWING 0x38
-+#define PCIE20_PARF_PCS_SWING_TX_SWING_FULL(x) __set(x, 14, 8)
-+#define PCIE20_PARF_PCS_SWING_TX_SWING_LOW(x) __set(x, 6, 0)
-+
-+#define PCIE20_PARF_PHY_CTRL 0x40
-+#define PCIE20_PARF_PHY_CTRL_PHY_TX0_TERM_OFFST(x) __set(x, 20, 16)
-+#define PCIE20_PARF_PHY_CTRL_PHY_LOS_LEVEL(x) __set(x, 12, 8)
-+#define PCIE20_PARF_PHY_CTRL_PHY_RTUNE_REQ (1 << 4)
-+#define PCIE20_PARF_PHY_CTRL_PHY_TEST_BURNIN (1 << 2)
-+#define PCIE20_PARF_PHY_CTRL_PHY_TEST_BYPASS (1 << 1)
-+#define PCIE20_PARF_PHY_CTRL_PHY_TEST_PWR_DOWN (1 << 0)
-+
-+#define PCIE20_PARF_PHY_REFCLK 0x4C
-+#define PCIE20_PARF_CONFIG_BITS 0x50
-+
-+#define PCIE20_ELBI_SYS_CTRL 0x04
-+#define PCIE20_ELBI_SYS_CTRL_LTSSM_EN 0x01
-+
-+#define PCIE20_CAP 0x70
-+#define PCIE20_CAP_LINKCTRLSTATUS (PCIE20_CAP + 0x10)
-+
-+#define PCIE20_COMMAND_STATUS 0x04
-+#define PCIE20_BUSNUMBERS 0x18
-+#define PCIE20_MEMORY_BASE_LIMIT 0x20
-+
-+#define PCIE20_AXI_MSTR_RESP_COMP_CTRL0 0x818
-+#define PCIE20_AXI_MSTR_RESP_COMP_CTRL1 0x81c
-+#define PCIE20_PLR_IATU_VIEWPORT 0x900
-+#define PCIE20_PLR_IATU_CTRL1 0x904
-+#define PCIE20_PLR_IATU_CTRL2 0x908
-+#define PCIE20_PLR_IATU_LBAR 0x90C
-+#define PCIE20_PLR_IATU_UBAR 0x910
-+#define PCIE20_PLR_IATU_LAR 0x914
-+#define PCIE20_PLR_IATU_LTAR 0x918
-+#define PCIE20_PLR_IATU_UTAR 0x91c
-+
-+#define MSM_PCIE_DEV_CFG_ADDR 0x01000000
-+
-+#define RD 0
-+#define WR 1
-+
-+#define MAX_RC_NUM 3
-+#define PCIE_BUS_PRIV_DATA(pdev) \
-+ (((struct pci_sys_data *)pdev->bus->sysdata)->private_data)
-+
-+/* PCIe TLP types that we are interested in */
-+#define PCI_CFG0_RDWR 0x4
-+#define PCI_CFG1_RDWR 0x5
-+
-+#define readl_poll_timeout(addr, val, cond, sleep_us, timeout_us) \
-+({ \
-+ unsigned long timeout = jiffies + usecs_to_jiffies(timeout_us); \
-+ might_sleep_if(timeout_us); \
-+ for (;;) { \
-+ (val) = readl(addr); \
-+ if (cond) \
-+ break; \
-+ if (timeout_us && time_after(jiffies, timeout)) { \
-+ (val) = readl(addr); \
-+ break; \
-+ } \
-+ if (sleep_us) \
-+ usleep_range(DIV_ROUND_UP(sleep_us, 4), sleep_us); \
-+ } \
-+ (cond) ? 0 : -ETIMEDOUT; \
-+})
-+
-+struct qcom_pcie {
-+ void __iomem *elbi_base;
-+ void __iomem *parf_base;
-+ void __iomem *dwc_base;
-+ void __iomem *cfg_base;
-+ int reset_gpio;
-+ struct clk *iface_clk;
-+ struct clk *bus_clk;
-+ struct clk *phy_clk;
-+ int irq_int[4];
-+ struct reset_control *axi_reset;
-+ struct reset_control *ahb_reset;
-+ struct reset_control *por_reset;
-+ struct reset_control *pci_reset;
-+ struct reset_control *phy_reset;
-+
-+ struct resource conf;
-+ struct resource io;
-+ struct resource mem;
-+};
-+
-+static int qcom_pcie_map_irq(const struct pci_dev *dev, u8 slot, u8 pin);
-+static int qcom_pcie_setup(int nr, struct pci_sys_data *sys);
-+static int msm_pcie_rd_conf(struct pci_bus *bus, u32 devfn, int where,
-+ int size, u32 *val);
-+static int msm_pcie_wr_conf(struct pci_bus *bus, u32 devfn,
-+ int where, int size, u32 val);
-+
-+static struct pci_ops qcom_pcie_ops = {
-+ .read = msm_pcie_rd_conf,
-+ .write = msm_pcie_wr_conf,
-+};
-+
-+static struct hw_pci qcom_hw_pci[MAX_RC_NUM] = {
-+ {
-+#ifdef CONFIG_PCI_DOMAINS
-+ .domain = 0,
-+#endif
-+ .ops = &qcom_pcie_ops,
-+ .nr_controllers = 1,
-+ .swizzle = pci_common_swizzle,
-+ .setup = qcom_pcie_setup,
-+ .map_irq = qcom_pcie_map_irq,
-+ },
-+ {
-+#ifdef CONFIG_PCI_DOMAINS
-+ .domain = 1,
-+#endif
-+ .ops = &qcom_pcie_ops,
-+ .nr_controllers = 1,
-+ .swizzle = pci_common_swizzle,
-+ .setup = qcom_pcie_setup,
-+ .map_irq = qcom_pcie_map_irq,
-+ },
-+ {
-+#ifdef CONFIG_PCI_DOMAINS
-+ .domain = 2,
-+#endif
-+ .ops = &qcom_pcie_ops,
-+ .nr_controllers = 1,
-+ .swizzle = pci_common_swizzle,
-+ .setup = qcom_pcie_setup,
-+ .map_irq = qcom_pcie_map_irq,
-+ },
-+};
-+
-+static int nr_controllers;
-+static DEFINE_SPINLOCK(qcom_hw_pci_lock);
-+
-+static inline struct qcom_pcie *sys_to_pcie(struct pci_sys_data *sys)
-+{
-+ return sys->private_data;
-+}
-+
-+inline int is_msm_pcie_rc(struct pci_bus *bus)
-+{
-+ return (bus->number == 0);
-+}
-+
-+static int qcom_pcie_is_link_up(struct qcom_pcie *dev)
-+{
-+ return readl_relaxed(dev->dwc_base + PCIE20_CAP_LINKCTRLSTATUS) & BIT(29);
-+}
-+
-+inline int msm_pcie_get_cfgtype(struct pci_bus *bus)
-+{
-+ /*
-+ * http://www.tldp.org/LDP/tlk/dd/pci.html
-+ * Pass it onto the secondary bus interface unchanged if the
-+ * bus number specified is greater than the secondary bus
-+ * number and less than or equal to the subordinate bus
-+ * number.
-+ *
-+ * Read/Write to the RC and Device/Switch connected to the RC
-+ * are CFG0 type transactions. Rest have to be forwarded
-+ * down stream as CFG1 transactions.
-+ *
-+ */
-+ if (bus->number == 0)
-+ return PCI_CFG0_RDWR;
-+
-+ return PCI_CFG0_RDWR;
-+}
-+
-+void msm_pcie_config_cfgtype(struct pci_bus *bus, u32 devfn)
-+{
-+ uint32_t bdf, cfgtype;
-+ struct qcom_pcie *dev = sys_to_pcie(bus->sysdata);
-+
-+ cfgtype = msm_pcie_get_cfgtype(bus);
-+
-+ if (cfgtype == PCI_CFG0_RDWR) {
-+ bdf = MSM_PCIE_DEV_CFG_ADDR;
-+ } else {
-+ /*
-+ * iATU Lower Target Address Register
-+ * Bits Description
-+ * *-1:0 Forms bits [*:0] of the
-+ * start address of the new
-+ * address of the translated
-+ * region. The start address
-+ * must be aligned to a
-+ * CX_ATU_MIN_REGION_SIZE kB
-+ * boundary, so these bits are
-+ * always 0. A write to this
-+ * location is ignored by the
-+ * PCIe core.
-+ * 31:*1 Forms bits [31:*] of the of
-+ * the new address of the
-+ * translated region.
-+ *
-+ * * is log2(CX_ATU_MIN_REGION_SIZE)
-+ */
-+ bdf = (((bus->number & 0xff) << 24) & 0xff000000) |
-+ (((devfn & 0xff) << 16) & 0x00ff0000);
-+ }
-+
-+ writel_relaxed(0, dev->dwc_base + PCIE20_PLR_IATU_VIEWPORT);
-+ wmb();
-+
-+ /* Program Bdf Address */
-+ writel_relaxed(bdf, dev->dwc_base + PCIE20_PLR_IATU_LTAR);
-+ wmb();
-+
-+ /* Write Config Request Type */
-+ writel_relaxed(cfgtype, dev->dwc_base + PCIE20_PLR_IATU_CTRL1);
-+ wmb();
-+}
-+
-+static inline int msm_pcie_oper_conf(struct pci_bus *bus, u32 devfn, int oper,
-+ int where, int size, u32 *val)
-+{
-+ uint32_t word_offset, byte_offset, mask;
-+ uint32_t rd_val, wr_val;
-+ struct qcom_pcie *dev = sys_to_pcie(bus->sysdata);
-+ void __iomem *config_base;
-+ int rc;
-+
-+ rc = is_msm_pcie_rc(bus);
-+
-+ /*
-+ * For downstream bus, make sure link is up
-+ */
-+ if (rc && (devfn != 0)) {
-+ *val = ~0;
-+ return PCIBIOS_DEVICE_NOT_FOUND;
-+ } else if ((!rc) && (!qcom_pcie_is_link_up(dev))) {
-+ *val = ~0;
-+ return PCIBIOS_DEVICE_NOT_FOUND;
-+ }
-+
-+ msm_pcie_config_cfgtype(bus, devfn);
-+
-+ word_offset = where & ~0x3;
-+ byte_offset = where & 0x3;
-+ mask = (~0 >> (8 * (4 - size))) << (8 * byte_offset);
-+
-+ config_base = (rc) ? dev->dwc_base : dev->cfg_base;
-+ rd_val = readl_relaxed(config_base + word_offset);
-+
-+ if (oper == RD) {
-+ *val = ((rd_val & mask) >> (8 * byte_offset));
-+ } else {
-+ wr_val = (rd_val & ~mask) |
-+ ((*val << (8 * byte_offset)) & mask);
-+ writel_relaxed(wr_val, config_base + word_offset);
-+ wmb(); /* ensure config data is written to hardware register */
-+ }
-+
-+ return 0;
-+}
-+
-+static int msm_pcie_rd_conf(struct pci_bus *bus, u32 devfn, int where,
-+ int size, u32 *val)
-+{
-+ return msm_pcie_oper_conf(bus, devfn, RD, where, size, val);
-+}
-+
-+static int msm_pcie_wr_conf(struct pci_bus *bus, u32 devfn,
-+ int where, int size, u32 val)
-+{
-+ /*
-+ *Attempt to reset secondary bus is causing PCIE core to reset.
-+ *Disable secondary bus reset functionality.
-+ */
-+ if ((bus->number == 0) && (where == PCI_BRIDGE_CONTROL) &&
-+ (val & PCI_BRIDGE_CTL_BUS_RESET)) {
-+ pr_info("PCIE secondary bus reset not supported\n");
-+ val &= ~PCI_BRIDGE_CTL_BUS_RESET;
-+ }
-+
-+ return msm_pcie_oper_conf(bus, devfn, WR, where, size, &val);
-+}
-+
-+static int qcom_pcie_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
-+{
-+ struct qcom_pcie *pcie_dev = PCIE_BUS_PRIV_DATA(dev);
-+
-+ return pcie_dev->irq_int[pin-1];
-+}
-+
-+static int qcom_pcie_setup(int nr, struct pci_sys_data *sys)
-+{
-+ struct qcom_pcie *qcom_pcie = sys->private_data;
-+
-+ /*
-+ * specify linux PCI framework to allocate device memory (BARs)
-+ * from msm_pcie_dev.dev_mem_res resource.
-+ */
-+ sys->mem_offset = 0;
-+ sys->io_offset = 0;
-+
-+ pci_add_resource(&sys->resources, &qcom_pcie->mem);
-+ pci_add_resource(&sys->resources, &qcom_pcie->io);
-+
-+ return 1;
-+}
-+
-+static inline void qcom_elbi_writel_relaxed(struct qcom_pcie *pcie, u32 val, u32 reg)
-+{
-+ writel_relaxed(val, pcie->elbi_base + reg);
-+}
-+
-+static inline u32 qcom_elbi_readl_relaxed(struct qcom_pcie *pcie, u32 reg)
-+{
-+ return readl_relaxed(pcie->elbi_base + reg);
-+}
-+
-+static inline void qcom_parf_writel_relaxed(struct qcom_pcie *pcie, u32 val, u32 reg)
-+{
-+ writel_relaxed(val, pcie->parf_base + reg);
-+}
-+
-+static inline u32 qcom_parf_readl_relaxed(struct qcom_pcie *pcie, u32 reg)
-+{
-+ return readl_relaxed(pcie->parf_base + reg);
-+}
-+
-+static void msm_pcie_write_mask(void __iomem *addr,
-+ uint32_t clear_mask, uint32_t set_mask)
-+{
-+ uint32_t val;
-+
-+ val = (readl_relaxed(addr) & ~clear_mask) | set_mask;
-+ writel_relaxed(val, addr);
-+ wmb(); /* ensure data is written to hardware register */
-+}
-+
-+static void qcom_pcie_config_controller(struct qcom_pcie *dev)
-+{
-+ /*
-+ * program and enable address translation region 0 (device config
-+ * address space); region type config;
-+ * axi config address range to device config address range
-+ */
-+ writel_relaxed(0, dev->dwc_base + PCIE20_PLR_IATU_VIEWPORT);
-+ /* ensure that hardware locks the region before programming it */
-+ wmb();
-+
-+ writel_relaxed(4, dev->dwc_base + PCIE20_PLR_IATU_CTRL1);
-+ writel_relaxed(BIT(31), dev->dwc_base + PCIE20_PLR_IATU_CTRL2);
-+ writel_relaxed(dev->conf.start, dev->dwc_base + PCIE20_PLR_IATU_LBAR);
-+ writel_relaxed(0, dev->dwc_base + PCIE20_PLR_IATU_UBAR);
-+ writel_relaxed(dev->conf.end, dev->dwc_base + PCIE20_PLR_IATU_LAR);
-+ writel_relaxed(MSM_PCIE_DEV_CFG_ADDR,
-+ dev->dwc_base + PCIE20_PLR_IATU_LTAR);
-+ writel_relaxed(0, dev->dwc_base + PCIE20_PLR_IATU_UTAR);
-+ /* ensure that hardware registers the configuration */
-+ wmb();
-+
-+ /*
-+ * program and enable address translation region 2 (device resource
-+ * address space); region type memory;
-+ * axi device bar address range to device bar address range
-+ */
-+ writel_relaxed(2, dev->dwc_base + PCIE20_PLR_IATU_VIEWPORT);
-+ /* ensure that hardware locks the region before programming it */
-+ wmb();
-+
-+ writel_relaxed(0, dev->dwc_base + PCIE20_PLR_IATU_CTRL1);
-+ writel_relaxed(BIT(31), dev->dwc_base + PCIE20_PLR_IATU_CTRL2);
-+ writel_relaxed(dev->mem.start, dev->dwc_base + PCIE20_PLR_IATU_LBAR);
-+ writel_relaxed(0, dev->dwc_base + PCIE20_PLR_IATU_UBAR);
-+ writel_relaxed(dev->mem.end, dev->dwc_base + PCIE20_PLR_IATU_LAR);
-+ writel_relaxed(dev->mem.start,
-+ dev->dwc_base + PCIE20_PLR_IATU_LTAR);
-+ writel_relaxed(0, dev->dwc_base + PCIE20_PLR_IATU_UTAR);
-+ /* ensure that hardware registers the configuration */
-+ wmb();
-+
-+ /* 1K PCIE buffer setting */
-+ writel_relaxed(0x3, dev->dwc_base + PCIE20_AXI_MSTR_RESP_COMP_CTRL0);
-+ writel_relaxed(0x1, dev->dwc_base + PCIE20_AXI_MSTR_RESP_COMP_CTRL1);
-+ /* ensure that hardware registers the configuration */
-+ wmb();
-+}
-+
-+static int qcom_pcie_probe(struct platform_device *pdev)
-+{
-+ unsigned long flags;
-+ struct qcom_pcie *qcom_pcie;
-+ struct device_node *np = pdev->dev.of_node;
-+ struct resource *elbi_base, *parf_base, *dwc_base;
-+ struct hw_pci *hw;
-+ struct of_pci_range range;
-+ struct of_pci_range_parser parser;
-+ int ret, i;
-+ u32 val;
-+
-+ qcom_pcie = devm_kzalloc(&pdev->dev, sizeof(*qcom_pcie), GFP_KERNEL);
-+ if (!qcom_pcie) {
-+ dev_err(&pdev->dev, "no memory for qcom_pcie\n");
-+ return -ENOMEM;
-+ }
-+
-+ elbi_base = platform_get_resource_byname(pdev, IORESOURCE_MEM, "elbi");
-+ qcom_pcie->elbi_base = devm_ioremap_resource(&pdev->dev, elbi_base);
-+ if (IS_ERR(qcom_pcie->elbi_base)) {
-+ dev_err(&pdev->dev, "Failed to ioremap elbi space\n");
-+ return PTR_ERR(qcom_pcie->elbi_base);
-+ }
-+
-+ parf_base = platform_get_resource_byname(pdev, IORESOURCE_MEM, "parf");
-+ qcom_pcie->parf_base = devm_ioremap_resource(&pdev->dev, parf_base);
-+ if (IS_ERR(qcom_pcie->parf_base)) {
-+ dev_err(&pdev->dev, "Failed to ioremap parf space\n");
-+ return PTR_ERR(qcom_pcie->parf_base);
-+ }
-+
-+ dwc_base = platform_get_resource_byname(pdev, IORESOURCE_MEM, "base");
-+ qcom_pcie->dwc_base = devm_ioremap_resource(&pdev->dev, dwc_base);
-+ if (IS_ERR(qcom_pcie->dwc_base)) {
-+ dev_err(&pdev->dev, "Failed to ioremap dwc_base space\n");
-+ return PTR_ERR(qcom_pcie->dwc_base);
-+ }
-+
-+ if (of_pci_range_parser_init(&parser, np)) {
-+ dev_err(&pdev->dev, "missing ranges property\n");
-+ return -EINVAL;
-+ }
-+
-+ /* Get the I/O and memory ranges from DT */
-+ for_each_of_pci_range(&parser, &range) {
-+ switch (range.pci_space & 0x3) {
-+ case 0: /* cfg */
-+ of_pci_range_to_resource(&range, np, &qcom_pcie->conf);
-+ qcom_pcie->conf.flags = IORESOURCE_MEM;
-+ break;
-+ case 1: /* io */
-+ of_pci_range_to_resource(&range, np, &qcom_pcie->io);
-+ break;
-+ default: /* mem */
-+ of_pci_range_to_resource(&range, np, &qcom_pcie->mem);
-+ break;
-+ }
-+ }
-+
-+ qcom_pcie->cfg_base = devm_ioremap_resource(&pdev->dev, &qcom_pcie->conf);
-+ if (IS_ERR(qcom_pcie->cfg_base)) {
-+ dev_err(&pdev->dev, "Failed to ioremap PCIe cfg space\n");
-+ return PTR_ERR(qcom_pcie->cfg_base);
-+ }
-+
-+ qcom_pcie->reset_gpio = of_get_named_gpio(np, "reset-gpio", 0);
-+ if (!gpio_is_valid(qcom_pcie->reset_gpio)) {
-+ dev_err(&pdev->dev, "pcie reset gpio is not valid\n");
-+ return -EINVAL;
-+ }
-+
-+ ret = devm_gpio_request_one(&pdev->dev, qcom_pcie->reset_gpio,
-+ GPIOF_DIR_OUT, "pcie_reset");
-+ if (ret) {
-+ dev_err(&pdev->dev, "Failed to request pcie reset gpio\n");
-+ return ret;
-+ }
-+
-+ qcom_pcie->iface_clk = devm_clk_get(&pdev->dev, "iface");
-+ if (IS_ERR(qcom_pcie->iface_clk)) {
-+ dev_err(&pdev->dev, "Failed to get pcie iface clock\n");
-+ return PTR_ERR(qcom_pcie->iface_clk);
-+ }
-+
-+ qcom_pcie->phy_clk = devm_clk_get(&pdev->dev, "phy");
-+ if (IS_ERR(qcom_pcie->phy_clk)) {
-+ dev_err(&pdev->dev, "Failed to get pcie phy clock\n");
-+ return PTR_ERR(qcom_pcie->phy_clk);
-+ }
-+
-+ qcom_pcie->bus_clk = devm_clk_get(&pdev->dev, "core");
-+ if (IS_ERR(qcom_pcie->bus_clk)) {
-+ dev_err(&pdev->dev, "Failed to get pcie core clock\n");
-+ return PTR_ERR(qcom_pcie->bus_clk);
-+ }
-+
-+ qcom_pcie->axi_reset = devm_reset_control_get(&pdev->dev, "axi");
-+ if (IS_ERR(qcom_pcie->axi_reset)) {
-+ dev_err(&pdev->dev, "Failed to get axi reset\n");
-+ return PTR_ERR(qcom_pcie->axi_reset);
-+ }
-+
-+ qcom_pcie->ahb_reset = devm_reset_control_get(&pdev->dev, "ahb");
-+ if (IS_ERR(qcom_pcie->ahb_reset)) {
-+ dev_err(&pdev->dev, "Failed to get ahb reset\n");
-+ return PTR_ERR(qcom_pcie->ahb_reset);
-+ }
-+
-+ qcom_pcie->por_reset = devm_reset_control_get(&pdev->dev, "por");
-+ if (IS_ERR(qcom_pcie->por_reset)) {
-+ dev_err(&pdev->dev, "Failed to get por reset\n");
-+ return PTR_ERR(qcom_pcie->por_reset);
-+ }
-+
-+ qcom_pcie->pci_reset = devm_reset_control_get(&pdev->dev, "pci");
-+ if (IS_ERR(qcom_pcie->pci_reset)) {
-+ dev_err(&pdev->dev, "Failed to get pci reset\n");
-+ return PTR_ERR(qcom_pcie->pci_reset);
-+ }
-+
-+ qcom_pcie->phy_reset = devm_reset_control_get(&pdev->dev, "phy");
-+ if (IS_ERR(qcom_pcie->phy_reset)) {
-+ dev_err(&pdev->dev, "Failed to get phy reset\n");
-+ return PTR_ERR(qcom_pcie->phy_reset);
-+ }
-+
-+ for (i = 0; i < 4; i++) {
-+ qcom_pcie->irq_int[i] = platform_get_irq(pdev, i+1);
-+ if (qcom_pcie->irq_int[i] < 0) {
-+ dev_err(&pdev->dev, "failed to get irq resource\n");
-+ return qcom_pcie->irq_int[i];
-+ }
-+ }
-+
-+ gpio_set_value(qcom_pcie->reset_gpio, 0);
-+ usleep_range(10000, 15000);
-+
-+ /* assert PCIe PARF reset while powering the core */
-+ reset_control_assert(qcom_pcie->ahb_reset);
-+
-+ /* enable clocks */
-+ ret = clk_prepare_enable(qcom_pcie->iface_clk);
-+ if (ret)
-+ return ret;
-+ ret = clk_prepare_enable(qcom_pcie->phy_clk);
-+ if (ret)
-+ return ret;
-+ ret = clk_prepare_enable(qcom_pcie->bus_clk);
-+ if (ret)
-+ return ret;
-+
-+ /*
-+ * de-assert PCIe PARF reset;
-+ * wait 1us before accessing PARF registers
-+ */
-+ reset_control_deassert(qcom_pcie->ahb_reset);
-+ udelay(1);
-+
-+ /* enable PCIe clocks and resets */
-+ msm_pcie_write_mask(qcom_pcie->parf_base + PCIE20_PARF_PHY_CTRL, BIT(0), 0);
-+
-+ /* Set Tx Termination Offset */
-+ val = qcom_parf_readl_relaxed(qcom_pcie, PCIE20_PARF_PHY_CTRL);
-+ val |= PCIE20_PARF_PHY_CTRL_PHY_TX0_TERM_OFFST(7);
-+ qcom_parf_writel_relaxed(qcom_pcie, val, PCIE20_PARF_PHY_CTRL);
-+
-+ /* PARF programming */
-+ qcom_parf_writel_relaxed(qcom_pcie, PCIE20_PARF_PCS_DEEMPH_TX_DEEMPH_GEN1(0x18) |
-+ PCIE20_PARF_PCS_DEEMPH_TX_DEEMPH_GEN2_3_5DB(0x18) |
-+ PCIE20_PARF_PCS_DEEMPH_TX_DEEMPH_GEN2_6DB(0x22),
-+ PCIE20_PARF_PCS_DEEMPH);
-+ qcom_parf_writel_relaxed(qcom_pcie, PCIE20_PARF_PCS_SWING_TX_SWING_FULL(0x78) |
-+ PCIE20_PARF_PCS_SWING_TX_SWING_LOW(0x78),
-+ PCIE20_PARF_PCS_SWING);
-+ qcom_parf_writel_relaxed(qcom_pcie, (4<<24), PCIE20_PARF_CONFIG_BITS);
-+ /* ensure that hardware registers the PARF configuration */
-+ wmb();
-+
-+ /* enable reference clock */
-+ msm_pcie_write_mask(qcom_pcie->parf_base + PCIE20_PARF_PHY_REFCLK, BIT(12), BIT(16));
-+
-+ /* ensure that access is enabled before proceeding */
-+ wmb();
-+
-+ /* de-assert PICe PHY, Core, POR and AXI clk domain resets */
-+ reset_control_deassert(qcom_pcie->phy_reset);
-+ reset_control_deassert(qcom_pcie->pci_reset);
-+ reset_control_deassert(qcom_pcie->por_reset);
-+ reset_control_deassert(qcom_pcie->axi_reset);
-+
-+ /* wait 150ms for clock acquisition */
-+ usleep_range(10000, 15000);
-+
-+ /* de-assert PCIe reset link to bring EP out of reset */
-+ gpio_set_value(qcom_pcie->reset_gpio, 1 - 0);
-+ usleep_range(10000, 15000);
-+
-+ /* enable link training */
-+ val = qcom_elbi_readl_relaxed(qcom_pcie, PCIE20_ELBI_SYS_CTRL);
-+ val |= PCIE20_ELBI_SYS_CTRL_LTSSM_EN;
-+ qcom_elbi_writel_relaxed(qcom_pcie, val, PCIE20_ELBI_SYS_CTRL);
-+ wmb();
-+
-+ /* poll for link to come up for upto 100ms */
-+ ret = readl_poll_timeout(
-+ (qcom_pcie->dwc_base + PCIE20_CAP_LINKCTRLSTATUS),
-+ val, (val & BIT(29)), 10000, 100000);
-+
-+ printk("link initialized %d\n", ret);
-+
-+ qcom_pcie_config_controller(qcom_pcie);
-+
-+ platform_set_drvdata(pdev, qcom_pcie);
-+
-+ spin_lock_irqsave(&qcom_hw_pci_lock, flags);
-+ qcom_hw_pci[nr_controllers].private_data = (void **)&qcom_pcie;
-+ hw = &qcom_hw_pci[nr_controllers];
-+ nr_controllers++;
-+ spin_unlock_irqrestore(&qcom_hw_pci_lock, flags);
-+
-+ pci_common_init(hw);
-+
-+ return 0;
-+}
-+
-+static int __exit qcom_pcie_remove(struct platform_device *pdev)
-+{
-+ struct qcom_pcie *qcom_pcie = platform_get_drvdata(pdev);
-+
-+ return 0;
-+}
-+
-+static struct of_device_id qcom_pcie_match[] = {
-+ { .compatible = "qcom,pcie-ipq8064", },
-+ {}
-+};
-+
-+static struct platform_driver qcom_pcie_driver = {
-+ .probe = qcom_pcie_probe,
-+ .remove = qcom_pcie_remove,
-+ .driver = {
-+ .name = "qcom_pcie",
-+ .owner = THIS_MODULE,
-+ .of_match_table = qcom_pcie_match,
-+ },
-+};
-+
-+static int qcom_pcie_init(void)
-+{
-+ return platform_driver_register(&qcom_pcie_driver);
-+}
-+subsys_initcall(qcom_pcie_init);
-+
-+/* RC do not represent the right class; set it to PCI_CLASS_BRIDGE_PCI */
-+static void msm_pcie_fixup_early(struct pci_dev *dev)
-+{
-+ if (dev->hdr_type == 1)
-+ dev->class = (dev->class & 0xff) | (PCI_CLASS_BRIDGE_PCI << 8);
-+}
-+DECLARE_PCI_FIXUP_EARLY(PCIE_VENDOR_ID_RCP, PCIE_DEVICE_ID_RCP, msm_pcie_fixup_early);
diff --git a/target/linux/ipq806x/patches/0139-ARM-dts-msm-Add-PCIe-related-nodes-for-IPQ8064-AP148.patch b/target/linux/ipq806x/patches/0139-ARM-dts-msm-Add-PCIe-related-nodes-for-IPQ8064-AP148.patch
deleted file mode 100644
index 1fd2052..0000000
--- a/target/linux/ipq806x/patches/0139-ARM-dts-msm-Add-PCIe-related-nodes-for-IPQ8064-AP148.patch
+++ /dev/null
@@ -1,172 +0,0 @@
-From 7c6525a0d5cf88f9244187fbe8ee293fa4ee43c1 Mon Sep 17 00:00:00 2001
-From: Kumar Gala <galak@codeaurora.org>
-Date: Mon, 12 May 2014 19:36:23 -0500
-Subject: [PATCH 139/182] ARM: dts: msm: Add PCIe related nodes for
- IPQ8064/AP148
-
----
- arch/arm/boot/dts/qcom-ipq8064-ap148.dts | 38 ++++++++++++
- arch/arm/boot/dts/qcom-ipq8064.dtsi | 93 ++++++++++++++++++++++++++++++
- 2 files changed, 131 insertions(+)
-
---- a/arch/arm/boot/dts/qcom-ipq8064-ap148.dts
-+++ b/arch/arm/boot/dts/qcom-ipq8064-ap148.dts
-@@ -21,6 +21,22 @@
- bias-disable;
- };
-
-+ pcie1_pins: pcie1_pinmux {
-+ mux {
-+ pins = "gpio3";
-+ drive-strength = <2>;
-+ bias-disable;
-+ };
-+ };
-+
-+ pcie2_pins: pcie2_pinmux {
-+ mux {
-+ pins = "gpio48";
-+ drive-strength = <2>;
-+ bias-disable;
-+ };
-+ };
-+
- spi_pins: spi_pins {
- mux {
- pins = "gpio18", "gpio19", "gpio21";
-@@ -80,5 +96,27 @@
- };
- };
- };
-+
-+ pci@1b500000 {
-+ status = "ok";
-+ reset-gpio = <&qcom_pinmux 3 0>;
-+ pinctrl-0 = <&pcie1_pins>;
-+ pinctrl-names = "default";
-+
-+ ranges = <0x00000000 0 0x00000000 0x0ff00000 0 0x00100000 /* configuration space */
-+ 0x81000000 0 0 0x0fe00000 0 0x00100000 /* downstream I/O */
-+ 0x82000000 0 0x00000000 0x08000000 0 0x07e00000>; /* non-prefetchable memory */
-+ };
-+
-+ pci@1b700000 {
-+ status = "ok";
-+ reset-gpio = <&qcom_pinmux 48 0>;
-+ pinctrl-0 = <&pcie2_pins>;
-+ pinctrl-names = "default";
-+
-+ ranges = <0x00000000 0 0x00000000 0x31f00000 0 0x00100000 /* configuration space */
-+ 0x81000000 0 0 0x31e00000 0 0x00100000 /* downstream I/O */
-+ 0x82000000 0 0x00000000 0x2e000000 0 0x03e00000>; /* non-prefetchable memory */
-+ };
- };
- };
---- a/arch/arm/boot/dts/qcom-ipq8064.dtsi
-+++ b/arch/arm/boot/dts/qcom-ipq8064.dtsi
-@@ -2,6 +2,7 @@
-
- #include "skeleton.dtsi"
- #include <dt-bindings/clock/qcom,gcc-ipq806x.h>
-+#include <dt-bindings/reset/qcom,gcc-ipq806x.h>
- #include <dt-bindings/soc/qcom,gsbi.h>
-
- / {
-@@ -246,5 +247,97 @@
- #clock-cells = <1>;
- #reset-cells = <1>;
- };
-+
-+ pci@1b500000 {
-+ compatible = "qcom,pcie-ipq8064";
-+ reg = <0x1b500000 0x1000
-+ 0x1b502000 0x80
-+ 0x1b600000 0x100
-+ >;
-+ reg-names = "base", "elbi", "parf";
-+
-+ #address-cells = <3>;
-+ #size-cells = <2>;
-+ device_type = "pci";
-+ interrupts = <0 35 0x0
-+ 0 36 0x0
-+ 0 37 0x0
-+ 0 38 0x0
-+ 0 39 0x0>;
-+ resets = <&gcc PCIE_ACLK_RESET>,
-+ <&gcc PCIE_HCLK_RESET>,
-+ <&gcc PCIE_POR_RESET>,
-+ <&gcc PCIE_PCI_RESET>,
-+ <&gcc PCIE_PHY_RESET>;
-+ reset-names = "axi", "ahb", "por", "pci", "phy";
-+
-+ clocks = <&gcc PCIE_A_CLK>,
-+ <&gcc PCIE_H_CLK>,
-+ <&gcc PCIE_PHY_CLK>;
-+ clock-names = "core", "iface", "phy";
-+ status = "disabled";
-+ };
-+
-+ pci@1b700000 {
-+ compatible = "qcom,pcie-ipq8064";
-+ reg = <0x1b700000 0x1000
-+ 0x1b702000 0x80
-+ 0x1b800000 0x100
-+ >;
-+ reg-names = "base", "elbi", "parf";
-+
-+ #address-cells = <3>;
-+ #size-cells = <2>;
-+ device_type = "pci";
-+
-+ interrupts = <0 57 0x0
-+ 0 58 0x0
-+ 0 59 0x0
-+ 0 60 0x0
-+ 0 61 0x0>;
-+ resets = <&gcc PCIE_1_ACLK_RESET>,
-+ <&gcc PCIE_1_HCLK_RESET>,
-+ <&gcc PCIE_1_POR_RESET>,
-+ <&gcc PCIE_1_PCI_RESET>,
-+ <&gcc PCIE_1_PHY_RESET>;
-+ reset-names = "axi", "ahb", "por", "pci", "phy";
-+
-+ clocks = <&gcc PCIE_1_A_CLK>,
-+ <&gcc PCIE_1_H_CLK>,
-+ <&gcc PCIE_1_PHY_CLK>;
-+ clock-names = "core", "iface", "phy";
-+ status = "disabled";
-+ };
-+
-+ pci@1b900000 {
-+ compatible = "qcom,pcie-ipq8064";
-+ reg = <0x1b900000 0x1000
-+ 0x1b902000 0x80
-+ 0x1ba00000 0x100
-+ >;
-+ reg-names = "base", "elbi", "parf";
-+
-+ #address-cells = <3>;
-+ #size-cells = <2>;
-+ device_type = "pci";
-+
-+ interrupts = <0 71 0x0
-+ 0 72 0x0
-+ 0 73 0x0
-+ 0 74 0x0
-+ 0 75 0x0>;
-+ resets = <&gcc PCIE_2_ACLK_RESET>,
-+ <&gcc PCIE_2_HCLK_RESET>,
-+ <&gcc PCIE_2_POR_RESET>,
-+ <&gcc PCIE_2_PCI_RESET>,
-+ <&gcc PCIE_2_PHY_RESET>;
-+ reset-names = "axi", "ahb", "por", "pci", "phy";
-+
-+ clocks = <&gcc PCIE_2_A_CLK>,
-+ <&gcc PCIE_2_H_CLK>,
-+ <&gcc PCIE_2_PHY_CLK>;
-+ clock-names = "core", "iface", "phy";
-+ status = "disabled";
-+ };
- };
- };
diff --git a/target/linux/ipq806x/patches/0140-ARM-qcom-config-Enable-PCI-support-for-IPQ806x.patch b/target/linux/ipq806x/patches/0140-ARM-qcom-config-Enable-PCI-support-for-IPQ806x.patch
deleted file mode 100644
index 14a5db4..0000000
--- a/target/linux/ipq806x/patches/0140-ARM-qcom-config-Enable-PCI-support-for-IPQ806x.patch
+++ /dev/null
@@ -1,28 +0,0 @@
-From a7e90802be401083098511e72866a0f824c10e15 Mon Sep 17 00:00:00 2001
-From: Kumar Gala <galak@codeaurora.org>
-Date: Fri, 16 May 2014 16:54:48 -0500
-Subject: [PATCH 140/182] ARM: qcom: config: Enable PCI support for IPQ806x
-
----
- arch/arm/configs/qcom_defconfig | 3 +++
- 1 file changed, 3 insertions(+)
-
---- a/arch/arm/configs/qcom_defconfig
-+++ b/arch/arm/configs/qcom_defconfig
-@@ -21,6 +21,8 @@ CONFIG_ARCH_QCOM=y
- CONFIG_ARCH_MSM8X60=y
- CONFIG_ARCH_MSM8960=y
- CONFIG_ARCH_MSM8974=y
-+CONFIG_PCI=y
-+CONFIG_PCI_MSI=y
- CONFIG_SMP=y
- CONFIG_PREEMPT=y
- CONFIG_AEABI=y
-@@ -83,6 +85,7 @@ CONFIG_INPUT_MISC=y
- CONFIG_INPUT_UINPUT=y
- CONFIG_SERIO_LIBPS2=y
- # CONFIG_LEGACY_PTYS is not set
-+CONFIG_SERIAL_8250=y
- CONFIG_SERIAL_MSM=y
- CONFIG_SERIAL_MSM_CONSOLE=y
- CONFIG_HW_RANDOM=y
diff --git a/target/linux/ipq806x/patches/0141-ahci-platform-Bump-max-number-of-clocks-to-5.patch b/target/linux/ipq806x/patches/0141-ahci-platform-Bump-max-number-of-clocks-to-5.patch
deleted file mode 100644
index 2f5adca..0000000
--- a/target/linux/ipq806x/patches/0141-ahci-platform-Bump-max-number-of-clocks-to-5.patch
+++ /dev/null
@@ -1,23 +0,0 @@
-From fd475809eefc0870515d0b04815e2bbae67be906 Mon Sep 17 00:00:00 2001
-From: Kumar Gala <galak@codeaurora.org>
-Date: Fri, 6 Jun 2014 12:09:01 -0500
-Subject: [PATCH 141/182] ahci-platform: Bump max number of clocks to 5
-
-Qualcomm IPQ806x SoCs with SATA controllers need 5 clocks to be enabled.
-
-Signed-off-by: Kumar Gala <galak@codeaurora.org>
----
- drivers/ata/ahci.h | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/drivers/ata/ahci.h
-+++ b/drivers/ata/ahci.h
-@@ -53,7 +53,7 @@
-
- enum {
- AHCI_MAX_PORTS = 32,
-- AHCI_MAX_CLKS = 3,
-+ AHCI_MAX_CLKS = 5,
- AHCI_MAX_SG = 168, /* hardware max is 64K */
- AHCI_DMA_BOUNDARY = 0xffffffff,
- AHCI_MAX_CMDS = 32,
diff --git a/target/linux/ipq806x/patches/0142-ata-Add-Qualcomm-ARM-SoC-AHCI-SATA-host-controller-d.patch b/target/linux/ipq806x/patches/0142-ata-Add-Qualcomm-ARM-SoC-AHCI-SATA-host-controller-d.patch
deleted file mode 100644
index 5db5d9d..0000000
--- a/target/linux/ipq806x/patches/0142-ata-Add-Qualcomm-ARM-SoC-AHCI-SATA-host-controller-d.patch
+++ /dev/null
@@ -1,136 +0,0 @@
-From c5ea64dcf7b5d45e402e78b9f291d521669b7b80 Mon Sep 17 00:00:00 2001
-From: Kumar Gala <galak@codeaurora.org>
-Date: Fri, 30 May 2014 15:35:40 -0500
-Subject: [PATCH 142/182] ata: Add Qualcomm ARM SoC AHCI SATA host controller
- driver
-
-Add support for the Qualcomm AHCI SATA controller that exists on several
-SoC and specifically the IPQ806x family of chips. The IPQ806x SATA support
-requires the associated IPQ806x SATA PHY Driver to be enabled as well.
-
-Signed-off-by: Kumar Gala <galak@codeaurora.org>
----
- drivers/ata/Kconfig | 10 ++++++
- drivers/ata/Makefile | 1 +
- drivers/ata/ahci_qcom.c | 86 +++++++++++++++++++++++++++++++++++++++++++++++
- 3 files changed, 97 insertions(+)
- create mode 100644 drivers/ata/ahci_qcom.c
-
---- a/drivers/ata/Kconfig
-+++ b/drivers/ata/Kconfig
-@@ -122,6 +122,16 @@ config AHCI_IMX
-
- If unsure, say N.
-
-+config AHCI_QCOM
-+ tristate "Qualcomm AHCI SATA support"
-+ depends on ARCH_QCOM
-+ help
-+ This option enables support for AHCI SATA controller
-+ integrated into Qualcomm ARM SoC chipsets. For more
-+ information please refer to http://www.qualcomm.com/chipsets.
-+
-+ If unsure, say N.
-+
- config SATA_FSL
- tristate "Freescale 3.0Gbps SATA support"
- depends on FSL_SOC
---- a/drivers/ata/Makefile
-+++ b/drivers/ata/Makefile
-@@ -11,6 +11,7 @@ obj-$(CONFIG_SATA_SIL24) += sata_sil24.o
- obj-$(CONFIG_SATA_DWC) += sata_dwc_460ex.o
- obj-$(CONFIG_SATA_HIGHBANK) += sata_highbank.o libahci.o
- obj-$(CONFIG_AHCI_IMX) += ahci_imx.o libahci.o libahci_platform.o
-+obj-$(CONFIG_AHCI_QCOM) += ahci_qcom.o libahci.o libahci_platform.o
-
- # SFF w/ custom DMA
- obj-$(CONFIG_PDC_ADMA) += pdc_adma.o
---- /dev/null
-+++ b/drivers/ata/ahci_qcom.c
-@@ -0,0 +1,86 @@
-+/*
-+ * Qualcomm ARM SoC AHCI SATA platform driver
-+ *
-+ * based on the AHCI SATA platform driver by Jeff Garzik and Anton Vorontsov
-+ *
-+ * Copyright (c) 2014, The Linux Foundation. All rights reserved.
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 and
-+ * only version 2 as published by the Free Software Foundation.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ * GNU General Public License for more details.
-+ */
-+
-+#include <linux/kernel.h>
-+#include <linux/module.h>
-+#include <linux/pm.h>
-+#include <linux/device.h>
-+#include <linux/platform_device.h>
-+#include <linux/libata.h>
-+#include <linux/ahci_platform.h>
-+#include "ahci.h"
-+
-+static const struct ata_port_info qcom_ahci_port_info = {
-+ .flags = AHCI_FLAG_COMMON,
-+ .pio_mask = ATA_PIO4,
-+ .udma_mask = ATA_UDMA6,
-+ .port_ops = &ahci_platform_ops,
-+};
-+
-+static int qcom_ahci_probe(struct platform_device *pdev)
-+{
-+ struct ahci_host_priv *hpriv;
-+ struct clk *rxoob_clk;
-+ int rc;
-+
-+ hpriv = ahci_platform_get_resources(pdev);
-+ if (IS_ERR(hpriv))
-+ return PTR_ERR(hpriv);
-+
-+ /* Try and set the rxoob clk to 100Mhz */
-+ rxoob_clk = of_clk_get_by_name(pdev->dev.of_node, "rxoob");
-+ if (IS_ERR(rxoob_clk))
-+ return PTR_ERR(rxoob_clk);
-+
-+ rc = clk_set_rate(rxoob_clk, 100000000);
-+ if (rc)
-+ return rc;
-+
-+ rc = ahci_platform_enable_resources(hpriv);
-+ if (rc)
-+ return rc;
-+
-+ rc = ahci_platform_init_host(pdev, hpriv, &qcom_ahci_port_info, 0, 0);
-+ if (rc)
-+ goto disable_resources;
-+
-+ return 0;
-+disable_resources:
-+ ahci_platform_disable_resources(hpriv);
-+ return rc;
-+}
-+
-+static const struct of_device_id qcom_ahci_of_match[] = {
-+ { .compatible = "qcom,msm-ahci", },
-+ {},
-+};
-+MODULE_DEVICE_TABLE(of, qcom_ahci_of_match);
-+
-+static struct platform_driver qcom_ahci_driver = {
-+ .probe = qcom_ahci_probe,
-+ .remove = ata_platform_remove_one,
-+ .driver = {
-+ .name = "qcom_ahci_qcom",
-+ .owner = THIS_MODULE,
-+ .of_match_table = qcom_ahci_of_match,
-+ },
-+};
-+module_platform_driver(qcom_ahci_driver);
-+
-+MODULE_DESCRIPTION("Qualcomm AHCI SATA platform driver");
-+MODULE_LICENSE("GPL v2");
-+MODULE_ALIAS("ahci:qcom");
diff --git a/target/linux/ipq806x/patches/0143-ata-qcom-Add-device-tree-bindings-information.patch b/target/linux/ipq806x/patches/0143-ata-qcom-Add-device-tree-bindings-information.patch
deleted file mode 100644
index 01ca733..0000000
--- a/target/linux/ipq806x/patches/0143-ata-qcom-Add-device-tree-bindings-information.patch
+++ /dev/null
@@ -1,57 +0,0 @@
-From dd280a4cf6b826144f74d3fc4285633f1c337a1d Mon Sep 17 00:00:00 2001
-From: Kumar Gala <galak@codeaurora.org>
-Date: Thu, 12 Jun 2014 11:28:47 -0500
-Subject: [PATCH 143/182] ata: qcom: Add device tree bindings information
-
-Add device tree binding for Qualcomm AHCI SATA controller and specifically
-the sata controller on the IPQ806x family of SoCs.
-
-Signed-off-by: Kumar Gala <galak@codeaurora.org>
----
- .../devicetree/bindings/ata/qcom-sata.txt | 40 ++++++++++++++++++++
- 1 file changed, 40 insertions(+)
- create mode 100644 Documentation/devicetree/bindings/ata/qcom-sata.txt
-
---- /dev/null
-+++ b/Documentation/devicetree/bindings/ata/qcom-sata.txt
-@@ -0,0 +1,40 @@
-+* Qualcomm AHCI SATA Controller
-+
-+SATA nodes are defined to describe on-chip Serial ATA controllers.
-+Each SATA controller should have its own node.
-+
-+Required properties:
-+- compatible : compatible list, contains "qcom,msm-ahci"
-+- interrupts : <interrupt mapping for SATA IRQ>
-+- reg : <registers mapping>
-+- phys : Must contain exactly one entry as specified
-+ in phy-bindings.txt
-+- phy-names : Must be "sata-phy"
-+
-+Required properties for "qcom,ipq806x-ahci" compatible:
-+- clocks : Must contain an entry for each entry in clock-names.
-+- clock-names : Shall be:
-+ "slave_iface" - Fabric port AHB clock for SATA
-+ "iface" - AHB clock
-+ "core" - core clock
-+ "rxoob" - RX out-of-band clock
-+ "pmalive" - Power Module Alive clock
-+
-+Example:
-+ sata@29000000 {
-+ compatible = "qcom,ipq806x-ahci", "qcom,msm-ahci";
-+ reg = <0x29000000 0x180>;
-+
-+ interrupts = <0 209 0x0>;
-+
-+ clocks = <&gcc SFAB_SATA_S_H_CLK>,
-+ <&gcc SATA_H_CLK>,
-+ <&gcc SATA_A_CLK>,
-+ <&gcc SATA_RXOOB_CLK>,
-+ <&gcc SATA_PMALIVE_CLK>;
-+ clock-names = "slave_iface", "iface", "core",
-+ "rxoob", "pmalive";
-+
-+ phys = <&sata_phy>;
-+ phy-names = "sata-phy";
-+ };
diff --git a/target/linux/ipq806x/patches/0144-phy-qcom-Add-driver-for-QCOM-IPQ806x-SATA-PHY.patch b/target/linux/ipq806x/patches/0144-phy-qcom-Add-driver-for-QCOM-IPQ806x-SATA-PHY.patch
deleted file mode 100644
index 9a5457d..0000000
--- a/target/linux/ipq806x/patches/0144-phy-qcom-Add-driver-for-QCOM-IPQ806x-SATA-PHY.patch
+++ /dev/null
@@ -1,251 +0,0 @@
-From 7554dfbbec255e4cd5dd4445841c28c48fd4a855 Mon Sep 17 00:00:00 2001
-From: Kumar Gala <galak@codeaurora.org>
-Date: Tue, 3 Jun 2014 11:59:09 -0500
-Subject: [PATCH 144/182] phy: qcom: Add driver for QCOM IPQ806x SATA PHY
-
-Add a PHY driver for uses with AHCI based SATA controller driver on the
-IPQ806x family of SoCs.
-
-Signed-off-by: Kumar Gala <galak@codeaurora.org>
----
- drivers/phy/Kconfig | 7 ++
- drivers/phy/Makefile | 1 +
- drivers/phy/phy-qcom-ipq806x-sata.c | 211 +++++++++++++++++++++++++++++++++++
- 3 files changed, 219 insertions(+)
- create mode 100644 drivers/phy/phy-qcom-ipq806x-sata.c
-
---- a/drivers/phy/Kconfig
-+++ b/drivers/phy/Kconfig
-@@ -65,4 +65,11 @@ config BCM_KONA_USB2_PHY
- help
- Enable this to support the Broadcom Kona USB 2.0 PHY.
-
-+config PHY_QCOM_IPQ806X_SATA
-+ tristate "Qualcomm IPQ806x SATA SerDes/PHY driver"
-+ depends on ARCH_QCOM
-+ depends on HAS_IOMEM
-+ depends on OF
-+ select GENERIC_PHY
-+
- endmenu
---- a/drivers/phy/Makefile
-+++ b/drivers/phy/Makefile
-@@ -9,3 +9,4 @@ obj-$(CONFIG_PHY_EXYNOS_MIPI_VIDEO) += p
- obj-$(CONFIG_PHY_MVEBU_SATA) += phy-mvebu-sata.o
- obj-$(CONFIG_OMAP_USB2) += phy-omap-usb2.o
- obj-$(CONFIG_TWL4030_USB) += phy-twl4030-usb.o
-+obj-$(CONFIG_PHY_QCOM_IPQ806X_SATA) += phy-qcom-ipq806x-sata.o
---- /dev/null
-+++ b/drivers/phy/phy-qcom-ipq806x-sata.c
-@@ -0,0 +1,211 @@
-+/*
-+ * Copyright (c) 2014, The Linux Foundation. All rights reserved.
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 and
-+ * only version 2 as published by the Free Software Foundation.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ * GNU General Public License for more details.
-+ */
-+
-+#include <linux/io.h>
-+#include <linux/kernel.h>
-+#include <linux/module.h>
-+#include <linux/of.h>
-+#include <linux/of_address.h>
-+#include <linux/time.h>
-+#include <linux/delay.h>
-+#include <linux/clk.h>
-+#include <linux/slab.h>
-+#include <linux/platform_device.h>
-+#include <linux/phy/phy.h>
-+
-+struct qcom_ipq806x_sata_phy {
-+ void __iomem *mmio;
-+ struct clk *cfg_clk;
-+};
-+
-+#define __set(v, a, b) (((v) << (b)) & GENMASK(a, b))
-+
-+#define SATA_PHY_P0_PARAM0 0x200
-+#define SATA_PHY_P0_PARAM0_P0_TX_PREEMPH_GEN3(x) __set(x, 17, 12)
-+#define SATA_PHY_P0_PARAM0_P0_TX_PREEMPH_GEN3_MASK GENMASK(17, 12)
-+#define SATA_PHY_P0_PARAM0_P0_TX_PREEMPH_GEN2(x) __set(x, 11, 6)
-+#define SATA_PHY_P0_PARAM0_P0_TX_PREEMPH_GEN2_MASK GENMASK(11, 6)
-+#define SATA_PHY_P0_PARAM0_P0_TX_PREEMPH_GEN1(x) __set(x, 5, 0)
-+#define SATA_PHY_P0_PARAM0_P0_TX_PREEMPH_GEN1_MASK GENMASK(5, 0)
-+
-+#define SATA_PHY_P0_PARAM1 0x204
-+#define SATA_PHY_P0_PARAM1_RESERVED_BITS31_21(x) __set(x, 31, 21)
-+#define SATA_PHY_P0_PARAM1_P0_TX_AMPLITUDE_GEN3(x) __set(x, 20, 14)
-+#define SATA_PHY_P0_PARAM1_P0_TX_AMPLITUDE_GEN3_MASK GENMASK(20, 14)
-+#define SATA_PHY_P0_PARAM1_P0_TX_AMPLITUDE_GEN2(x) __set(x, 13, 7)
-+#define SATA_PHY_P0_PARAM1_P0_TX_AMPLITUDE_GEN2_MASK GENMASK(13, 7)
-+#define SATA_PHY_P0_PARAM1_P0_TX_AMPLITUDE_GEN1(x) __set(x, 6, 0)
-+#define SATA_PHY_P0_PARAM1_P0_TX_AMPLITUDE_GEN1_MASK GENMASK(6, 0)
-+
-+#define SATA_PHY_P0_PARAM2 0x208
-+#define SATA_PHY_P0_PARAM2_RX_EQ(x) __set(x, 20, 18)
-+#define SATA_PHY_P0_PARAM2_RX_EQ_MASK GENMASK(20, 18)
-+
-+#define SATA_PHY_P0_PARAM3 0x20C
-+#define SATA_PHY_SSC_EN 0x8
-+#define SATA_PHY_P0_PARAM4 0x210
-+#define SATA_PHY_REF_SSP_EN 0x2
-+#define SATA_PHY_RESET 0x1
-+
-+static inline void qcom_ipq806x_sata_delay_us(unsigned int delay)
-+{
-+ /* sleep for max. 50us more to combine processor wakeups */
-+ usleep_range(delay, delay + 50);
-+}
-+
-+static int qcom_ipq806x_sata_phy_init(struct phy *generic_phy)
-+{
-+ struct qcom_ipq806x_sata_phy *phy = phy_get_drvdata(generic_phy);
-+ u32 reg;
-+
-+ /* Setting SSC_EN to 1 */
-+ reg = readl_relaxed(phy->mmio + SATA_PHY_P0_PARAM3);
-+ reg = reg | SATA_PHY_SSC_EN;
-+ writel_relaxed(reg, phy->mmio + SATA_PHY_P0_PARAM3);
-+
-+ reg = readl_relaxed(phy->mmio + SATA_PHY_P0_PARAM0) &
-+ ~(SATA_PHY_P0_PARAM0_P0_TX_PREEMPH_GEN3_MASK |
-+ SATA_PHY_P0_PARAM0_P0_TX_PREEMPH_GEN2_MASK |
-+ SATA_PHY_P0_PARAM0_P0_TX_PREEMPH_GEN1_MASK);
-+ reg |= SATA_PHY_P0_PARAM0_P0_TX_PREEMPH_GEN3(0xf);
-+ writel_relaxed(reg, phy->mmio + SATA_PHY_P0_PARAM0);
-+
-+ reg = readl_relaxed(phy->mmio + SATA_PHY_P0_PARAM1) &
-+ ~(SATA_PHY_P0_PARAM1_P0_TX_AMPLITUDE_GEN3_MASK |
-+ SATA_PHY_P0_PARAM1_P0_TX_AMPLITUDE_GEN2_MASK |
-+ SATA_PHY_P0_PARAM1_P0_TX_AMPLITUDE_GEN1_MASK);
-+ reg |= SATA_PHY_P0_PARAM1_P0_TX_AMPLITUDE_GEN3(0x55) |
-+ SATA_PHY_P0_PARAM1_P0_TX_AMPLITUDE_GEN2(0x55) |
-+ SATA_PHY_P0_PARAM1_P0_TX_AMPLITUDE_GEN1(0x55);
-+ writel_relaxed(reg, phy->mmio + SATA_PHY_P0_PARAM1);
-+
-+ reg = readl_relaxed(phy->mmio + SATA_PHY_P0_PARAM2) &
-+ ~SATA_PHY_P0_PARAM2_RX_EQ_MASK;
-+ reg |= SATA_PHY_P0_PARAM2_RX_EQ(0x3);
-+ writel_relaxed(reg, phy->mmio + SATA_PHY_P0_PARAM2);
-+
-+ /* Setting PHY_RESET to 1 */
-+ reg = readl_relaxed(phy->mmio + SATA_PHY_P0_PARAM4);
-+ reg = reg | SATA_PHY_RESET;
-+ writel_relaxed(reg, phy->mmio + SATA_PHY_P0_PARAM4);
-+
-+ /* Setting REF_SSP_EN to 1 */
-+ reg = readl_relaxed(phy->mmio + SATA_PHY_P0_PARAM4);
-+ reg = reg | SATA_PHY_REF_SSP_EN | SATA_PHY_RESET;
-+ writel_relaxed(reg, phy->mmio + SATA_PHY_P0_PARAM4);
-+ mb();
-+ qcom_ipq806x_sata_delay_us(20);
-+
-+ /* Clearing PHY_RESET to 0 */
-+ reg = readl_relaxed(phy->mmio + SATA_PHY_P0_PARAM4);
-+ reg = reg & ~SATA_PHY_RESET;
-+ writel_relaxed(reg, phy->mmio + SATA_PHY_P0_PARAM4);
-+
-+ return 0;
-+}
-+
-+static int qcom_ipq806x_sata_phy_exit(struct phy *generic_phy)
-+{
-+ struct qcom_ipq806x_sata_phy *phy = phy_get_drvdata(generic_phy);
-+ u32 reg;
-+
-+ /* Setting PHY_RESET to 1 */
-+ reg = readl_relaxed(phy->mmio + SATA_PHY_P0_PARAM4);
-+ reg = reg | SATA_PHY_RESET;
-+ writel_relaxed(reg, phy->mmio + SATA_PHY_P0_PARAM4);
-+
-+ return 0;
-+}
-+
-+static struct phy_ops qcom_ipq806x_sata_phy_ops = {
-+ .init = qcom_ipq806x_sata_phy_init,
-+ .exit = qcom_ipq806x_sata_phy_exit,
-+ .owner = THIS_MODULE,
-+};
-+
-+static int qcom_ipq806x_sata_phy_probe(struct platform_device *pdev)
-+{
-+ struct qcom_ipq806x_sata_phy *phy;
-+ struct device *dev = &pdev->dev;
-+ struct resource *res;
-+ struct phy_provider *phy_provider;
-+ struct phy *generic_phy;
-+ int ret;
-+
-+ phy = devm_kzalloc(dev, sizeof(*phy), GFP_KERNEL);
-+ if (!phy) {
-+ dev_err(dev, "%s: failed to allocate phy\n", __func__);
-+ return -ENOMEM;
-+ }
-+
-+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-+ phy->mmio = devm_ioremap_resource(dev, res);
-+ if (IS_ERR(phy->mmio))
-+ return PTR_ERR(phy->mmio);
-+
-+ generic_phy = devm_phy_create(dev, &qcom_ipq806x_sata_phy_ops, NULL);
-+ if (IS_ERR(generic_phy)) {
-+ dev_err(dev, "%s: failed to create phy\n", __func__);
-+ return PTR_ERR(generic_phy);
-+ }
-+
-+ phy_set_drvdata(generic_phy, phy);
-+
-+ phy->cfg_clk = devm_clk_get(dev, "cfg");
-+ if (IS_ERR(phy->cfg_clk)) {
-+ dev_err(dev, "Failed to get sata cfg clock\n");
-+ return PTR_ERR(phy->cfg_clk);
-+ }
-+
-+ ret = clk_prepare_enable(phy->cfg_clk);
-+ if (ret)
-+ return ret;
-+
-+ phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
-+ if (IS_ERR(phy_provider)) {
-+ clk_disable_unprepare(phy->cfg_clk);
-+ dev_err(dev, "%s: failed to register phy\n", __func__);
-+ return PTR_ERR(phy_provider);
-+ }
-+
-+ return 0;
-+}
-+
-+static int qcom_ipq806x_sata_phy_remove(struct platform_device *pdev)
-+{
-+ struct qcom_ipq806x_sata_phy *phy = platform_get_drvdata(pdev);
-+
-+ clk_disable_unprepare(phy->cfg_clk);
-+
-+ return 0;
-+}
-+
-+static const struct of_device_id qcom_ipq806x_sata_phy_of_match[] = {
-+ { .compatible = "qcom,ipq806x-sata-phy" },
-+ { },
-+};
-+MODULE_DEVICE_TABLE(of, qcom_ipq806x_sata_phy_of_match);
-+
-+static struct platform_driver qcom_ipq806x_sata_phy_driver = {
-+ .probe = qcom_ipq806x_sata_phy_probe,
-+ .remove = qcom_ipq806x_sata_phy_remove,
-+ .driver = {
-+ .name = "qcom-ipq806x-sata-phy",
-+ .owner = THIS_MODULE,
-+ .of_match_table = qcom_ipq806x_sata_phy_of_match,
-+ }
-+};
-+module_platform_driver(qcom_ipq806x_sata_phy_driver);
-+
-+MODULE_DESCRIPTION("QCOM IPQ806x SATA PHY driver");
-+MODULE_LICENSE("GPL v2");
diff --git a/target/linux/ipq806x/patches/0145-phy-qcom-Add-device-tree-bindings-information.patch b/target/linux/ipq806x/patches/0145-phy-qcom-Add-device-tree-bindings-information.patch
deleted file mode 100644
index bd5e5d4..0000000
--- a/target/linux/ipq806x/patches/0145-phy-qcom-Add-device-tree-bindings-information.patch
+++ /dev/null
@@ -1,40 +0,0 @@
-From 37258bc8fe832e4c681593a864686f627f6d3455 Mon Sep 17 00:00:00 2001
-From: Kumar Gala <galak@codeaurora.org>
-Date: Tue, 10 Jun 2014 13:09:01 -0500
-Subject: [PATCH 145/182] phy: qcom: Add device tree bindings information
-
-Add binding spec for Qualcomm SoC PHYs, starting with the SATA PHY on
-the IPQ806x family of SoCs.
-
-Signed-off-by: Kumar Gala <galak@codeaurora.org>
----
- Documentation/devicetree/bindings/phy/qcom-phy.txt | 23 ++++++++++++++++++++
- 1 file changed, 23 insertions(+)
- create mode 100644 Documentation/devicetree/bindings/phy/qcom-phy.txt
-
---- /dev/null
-+++ b/Documentation/devicetree/bindings/phy/qcom-phy.txt
-@@ -0,0 +1,23 @@
-+Qualcomm IPQ806x SATA PHY Controller
-+------------------------------------
-+
-+SATA PHY nodes are defined to describe on-chip SATA Physical layer controllers.
-+Each SATA PHY controller should have its own node.
-+
-+Required properties:
-+- compatible: compatible list, contains "qcom,ipq806x-sata-phy"
-+- reg: offset and length of the SATA PHY register set;
-+- #phy-cells: must be zero
-+- clocks: must be exactly one entry
-+- clock-names: must be "cfg"
-+
-+Example:
-+ sata_phy: sata-phy@1b400000 {
-+ compatible = "qcom,ipq806x-sata-phy";
-+ reg = <0x1b400000 0x200>;
-+
-+ clocks = <&gcc SATA_PHY_CFG_CLK>;
-+ clock-names = "cfg";
-+
-+ #phy-cells = <0>;
-+ };
diff --git a/target/linux/ipq806x/patches/0146-ARM-dts-qcom-Add-SATA-support-for-IPQ8064-and-AP148-.patch b/target/linux/ipq806x/patches/0146-ARM-dts-qcom-Add-SATA-support-for-IPQ8064-and-AP148-.patch
deleted file mode 100644
index da124c7..0000000
--- a/target/linux/ipq806x/patches/0146-ARM-dts-qcom-Add-SATA-support-for-IPQ8064-and-AP148-.patch
+++ /dev/null
@@ -1,65 +0,0 @@
-From 6992cf3e8900d042a845eafc11e7841f32fec0a6 Mon Sep 17 00:00:00 2001
-From: Kumar Gala <galak@codeaurora.org>
-Date: Thu, 12 Jun 2014 10:56:54 -0500
-Subject: [PATCH 146/182] ARM: dts: qcom: Add SATA support for IPQ8064 and
- AP148 board
-
----
- arch/arm/boot/dts/qcom-ipq8064-ap148.dts | 8 ++++++++
- arch/arm/boot/dts/qcom-ipq8064.dtsi | 30 ++++++++++++++++++++++++++++++
- 2 files changed, 38 insertions(+)
-
---- a/arch/arm/boot/dts/qcom-ipq8064-ap148.dts
-+++ b/arch/arm/boot/dts/qcom-ipq8064-ap148.dts
-@@ -118,5 +118,13 @@
- 0x81000000 0 0 0x31e00000 0 0x00100000 /* downstream I/O */
- 0x82000000 0 0x00000000 0x2e000000 0 0x03e00000>; /* non-prefetchable memory */
- };
-+
-+ sata-phy@1b400000 {
-+ status = "ok";
-+ };
-+
-+ sata@29000000 {
-+ status = "ok";
-+ };
- };
- };
---- a/arch/arm/boot/dts/qcom-ipq8064.dtsi
-+++ b/arch/arm/boot/dts/qcom-ipq8064.dtsi
-@@ -339,5 +339,35 @@
- clock-names = "core", "iface", "phy";
- status = "disabled";
- };
-+
-+ sata_phy: sata-phy@1b400000 {
-+ compatible = "qcom,ipq806x-sata-phy";
-+ reg = <0x1b400000 0x200>;
-+
-+ clocks = <&gcc SATA_PHY_CFG_CLK>;
-+ clock-names = "cfg";
-+
-+ #phy-cells = <0>;
-+ status = "disabled";
-+ };
-+
-+ sata@29000000 {
-+ compatible = "qcom,ipq806x-ahci", "qcom,msm-ahci";
-+ reg = <0x29000000 0x180>;
-+
-+ interrupts = <0 209 0x0>;
-+
-+ clocks = <&gcc SFAB_SATA_S_H_CLK>,
-+ <&gcc SATA_H_CLK>,
-+ <&gcc SATA_A_CLK>,
-+ <&gcc SATA_RXOOB_CLK>,
-+ <&gcc SATA_PMALIVE_CLK>;
-+ clock-names = "slave_face", "iface", "core",
-+ "rxoob", "pmalive";
-+
-+ phys = <&sata_phy>;
-+ phy-names = "sata-phy";
-+ status = "disabled";
-+ };
- };
- };
diff --git a/target/linux/ipq806x/patches/0147-ARM-qcom-Enable-SATA-SATA-PHY-drivers-in-defconfig.patch b/target/linux/ipq806x/patches/0147-ARM-qcom-Enable-SATA-SATA-PHY-drivers-in-defconfig.patch
deleted file mode 100644
index 7465f56..0000000
--- a/target/linux/ipq806x/patches/0147-ARM-qcom-Enable-SATA-SATA-PHY-drivers-in-defconfig.patch
+++ /dev/null
@@ -1,37 +0,0 @@
-From 54a945eca8381fa8cda03b20eda3b2f23a88d289 Mon Sep 17 00:00:00 2001
-From: Kumar Gala <galak@codeaurora.org>
-Date: Tue, 3 Jun 2014 10:36:41 -0500
-Subject: [PATCH 147/182] ARM: qcom: Enable SATA/SATA-PHY drivers in defconfig
-
----
- arch/arm/configs/qcom_defconfig | 5 +++--
- 1 file changed, 3 insertions(+), 2 deletions(-)
-
---- a/arch/arm/configs/qcom_defconfig
-+++ b/arch/arm/configs/qcom_defconfig
-@@ -57,7 +57,6 @@ CONFIG_MTD_BLOCK=y
- CONFIG_MTD_M25P80=y
- CONFIG_BLK_DEV_LOOP=y
- CONFIG_BLK_DEV_RAM=y
--CONFIG_SCSI=y
- CONFIG_SCSI_TGT=y
- CONFIG_BLK_DEV_SD=y
- CONFIG_CHR_DEV_SG=y
-@@ -66,6 +65,8 @@ CONFIG_SCSI_MULTI_LUN=y
- CONFIG_SCSI_CONSTANTS=y
- CONFIG_SCSI_LOGGING=y
- CONFIG_SCSI_SCAN_ASYNC=y
-+CONFIG_ATA=y
-+CONFIG_AHCI_QCOM=y
- CONFIG_NETDEVICES=y
- CONFIG_DUMMY=y
- CONFIG_MDIO_BITBANG=y
-@@ -141,7 +142,7 @@ CONFIG_MSM_GCC_8660=y
- CONFIG_MSM_MMCC_8960=y
- CONFIG_MSM_MMCC_8974=y
- CONFIG_MSM_IOMMU=y
--CONFIG_GENERIC_PHY=y
-+CONFIG_PHY_QCOM_IPQ806X_SATA=y
- CONFIG_EXT2_FS=y
- CONFIG_EXT2_FS_XATTR=y
- CONFIG_EXT3_FS=y
diff --git a/target/linux/ipq806x/patches/0148-ARM-qcom-enable-default-CPU_IDLE-to-get-wfi-support-.patch b/target/linux/ipq806x/patches/0148-ARM-qcom-enable-default-CPU_IDLE-to-get-wfi-support-.patch
deleted file mode 100644
index c68a23b..0000000
--- a/target/linux/ipq806x/patches/0148-ARM-qcom-enable-default-CPU_IDLE-to-get-wfi-support-.patch
+++ /dev/null
@@ -1,21 +0,0 @@
-From 8c9156c67c3e3e37812bb0e4d24263be0e564881 Mon Sep 17 00:00:00 2001
-From: Kumar Gala <galak@codeaurora.org>
-Date: Mon, 16 Jun 2014 14:40:29 -0500
-Subject: [PATCH 148/182] ARM: qcom: enable default CPU_IDLE to get wfi
- support on IPQ806x
-
-Signed-off-by: Kumar Gala <galak@codeaurora.org>
----
- arch/arm/configs/qcom_defconfig | 1 +
- 1 file changed, 1 insertion(+)
-
---- a/arch/arm/configs/qcom_defconfig
-+++ b/arch/arm/configs/qcom_defconfig
-@@ -31,6 +31,7 @@ CONFIG_HIGHPTE=y
- CONFIG_CLEANCACHE=y
- CONFIG_ARM_APPENDED_DTB=y
- CONFIG_ARM_ATAG_DTB_COMPAT=y
-+CONFIG_CPU_IDLE=y
- CONFIG_VFP=y
- CONFIG_NEON=y
- # CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
diff --git a/target/linux/ipq806x/patches/0149-pinctrl-qcom-Add-BUS_HOLD-Keeper-bias.patch b/target/linux/ipq806x/patches/0149-pinctrl-qcom-Add-BUS_HOLD-Keeper-bias.patch
deleted file mode 100644
index 8b2e18a..0000000
--- a/target/linux/ipq806x/patches/0149-pinctrl-qcom-Add-BUS_HOLD-Keeper-bias.patch
+++ /dev/null
@@ -1,50 +0,0 @@
-From b1325bfad3ad0e543ce90a6b08d74500dc96f4b9 Mon Sep 17 00:00:00 2001
-From: Andy Gross <agross@codeaurora.org>
-Date: Mon, 16 Jun 2014 16:52:55 -0500
-Subject: [PATCH 149/182] pinctrl: qcom: Add BUS_HOLD/Keeper bias
-
-This patch adds the bus_hold bias option for pins.
-
-Signed-off-by: Andy Gross <agross@codeaurora.org>
----
- drivers/pinctrl/pinctrl-msm.c | 8 ++++++++
- 1 file changed, 8 insertions(+)
-
---- a/drivers/pinctrl/pinctrl-msm.c
-+++ b/drivers/pinctrl/pinctrl-msm.c
-@@ -207,6 +207,7 @@ static int msm_config_reg(struct msm_pin
- case PIN_CONFIG_BIAS_DISABLE:
- case PIN_CONFIG_BIAS_PULL_DOWN:
- case PIN_CONFIG_BIAS_PULL_UP:
-+ case PIN_CONFIG_BIAS_BUS_HOLD:
- *bit = g->pull_bit;
- *mask = 3;
- break;
-@@ -243,6 +244,7 @@ static int msm_config_set(struct pinctrl
-
- #define MSM_NO_PULL 0
- #define MSM_PULL_DOWN 1
-+#define MSM_KEEPER 2
- #define MSM_PULL_UP 3
-
- static unsigned msm_regval_to_drive(u32 val)
-@@ -280,6 +282,9 @@ static int msm_config_group_get(struct p
- case PIN_CONFIG_BIAS_PULL_DOWN:
- arg = arg == MSM_PULL_DOWN;
- break;
-+ case PIN_CONFIG_BIAS_BUS_HOLD:
-+ arg = arg == MSM_KEEPER;
-+ break;
- case PIN_CONFIG_BIAS_PULL_UP:
- arg = arg == MSM_PULL_UP;
- break;
-@@ -339,6 +344,9 @@ static int msm_config_group_set(struct p
- case PIN_CONFIG_BIAS_PULL_DOWN:
- arg = MSM_PULL_DOWN;
- break;
-+ case PIN_CONFIG_BIAS_BUS_HOLD:
-+ arg = MSM_KEEPER;
-+ break;
- case PIN_CONFIG_BIAS_PULL_UP:
- arg = MSM_PULL_UP;
- break;
diff --git a/target/linux/ipq806x/patches/0150-mtd-nand-Add-Qualcomm-NAND-controller.patch b/target/linux/ipq806x/patches/0150-mtd-nand-Add-Qualcomm-NAND-controller.patch
deleted file mode 100644
index f19045e..0000000
--- a/target/linux/ipq806x/patches/0150-mtd-nand-Add-Qualcomm-NAND-controller.patch
+++ /dev/null
@@ -1,8784 +0,0 @@
-From d2981ca1343b837fc574c4e46806d041b258720d Mon Sep 17 00:00:00 2001
-From: Andy Gross <agross@codeaurora.org>
-Date: Mon, 16 Jun 2014 17:13:22 -0500
-Subject: [PATCH 150/182] mtd: nand: Add Qualcomm NAND controller
-
-This patch adds the Qualcomm NAND controller and required infrastructure.
-
-Signed-off-by: Andy Gross <agross@codeaurora.org>
----
- drivers/mtd/nand/Kconfig | 18 +
- drivers/mtd/nand/Makefile | 2 +
- drivers/mtd/nand/qcom_adm_dma.c | 797 +++++
- drivers/mtd/nand/qcom_adm_dma.h | 268 ++
- drivers/mtd/nand/qcom_nand.c | 7455 +++++++++++++++++++++++++++++++++++++++
- drivers/mtd/nand/qcom_nand.h | 196 +
- 6 files changed, 8736 insertions(+)
- create mode 100644 drivers/mtd/nand/qcom_adm_dma.c
- create mode 100644 drivers/mtd/nand/qcom_adm_dma.h
- create mode 100644 drivers/mtd/nand/qcom_nand.c
- create mode 100644 drivers/mtd/nand/qcom_nand.h
-
---- a/drivers/mtd/nand/Kconfig
-+++ b/drivers/mtd/nand/Kconfig
-@@ -510,4 +510,22 @@ config MTD_NAND_XWAY
- Enables support for NAND Flash chips on Lantiq XWAY SoCs. NAND is attached
- to the External Bus Unit (EBU).
-
-+config MTD_QCOM_DMA
-+ tristate "QCMO NAND DMA Support"
-+ depends on ARCH_QCOM && MTD_QCOM_NAND
-+ default n
-+ help
-+ DMA support for QCOM NAND
-+
-+config MTD_QCOM_NAND
-+ tristate "QCOM NAND Device Support"
-+ depends on MTD && ARCH_QCOM
-+ select CRC16
-+ select BITREVERSE
-+ select MTD_NAND_IDS
-+ select MTD_QCOM_DMA
-+ default y
-+ help
-+ Support for some NAND chips connected to the QCOM NAND controller.
-+
- endif # MTD_NAND
---- a/drivers/mtd/nand/Makefile
-+++ b/drivers/mtd/nand/Makefile
-@@ -49,5 +49,7 @@ obj-$(CONFIG_MTD_NAND_JZ4740) += jz4740
- obj-$(CONFIG_MTD_NAND_GPMI_NAND) += gpmi-nand/
- obj-$(CONFIG_MTD_NAND_XWAY) += xway_nand.o
- obj-$(CONFIG_MTD_NAND_BCM47XXNFLASH) += bcm47xxnflash/
-+obj-$(CONFIG_MTD_QCOM_NAND) += qcom_nand.o
-+obj-$(CONFIG_MTD_QCOM_DMA) += qcom_adm_dma.o
-
- nand-objs := nand_base.o nand_bbt.o
---- /dev/null
-+++ b/drivers/mtd/nand/qcom_adm_dma.c
-@@ -0,0 +1,797 @@
-+/* * Copyright (c) 2012 The Linux Foundation. All rights reserved.* */
-+/* linux/arch/arm/mach-msm/dma.c
-+ *
-+ * Copyright (C) 2007 Google, Inc.
-+ * Copyright (c) 2008-2010, 2012 The Linux Foundation. All rights reserved.
-+ *
-+ * This software is licensed under the terms of the GNU General Public
-+ * License version 2, as published by the Free Software Foundation, and
-+ * may be copied, distributed, and modified under those terms.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ * GNU General Public License for more details.
-+ *
-+ */
-+
-+#include <linux/clk.h>
-+#include <linux/err.h>
-+#include <linux/io.h>
-+#include <linux/interrupt.h>
-+#include <linux/module.h>
-+#include <linux/platform_device.h>
-+#include <linux/spinlock.h>
-+#include <linux/pm_runtime.h>
-+#include <linux/reset.h>
-+#include <linux/reset-controller.h>
-+#include "qcom_adm_dma.h"
-+
-+#define MODULE_NAME "msm_dmov"
-+
-+#define MSM_DMOV_CHANNEL_COUNT 16
-+#define MSM_DMOV_CRCI_COUNT 16
-+
-+enum {
-+ CLK_DIS,
-+ CLK_TO_BE_DIS,
-+ CLK_EN
-+};
-+
-+struct msm_dmov_ci_conf {
-+ int start;
-+ int end;
-+ int burst;
-+};
-+
-+struct msm_dmov_crci_conf {
-+ int sd;
-+ int blk_size;
-+};
-+
-+struct msm_dmov_chan_conf {
-+ int sd;
-+ int block;
-+ int priority;
-+};
-+
-+struct msm_dmov_conf {
-+ void *base;
-+ struct msm_dmov_crci_conf *crci_conf;
-+ struct msm_dmov_chan_conf *chan_conf;
-+ int channel_active;
-+ int sd;
-+ size_t sd_size;
-+ struct list_head staged_commands[MSM_DMOV_CHANNEL_COUNT];
-+ struct list_head ready_commands[MSM_DMOV_CHANNEL_COUNT];
-+ struct list_head active_commands[MSM_DMOV_CHANNEL_COUNT];
-+ struct mutex lock;
-+ spinlock_t list_lock;
-+ unsigned int irq;
-+ struct clk *clk;
-+ struct clk *pclk;
-+ struct clk *ebiclk;
-+ unsigned int clk_ctl;
-+ struct delayed_work work;
-+ struct workqueue_struct *cmd_wq;
-+
-+ struct reset_control *adm_reset;
-+ struct reset_control *pbus_reset;
-+ struct reset_control *c0_reset;
-+ struct reset_control *c1_reset;
-+ struct reset_control *c2_reset;
-+
-+};
-+
-+static void msm_dmov_clock_work(struct work_struct *);
-+
-+#define DMOV_CRCI_DEFAULT_CONF { .sd = 0, .blk_size = 0 }
-+#define DMOV_CRCI_CONF(secd, blk) { .sd = secd, .blk_size = blk }
-+
-+static struct msm_dmov_crci_conf adm_crci_conf[] = {
-+ DMOV_CRCI_DEFAULT_CONF,
-+ DMOV_CRCI_DEFAULT_CONF,
-+ DMOV_CRCI_DEFAULT_CONF,
-+ DMOV_CRCI_DEFAULT_CONF,
-+ DMOV_CRCI_DEFAULT_CONF,
-+ DMOV_CRCI_DEFAULT_CONF,
-+ DMOV_CRCI_DEFAULT_CONF,
-+ DMOV_CRCI_DEFAULT_CONF,
-+ DMOV_CRCI_DEFAULT_CONF,
-+ DMOV_CRCI_DEFAULT_CONF,
-+ DMOV_CRCI_CONF(0, 1),
-+ DMOV_CRCI_DEFAULT_CONF,
-+ DMOV_CRCI_DEFAULT_CONF,
-+ DMOV_CRCI_DEFAULT_CONF,
-+ DMOV_CRCI_DEFAULT_CONF,
-+ DMOV_CRCI_DEFAULT_CONF,
-+};
-+
-+#define DMOV_CHANNEL_DEFAULT_CONF { .sd = 0, .block = 0, .priority = 1 }
-+
-+static struct msm_dmov_chan_conf adm_chan_conf[] = {
-+ DMOV_CHANNEL_DEFAULT_CONF,
-+ DMOV_CHANNEL_DEFAULT_CONF,
-+ DMOV_CHANNEL_DEFAULT_CONF,
-+ DMOV_CHANNEL_DEFAULT_CONF,
-+ DMOV_CHANNEL_DEFAULT_CONF,
-+ DMOV_CHANNEL_DEFAULT_CONF,
-+ DMOV_CHANNEL_DEFAULT_CONF,
-+ DMOV_CHANNEL_DEFAULT_CONF,
-+ DMOV_CHANNEL_DEFAULT_CONF,
-+ DMOV_CHANNEL_DEFAULT_CONF,
-+ DMOV_CHANNEL_DEFAULT_CONF,
-+ DMOV_CHANNEL_DEFAULT_CONF,
-+ DMOV_CHANNEL_DEFAULT_CONF,
-+ DMOV_CHANNEL_DEFAULT_CONF,
-+ DMOV_CHANNEL_DEFAULT_CONF,
-+ DMOV_CHANNEL_DEFAULT_CONF,
-+};
-+
-+#define DMOV_IRQ_TO_ADM(irq) 0
-+
-+static struct msm_dmov_conf dmov_conf[] = {
-+ {
-+ .crci_conf = adm_crci_conf,
-+ .chan_conf = adm_chan_conf,
-+ .lock = __MUTEX_INITIALIZER(dmov_conf[0].lock),
-+ .list_lock = __SPIN_LOCK_UNLOCKED(dmov_list_lock),
-+ .clk_ctl = CLK_EN,
-+ .work = __DELAYED_WORK_INITIALIZER(dmov_conf[0].work,
-+ msm_dmov_clock_work,0),
-+ }
-+};
-+
-+#define MSM_DMOV_ID_COUNT (MSM_DMOV_CHANNEL_COUNT * ARRAY_SIZE(dmov_conf))
-+#define DMOV_REG(name, adm) ((name) + (dmov_conf[adm].base) +\
-+ (dmov_conf[adm].sd * dmov_conf[adm].sd_size))
-+#define DMOV_ID_TO_ADM(id) ((id) / MSM_DMOV_CHANNEL_COUNT)
-+#define DMOV_ID_TO_CHAN(id) ((id) % MSM_DMOV_CHANNEL_COUNT)
-+#define DMOV_CHAN_ADM_TO_ID(ch, adm) ((ch) + (adm) * MSM_DMOV_CHANNEL_COUNT)
-+
-+enum {
-+ MSM_DMOV_PRINT_ERRORS = 1,
-+ MSM_DMOV_PRINT_IO = 2,
-+ MSM_DMOV_PRINT_FLOW = 4
-+};
-+
-+unsigned int msm_dmov_print_mask = MSM_DMOV_PRINT_ERRORS;
-+
-+#define MSM_DMOV_DPRINTF(mask, format, args...) \
-+ do { \
-+ if ((mask) & msm_dmov_print_mask) \
-+ printk(KERN_ERR format, args); \
-+ } while (0)
-+#define PRINT_ERROR(format, args...) \
-+ MSM_DMOV_DPRINTF(MSM_DMOV_PRINT_ERRORS, format, args);
-+#define PRINT_IO(format, args...) \
-+ MSM_DMOV_DPRINTF(MSM_DMOV_PRINT_IO, format, args);
-+#define PRINT_FLOW(format, args...) \
-+ MSM_DMOV_DPRINTF(MSM_DMOV_PRINT_FLOW, format, args);
-+
-+static int msm_dmov_clk_on(int adm)
-+{
-+ int ret;
-+
-+return 0;
-+ ret = clk_prepare_enable(dmov_conf[adm].clk);
-+ if (ret)
-+ return ret;
-+ if (dmov_conf[adm].pclk) {
-+ ret = clk_prepare_enable(dmov_conf[adm].pclk);
-+ if (ret) {
-+ clk_disable_unprepare(dmov_conf[adm].clk);
-+ return ret;
-+ }
-+ }
-+ if (dmov_conf[adm].ebiclk) {
-+ ret = clk_prepare_enable(dmov_conf[adm].ebiclk);
-+ if (ret) {
-+ if (dmov_conf[adm].pclk)
-+ clk_disable_unprepare(dmov_conf[adm].pclk);
-+ clk_disable_unprepare(dmov_conf[adm].clk);
-+ }
-+ }
-+ return ret;
-+}
-+
-+static void msm_dmov_clk_off(int adm)
-+{
-+#if 0
-+ if (dmov_conf[adm].ebiclk)
-+ clk_disable_unprepare(dmov_conf[adm].ebiclk);
-+ if (dmov_conf[adm].pclk)
-+ clk_disable_unprepare(dmov_conf[adm].pclk);
-+ clk_disable_unprepare(dmov_conf[adm].clk);
-+#endif
-+}
-+
-+static void msm_dmov_clock_work(struct work_struct *work)
-+{
-+ struct msm_dmov_conf *conf =
-+ container_of(to_delayed_work(work), struct msm_dmov_conf, work);
-+ int adm = DMOV_IRQ_TO_ADM(conf->irq);
-+ mutex_lock(&conf->lock);
-+ if (conf->clk_ctl == CLK_TO_BE_DIS) {
-+ BUG_ON(conf->channel_active);
-+ msm_dmov_clk_off(adm);
-+ conf->clk_ctl = CLK_DIS;
-+ }
-+ mutex_unlock(&conf->lock);
-+}
-+
-+enum {
-+ NOFLUSH = 0,
-+ GRACEFUL,
-+ NONGRACEFUL,
-+};
-+
-+/* Caller must hold the list lock */
-+static struct msm_dmov_cmd *start_ready_cmd(unsigned ch, int adm)
-+{
-+ struct msm_dmov_cmd *cmd;
-+
-+ if (list_empty(&dmov_conf[adm].ready_commands[ch])) {
-+ return NULL;
-+ }
-+
-+ cmd = list_entry(dmov_conf[adm].ready_commands[ch].next, typeof(*cmd),
-+ list);
-+ list_del(&cmd->list);
-+ if (cmd->exec_func)
-+ cmd->exec_func(cmd);
-+ list_add_tail(&cmd->list, &dmov_conf[adm].active_commands[ch]);
-+ if (!dmov_conf[adm].channel_active) {
-+ enable_irq(dmov_conf[adm].irq);
-+ }
-+ dmov_conf[adm].channel_active |= BIT(ch);
-+ PRINT_IO("msm dmov enqueue command, %x, ch %d\n", cmd->cmdptr, ch);
-+ writel_relaxed(cmd->cmdptr, DMOV_REG(DMOV_CMD_PTR(ch), adm));
-+
-+ return cmd;
-+}
-+
-+static void msm_dmov_enqueue_cmd_ext_work(struct work_struct *work)
-+{
-+ struct msm_dmov_cmd *cmd =
-+ container_of(work, struct msm_dmov_cmd, work);
-+ unsigned id = cmd->id;
-+ unsigned status;
-+ unsigned long flags;
-+ int adm = DMOV_ID_TO_ADM(id);
-+ int ch = DMOV_ID_TO_CHAN(id);
-+
-+ mutex_lock(&dmov_conf[adm].lock);
-+ if (dmov_conf[adm].clk_ctl == CLK_DIS) {
-+ status = msm_dmov_clk_on(adm);
-+ if (status != 0)
-+ goto error;
-+ }
-+ dmov_conf[adm].clk_ctl = CLK_EN;
-+
-+ spin_lock_irqsave(&dmov_conf[adm].list_lock, flags);
-+
-+ cmd = list_entry(dmov_conf[adm].staged_commands[ch].next, typeof(*cmd),
-+ list);
-+ list_del(&cmd->list);
-+ list_add_tail(&cmd->list, &dmov_conf[adm].ready_commands[ch]);
-+ status = readl_relaxed(DMOV_REG(DMOV_STATUS(ch), adm));
-+ if (status & DMOV_STATUS_CMD_PTR_RDY) {
-+ PRINT_IO("msm_dmov_enqueue_cmd(%d), start command, status %x\n",
-+ id, status);
-+ cmd = start_ready_cmd(ch, adm);
-+ /*
-+ * We added something to the ready list, and still hold the
-+ * list lock. Thus, no need to check for cmd == NULL
-+ */
-+ if (cmd->toflush) {
-+ int flush = (cmd->toflush == GRACEFUL) ? 1 << 31 : 0;
-+ writel_relaxed(flush, DMOV_REG(DMOV_FLUSH0(ch), adm));
-+ }
-+ } else {
-+ cmd->toflush = 0;
-+ if (list_empty(&dmov_conf[adm].active_commands[ch]) &&
-+ !list_empty(&dmov_conf[adm].ready_commands[ch]))
-+ PRINT_ERROR("msm_dmov_enqueue_cmd_ext(%d), stalled, "
-+ "status %x\n", id, status);
-+ PRINT_IO("msm_dmov_enqueue_cmd(%d), enqueue command, status "
-+ "%x\n", id, status);
-+ }
-+ if (!dmov_conf[adm].channel_active) {
-+ dmov_conf[adm].clk_ctl = CLK_TO_BE_DIS;
-+ schedule_delayed_work(&dmov_conf[adm].work, (HZ/10));
-+ }
-+ spin_unlock_irqrestore(&dmov_conf[adm].list_lock, flags);
-+error:
-+ mutex_unlock(&dmov_conf[adm].lock);
-+}
-+
-+static void __msm_dmov_enqueue_cmd_ext(unsigned id, struct msm_dmov_cmd *cmd)
-+{
-+ int adm = DMOV_ID_TO_ADM(id);
-+ int ch = DMOV_ID_TO_CHAN(id);
-+ unsigned long flags;
-+ cmd->id = id;
-+ cmd->toflush = 0;
-+
-+ spin_lock_irqsave(&dmov_conf[adm].list_lock, flags);
-+ list_add_tail(&cmd->list, &dmov_conf[adm].staged_commands[ch]);
-+ spin_unlock_irqrestore(&dmov_conf[adm].list_lock, flags);
-+
-+ queue_work(dmov_conf[adm].cmd_wq, &cmd->work);
-+}
-+
-+void msm_dmov_enqueue_cmd_ext(unsigned id, struct msm_dmov_cmd *cmd)
-+{
-+ INIT_WORK(&cmd->work, msm_dmov_enqueue_cmd_ext_work);
-+ __msm_dmov_enqueue_cmd_ext(id, cmd);
-+}
-+EXPORT_SYMBOL(msm_dmov_enqueue_cmd_ext);
-+
-+void msm_dmov_enqueue_cmd(unsigned id, struct msm_dmov_cmd *cmd)
-+{
-+ /* Disable callback function (for backwards compatibility) */
-+ cmd->exec_func = NULL;
-+ INIT_WORK(&cmd->work, msm_dmov_enqueue_cmd_ext_work);
-+ __msm_dmov_enqueue_cmd_ext(id, cmd);
-+}
-+EXPORT_SYMBOL(msm_dmov_enqueue_cmd);
-+
-+void msm_dmov_flush(unsigned int id, int graceful)
-+{
-+ unsigned long irq_flags;
-+ int ch = DMOV_ID_TO_CHAN(id);
-+ int adm = DMOV_ID_TO_ADM(id);
-+ int flush = graceful ? DMOV_FLUSH_TYPE : 0;
-+ struct msm_dmov_cmd *cmd;
-+
-+ spin_lock_irqsave(&dmov_conf[adm].list_lock, irq_flags);
-+ /* XXX not checking if flush cmd sent already */
-+ if (!list_empty(&dmov_conf[adm].active_commands[ch])) {
-+ PRINT_IO("msm_dmov_flush(%d), send flush cmd\n", id);
-+ writel_relaxed(flush, DMOV_REG(DMOV_FLUSH0(ch), adm));
-+ }
-+ list_for_each_entry(cmd, &dmov_conf[adm].staged_commands[ch], list)
-+ cmd->toflush = graceful ? GRACEFUL : NONGRACEFUL;
-+ /* spin_unlock_irqrestore has the necessary barrier */
-+ spin_unlock_irqrestore(&dmov_conf[adm].list_lock, irq_flags);
-+}
-+EXPORT_SYMBOL(msm_dmov_flush);
-+
-+struct msm_dmov_exec_cmdptr_cmd {
-+ struct msm_dmov_cmd dmov_cmd;
-+ struct completion complete;
-+ unsigned id;
-+ unsigned int result;
-+ struct msm_dmov_errdata err;
-+};
-+
-+static void
-+dmov_exec_cmdptr_complete_func(struct msm_dmov_cmd *_cmd,
-+ unsigned int result,
-+ struct msm_dmov_errdata *err)
-+{
-+ struct msm_dmov_exec_cmdptr_cmd *cmd = container_of(_cmd, struct msm_dmov_exec_cmdptr_cmd, dmov_cmd);
-+ cmd->result = result;
-+ if (result != 0x80000002 && err)
-+ memcpy(&cmd->err, err, sizeof(struct msm_dmov_errdata));
-+
-+ complete(&cmd->complete);
-+}
-+
-+int msm_dmov_exec_cmd(unsigned id, unsigned int cmdptr)
-+{
-+ struct msm_dmov_exec_cmdptr_cmd cmd;
-+
-+ PRINT_FLOW("dmov_exec_cmdptr(%d, %x)\n", id, cmdptr);
-+
-+ cmd.dmov_cmd.cmdptr = cmdptr;
-+ cmd.dmov_cmd.complete_func = dmov_exec_cmdptr_complete_func;
-+ cmd.dmov_cmd.exec_func = NULL;
-+ cmd.id = id;
-+ cmd.result = 0;
-+ INIT_WORK_ONSTACK(&cmd.dmov_cmd.work, msm_dmov_enqueue_cmd_ext_work);
-+ init_completion(&cmd.complete);
-+
-+ __msm_dmov_enqueue_cmd_ext(id, &cmd.dmov_cmd);
-+ wait_for_completion_timeout(&cmd.complete, msecs_to_jiffies(1000));
-+
-+ if (cmd.result != 0x80000002) {
-+ PRINT_ERROR("dmov_exec_cmdptr(%d): ERROR, result: %x\n", id, cmd.result);
-+ PRINT_ERROR("dmov_exec_cmdptr(%d): flush: %x %x %x %x\n",
-+ id, cmd.err.flush[0], cmd.err.flush[1], cmd.err.flush[2], cmd.err.flush[3]);
-+ return -EIO;
-+ }
-+ PRINT_FLOW("dmov_exec_cmdptr(%d, %x) done\n", id, cmdptr);
-+ return 0;
-+}
-+EXPORT_SYMBOL(msm_dmov_exec_cmd);
-+
-+static void fill_errdata(struct msm_dmov_errdata *errdata, int ch, int adm)
-+{
-+ errdata->flush[0] = readl_relaxed(DMOV_REG(DMOV_FLUSH0(ch), adm));
-+ errdata->flush[1] = readl_relaxed(DMOV_REG(DMOV_FLUSH1(ch), adm));
-+ errdata->flush[2] = 0;
-+ errdata->flush[3] = readl_relaxed(DMOV_REG(DMOV_FLUSH3(ch), adm));
-+ errdata->flush[4] = readl_relaxed(DMOV_REG(DMOV_FLUSH4(ch), adm));
-+ errdata->flush[5] = readl_relaxed(DMOV_REG(DMOV_FLUSH5(ch), adm));
-+}
-+
-+static irqreturn_t msm_dmov_isr(int irq, void *dev_id)
-+{
-+ unsigned int int_status;
-+ unsigned int mask;
-+ unsigned int id;
-+ unsigned int ch;
-+ unsigned long irq_flags;
-+ unsigned int ch_status;
-+ unsigned int ch_result;
-+ unsigned int valid = 0;
-+ struct msm_dmov_cmd *cmd;
-+ int adm = DMOV_IRQ_TO_ADM(irq);
-+
-+ mutex_lock(&dmov_conf[adm].lock);
-+ /* read and clear isr */
-+ int_status = readl_relaxed(DMOV_REG(DMOV_ISR, adm));
-+ PRINT_FLOW("msm_datamover_irq_handler: DMOV_ISR %x\n", int_status);
-+
-+ spin_lock_irqsave(&dmov_conf[adm].list_lock, irq_flags);
-+ while (int_status) {
-+ mask = int_status & -int_status;
-+ ch = fls(mask) - 1;
-+ id = DMOV_CHAN_ADM_TO_ID(ch, adm);
-+ PRINT_FLOW("msm_datamover_irq_handler %08x %08x id %d\n", int_status, mask, id);
-+ int_status &= ~mask;
-+ ch_status = readl_relaxed(DMOV_REG(DMOV_STATUS(ch), adm));
-+ if (!(ch_status & DMOV_STATUS_RSLT_VALID)) {
-+ PRINT_FLOW("msm_datamover_irq_handler id %d, "
-+ "result not valid %x\n", id, ch_status);
-+ continue;
-+ }
-+ do {
-+ valid = 1;
-+ ch_result = readl_relaxed(DMOV_REG(DMOV_RSLT(ch), adm));
-+ if (list_empty(&dmov_conf[adm].active_commands[ch])) {
-+ PRINT_ERROR("msm_datamover_irq_handler id %d, got result "
-+ "with no active command, status %x, result %x\n",
-+ id, ch_status, ch_result);
-+ cmd = NULL;
-+ } else {
-+ cmd = list_entry(dmov_conf[adm].
-+ active_commands[ch].next, typeof(*cmd),
-+ list);
-+ }
-+ PRINT_FLOW("msm_datamover_irq_handler id %d, status %x, result %x\n", id, ch_status, ch_result);
-+ if (ch_result & DMOV_RSLT_DONE) {
-+ PRINT_FLOW("msm_datamover_irq_handler id %d, status %x\n",
-+ id, ch_status);
-+ PRINT_IO("msm_datamover_irq_handler id %d, got result "
-+ "for %p, result %x\n", id, cmd, ch_result);
-+ if (cmd) {
-+ list_del(&cmd->list);
-+ cmd->complete_func(cmd, ch_result, NULL);
-+ }
-+ }
-+ if (ch_result & DMOV_RSLT_FLUSH) {
-+ struct msm_dmov_errdata errdata;
-+
-+ fill_errdata(&errdata, ch, adm);
-+ PRINT_FLOW("msm_datamover_irq_handler id %d, status %x\n", id, ch_status);
-+ PRINT_FLOW("msm_datamover_irq_handler id %d, flush, result %x, flush0 %x\n", id, ch_result, errdata.flush[0]);
-+ if (cmd) {
-+ list_del(&cmd->list);
-+ cmd->complete_func(cmd, ch_result, &errdata);
-+ }
-+ }
-+ if (ch_result & DMOV_RSLT_ERROR) {
-+ struct msm_dmov_errdata errdata;
-+
-+ fill_errdata(&errdata, ch, adm);
-+
-+ PRINT_ERROR("msm_datamover_irq_handler id %d, status %x\n", id, ch_status);
-+ PRINT_ERROR("msm_datamover_irq_handler id %d, error, result %x, flush0 %x\n", id, ch_result, errdata.flush[0]);
-+ if (cmd) {
-+ list_del(&cmd->list);
-+ cmd->complete_func(cmd, ch_result, &errdata);
-+ }
-+ /* this does not seem to work, once we get an error */
-+ /* the datamover will no longer accept commands */
-+ writel_relaxed(0, DMOV_REG(DMOV_FLUSH0(ch),
-+ adm));
-+ }
-+ rmb();
-+ ch_status = readl_relaxed(DMOV_REG(DMOV_STATUS(ch),
-+ adm));
-+ PRINT_FLOW("msm_datamover_irq_handler id %d, status %x\n", id, ch_status);
-+ if (ch_status & DMOV_STATUS_CMD_PTR_RDY)
-+ start_ready_cmd(ch, adm);
-+ } while (ch_status & DMOV_STATUS_RSLT_VALID);
-+ if (list_empty(&dmov_conf[adm].active_commands[ch]) &&
-+ list_empty(&dmov_conf[adm].ready_commands[ch]))
-+ dmov_conf[adm].channel_active &= ~(1U << ch);
-+ PRINT_FLOW("msm_datamover_irq_handler id %d, status %x\n", id, ch_status);
-+ }
-+ spin_unlock_irqrestore(&dmov_conf[adm].list_lock, irq_flags);
-+
-+ if (!dmov_conf[adm].channel_active && valid) {
-+ disable_irq_nosync(dmov_conf[adm].irq);
-+ dmov_conf[adm].clk_ctl = CLK_TO_BE_DIS;
-+ schedule_delayed_work(&dmov_conf[adm].work, (HZ/10));
-+ }
-+
-+ mutex_unlock(&dmov_conf[adm].lock);
-+
-+ return valid ? IRQ_HANDLED : IRQ_NONE;
-+}
-+
-+static int msm_dmov_suspend_late(struct device *dev)
-+{
-+ struct platform_device *pdev = to_platform_device(dev);
-+ int adm = (pdev->id >= 0) ? pdev->id : 0;
-+ mutex_lock(&dmov_conf[adm].lock);
-+ if (dmov_conf[adm].clk_ctl == CLK_TO_BE_DIS) {
-+ BUG_ON(dmov_conf[adm].channel_active);
-+ msm_dmov_clk_off(adm);
-+ dmov_conf[adm].clk_ctl = CLK_DIS;
-+ }
-+ mutex_unlock(&dmov_conf[adm].lock);
-+ return 0;
-+}
-+
-+static int msm_dmov_runtime_suspend(struct device *dev)
-+{
-+ dev_dbg(dev, "pm_runtime: suspending...\n");
-+ return 0;
-+}
-+
-+static int msm_dmov_runtime_resume(struct device *dev)
-+{
-+ dev_dbg(dev, "pm_runtime: resuming...\n");
-+ return 0;
-+}
-+
-+static int msm_dmov_runtime_idle(struct device *dev)
-+{
-+ dev_dbg(dev, "pm_runtime: idling...\n");
-+ return 0;
-+}
-+
-+static struct dev_pm_ops msm_dmov_dev_pm_ops = {
-+ .runtime_suspend = msm_dmov_runtime_suspend,
-+ .runtime_resume = msm_dmov_runtime_resume,
-+ .runtime_idle = msm_dmov_runtime_idle,
-+ .suspend = msm_dmov_suspend_late,
-+};
-+
-+static int msm_dmov_init_clocks(struct platform_device *pdev)
-+{
-+ int adm = (pdev->id >= 0) ? pdev->id : 0;
-+ int ret;
-+
-+ dmov_conf[adm].clk = devm_clk_get(&pdev->dev, "core_clk");
-+ if (IS_ERR(dmov_conf[adm].clk)) {
-+ printk(KERN_ERR "%s: Error getting adm_clk\n", __func__);
-+ dmov_conf[adm].clk = NULL;
-+ return -ENOENT;
-+ }
-+
-+ dmov_conf[adm].pclk = devm_clk_get(&pdev->dev, "iface_clk");
-+ if (IS_ERR(dmov_conf[adm].pclk)) {
-+ dmov_conf[adm].pclk = NULL;
-+ /* pclk not present on all SoCs, don't bail on failure */
-+ }
-+
-+ dmov_conf[adm].ebiclk = devm_clk_get(&pdev->dev, "mem_clk");
-+ if (IS_ERR(dmov_conf[adm].ebiclk)) {
-+ dmov_conf[adm].ebiclk = NULL;
-+ /* ebiclk not present on all SoCs, don't bail on failure */
-+ } else {
-+ ret = clk_set_rate(dmov_conf[adm].ebiclk, 27000000);
-+ if (ret)
-+ return -ENOENT;
-+ }
-+
-+ return 0;
-+}
-+
-+static void config_datamover(int adm)
-+{
-+ int i;
-+
-+ /* Reset the ADM */
-+ reset_control_assert(dmov_conf[adm].adm_reset);
-+ reset_control_assert(dmov_conf[adm].c0_reset);
-+ reset_control_assert(dmov_conf[adm].c1_reset);
-+ reset_control_assert(dmov_conf[adm].c2_reset);
-+
-+ reset_control_deassert(dmov_conf[adm].c2_reset);
-+ reset_control_deassert(dmov_conf[adm].c1_reset);
-+ reset_control_deassert(dmov_conf[adm].c0_reset);
-+ reset_control_deassert(dmov_conf[adm].adm_reset);
-+
-+ for (i = 0; i < MSM_DMOV_CHANNEL_COUNT; i++) {
-+ struct msm_dmov_chan_conf *chan_conf =
-+ dmov_conf[adm].chan_conf;
-+ unsigned conf;
-+ /* Only configure scorpion channels */
-+ if (chan_conf[i].sd <= 1) {
-+ conf = readl_relaxed(DMOV_REG(DMOV_CONF(i), adm));
-+ conf |= DMOV_CONF_MPU_DISABLE |
-+ DMOV_CONF_PERM_MPU_CONF |
-+ DMOV_CONF_FLUSH_RSLT_EN |
-+ DMOV_CONF_FORCE_RSLT_EN |
-+ DMOV_CONF_IRQ_EN |
-+ DMOV_CONF_PRIORITY(chan_conf[i].priority);
-+
-+ conf &= ~DMOV_CONF_SD(7);
-+ conf |= DMOV_CONF_SD(chan_conf[i].sd);
-+ writel_relaxed(conf, DMOV_REG(DMOV_CONF(i), adm));
-+ }
-+ }
-+
-+ for (i = 0; i < MSM_DMOV_CRCI_COUNT; i++) {
-+ writel_relaxed(DMOV_CRCI_CTL_RST,
-+ DMOV_REG(DMOV_CRCI_CTL(i), adm));
-+ }
-+
-+ /* NAND CRCI Enable */
-+ writel_relaxed(0, DMOV_REG(DMOV_CRCI_CTL(DMOV_NAND_CRCI_DATA), adm));
-+ writel_relaxed(0, DMOV_REG(DMOV_CRCI_CTL(DMOV_NAND_CRCI_CMD), adm));
-+
-+ /* GSBI5 CRCI Enable */
-+ writel_relaxed(0, DMOV_REG(DMOV_CRCI_CTL(DMOV_SPI_GSBI5_RX_CRCI), adm));
-+ writel_relaxed(0, DMOV_REG(DMOV_CRCI_CTL(DMOV_SPI_GSBI5_TX_CRCI), adm));
-+
-+ writel_relaxed(DMOV_CI_CONF_RANGE_START(0x40) | /* EBI1 */
-+ DMOV_CI_CONF_RANGE_END(0xb0) |
-+ DMOV_CI_CONF_MAX_BURST(0x8),
-+ DMOV_REG(DMOV_CI_CONF(0), adm));
-+
-+ writel_relaxed(DMOV_CI_CONF_RANGE_START(0x2a) | /* IMEM */
-+ DMOV_CI_CONF_RANGE_END(0x2c) |
-+ DMOV_CI_CONF_MAX_BURST(0x8),
-+ DMOV_REG(DMOV_CI_CONF(1), adm));
-+
-+ writel_relaxed(DMOV_CI_CONF_RANGE_START(0x12) | /* CPSS/SPS */
-+ DMOV_CI_CONF_RANGE_END(0x28) |
-+ DMOV_CI_CONF_MAX_BURST(0x8),
-+ DMOV_REG(DMOV_CI_CONF(2), adm));
-+
-+ writel_relaxed(DMOV_HI_GP_CTL_CORE_CLK_LP_EN | /* will disable LP */
-+ DMOV_HI_GP_CTL_LP_CNT(0xf),
-+ DMOV_REG(DMOV_HI_GP_CTL, adm));
-+
-+}
-+
-+static int msm_dmov_probe(struct platform_device *pdev)
-+{
-+
-+ int adm = (pdev->id >= 0) ? pdev->id : 0;
-+ int i;
-+ int ret;
-+ struct resource *irqres =
-+ platform_get_resource(pdev, IORESOURCE_IRQ, 0);
-+ struct resource *mres =
-+ platform_get_resource(pdev, IORESOURCE_MEM, 0);
-+
-+ dmov_conf[adm].sd=0;
-+ dmov_conf[adm].sd_size=0x800;
-+
-+ dmov_conf[adm].irq = irqres->start;
-+
-+ dmov_conf[adm].base = devm_ioremap_resource(&pdev->dev, mres);
-+ if (!dmov_conf[adm].base)
-+ return -ENOMEM;
-+
-+ dmov_conf[adm].cmd_wq = alloc_ordered_workqueue("dmov%d_wq", 0, adm);
-+ if (!dmov_conf[adm].cmd_wq) {
-+ PRINT_ERROR("Couldn't allocate ADM%d workqueue.\n", adm);
-+ return -ENOMEM;
-+ }
-+
-+ /* get resets */
-+ dmov_conf[adm].adm_reset = devm_reset_control_get(&pdev->dev, "adm");
-+ if (IS_ERR(dmov_conf[adm].adm_reset)) {
-+ dev_err(&pdev->dev, "failed to get adm reset\n");
-+ ret = PTR_ERR(dmov_conf[adm].adm_reset);
-+ goto out_wq;
-+ }
-+
-+ dmov_conf[adm].pbus_reset = devm_reset_control_get(&pdev->dev, "pbus");
-+ if (IS_ERR(dmov_conf[adm].pbus_reset)) {
-+ dev_err(&pdev->dev, "failed to get pbus reset\n");
-+ ret = PTR_ERR(dmov_conf[adm].pbus_reset);
-+ goto out_wq;
-+ }
-+
-+ dmov_conf[adm].c0_reset = devm_reset_control_get(&pdev->dev, "c0");
-+ if (IS_ERR(dmov_conf[adm].c0_reset)) {
-+ dev_err(&pdev->dev, "failed to get c0 reset\n");
-+ ret = PTR_ERR(dmov_conf[adm].c0_reset);
-+ goto out_wq;
-+ }
-+
-+ dmov_conf[adm].c1_reset = devm_reset_control_get(&pdev->dev, "c1");
-+ if (IS_ERR(dmov_conf[adm].c1_reset)) {
-+ dev_err(&pdev->dev, "failed to get c1 reset\n");
-+ ret = PTR_ERR(dmov_conf[adm].c1_reset);
-+ goto out_wq;
-+ }
-+
-+ dmov_conf[adm].c2_reset = devm_reset_control_get(&pdev->dev, "c2");
-+ if (IS_ERR(dmov_conf[adm].c2_reset)) {
-+ dev_err(&pdev->dev, "failed to get c2 reset\n");
-+ ret = PTR_ERR(dmov_conf[adm].c2_reset);
-+ goto out_wq;
-+ }
-+
-+ ret = devm_request_threaded_irq(&pdev->dev, dmov_conf[adm].irq, NULL,
-+ msm_dmov_isr, IRQF_ONESHOT, "msmdatamover", NULL);
-+
-+ if (ret) {
-+ PRINT_ERROR("Requesting ADM%d irq %d failed\n", adm,
-+ dmov_conf[adm].irq);
-+ goto out_wq;
-+ }
-+
-+ disable_irq(dmov_conf[adm].irq);
-+ ret = msm_dmov_init_clocks(pdev);
-+ if (ret) {
-+ PRINT_ERROR("Requesting ADM%d clocks failed\n", adm);
-+ goto out_wq;
-+ }
-+ clk_prepare_enable(dmov_conf[adm].clk);
-+ clk_prepare_enable(dmov_conf[adm].pclk);
-+
-+// ret = msm_dmov_clk_on(adm);
-+// if (ret) {
-+// PRINT_ERROR("Enabling ADM%d clocks failed\n", adm);
-+// goto out_wq;
-+// }
-+
-+ config_datamover(adm);
-+ for (i = 0; i < MSM_DMOV_CHANNEL_COUNT; i++) {
-+ INIT_LIST_HEAD(&dmov_conf[adm].staged_commands[i]);
-+ INIT_LIST_HEAD(&dmov_conf[adm].ready_commands[i]);
-+ INIT_LIST_HEAD(&dmov_conf[adm].active_commands[i]);
-+
-+ writel_relaxed(DMOV_RSLT_CONF_IRQ_EN
-+ | DMOV_RSLT_CONF_FORCE_FLUSH_RSLT,
-+ DMOV_REG(DMOV_RSLT_CONF(i), adm));
-+ }
-+ wmb();
-+// msm_dmov_clk_off(adm);
-+ return ret;
-+out_wq:
-+ destroy_workqueue(dmov_conf[adm].cmd_wq);
-+ return ret;
-+}
-+
-+#ifdef CONFIG_OF
-+static const struct of_device_id adm_of_match[] = {
-+ { .compatible = "qcom,adm", },
-+ {},
-+};
-+MODULE_DEVICE_TABLE(of, adm_of_match);
-+#endif
-+
-+static struct platform_driver msm_dmov_driver = {
-+ .probe = msm_dmov_probe,
-+ .driver = {
-+ .name = MODULE_NAME,
-+ .owner = THIS_MODULE,
-+ .of_match_table = adm_of_match,
-+ .pm = &msm_dmov_dev_pm_ops,
-+ },
-+};
-+
-+/* static int __init */
-+static int __init msm_init_datamover(void)
-+{
-+ int ret;
-+ ret = platform_driver_register(&msm_dmov_driver);
-+ if (ret)
-+ return ret;
-+ return 0;
-+}
-+arch_initcall(msm_init_datamover);
---- /dev/null
-+++ b/drivers/mtd/nand/qcom_adm_dma.h
-@@ -0,0 +1,268 @@
-+/* * Copyright (c) 2012 The Linux Foundation. All rights reserved.* */
-+/* linux/include/asm-arm/arch-msm/dma.h
-+ *
-+ * Copyright (C) 2007 Google, Inc.
-+ * Copyright (c) 2008-2012, The Linux Foundation. All rights reserved.
-+ *
-+ * This software is licensed under the terms of the GNU General Public
-+ * License version 2, as published by the Free Software Foundation, and
-+ * may be copied, distributed, and modified under those terms.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ * GNU General Public License for more details.
-+ *
-+ */
-+
-+#ifndef __ASM_ARCH_MSM_DMA_H
-+#define __ASM_ARCH_MSM_DMA_H
-+#include <linux/list.h>
-+
-+struct msm_dmov_errdata {
-+ uint32_t flush[6];
-+};
-+
-+struct msm_dmov_cmd {
-+ struct list_head list;
-+ unsigned int cmdptr;
-+ void (*complete_func)(struct msm_dmov_cmd *cmd,
-+ unsigned int result,
-+ struct msm_dmov_errdata *err);
-+ void (*exec_func)(struct msm_dmov_cmd *cmd);
-+ struct work_struct work;
-+ unsigned id; /* For internal use */
-+ void *user; /* Pointer for caller's reference */
-+ u8 toflush;
-+};
-+
-+struct msm_dmov_pdata {
-+ int sd;
-+ size_t sd_size;
-+};
-+
-+void msm_dmov_enqueue_cmd(unsigned id, struct msm_dmov_cmd *cmd);
-+void msm_dmov_enqueue_cmd_ext(unsigned id, struct msm_dmov_cmd *cmd);
-+void msm_dmov_flush(unsigned int id, int graceful);
-+int msm_dmov_exec_cmd(unsigned id, unsigned int cmdptr);
-+
-+#define DMOV_CRCIS_PER_CONF 10
-+
-+#define DMOV_ADDR(off, ch) ((off) + ((ch) << 2))
-+
-+#define DMOV_CMD_PTR(ch) DMOV_ADDR(0x000, ch)
-+#define DMOV_CMD_LIST (0 << 29) /* does not work */
-+#define DMOV_CMD_PTR_LIST (1 << 29) /* works */
-+#define DMOV_CMD_INPUT_CFG (2 << 29) /* untested */
-+#define DMOV_CMD_OUTPUT_CFG (3 << 29) /* untested */
-+#define DMOV_CMD_ADDR(addr) ((addr) >> 3)
-+
-+#define DMOV_RSLT(ch) DMOV_ADDR(0x040, ch)
-+#define DMOV_RSLT_VALID (1 << 31) /* 0 == host has empties result fifo */
-+#define DMOV_RSLT_ERROR (1 << 3)
-+#define DMOV_RSLT_FLUSH (1 << 2)
-+#define DMOV_RSLT_DONE (1 << 1) /* top pointer done */
-+#define DMOV_RSLT_USER (1 << 0) /* command with FR force result */
-+
-+#define DMOV_FLUSH0(ch) DMOV_ADDR(0x080, ch)
-+#define DMOV_FLUSH1(ch) DMOV_ADDR(0x0C0, ch)
-+#define DMOV_FLUSH2(ch) DMOV_ADDR(0x100, ch)
-+#define DMOV_FLUSH3(ch) DMOV_ADDR(0x140, ch)
-+#define DMOV_FLUSH4(ch) DMOV_ADDR(0x180, ch)
-+#define DMOV_FLUSH5(ch) DMOV_ADDR(0x1C0, ch)
-+#define DMOV_FLUSH_TYPE (1 << 31)
-+
-+#define DMOV_STATUS(ch) DMOV_ADDR(0x200, ch)
-+#define DMOV_STATUS_RSLT_COUNT(n) (((n) >> 29))
-+#define DMOV_STATUS_CMD_COUNT(n) (((n) >> 27) & 3)
-+#define DMOV_STATUS_RSLT_VALID (1 << 1)
-+#define DMOV_STATUS_CMD_PTR_RDY (1 << 0)
-+
-+#define DMOV_CONF(ch) DMOV_ADDR(0x240, ch)
-+#define DMOV_CONF_SD(sd) (((sd & 4) << 11) | ((sd & 3) << 4))
-+#define DMOV_CONF_OTHER_CH_BLK_MASK(m) ((m << 0x10) & 0xffff0000)
-+#define DMOV_CONF_SHADOW_EN (1 << 12)
-+#define DMOV_CONF_MPU_DISABLE (1 << 11)
-+#define DMOV_CONF_PERM_MPU_CONF (1 << 9)
-+#define DMOV_CONF_FLUSH_RSLT_EN (1 << 8)
-+#define DMOV_CONF_IRQ_EN (1 << 6)
-+#define DMOV_CONF_FORCE_RSLT_EN (1 << 7)
-+#define DMOV_CONF_PRIORITY(n) (n << 0)
-+
-+#define DMOV_DBG_ERR(ci) DMOV_ADDR(0x280, ci)
-+
-+#define DMOV_RSLT_CONF(ch) DMOV_ADDR(0x300, ch)
-+#define DMOV_RSLT_CONF_FORCE_TOP_PTR_RSLT (1 << 2)
-+#define DMOV_RSLT_CONF_FORCE_FLUSH_RSLT (1 << 1)
-+#define DMOV_RSLT_CONF_IRQ_EN (1 << 0)
-+
-+#define DMOV_ISR DMOV_ADDR(0x380, 0)
-+
-+#define DMOV_CI_CONF(ci) DMOV_ADDR(0x390, ci)
-+#define DMOV_CI_CONF_RANGE_END(n) ((n) << 24)
-+#define DMOV_CI_CONF_RANGE_START(n) ((n) << 16)
-+#define DMOV_CI_CONF_MAX_BURST(n) ((n) << 0)
-+
-+#define DMOV_CI_DBG_ERR(ci) DMOV_ADDR(0x3B0, ci)
-+
-+#define DMOV_CRCI_CONF0 DMOV_ADDR(0x3D0, 0)
-+#define DMOV_CRCI_CONF0_CRCI9_SD (2 << 0x1b)
-+
-+#define DMOV_CRCI_CONF1 DMOV_ADDR(0x3D4, 0)
-+#define DMOV_CRCI_CONF0_SD(crci, sd) (sd << (crci*3))
-+#define DMOV_CRCI_CONF1_SD(crci, sd) (sd << ((crci-DMOV_CRCIS_PER_CONF)*3))
-+
-+#define DMOV_HI_GP_CTL DMOV_ADDR(0x3D8, 0)
-+#define DMOV_HI_GP_CTL_CORE_CLK_LP_EN (1 << 12)
-+#define DMOV_HI_GP_CTL_LP_CNT(x) (((x) & 0xf) << 8)
-+#define DMOV_HI_GP_CTL_CI3_CLK_LP_EN (1 << 7)
-+#define DMOV_HI_GP_CTL_CI2_CLK_LP_EN (1 << 6)
-+#define DMOV_HI_GP_CTL_CI1_CLK_LP_EN (1 << 5)
-+#define DMOV_HI_GP_CTL_CI0_CLK_LP_EN (1 << 4)
-+
-+#define DMOV_CRCI_CTL(crci) DMOV_ADDR(0x400, crci)
-+#define DMOV_CRCI_CTL_BLK_SZ(n) ((n) << 0)
-+#define DMOV_CRCI_CTL_RST (1 << 17)
-+#define DMOV_CRCI_MUX (1 << 18)
-+
-+/* channel assignments */
-+
-+/*
-+ * Format of CRCI numbers: crci number + (muxsel << 4)
-+ */
-+
-+#define DMOV_GP_CHAN 9
-+
-+#define DMOV_CE_IN_CHAN 0
-+#define DMOV_CE_IN_CRCI 2
-+
-+#define DMOV_CE_OUT_CHAN 1
-+#define DMOV_CE_OUT_CRCI 3
-+
-+#define DMOV_TSIF_CHAN 2
-+#define DMOV_TSIF_CRCI 11
-+
-+#define DMOV_HSUART_GSBI6_TX_CHAN 7
-+#define DMOV_HSUART_GSBI6_TX_CRCI 6
-+
-+#define DMOV_HSUART_GSBI6_RX_CHAN 8
-+#define DMOV_HSUART_GSBI6_RX_CRCI 11
-+
-+#define DMOV_HSUART_GSBI8_TX_CHAN 7
-+#define DMOV_HSUART_GSBI8_TX_CRCI 10
-+
-+#define DMOV_HSUART_GSBI8_RX_CHAN 8
-+#define DMOV_HSUART_GSBI8_RX_CRCI 9
-+
-+#define DMOV_HSUART_GSBI9_TX_CHAN 4
-+#define DMOV_HSUART_GSBI9_TX_CRCI 13
-+
-+#define DMOV_HSUART_GSBI9_RX_CHAN 3
-+#define DMOV_HSUART_GSBI9_RX_CRCI 12
-+
-+#define DMOV_NAND_CHAN 3
-+#define DMOV_NAND_CRCI_CMD 15
-+#define DMOV_NAND_CRCI_DATA 3
-+
-+#define DMOV_SPI_GSBI5_RX_CRCI 9
-+#define DMOV_SPI_GSBI5_TX_CRCI 10
-+#define DMOV_SPI_GSBI5_RX_CHAN 6
-+#define DMOV_SPI_GSBI5_TX_CHAN 5
-+
-+/* channels for APQ8064 */
-+#define DMOV8064_CE_IN_CHAN 0
-+#define DMOV8064_CE_IN_CRCI 14
-+
-+#define DMOV8064_CE_OUT_CHAN 1
-+#define DMOV8064_CE_OUT_CRCI 15
-+
-+#define DMOV8064_TSIF_CHAN 2
-+#define DMOV8064_TSIF_CRCI 1
-+
-+/* channels for APQ8064 SGLTE*/
-+#define DMOV_APQ8064_HSUART_GSBI4_TX_CHAN 11
-+#define DMOV_APQ8064_HSUART_GSBI4_TX_CRCI 8
-+
-+#define DMOV_APQ8064_HSUART_GSBI4_RX_CHAN 10
-+#define DMOV_APQ8064_HSUART_GSBI4_RX_CRCI 7
-+
-+/* channels for MPQ8064 */
-+#define DMOV_MPQ8064_HSUART_GSBI6_TX_CHAN 7
-+#define DMOV_MPQ8064_HSUART_GSBI6_TX_CRCI 6
-+
-+#define DMOV_MPQ8064_HSUART_GSBI6_RX_CHAN 6
-+#define DMOV_MPQ8064_HSUART_GSBI6_RX_CRCI 11
-+
-+#define DMOV_IPQ806X_HSUART_GSBI6_TX_CHAN DMOV_MPQ8064_HSUART_GSBI6_TX_CHAN
-+#define DMOV_IPQ806X_HSUART_GSBI6_TX_CRCI DMOV_MPQ8064_HSUART_GSBI6_TX_CRCI
-+
-+#define DMOV_IPQ806X_HSUART_GSBI6_RX_CHAN DMOV_MPQ8064_HSUART_GSBI6_RX_CHAN
-+#define DMOV_IPQ806X_HSUART_GSBI6_RX_CRCI DMOV_MPQ8064_HSUART_GSBI6_RX_CRCI
-+
-+/* no client rate control ifc (eg, ram) */
-+#define DMOV_NONE_CRCI 0
-+
-+
-+/* If the CMD_PTR register has CMD_PTR_LIST selected, the data mover
-+ * is going to walk a list of 32bit pointers as described below. Each
-+ * pointer points to a *array* of dmov_s, etc structs. The last pointer
-+ * in the list is marked with CMD_PTR_LP. The last struct in each array
-+ * is marked with CMD_LC (see below).
-+ */
-+#define CMD_PTR_ADDR(addr) ((addr) >> 3)
-+#define CMD_PTR_LP (1 << 31) /* last pointer */
-+#define CMD_PTR_PT (3 << 29) /* ? */
-+
-+/* Single Item Mode */
-+typedef struct {
-+ unsigned cmd;
-+ unsigned src;
-+ unsigned dst;
-+ unsigned len;
-+} dmov_s;
-+
-+/* Scatter/Gather Mode */
-+typedef struct {
-+ unsigned cmd;
-+ unsigned src_dscr;
-+ unsigned dst_dscr;
-+ unsigned _reserved;
-+} dmov_sg;
-+
-+/* Box mode */
-+typedef struct {
-+ uint32_t cmd;
-+ uint32_t src_row_addr;
-+ uint32_t dst_row_addr;
-+ uint32_t src_dst_len;
-+ uint32_t num_rows;
-+ uint32_t row_offset;
-+} dmov_box;
-+
-+/* bits for the cmd field of the above structures */
-+
-+#define CMD_LC (1 << 31) /* last command */
-+#define CMD_FR (1 << 22) /* force result -- does not work? */
-+#define CMD_OCU (1 << 21) /* other channel unblock */
-+#define CMD_OCB (1 << 20) /* other channel block */
-+#define CMD_TCB (1 << 19) /* ? */
-+#define CMD_DAH (1 << 18) /* destination address hold -- does not work?*/
-+#define CMD_SAH (1 << 17) /* source address hold -- does not work? */
-+
-+#define CMD_MODE_SINGLE (0 << 0) /* dmov_s structure used */
-+#define CMD_MODE_SG (1 << 0) /* untested */
-+#define CMD_MODE_IND_SG (2 << 0) /* untested */
-+#define CMD_MODE_BOX (3 << 0) /* untested */
-+
-+#define CMD_DST_SWAP_BYTES (1 << 14) /* exchange each byte n with byte n+1 */
-+#define CMD_DST_SWAP_SHORTS (1 << 15) /* exchange each short n with short n+1 */
-+#define CMD_DST_SWAP_WORDS (1 << 16) /* exchange each word n with word n+1 */
-+
-+#define CMD_SRC_SWAP_BYTES (1 << 11) /* exchange each byte n with byte n+1 */
-+#define CMD_SRC_SWAP_SHORTS (1 << 12) /* exchange each short n with short n+1 */
-+#define CMD_SRC_SWAP_WORDS (1 << 13) /* exchange each word n with word n+1 */
-+
-+#define CMD_DST_CRCI(n) (((n) & 15) << 7)
-+#define CMD_SRC_CRCI(n) (((n) & 15) << 3)
-+
-+#endif
---- /dev/null
-+++ b/drivers/mtd/nand/qcom_nand.c
-@@ -0,0 +1,7455 @@
-+/*
-+ * Copyright (C) 2007 Google, Inc.
-+ * Copyright (c) 2008-2012, The Linux Foundation. All rights reserved.
-+ *
-+ * This software is licensed under the terms of the GNU General Public
-+ * License version 2, as published by the Free Software Foundation, and
-+ * may be copied, distributed, and modified under those terms.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ * GNU General Public License for more details.
-+ *
-+ */
-+
-+#include <linux/slab.h>
-+#include <linux/kernel.h>
-+#include <linux/module.h>
-+#include <linux/mtd/mtd.h>
-+#include <linux/mtd/nand.h>
-+#include <linux/mtd/partitions.h>
-+#include <linux/platform_device.h>
-+#include <linux/sched.h>
-+#include <linux/dma-mapping.h>
-+#include <linux/io.h>
-+#include <linux/crc16.h>
-+#include <linux/bitrev.h>
-+#include <linux/clk.h>
-+
-+#include <asm/dma.h>
-+#include <asm/mach/flash.h>
-+
-+#include "qcom_adm_dma.h"
-+
-+#include "qcom_nand.h"
-+unsigned long msm_nand_phys = 0;
-+unsigned long msm_nandc01_phys = 0;
-+unsigned long msm_nandc10_phys = 0;
-+unsigned long msm_nandc11_phys = 0;
-+unsigned long ebi2_register_base = 0;
-+static uint32_t dual_nand_ctlr_present;
-+static uint32_t interleave_enable;
-+static uint32_t enable_bch_ecc;
-+static uint32_t boot_layout;
-+
-+
-+#define MSM_NAND_DMA_BUFFER_SIZE SZ_8K
-+#define MSM_NAND_DMA_BUFFER_SLOTS \
-+ (MSM_NAND_DMA_BUFFER_SIZE / (sizeof(((atomic_t *)0)->counter) * 8))
-+
-+#define MSM_NAND_CFG0_RAW_ONFI_IDENTIFIER 0x88000800
-+#define MSM_NAND_CFG0_RAW_ONFI_PARAM_INFO 0x88040000
-+#define MSM_NAND_CFG1_RAW_ONFI_IDENTIFIER 0x0005045d
-+#define MSM_NAND_CFG1_RAW_ONFI_PARAM_INFO 0x0005045d
-+
-+#define ONFI_IDENTIFIER_LENGTH 0x0004
-+#define ONFI_PARAM_INFO_LENGTH 0x0200
-+#define ONFI_PARAM_PAGE_LENGTH 0x0100
-+
-+#define ONFI_PARAMETER_PAGE_SIGNATURE 0x49464E4F
-+
-+#define FLASH_READ_ONFI_IDENTIFIER_COMMAND 0x90
-+#define FLASH_READ_ONFI_IDENTIFIER_ADDRESS 0x20
-+#define FLASH_READ_ONFI_PARAMETERS_COMMAND 0xEC
-+#define FLASH_READ_ONFI_PARAMETERS_ADDRESS 0x00
-+
-+#define UD_SIZE_BYTES_MASK (0x3FF << 9)
-+#define SPARE_SIZE_BYTES_MASK (0xF << 23)
-+#define ECC_NUM_DATA_BYTES_MASK (0x3FF << 16)
-+
-+#define VERBOSE 0
-+
-+struct msm_nand_chip {
-+ struct device *dev;
-+ wait_queue_head_t wait_queue;
-+ atomic_t dma_buffer_busy;
-+ unsigned dma_channel;
-+ uint8_t *dma_buffer;
-+ dma_addr_t dma_addr;
-+ unsigned CFG0, CFG1, CFG0_RAW, CFG1_RAW;
-+ uint32_t ecc_buf_cfg;
-+ uint32_t ecc_bch_cfg;
-+ uint32_t ecc_parity_bytes;
-+ unsigned cw_size;
-+ unsigned int uncorrectable_bit_mask;
-+ unsigned int num_err_mask;
-+};
-+
-+#define CFG1_WIDE_FLASH (1U << 1)
-+
-+/* TODO: move datamover code out */
-+
-+#define SRC_CRCI_NAND_CMD CMD_SRC_CRCI(DMOV_NAND_CRCI_CMD)
-+#define DST_CRCI_NAND_CMD CMD_DST_CRCI(DMOV_NAND_CRCI_CMD)
-+#define SRC_CRCI_NAND_DATA CMD_SRC_CRCI(DMOV_NAND_CRCI_DATA)
-+#define DST_CRCI_NAND_DATA CMD_DST_CRCI(DMOV_NAND_CRCI_DATA)
-+
-+#define msm_virt_to_dma(chip, vaddr) \
-+ ((chip)->dma_addr + \
-+ ((uint8_t *)(vaddr) - (chip)->dma_buffer))
-+
-+/**
-+ * msm_nand_oob_64 - oob info for 2KB page
-+ */
-+static struct nand_ecclayout msm_nand_oob_64 = {
-+ .eccbytes = 40,
-+ .eccpos = {
-+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
-+ 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
-+ 20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
-+ 46, 47, 48, 49, 50, 51, 52, 53, 54, 55,
-+ },
-+ .oobavail = 16,
-+ .oobfree = {
-+ {30, 16},
-+ }
-+};
-+
-+/**
-+ * msm_nand_oob_128 - oob info for 4KB page
-+ */
-+static struct nand_ecclayout msm_nand_oob_128 = {
-+ .eccbytes = 80,
-+ .eccpos = {
-+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
-+ 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
-+ 20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
-+ 30, 31, 32, 33, 34, 35, 36, 37, 38, 39,
-+ 40, 41, 42, 43, 44, 45, 46, 47, 48, 49,
-+ 50, 51, 52, 53, 54, 55, 56, 57, 58, 59,
-+ 60, 61, 62, 63, 64, 65, 66, 67, 68, 69,
-+ 102, 103, 104, 105, 106, 107, 108, 109, 110, 111,
-+ },
-+ .oobavail = 32,
-+ .oobfree = {
-+ {70, 32},
-+ }
-+};
-+
-+/**
-+ * msm_nand_oob_224 - oob info for 4KB page 8Bit interface
-+ */
-+static struct nand_ecclayout msm_nand_oob_224_x8 = {
-+ .eccbytes = 104,
-+ .eccpos = {
-+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
-+ 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
-+ 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38,
-+ 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51,
-+ 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64,
-+ 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77,
-+ 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90,
-+ 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135,
-+ },
-+ .oobavail = 32,
-+ .oobfree = {
-+ {91, 32},
-+ }
-+};
-+
-+/**
-+ * msm_nand_oob_224 - oob info for 4KB page 16Bit interface
-+ */
-+static struct nand_ecclayout msm_nand_oob_224_x16 = {
-+ .eccbytes = 112,
-+ .eccpos = {
-+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,
-+ 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27,
-+ 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41,
-+ 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55,
-+ 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69,
-+ 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83,
-+ 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97,
-+ 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143,
-+ },
-+ .oobavail = 32,
-+ .oobfree = {
-+ {98, 32},
-+ }
-+};
-+
-+/**
-+ * msm_nand_oob_256 - oob info for 8KB page
-+ */
-+static struct nand_ecclayout msm_nand_oob_256 = {
-+ .eccbytes = 160,
-+ .eccpos = {
-+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
-+ 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
-+ 20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
-+ 30, 31, 32, 33, 34, 35, 36, 37, 38, 39,
-+ 40, 41, 42, 43, 44, 45, 46, 47, 48, 49,
-+ 50, 51, 52, 53, 54, 55, 56, 57, 58, 59,
-+ 60, 61, 62, 63, 64, 65, 66, 67, 68, 69,
-+ 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
-+ 80, 81, 82, 83, 84, 85, 86, 87, 88, 89,
-+ 90, 91, 92, 93, 94, 96, 97, 98 , 99, 100,
-+ 101, 102, 103, 104, 105, 106, 107, 108, 109, 110,
-+ 111, 112, 113, 114, 115, 116, 117, 118, 119, 120,
-+ 121, 122, 123, 124, 125, 126, 127, 128, 129, 130,
-+ 131, 132, 133, 134, 135, 136, 137, 138, 139, 140,
-+ 141, 142, 143, 144, 145, 146, 147, 148, 149, 150,
-+ 215, 216, 217, 218, 219, 220, 221, 222, 223, 224,
-+ },
-+ .oobavail = 64,
-+ .oobfree = {
-+ {151, 64},
-+ }
-+};
-+
-+/**
-+ * msm_onenand_oob_64 - oob info for large (2KB) page
-+ */
-+static struct nand_ecclayout msm_onenand_oob_64 = {
-+ .eccbytes = 20,
-+ .eccpos = {
-+ 8, 9, 10, 11, 12,
-+ 24, 25, 26, 27, 28,
-+ 40, 41, 42, 43, 44,
-+ 56, 57, 58, 59, 60,
-+ },
-+ .oobavail = 20,
-+ .oobfree = {
-+ {2, 3}, {14, 2}, {18, 3}, {30, 2},
-+ {34, 3}, {46, 2}, {50, 3}, {62, 2}
-+ }
-+};
-+
-+static void *msm_nand_get_dma_buffer(struct msm_nand_chip *chip, size_t size)
-+{
-+ unsigned int bitmask, free_bitmask, old_bitmask;
-+ unsigned int need_mask, current_need_mask;
-+ int free_index;
-+
-+ need_mask = (1UL << DIV_ROUND_UP(size, MSM_NAND_DMA_BUFFER_SLOTS)) - 1;
-+ bitmask = atomic_read(&chip->dma_buffer_busy);
-+ free_bitmask = ~bitmask;
-+ while (free_bitmask) {
-+ free_index = __ffs(free_bitmask);
-+ current_need_mask = need_mask << free_index;
-+
-+ if (size + free_index * MSM_NAND_DMA_BUFFER_SLOTS >=
-+ MSM_NAND_DMA_BUFFER_SIZE)
-+ return NULL;
-+
-+ if ((bitmask & current_need_mask) == 0) {
-+ old_bitmask =
-+ atomic_cmpxchg(&chip->dma_buffer_busy,
-+ bitmask,
-+ bitmask | current_need_mask);
-+ if (old_bitmask == bitmask)
-+ return chip->dma_buffer +
-+ free_index * MSM_NAND_DMA_BUFFER_SLOTS;
-+ free_bitmask = 0; /* force return */
-+ }
-+ /* current free range was too small, clear all free bits */
-+ /* below the top busy bit within current_need_mask */
-+ free_bitmask &=
-+ ~(~0U >> (32 - fls(bitmask & current_need_mask)));
-+ }
-+
-+ return NULL;
-+}
-+
-+static void msm_nand_release_dma_buffer(struct msm_nand_chip *chip,
-+ void *buffer, size_t size)
-+{
-+ int index;
-+ unsigned int used_mask;
-+
-+ used_mask = (1UL << DIV_ROUND_UP(size, MSM_NAND_DMA_BUFFER_SLOTS)) - 1;
-+ index = ((uint8_t *)buffer - chip->dma_buffer) /
-+ MSM_NAND_DMA_BUFFER_SLOTS;
-+ atomic_sub(used_mask << index, &chip->dma_buffer_busy);
-+
-+ wake_up(&chip->wait_queue);
-+}
-+
-+
-+unsigned flash_rd_reg(struct msm_nand_chip *chip, unsigned addr)
-+{
-+ struct {
-+ dmov_s cmd;
-+ unsigned cmdptr;
-+ unsigned data;
-+ } *dma_buffer;
-+ unsigned rv;
-+
-+ wait_event(chip->wait_queue,
-+ (dma_buffer = msm_nand_get_dma_buffer(
-+ chip, sizeof(*dma_buffer))));
-+
-+ dma_buffer->cmd.cmd = CMD_LC | CMD_OCB | CMD_OCU;
-+ dma_buffer->cmd.src = addr;
-+ dma_buffer->cmd.dst = msm_virt_to_dma(chip, &dma_buffer->data);
-+ dma_buffer->cmd.len = 4;
-+
-+ dma_buffer->cmdptr =
-+ (msm_virt_to_dma(chip, &dma_buffer->cmd) >> 3) | CMD_PTR_LP;
-+ dma_buffer->data = 0xeeeeeeee;
-+
-+ mb();
-+ msm_dmov_exec_cmd(
-+ chip->dma_channel, DMOV_CMD_PTR_LIST |
-+ DMOV_CMD_ADDR(msm_virt_to_dma(chip, &dma_buffer->cmdptr)));
-+ mb();
-+
-+ rv = dma_buffer->data;
-+
-+ msm_nand_release_dma_buffer(chip, dma_buffer, sizeof(*dma_buffer));
-+
-+ return rv;
-+}
-+
-+void flash_wr_reg(struct msm_nand_chip *chip, unsigned addr, unsigned val)
-+{
-+ struct {
-+ dmov_s cmd;
-+ unsigned cmdptr;
-+ unsigned data;
-+ } *dma_buffer;
-+
-+ wait_event(chip->wait_queue,
-+ (dma_buffer = msm_nand_get_dma_buffer(
-+ chip, sizeof(*dma_buffer))));
-+
-+ dma_buffer->cmd.cmd = CMD_LC | CMD_OCB | CMD_OCU;
-+ dma_buffer->cmd.src = msm_virt_to_dma(chip, &dma_buffer->data);
-+ dma_buffer->cmd.dst = addr;
-+ dma_buffer->cmd.len = 4;
-+
-+ dma_buffer->cmdptr =
-+ (msm_virt_to_dma(chip, &dma_buffer->cmd) >> 3) | CMD_PTR_LP;
-+ dma_buffer->data = val;
-+
-+ mb();
-+ msm_dmov_exec_cmd(
-+ chip->dma_channel, DMOV_CMD_PTR_LIST |
-+ DMOV_CMD_ADDR(msm_virt_to_dma(chip, &dma_buffer->cmdptr)));
-+ mb();
-+
-+ msm_nand_release_dma_buffer(chip, dma_buffer, sizeof(*dma_buffer));
-+}
-+
-+/*
-+ * Allocates a bounce buffer, and stores the buffer address in
-+ * variable pointed to by bounce_buf. bounce_buf should point to a
-+ * stack variable, to avoid SMP issues.
-+ */
-+static int msm_nand_alloc_bounce(void *addr, size_t size,
-+ enum dma_data_direction dir,
-+ uint8_t **bounce_buf)
-+{
-+ if (bounce_buf == NULL) {
-+ printk(KERN_ERR "not allocating bounce buffer\n");
-+ return -EINVAL;
-+ }
-+
-+ *bounce_buf = kmalloc(size, GFP_KERNEL | GFP_NOFS | GFP_DMA);
-+ if (*bounce_buf == NULL) {
-+ printk(KERN_ERR "error alloc bounce buffer %zu\n", size);
-+ return -ENOMEM;
-+ }
-+
-+ if (dir == DMA_TO_DEVICE || dir == DMA_BIDIRECTIONAL)
-+ memcpy(*bounce_buf, addr, size);
-+
-+ return 0;
-+}
-+
-+/*
-+ * Maps the user buffer for DMA. If the buffer is vmalloced and the
-+ * buffer crosses a page boundary, then we kmalloc a bounce buffer and
-+ * copy the data into it. The bounce buffer is stored in the variable
-+ * pointed to by bounce_buf, for freeing up later on. The bounce_buf
-+ * should point to a stack variable, to avoid SMP issues.
-+ */
-+static dma_addr_t
-+msm_nand_dma_map(struct device *dev, void *addr, size_t size,
-+ enum dma_data_direction dir, uint8_t **bounce_buf)
-+{
-+ int ret;
-+ struct page *page;
-+ unsigned long offset = (unsigned long)addr & ~PAGE_MASK;
-+
-+ if (virt_addr_valid(addr)) {
-+ page = virt_to_page(addr);
-+ } else {
-+ if (size + offset > PAGE_SIZE) {
-+ ret = msm_nand_alloc_bounce(addr, size, dir, bounce_buf);
-+ if (ret < 0)
-+ return DMA_ERROR_CODE;
-+
-+ offset = (unsigned long)*bounce_buf & ~PAGE_MASK;
-+ page = virt_to_page(*bounce_buf);
-+ } else {
-+ page = vmalloc_to_page(addr);
-+ }
-+ }
-+
-+ return dma_map_page(dev, page, offset, size, dir);
-+}
-+
-+static void msm_nand_dma_unmap(struct device *dev, dma_addr_t addr, size_t size,
-+ enum dma_data_direction dir,
-+ void *orig_buf, void *bounce_buf)
-+{
-+ dma_unmap_page(dev, addr, size, dir);
-+
-+ if (bounce_buf != NULL) {
-+ if (dir == DMA_FROM_DEVICE || dir == DMA_BIDIRECTIONAL)
-+ memcpy(orig_buf, bounce_buf, size);
-+
-+ kfree(bounce_buf);
-+ }
-+}
-+
-+uint32_t flash_read_id(struct msm_nand_chip *chip)
-+{
-+ struct {
-+ dmov_s cmd[9];
-+ unsigned cmdptr;
-+ unsigned data[7];
-+ } *dma_buffer;
-+ uint32_t rv;
-+ dmov_s *cmd;
-+
-+ wait_event(chip->wait_queue, (dma_buffer = msm_nand_get_dma_buffer
-+ (chip, sizeof(*dma_buffer))));
-+
-+ dma_buffer->data[0] = 0 | 4;
-+ dma_buffer->data[1] = MSM_NAND_CMD_FETCH_ID;
-+ dma_buffer->data[2] = 1;
-+ dma_buffer->data[3] = 0xeeeeeeee;
-+ dma_buffer->data[4] = 0xeeeeeeee;
-+ dma_buffer->data[5] = flash_rd_reg(chip, MSM_NAND_SFLASHC_BURST_CFG);
-+ dma_buffer->data[6] = 0x00000000;
-+ BUILD_BUG_ON(6 != ARRAY_SIZE(dma_buffer->data) - 1);
-+
-+ cmd = dma_buffer->cmd;
-+
-+ cmd->cmd = 0 | CMD_OCB;
-+ cmd->src = msm_virt_to_dma(chip, &dma_buffer->data[6]);
-+ cmd->dst = MSM_NAND_SFLASHC_BURST_CFG;
-+ cmd->len = 4;
-+ cmd++;
-+
-+ cmd->cmd = 0;
-+ cmd->src = msm_virt_to_dma(chip, &dma_buffer->data[6]);
-+ cmd->dst = MSM_NAND_ADDR0;
-+ cmd->len = 4;
-+ cmd++;
-+
-+ cmd->cmd = 0;
-+ cmd->src = msm_virt_to_dma(chip, &dma_buffer->data[6]);
-+ cmd->dst = MSM_NAND_ADDR1;
-+ cmd->len = 4;
-+ cmd++;
-+
-+ cmd->cmd = 0;
-+ cmd->src = msm_virt_to_dma(chip, &dma_buffer->data[0]);
-+ cmd->dst = MSM_NAND_FLASH_CHIP_SELECT;
-+ cmd->len = 4;
-+ cmd++;
-+
-+ cmd->cmd = DST_CRCI_NAND_CMD;
-+ cmd->src = msm_virt_to_dma(chip, &dma_buffer->data[1]);
-+ cmd->dst = MSM_NAND_FLASH_CMD;
-+ cmd->len = 4;
-+ cmd++;
-+
-+ cmd->cmd = 0;
-+ cmd->src = msm_virt_to_dma(chip, &dma_buffer->data[2]);
-+ cmd->dst = MSM_NAND_EXEC_CMD;
-+ cmd->len = 4;
-+ cmd++;
-+
-+ cmd->cmd = SRC_CRCI_NAND_DATA;
-+ cmd->src = MSM_NAND_FLASH_STATUS;
-+ cmd->dst = msm_virt_to_dma(chip, &dma_buffer->data[3]);
-+ cmd->len = 4;
-+ cmd++;
-+
-+ cmd->cmd = 0;
-+ cmd->src = MSM_NAND_READ_ID;
-+ cmd->dst = msm_virt_to_dma(chip, &dma_buffer->data[4]);
-+ cmd->len = 4;
-+ cmd++;
-+
-+ cmd->cmd = CMD_OCU | CMD_LC;
-+ cmd->src = msm_virt_to_dma(chip, &dma_buffer->data[5]);
-+ cmd->dst = MSM_NAND_SFLASHC_BURST_CFG;
-+ cmd->len = 4;
-+ cmd++;
-+
-+ BUILD_BUG_ON(8 != ARRAY_SIZE(dma_buffer->cmd) - 1);
-+
-+ dma_buffer->cmdptr = (msm_virt_to_dma(chip, dma_buffer->cmd) >> 3
-+ ) | CMD_PTR_LP;
-+
-+ mb();
-+ msm_dmov_exec_cmd(chip->dma_channel, DMOV_CMD_PTR_LIST |
-+ DMOV_CMD_ADDR(msm_virt_to_dma(chip, &dma_buffer->cmdptr)));
-+ mb();
-+
-+ pr_info("status: %x\n", dma_buffer->data[3]);
-+ pr_info("nandid: %x maker %02x device %02x\n",
-+ dma_buffer->data[4], dma_buffer->data[4] & 0xff,
-+ (dma_buffer->data[4] >> 8) & 0xff);
-+ rv = dma_buffer->data[4];
-+ msm_nand_release_dma_buffer(chip, dma_buffer, sizeof(*dma_buffer));
-+ return rv;
-+}
-+
-+struct flash_identification {
-+ uint32_t flash_id;
-+ uint32_t density;
-+ uint32_t widebus;
-+ uint32_t pagesize;
-+ uint32_t blksize;
-+ uint32_t oobsize;
-+ uint32_t ecc_correctability;
-+} supported_flash;
-+
-+uint16_t flash_onfi_crc_check(uint8_t *buffer, uint16_t count)
-+{
-+ int i;
-+ uint16_t result;
-+
-+ for (i = 0; i < count; i++)
-+ buffer[i] = bitrev8(buffer[i]);
-+
-+ result = bitrev16(crc16(bitrev16(0x4f4e), buffer, count));
-+
-+ for (i = 0; i < count; i++)
-+ buffer[i] = bitrev8(buffer[i]);
-+
-+ return result;
-+}
-+
-+static void flash_reset(struct msm_nand_chip *chip)
-+{
-+ struct {
-+ dmov_s cmd[6];
-+ unsigned cmdptr;
-+ struct {
-+ uint32_t cmd;
-+ uint32_t exec;
-+ uint32_t flash_status;
-+ uint32_t sflash_bcfg_orig;
-+ uint32_t sflash_bcfg_mod;
-+ uint32_t chip_select;
-+ } data;
-+ } *dma_buffer;
-+ dmov_s *cmd;
-+ dma_addr_t dma_cmd;
-+ dma_addr_t dma_cmdptr;
-+
-+ wait_event(chip->wait_queue, (dma_buffer = msm_nand_get_dma_buffer
-+ (chip, sizeof(*dma_buffer))));
-+
-+ dma_buffer->data.sflash_bcfg_orig
-+ = flash_rd_reg(chip, MSM_NAND_SFLASHC_BURST_CFG);
-+ dma_buffer->data.sflash_bcfg_mod = 0x00000000;
-+ dma_buffer->data.chip_select = 4;
-+ dma_buffer->data.cmd = MSM_NAND_CMD_RESET;
-+ dma_buffer->data.exec = 1;
-+ dma_buffer->data.flash_status = 0xeeeeeeee;
-+
-+ cmd = dma_buffer->cmd;
-+
-+ /* Put the Nand ctlr in Async mode and disable SFlash ctlr */
-+ cmd->cmd = 0;
-+ cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.sflash_bcfg_mod);
-+ cmd->dst = MSM_NAND_SFLASHC_BURST_CFG;
-+ cmd->len = 4;
-+ cmd++;
-+
-+ cmd->cmd = 0;
-+ cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.chip_select);
-+ cmd->dst = MSM_NAND_FLASH_CHIP_SELECT;
-+ cmd->len = 4;
-+ cmd++;
-+
-+ /* Block on cmd ready, & write Reset command */
-+ cmd->cmd = DST_CRCI_NAND_CMD;
-+ cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.cmd);
-+ cmd->dst = MSM_NAND_FLASH_CMD;
-+ cmd->len = 4;
-+ cmd++;
-+
-+ cmd->cmd = 0;
-+ cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.exec);
-+ cmd->dst = MSM_NAND_EXEC_CMD;
-+ cmd->len = 4;
-+ cmd++;
-+
-+ cmd->cmd = SRC_CRCI_NAND_DATA;
-+ cmd->src = MSM_NAND_FLASH_STATUS;
-+ cmd->dst = msm_virt_to_dma(chip, &dma_buffer->data.flash_status);
-+ cmd->len = 4;
-+ cmd++;
-+
-+ /* Restore the SFLASH_BURST_CONFIG register */
-+ cmd->cmd = 0;
-+ cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.sflash_bcfg_orig);
-+ cmd->dst = MSM_NAND_SFLASHC_BURST_CFG;
-+ cmd->len = 4;
-+ cmd++;
-+
-+ BUILD_BUG_ON(6 != ARRAY_SIZE(dma_buffer->cmd));
-+
-+ dma_buffer->cmd[0].cmd |= CMD_OCB;
-+ cmd[-1].cmd |= CMD_OCU | CMD_LC;
-+
-+ dma_cmd = msm_virt_to_dma(chip, dma_buffer->cmd);
-+ dma_buffer->cmdptr = (dma_cmd >> 3) | CMD_PTR_LP;
-+
-+ mb();
-+ dma_cmdptr = msm_virt_to_dma(chip, &dma_buffer->cmdptr);
-+ msm_dmov_exec_cmd(chip->dma_channel,
-+ DMOV_CMD_PTR_LIST | DMOV_CMD_ADDR(dma_cmdptr));
-+ mb();
-+
-+ msm_nand_release_dma_buffer(chip, dma_buffer, sizeof(*dma_buffer));
-+}
-+
-+uint32_t flash_onfi_probe(struct msm_nand_chip *chip)
-+{
-+
-+
-+ struct onfi_param_page {
-+ uint32_t parameter_page_signature;
-+ uint16_t revision_number;
-+ uint16_t features_supported;
-+ uint16_t optional_commands_supported;
-+ uint8_t reserved0[22];
-+ uint8_t device_manufacturer[12];
-+ uint8_t device_model[20];
-+ uint8_t jedec_manufacturer_id;
-+ uint16_t date_code;
-+ uint8_t reserved1[13];
-+ uint32_t number_of_data_bytes_per_page;
-+ uint16_t number_of_spare_bytes_per_page;
-+ uint32_t number_of_data_bytes_per_partial_page;
-+ uint16_t number_of_spare_bytes_per_partial_page;
-+ uint32_t number_of_pages_per_block;
-+ uint32_t number_of_blocks_per_logical_unit;
-+ uint8_t number_of_logical_units;
-+ uint8_t number_of_address_cycles;
-+ uint8_t number_of_bits_per_cell;
-+ uint16_t maximum_bad_blocks_per_logical_unit;
-+ uint16_t block_endurance;
-+ uint8_t guaranteed_valid_begin_blocks;
-+ uint16_t guaranteed_valid_begin_blocks_endurance;
-+ uint8_t number_of_programs_per_page;
-+ uint8_t partial_program_attributes;
-+ uint8_t number_of_bits_ecc_correctability;
-+ uint8_t number_of_interleaved_address_bits;
-+ uint8_t interleaved_operation_attributes;
-+ uint8_t reserved2[13];
-+ uint8_t io_pin_capacitance;
-+ uint16_t timing_mode_support;
-+ uint16_t program_cache_timing_mode_support;
-+ uint16_t maximum_page_programming_time;
-+ uint16_t maximum_block_erase_time;
-+ uint16_t maximum_page_read_time;
-+ uint16_t maximum_change_column_setup_time;
-+ uint8_t reserved3[23];
-+ uint16_t vendor_specific_revision_number;
-+ uint8_t vendor_specific[88];
-+ uint16_t integrity_crc;
-+
-+ } __attribute__((__packed__));
-+
-+ struct onfi_param_page *onfi_param_page_ptr;
-+ uint8_t *onfi_identifier_buf = NULL;
-+ uint8_t *onfi_param_info_buf = NULL;
-+
-+ struct {
-+ dmov_s cmd[12];
-+ unsigned cmdptr;
-+ struct {
-+ uint32_t cmd;
-+ uint32_t addr0;
-+ uint32_t addr1;
-+ uint32_t cfg0;
-+ uint32_t cfg1;
-+ uint32_t exec;
-+ uint32_t flash_status;
-+ uint32_t devcmd1_orig;
-+ uint32_t devcmdvld_orig;
-+ uint32_t devcmd1_mod;
-+ uint32_t devcmdvld_mod;
-+ uint32_t sflash_bcfg_orig;
-+ uint32_t sflash_bcfg_mod;
-+ uint32_t chip_select;
-+ } data;
-+ } *dma_buffer;
-+ dmov_s *cmd;
-+
-+ unsigned page_address = 0;
-+ int err = 0;
-+ dma_addr_t dma_addr_param_info = 0;
-+ dma_addr_t dma_addr_identifier = 0;
-+ unsigned cmd_set_count = 2;
-+ unsigned crc_chk_count = 0;
-+
-+ /*if (msm_nand_data.nr_parts) {
-+ page_address = ((msm_nand_data.parts[0]).offset << 6);
-+ } else {
-+ pr_err("flash_onfi_probe: "
-+ "No partition info available\n");
-+ err = -EIO;
-+ return err;
-+ }*/
-+
-+ wait_event(chip->wait_queue, (onfi_identifier_buf =
-+ msm_nand_get_dma_buffer(chip, ONFI_IDENTIFIER_LENGTH)));
-+ dma_addr_identifier = msm_virt_to_dma(chip, onfi_identifier_buf);
-+
-+ wait_event(chip->wait_queue, (onfi_param_info_buf =
-+ msm_nand_get_dma_buffer(chip, ONFI_PARAM_INFO_LENGTH)));
-+ dma_addr_param_info = msm_virt_to_dma(chip, onfi_param_info_buf);
-+
-+ wait_event(chip->wait_queue, (dma_buffer = msm_nand_get_dma_buffer
-+ (chip, sizeof(*dma_buffer))));
-+
-+ dma_buffer->data.sflash_bcfg_orig = flash_rd_reg
-+ (chip, MSM_NAND_SFLASHC_BURST_CFG);
-+ dma_buffer->data.devcmd1_orig = flash_rd_reg(chip, MSM_NAND_DEV_CMD1);
-+ dma_buffer->data.devcmdvld_orig = flash_rd_reg(chip,
-+ MSM_NAND_DEV_CMD_VLD);
-+ dma_buffer->data.chip_select = 4;
-+
-+ while (cmd_set_count-- > 0) {
-+ cmd = dma_buffer->cmd;
-+
-+ dma_buffer->data.devcmd1_mod = (dma_buffer->data.devcmd1_orig &
-+ 0xFFFFFF00) | (cmd_set_count
-+ ? FLASH_READ_ONFI_IDENTIFIER_COMMAND
-+ : FLASH_READ_ONFI_PARAMETERS_COMMAND);
-+ dma_buffer->data.cmd = MSM_NAND_CMD_PAGE_READ;
-+ dma_buffer->data.addr0 = (page_address << 16) | (cmd_set_count
-+ ? FLASH_READ_ONFI_IDENTIFIER_ADDRESS
-+ : FLASH_READ_ONFI_PARAMETERS_ADDRESS);
-+ dma_buffer->data.addr1 = (page_address >> 16) & 0xFF;
-+ dma_buffer->data.cfg0 = (cmd_set_count
-+ ? MSM_NAND_CFG0_RAW_ONFI_IDENTIFIER
-+ : MSM_NAND_CFG0_RAW_ONFI_PARAM_INFO);
-+ dma_buffer->data.cfg1 = (cmd_set_count
-+ ? MSM_NAND_CFG1_RAW_ONFI_IDENTIFIER
-+ : MSM_NAND_CFG1_RAW_ONFI_PARAM_INFO);
-+ dma_buffer->data.sflash_bcfg_mod = 0x00000000;
-+ dma_buffer->data.devcmdvld_mod = (dma_buffer->
-+ data.devcmdvld_orig & 0xFFFFFFFE);
-+ dma_buffer->data.exec = 1;
-+ dma_buffer->data.flash_status = 0xeeeeeeee;
-+
-+ /* Put the Nand ctlr in Async mode and disable SFlash ctlr */
-+ cmd->cmd = 0;
-+ cmd->src = msm_virt_to_dma(chip,
-+ &dma_buffer->data.sflash_bcfg_mod);
-+ cmd->dst = MSM_NAND_SFLASHC_BURST_CFG;
-+ cmd->len = 4;
-+ cmd++;
-+
-+ cmd->cmd = 0;
-+ cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.chip_select);
-+ cmd->dst = MSM_NAND_FLASH_CHIP_SELECT;
-+ cmd->len = 4;
-+ cmd++;
-+
-+ /* Block on cmd ready, & write CMD,ADDR0,ADDR1,CHIPSEL regs */
-+ cmd->cmd = DST_CRCI_NAND_CMD;
-+ cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.cmd);
-+ cmd->dst = MSM_NAND_FLASH_CMD;
-+ cmd->len = 12;
-+ cmd++;
-+
-+ /* Configure the CFG0 and CFG1 registers */
-+ cmd->cmd = 0;
-+ cmd->src = msm_virt_to_dma(chip,
-+ &dma_buffer->data.cfg0);
-+ cmd->dst = MSM_NAND_DEV0_CFG0;
-+ cmd->len = 8;
-+ cmd++;
-+
-+ /* Configure the DEV_CMD_VLD register */
-+ cmd->cmd = 0;
-+ cmd->src = msm_virt_to_dma(chip,
-+ &dma_buffer->data.devcmdvld_mod);
-+ cmd->dst = MSM_NAND_DEV_CMD_VLD;
-+ cmd->len = 4;
-+ cmd++;
-+
-+ /* Configure the DEV_CMD1 register */
-+ cmd->cmd = 0;
-+ cmd->src = msm_virt_to_dma(chip,
-+ &dma_buffer->data.devcmd1_mod);
-+ cmd->dst = MSM_NAND_DEV_CMD1;
-+ cmd->len = 4;
-+ cmd++;
-+
-+ /* Kick the execute command */
-+ cmd->cmd = 0;
-+ cmd->src = msm_virt_to_dma(chip,
-+ &dma_buffer->data.exec);
-+ cmd->dst = MSM_NAND_EXEC_CMD;
-+ cmd->len = 4;
-+ cmd++;
-+
-+ /* Block on data ready, and read the two status registers */
-+ cmd->cmd = SRC_CRCI_NAND_DATA;
-+ cmd->src = MSM_NAND_FLASH_STATUS;
-+ cmd->dst = msm_virt_to_dma(chip,
-+ &dma_buffer->data.flash_status);
-+ cmd->len = 4;
-+ cmd++;
-+
-+ /* Read data block - valid only if status says success */
-+ cmd->cmd = 0;
-+ cmd->src = MSM_NAND_FLASH_BUFFER;
-+ cmd->dst = (cmd_set_count ? dma_addr_identifier :
-+ dma_addr_param_info);
-+ cmd->len = (cmd_set_count ? ONFI_IDENTIFIER_LENGTH :
-+ ONFI_PARAM_INFO_LENGTH);
-+ cmd++;
-+
-+ /* Restore the DEV_CMD1 register */
-+ cmd->cmd = 0 ;
-+ cmd->src = msm_virt_to_dma(chip,
-+ &dma_buffer->data.devcmd1_orig);
-+ cmd->dst = MSM_NAND_DEV_CMD1;
-+ cmd->len = 4;
-+ cmd++;
-+
-+ /* Restore the DEV_CMD_VLD register */
-+ cmd->cmd = 0;
-+ cmd->src = msm_virt_to_dma(chip,
-+ &dma_buffer->data.devcmdvld_orig);
-+ cmd->dst = MSM_NAND_DEV_CMD_VLD;
-+ cmd->len = 4;
-+ cmd++;
-+
-+ /* Restore the SFLASH_BURST_CONFIG register */
-+ cmd->cmd = 0;
-+ cmd->src = msm_virt_to_dma(chip,
-+ &dma_buffer->data.sflash_bcfg_orig);
-+ cmd->dst = MSM_NAND_SFLASHC_BURST_CFG;
-+ cmd->len = 4;
-+ cmd++;
-+
-+ BUILD_BUG_ON(12 != ARRAY_SIZE(dma_buffer->cmd));
-+ BUG_ON(cmd - dma_buffer->cmd > ARRAY_SIZE(dma_buffer->cmd));
-+ dma_buffer->cmd[0].cmd |= CMD_OCB;
-+ cmd[-1].cmd |= CMD_OCU | CMD_LC;
-+
-+ dma_buffer->cmdptr = (msm_virt_to_dma(chip, dma_buffer->cmd)
-+ >> 3) | CMD_PTR_LP;
-+
-+ mb();
-+ msm_dmov_exec_cmd(chip->dma_channel,
-+ DMOV_CMD_PTR_LIST | DMOV_CMD_ADDR(msm_virt_to_dma(chip,
-+ &dma_buffer->cmdptr)));
-+ mb();
-+
-+ /* Check for errors, protection violations etc */
-+ if (dma_buffer->data.flash_status & 0x110) {
-+ pr_info("MPU/OP error (0x%x) during "
-+ "ONFI probe\n",
-+ dma_buffer->data.flash_status);
-+ err = -EIO;
-+ break;
-+ }
-+
-+ if (cmd_set_count) {
-+ onfi_param_page_ptr = (struct onfi_param_page *)
-+ (&(onfi_identifier_buf[0]));
-+ if (onfi_param_page_ptr->parameter_page_signature !=
-+ ONFI_PARAMETER_PAGE_SIGNATURE) {
-+ pr_info("ONFI probe : Found a non"
-+ "ONFI Compliant device \n");
-+ err = -EIO;
-+ break;
-+ }
-+ } else {
-+ for (crc_chk_count = 0; crc_chk_count <
-+ ONFI_PARAM_INFO_LENGTH
-+ / ONFI_PARAM_PAGE_LENGTH;
-+ crc_chk_count++) {
-+ onfi_param_page_ptr =
-+ (struct onfi_param_page *)
-+ (&(onfi_param_info_buf
-+ [ONFI_PARAM_PAGE_LENGTH *
-+ crc_chk_count]));
-+ if (flash_onfi_crc_check(
-+ (uint8_t *)onfi_param_page_ptr,
-+ ONFI_PARAM_PAGE_LENGTH - 2) ==
-+ onfi_param_page_ptr->integrity_crc) {
-+ break;
-+ }
-+ }
-+ if (crc_chk_count >= ONFI_PARAM_INFO_LENGTH
-+ / ONFI_PARAM_PAGE_LENGTH) {
-+ pr_info("ONFI probe : CRC Check "
-+ "failed on ONFI Parameter "
-+ "data \n");
-+ err = -EIO;
-+ break;
-+ } else {
-+ supported_flash.flash_id =
-+ flash_read_id(chip);
-+ supported_flash.widebus =
-+ onfi_param_page_ptr->
-+ features_supported & 0x01;
-+ supported_flash.pagesize =
-+ onfi_param_page_ptr->
-+ number_of_data_bytes_per_page;
-+ supported_flash.blksize =
-+ onfi_param_page_ptr->
-+ number_of_pages_per_block *
-+ supported_flash.pagesize;
-+ supported_flash.oobsize =
-+ onfi_param_page_ptr->
-+ number_of_spare_bytes_per_page;
-+ supported_flash.density =
-+ onfi_param_page_ptr->
-+ number_of_blocks_per_logical_unit
-+ * supported_flash.blksize;
-+ supported_flash.ecc_correctability =
-+ onfi_param_page_ptr->
-+ number_of_bits_ecc_correctability;
-+
-+ pr_info("ONFI probe : Found an ONFI "
-+ "compliant device %s\n",
-+ onfi_param_page_ptr->device_model);
-+
-+ /* Temporary hack for MT29F4G08ABC device.
-+ * Since the device is not properly adhering
-+ * to ONFi specification it is reporting
-+ * as 16 bit device though it is 8 bit device!!!
-+ */
-+ if (!strncmp(onfi_param_page_ptr->device_model,
-+ "MT29F4G08ABC", 12))
-+ supported_flash.widebus = 0;
-+ }
-+ }
-+ }
-+
-+ msm_nand_release_dma_buffer(chip, dma_buffer, sizeof(*dma_buffer));
-+ msm_nand_release_dma_buffer(chip, onfi_param_info_buf,
-+ ONFI_PARAM_INFO_LENGTH);
-+ msm_nand_release_dma_buffer(chip, onfi_identifier_buf,
-+ ONFI_IDENTIFIER_LENGTH);
-+
-+ return err;
-+}
-+
-+static int msm_nand_read_oob(struct mtd_info *mtd, loff_t from,
-+ struct mtd_oob_ops *ops)
-+{
-+ struct msm_nand_chip *chip = mtd->priv;
-+
-+ struct {
-+ dmov_s cmd[8 * 5 + 2];
-+ unsigned cmdptr;
-+ struct {
-+ uint32_t cmd;
-+ uint32_t addr0;
-+ uint32_t addr1;
-+ uint32_t chipsel;
-+ uint32_t cfg0;
-+ uint32_t cfg1;
-+ uint32_t eccbchcfg;
-+ uint32_t exec;
-+ uint32_t ecccfg;
-+ struct {
-+ uint32_t flash_status;
-+ uint32_t buffer_status;
-+ } result[8];
-+ } data;
-+ } *dma_buffer;
-+ dmov_s *cmd;
-+ unsigned n;
-+ unsigned page = 0;
-+ uint32_t oob_len;
-+ uint32_t sectordatasize;
-+ uint32_t sectoroobsize;
-+ int err, pageerr, rawerr;
-+ dma_addr_t data_dma_addr = 0;
-+ dma_addr_t oob_dma_addr = 0;
-+ dma_addr_t data_dma_addr_curr = 0;
-+ dma_addr_t oob_dma_addr_curr = 0;
-+ uint8_t *dat_bounce_buf = NULL;
-+ uint8_t *oob_bounce_buf = NULL;
-+ uint32_t oob_col = 0;
-+ unsigned page_count;
-+ unsigned pages_read = 0;
-+ unsigned start_sector = 0;
-+ uint32_t ecc_errors;
-+ uint32_t total_ecc_errors = 0;
-+ unsigned cwperpage;
-+#if VERBOSE
-+ pr_info("================================================="
-+ "================\n");
-+ pr_info("%s:\nfrom 0x%llx mode %d\ndatbuf 0x%p datlen 0x%x"
-+ "\noobbuf 0x%p ooblen 0x%x\n",
-+ __func__, from, ops->mode, ops->datbuf, ops->len,
-+ ops->oobbuf, ops->ooblen);
-+#endif
-+
-+ if (mtd->writesize == 2048)
-+ page = from >> 11;
-+
-+ if (mtd->writesize == 4096)
-+ page = from >> 12;
-+
-+ oob_len = ops->ooblen;
-+ cwperpage = (mtd->writesize >> 9);
-+
-+ if (from & (mtd->writesize - 1)) {
-+ pr_err("%s: unsupported from, 0x%llx\n",
-+ __func__, from);
-+ return -EINVAL;
-+ }
-+ if (ops->mode != MTD_OPS_RAW) {
-+ if (ops->datbuf != NULL && (ops->len % mtd->writesize) != 0) {
-+ /* when ops->datbuf is NULL, ops->len can be ooblen */
-+ pr_err("%s: unsupported ops->len, %d\n",
-+ __func__, ops->len);
-+ return -EINVAL;
-+ }
-+ } else {
-+ if (ops->datbuf != NULL &&
-+ (ops->len % (mtd->writesize + mtd->oobsize)) != 0) {
-+ pr_err("%s: unsupported ops->len,"
-+ " %d for MTD_OPS_RAW\n", __func__, ops->len);
-+ return -EINVAL;
-+ }
-+ }
-+
-+ if (ops->mode != MTD_OPS_RAW && ops->ooblen != 0 && ops->ooboffs != 0) {
-+ pr_err("%s: unsupported ops->ooboffs, %d\n",
-+ __func__, ops->ooboffs);
-+ return -EINVAL;
-+ }
-+
-+ if (ops->oobbuf && !ops->datbuf && ops->mode == MTD_OPS_AUTO_OOB)
-+ start_sector = cwperpage - 1;
-+
-+ if (ops->oobbuf && !ops->datbuf) {
-+ page_count = ops->ooblen / ((ops->mode == MTD_OPS_AUTO_OOB) ?
-+ mtd->oobavail : mtd->oobsize);
-+ if ((page_count == 0) && (ops->ooblen))
-+ page_count = 1;
-+ } else if (ops->mode != MTD_OPS_RAW)
-+ page_count = ops->len / mtd->writesize;
-+ else
-+ page_count = ops->len / (mtd->writesize + mtd->oobsize);
-+
-+ if (ops->datbuf) {
-+ data_dma_addr_curr = data_dma_addr =
-+ msm_nand_dma_map(chip->dev, ops->datbuf, ops->len,
-+ DMA_FROM_DEVICE, &dat_bounce_buf);
-+ if (dma_mapping_error(chip->dev, data_dma_addr)) {
-+ pr_err("msm_nand_read_oob: failed to get dma addr "
-+ "for %p\n", ops->datbuf);
-+ return -EIO;
-+ }
-+ }
-+ if (ops->oobbuf) {
-+ memset(ops->oobbuf, 0xff, ops->ooblen);
-+ oob_dma_addr_curr = oob_dma_addr =
-+ msm_nand_dma_map(chip->dev, ops->oobbuf,
-+ ops->ooblen, DMA_BIDIRECTIONAL,
-+ &oob_bounce_buf);
-+ if (dma_mapping_error(chip->dev, oob_dma_addr)) {
-+ pr_err("msm_nand_read_oob: failed to get dma addr "
-+ "for %p\n", ops->oobbuf);
-+ err = -EIO;
-+ goto err_dma_map_oobbuf_failed;
-+ }
-+ }
-+
-+ wait_event(chip->wait_queue,
-+ (dma_buffer = msm_nand_get_dma_buffer(
-+ chip, sizeof(*dma_buffer))));
-+
-+ oob_col = start_sector * chip->cw_size;
-+ if (chip->CFG1 & CFG1_WIDE_FLASH)
-+ oob_col >>= 1;
-+
-+ err = 0;
-+ while (page_count-- > 0) {
-+ cmd = dma_buffer->cmd;
-+
-+ /* CMD / ADDR0 / ADDR1 / CHIPSEL program values */
-+ if (ops->mode != MTD_OPS_RAW) {
-+ dma_buffer->data.cmd = MSM_NAND_CMD_PAGE_READ_ECC;
-+ dma_buffer->data.cfg0 =
-+ (chip->CFG0 & ~(7U << 6))
-+ | (((cwperpage-1) - start_sector) << 6);
-+ dma_buffer->data.cfg1 = chip->CFG1;
-+ if (enable_bch_ecc)
-+ dma_buffer->data.eccbchcfg = chip->ecc_bch_cfg;
-+ } else {
-+ dma_buffer->data.cmd = MSM_NAND_CMD_PAGE_READ;
-+ dma_buffer->data.cfg0 = (chip->CFG0_RAW
-+ & ~(7U << 6)) | ((cwperpage-1) << 6);
-+ dma_buffer->data.cfg1 = chip->CFG1_RAW |
-+ (chip->CFG1 & CFG1_WIDE_FLASH);
-+ }
-+
-+ dma_buffer->data.addr0 = (page << 16) | oob_col;
-+ dma_buffer->data.addr1 = (page >> 16) & 0xff;
-+ /* chipsel_0 + enable DM interface */
-+ dma_buffer->data.chipsel = 0 | 4;
-+
-+
-+ /* GO bit for the EXEC register */
-+ dma_buffer->data.exec = 1;
-+
-+
-+ BUILD_BUG_ON(8 != ARRAY_SIZE(dma_buffer->data.result));
-+
-+ for (n = start_sector; n < cwperpage; n++) {
-+ /* flash + buffer status return words */
-+ dma_buffer->data.result[n].flash_status = 0xeeeeeeee;
-+ dma_buffer->data.result[n].buffer_status = 0xeeeeeeee;
-+
-+ /* block on cmd ready, then
-+ * write CMD / ADDR0 / ADDR1 / CHIPSEL
-+ * regs in a burst
-+ */
-+ cmd->cmd = DST_CRCI_NAND_CMD;
-+ cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.cmd);
-+ cmd->dst = MSM_NAND_FLASH_CMD;
-+ if (n == start_sector)
-+ cmd->len = 16;
-+ else
-+ cmd->len = 4;
-+ cmd++;
-+
-+ if (n == start_sector) {
-+ cmd->cmd = 0;
-+ cmd->src = msm_virt_to_dma(chip,
-+ &dma_buffer->data.cfg0);
-+ cmd->dst = MSM_NAND_DEV0_CFG0;
-+ if (enable_bch_ecc)
-+ cmd->len = 12;
-+ else
-+ cmd->len = 8;
-+ cmd++;
-+
-+ dma_buffer->data.ecccfg = chip->ecc_buf_cfg;
-+ cmd->cmd = 0;
-+ cmd->src = msm_virt_to_dma(chip,
-+ &dma_buffer->data.ecccfg);
-+ cmd->dst = MSM_NAND_EBI2_ECC_BUF_CFG;
-+ cmd->len = 4;
-+ cmd++;
-+ }
-+
-+ /* kick the execute register */
-+ cmd->cmd = 0;
-+ cmd->src =
-+ msm_virt_to_dma(chip, &dma_buffer->data.exec);
-+ cmd->dst = MSM_NAND_EXEC_CMD;
-+ cmd->len = 4;
-+ cmd++;
-+
-+ /* block on data ready, then
-+ * read the status register
-+ */
-+ cmd->cmd = SRC_CRCI_NAND_DATA;
-+ cmd->src = MSM_NAND_FLASH_STATUS;
-+ cmd->dst = msm_virt_to_dma(chip,
-+ &dma_buffer->data.result[n]);
-+ /* MSM_NAND_FLASH_STATUS + MSM_NAND_BUFFER_STATUS */
-+ cmd->len = 8;
-+ cmd++;
-+
-+ /* read data block
-+ * (only valid if status says success)
-+ */
-+ if (ops->datbuf) {
-+ if (ops->mode != MTD_OPS_RAW) {
-+ if (!boot_layout)
-+ sectordatasize = (n < (cwperpage - 1))
-+ ? 516 : (512 - ((cwperpage - 1) << 2));
-+ else
-+ sectordatasize = 512;
-+ } else {
-+ sectordatasize = chip->cw_size;
-+ }
-+
-+ cmd->cmd = 0;
-+ cmd->src = MSM_NAND_FLASH_BUFFER;
-+ cmd->dst = data_dma_addr_curr;
-+ data_dma_addr_curr += sectordatasize;
-+ cmd->len = sectordatasize;
-+ cmd++;
-+ }
-+
-+ if (ops->oobbuf && (n == (cwperpage - 1)
-+ || ops->mode != MTD_OPS_AUTO_OOB)) {
-+ cmd->cmd = 0;
-+ if (n == (cwperpage - 1)) {
-+ cmd->src = MSM_NAND_FLASH_BUFFER +
-+ (512 - ((cwperpage - 1) << 2));
-+ sectoroobsize = (cwperpage << 2);
-+ if (ops->mode != MTD_OPS_AUTO_OOB)
-+ sectoroobsize +=
-+ chip->ecc_parity_bytes;
-+ } else {
-+ cmd->src = MSM_NAND_FLASH_BUFFER + 516;
-+ sectoroobsize = chip->ecc_parity_bytes;
-+ }
-+
-+ cmd->dst = oob_dma_addr_curr;
-+ if (sectoroobsize < oob_len)
-+ cmd->len = sectoroobsize;
-+ else
-+ cmd->len = oob_len;
-+ oob_dma_addr_curr += cmd->len;
-+ oob_len -= cmd->len;
-+ if (cmd->len > 0)
-+ cmd++;
-+ }
-+ }
-+
-+ BUILD_BUG_ON(8 * 5 + 2 != ARRAY_SIZE(dma_buffer->cmd));
-+ BUG_ON(cmd - dma_buffer->cmd > ARRAY_SIZE(dma_buffer->cmd));
-+ dma_buffer->cmd[0].cmd |= CMD_OCB;
-+ cmd[-1].cmd |= CMD_OCU | CMD_LC;
-+
-+ dma_buffer->cmdptr =
-+ (msm_virt_to_dma(chip, dma_buffer->cmd) >> 3)
-+ | CMD_PTR_LP;
-+
-+ mb();
-+ msm_dmov_exec_cmd(chip->dma_channel,
-+ DMOV_CMD_PTR_LIST | DMOV_CMD_ADDR(msm_virt_to_dma(chip,
-+ &dma_buffer->cmdptr)));
-+ mb();
-+
-+ /* if any of the writes failed (0x10), or there
-+ * was a protection violation (0x100), we lose
-+ */
-+ pageerr = rawerr = 0;
-+ for (n = start_sector; n < cwperpage; n++) {
-+ if (dma_buffer->data.result[n].flash_status & 0x110) {
-+ rawerr = -EIO;
-+ break;
-+ }
-+ }
-+ if (rawerr) {
-+ if (ops->datbuf && ops->mode != MTD_OPS_RAW) {
-+ uint8_t *datbuf = ops->datbuf +
-+ pages_read * mtd->writesize;
-+
-+ dma_sync_single_for_cpu(chip->dev,
-+ data_dma_addr_curr-mtd->writesize,
-+ mtd->writesize, DMA_BIDIRECTIONAL);
-+
-+ for (n = 0; n < mtd->writesize; n++) {
-+ /* empty blocks read 0x54 at
-+ * these offsets
-+ */
-+ if ((n % 516 == 3 || n % 516 == 175)
-+ && datbuf[n] == 0x54)
-+ datbuf[n] = 0xff;
-+ if (datbuf[n] != 0xff) {
-+ pageerr = rawerr;
-+ break;
-+ }
-+ }
-+
-+ dma_sync_single_for_device(chip->dev,
-+ data_dma_addr_curr-mtd->writesize,
-+ mtd->writesize, DMA_BIDIRECTIONAL);
-+
-+ }
-+ if (ops->oobbuf) {
-+ dma_sync_single_for_cpu(chip->dev,
-+ oob_dma_addr_curr - (ops->ooblen - oob_len),
-+ ops->ooblen - oob_len, DMA_BIDIRECTIONAL);
-+
-+ for (n = 0; n < ops->ooblen; n++) {
-+ if (ops->oobbuf[n] != 0xff) {
-+ pageerr = rawerr;
-+ break;
-+ }
-+ }
-+
-+ dma_sync_single_for_device(chip->dev,
-+ oob_dma_addr_curr - (ops->ooblen - oob_len),
-+ ops->ooblen - oob_len, DMA_BIDIRECTIONAL);
-+ }
-+ }
-+ if (pageerr) {
-+ for (n = start_sector; n < cwperpage; n++) {
-+ if (dma_buffer->data.result[n].buffer_status &
-+ chip->uncorrectable_bit_mask) {
-+ /* not thread safe */
-+ mtd->ecc_stats.failed++;
-+ pageerr = -EBADMSG;
-+ break;
-+ }
-+ }
-+ }
-+ if (!rawerr) { /* check for corretable errors */
-+ for (n = start_sector; n < cwperpage; n++) {
-+ ecc_errors =
-+ (dma_buffer->data.result[n].buffer_status
-+ & chip->num_err_mask);
-+ if (ecc_errors) {
-+ total_ecc_errors += ecc_errors;
-+ /* not thread safe */
-+ mtd->ecc_stats.corrected += ecc_errors;
-+ if (ecc_errors > 1)
-+ pageerr = -EUCLEAN;
-+ }
-+ }
-+ }
-+ if (pageerr && (pageerr != -EUCLEAN || err == 0))
-+ err = pageerr;
-+
-+#if VERBOSE
-+ if (rawerr && !pageerr) {
-+ pr_err("msm_nand_read_oob %llx %x %x empty page\n",
-+ (loff_t)page * mtd->writesize, ops->len,
-+ ops->ooblen);
-+ } else {
-+ for (n = start_sector; n < cwperpage; n++)
-+ pr_info("flash_status[%d] = %x,\
-+ buffr_status[%d] = %x\n",
-+ n, dma_buffer->data.result[n].flash_status,
-+ n, dma_buffer->data.result[n].buffer_status);
-+ }
-+#endif
-+ if (err && err != -EUCLEAN && err != -EBADMSG)
-+ break;
-+ pages_read++;
-+ page++;
-+ }
-+ msm_nand_release_dma_buffer(chip, dma_buffer, sizeof(*dma_buffer));
-+
-+ if (ops->oobbuf) {
-+ msm_nand_dma_unmap(chip->dev, oob_dma_addr,
-+ ops->ooblen, DMA_FROM_DEVICE,
-+ ops->oobbuf, oob_bounce_buf);
-+ }
-+err_dma_map_oobbuf_failed:
-+ if (ops->datbuf) {
-+ msm_nand_dma_unmap(chip->dev, data_dma_addr,
-+ ops->len, DMA_BIDIRECTIONAL,
-+ ops->datbuf, dat_bounce_buf);
-+ }
-+
-+ if (ops->mode != MTD_OPS_RAW)
-+ ops->retlen = mtd->writesize * pages_read;
-+ else
-+ ops->retlen = (mtd->writesize + mtd->oobsize) *
-+ pages_read;
-+ ops->oobretlen = ops->ooblen - oob_len;
-+ if (err)
-+ pr_err("msm_nand_read_oob %llx %x %x failed %d, corrected %d\n",
-+ from, ops->datbuf ? ops->len : 0, ops->ooblen, err,
-+ total_ecc_errors);
-+#if VERBOSE
-+ pr_info("\n%s: ret %d, retlen %d oobretlen %d\n",
-+ __func__, err, ops->retlen, ops->oobretlen);
-+
-+ pr_info("==================================================="
-+ "==============\n");
-+#endif
-+ return err;
-+}
-+
-+static int msm_nand_read_oob_dualnandc(struct mtd_info *mtd, loff_t from,
-+ struct mtd_oob_ops *ops)
-+{
-+ struct msm_nand_chip *chip = mtd->priv;
-+
-+ struct {
-+ dmov_s cmd[16 * 6 + 20];
-+ unsigned cmdptr;
-+ struct {
-+ uint32_t cmd;
-+ uint32_t nandc01_addr0;
-+ uint32_t nandc10_addr0;
-+ uint32_t nandc11_addr1;
-+ uint32_t chipsel_cs0;
-+ uint32_t chipsel_cs1;
-+ uint32_t cfg0;
-+ uint32_t cfg1;
-+ uint32_t eccbchcfg;
-+ uint32_t exec;
-+ uint32_t ecccfg;
-+ uint32_t ebi2_chip_select_cfg0;
-+ uint32_t adm_mux_data_ack_req_nc01;
-+ uint32_t adm_mux_cmd_ack_req_nc01;
-+ uint32_t adm_mux_data_ack_req_nc10;
-+ uint32_t adm_mux_cmd_ack_req_nc10;
-+ uint32_t adm_default_mux;
-+ uint32_t default_ebi2_chip_select_cfg0;
-+ uint32_t nc10_flash_dev_cmd_vld;
-+ uint32_t nc10_flash_dev_cmd1;
-+ uint32_t nc10_flash_dev_cmd_vld_default;
-+ uint32_t nc10_flash_dev_cmd1_default;
-+ struct {
-+ uint32_t flash_status;
-+ uint32_t buffer_status;
-+ } result[16];
-+ } data;
-+ } *dma_buffer;
-+ dmov_s *cmd;
-+ unsigned n;
-+ unsigned page = 0;
-+ uint32_t oob_len;
-+ uint32_t sectordatasize;
-+ uint32_t sectoroobsize;
-+ int err, pageerr, rawerr;
-+ dma_addr_t data_dma_addr = 0;
-+ dma_addr_t oob_dma_addr = 0;
-+ dma_addr_t data_dma_addr_curr = 0;
-+ dma_addr_t oob_dma_addr_curr = 0;
-+ uint32_t oob_col = 0;
-+ unsigned page_count;
-+ unsigned pages_read = 0;
-+ unsigned start_sector = 0;
-+ uint32_t ecc_errors;
-+ uint32_t total_ecc_errors = 0;
-+ unsigned cwperpage;
-+ unsigned cw_offset = chip->cw_size;
-+#if VERBOSE
-+ pr_info("================================================="
-+ "============\n");
-+ pr_info("%s:\nfrom 0x%llx mode %d\ndatbuf 0x%p datlen 0x%x"
-+ "\noobbuf 0x%p ooblen 0x%x\n\n",
-+ __func__, from, ops->mode, ops->datbuf,
-+ ops->len, ops->oobbuf, ops->ooblen);
-+#endif
-+
-+ if (mtd->writesize == 2048)
-+ page = from >> 11;
-+
-+ if (mtd->writesize == 4096)
-+ page = from >> 12;
-+
-+ if (interleave_enable)
-+ page = (from >> 1) >> 12;
-+
-+ oob_len = ops->ooblen;
-+ cwperpage = (mtd->writesize >> 9);
-+
-+ if (from & (mtd->writesize - 1)) {
-+ pr_err("%s: unsupported from, 0x%llx\n",
-+ __func__, from);
-+ return -EINVAL;
-+ }
-+ if (ops->mode != MTD_OPS_RAW) {
-+ if (ops->datbuf != NULL && (ops->len % mtd->writesize) != 0) {
-+ pr_err("%s: unsupported ops->len, %d\n",
-+ __func__, ops->len);
-+ return -EINVAL;
-+ }
-+ } else {
-+ if (ops->datbuf != NULL &&
-+ (ops->len % (mtd->writesize + mtd->oobsize)) != 0) {
-+ pr_err("%s: unsupported ops->len,"
-+ " %d for MTD_OPS_RAW\n", __func__, ops->len);
-+ return -EINVAL;
-+ }
-+ }
-+
-+ if (ops->mode != MTD_OPS_RAW && ops->ooblen != 0 && ops->ooboffs != 0) {
-+ pr_err("%s: unsupported ops->ooboffs, %d\n",
-+ __func__, ops->ooboffs);
-+ return -EINVAL;
-+ }
-+
-+ if (ops->oobbuf && !ops->datbuf && ops->mode == MTD_OPS_AUTO_OOB)
-+ start_sector = cwperpage - 1;
-+
-+ if (ops->oobbuf && !ops->datbuf) {
-+ page_count = ops->ooblen / ((ops->mode == MTD_OPS_AUTO_OOB) ?
-+ mtd->oobavail : mtd->oobsize);
-+ if ((page_count == 0) && (ops->ooblen))
-+ page_count = 1;
-+ } else if (ops->mode != MTD_OPS_RAW)
-+ page_count = ops->len / mtd->writesize;
-+ else
-+ page_count = ops->len / (mtd->writesize + mtd->oobsize);
-+
-+ if (ops->datbuf) {
-+ data_dma_addr_curr = data_dma_addr =
-+ msm_nand_dma_map(chip->dev, ops->datbuf, ops->len,
-+ DMA_FROM_DEVICE, NULL);
-+ if (dma_mapping_error(chip->dev, data_dma_addr)) {
-+ pr_err("msm_nand_read_oob_dualnandc: "
-+ "failed to get dma addr for %p\n",
-+ ops->datbuf);
-+ return -EIO;
-+ }
-+ }
-+ if (ops->oobbuf) {
-+ memset(ops->oobbuf, 0xff, ops->ooblen);
-+ oob_dma_addr_curr = oob_dma_addr =
-+ msm_nand_dma_map(chip->dev, ops->oobbuf,
-+ ops->ooblen, DMA_BIDIRECTIONAL, NULL);
-+ if (dma_mapping_error(chip->dev, oob_dma_addr)) {
-+ pr_err("msm_nand_read_oob_dualnandc: "
-+ "failed to get dma addr for %p\n",
-+ ops->oobbuf);
-+ err = -EIO;
-+ goto err_dma_map_oobbuf_failed;
-+ }
-+ }
-+
-+ wait_event(chip->wait_queue,
-+ (dma_buffer = msm_nand_get_dma_buffer(
-+ chip, sizeof(*dma_buffer))));
-+
-+ oob_col = start_sector * chip->cw_size;
-+ if (chip->CFG1 & CFG1_WIDE_FLASH) {
-+ oob_col >>= 1;
-+ cw_offset >>= 1;
-+ }
-+
-+ err = 0;
-+ while (page_count-- > 0) {
-+ cmd = dma_buffer->cmd;
-+
-+ if (ops->mode != MTD_OPS_RAW) {
-+ dma_buffer->data.cmd = MSM_NAND_CMD_PAGE_READ_ECC;
-+ if (start_sector == (cwperpage - 1)) {
-+ dma_buffer->data.cfg0 = (chip->CFG0 &
-+ ~(7U << 6));
-+ } else {
-+ dma_buffer->data.cfg0 = (chip->CFG0 &
-+ ~(7U << 6))
-+ | (((cwperpage >> 1)-1) << 6);
-+ }
-+ dma_buffer->data.cfg1 = chip->CFG1;
-+ if (enable_bch_ecc)
-+ dma_buffer->data.eccbchcfg = chip->ecc_bch_cfg;
-+ } else {
-+ dma_buffer->data.cmd = MSM_NAND_CMD_PAGE_READ;
-+ dma_buffer->data.cfg0 = ((chip->CFG0_RAW &
-+ ~(7U << 6)) | ((((cwperpage >> 1)-1) << 6)));
-+ dma_buffer->data.cfg1 = chip->CFG1_RAW |
-+ (chip->CFG1 & CFG1_WIDE_FLASH);
-+ }
-+
-+ if (!interleave_enable) {
-+ if (start_sector == (cwperpage - 1)) {
-+ dma_buffer->data.nandc10_addr0 =
-+ (page << 16) | oob_col;
-+ dma_buffer->data.nc10_flash_dev_cmd_vld = 0xD;
-+ dma_buffer->data.nc10_flash_dev_cmd1 =
-+ 0xF00F3000;
-+ } else {
-+ dma_buffer->data.nandc01_addr0 = page << 16;
-+ /* NC10 ADDR0 points to the next code word */
-+ dma_buffer->data.nandc10_addr0 = (page << 16) |
-+ cw_offset;
-+ dma_buffer->data.nc10_flash_dev_cmd_vld = 0x1D;
-+ dma_buffer->data.nc10_flash_dev_cmd1 =
-+ 0xF00FE005;
-+ }
-+ } else {
-+ dma_buffer->data.nandc01_addr0 =
-+ dma_buffer->data.nandc10_addr0 =
-+ (page << 16) | oob_col;
-+ }
-+ /* ADDR1 */
-+ dma_buffer->data.nandc11_addr1 = (page >> 16) & 0xff;
-+
-+ dma_buffer->data.adm_mux_data_ack_req_nc01 = 0x00000A3C;
-+ dma_buffer->data.adm_mux_cmd_ack_req_nc01 = 0x0000053C;
-+ dma_buffer->data.adm_mux_data_ack_req_nc10 = 0x00000F28;
-+ dma_buffer->data.adm_mux_cmd_ack_req_nc10 = 0x00000F14;
-+ dma_buffer->data.adm_default_mux = 0x00000FC0;
-+ dma_buffer->data.nc10_flash_dev_cmd_vld_default = 0x1D;
-+ dma_buffer->data.nc10_flash_dev_cmd1_default = 0xF00F3000;
-+
-+ dma_buffer->data.ebi2_chip_select_cfg0 = 0x00000805;
-+ dma_buffer->data.default_ebi2_chip_select_cfg0 = 0x00000801;
-+
-+ /* chipsel_0 + enable DM interface */
-+ dma_buffer->data.chipsel_cs0 = (1<<4) | 4;
-+ /* chipsel_1 + enable DM interface */
-+ dma_buffer->data.chipsel_cs1 = (1<<4) | 5;
-+
-+ /* GO bit for the EXEC register */
-+ dma_buffer->data.exec = 1;
-+
-+ BUILD_BUG_ON(16 != ARRAY_SIZE(dma_buffer->data.result));
-+
-+ for (n = start_sector; n < cwperpage; n++) {
-+ /* flash + buffer status return words */
-+ dma_buffer->data.result[n].flash_status = 0xeeeeeeee;
-+ dma_buffer->data.result[n].buffer_status = 0xeeeeeeee;
-+
-+ if (n == start_sector) {
-+ if (!interleave_enable) {
-+ cmd->cmd = 0;
-+ cmd->src = msm_virt_to_dma(chip,
-+ &dma_buffer->
-+ data.nc10_flash_dev_cmd_vld);
-+ cmd->dst = NC10(MSM_NAND_DEV_CMD_VLD);
-+ cmd->len = 4;
-+ cmd++;
-+
-+ cmd->cmd = 0;
-+ cmd->src = msm_virt_to_dma(chip,
-+ &dma_buffer->data.nc10_flash_dev_cmd1);
-+ cmd->dst = NC10(MSM_NAND_DEV_CMD1);
-+ cmd->len = 4;
-+ cmd++;
-+
-+ /* NC01, NC10 --> ADDR1 */
-+ cmd->cmd = 0;
-+ cmd->src = msm_virt_to_dma(chip,
-+ &dma_buffer->data.nandc11_addr1);
-+ cmd->dst = NC11(MSM_NAND_ADDR1);
-+ cmd->len = 8;
-+ cmd++;
-+
-+ cmd->cmd = 0;
-+ cmd->src = msm_virt_to_dma(chip,
-+ &dma_buffer->data.cfg0);
-+ cmd->dst = NC11(MSM_NAND_DEV0_CFG0);
-+ if (enable_bch_ecc)
-+ cmd->len = 12;
-+ else
-+ cmd->len = 8;
-+ cmd++;
-+ } else {
-+ /* enable CS0 & CS1 */
-+ cmd->cmd = 0;
-+ cmd->src = msm_virt_to_dma(chip,
-+ &dma_buffer->
-+ data.ebi2_chip_select_cfg0);
-+ cmd->dst = EBI2_CHIP_SELECT_CFG0;
-+ cmd->len = 4;
-+ cmd++;
-+
-+ /* NC01, NC10 --> ADDR1 */
-+ cmd->cmd = 0;
-+ cmd->src = msm_virt_to_dma(chip,
-+ &dma_buffer->data.nandc11_addr1);
-+ cmd->dst = NC11(MSM_NAND_ADDR1);
-+ cmd->len = 4;
-+ cmd++;
-+
-+ /* Enable CS0 for NC01 */
-+ cmd->cmd = 0;
-+ cmd->src = msm_virt_to_dma(chip,
-+ &dma_buffer->data.chipsel_cs0);
-+ cmd->dst =
-+ NC01(MSM_NAND_FLASH_CHIP_SELECT);
-+ cmd->len = 4;
-+ cmd++;
-+
-+ /* Enable CS1 for NC10 */
-+ cmd->cmd = 0;
-+ cmd->src = msm_virt_to_dma(chip,
-+ &dma_buffer->data.chipsel_cs1);
-+ cmd->dst =
-+ NC10(MSM_NAND_FLASH_CHIP_SELECT);
-+ cmd->len = 4;
-+ cmd++;
-+
-+ /* config DEV0_CFG0 & CFG1 for CS0 */
-+ cmd->cmd = 0;
-+ cmd->src = msm_virt_to_dma(chip,
-+ &dma_buffer->data.cfg0);
-+ cmd->dst = NC01(MSM_NAND_DEV0_CFG0);
-+ cmd->len = 8;
-+ cmd++;
-+
-+ /* config DEV1_CFG0 & CFG1 for CS1 */
-+ cmd->cmd = 0;
-+ cmd->src = msm_virt_to_dma(chip,
-+ &dma_buffer->data.cfg0);
-+ cmd->dst = NC10(MSM_NAND_DEV1_CFG0);
-+ cmd->len = 8;
-+ cmd++;
-+ }
-+
-+ dma_buffer->data.ecccfg = chip->ecc_buf_cfg;
-+ cmd->cmd = 0;
-+ cmd->src = msm_virt_to_dma(chip,
-+ &dma_buffer->data.ecccfg);
-+ cmd->dst = NC11(MSM_NAND_EBI2_ECC_BUF_CFG);
-+ cmd->len = 4;
-+ cmd++;
-+
-+ /* if 'only' the last code word */
-+ if (n == cwperpage - 1) {
-+ /* MASK CMD ACK/REQ --> NC01 (0x53C)*/
-+ cmd->cmd = 0;
-+ cmd->src = msm_virt_to_dma(chip,
-+ &dma_buffer->
-+ data.adm_mux_cmd_ack_req_nc01);
-+ cmd->dst = EBI2_NAND_ADM_MUX;
-+ cmd->len = 4;
-+ cmd++;
-+
-+ /* CMD */
-+ cmd->cmd = DST_CRCI_NAND_CMD;
-+ cmd->src = msm_virt_to_dma(chip,
-+ &dma_buffer->data.cmd);
-+ cmd->dst = NC10(MSM_NAND_FLASH_CMD);
-+ cmd->len = 4;
-+ cmd++;
-+
-+ /* NC10 --> ADDR0 ( 0x0 ) */
-+ cmd->cmd = 0;
-+ cmd->src = msm_virt_to_dma(chip,
-+ &dma_buffer->data.nandc10_addr0);
-+ cmd->dst = NC10(MSM_NAND_ADDR0);
-+ cmd->len = 4;
-+ cmd++;
-+
-+ /* kick the execute reg for NC10 */
-+ cmd->cmd = 0;
-+ cmd->src = msm_virt_to_dma(chip,
-+ &dma_buffer->data.exec);
-+ cmd->dst = NC10(MSM_NAND_EXEC_CMD);
-+ cmd->len = 4;
-+ cmd++;
-+
-+ /* MASK DATA ACK/REQ --> NC01 (0xA3C)*/
-+ cmd->cmd = 0;
-+ cmd->src = msm_virt_to_dma(chip,
-+ &dma_buffer->
-+ data.adm_mux_data_ack_req_nc01);
-+ cmd->dst = EBI2_NAND_ADM_MUX;
-+ cmd->len = 4;
-+ cmd++;
-+
-+ /* block on data ready from NC10, then
-+ * read the status register
-+ */
-+ cmd->cmd = SRC_CRCI_NAND_DATA;
-+ cmd->src = NC10(MSM_NAND_FLASH_STATUS);
-+ cmd->dst = msm_virt_to_dma(chip,
-+ &dma_buffer->data.result[n]);
-+ /* MSM_NAND_FLASH_STATUS +
-+ * MSM_NAND_BUFFER_STATUS
-+ */
-+ cmd->len = 8;
-+ cmd++;
-+ } else {
-+ /* NC01 --> ADDR0 */
-+ cmd->cmd = 0;
-+ cmd->src = msm_virt_to_dma(chip,
-+ &dma_buffer->data.nandc01_addr0);
-+ cmd->dst = NC01(MSM_NAND_ADDR0);
-+ cmd->len = 4;
-+ cmd++;
-+
-+ /* NC10 --> ADDR1 */
-+ cmd->cmd = 0;
-+ cmd->src = msm_virt_to_dma(chip,
-+ &dma_buffer->data.nandc10_addr0);
-+ cmd->dst = NC10(MSM_NAND_ADDR0);
-+ cmd->len = 4;
-+ cmd++;
-+
-+ /* MASK CMD ACK/REQ --> NC10 (0xF14)*/
-+ cmd->cmd = 0;
-+ cmd->src = msm_virt_to_dma(chip,
-+ &dma_buffer->
-+ data.adm_mux_cmd_ack_req_nc10);
-+ cmd->dst = EBI2_NAND_ADM_MUX;
-+ cmd->len = 4;
-+ cmd++;
-+
-+ /* CMD */
-+ cmd->cmd = DST_CRCI_NAND_CMD;
-+ cmd->src = msm_virt_to_dma(chip,
-+ &dma_buffer->data.cmd);
-+ cmd->dst = NC01(MSM_NAND_FLASH_CMD);
-+ cmd->len = 4;
-+ cmd++;
-+
-+ /* kick the execute register for NC01*/
-+ cmd->cmd = 0;
-+ cmd->src = msm_virt_to_dma(chip,
-+ &dma_buffer->data.exec);
-+ cmd->dst = NC01(MSM_NAND_EXEC_CMD);
-+ cmd->len = 4;
-+ cmd++;
-+ }
-+ }
-+
-+ /* read data block
-+ * (only valid if status says success)
-+ */
-+ if (ops->datbuf || (ops->oobbuf &&
-+ ops->mode != MTD_OPS_AUTO_OOB)) {
-+ if (ops->mode != MTD_OPS_RAW)
-+ sectordatasize = (n < (cwperpage - 1))
-+ ? 516 : (512 - ((cwperpage - 1) << 2));
-+ else
-+ sectordatasize = chip->cw_size;
-+
-+ if (n % 2 == 0) {
-+ /* MASK DATA ACK/REQ --> NC10 (0xF28)*/
-+ cmd->cmd = 0;
-+ cmd->src = msm_virt_to_dma(chip,
-+ &dma_buffer->
-+ data.adm_mux_data_ack_req_nc10);
-+ cmd->dst = EBI2_NAND_ADM_MUX;
-+ cmd->len = 4;
-+ cmd++;
-+
-+ /* block on data ready from NC01, then
-+ * read the status register
-+ */
-+ cmd->cmd = SRC_CRCI_NAND_DATA;
-+ cmd->src = NC01(MSM_NAND_FLASH_STATUS);
-+ cmd->dst = msm_virt_to_dma(chip,
-+ &dma_buffer->data.result[n]);
-+ /* MSM_NAND_FLASH_STATUS +
-+ * MSM_NAND_BUFFER_STATUS
-+ */
-+ cmd->len = 8;
-+ cmd++;
-+
-+ /* MASK CMD ACK/REQ --> NC01 (0x53C)*/
-+ cmd->cmd = 0;
-+ cmd->src = msm_virt_to_dma(chip,
-+ &dma_buffer->
-+ data.adm_mux_cmd_ack_req_nc01);
-+ cmd->dst = EBI2_NAND_ADM_MUX;
-+ cmd->len = 4;
-+ cmd++;
-+
-+ /* CMD */
-+ cmd->cmd = DST_CRCI_NAND_CMD;
-+ cmd->src = msm_virt_to_dma(chip,
-+ &dma_buffer->data.cmd);
-+ cmd->dst = NC10(MSM_NAND_FLASH_CMD);
-+ cmd->len = 4;
-+ cmd++;
-+
-+ /* kick the execute register for NC10 */
-+ cmd->cmd = 0;
-+ cmd->src = msm_virt_to_dma(chip,
-+ &dma_buffer->data.exec);
-+ cmd->dst = NC10(MSM_NAND_EXEC_CMD);
-+ cmd->len = 4;
-+ cmd++;
-+
-+ /* Read only when there is data
-+ * buffer
-+ */
-+ if (ops->datbuf) {
-+ cmd->cmd = 0;
-+ cmd->src =
-+ NC01(MSM_NAND_FLASH_BUFFER);
-+ cmd->dst = data_dma_addr_curr;
-+ data_dma_addr_curr +=
-+ sectordatasize;
-+ cmd->len = sectordatasize;
-+ cmd++;
-+ }
-+ } else {
-+ /* MASK DATA ACK/REQ -->
-+ * NC01 (0xA3C)
-+ */
-+ cmd->cmd = 0;
-+ cmd->src = msm_virt_to_dma(chip,
-+ &dma_buffer->
-+ data.adm_mux_data_ack_req_nc01);
-+ cmd->dst = EBI2_NAND_ADM_MUX;
-+ cmd->len = 4;
-+ cmd++;
-+
-+ /* block on data ready from NC10
-+ * then read the status register
-+ */
-+ cmd->cmd = SRC_CRCI_NAND_DATA;
-+ cmd->src =
-+ NC10(MSM_NAND_FLASH_STATUS);
-+ cmd->dst = msm_virt_to_dma(chip,
-+ &dma_buffer->data.result[n]);
-+ /* MSM_NAND_FLASH_STATUS +
-+ * MSM_NAND_BUFFER_STATUS
-+ */
-+ cmd->len = 8;
-+ cmd++;
-+ if (n != cwperpage - 1) {
-+ /* MASK CMD ACK/REQ -->
-+ * NC10 (0xF14)
-+ */
-+ cmd->cmd = 0;
-+ cmd->src =
-+ msm_virt_to_dma(chip,
-+ &dma_buffer->
-+ data.adm_mux_cmd_ack_req_nc10);
-+ cmd->dst = EBI2_NAND_ADM_MUX;
-+ cmd->len = 4;
-+ cmd++;
-+
-+ /* CMD */
-+ cmd->cmd = DST_CRCI_NAND_CMD;
-+ cmd->src = msm_virt_to_dma(chip,
-+ &dma_buffer->data.cmd);
-+ cmd->dst =
-+ NC01(MSM_NAND_FLASH_CMD);
-+ cmd->len = 4;
-+ cmd++;
-+
-+ /* EXEC */
-+ cmd->cmd = 0;
-+ cmd->src = msm_virt_to_dma(chip,
-+ &dma_buffer->data.exec);
-+ cmd->dst =
-+ NC01(MSM_NAND_EXEC_CMD);
-+ cmd->len = 4;
-+ cmd++;
-+ }
-+
-+ /* Read only when there is data
-+ * buffer
-+ */
-+ if (ops->datbuf) {
-+ cmd->cmd = 0;
-+ cmd->src =
-+ NC10(MSM_NAND_FLASH_BUFFER);
-+ cmd->dst = data_dma_addr_curr;
-+ data_dma_addr_curr +=
-+ sectordatasize;
-+ cmd->len = sectordatasize;
-+ cmd++;
-+ }
-+ }
-+ }
-+
-+ if (ops->oobbuf && (n == (cwperpage - 1)
-+ || ops->mode != MTD_OPS_AUTO_OOB)) {
-+ cmd->cmd = 0;
-+ if (n == (cwperpage - 1)) {
-+ /* Use NC10 for reading the
-+ * last codeword!!!
-+ */
-+ cmd->src = NC10(MSM_NAND_FLASH_BUFFER) +
-+ (512 - ((cwperpage - 1) << 2));
-+ sectoroobsize = (cwperpage << 2);
-+ if (ops->mode != MTD_OPS_AUTO_OOB)
-+ sectoroobsize +=
-+ chip->ecc_parity_bytes;
-+ } else {
-+ if (n % 2 == 0)
-+ cmd->src =
-+ NC01(MSM_NAND_FLASH_BUFFER)
-+ + 516;
-+ else
-+ cmd->src =
-+ NC10(MSM_NAND_FLASH_BUFFER)
-+ + 516;
-+ sectoroobsize = chip->ecc_parity_bytes;
-+ }
-+ cmd->dst = oob_dma_addr_curr;
-+ if (sectoroobsize < oob_len)
-+ cmd->len = sectoroobsize;
-+ else
-+ cmd->len = oob_len;
-+ oob_dma_addr_curr += cmd->len;
-+ oob_len -= cmd->len;
-+ if (cmd->len > 0)
-+ cmd++;
-+ }
-+ }
-+ /* ADM --> Default mux state (0xFC0) */
-+ cmd->cmd = 0;
-+ cmd->src = msm_virt_to_dma(chip,
-+ &dma_buffer->data.adm_default_mux);
-+ cmd->dst = EBI2_NAND_ADM_MUX;
-+ cmd->len = 4;
-+ cmd++;
-+
-+ if (!interleave_enable) {
-+ cmd->cmd = 0;
-+ cmd->src = msm_virt_to_dma(chip,
-+ &dma_buffer->data.nc10_flash_dev_cmd_vld_default);
-+ cmd->dst = NC10(MSM_NAND_DEV_CMD_VLD);
-+ cmd->len = 4;
-+ cmd++;
-+
-+ cmd->cmd = 0;
-+ cmd->src = msm_virt_to_dma(chip,
-+ &dma_buffer->data.nc10_flash_dev_cmd1_default);
-+ cmd->dst = NC10(MSM_NAND_DEV_CMD1);
-+ cmd->len = 4;
-+ cmd++;
-+ } else {
-+ /* disable CS1 */
-+ cmd->cmd = 0;
-+ cmd->src = msm_virt_to_dma(chip,
-+ &dma_buffer->data.default_ebi2_chip_select_cfg0);
-+ cmd->dst = EBI2_CHIP_SELECT_CFG0;
-+ cmd->len = 4;
-+ cmd++;
-+ }
-+
-+ BUILD_BUG_ON(16 * 6 + 20 != ARRAY_SIZE(dma_buffer->cmd));
-+ BUG_ON(cmd - dma_buffer->cmd > ARRAY_SIZE(dma_buffer->cmd));
-+ dma_buffer->cmd[0].cmd |= CMD_OCB;
-+ cmd[-1].cmd |= CMD_OCU | CMD_LC;
-+
-+ dma_buffer->cmdptr =
-+ (msm_virt_to_dma(chip, dma_buffer->cmd) >> 3)
-+ | CMD_PTR_LP;
-+
-+ mb();
-+ msm_dmov_exec_cmd(chip->dma_channel,
-+ DMOV_CMD_PTR_LIST | DMOV_CMD_ADDR(msm_virt_to_dma(chip,
-+ &dma_buffer->cmdptr)));
-+ mb();
-+
-+ /* if any of the writes failed (0x10), or there
-+ * was a protection violation (0x100), we lose
-+ */
-+ pageerr = rawerr = 0;
-+ for (n = start_sector; n < cwperpage; n++) {
-+ if (dma_buffer->data.result[n].flash_status & 0x110) {
-+ rawerr = -EIO;
-+ break;
-+ }
-+ }
-+ if (rawerr) {
-+ if (ops->datbuf && ops->mode != MTD_OPS_RAW) {
-+ uint8_t *datbuf = ops->datbuf +
-+ pages_read * mtd->writesize;
-+
-+ dma_sync_single_for_cpu(chip->dev,
-+ data_dma_addr_curr-mtd->writesize,
-+ mtd->writesize, DMA_BIDIRECTIONAL);
-+
-+ for (n = 0; n < mtd->writesize; n++) {
-+ /* empty blocks read 0x54 at
-+ * these offsets
-+ */
-+ if ((n % 516 == 3 || n % 516 == 175)
-+ && datbuf[n] == 0x54)
-+ datbuf[n] = 0xff;
-+ if (datbuf[n] != 0xff) {
-+ pageerr = rawerr;
-+ break;
-+ }
-+ }
-+
-+ dma_sync_single_for_device(chip->dev,
-+ data_dma_addr_curr-mtd->writesize,
-+ mtd->writesize, DMA_BIDIRECTIONAL);
-+
-+ }
-+ if (ops->oobbuf) {
-+ dma_sync_single_for_cpu(chip->dev,
-+ oob_dma_addr_curr - (ops->ooblen - oob_len),
-+ ops->ooblen - oob_len, DMA_BIDIRECTIONAL);
-+
-+ for (n = 0; n < ops->ooblen; n++) {
-+ if (ops->oobbuf[n] != 0xff) {
-+ pageerr = rawerr;
-+ break;
-+ }
-+ }
-+
-+ dma_sync_single_for_device(chip->dev,
-+ oob_dma_addr_curr - (ops->ooblen - oob_len),
-+ ops->ooblen - oob_len, DMA_BIDIRECTIONAL);
-+ }
-+ }
-+ if (pageerr) {
-+ for (n = start_sector; n < cwperpage; n++) {
-+ if (dma_buffer->data.result[n].buffer_status
-+ & chip->uncorrectable_bit_mask) {
-+ /* not thread safe */
-+ mtd->ecc_stats.failed++;
-+ pageerr = -EBADMSG;
-+ break;
-+ }
-+ }
-+ }
-+ if (!rawerr) { /* check for corretable errors */
-+ for (n = start_sector; n < cwperpage; n++) {
-+ ecc_errors = dma_buffer->data.
-+ result[n].buffer_status
-+ & chip->num_err_mask;
-+ if (ecc_errors) {
-+ total_ecc_errors += ecc_errors;
-+ /* not thread safe */
-+ mtd->ecc_stats.corrected += ecc_errors;
-+ if (ecc_errors > 1)
-+ pageerr = -EUCLEAN;
-+ }
-+ }
-+ }
-+ if (pageerr && (pageerr != -EUCLEAN || err == 0))
-+ err = pageerr;
-+
-+#if VERBOSE
-+ if (rawerr && !pageerr) {
-+ pr_err("msm_nand_read_oob_dualnandc "
-+ "%llx %x %x empty page\n",
-+ (loff_t)page * mtd->writesize, ops->len,
-+ ops->ooblen);
-+ } else {
-+ for (n = start_sector; n < cwperpage; n++) {
-+ if (n%2) {
-+ pr_info("NC10: flash_status[%d] = %x, "
-+ "buffr_status[%d] = %x\n",
-+ n, dma_buffer->
-+ data.result[n].flash_status,
-+ n, dma_buffer->
-+ data.result[n].buffer_status);
-+ } else {
-+ pr_info("NC01: flash_status[%d] = %x, "
-+ "buffr_status[%d] = %x\n",
-+ n, dma_buffer->
-+ data.result[n].flash_status,
-+ n, dma_buffer->
-+ data.result[n].buffer_status);
-+ }
-+ }
-+ }
-+#endif
-+ if (err && err != -EUCLEAN && err != -EBADMSG)
-+ break;
-+ pages_read++;
-+ page++;
-+ }
-+
-+ msm_nand_release_dma_buffer(chip, dma_buffer, sizeof(*dma_buffer));
-+
-+ if (ops->oobbuf) {
-+ dma_unmap_page(chip->dev, oob_dma_addr,
-+ ops->ooblen, DMA_FROM_DEVICE);
-+ }
-+err_dma_map_oobbuf_failed:
-+ if (ops->datbuf) {
-+ dma_unmap_page(chip->dev, data_dma_addr,
-+ ops->len, DMA_BIDIRECTIONAL);
-+ }
-+
-+ if (ops->mode != MTD_OPS_RAW)
-+ ops->retlen = mtd->writesize * pages_read;
-+ else
-+ ops->retlen = (mtd->writesize + mtd->oobsize) *
-+ pages_read;
-+ ops->oobretlen = ops->ooblen - oob_len;
-+ if (err)
-+ pr_err("msm_nand_read_oob_dualnandc "
-+ "%llx %x %x failed %d, corrected %d\n",
-+ from, ops->datbuf ? ops->len : 0, ops->ooblen, err,
-+ total_ecc_errors);
-+#if VERBOSE
-+ pr_info("\n%s: ret %d, retlen %d oobretlen %d\n",
-+ __func__, err, ops->retlen, ops->oobretlen);
-+
-+ pr_info("==================================================="
-+ "==========\n");
-+#endif
-+ return err;
-+}
-+
-+static int
-+msm_nand_read(struct mtd_info *mtd, loff_t from, size_t len,
-+ size_t *retlen, u_char *buf)
-+{
-+ int ret;
-+ struct mtd_ecc_stats stats;
-+ struct mtd_oob_ops ops;
-+ int (*read_oob)(struct mtd_info *, loff_t, struct mtd_oob_ops *);
-+
-+ if (!dual_nand_ctlr_present)
-+ read_oob = msm_nand_read_oob;
-+ else
-+ read_oob = msm_nand_read_oob_dualnandc;
-+
-+ ops.mode = MTD_OPS_PLACE_OOB;
-+ ops.retlen = 0;
-+ ops.ooblen = 0;
-+ ops.oobbuf = NULL;
-+ ret = 0;
-+ *retlen = 0;
-+ stats = mtd->ecc_stats;
-+
-+ if ((from & (mtd->writesize - 1)) == 0 && len == mtd->writesize) {
-+ /* reading a page on page boundary */
-+ ops.len = len;
-+ ops.datbuf = buf;
-+ ret = read_oob(mtd, from, &ops);
-+ *retlen = ops.retlen;
-+ } else if (len > 0) {
-+ /* reading any size on any offset. partial page is supported */
-+ u8 *bounce_buf;
-+ loff_t aligned_from;
-+ loff_t offset;
-+ size_t actual_len;
-+
-+ bounce_buf = kmalloc(mtd->writesize, GFP_KERNEL);
-+ if (!bounce_buf) {
-+ pr_err("%s: could not allocate memory\n", __func__);
-+ ret = -ENOMEM;
-+ goto out;
-+ }
-+
-+ ops.len = mtd->writesize;
-+ offset = from & (mtd->writesize - 1);
-+ aligned_from = from - offset;
-+
-+ for (;;) {
-+ int no_copy;
-+
-+ actual_len = mtd->writesize - offset;
-+ if (actual_len > len)
-+ actual_len = len;
-+
-+ no_copy = (offset == 0 && actual_len == mtd->writesize);
-+ ops.datbuf = (no_copy) ? buf : bounce_buf;
-+
-+ /*
-+ * MTD API requires that all the pages are to
-+ * be read even if uncorrectable or
-+ * correctable ECC errors occur.
-+ */
-+ ret = read_oob(mtd, aligned_from, &ops);
-+ if (ret == -EBADMSG || ret == -EUCLEAN)
-+ ret = 0;
-+
-+ if (ret < 0)
-+ break;
-+
-+ if (!no_copy)
-+ memcpy(buf, bounce_buf + offset, actual_len);
-+
-+ len -= actual_len;
-+ *retlen += actual_len;
-+ if (len == 0)
-+ break;
-+
-+ buf += actual_len;
-+ offset = 0;
-+ aligned_from += mtd->writesize;
-+ }
-+
-+ kfree(bounce_buf);
-+ }
-+
-+out:
-+ if (ret)
-+ return ret;
-+
-+ if (mtd->ecc_stats.failed - stats.failed)
-+ return -EBADMSG;
-+
-+ if (mtd->ecc_stats.corrected - stats.corrected)
-+ return -EUCLEAN;
-+
-+ return 0;
-+}
-+
-+static int
-+msm_nand_write_oob(struct mtd_info *mtd, loff_t to, struct mtd_oob_ops *ops)
-+{
-+ struct msm_nand_chip *chip = mtd->priv;
-+ struct {
-+ dmov_s cmd[8 * 7 + 2];
-+ unsigned cmdptr;
-+ struct {
-+ uint32_t cmd;
-+ uint32_t addr0;
-+ uint32_t addr1;
-+ uint32_t chipsel;
-+ uint32_t cfg0;
-+ uint32_t cfg1;
-+ uint32_t eccbchcfg;
-+ uint32_t exec;
-+ uint32_t ecccfg;
-+ uint32_t clrfstatus;
-+ uint32_t clrrstatus;
-+ uint32_t flash_status[8];
-+ } data;
-+ } *dma_buffer;
-+ dmov_s *cmd;
-+ unsigned n;
-+ unsigned page = 0;
-+ uint32_t oob_len;
-+ uint32_t sectordatawritesize;
-+ int err = 0;
-+ dma_addr_t data_dma_addr = 0;
-+ dma_addr_t oob_dma_addr = 0;
-+ dma_addr_t data_dma_addr_curr = 0;
-+ dma_addr_t oob_dma_addr_curr = 0;
-+ uint8_t *dat_bounce_buf = NULL;
-+ uint8_t *oob_bounce_buf = NULL;
-+ unsigned page_count;
-+ unsigned pages_written = 0;
-+ unsigned cwperpage;
-+#if VERBOSE
-+ pr_info("================================================="
-+ "================\n");
-+ pr_info("%s:\nto 0x%llx mode %d\ndatbuf 0x%p datlen 0x%x"
-+ "\noobbuf 0x%p ooblen 0x%x\n",
-+ __func__, to, ops->mode, ops->datbuf, ops->len,
-+ ops->oobbuf, ops->ooblen);
-+#endif
-+
-+ if (mtd->writesize == 2048)
-+ page = to >> 11;
-+
-+ if (mtd->writesize == 4096)
-+ page = to >> 12;
-+
-+ oob_len = ops->ooblen;
-+ cwperpage = (mtd->writesize >> 9);
-+
-+ if (to & (mtd->writesize - 1)) {
-+ pr_err("%s: unsupported to, 0x%llx\n", __func__, to);
-+ return -EINVAL;
-+ }
-+
-+ if (ops->mode != MTD_OPS_RAW) {
-+ if (ops->ooblen != 0 && ops->mode != MTD_OPS_AUTO_OOB) {
-+ pr_err("%s: unsupported ops->mode,%d\n",
-+ __func__, ops->mode);
-+ return -EINVAL;
-+ }
-+ if ((ops->len % mtd->writesize) != 0) {
-+ pr_err("%s: unsupported ops->len, %d\n",
-+ __func__, ops->len);
-+ return -EINVAL;
-+ }
-+ } else {
-+ if ((ops->len % (mtd->writesize + mtd->oobsize)) != 0) {
-+ pr_err("%s: unsupported ops->len, "
-+ "%d for MTD_OPS_RAW mode\n",
-+ __func__, ops->len);
-+ return -EINVAL;
-+ }
-+ }
-+
-+ if (ops->datbuf == NULL) {
-+ pr_err("%s: unsupported ops->datbuf == NULL\n", __func__);
-+ return -EINVAL;
-+ }
-+ if (ops->mode != MTD_OPS_RAW && ops->ooblen != 0 && ops->ooboffs != 0) {
-+ pr_err("%s: unsupported ops->ooboffs, %d\n",
-+ __func__, ops->ooboffs);
-+ return -EINVAL;
-+ }
-+
-+ if (ops->datbuf) {
-+ data_dma_addr_curr = data_dma_addr =
-+ msm_nand_dma_map(chip->dev, ops->datbuf,
-+ ops->len, DMA_TO_DEVICE,
-+ &dat_bounce_buf);
-+ if (dma_mapping_error(chip->dev, data_dma_addr)) {
-+ pr_err("msm_nand_write_oob: failed to get dma addr "
-+ "for %p\n", ops->datbuf);
-+ return -EIO;
-+ }
-+ }
-+ if (ops->oobbuf) {
-+ oob_dma_addr_curr = oob_dma_addr =
-+ msm_nand_dma_map(chip->dev, ops->oobbuf,
-+ ops->ooblen, DMA_TO_DEVICE,
-+ &oob_bounce_buf);
-+ if (dma_mapping_error(chip->dev, oob_dma_addr)) {
-+ pr_err("msm_nand_write_oob: failed to get dma addr "
-+ "for %p\n", ops->oobbuf);
-+ err = -EIO;
-+ goto err_dma_map_oobbuf_failed;
-+ }
-+ }
-+ if (ops->mode != MTD_OPS_RAW)
-+ page_count = ops->len / mtd->writesize;
-+ else
-+ page_count = ops->len / (mtd->writesize + mtd->oobsize);
-+
-+ wait_event(chip->wait_queue, (dma_buffer =
-+ msm_nand_get_dma_buffer(chip, sizeof(*dma_buffer))));
-+
-+ while (page_count-- > 0) {
-+ cmd = dma_buffer->cmd;
-+
-+ if (ops->mode != MTD_OPS_RAW) {
-+ dma_buffer->data.cfg0 = chip->CFG0;
-+ dma_buffer->data.cfg1 = chip->CFG1;
-+ if (enable_bch_ecc)
-+ dma_buffer->data.eccbchcfg = chip->ecc_bch_cfg;
-+ } else {
-+ dma_buffer->data.cfg0 = (chip->CFG0_RAW &
-+ ~(7U << 6)) | ((cwperpage-1) << 6);
-+ dma_buffer->data.cfg1 = chip->CFG1_RAW |
-+ (chip->CFG1 & CFG1_WIDE_FLASH);
-+ }
-+
-+ /* CMD / ADDR0 / ADDR1 / CHIPSEL program values */
-+ dma_buffer->data.cmd = MSM_NAND_CMD_PRG_PAGE;
-+ dma_buffer->data.addr0 = page << 16;
-+ dma_buffer->data.addr1 = (page >> 16) & 0xff;
-+ /* chipsel_0 + enable DM interface */
-+ dma_buffer->data.chipsel = 0 | 4;
-+
-+
-+ /* GO bit for the EXEC register */
-+ dma_buffer->data.exec = 1;
-+ dma_buffer->data.clrfstatus = 0x00000020;
-+ dma_buffer->data.clrrstatus = 0x000000C0;
-+
-+ BUILD_BUG_ON(8 != ARRAY_SIZE(dma_buffer->data.flash_status));
-+
-+ for (n = 0; n < cwperpage ; n++) {
-+ /* status return words */
-+ dma_buffer->data.flash_status[n] = 0xeeeeeeee;
-+ /* block on cmd ready, then
-+ * write CMD / ADDR0 / ADDR1 / CHIPSEL regs in a burst
-+ */
-+ cmd->cmd = DST_CRCI_NAND_CMD;
-+ cmd->src =
-+ msm_virt_to_dma(chip, &dma_buffer->data.cmd);
-+ cmd->dst = MSM_NAND_FLASH_CMD;
-+ if (n == 0)
-+ cmd->len = 16;
-+ else
-+ cmd->len = 4;
-+ cmd++;
-+
-+ if (n == 0) {
-+ cmd->cmd = 0;
-+ cmd->src = msm_virt_to_dma(chip,
-+ &dma_buffer->data.cfg0);
-+ cmd->dst = MSM_NAND_DEV0_CFG0;
-+ if (enable_bch_ecc)
-+ cmd->len = 12;
-+ else
-+ cmd->len = 8;
-+ cmd++;
-+
-+ dma_buffer->data.ecccfg = chip->ecc_buf_cfg;
-+ cmd->cmd = 0;
-+ cmd->src = msm_virt_to_dma(chip,
-+ &dma_buffer->data.ecccfg);
-+ cmd->dst = MSM_NAND_EBI2_ECC_BUF_CFG;
-+ cmd->len = 4;
-+ cmd++;
-+ }
-+
-+ /* write data block */
-+ if (ops->mode != MTD_OPS_RAW) {
-+ if (!boot_layout)
-+ sectordatawritesize = (n < (cwperpage - 1)) ?
-+ 516 : (512 - ((cwperpage - 1) << 2));
-+ else
-+ sectordatawritesize = 512;
-+ } else {
-+ sectordatawritesize = chip->cw_size;
-+ }
-+
-+ cmd->cmd = 0;
-+ cmd->src = data_dma_addr_curr;
-+ data_dma_addr_curr += sectordatawritesize;
-+ cmd->dst = MSM_NAND_FLASH_BUFFER;
-+ cmd->len = sectordatawritesize;
-+ cmd++;
-+
-+ if (ops->oobbuf) {
-+ if (n == (cwperpage - 1)) {
-+ cmd->cmd = 0;
-+ cmd->src = oob_dma_addr_curr;
-+ cmd->dst = MSM_NAND_FLASH_BUFFER +
-+ (512 - ((cwperpage - 1) << 2));
-+ if ((cwperpage << 2) < oob_len)
-+ cmd->len = (cwperpage << 2);
-+ else
-+ cmd->len = oob_len;
-+ oob_dma_addr_curr += cmd->len;
-+ oob_len -= cmd->len;
-+ if (cmd->len > 0)
-+ cmd++;
-+ }
-+ if (ops->mode != MTD_OPS_AUTO_OOB) {
-+ /* skip ecc bytes in oobbuf */
-+ if (oob_len < chip->ecc_parity_bytes) {
-+ oob_dma_addr_curr +=
-+ chip->ecc_parity_bytes;
-+ oob_len -=
-+ chip->ecc_parity_bytes;
-+ } else {
-+ oob_dma_addr_curr += oob_len;
-+ oob_len = 0;
-+ }
-+ }
-+ }
-+
-+ /* kick the execute register */
-+ cmd->cmd = 0;
-+ cmd->src =
-+ msm_virt_to_dma(chip, &dma_buffer->data.exec);
-+ cmd->dst = MSM_NAND_EXEC_CMD;
-+ cmd->len = 4;
-+ cmd++;
-+
-+ /* block on data ready, then
-+ * read the status register
-+ */
-+ cmd->cmd = SRC_CRCI_NAND_DATA;
-+ cmd->src = MSM_NAND_FLASH_STATUS;
-+ cmd->dst = msm_virt_to_dma(chip,
-+ &dma_buffer->data.flash_status[n]);
-+ cmd->len = 4;
-+ cmd++;
-+
-+ cmd->cmd = 0;
-+ cmd->src = msm_virt_to_dma(chip,
-+ &dma_buffer->data.clrfstatus);
-+ cmd->dst = MSM_NAND_FLASH_STATUS;
-+ cmd->len = 4;
-+ cmd++;
-+
-+ cmd->cmd = 0;
-+ cmd->src = msm_virt_to_dma(chip,
-+ &dma_buffer->data.clrrstatus);
-+ cmd->dst = MSM_NAND_READ_STATUS;
-+ cmd->len = 4;
-+ cmd++;
-+
-+ }
-+
-+ dma_buffer->cmd[0].cmd |= CMD_OCB;
-+ cmd[-1].cmd |= CMD_OCU | CMD_LC;
-+ BUILD_BUG_ON(8 * 7 + 2 != ARRAY_SIZE(dma_buffer->cmd));
-+ BUG_ON(cmd - dma_buffer->cmd > ARRAY_SIZE(dma_buffer->cmd));
-+ dma_buffer->cmdptr =
-+ (msm_virt_to_dma(chip, dma_buffer->cmd) >> 3) |
-+ CMD_PTR_LP;
-+
-+ mb();
-+ msm_dmov_exec_cmd(chip->dma_channel,
-+ DMOV_CMD_PTR_LIST | DMOV_CMD_ADDR(
-+ msm_virt_to_dma(chip, &dma_buffer->cmdptr)));
-+ mb();
-+
-+ /* if any of the writes failed (0x10), or there was a
-+ * protection violation (0x100), or the program success
-+ * bit (0x80) is unset, we lose
-+ */
-+ err = 0;
-+ for (n = 0; n < cwperpage; n++) {
-+ if (dma_buffer->data.flash_status[n] & 0x110) {
-+ err = -EIO;
-+ break;
-+ }
-+ if (!(dma_buffer->data.flash_status[n] & 0x80)) {
-+ err = -EIO;
-+ break;
-+ }
-+ }
-+
-+#if VERBOSE
-+ for (n = 0; n < cwperpage; n++)
-+ pr_info("write pg %d: flash_status[%d] = %x\n", page,
-+ n, dma_buffer->data.flash_status[n]);
-+
-+#endif
-+ if (err)
-+ break;
-+ pages_written++;
-+ page++;
-+ }
-+ if (ops->mode != MTD_OPS_RAW)
-+ ops->retlen = mtd->writesize * pages_written;
-+ else
-+ ops->retlen = (mtd->writesize + mtd->oobsize) * pages_written;
-+
-+ ops->oobretlen = ops->ooblen - oob_len;
-+
-+ msm_nand_release_dma_buffer(chip, dma_buffer, sizeof(*dma_buffer));
-+
-+ if (ops->oobbuf) {
-+ msm_nand_dma_unmap(chip->dev, oob_dma_addr,
-+ ops->ooblen, DMA_TO_DEVICE,
-+ ops->oobbuf, oob_bounce_buf);
-+ }
-+err_dma_map_oobbuf_failed:
-+ if (ops->datbuf) {
-+ msm_nand_dma_unmap(chip->dev, data_dma_addr, ops->len,
-+ DMA_TO_DEVICE, ops->datbuf,
-+ dat_bounce_buf);
-+ }
-+ if (err)
-+ pr_err("msm_nand_write_oob %llx %x %x failed %d\n",
-+ to, ops->len, ops->ooblen, err);
-+
-+#if VERBOSE
-+ pr_info("\n%s: ret %d, retlen %d oobretlen %d\n",
-+ __func__, err, ops->retlen, ops->oobretlen);
-+
-+ pr_info("==================================================="
-+ "==============\n");
-+#endif
-+ return err;
-+}
-+
-+static int
-+msm_nand_write_oob_dualnandc(struct mtd_info *mtd, loff_t to,
-+ struct mtd_oob_ops *ops)
-+{
-+ struct msm_nand_chip *chip = mtd->priv;
-+ struct {
-+ dmov_s cmd[16 * 6 + 18];
-+ unsigned cmdptr;
-+ struct {
-+ uint32_t cmd;
-+ uint32_t nandc01_addr0;
-+ uint32_t nandc10_addr0;
-+ uint32_t nandc11_addr1;
-+ uint32_t chipsel_cs0;
-+ uint32_t chipsel_cs1;
-+ uint32_t cfg0;
-+ uint32_t cfg1;
-+ uint32_t eccbchcfg;
-+ uint32_t exec;
-+ uint32_t ecccfg;
-+ uint32_t cfg0_nc01;
-+ uint32_t ebi2_chip_select_cfg0;
-+ uint32_t adm_mux_data_ack_req_nc01;
-+ uint32_t adm_mux_cmd_ack_req_nc01;
-+ uint32_t adm_mux_data_ack_req_nc10;
-+ uint32_t adm_mux_cmd_ack_req_nc10;
-+ uint32_t adm_default_mux;
-+ uint32_t default_ebi2_chip_select_cfg0;
-+ uint32_t nc01_flash_dev_cmd_vld;
-+ uint32_t nc10_flash_dev_cmd0;
-+ uint32_t nc01_flash_dev_cmd_vld_default;
-+ uint32_t nc10_flash_dev_cmd0_default;
-+ uint32_t flash_status[16];
-+ uint32_t clrfstatus;
-+ uint32_t clrrstatus;
-+ } data;
-+ } *dma_buffer;
-+ dmov_s *cmd;
-+ unsigned n;
-+ unsigned page = 0;
-+ uint32_t oob_len;
-+ uint32_t sectordatawritesize;
-+ int err = 0;
-+ dma_addr_t data_dma_addr = 0;
-+ dma_addr_t oob_dma_addr = 0;
-+ dma_addr_t data_dma_addr_curr = 0;
-+ dma_addr_t oob_dma_addr_curr = 0;
-+ unsigned page_count;
-+ unsigned pages_written = 0;
-+ unsigned cwperpage;
-+ unsigned cw_offset = chip->cw_size;
-+#if VERBOSE
-+ pr_info("================================================="
-+ "============\n");
-+ pr_info("%s:\nto 0x%llx mode %d\ndatbuf 0x%p datlen 0x%x"
-+ "\noobbuf 0x%p ooblen 0x%x\n\n",
-+ __func__, to, ops->mode, ops->datbuf, ops->len,
-+ ops->oobbuf, ops->ooblen);
-+#endif
-+
-+ if (mtd->writesize == 2048)
-+ page = to >> 11;
-+
-+ if (mtd->writesize == 4096)
-+ page = to >> 12;
-+
-+ if (interleave_enable)
-+ page = (to >> 1) >> 12;
-+
-+ oob_len = ops->ooblen;
-+ cwperpage = (mtd->writesize >> 9);
-+
-+ if (to & (mtd->writesize - 1)) {
-+ pr_err("%s: unsupported to, 0x%llx\n", __func__, to);
-+ return -EINVAL;
-+ }
-+
-+ if (ops->mode != MTD_OPS_RAW) {
-+ if (ops->ooblen != 0 && ops->mode != MTD_OPS_AUTO_OOB) {
-+ pr_err("%s: unsupported ops->mode,%d\n",
-+ __func__, ops->mode);
-+ return -EINVAL;
-+ }
-+ if ((ops->len % mtd->writesize) != 0) {
-+ pr_err("%s: unsupported ops->len, %d\n",
-+ __func__, ops->len);
-+ return -EINVAL;
-+ }
-+ } else {
-+ if ((ops->len % (mtd->writesize + mtd->oobsize)) != 0) {
-+ pr_err("%s: unsupported ops->len, "
-+ "%d for MTD_OPS_RAW mode\n",
-+ __func__, ops->len);
-+ return -EINVAL;
-+ }
-+ }
-+
-+ if (ops->datbuf == NULL) {
-+ pr_err("%s: unsupported ops->datbuf == NULL\n", __func__);
-+ return -EINVAL;
-+ }
-+
-+ if (ops->mode != MTD_OPS_RAW && ops->ooblen != 0 && ops->ooboffs != 0) {
-+ pr_err("%s: unsupported ops->ooboffs, %d\n",
-+ __func__, ops->ooboffs);
-+ return -EINVAL;
-+ }
-+
-+ if (ops->datbuf) {
-+ data_dma_addr_curr = data_dma_addr =
-+ msm_nand_dma_map(chip->dev, ops->datbuf,
-+ ops->len, DMA_TO_DEVICE, NULL);
-+ if (dma_mapping_error(chip->dev, data_dma_addr)) {
-+ pr_err("msm_nand_write_oob_dualnandc:"
-+ "failed to get dma addr "
-+ "for %p\n", ops->datbuf);
-+ return -EIO;
-+ }
-+ }
-+ if (ops->oobbuf) {
-+ oob_dma_addr_curr = oob_dma_addr =
-+ msm_nand_dma_map(chip->dev, ops->oobbuf,
-+ ops->ooblen, DMA_TO_DEVICE, NULL);
-+ if (dma_mapping_error(chip->dev, oob_dma_addr)) {
-+ pr_err("msm_nand_write_oob_dualnandc:"
-+ "failed to get dma addr "
-+ "for %p\n", ops->oobbuf);
-+ err = -EIO;
-+ goto err_dma_map_oobbuf_failed;
-+ }
-+ }
-+ if (ops->mode != MTD_OPS_RAW)
-+ page_count = ops->len / mtd->writesize;
-+ else
-+ page_count = ops->len / (mtd->writesize + mtd->oobsize);
-+
-+ wait_event(chip->wait_queue, (dma_buffer =
-+ msm_nand_get_dma_buffer(chip, sizeof(*dma_buffer))));
-+
-+ if (chip->CFG1 & CFG1_WIDE_FLASH)
-+ cw_offset >>= 1;
-+
-+ dma_buffer->data.ebi2_chip_select_cfg0 = 0x00000805;
-+ dma_buffer->data.adm_mux_data_ack_req_nc01 = 0x00000A3C;
-+ dma_buffer->data.adm_mux_cmd_ack_req_nc01 = 0x0000053C;
-+ dma_buffer->data.adm_mux_data_ack_req_nc10 = 0x00000F28;
-+ dma_buffer->data.adm_mux_cmd_ack_req_nc10 = 0x00000F14;
-+ dma_buffer->data.adm_default_mux = 0x00000FC0;
-+ dma_buffer->data.default_ebi2_chip_select_cfg0 = 0x00000801;
-+ dma_buffer->data.nc01_flash_dev_cmd_vld = 0x9;
-+ dma_buffer->data.nc10_flash_dev_cmd0 = 0x1085D060;
-+ dma_buffer->data.nc01_flash_dev_cmd_vld_default = 0x1D;
-+ dma_buffer->data.nc10_flash_dev_cmd0_default = 0x1080D060;
-+ dma_buffer->data.clrfstatus = 0x00000020;
-+ dma_buffer->data.clrrstatus = 0x000000C0;
-+
-+ while (page_count-- > 0) {
-+ cmd = dma_buffer->cmd;
-+
-+ if (ops->mode != MTD_OPS_RAW) {
-+ dma_buffer->data.cfg0 = ((chip->CFG0 & ~(7U << 6))
-+ & ~(1 << 4)) | ((((cwperpage >> 1)-1)) << 6);
-+ dma_buffer->data.cfg1 = chip->CFG1;
-+ if (enable_bch_ecc)
-+ dma_buffer->data.eccbchcfg = chip->ecc_bch_cfg;
-+ } else {
-+ dma_buffer->data.cfg0 = ((chip->CFG0_RAW &
-+ ~(7U << 6)) & ~(1 << 4)) | (((cwperpage >> 1)-1) << 6);
-+ dma_buffer->data.cfg1 = chip->CFG1_RAW |
-+ (chip->CFG1 & CFG1_WIDE_FLASH);
-+ }
-+
-+ /* Disables the automatic issuing of the read
-+ * status command for first NAND controller.
-+ */
-+ if (!interleave_enable)
-+ dma_buffer->data.cfg0_nc01 = dma_buffer->data.cfg0
-+ | (1 << 4);
-+ else
-+ dma_buffer->data.cfg0 |= (1 << 4);
-+
-+ dma_buffer->data.cmd = MSM_NAND_CMD_PRG_PAGE;
-+ dma_buffer->data.chipsel_cs0 = (1<<4) | 4;
-+ dma_buffer->data.chipsel_cs1 = (1<<4) | 5;
-+
-+ /* GO bit for the EXEC register */
-+ dma_buffer->data.exec = 1;
-+
-+ if (!interleave_enable) {
-+ dma_buffer->data.nandc01_addr0 = (page << 16) | 0x0;
-+ /* NC10 ADDR0 points to the next code word */
-+ dma_buffer->data.nandc10_addr0 =
-+ (page << 16) | cw_offset;
-+ } else {
-+ dma_buffer->data.nandc01_addr0 =
-+ dma_buffer->data.nandc10_addr0 = (page << 16) | 0x0;
-+ }
-+ /* ADDR1 */
-+ dma_buffer->data.nandc11_addr1 = (page >> 16) & 0xff;
-+
-+ BUILD_BUG_ON(16 != ARRAY_SIZE(dma_buffer->data.flash_status));
-+
-+ for (n = 0; n < cwperpage; n++) {
-+ /* status return words */
-+ dma_buffer->data.flash_status[n] = 0xeeeeeeee;
-+
-+ if (n == 0) {
-+ if (!interleave_enable) {
-+ cmd->cmd = 0;
-+ cmd->src = msm_virt_to_dma(chip,
-+ &dma_buffer->
-+ data.nc01_flash_dev_cmd_vld);
-+ cmd->dst = NC01(MSM_NAND_DEV_CMD_VLD);
-+ cmd->len = 4;
-+ cmd++;
-+
-+ cmd->cmd = 0;
-+ cmd->src = msm_virt_to_dma(chip,
-+ &dma_buffer->data.nc10_flash_dev_cmd0);
-+ cmd->dst = NC10(MSM_NAND_DEV_CMD0);
-+ cmd->len = 4;
-+ cmd++;
-+
-+ /* common settings for both NC01 & NC10
-+ * NC01, NC10 --> ADDR1 / CHIPSEL
-+ */
-+ cmd->cmd = 0;
-+ cmd->src = msm_virt_to_dma(chip,
-+ &dma_buffer->data.nandc11_addr1);
-+ cmd->dst = NC11(MSM_NAND_ADDR1);
-+ cmd->len = 8;
-+ cmd++;
-+
-+ /* Disables the automatic issue of the
-+ * read status command after the write
-+ * operation.
-+ */
-+ cmd->cmd = 0;
-+ cmd->src = msm_virt_to_dma(chip,
-+ &dma_buffer->data.cfg0_nc01);
-+ cmd->dst = NC01(MSM_NAND_DEV0_CFG0);
-+ cmd->len = 4;
-+ cmd++;
-+
-+ cmd->cmd = 0;
-+ cmd->src = msm_virt_to_dma(chip,
-+ &dma_buffer->data.cfg0);
-+ cmd->dst = NC10(MSM_NAND_DEV0_CFG0);
-+ cmd->len = 4;
-+ cmd++;
-+
-+ cmd->cmd = 0;
-+ cmd->src = msm_virt_to_dma(chip,
-+ &dma_buffer->data.cfg1);
-+ cmd->dst = NC11(MSM_NAND_DEV0_CFG1);
-+ if (enable_bch_ecc)
-+ cmd->len = 8;
-+ else
-+ cmd->len = 4;
-+ cmd++;
-+ } else {
-+ /* enable CS1 */
-+ cmd->cmd = 0;
-+ cmd->src = msm_virt_to_dma(chip,
-+ &dma_buffer->
-+ data.ebi2_chip_select_cfg0);
-+ cmd->dst = EBI2_CHIP_SELECT_CFG0;
-+ cmd->len = 4;
-+ cmd++;
-+
-+ /* NC11 --> ADDR1 */
-+ cmd->cmd = 0;
-+ cmd->src = msm_virt_to_dma(chip,
-+ &dma_buffer->data.nandc11_addr1);
-+ cmd->dst = NC11(MSM_NAND_ADDR1);
-+ cmd->len = 4;
-+ cmd++;
-+
-+ /* Enable CS0 for NC01 */
-+ cmd->cmd = 0;
-+ cmd->src = msm_virt_to_dma(chip,
-+ &dma_buffer->data.chipsel_cs0);
-+ cmd->dst =
-+ NC01(MSM_NAND_FLASH_CHIP_SELECT);
-+ cmd->len = 4;
-+ cmd++;
-+
-+ /* Enable CS1 for NC10 */
-+ cmd->cmd = 0;
-+ cmd->src = msm_virt_to_dma(chip,
-+ &dma_buffer->data.chipsel_cs1);
-+ cmd->dst =
-+ NC10(MSM_NAND_FLASH_CHIP_SELECT);
-+ cmd->len = 4;
-+ cmd++;
-+
-+ /* config DEV0_CFG0 & CFG1 for CS0 */
-+ cmd->cmd = 0;
-+ cmd->src = msm_virt_to_dma(chip,
-+ &dma_buffer->data.cfg0);
-+ cmd->dst = NC01(MSM_NAND_DEV0_CFG0);
-+ cmd->len = 8;
-+ cmd++;
-+
-+ /* config DEV1_CFG0 & CFG1 for CS1 */
-+ cmd->cmd = 0;
-+ cmd->src = msm_virt_to_dma(chip,
-+ &dma_buffer->data.cfg0);
-+ cmd->dst = NC10(MSM_NAND_DEV1_CFG0);
-+ cmd->len = 8;
-+ cmd++;
-+ }
-+
-+ dma_buffer->data.ecccfg = chip->ecc_buf_cfg;
-+ cmd->cmd = 0;
-+ cmd->src = msm_virt_to_dma(chip,
-+ &dma_buffer->data.ecccfg);
-+ cmd->dst = NC11(MSM_NAND_EBI2_ECC_BUF_CFG);
-+ cmd->len = 4;
-+ cmd++;
-+
-+ /* NC01 --> ADDR0 */
-+ cmd->cmd = 0;
-+ cmd->src = msm_virt_to_dma(chip,
-+ &dma_buffer->data.nandc01_addr0);
-+ cmd->dst = NC01(MSM_NAND_ADDR0);
-+ cmd->len = 4;
-+ cmd++;
-+
-+ /* NC10 --> ADDR0 */
-+ cmd->cmd = 0;
-+ cmd->src = msm_virt_to_dma(chip,
-+ &dma_buffer->data.nandc10_addr0);
-+ cmd->dst = NC10(MSM_NAND_ADDR0);
-+ cmd->len = 4;
-+ cmd++;
-+ }
-+
-+ if (n % 2 == 0) {
-+ /* MASK CMD ACK/REQ --> NC10 (0xF14)*/
-+ cmd->cmd = 0;
-+ cmd->src = msm_virt_to_dma(chip,
-+ &dma_buffer->data.adm_mux_cmd_ack_req_nc10);
-+ cmd->dst = EBI2_NAND_ADM_MUX;
-+ cmd->len = 4;
-+ cmd++;
-+
-+ /* CMD */
-+ cmd->cmd = DST_CRCI_NAND_CMD;
-+ cmd->src = msm_virt_to_dma(chip,
-+ &dma_buffer->data.cmd);
-+ cmd->dst = NC01(MSM_NAND_FLASH_CMD);
-+ cmd->len = 4;
-+ cmd++;
-+ } else {
-+ /* MASK CMD ACK/REQ --> NC01 (0x53C)*/
-+ cmd->cmd = 0;
-+ cmd->src = msm_virt_to_dma(chip,
-+ &dma_buffer->data.adm_mux_cmd_ack_req_nc01);
-+ cmd->dst = EBI2_NAND_ADM_MUX;
-+ cmd->len = 4;
-+ cmd++;
-+
-+ /* CMD */
-+ cmd->cmd = DST_CRCI_NAND_CMD;
-+ cmd->src = msm_virt_to_dma(chip,
-+ &dma_buffer->data.cmd);
-+ cmd->dst = NC10(MSM_NAND_FLASH_CMD);
-+ cmd->len = 4;
-+ cmd++;
-+ }
-+
-+ if (ops->mode != MTD_OPS_RAW)
-+ sectordatawritesize = (n < (cwperpage - 1)) ?
-+ 516 : (512 - ((cwperpage - 1) << 2));
-+ else
-+ sectordatawritesize = chip->cw_size;
-+
-+ cmd->cmd = 0;
-+ cmd->src = data_dma_addr_curr;
-+ data_dma_addr_curr += sectordatawritesize;
-+
-+ if (n % 2 == 0)
-+ cmd->dst = NC01(MSM_NAND_FLASH_BUFFER);
-+ else
-+ cmd->dst = NC10(MSM_NAND_FLASH_BUFFER);
-+ cmd->len = sectordatawritesize;
-+ cmd++;
-+
-+ if (ops->oobbuf) {
-+ if (n == (cwperpage - 1)) {
-+ cmd->cmd = 0;
-+ cmd->src = oob_dma_addr_curr;
-+ cmd->dst = NC10(MSM_NAND_FLASH_BUFFER) +
-+ (512 - ((cwperpage - 1) << 2));
-+ if ((cwperpage << 2) < oob_len)
-+ cmd->len = (cwperpage << 2);
-+ else
-+ cmd->len = oob_len;
-+ oob_dma_addr_curr += cmd->len;
-+ oob_len -= cmd->len;
-+ if (cmd->len > 0)
-+ cmd++;
-+ }
-+ if (ops->mode != MTD_OPS_AUTO_OOB) {
-+ /* skip ecc bytes in oobbuf */
-+ if (oob_len < chip->ecc_parity_bytes) {
-+ oob_dma_addr_curr +=
-+ chip->ecc_parity_bytes;
-+ oob_len -=
-+ chip->ecc_parity_bytes;
-+ } else {
-+ oob_dma_addr_curr += oob_len;
-+ oob_len = 0;
-+ }
-+ }
-+ }
-+
-+ if (n % 2 == 0) {
-+ if (n != 0) {
-+ /* MASK DATA ACK/REQ --> NC01 (0xA3C)*/
-+ cmd->cmd = 0;
-+ cmd->src = msm_virt_to_dma(chip,
-+ &dma_buffer->
-+ data.adm_mux_data_ack_req_nc01);
-+ cmd->dst = EBI2_NAND_ADM_MUX;
-+ cmd->len = 4;
-+ cmd++;
-+
-+ /* block on data ready from NC10, then
-+ * read the status register
-+ */
-+ cmd->cmd = SRC_CRCI_NAND_DATA;
-+ cmd->src = NC10(MSM_NAND_FLASH_STATUS);
-+ cmd->dst = msm_virt_to_dma(chip,
-+ &dma_buffer->data.flash_status[n-1]);
-+ cmd->len = 4;
-+ cmd++;
-+ }
-+ /* kick the NC01 execute register */
-+ cmd->cmd = 0;
-+ cmd->src = msm_virt_to_dma(chip,
-+ &dma_buffer->data.exec);
-+ cmd->dst = NC01(MSM_NAND_EXEC_CMD);
-+ cmd->len = 4;
-+ cmd++;
-+ } else {
-+ /* MASK DATA ACK/REQ --> NC10 (0xF28)*/
-+ cmd->cmd = 0;
-+ cmd->src = msm_virt_to_dma(chip,
-+ &dma_buffer->data.adm_mux_data_ack_req_nc10);
-+ cmd->dst = EBI2_NAND_ADM_MUX;
-+ cmd->len = 4;
-+ cmd++;
-+
-+ /* block on data ready from NC01, then
-+ * read the status register
-+ */
-+ cmd->cmd = SRC_CRCI_NAND_DATA;
-+ cmd->src = NC01(MSM_NAND_FLASH_STATUS);
-+ cmd->dst = msm_virt_to_dma(chip,
-+ &dma_buffer->data.flash_status[n-1]);
-+ cmd->len = 4;
-+ cmd++;
-+
-+ /* kick the execute register */
-+ cmd->cmd = 0;
-+ cmd->src =
-+ msm_virt_to_dma(chip, &dma_buffer->data.exec);
-+ cmd->dst = NC10(MSM_NAND_EXEC_CMD);
-+ cmd->len = 4;
-+ cmd++;
-+ }
-+ }
-+
-+ /* MASK DATA ACK/REQ --> NC01 (0xA3C)*/
-+ cmd->cmd = 0;
-+ cmd->src = msm_virt_to_dma(chip,
-+ &dma_buffer->data.adm_mux_data_ack_req_nc01);
-+ cmd->dst = EBI2_NAND_ADM_MUX;
-+ cmd->len = 4;
-+ cmd++;
-+
-+ /* we should process outstanding request */
-+ /* block on data ready, then
-+ * read the status register
-+ */
-+ cmd->cmd = SRC_CRCI_NAND_DATA;
-+ cmd->src = NC10(MSM_NAND_FLASH_STATUS);
-+ cmd->dst = msm_virt_to_dma(chip,
-+ &dma_buffer->data.flash_status[n-1]);
-+ cmd->len = 4;
-+ cmd++;
-+
-+ cmd->cmd = 0;
-+ cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.clrfstatus);
-+ cmd->dst = NC11(MSM_NAND_FLASH_STATUS);
-+ cmd->len = 4;
-+ cmd++;
-+
-+ cmd->cmd = 0;
-+ cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.clrrstatus);
-+ cmd->dst = NC11(MSM_NAND_READ_STATUS);
-+ cmd->len = 4;
-+ cmd++;
-+
-+ /* MASK DATA ACK/REQ --> NC01 (0xFC0)*/
-+ cmd->cmd = 0;
-+ cmd->src = msm_virt_to_dma(chip,
-+ &dma_buffer->data.adm_default_mux);
-+ cmd->dst = EBI2_NAND_ADM_MUX;
-+ cmd->len = 4;
-+ cmd++;
-+
-+ if (!interleave_enable) {
-+ /* setting to defalut values back */
-+ cmd->cmd = 0;
-+ cmd->src = msm_virt_to_dma(chip,
-+ &dma_buffer->data.nc01_flash_dev_cmd_vld_default);
-+ cmd->dst = NC01(MSM_NAND_DEV_CMD_VLD);
-+ cmd->len = 4;
-+ cmd++;
-+
-+ cmd->cmd = 0;
-+ cmd->src = msm_virt_to_dma(chip,
-+ &dma_buffer->data.nc10_flash_dev_cmd0_default);
-+ cmd->dst = NC10(MSM_NAND_DEV_CMD0);
-+ cmd->len = 4;
-+ cmd++;
-+ } else {
-+ /* disable CS1 */
-+ cmd->cmd = 0;
-+ cmd->src = msm_virt_to_dma(chip,
-+ &dma_buffer->data.default_ebi2_chip_select_cfg0);
-+ cmd->dst = EBI2_CHIP_SELECT_CFG0;
-+ cmd->len = 4;
-+ cmd++;
-+ }
-+
-+ dma_buffer->cmd[0].cmd |= CMD_OCB;
-+ cmd[-1].cmd |= CMD_OCU | CMD_LC;
-+ BUILD_BUG_ON(16 * 6 + 18 != ARRAY_SIZE(dma_buffer->cmd));
-+ BUG_ON(cmd - dma_buffer->cmd > ARRAY_SIZE(dma_buffer->cmd));
-+ dma_buffer->cmdptr =
-+ ((msm_virt_to_dma(chip, dma_buffer->cmd) >> 3) | CMD_PTR_LP);
-+
-+ mb();
-+ msm_dmov_exec_cmd(chip->dma_channel,
-+ DMOV_CMD_PTR_LIST | DMOV_CMD_ADDR(
-+ msm_virt_to_dma(chip, &dma_buffer->cmdptr)));
-+ mb();
-+
-+ /* if any of the writes failed (0x10), or there was a
-+ * protection violation (0x100), or the program success
-+ * bit (0x80) is unset, we lose
-+ */
-+ err = 0;
-+ for (n = 0; n < cwperpage; n++) {
-+ if (dma_buffer->data.flash_status[n] & 0x110) {
-+ err = -EIO;
-+ break;
-+ }
-+ if (!(dma_buffer->data.flash_status[n] & 0x80)) {
-+ err = -EIO;
-+ break;
-+ }
-+ }
-+ /* check for flash status busy for the last codeword */
-+ if (!interleave_enable)
-+ if (!(dma_buffer->data.flash_status[cwperpage - 1]
-+ & 0x20)) {
-+ err = -EIO;
-+ break;
-+ }
-+#if VERBOSE
-+ for (n = 0; n < cwperpage; n++) {
-+ if (n%2) {
-+ pr_info("NC10: write pg %d: flash_status[%d] = %x\n",
-+ page, n, dma_buffer->data.flash_status[n]);
-+ } else {
-+ pr_info("NC01: write pg %d: flash_status[%d] = %x\n",
-+ page, n, dma_buffer->data.flash_status[n]);
-+ }
-+ }
-+#endif
-+ if (err)
-+ break;
-+ pages_written++;
-+ page++;
-+ }
-+ if (ops->mode != MTD_OPS_RAW)
-+ ops->retlen = mtd->writesize * pages_written;
-+ else
-+ ops->retlen = (mtd->writesize + mtd->oobsize) * pages_written;
-+
-+ ops->oobretlen = ops->ooblen - oob_len;
-+
-+ msm_nand_release_dma_buffer(chip, dma_buffer, sizeof(*dma_buffer));
-+
-+ if (ops->oobbuf)
-+ dma_unmap_page(chip->dev, oob_dma_addr,
-+ ops->ooblen, DMA_TO_DEVICE);
-+err_dma_map_oobbuf_failed:
-+ if (ops->datbuf)
-+ dma_unmap_page(chip->dev, data_dma_addr, ops->len,
-+ DMA_TO_DEVICE);
-+ if (err)
-+ pr_err("msm_nand_write_oob_dualnandc %llx %x %x failed %d\n",
-+ to, ops->len, ops->ooblen, err);
-+
-+#if VERBOSE
-+ pr_info("\n%s: ret %d, retlen %d oobretlen %d\n",
-+ __func__, err, ops->retlen, ops->oobretlen);
-+
-+ pr_info("==================================================="
-+ "==========\n");
-+#endif
-+ return err;
-+}
-+
-+static int msm_nand_write(struct mtd_info *mtd, loff_t to, size_t len,
-+ size_t *retlen, const u_char *buf)
-+{
-+ int ret;
-+ struct mtd_oob_ops ops;
-+ int (*write_oob)(struct mtd_info *, loff_t, struct mtd_oob_ops *);
-+
-+ if (!dual_nand_ctlr_present)
-+ write_oob = msm_nand_write_oob;
-+ else
-+ write_oob = msm_nand_write_oob_dualnandc;
-+
-+ ops.mode = MTD_OPS_PLACE_OOB;
-+ ops.retlen = 0;
-+ ops.ooblen = 0;
-+ ops.oobbuf = NULL;
-+ ret = 0;
-+ *retlen = 0;
-+
-+ if (!virt_addr_valid(buf) &&
-+ ((to | len) & (mtd->writesize - 1)) == 0 &&
-+ ((unsigned long) buf & ~PAGE_MASK) + len > PAGE_SIZE) {
-+ /*
-+ * Handle writing of large size write buffer in vmalloc
-+ * address space that does not fit in an MMU page.
-+ * The destination address must be on page boundary,
-+ * and the size must be multiple of NAND page size.
-+ * Writing partial page is not supported.
-+ */
-+ ops.len = mtd->writesize;
-+
-+ for (;;) {
-+ ops.datbuf = (uint8_t *) buf;
-+
-+ ret = write_oob(mtd, to, &ops);
-+ if (ret < 0)
-+ break;
-+
-+ len -= mtd->writesize;
-+ *retlen += mtd->writesize;
-+ if (len == 0)
-+ break;
-+
-+ buf += mtd->writesize;
-+ to += mtd->writesize;
-+ }
-+ } else {
-+ ops.len = len;
-+ ops.datbuf = (uint8_t *) buf;
-+ ret = write_oob(mtd, to, &ops);
-+ *retlen = ops.retlen;
-+ }
-+
-+ return ret;
-+}
-+
-+static int
-+msm_nand_erase(struct mtd_info *mtd, struct erase_info *instr)
-+{
-+ int err;
-+ struct msm_nand_chip *chip = mtd->priv;
-+ struct {
-+ dmov_s cmd[6];
-+ unsigned cmdptr;
-+ struct {
-+ uint32_t cmd;
-+ uint32_t addr0;
-+ uint32_t addr1;
-+ uint32_t chipsel;
-+ uint32_t cfg0;
-+ uint32_t cfg1;
-+ uint32_t exec;
-+ uint32_t flash_status;
-+ uint32_t clrfstatus;
-+ uint32_t clrrstatus;
-+ } data;
-+ } *dma_buffer;
-+ dmov_s *cmd;
-+ unsigned page = 0;
-+
-+ if (mtd->writesize == 2048)
-+ page = instr->addr >> 11;
-+
-+ if (mtd->writesize == 4096)
-+ page = instr->addr >> 12;
-+
-+ if (instr->addr & (mtd->erasesize - 1)) {
-+ pr_err("%s: unsupported erase address, 0x%llx\n",
-+ __func__, instr->addr);
-+ return -EINVAL;
-+ }
-+ if (instr->len != mtd->erasesize) {
-+ pr_err("%s: unsupported erase len, %lld\n",
-+ __func__, instr->len);
-+ return -EINVAL;
-+ }
-+
-+ wait_event(chip->wait_queue,
-+ (dma_buffer = msm_nand_get_dma_buffer(
-+ chip, sizeof(*dma_buffer))));
-+
-+ cmd = dma_buffer->cmd;
-+
-+ dma_buffer->data.cmd = MSM_NAND_CMD_BLOCK_ERASE;
-+ dma_buffer->data.addr0 = page;
-+ dma_buffer->data.addr1 = 0;
-+ dma_buffer->data.chipsel = 0 | 4;
-+ dma_buffer->data.exec = 1;
-+ dma_buffer->data.flash_status = 0xeeeeeeee;
-+ dma_buffer->data.cfg0 = chip->CFG0 & (~(7 << 6)); /* CW_PER_PAGE = 0 */
-+ dma_buffer->data.cfg1 = chip->CFG1;
-+ dma_buffer->data.clrfstatus = 0x00000020;
-+ dma_buffer->data.clrrstatus = 0x000000C0;
-+
-+ cmd->cmd = DST_CRCI_NAND_CMD | CMD_OCB;
-+ cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.cmd);
-+ cmd->dst = MSM_NAND_FLASH_CMD;
-+ cmd->len = 16;
-+ cmd++;
-+
-+ cmd->cmd = 0;
-+ cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.cfg0);
-+ cmd->dst = MSM_NAND_DEV0_CFG0;
-+ cmd->len = 8;
-+ cmd++;
-+
-+ cmd->cmd = 0;
-+ cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.exec);
-+ cmd->dst = MSM_NAND_EXEC_CMD;
-+ cmd->len = 4;
-+ cmd++;
-+
-+ cmd->cmd = SRC_CRCI_NAND_DATA;
-+ cmd->src = MSM_NAND_FLASH_STATUS;
-+ cmd->dst = msm_virt_to_dma(chip, &dma_buffer->data.flash_status);
-+ cmd->len = 4;
-+ cmd++;
-+
-+ cmd->cmd = 0;
-+ cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.clrfstatus);
-+ cmd->dst = MSM_NAND_FLASH_STATUS;
-+ cmd->len = 4;
-+ cmd++;
-+
-+ cmd->cmd = CMD_OCU | CMD_LC;
-+ cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.clrrstatus);
-+ cmd->dst = MSM_NAND_READ_STATUS;
-+ cmd->len = 4;
-+ cmd++;
-+
-+ BUILD_BUG_ON(5 != ARRAY_SIZE(dma_buffer->cmd) - 1);
-+ BUG_ON(cmd - dma_buffer->cmd > ARRAY_SIZE(dma_buffer->cmd));
-+ dma_buffer->cmdptr =
-+ (msm_virt_to_dma(chip, dma_buffer->cmd) >> 3) | CMD_PTR_LP;
-+
-+ mb();
-+ msm_dmov_exec_cmd(
-+ chip->dma_channel, DMOV_CMD_PTR_LIST |
-+ DMOV_CMD_ADDR(msm_virt_to_dma(chip, &dma_buffer->cmdptr)));
-+ mb();
-+
-+ /* we fail if there was an operation error, a mpu error, or the
-+ * erase success bit was not set.
-+ */
-+
-+ if (dma_buffer->data.flash_status & 0x110 ||
-+ !(dma_buffer->data.flash_status & 0x80))
-+ err = -EIO;
-+ else
-+ err = 0;
-+
-+ msm_nand_release_dma_buffer(chip, dma_buffer, sizeof(*dma_buffer));
-+ if (err) {
-+ pr_err("%s: erase failed, 0x%llx\n", __func__, instr->addr);
-+ instr->fail_addr = instr->addr;
-+ instr->state = MTD_ERASE_FAILED;
-+ } else {
-+ instr->state = MTD_ERASE_DONE;
-+ instr->fail_addr = 0xffffffff;
-+ mtd_erase_callback(instr);
-+ }
-+ return err;
-+}
-+
-+static int
-+msm_nand_erase_dualnandc(struct mtd_info *mtd, struct erase_info *instr)
-+{
-+ int err;
-+ struct msm_nand_chip *chip = mtd->priv;
-+ struct {
-+ dmov_s cmd[18];
-+ unsigned cmdptr;
-+ struct {
-+ uint32_t cmd;
-+ uint32_t addr0;
-+ uint32_t addr1;
-+ uint32_t chipsel_cs0;
-+ uint32_t chipsel_cs1;
-+ uint32_t cfg0;
-+ uint32_t cfg1;
-+ uint32_t exec;
-+ uint32_t ecccfg;
-+ uint32_t ebi2_chip_select_cfg0;
-+ uint32_t adm_mux_data_ack_req_nc01;
-+ uint32_t adm_mux_cmd_ack_req_nc01;
-+ uint32_t adm_mux_data_ack_req_nc10;
-+ uint32_t adm_mux_cmd_ack_req_nc10;
-+ uint32_t adm_default_mux;
-+ uint32_t default_ebi2_chip_select_cfg0;
-+ uint32_t nc01_flash_dev_cmd0;
-+ uint32_t nc01_flash_dev_cmd0_default;
-+ uint32_t flash_status[2];
-+ uint32_t clrfstatus;
-+ uint32_t clrrstatus;
-+ } data;
-+ } *dma_buffer;
-+ dmov_s *cmd;
-+ unsigned page = 0;
-+
-+ if (mtd->writesize == 2048)
-+ page = instr->addr >> 11;
-+
-+ if (mtd->writesize == 4096)
-+ page = instr->addr >> 12;
-+
-+ if (mtd->writesize == 8192)
-+ page = (instr->addr >> 1) >> 12;
-+
-+ if (instr->addr & (mtd->erasesize - 1)) {
-+ pr_err("%s: unsupported erase address, 0x%llx\n",
-+ __func__, instr->addr);
-+ return -EINVAL;
-+ }
-+ if (instr->len != mtd->erasesize) {
-+ pr_err("%s: unsupported erase len, %lld\n",
-+ __func__, instr->len);
-+ return -EINVAL;
-+ }
-+
-+ wait_event(chip->wait_queue,
-+ (dma_buffer = msm_nand_get_dma_buffer(
-+ chip, sizeof(*dma_buffer))));
-+
-+ cmd = dma_buffer->cmd;
-+
-+ dma_buffer->data.cmd = MSM_NAND_CMD_BLOCK_ERASE;
-+ dma_buffer->data.addr0 = page;
-+ dma_buffer->data.addr1 = 0;
-+ dma_buffer->data.chipsel_cs0 = (1<<4) | 4;
-+ dma_buffer->data.chipsel_cs1 = (1<<4) | 5;
-+ dma_buffer->data.exec = 1;
-+ dma_buffer->data.flash_status[0] = 0xeeeeeeee;
-+ dma_buffer->data.flash_status[1] = 0xeeeeeeee;
-+ dma_buffer->data.cfg0 = chip->CFG0 & (~(7 << 6)); /* CW_PER_PAGE = 0 */
-+ dma_buffer->data.cfg1 = chip->CFG1;
-+ dma_buffer->data.clrfstatus = 0x00000020;
-+ dma_buffer->data.clrrstatus = 0x000000C0;
-+
-+ dma_buffer->data.ebi2_chip_select_cfg0 = 0x00000805;
-+ dma_buffer->data.adm_mux_data_ack_req_nc01 = 0x00000A3C;
-+ dma_buffer->data.adm_mux_cmd_ack_req_nc01 = 0x0000053C;
-+ dma_buffer->data.adm_mux_data_ack_req_nc10 = 0x00000F28;
-+ dma_buffer->data.adm_mux_cmd_ack_req_nc10 = 0x00000F14;
-+ dma_buffer->data.adm_default_mux = 0x00000FC0;
-+ dma_buffer->data.default_ebi2_chip_select_cfg0 = 0x00000801;
-+
-+ /* enable CS1 */
-+ cmd->cmd = 0 | CMD_OCB;
-+ cmd->src = msm_virt_to_dma(chip,
-+ &dma_buffer->data.ebi2_chip_select_cfg0);
-+ cmd->dst = EBI2_CHIP_SELECT_CFG0;
-+ cmd->len = 4;
-+ cmd++;
-+
-+ /* erase CS0 block now !!! */
-+ /* 0xF14 */
-+ cmd->cmd = 0;
-+ cmd->src = msm_virt_to_dma(chip,
-+ &dma_buffer->data.adm_mux_cmd_ack_req_nc10);
-+ cmd->dst = EBI2_NAND_ADM_MUX;
-+ cmd->len = 4;
-+ cmd++;
-+
-+ cmd->cmd = DST_CRCI_NAND_CMD;
-+ cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.cmd);
-+ cmd->dst = NC01(MSM_NAND_FLASH_CMD);
-+ cmd->len = 16;
-+ cmd++;
-+
-+ cmd->cmd = 0;
-+ cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.cfg0);
-+ cmd->dst = NC01(MSM_NAND_DEV0_CFG0);
-+ cmd->len = 8;
-+ cmd++;
-+
-+ cmd->cmd = 0;
-+ cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.exec);
-+ cmd->dst = NC01(MSM_NAND_EXEC_CMD);
-+ cmd->len = 4;
-+ cmd++;
-+
-+ /* 0xF28 */
-+ cmd->cmd = 0;
-+ cmd->src = msm_virt_to_dma(chip,
-+ &dma_buffer->data.adm_mux_data_ack_req_nc10);
-+ cmd->dst = EBI2_NAND_ADM_MUX;
-+ cmd->len = 4;
-+ cmd++;
-+
-+ cmd->cmd = SRC_CRCI_NAND_DATA;
-+ cmd->src = NC01(MSM_NAND_FLASH_STATUS);
-+ cmd->dst = msm_virt_to_dma(chip, &dma_buffer->data.flash_status[0]);
-+ cmd->len = 4;
-+ cmd++;
-+
-+ /* erase CS1 block now !!! */
-+ /* 0x53C */
-+ cmd->cmd = 0;
-+ cmd->src = msm_virt_to_dma(chip,
-+ &dma_buffer->data.adm_mux_cmd_ack_req_nc01);
-+ cmd->dst = EBI2_NAND_ADM_MUX;
-+ cmd->len = 4;
-+ cmd++;
-+
-+ cmd->cmd = DST_CRCI_NAND_CMD;
-+ cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.cmd);
-+ cmd->dst = NC10(MSM_NAND_FLASH_CMD);
-+ cmd->len = 12;
-+ cmd++;
-+
-+ cmd->cmd = 0;
-+ cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.chipsel_cs1);
-+ cmd->dst = NC10(MSM_NAND_FLASH_CHIP_SELECT);
-+ cmd->len = 4;
-+ cmd++;
-+
-+ cmd->cmd = 0;
-+ cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.cfg0);
-+ cmd->dst = NC10(MSM_NAND_DEV1_CFG0);
-+ cmd->len = 8;
-+
-+ cmd->cmd = 0;
-+ cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.exec);
-+ cmd->dst = NC10(MSM_NAND_EXEC_CMD);
-+ cmd->len = 4;
-+ cmd++;
-+
-+ /* 0xA3C */
-+ cmd->cmd = 0;
-+ cmd->src = msm_virt_to_dma(chip,
-+ &dma_buffer->data.adm_mux_data_ack_req_nc01);
-+ cmd->dst = EBI2_NAND_ADM_MUX;
-+ cmd->len = 4;
-+ cmd++;
-+
-+ cmd->cmd = SRC_CRCI_NAND_DATA;
-+ cmd->src = NC10(MSM_NAND_FLASH_STATUS);
-+ cmd->dst = msm_virt_to_dma(chip, &dma_buffer->data.flash_status[1]);
-+ cmd->len = 4;
-+ cmd++;
-+
-+ cmd->cmd = 0;
-+ cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.clrfstatus);
-+ cmd->dst = NC11(MSM_NAND_FLASH_STATUS);
-+ cmd->len = 4;
-+ cmd++;
-+
-+ cmd->cmd = 0;
-+ cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.clrrstatus);
-+ cmd->dst = NC11(MSM_NAND_READ_STATUS);
-+ cmd->len = 4;
-+ cmd++;
-+
-+ cmd->cmd = 0;
-+ cmd->src = msm_virt_to_dma(chip,
-+ &dma_buffer->data.adm_default_mux);
-+ cmd->dst = EBI2_NAND_ADM_MUX;
-+ cmd->len = 4;
-+ cmd++;
-+
-+ /* disable CS1 */
-+ cmd->cmd = CMD_OCU | CMD_LC;
-+ cmd->src = msm_virt_to_dma(chip,
-+ &dma_buffer->data.default_ebi2_chip_select_cfg0);
-+ cmd->dst = EBI2_CHIP_SELECT_CFG0;
-+ cmd->len = 4;
-+ cmd++;
-+
-+ BUILD_BUG_ON(17 != ARRAY_SIZE(dma_buffer->cmd) - 1);
-+ BUG_ON(cmd - dma_buffer->cmd > ARRAY_SIZE(dma_buffer->cmd));
-+
-+ dma_buffer->cmdptr =
-+ (msm_virt_to_dma(chip, dma_buffer->cmd) >> 3) | CMD_PTR_LP;
-+
-+ mb();
-+ msm_dmov_exec_cmd(
-+ chip->dma_channel, DMOV_CMD_PTR_LIST |
-+ DMOV_CMD_ADDR(msm_virt_to_dma(chip, &dma_buffer->cmdptr)));
-+ mb();
-+
-+ /* we fail if there was an operation error, a mpu error, or the
-+ * erase success bit was not set.
-+ */
-+
-+ if (dma_buffer->data.flash_status[0] & 0x110 ||
-+ !(dma_buffer->data.flash_status[0] & 0x80) ||
-+ dma_buffer->data.flash_status[1] & 0x110 ||
-+ !(dma_buffer->data.flash_status[1] & 0x80))
-+ err = -EIO;
-+ else
-+ err = 0;
-+
-+ msm_nand_release_dma_buffer(chip, dma_buffer, sizeof(*dma_buffer));
-+ if (err) {
-+ pr_err("%s: erase failed, 0x%llx\n", __func__, instr->addr);
-+ instr->fail_addr = instr->addr;
-+ instr->state = MTD_ERASE_FAILED;
-+ } else {
-+ instr->state = MTD_ERASE_DONE;
-+ instr->fail_addr = 0xffffffff;
-+ mtd_erase_callback(instr);
-+ }
-+ return err;
-+}
-+
-+static int
-+msm_nand_block_isbad(struct mtd_info *mtd, loff_t ofs)
-+{
-+ struct msm_nand_chip *chip = mtd->priv;
-+ int ret;
-+ struct {
-+ dmov_s cmd[5];
-+ unsigned cmdptr;
-+ struct {
-+ uint32_t cmd;
-+ uint32_t addr0;
-+ uint32_t addr1;
-+ uint32_t chipsel;
-+ uint32_t cfg0;
-+ uint32_t cfg1;
-+ uint32_t eccbchcfg;
-+ uint32_t exec;
-+ uint32_t ecccfg;
-+ struct {
-+ uint32_t flash_status;
-+ uint32_t buffer_status;
-+ } result;
-+ } data;
-+ } *dma_buffer;
-+ dmov_s *cmd;
-+ uint8_t *buf;
-+ unsigned page = 0;
-+ unsigned cwperpage;
-+
-+ if (mtd->writesize == 2048)
-+ page = ofs >> 11;
-+
-+ if (mtd->writesize == 4096)
-+ page = ofs >> 12;
-+
-+ cwperpage = (mtd->writesize >> 9);
-+
-+ /* Check for invalid offset */
-+ if (ofs > mtd->size)
-+ return -EINVAL;
-+ if (ofs & (mtd->erasesize - 1)) {
-+ pr_err("%s: unsupported block address, 0x%x\n",
-+ __func__, (uint32_t)ofs);
-+ return -EINVAL;
-+ }
-+
-+ wait_event(chip->wait_queue,
-+ (dma_buffer = msm_nand_get_dma_buffer(chip ,
-+ sizeof(*dma_buffer) + 4)));
-+ buf = (uint8_t *)dma_buffer + sizeof(*dma_buffer);
-+
-+ /* Read 4 bytes starting from the bad block marker location
-+ * in the last code word of the page
-+ */
-+
-+ cmd = dma_buffer->cmd;
-+
-+ dma_buffer->data.cmd = MSM_NAND_CMD_PAGE_READ;
-+ dma_buffer->data.cfg0 = chip->CFG0_RAW & ~(7U << 6);
-+ dma_buffer->data.cfg1 = chip->CFG1_RAW |
-+ (chip->CFG1 & CFG1_WIDE_FLASH);
-+ if (enable_bch_ecc)
-+ dma_buffer->data.eccbchcfg = chip->ecc_bch_cfg;
-+
-+ if (chip->CFG1 & CFG1_WIDE_FLASH)
-+ dma_buffer->data.addr0 = (page << 16) |
-+ ((chip->cw_size * (cwperpage-1)) >> 1);
-+ else
-+ dma_buffer->data.addr0 = (page << 16) |
-+ (chip->cw_size * (cwperpage-1));
-+
-+ dma_buffer->data.addr1 = (page >> 16) & 0xff;
-+ dma_buffer->data.chipsel = 0 | 4;
-+
-+ dma_buffer->data.exec = 1;
-+
-+ dma_buffer->data.result.flash_status = 0xeeeeeeee;
-+ dma_buffer->data.result.buffer_status = 0xeeeeeeee;
-+
-+ cmd->cmd = DST_CRCI_NAND_CMD;
-+ cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.cmd);
-+ cmd->dst = MSM_NAND_FLASH_CMD;
-+ cmd->len = 16;
-+ cmd++;
-+
-+ cmd->cmd = 0;
-+ cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.cfg0);
-+ cmd->dst = MSM_NAND_DEV0_CFG0;
-+ if (enable_bch_ecc)
-+ cmd->len = 12;
-+ else
-+ cmd->len = 8;
-+ cmd++;
-+
-+ cmd->cmd = 0;
-+ cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.exec);
-+ cmd->dst = MSM_NAND_EXEC_CMD;
-+ cmd->len = 4;
-+ cmd++;
-+
-+ cmd->cmd = SRC_CRCI_NAND_DATA;
-+ cmd->src = MSM_NAND_FLASH_STATUS;
-+ cmd->dst = msm_virt_to_dma(chip, &dma_buffer->data.result);
-+ cmd->len = 8;
-+ cmd++;
-+
-+ cmd->cmd = 0;
-+ cmd->src = MSM_NAND_FLASH_BUFFER +
-+ (mtd->writesize - (chip->cw_size * (cwperpage-1)));
-+ cmd->dst = msm_virt_to_dma(chip, buf);
-+ cmd->len = 4;
-+ cmd++;
-+
-+ BUILD_BUG_ON(5 != ARRAY_SIZE(dma_buffer->cmd));
-+ BUG_ON(cmd - dma_buffer->cmd > ARRAY_SIZE(dma_buffer->cmd));
-+ dma_buffer->cmd[0].cmd |= CMD_OCB;
-+ cmd[-1].cmd |= CMD_OCU | CMD_LC;
-+
-+ dma_buffer->cmdptr = (msm_virt_to_dma(chip,
-+ dma_buffer->cmd) >> 3) | CMD_PTR_LP;
-+
-+ mb();
-+ msm_dmov_exec_cmd(chip->dma_channel, DMOV_CMD_PTR_LIST |
-+ DMOV_CMD_ADDR(msm_virt_to_dma(chip, &dma_buffer->cmdptr)));
-+ mb();
-+
-+ ret = 0;
-+ if (dma_buffer->data.result.flash_status & 0x110)
-+ ret = -EIO;
-+
-+ if (!ret) {
-+ /* Check for bad block marker byte */
-+ if (chip->CFG1 & CFG1_WIDE_FLASH) {
-+ if (buf[0] != 0xFF || buf[1] != 0xFF)
-+ ret = 1;
-+ } else {
-+ if (buf[0] != 0xFF)
-+ ret = 1;
-+ }
-+ }
-+
-+ msm_nand_release_dma_buffer(chip, dma_buffer, sizeof(*dma_buffer) + 4);
-+ return ret;
-+}
-+
-+static int
-+msm_nand_block_isbad_dualnandc(struct mtd_info *mtd, loff_t ofs)
-+{
-+ struct msm_nand_chip *chip = mtd->priv;
-+ int ret;
-+ struct {
-+ dmov_s cmd[18];
-+ unsigned cmdptr;
-+ struct {
-+ uint32_t cmd;
-+ uint32_t addr0;
-+ uint32_t addr1;
-+ uint32_t chipsel_cs0;
-+ uint32_t chipsel_cs1;
-+ uint32_t cfg0;
-+ uint32_t cfg1;
-+ uint32_t exec;
-+ uint32_t ecccfg;
-+ uint32_t ebi2_chip_select_cfg0;
-+ uint32_t adm_mux_data_ack_req_nc01;
-+ uint32_t adm_mux_cmd_ack_req_nc01;
-+ uint32_t adm_mux_data_ack_req_nc10;
-+ uint32_t adm_mux_cmd_ack_req_nc10;
-+ uint32_t adm_default_mux;
-+ uint32_t default_ebi2_chip_select_cfg0;
-+ struct {
-+ uint32_t flash_status;
-+ uint32_t buffer_status;
-+ } result[2];
-+ } data;
-+ } *dma_buffer;
-+ dmov_s *cmd;
-+ uint8_t *buf01;
-+ uint8_t *buf10;
-+ unsigned page = 0;
-+ unsigned cwperpage;
-+
-+ if (mtd->writesize == 2048)
-+ page = ofs >> 11;
-+
-+ if (mtd->writesize == 4096)
-+ page = ofs >> 12;
-+
-+ if (mtd->writesize == 8192)
-+ page = (ofs >> 1) >> 12;
-+
-+ cwperpage = ((mtd->writesize >> 1) >> 9);
-+
-+ /* Check for invalid offset */
-+ if (ofs > mtd->size)
-+ return -EINVAL;
-+ if (ofs & (mtd->erasesize - 1)) {
-+ pr_err("%s: unsupported block address, 0x%x\n",
-+ __func__, (uint32_t)ofs);
-+ return -EINVAL;
-+ }
-+
-+ wait_event(chip->wait_queue,
-+ (dma_buffer = msm_nand_get_dma_buffer(chip ,
-+ sizeof(*dma_buffer) + 8)));
-+ buf01 = (uint8_t *)dma_buffer + sizeof(*dma_buffer);
-+ buf10 = buf01 + 4;
-+
-+ /* Read 4 bytes starting from the bad block marker location
-+ * in the last code word of the page
-+ */
-+ cmd = dma_buffer->cmd;
-+
-+ dma_buffer->data.cmd = MSM_NAND_CMD_PAGE_READ;
-+ dma_buffer->data.cfg0 = chip->CFG0_RAW & ~(7U << 6);
-+ dma_buffer->data.cfg1 = chip->CFG1_RAW |
-+ (chip->CFG1 & CFG1_WIDE_FLASH);
-+
-+ if (chip->CFG1 & CFG1_WIDE_FLASH)
-+ dma_buffer->data.addr0 = (page << 16) |
-+ ((528*(cwperpage-1)) >> 1);
-+ else
-+ dma_buffer->data.addr0 = (page << 16) |
-+ (528*(cwperpage-1));
-+
-+ dma_buffer->data.addr1 = (page >> 16) & 0xff;
-+ dma_buffer->data.chipsel_cs0 = (1<<4) | 4;
-+ dma_buffer->data.chipsel_cs1 = (1<<4) | 5;
-+
-+ dma_buffer->data.exec = 1;
-+
-+ dma_buffer->data.result[0].flash_status = 0xeeeeeeee;
-+ dma_buffer->data.result[0].buffer_status = 0xeeeeeeee;
-+ dma_buffer->data.result[1].flash_status = 0xeeeeeeee;
-+ dma_buffer->data.result[1].buffer_status = 0xeeeeeeee;
-+
-+ dma_buffer->data.ebi2_chip_select_cfg0 = 0x00000805;
-+ dma_buffer->data.adm_mux_data_ack_req_nc01 = 0x00000A3C;
-+ dma_buffer->data.adm_mux_cmd_ack_req_nc01 = 0x0000053C;
-+ dma_buffer->data.adm_mux_data_ack_req_nc10 = 0x00000F28;
-+ dma_buffer->data.adm_mux_cmd_ack_req_nc10 = 0x00000F14;
-+ dma_buffer->data.adm_default_mux = 0x00000FC0;
-+ dma_buffer->data.default_ebi2_chip_select_cfg0 = 0x00000801;
-+
-+ /* Reading last code word from NC01 */
-+ /* enable CS1 */
-+ cmd->cmd = 0;
-+ cmd->src = msm_virt_to_dma(chip,
-+ &dma_buffer->data.ebi2_chip_select_cfg0);
-+ cmd->dst = EBI2_CHIP_SELECT_CFG0;
-+ cmd->len = 4;
-+ cmd++;
-+
-+ /* 0xF14 */
-+ cmd->cmd = 0;
-+ cmd->src = msm_virt_to_dma(chip,
-+ &dma_buffer->data.adm_mux_cmd_ack_req_nc10);
-+ cmd->dst = EBI2_NAND_ADM_MUX;
-+ cmd->len = 4;
-+ cmd++;
-+
-+ cmd->cmd = DST_CRCI_NAND_CMD;
-+ cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.cmd);
-+ cmd->dst = NC01(MSM_NAND_FLASH_CMD);
-+ cmd->len = 16;
-+ cmd++;
-+
-+ cmd->cmd = 0;
-+ cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.cfg0);
-+ cmd->dst = NC01(MSM_NAND_DEV0_CFG0);
-+ cmd->len = 8;
-+ cmd++;
-+
-+ cmd->cmd = 0;
-+ cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.exec);
-+ cmd->dst = NC01(MSM_NAND_EXEC_CMD);
-+ cmd->len = 4;
-+ cmd++;
-+
-+ /* 0xF28 */
-+ cmd->cmd = 0;
-+ cmd->src = msm_virt_to_dma(chip,
-+ &dma_buffer->data.adm_mux_data_ack_req_nc10);
-+ cmd->dst = EBI2_NAND_ADM_MUX;
-+ cmd->len = 4;
-+ cmd++;
-+
-+ cmd->cmd = SRC_CRCI_NAND_DATA;
-+ cmd->src = NC01(MSM_NAND_FLASH_STATUS);
-+ cmd->dst = msm_virt_to_dma(chip, &dma_buffer->data.result[0]);
-+ cmd->len = 8;
-+ cmd++;
-+
-+ cmd->cmd = 0;
-+ cmd->src = NC01(MSM_NAND_FLASH_BUFFER) + ((mtd->writesize >> 1) -
-+ (528*(cwperpage-1)));
-+ cmd->dst = msm_virt_to_dma(chip, buf01);
-+ cmd->len = 4;
-+ cmd++;
-+
-+ /* Reading last code word from NC10 */
-+ /* 0x53C */
-+ cmd->cmd = 0;
-+ cmd->src = msm_virt_to_dma(chip,
-+ &dma_buffer->data.adm_mux_cmd_ack_req_nc01);
-+ cmd->dst = EBI2_NAND_ADM_MUX;
-+ cmd->len = 4;
-+ cmd++;
-+
-+ cmd->cmd = DST_CRCI_NAND_CMD;
-+ cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.cmd);
-+ cmd->dst = NC10(MSM_NAND_FLASH_CMD);
-+ cmd->len = 12;
-+ cmd++;
-+
-+ cmd->cmd = 0;
-+ cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.chipsel_cs1);
-+ cmd->dst = NC10(MSM_NAND_FLASH_CHIP_SELECT);
-+ cmd->len = 4;
-+ cmd++;
-+
-+ cmd->cmd = 0;
-+ cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.cfg0);
-+ cmd->dst = NC10(MSM_NAND_DEV1_CFG0);
-+ cmd->len = 8;
-+ cmd++;
-+
-+ cmd->cmd = 0;
-+ cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.exec);
-+ cmd->dst = NC10(MSM_NAND_EXEC_CMD);
-+ cmd->len = 4;
-+ cmd++;
-+
-+ /* A3C */
-+ cmd->cmd = 0;
-+ cmd->src = msm_virt_to_dma(chip,
-+ &dma_buffer->data.adm_mux_data_ack_req_nc01);
-+ cmd->dst = EBI2_NAND_ADM_MUX;
-+ cmd->len = 4;
-+ cmd++;
-+
-+ cmd->cmd = SRC_CRCI_NAND_DATA;
-+ cmd->src = NC10(MSM_NAND_FLASH_STATUS);
-+ cmd->dst = msm_virt_to_dma(chip, &dma_buffer->data.result[1]);
-+ cmd->len = 8;
-+ cmd++;
-+
-+ cmd->cmd = 0;
-+ cmd->src = NC10(MSM_NAND_FLASH_BUFFER) + ((mtd->writesize >> 1) -
-+ (528*(cwperpage-1)));
-+ cmd->dst = msm_virt_to_dma(chip, buf10);
-+ cmd->len = 4;
-+ cmd++;
-+
-+ /* FC0 */
-+ cmd->cmd = 0;
-+ cmd->src = msm_virt_to_dma(chip,
-+ &dma_buffer->data.adm_default_mux);
-+ cmd->dst = EBI2_NAND_ADM_MUX;
-+ cmd->len = 4;
-+ cmd++;
-+
-+ /* disble CS1 */
-+ cmd->cmd = 0;
-+ cmd->src = msm_virt_to_dma(chip,
-+ &dma_buffer->data.ebi2_chip_select_cfg0);
-+ cmd->dst = EBI2_CHIP_SELECT_CFG0;
-+ cmd->len = 4;
-+ cmd++;
-+
-+ BUILD_BUG_ON(18 != ARRAY_SIZE(dma_buffer->cmd));
-+ BUG_ON(cmd - dma_buffer->cmd > ARRAY_SIZE(dma_buffer->cmd));
-+ dma_buffer->cmd[0].cmd |= CMD_OCB;
-+ cmd[-1].cmd |= CMD_OCU | CMD_LC;
-+
-+ dma_buffer->cmdptr = (msm_virt_to_dma(chip,
-+ dma_buffer->cmd) >> 3) | CMD_PTR_LP;
-+
-+ mb();
-+ msm_dmov_exec_cmd(chip->dma_channel, DMOV_CMD_PTR_LIST |
-+ DMOV_CMD_ADDR(msm_virt_to_dma(chip, &dma_buffer->cmdptr)));
-+ mb();
-+
-+ ret = 0;
-+ if ((dma_buffer->data.result[0].flash_status & 0x110) ||
-+ (dma_buffer->data.result[1].flash_status & 0x110))
-+ ret = -EIO;
-+
-+ if (!ret) {
-+ /* Check for bad block marker byte for NC01 & NC10 */
-+ if (chip->CFG1 & CFG1_WIDE_FLASH) {
-+ if ((buf01[0] != 0xFF || buf01[1] != 0xFF) ||
-+ (buf10[0] != 0xFF || buf10[1] != 0xFF))
-+ ret = 1;
-+ } else {
-+ if (buf01[0] != 0xFF || buf10[0] != 0xFF)
-+ ret = 1;
-+ }
-+ }
-+
-+ msm_nand_release_dma_buffer(chip, dma_buffer, sizeof(*dma_buffer) + 8);
-+ return ret;
-+}
-+
-+static int
-+msm_nand_block_markbad(struct mtd_info *mtd, loff_t ofs)
-+{
-+ struct mtd_oob_ops ops;
-+ int ret;
-+ uint8_t *buf;
-+
-+ /* Check for invalid offset */
-+ if (ofs > mtd->size)
-+ return -EINVAL;
-+ if (ofs & (mtd->erasesize - 1)) {
-+ pr_err("%s: unsupported block address, 0x%x\n",
-+ __func__, (uint32_t)ofs);
-+ return -EINVAL;
-+ }
-+
-+ /*
-+ Write all 0s to the first page
-+ This will set the BB marker to 0
-+ */
-+ buf = page_address(ZERO_PAGE());
-+
-+ ops.mode = MTD_OPS_RAW;
-+ ops.len = mtd->writesize + mtd->oobsize;
-+ ops.retlen = 0;
-+ ops.ooblen = 0;
-+ ops.datbuf = buf;
-+ ops.oobbuf = NULL;
-+ if (!interleave_enable)
-+ ret = msm_nand_write_oob(mtd, ofs, &ops);
-+ else
-+ ret = msm_nand_write_oob_dualnandc(mtd, ofs, &ops);
-+
-+ return ret;
-+}
-+
-+/**
-+ * msm_nand_suspend - [MTD Interface] Suspend the msm_nand flash
-+ * @param mtd MTD device structure
-+ */
-+static int msm_nand_suspend(struct mtd_info *mtd)
-+{
-+ return 0;
-+}
-+
-+/**
-+ * msm_nand_resume - [MTD Interface] Resume the msm_nand flash
-+ * @param mtd MTD device structure
-+ */
-+static void msm_nand_resume(struct mtd_info *mtd)
-+{
-+}
-+
-+struct onenand_information {
-+ uint16_t manufacturer_id;
-+ uint16_t device_id;
-+ uint16_t version_id;
-+ uint16_t data_buf_size;
-+ uint16_t boot_buf_size;
-+ uint16_t num_of_buffers;
-+ uint16_t technology;
-+};
-+
-+static struct onenand_information onenand_info;
-+static uint32_t nand_sfcmd_mode;
-+
-+uint32_t flash_onenand_probe(struct msm_nand_chip *chip)
-+{
-+ struct {
-+ dmov_s cmd[7];
-+ unsigned cmdptr;
-+ struct {
-+ uint32_t bcfg;
-+ uint32_t cmd;
-+ uint32_t exec;
-+ uint32_t status;
-+ uint32_t addr0;
-+ uint32_t addr1;
-+ uint32_t addr2;
-+ uint32_t addr3;
-+ uint32_t addr4;
-+ uint32_t addr5;
-+ uint32_t addr6;
-+ uint32_t data0;
-+ uint32_t data1;
-+ uint32_t data2;
-+ uint32_t data3;
-+ uint32_t data4;
-+ uint32_t data5;
-+ uint32_t data6;
-+ } data;
-+ } *dma_buffer;
-+ dmov_s *cmd;
-+
-+ int err = 0;
-+ uint32_t initialsflashcmd = 0;
-+
-+ initialsflashcmd = flash_rd_reg(chip, MSM_NAND_SFLASHC_CMD);
-+
-+ if ((initialsflashcmd & 0x10) == 0x10)
-+ nand_sfcmd_mode = MSM_NAND_SFCMD_ASYNC;
-+ else
-+ nand_sfcmd_mode = MSM_NAND_SFCMD_BURST;
-+
-+ printk(KERN_INFO "SFLASHC Async Mode bit: %x \n", nand_sfcmd_mode);
-+
-+ wait_event(chip->wait_queue, (dma_buffer = msm_nand_get_dma_buffer
-+ (chip, sizeof(*dma_buffer))));
-+
-+ cmd = dma_buffer->cmd;
-+
-+ dma_buffer->data.bcfg = SFLASH_BCFG |
-+ (nand_sfcmd_mode ? 0 : (1 << 24));
-+ dma_buffer->data.cmd = SFLASH_PREPCMD(7, 0, 0,
-+ MSM_NAND_SFCMD_DATXS,
-+ nand_sfcmd_mode,
-+ MSM_NAND_SFCMD_REGRD);
-+ dma_buffer->data.exec = 1;
-+ dma_buffer->data.status = CLEAN_DATA_32;
-+ dma_buffer->data.addr0 = (ONENAND_DEVICE_ID << 16) |
-+ (ONENAND_MANUFACTURER_ID);
-+ dma_buffer->data.addr1 = (ONENAND_DATA_BUFFER_SIZE << 16) |
-+ (ONENAND_VERSION_ID);
-+ dma_buffer->data.addr2 = (ONENAND_AMOUNT_OF_BUFFERS << 16) |
-+ (ONENAND_BOOT_BUFFER_SIZE);
-+ dma_buffer->data.addr3 = (CLEAN_DATA_16 << 16) |
-+ (ONENAND_TECHNOLOGY << 0);
-+ dma_buffer->data.data0 = CLEAN_DATA_32;
-+ dma_buffer->data.data1 = CLEAN_DATA_32;
-+ dma_buffer->data.data2 = CLEAN_DATA_32;
-+ dma_buffer->data.data3 = CLEAN_DATA_32;
-+
-+ /* Enable and configure the SFlash controller */
-+ cmd->cmd = 0;
-+ cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.bcfg);
-+ cmd->dst = MSM_NAND_SFLASHC_BURST_CFG;
-+ cmd->len = 4;
-+ cmd++;
-+
-+ /* Block on cmd ready and write CMD register */
-+ cmd->cmd = DST_CRCI_NAND_CMD;
-+ cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.cmd);
-+ cmd->dst = MSM_NAND_SFLASHC_CMD;
-+ cmd->len = 4;
-+ cmd++;
-+
-+ /* Configure the ADDR0 and ADDR1 registers */
-+ cmd->cmd = 0;
-+ cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.addr0);
-+ cmd->dst = MSM_NAND_ADDR0;
-+ cmd->len = 8;
-+ cmd++;
-+
-+ /* Configure the ADDR2 and ADDR3 registers */
-+ cmd->cmd = 0;
-+ cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.addr2);
-+ cmd->dst = MSM_NAND_ADDR2;
-+ cmd->len = 8;
-+ cmd++;
-+
-+ /* Kick the execute command */
-+ cmd->cmd = 0;
-+ cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.exec);
-+ cmd->dst = MSM_NAND_SFLASHC_EXEC_CMD;
-+ cmd->len = 4;
-+ cmd++;
-+
-+ /* Block on data ready, and read the two status registers */
-+ cmd->cmd = SRC_CRCI_NAND_DATA;
-+ cmd->src = MSM_NAND_SFLASHC_STATUS;
-+ cmd->dst = msm_virt_to_dma(chip, &dma_buffer->data.status);
-+ cmd->len = 4;
-+ cmd++;
-+
-+ /* Read data registers - valid only if status says success */
-+ cmd->cmd = 0;
-+ cmd->src = MSM_NAND_GENP_REG0;
-+ cmd->dst = msm_virt_to_dma(chip, &dma_buffer->data.data0);
-+ cmd->len = 16;
-+ cmd++;
-+
-+ BUILD_BUG_ON(7 != ARRAY_SIZE(dma_buffer->cmd));
-+ BUG_ON(cmd - dma_buffer->cmd > ARRAY_SIZE(dma_buffer->cmd));
-+ dma_buffer->cmd[0].cmd |= CMD_OCB;
-+ cmd[-1].cmd |= CMD_OCU | CMD_LC;
-+
-+ dma_buffer->cmdptr = (msm_virt_to_dma(chip, dma_buffer->cmd)
-+ >> 3) | CMD_PTR_LP;
-+
-+ mb();
-+ msm_dmov_exec_cmd(chip->dma_channel, DMOV_CMD_PTR_LIST
-+ | DMOV_CMD_ADDR(msm_virt_to_dma(chip,
-+ &dma_buffer->cmdptr)));
-+ mb();
-+
-+ /* Check for errors, protection violations etc */
-+ if (dma_buffer->data.status & 0x110) {
-+ pr_info("%s: MPU/OP error"
-+ "(0x%x) during Onenand probe\n",
-+ __func__, dma_buffer->data.status);
-+ err = -EIO;
-+ } else {
-+
-+ onenand_info.manufacturer_id =
-+ (dma_buffer->data.data0 >> 0) & 0x0000FFFF;
-+ onenand_info.device_id =
-+ (dma_buffer->data.data0 >> 16) & 0x0000FFFF;
-+ onenand_info.version_id =
-+ (dma_buffer->data.data1 >> 0) & 0x0000FFFF;
-+ onenand_info.data_buf_size =
-+ (dma_buffer->data.data1 >> 16) & 0x0000FFFF;
-+ onenand_info.boot_buf_size =
-+ (dma_buffer->data.data2 >> 0) & 0x0000FFFF;
-+ onenand_info.num_of_buffers =
-+ (dma_buffer->data.data2 >> 16) & 0x0000FFFF;
-+ onenand_info.technology =
-+ (dma_buffer->data.data3 >> 0) & 0x0000FFFF;
-+
-+
-+ pr_info("======================================="
-+ "==========================\n");
-+
-+ pr_info("%s: manufacturer_id = 0x%x\n"
-+ , __func__, onenand_info.manufacturer_id);
-+ pr_info("%s: device_id = 0x%x\n"
-+ , __func__, onenand_info.device_id);
-+ pr_info("%s: version_id = 0x%x\n"
-+ , __func__, onenand_info.version_id);
-+ pr_info("%s: data_buf_size = 0x%x\n"
-+ , __func__, onenand_info.data_buf_size);
-+ pr_info("%s: boot_buf_size = 0x%x\n"
-+ , __func__, onenand_info.boot_buf_size);
-+ pr_info("%s: num_of_buffers = 0x%x\n"
-+ , __func__, onenand_info.num_of_buffers);
-+ pr_info("%s: technology = 0x%x\n"
-+ , __func__, onenand_info.technology);
-+
-+ pr_info("======================================="
-+ "==========================\n");
-+
-+ if ((onenand_info.manufacturer_id != 0x00EC)
-+ || ((onenand_info.device_id & 0x0040) != 0x0040)
-+ || (onenand_info.data_buf_size != 0x0800)
-+ || (onenand_info.boot_buf_size != 0x0200)
-+ || (onenand_info.num_of_buffers != 0x0201)
-+ || (onenand_info.technology != 0)) {
-+
-+ pr_info("%s: Detected an unsupported device\n"
-+ , __func__);
-+ err = -EIO;
-+ }
-+ }
-+
-+ msm_nand_release_dma_buffer(chip, dma_buffer, sizeof(*dma_buffer));
-+
-+ return err;
-+}
-+
-+int msm_onenand_read_oob(struct mtd_info *mtd,
-+ loff_t from, struct mtd_oob_ops *ops)
-+{
-+ struct msm_nand_chip *chip = mtd->priv;
-+
-+ struct {
-+ dmov_s cmd[53];
-+ unsigned cmdptr;
-+ struct {
-+ uint32_t sfbcfg;
-+ uint32_t sfcmd[9];
-+ uint32_t sfexec;
-+ uint32_t sfstat[9];
-+ uint32_t addr0;
-+ uint32_t addr1;
-+ uint32_t addr2;
-+ uint32_t addr3;
-+ uint32_t addr4;
-+ uint32_t addr5;
-+ uint32_t addr6;
-+ uint32_t data0;
-+ uint32_t data1;
-+ uint32_t data2;
-+ uint32_t data3;
-+ uint32_t data4;
-+ uint32_t data5;
-+ uint32_t data6;
-+ uint32_t macro[5];
-+ } data;
-+ } *dma_buffer;
-+ dmov_s *cmd;
-+
-+ int err = 0;
-+ int i;
-+ dma_addr_t data_dma_addr = 0;
-+ dma_addr_t oob_dma_addr = 0;
-+ dma_addr_t data_dma_addr_curr = 0;
-+ dma_addr_t oob_dma_addr_curr = 0;
-+
-+ loff_t from_curr = 0;
-+ unsigned page_count;
-+ unsigned pages_read = 0;
-+
-+ uint16_t onenand_startaddr1;
-+ uint16_t onenand_startaddr8;
-+ uint16_t onenand_startaddr2;
-+ uint16_t onenand_startbuffer;
-+ uint16_t onenand_sysconfig1;
-+ uint16_t controller_status;
-+ uint16_t interrupt_status;
-+ uint16_t ecc_status;
-+#if VERBOSE
-+ pr_info("================================================="
-+ "================\n");
-+ pr_info("%s: from 0x%llx mode %d \ndatbuf 0x%p datlen 0x%x"
-+ "\noobbuf 0x%p ooblen 0x%x\n",
-+ __func__, from, ops->mode, ops->datbuf, ops->len,
-+ ops->oobbuf, ops->ooblen);
-+#endif
-+ if (!mtd) {
-+ pr_err("%s: invalid mtd pointer, 0x%x\n", __func__,
-+ (uint32_t)mtd);
-+ return -EINVAL;
-+ }
-+ if (from & (mtd->writesize - 1)) {
-+ pr_err("%s: unsupported from, 0x%llx\n", __func__,
-+ from);
-+ return -EINVAL;
-+ }
-+
-+ if ((ops->mode != MTD_OPS_PLACE_OOB) && (ops->mode != MTD_OPS_AUTO_OOB) &&
-+ (ops->mode != MTD_OPS_RAW)) {
-+ pr_err("%s: unsupported ops->mode, %d\n", __func__,
-+ ops->mode);
-+ return -EINVAL;
-+ }
-+
-+ if (((ops->datbuf == NULL) || (ops->len == 0)) &&
-+ ((ops->oobbuf == NULL) || (ops->ooblen == 0))) {
-+ pr_err("%s: incorrect ops fields - nothing to do\n",
-+ __func__);
-+ return -EINVAL;
-+ }
-+
-+ if ((ops->datbuf != NULL) && (ops->len == 0)) {
-+ pr_err("%s: data buffer passed but length 0\n",
-+ __func__);
-+ return -EINVAL;
-+ }
-+
-+ if ((ops->oobbuf != NULL) && (ops->ooblen == 0)) {
-+ pr_err("%s: oob buffer passed but length 0\n",
-+ __func__);
-+ return -EINVAL;
-+ }
-+
-+ if (ops->mode != MTD_OPS_RAW) {
-+ if (ops->datbuf != NULL && (ops->len % mtd->writesize) != 0) {
-+ /* when ops->datbuf is NULL, ops->len can be ooblen */
-+ pr_err("%s: unsupported ops->len, %d\n", __func__,
-+ ops->len);
-+ return -EINVAL;
-+ }
-+ } else {
-+ if (ops->datbuf != NULL &&
-+ (ops->len % (mtd->writesize + mtd->oobsize)) != 0) {
-+ pr_err("%s: unsupported ops->len,"
-+ " %d for MTD_OPS_RAW\n", __func__, ops->len);
-+ return -EINVAL;
-+ }
-+ }
-+
-+ if ((ops->mode == MTD_OPS_RAW) && (ops->oobbuf)) {
-+ pr_err("%s: unsupported operation, oobbuf pointer "
-+ "passed in for RAW mode, %x\n", __func__,
-+ (uint32_t)ops->oobbuf);
-+ return -EINVAL;
-+ }
-+
-+ if (ops->oobbuf && !ops->datbuf) {
-+ page_count = ops->ooblen / ((ops->mode == MTD_OPS_AUTO_OOB) ?
-+ mtd->oobavail : mtd->oobsize);
-+ if ((page_count == 0) && (ops->ooblen))
-+ page_count = 1;
-+ } else if (ops->mode != MTD_OPS_RAW)
-+ page_count = ops->len / mtd->writesize;
-+ else
-+ page_count = ops->len / (mtd->writesize + mtd->oobsize);
-+
-+ if ((ops->mode == MTD_OPS_PLACE_OOB) && (ops->oobbuf != NULL)) {
-+ if (page_count * mtd->oobsize > ops->ooblen) {
-+ pr_err("%s: unsupported ops->ooblen for "
-+ "PLACE, %d\n", __func__, ops->ooblen);
-+ return -EINVAL;
-+ }
-+ }
-+
-+ if ((ops->mode == MTD_OPS_PLACE_OOB) && (ops->ooblen != 0) &&
-+ (ops->ooboffs != 0)) {
-+ pr_err("%s: unsupported ops->ooboffs, %d\n", __func__,
-+ ops->ooboffs);
-+ return -EINVAL;
-+ }
-+
-+ if (ops->datbuf) {
-+ memset(ops->datbuf, 0x55, ops->len);
-+ data_dma_addr_curr = data_dma_addr = msm_nand_dma_map(chip->dev,
-+ ops->datbuf, ops->len, DMA_FROM_DEVICE, NULL);
-+ if (dma_mapping_error(chip->dev, data_dma_addr)) {
-+ pr_err("%s: failed to get dma addr for %p\n",
-+ __func__, ops->datbuf);
-+ return -EIO;
-+ }
-+ }
-+ if (ops->oobbuf) {
-+ memset(ops->oobbuf, 0x55, ops->ooblen);
-+ oob_dma_addr_curr = oob_dma_addr = msm_nand_dma_map(chip->dev,
-+ ops->oobbuf, ops->ooblen, DMA_FROM_DEVICE, NULL);
-+ if (dma_mapping_error(chip->dev, oob_dma_addr)) {
-+ pr_err("%s: failed to get dma addr for %p\n",
-+ __func__, ops->oobbuf);
-+ err = -EIO;
-+ goto err_dma_map_oobbuf_failed;
-+ }
-+ }
-+
-+ wait_event(chip->wait_queue, (dma_buffer = msm_nand_get_dma_buffer
-+ (chip, sizeof(*dma_buffer))));
-+
-+ from_curr = from;
-+
-+ while (page_count-- > 0) {
-+
-+ cmd = dma_buffer->cmd;
-+
-+ if ((onenand_info.device_id & ONENAND_DEVICE_IS_DDP)
-+ && (from_curr >= (mtd->size>>1))) { /* DDP Device */
-+ onenand_startaddr1 = DEVICE_FLASHCORE_1 |
-+ (((uint32_t)(from_curr-(mtd->size>>1))
-+ / mtd->erasesize));
-+ onenand_startaddr2 = DEVICE_BUFFERRAM_1;
-+ } else {
-+ onenand_startaddr1 = DEVICE_FLASHCORE_0 |
-+ ((uint32_t)from_curr / mtd->erasesize) ;
-+ onenand_startaddr2 = DEVICE_BUFFERRAM_0;
-+ }
-+
-+ onenand_startaddr8 = (((uint32_t)from_curr &
-+ (mtd->erasesize - 1)) / mtd->writesize) << 2;
-+ onenand_startbuffer = DATARAM0_0 << 8;
-+ onenand_sysconfig1 = (ops->mode == MTD_OPS_RAW) ?
-+ ONENAND_SYSCFG1_ECCDIS(nand_sfcmd_mode) :
-+ ONENAND_SYSCFG1_ECCENA(nand_sfcmd_mode);
-+
-+ dma_buffer->data.sfbcfg = SFLASH_BCFG |
-+ (nand_sfcmd_mode ? 0 : (1 << 24));
-+ dma_buffer->data.sfcmd[0] = SFLASH_PREPCMD(7, 0, 0,
-+ MSM_NAND_SFCMD_CMDXS,
-+ nand_sfcmd_mode,
-+ MSM_NAND_SFCMD_REGWR);
-+ dma_buffer->data.sfcmd[1] = SFLASH_PREPCMD(0, 0, 32,
-+ MSM_NAND_SFCMD_CMDXS,
-+ nand_sfcmd_mode,
-+ MSM_NAND_SFCMD_INTHI);
-+ dma_buffer->data.sfcmd[2] = SFLASH_PREPCMD(3, 7, 0,
-+ MSM_NAND_SFCMD_DATXS,
-+ nand_sfcmd_mode,
-+ MSM_NAND_SFCMD_REGRD);
-+ dma_buffer->data.sfcmd[3] = SFLASH_PREPCMD(256, 0, 0,
-+ MSM_NAND_SFCMD_DATXS,
-+ nand_sfcmd_mode,
-+ MSM_NAND_SFCMD_DATRD);
-+ dma_buffer->data.sfcmd[4] = SFLASH_PREPCMD(256, 0, 0,
-+ MSM_NAND_SFCMD_DATXS,
-+ nand_sfcmd_mode,
-+ MSM_NAND_SFCMD_DATRD);
-+ dma_buffer->data.sfcmd[5] = SFLASH_PREPCMD(256, 0, 0,
-+ MSM_NAND_SFCMD_DATXS,
-+ nand_sfcmd_mode,
-+ MSM_NAND_SFCMD_DATRD);
-+ dma_buffer->data.sfcmd[6] = SFLASH_PREPCMD(256, 0, 0,
-+ MSM_NAND_SFCMD_DATXS,
-+ nand_sfcmd_mode,
-+ MSM_NAND_SFCMD_DATRD);
-+ dma_buffer->data.sfcmd[7] = SFLASH_PREPCMD(32, 0, 0,
-+ MSM_NAND_SFCMD_DATXS,
-+ nand_sfcmd_mode,
-+ MSM_NAND_SFCMD_DATRD);
-+ dma_buffer->data.sfcmd[8] = SFLASH_PREPCMD(4, 10, 0,
-+ MSM_NAND_SFCMD_CMDXS,
-+ nand_sfcmd_mode,
-+ MSM_NAND_SFCMD_REGWR);
-+ dma_buffer->data.sfexec = 1;
-+ dma_buffer->data.sfstat[0] = CLEAN_DATA_32;
-+ dma_buffer->data.sfstat[1] = CLEAN_DATA_32;
-+ dma_buffer->data.sfstat[2] = CLEAN_DATA_32;
-+ dma_buffer->data.sfstat[3] = CLEAN_DATA_32;
-+ dma_buffer->data.sfstat[4] = CLEAN_DATA_32;
-+ dma_buffer->data.sfstat[5] = CLEAN_DATA_32;
-+ dma_buffer->data.sfstat[6] = CLEAN_DATA_32;
-+ dma_buffer->data.sfstat[7] = CLEAN_DATA_32;
-+ dma_buffer->data.sfstat[8] = CLEAN_DATA_32;
-+ dma_buffer->data.addr0 = (ONENAND_INTERRUPT_STATUS << 16) |
-+ (ONENAND_SYSTEM_CONFIG_1);
-+ dma_buffer->data.addr1 = (ONENAND_START_ADDRESS_8 << 16) |
-+ (ONENAND_START_ADDRESS_1);
-+ dma_buffer->data.addr2 = (ONENAND_START_BUFFER << 16) |
-+ (ONENAND_START_ADDRESS_2);
-+ dma_buffer->data.addr3 = (ONENAND_ECC_STATUS << 16) |
-+ (ONENAND_COMMAND);
-+ dma_buffer->data.addr4 = (ONENAND_CONTROLLER_STATUS << 16) |
-+ (ONENAND_INTERRUPT_STATUS);
-+ dma_buffer->data.addr5 = (ONENAND_INTERRUPT_STATUS << 16) |
-+ (ONENAND_SYSTEM_CONFIG_1);
-+ dma_buffer->data.addr6 = (ONENAND_START_ADDRESS_3 << 16) |
-+ (ONENAND_START_ADDRESS_1);
-+ dma_buffer->data.data0 = (ONENAND_CLRINTR << 16) |
-+ (onenand_sysconfig1);
-+ dma_buffer->data.data1 = (onenand_startaddr8 << 16) |
-+ (onenand_startaddr1);
-+ dma_buffer->data.data2 = (onenand_startbuffer << 16) |
-+ (onenand_startaddr2);
-+ dma_buffer->data.data3 = (CLEAN_DATA_16 << 16) |
-+ (ONENAND_CMDLOADSPARE);
-+ dma_buffer->data.data4 = (CLEAN_DATA_16 << 16) |
-+ (CLEAN_DATA_16);
-+ dma_buffer->data.data5 = (ONENAND_CLRINTR << 16) |
-+ (ONENAND_SYSCFG1_ECCENA(nand_sfcmd_mode));
-+ dma_buffer->data.data6 = (ONENAND_STARTADDR3_RES << 16) |
-+ (ONENAND_STARTADDR1_RES);
-+ dma_buffer->data.macro[0] = 0x0200;
-+ dma_buffer->data.macro[1] = 0x0300;
-+ dma_buffer->data.macro[2] = 0x0400;
-+ dma_buffer->data.macro[3] = 0x0500;
-+ dma_buffer->data.macro[4] = 0x8010;
-+
-+ /*************************************************************/
-+ /* Write necessary address registers in the onenand device */
-+ /*************************************************************/
-+
-+ /* Enable and configure the SFlash controller */
-+ cmd->cmd = 0;
-+ cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.sfbcfg);
-+ cmd->dst = MSM_NAND_SFLASHC_BURST_CFG;
-+ cmd->len = 4;
-+ cmd++;
-+
-+ /* Block on cmd ready and write CMD register */
-+ cmd->cmd = DST_CRCI_NAND_CMD;
-+ cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.sfcmd[0]);
-+ cmd->dst = MSM_NAND_SFLASHC_CMD;
-+ cmd->len = 4;
-+ cmd++;
-+
-+ /* Write the ADDR0 and ADDR1 registers */
-+ cmd->cmd = 0;
-+ cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.addr0);
-+ cmd->dst = MSM_NAND_ADDR0;
-+ cmd->len = 8;
-+ cmd++;
-+
-+ /* Write the ADDR2 ADDR3 ADDR4 ADDR5 registers */
-+ cmd->cmd = 0;
-+ cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.addr2);
-+ cmd->dst = MSM_NAND_ADDR2;
-+ cmd->len = 16;
-+ cmd++;
-+
-+ /* Write the ADDR6 registers */
-+ cmd->cmd = 0;
-+ cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.addr6);
-+ cmd->dst = MSM_NAND_ADDR6;
-+ cmd->len = 4;
-+ cmd++;
-+
-+ /* Write the GENP0, GENP1, GENP2, GENP3 registers */
-+ cmd->cmd = 0;
-+ cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.data0);
-+ cmd->dst = MSM_NAND_GENP_REG0;
-+ cmd->len = 16;
-+ cmd++;
-+
-+ /* Write the FLASH_DEV_CMD4,5,6 registers */
-+ cmd->cmd = 0;
-+ cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.data4);
-+ cmd->dst = MSM_NAND_DEV_CMD4;
-+ cmd->len = 12;
-+ cmd++;
-+
-+ /* Kick the execute command */
-+ cmd->cmd = 0;
-+ cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.sfexec);
-+ cmd->dst = MSM_NAND_SFLASHC_EXEC_CMD;
-+ cmd->len = 4;
-+ cmd++;
-+
-+ /* Block on data ready, and read the status register */
-+ cmd->cmd = SRC_CRCI_NAND_DATA;
-+ cmd->src = MSM_NAND_SFLASHC_STATUS;
-+ cmd->dst = msm_virt_to_dma(chip, &dma_buffer->data.sfstat[0]);
-+ cmd->len = 4;
-+ cmd++;
-+
-+ /*************************************************************/
-+ /* Wait for the interrupt from the Onenand device controller */
-+ /*************************************************************/
-+
-+ /* Block on cmd ready and write CMD register */
-+ cmd->cmd = DST_CRCI_NAND_CMD;
-+ cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.sfcmd[1]);
-+ cmd->dst = MSM_NAND_SFLASHC_CMD;
-+ cmd->len = 4;
-+ cmd++;
-+
-+ /* Kick the execute command */
-+ cmd->cmd = 0;
-+ cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.sfexec);
-+ cmd->dst = MSM_NAND_SFLASHC_EXEC_CMD;
-+ cmd->len = 4;
-+ cmd++;
-+
-+ /* Block on data ready, and read the status register */
-+ cmd->cmd = SRC_CRCI_NAND_DATA;
-+ cmd->src = MSM_NAND_SFLASHC_STATUS;
-+ cmd->dst = msm_virt_to_dma(chip, &dma_buffer->data.sfstat[1]);
-+ cmd->len = 4;
-+ cmd++;
-+
-+ /*************************************************************/
-+ /* Read necessary status registers from the onenand device */
-+ /*************************************************************/
-+
-+ /* Block on cmd ready and write CMD register */
-+ cmd->cmd = DST_CRCI_NAND_CMD;
-+ cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.sfcmd[2]);
-+ cmd->dst = MSM_NAND_SFLASHC_CMD;
-+ cmd->len = 4;
-+ cmd++;
-+
-+ /* Kick the execute command */
-+ cmd->cmd = 0;
-+ cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.sfexec);
-+ cmd->dst = MSM_NAND_SFLASHC_EXEC_CMD;
-+ cmd->len = 4;
-+ cmd++;
-+
-+ /* Block on data ready, and read the status register */
-+ cmd->cmd = SRC_CRCI_NAND_DATA;
-+ cmd->src = MSM_NAND_SFLASHC_STATUS;
-+ cmd->dst = msm_virt_to_dma(chip, &dma_buffer->data.sfstat[2]);
-+ cmd->len = 4;
-+ cmd++;
-+
-+ /* Read the GENP3 register */
-+ cmd->cmd = 0;
-+ cmd->src = MSM_NAND_GENP_REG3;
-+ cmd->dst = msm_virt_to_dma(chip, &dma_buffer->data.data3);
-+ cmd->len = 4;
-+ cmd++;
-+
-+ /* Read the DEVCMD4 register */
-+ cmd->cmd = 0;
-+ cmd->src = MSM_NAND_DEV_CMD4;
-+ cmd->dst = msm_virt_to_dma(chip, &dma_buffer->data.data4);
-+ cmd->len = 4;
-+ cmd++;
-+
-+ /*************************************************************/
-+ /* Read the data ram area from the onenand buffer ram */
-+ /*************************************************************/
-+
-+ if (ops->datbuf) {
-+
-+ dma_buffer->data.data3 = (CLEAN_DATA_16 << 16) |
-+ (ONENAND_CMDLOAD);
-+
-+ for (i = 0; i < 4; i++) {
-+
-+ /* Block on cmd ready and write CMD register */
-+ cmd->cmd = DST_CRCI_NAND_CMD;
-+ cmd->src = msm_virt_to_dma(chip,
-+ &dma_buffer->data.sfcmd[3+i]);
-+ cmd->dst = MSM_NAND_SFLASHC_CMD;
-+ cmd->len = 4;
-+ cmd++;
-+
-+ /* Write the MACRO1 register */
-+ cmd->cmd = 0;
-+ cmd->src = msm_virt_to_dma(chip,
-+ &dma_buffer->data.macro[i]);
-+ cmd->dst = MSM_NAND_MACRO1_REG;
-+ cmd->len = 4;
-+ cmd++;
-+
-+ /* Kick the execute command */
-+ cmd->cmd = 0;
-+ cmd->src = msm_virt_to_dma(chip,
-+ &dma_buffer->data.sfexec);
-+ cmd->dst = MSM_NAND_SFLASHC_EXEC_CMD;
-+ cmd->len = 4;
-+ cmd++;
-+
-+ /* Block on data rdy, & read status register */
-+ cmd->cmd = SRC_CRCI_NAND_DATA;
-+ cmd->src = MSM_NAND_SFLASHC_STATUS;
-+ cmd->dst = msm_virt_to_dma(chip,
-+ &dma_buffer->data.sfstat[3+i]);
-+ cmd->len = 4;
-+ cmd++;
-+
-+ /* Transfer nand ctlr buf contents to usr buf */
-+ cmd->cmd = 0;
-+ cmd->src = MSM_NAND_FLASH_BUFFER;
-+ cmd->dst = data_dma_addr_curr;
-+ cmd->len = 512;
-+ data_dma_addr_curr += 512;
-+ cmd++;
-+ }
-+ }
-+
-+ if ((ops->oobbuf) || (ops->mode == MTD_OPS_RAW)) {
-+
-+ /* Block on cmd ready and write CMD register */
-+ cmd->cmd = DST_CRCI_NAND_CMD;
-+ cmd->src = msm_virt_to_dma(chip,
-+ &dma_buffer->data.sfcmd[7]);
-+ cmd->dst = MSM_NAND_SFLASHC_CMD;
-+ cmd->len = 4;
-+ cmd++;
-+
-+ /* Write the MACRO1 register */
-+ cmd->cmd = 0;
-+ cmd->src = msm_virt_to_dma(chip,
-+ &dma_buffer->data.macro[4]);
-+ cmd->dst = MSM_NAND_MACRO1_REG;
-+ cmd->len = 4;
-+ cmd++;
-+
-+ /* Kick the execute command */
-+ cmd->cmd = 0;
-+ cmd->src = msm_virt_to_dma(chip,
-+ &dma_buffer->data.sfexec);
-+ cmd->dst = MSM_NAND_SFLASHC_EXEC_CMD;
-+ cmd->len = 4;
-+ cmd++;
-+
-+ /* Block on data ready, and read status register */
-+ cmd->cmd = SRC_CRCI_NAND_DATA;
-+ cmd->src = MSM_NAND_SFLASHC_STATUS;
-+ cmd->dst = msm_virt_to_dma(chip,
-+ &dma_buffer->data.sfstat[7]);
-+ cmd->len = 4;
-+ cmd++;
-+
-+ /* Transfer nand ctlr buffer contents into usr buf */
-+ if (ops->mode == MTD_OPS_AUTO_OOB) {
-+ for (i = 0; i < MTD_MAX_OOBFREE_ENTRIES; i++) {
-+ cmd->cmd = 0;
-+ cmd->src = MSM_NAND_FLASH_BUFFER +
-+ mtd->ecclayout->oobfree[i].offset;
-+ cmd->dst = oob_dma_addr_curr;
-+ cmd->len =
-+ mtd->ecclayout->oobfree[i].length;
-+ oob_dma_addr_curr +=
-+ mtd->ecclayout->oobfree[i].length;
-+ cmd++;
-+ }
-+ }
-+ if (ops->mode == MTD_OPS_PLACE_OOB) {
-+ cmd->cmd = 0;
-+ cmd->src = MSM_NAND_FLASH_BUFFER;
-+ cmd->dst = oob_dma_addr_curr;
-+ cmd->len = mtd->oobsize;
-+ oob_dma_addr_curr += mtd->oobsize;
-+ cmd++;
-+ }
-+ if (ops->mode == MTD_OPS_RAW) {
-+ cmd->cmd = 0;
-+ cmd->src = MSM_NAND_FLASH_BUFFER;
-+ cmd->dst = data_dma_addr_curr;
-+ cmd->len = mtd->oobsize;
-+ data_dma_addr_curr += mtd->oobsize;
-+ cmd++;
-+ }
-+ }
-+
-+ /*************************************************************/
-+ /* Restore the necessary registers to proper values */
-+ /*************************************************************/
-+
-+ /* Block on cmd ready and write CMD register */
-+ cmd->cmd = DST_CRCI_NAND_CMD;
-+ cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.sfcmd[8]);
-+ cmd->dst = MSM_NAND_SFLASHC_CMD;
-+ cmd->len = 4;
-+ cmd++;
-+
-+ /* Kick the execute command */
-+ cmd->cmd = 0;
-+ cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.sfexec);
-+ cmd->dst = MSM_NAND_SFLASHC_EXEC_CMD;
-+ cmd->len = 4;
-+ cmd++;
-+
-+ /* Block on data ready, and read the status register */
-+ cmd->cmd = SRC_CRCI_NAND_DATA;
-+ cmd->src = MSM_NAND_SFLASHC_STATUS;
-+ cmd->dst = msm_virt_to_dma(chip, &dma_buffer->data.sfstat[8]);
-+ cmd->len = 4;
-+ cmd++;
-+
-+
-+ BUILD_BUG_ON(53 != ARRAY_SIZE(dma_buffer->cmd));
-+ BUG_ON(cmd - dma_buffer->cmd > ARRAY_SIZE(dma_buffer->cmd));
-+ dma_buffer->cmd[0].cmd |= CMD_OCB;
-+ cmd[-1].cmd |= CMD_OCU | CMD_LC;
-+
-+ dma_buffer->cmdptr = (msm_virt_to_dma(chip, dma_buffer->cmd)
-+ >> 3) | CMD_PTR_LP;
-+
-+ mb();
-+ msm_dmov_exec_cmd(chip->dma_channel,
-+ DMOV_CMD_PTR_LIST | DMOV_CMD_ADDR(msm_virt_to_dma(chip,
-+ &dma_buffer->cmdptr)));
-+ mb();
-+
-+ ecc_status = (dma_buffer->data.data3 >> 16) &
-+ 0x0000FFFF;
-+ interrupt_status = (dma_buffer->data.data4 >> 0) &
-+ 0x0000FFFF;
-+ controller_status = (dma_buffer->data.data4 >> 16) &
-+ 0x0000FFFF;
-+
-+#if VERBOSE
-+ pr_info("\n%s: sflash status %x %x %x %x %x %x %x"
-+ "%x %x\n", __func__,
-+ dma_buffer->data.sfstat[0],
-+ dma_buffer->data.sfstat[1],
-+ dma_buffer->data.sfstat[2],
-+ dma_buffer->data.sfstat[3],
-+ dma_buffer->data.sfstat[4],
-+ dma_buffer->data.sfstat[5],
-+ dma_buffer->data.sfstat[6],
-+ dma_buffer->data.sfstat[7],
-+ dma_buffer->data.sfstat[8]);
-+
-+ pr_info("%s: controller_status = %x\n", __func__,
-+ controller_status);
-+ pr_info("%s: interrupt_status = %x\n", __func__,
-+ interrupt_status);
-+ pr_info("%s: ecc_status = %x\n", __func__,
-+ ecc_status);
-+#endif
-+ /* Check for errors, protection violations etc */
-+ if ((controller_status != 0)
-+ || (dma_buffer->data.sfstat[0] & 0x110)
-+ || (dma_buffer->data.sfstat[1] & 0x110)
-+ || (dma_buffer->data.sfstat[2] & 0x110)
-+ || (dma_buffer->data.sfstat[8] & 0x110)
-+ || ((dma_buffer->data.sfstat[3] & 0x110) &&
-+ (ops->datbuf))
-+ || ((dma_buffer->data.sfstat[4] & 0x110) &&
-+ (ops->datbuf))
-+ || ((dma_buffer->data.sfstat[5] & 0x110) &&
-+ (ops->datbuf))
-+ || ((dma_buffer->data.sfstat[6] & 0x110) &&
-+ (ops->datbuf))
-+ || ((dma_buffer->data.sfstat[7] & 0x110) &&
-+ ((ops->oobbuf)
-+ || (ops->mode == MTD_OPS_RAW)))) {
-+ pr_info("%s: ECC/MPU/OP error\n", __func__);
-+ err = -EIO;
-+ }
-+
-+ if (err)
-+ break;
-+ pages_read++;
-+ from_curr += mtd->writesize;
-+ }
-+
-+ msm_nand_release_dma_buffer(chip, dma_buffer, sizeof(*dma_buffer));
-+
-+ if (ops->oobbuf) {
-+ dma_unmap_page(chip->dev, oob_dma_addr, ops->ooblen,
-+ DMA_FROM_DEVICE);
-+ }
-+err_dma_map_oobbuf_failed:
-+ if (ops->datbuf) {
-+ dma_unmap_page(chip->dev, data_dma_addr, ops->len,
-+ DMA_FROM_DEVICE);
-+ }
-+
-+ if (err) {
-+ pr_err("%s: %llx %x %x failed\n", __func__, from_curr,
-+ ops->datbuf ? ops->len : 0, ops->ooblen);
-+ } else {
-+ ops->retlen = ops->oobretlen = 0;
-+ if (ops->datbuf != NULL) {
-+ if (ops->mode != MTD_OPS_RAW)
-+ ops->retlen = mtd->writesize * pages_read;
-+ else
-+ ops->retlen = (mtd->writesize + mtd->oobsize)
-+ * pages_read;
-+ }
-+ if (ops->oobbuf != NULL) {
-+ if (ops->mode == MTD_OPS_AUTO_OOB)
-+ ops->oobretlen = mtd->oobavail * pages_read;
-+ else
-+ ops->oobretlen = mtd->oobsize * pages_read;
-+ }
-+ }
-+
-+#if VERBOSE
-+ pr_info("\n%s: ret %d, retlen %d oobretlen %d\n",
-+ __func__, err, ops->retlen, ops->oobretlen);
-+
-+ pr_info("==================================================="
-+ "==============\n");
-+#endif
-+ return err;
-+}
-+
-+int msm_onenand_read(struct mtd_info *mtd, loff_t from, size_t len,
-+ size_t *retlen, u_char *buf)
-+{
-+ int ret;
-+ struct mtd_oob_ops ops;
-+
-+ ops.mode = MTD_OPS_PLACE_OOB;
-+ ops.datbuf = buf;
-+ ops.len = len;
-+ ops.retlen = 0;
-+ ops.oobbuf = NULL;
-+ ops.ooblen = 0;
-+ ops.oobretlen = 0;
-+ ret = msm_onenand_read_oob(mtd, from, &ops);
-+ *retlen = ops.retlen;
-+
-+ return ret;
-+}
-+
-+static int msm_onenand_write_oob(struct mtd_info *mtd, loff_t to,
-+ struct mtd_oob_ops *ops)
-+{
-+ struct msm_nand_chip *chip = mtd->priv;
-+
-+ struct {
-+ dmov_s cmd[53];
-+ unsigned cmdptr;
-+ struct {
-+ uint32_t sfbcfg;
-+ uint32_t sfcmd[10];
-+ uint32_t sfexec;
-+ uint32_t sfstat[10];
-+ uint32_t addr0;
-+ uint32_t addr1;
-+ uint32_t addr2;
-+ uint32_t addr3;
-+ uint32_t addr4;
-+ uint32_t addr5;
-+ uint32_t addr6;
-+ uint32_t data0;
-+ uint32_t data1;
-+ uint32_t data2;
-+ uint32_t data3;
-+ uint32_t data4;
-+ uint32_t data5;
-+ uint32_t data6;
-+ uint32_t macro[5];
-+ } data;
-+ } *dma_buffer;
-+ dmov_s *cmd;
-+
-+ int err = 0;
-+ int i, j, k;
-+ dma_addr_t data_dma_addr = 0;
-+ dma_addr_t oob_dma_addr = 0;
-+ dma_addr_t init_dma_addr = 0;
-+ dma_addr_t data_dma_addr_curr = 0;
-+ dma_addr_t oob_dma_addr_curr = 0;
-+ uint8_t *init_spare_bytes;
-+
-+ loff_t to_curr = 0;
-+ unsigned page_count;
-+ unsigned pages_written = 0;
-+
-+ uint16_t onenand_startaddr1;
-+ uint16_t onenand_startaddr8;
-+ uint16_t onenand_startaddr2;
-+ uint16_t onenand_startbuffer;
-+ uint16_t onenand_sysconfig1;
-+
-+ uint16_t controller_status;
-+ uint16_t interrupt_status;
-+ uint16_t ecc_status;
-+
-+#if VERBOSE
-+ pr_info("================================================="
-+ "================\n");
-+ pr_info("%s: to 0x%llx mode %d \ndatbuf 0x%p datlen 0x%x"
-+ "\noobbuf 0x%p ooblen 0x%x\n",
-+ __func__, to, ops->mode, ops->datbuf, ops->len,
-+ ops->oobbuf, ops->ooblen);
-+#endif
-+ if (!mtd) {
-+ pr_err("%s: invalid mtd pointer, 0x%x\n", __func__,
-+ (uint32_t)mtd);
-+ return -EINVAL;
-+ }
-+ if (to & (mtd->writesize - 1)) {
-+ pr_err("%s: unsupported to, 0x%llx\n", __func__, to);
-+ return -EINVAL;
-+ }
-+
-+ if ((ops->mode != MTD_OPS_PLACE_OOB) && (ops->mode != MTD_OPS_AUTO_OOB) &&
-+ (ops->mode != MTD_OPS_RAW)) {
-+ pr_err("%s: unsupported ops->mode, %d\n", __func__,
-+ ops->mode);
-+ return -EINVAL;
-+ }
-+
-+ if (((ops->datbuf == NULL) || (ops->len == 0)) &&
-+ ((ops->oobbuf == NULL) || (ops->ooblen == 0))) {
-+ pr_err("%s: incorrect ops fields - nothing to do\n",
-+ __func__);
-+ return -EINVAL;
-+ }
-+
-+ if ((ops->datbuf != NULL) && (ops->len == 0)) {
-+ pr_err("%s: data buffer passed but length 0\n",
-+ __func__);
-+ return -EINVAL;
-+ }
-+
-+ if ((ops->oobbuf != NULL) && (ops->ooblen == 0)) {
-+ pr_err("%s: oob buffer passed but length 0\n",
-+ __func__);
-+ return -EINVAL;
-+ }
-+
-+ if (ops->mode != MTD_OPS_RAW) {
-+ if (ops->datbuf != NULL && (ops->len % mtd->writesize) != 0) {
-+ /* when ops->datbuf is NULL, ops->len can be ooblen */
-+ pr_err("%s: unsupported ops->len, %d\n", __func__,
-+ ops->len);
-+ return -EINVAL;
-+ }
-+ } else {
-+ if (ops->datbuf != NULL &&
-+ (ops->len % (mtd->writesize + mtd->oobsize)) != 0) {
-+ pr_err("%s: unsupported ops->len,"
-+ " %d for MTD_OPS_RAW\n", __func__, ops->len);
-+ return -EINVAL;
-+ }
-+ }
-+
-+ if ((ops->mode == MTD_OPS_RAW) && (ops->oobbuf)) {
-+ pr_err("%s: unsupported operation, oobbuf pointer "
-+ "passed in for RAW mode, %x\n", __func__,
-+ (uint32_t)ops->oobbuf);
-+ return -EINVAL;
-+ }
-+
-+ if (ops->oobbuf && !ops->datbuf) {
-+ page_count = ops->ooblen / ((ops->mode == MTD_OPS_AUTO_OOB) ?
-+ mtd->oobavail : mtd->oobsize);
-+ if ((page_count == 0) && (ops->ooblen))
-+ page_count = 1;
-+ } else if (ops->mode != MTD_OPS_RAW)
-+ page_count = ops->len / mtd->writesize;
-+ else
-+ page_count = ops->len / (mtd->writesize + mtd->oobsize);
-+
-+ if ((ops->mode == MTD_OPS_AUTO_OOB) && (ops->oobbuf != NULL)) {
-+ if (page_count > 1) {
-+ pr_err("%s: unsupported ops->ooblen for"
-+ "AUTO, %d\n", __func__, ops->ooblen);
-+ return -EINVAL;
-+ }
-+ }
-+
-+ if ((ops->mode == MTD_OPS_PLACE_OOB) && (ops->oobbuf != NULL)) {
-+ if (page_count * mtd->oobsize > ops->ooblen) {
-+ pr_err("%s: unsupported ops->ooblen for"
-+ "PLACE, %d\n", __func__, ops->ooblen);
-+ return -EINVAL;
-+ }
-+ }
-+
-+ if ((ops->mode == MTD_OPS_PLACE_OOB) && (ops->ooblen != 0) &&
-+ (ops->ooboffs != 0)) {
-+ pr_err("%s: unsupported ops->ooboffs, %d\n",
-+ __func__, ops->ooboffs);
-+ return -EINVAL;
-+ }
-+
-+ init_spare_bytes = kmalloc(64, GFP_KERNEL);
-+ if (!init_spare_bytes) {
-+ pr_err("%s: failed to alloc init_spare_bytes buffer\n",
-+ __func__);
-+ return -ENOMEM;
-+ }
-+ for (i = 0; i < 64; i++)
-+ init_spare_bytes[i] = 0xFF;
-+
-+ if ((ops->oobbuf) && (ops->mode == MTD_OPS_AUTO_OOB)) {
-+ for (i = 0, k = 0; i < MTD_MAX_OOBFREE_ENTRIES; i++)
-+ for (j = 0; j < mtd->ecclayout->oobfree[i].length;
-+ j++) {
-+ init_spare_bytes[j +
-+ mtd->ecclayout->oobfree[i].offset]
-+ = (ops->oobbuf)[k];
-+ k++;
-+ }
-+ }
-+
-+ if (ops->datbuf) {
-+ data_dma_addr_curr = data_dma_addr = msm_nand_dma_map(chip->dev,
-+ ops->datbuf, ops->len, DMA_TO_DEVICE, NULL);
-+ if (dma_mapping_error(chip->dev, data_dma_addr)) {
-+ pr_err("%s: failed to get dma addr for %p\n",
-+ __func__, ops->datbuf);
-+ return -EIO;
-+ }
-+ }
-+ if (ops->oobbuf) {
-+ oob_dma_addr_curr = oob_dma_addr = msm_nand_dma_map(chip->dev,
-+ ops->oobbuf, ops->ooblen, DMA_TO_DEVICE, NULL);
-+ if (dma_mapping_error(chip->dev, oob_dma_addr)) {
-+ pr_err("%s: failed to get dma addr for %p\n",
-+ __func__, ops->oobbuf);
-+ err = -EIO;
-+ goto err_dma_map_oobbuf_failed;
-+ }
-+ }
-+
-+ init_dma_addr = msm_nand_dma_map(chip->dev, init_spare_bytes, 64,
-+ DMA_TO_DEVICE, NULL);
-+ if (dma_mapping_error(chip->dev, init_dma_addr)) {
-+ pr_err("%s: failed to get dma addr for %p\n",
-+ __func__, init_spare_bytes);
-+ err = -EIO;
-+ goto err_dma_map_initbuf_failed;
-+ }
-+
-+
-+ wait_event(chip->wait_queue, (dma_buffer = msm_nand_get_dma_buffer
-+ (chip, sizeof(*dma_buffer))));
-+
-+ to_curr = to;
-+
-+ while (page_count-- > 0) {
-+ cmd = dma_buffer->cmd;
-+
-+ if ((onenand_info.device_id & ONENAND_DEVICE_IS_DDP)
-+ && (to_curr >= (mtd->size>>1))) { /* DDP Device */
-+ onenand_startaddr1 = DEVICE_FLASHCORE_1 |
-+ (((uint32_t)(to_curr-(mtd->size>>1))
-+ / mtd->erasesize));
-+ onenand_startaddr2 = DEVICE_BUFFERRAM_1;
-+ } else {
-+ onenand_startaddr1 = DEVICE_FLASHCORE_0 |
-+ ((uint32_t)to_curr / mtd->erasesize) ;
-+ onenand_startaddr2 = DEVICE_BUFFERRAM_0;
-+ }
-+
-+ onenand_startaddr8 = (((uint32_t)to_curr &
-+ (mtd->erasesize - 1)) / mtd->writesize) << 2;
-+ onenand_startbuffer = DATARAM0_0 << 8;
-+ onenand_sysconfig1 = (ops->mode == MTD_OPS_RAW) ?
-+ ONENAND_SYSCFG1_ECCDIS(nand_sfcmd_mode) :
-+ ONENAND_SYSCFG1_ECCENA(nand_sfcmd_mode);
-+
-+ dma_buffer->data.sfbcfg = SFLASH_BCFG |
-+ (nand_sfcmd_mode ? 0 : (1 << 24));
-+ dma_buffer->data.sfcmd[0] = SFLASH_PREPCMD(6, 0, 0,
-+ MSM_NAND_SFCMD_CMDXS,
-+ nand_sfcmd_mode,
-+ MSM_NAND_SFCMD_REGWR);
-+ dma_buffer->data.sfcmd[1] = SFLASH_PREPCMD(256, 0, 0,
-+ MSM_NAND_SFCMD_CMDXS,
-+ nand_sfcmd_mode,
-+ MSM_NAND_SFCMD_DATWR);
-+ dma_buffer->data.sfcmd[2] = SFLASH_PREPCMD(256, 0, 0,
-+ MSM_NAND_SFCMD_CMDXS,
-+ nand_sfcmd_mode,
-+ MSM_NAND_SFCMD_DATWR);
-+ dma_buffer->data.sfcmd[3] = SFLASH_PREPCMD(256, 0, 0,
-+ MSM_NAND_SFCMD_CMDXS,
-+ nand_sfcmd_mode,
-+ MSM_NAND_SFCMD_DATWR);
-+ dma_buffer->data.sfcmd[4] = SFLASH_PREPCMD(256, 0, 0,
-+ MSM_NAND_SFCMD_CMDXS,
-+ nand_sfcmd_mode,
-+ MSM_NAND_SFCMD_DATWR);
-+ dma_buffer->data.sfcmd[5] = SFLASH_PREPCMD(32, 0, 0,
-+ MSM_NAND_SFCMD_CMDXS,
-+ nand_sfcmd_mode,
-+ MSM_NAND_SFCMD_DATWR);
-+ dma_buffer->data.sfcmd[6] = SFLASH_PREPCMD(1, 6, 0,
-+ MSM_NAND_SFCMD_CMDXS,
-+ nand_sfcmd_mode,
-+ MSM_NAND_SFCMD_REGWR);
-+ dma_buffer->data.sfcmd[7] = SFLASH_PREPCMD(0, 0, 32,
-+ MSM_NAND_SFCMD_CMDXS,
-+ nand_sfcmd_mode,
-+ MSM_NAND_SFCMD_INTHI);
-+ dma_buffer->data.sfcmd[8] = SFLASH_PREPCMD(3, 7, 0,
-+ MSM_NAND_SFCMD_DATXS,
-+ nand_sfcmd_mode,
-+ MSM_NAND_SFCMD_REGRD);
-+ dma_buffer->data.sfcmd[9] = SFLASH_PREPCMD(4, 10, 0,
-+ MSM_NAND_SFCMD_CMDXS,
-+ nand_sfcmd_mode,
-+ MSM_NAND_SFCMD_REGWR);
-+ dma_buffer->data.sfexec = 1;
-+ dma_buffer->data.sfstat[0] = CLEAN_DATA_32;
-+ dma_buffer->data.sfstat[1] = CLEAN_DATA_32;
-+ dma_buffer->data.sfstat[2] = CLEAN_DATA_32;
-+ dma_buffer->data.sfstat[3] = CLEAN_DATA_32;
-+ dma_buffer->data.sfstat[4] = CLEAN_DATA_32;
-+ dma_buffer->data.sfstat[5] = CLEAN_DATA_32;
-+ dma_buffer->data.sfstat[6] = CLEAN_DATA_32;
-+ dma_buffer->data.sfstat[7] = CLEAN_DATA_32;
-+ dma_buffer->data.sfstat[8] = CLEAN_DATA_32;
-+ dma_buffer->data.sfstat[9] = CLEAN_DATA_32;
-+ dma_buffer->data.addr0 = (ONENAND_INTERRUPT_STATUS << 16) |
-+ (ONENAND_SYSTEM_CONFIG_1);
-+ dma_buffer->data.addr1 = (ONENAND_START_ADDRESS_8 << 16) |
-+ (ONENAND_START_ADDRESS_1);
-+ dma_buffer->data.addr2 = (ONENAND_START_BUFFER << 16) |
-+ (ONENAND_START_ADDRESS_2);
-+ dma_buffer->data.addr3 = (ONENAND_ECC_STATUS << 16) |
-+ (ONENAND_COMMAND);
-+ dma_buffer->data.addr4 = (ONENAND_CONTROLLER_STATUS << 16) |
-+ (ONENAND_INTERRUPT_STATUS);
-+ dma_buffer->data.addr5 = (ONENAND_INTERRUPT_STATUS << 16) |
-+ (ONENAND_SYSTEM_CONFIG_1);
-+ dma_buffer->data.addr6 = (ONENAND_START_ADDRESS_3 << 16) |
-+ (ONENAND_START_ADDRESS_1);
-+ dma_buffer->data.data0 = (ONENAND_CLRINTR << 16) |
-+ (onenand_sysconfig1);
-+ dma_buffer->data.data1 = (onenand_startaddr8 << 16) |
-+ (onenand_startaddr1);
-+ dma_buffer->data.data2 = (onenand_startbuffer << 16) |
-+ (onenand_startaddr2);
-+ dma_buffer->data.data3 = (CLEAN_DATA_16 << 16) |
-+ (ONENAND_CMDPROGSPARE);
-+ dma_buffer->data.data4 = (CLEAN_DATA_16 << 16) |
-+ (CLEAN_DATA_16);
-+ dma_buffer->data.data5 = (ONENAND_CLRINTR << 16) |
-+ (ONENAND_SYSCFG1_ECCENA(nand_sfcmd_mode));
-+ dma_buffer->data.data6 = (ONENAND_STARTADDR3_RES << 16) |
-+ (ONENAND_STARTADDR1_RES);
-+ dma_buffer->data.macro[0] = 0x0200;
-+ dma_buffer->data.macro[1] = 0x0300;
-+ dma_buffer->data.macro[2] = 0x0400;
-+ dma_buffer->data.macro[3] = 0x0500;
-+ dma_buffer->data.macro[4] = 0x8010;
-+
-+
-+ /*************************************************************/
-+ /* Write necessary address registers in the onenand device */
-+ /*************************************************************/
-+
-+ /* Enable and configure the SFlash controller */
-+ cmd->cmd = 0;
-+ cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.sfbcfg);
-+ cmd->dst = MSM_NAND_SFLASHC_BURST_CFG;
-+ cmd->len = 4;
-+ cmd++;
-+
-+ /* Block on cmd ready and write CMD register */
-+ cmd->cmd = DST_CRCI_NAND_CMD;
-+ cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.sfcmd[0]);
-+ cmd->dst = MSM_NAND_SFLASHC_CMD;
-+ cmd->len = 4;
-+ cmd++;
-+
-+ /* Write the ADDR0 and ADDR1 registers */
-+ cmd->cmd = 0;
-+ cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.addr0);
-+ cmd->dst = MSM_NAND_ADDR0;
-+ cmd->len = 8;
-+ cmd++;
-+
-+ /* Write the ADDR2 ADDR3 ADDR4 ADDR5 registers */
-+ cmd->cmd = 0;
-+ cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.addr2);
-+ cmd->dst = MSM_NAND_ADDR2;
-+ cmd->len = 16;
-+ cmd++;
-+
-+ /* Write the ADDR6 registers */
-+ cmd->cmd = 0;
-+ cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.addr6);
-+ cmd->dst = MSM_NAND_ADDR6;
-+ cmd->len = 4;
-+ cmd++;
-+
-+ /* Write the GENP0, GENP1, GENP2, GENP3 registers */
-+ cmd->cmd = 0;
-+ cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.data0);
-+ cmd->dst = MSM_NAND_GENP_REG0;
-+ cmd->len = 16;
-+ cmd++;
-+
-+ /* Write the FLASH_DEV_CMD4,5,6 registers */
-+ cmd->cmd = 0;
-+ cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.data4);
-+ cmd->dst = MSM_NAND_DEV_CMD4;
-+ cmd->len = 12;
-+ cmd++;
-+
-+ /* Kick the execute command */
-+ cmd->cmd = 0;
-+ cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.sfexec);
-+ cmd->dst = MSM_NAND_SFLASHC_EXEC_CMD;
-+ cmd->len = 4;
-+ cmd++;
-+
-+ /* Block on data ready, and read the status register */
-+ cmd->cmd = SRC_CRCI_NAND_DATA;
-+ cmd->src = MSM_NAND_SFLASHC_STATUS;
-+ cmd->dst = msm_virt_to_dma(chip, &dma_buffer->data.sfstat[0]);
-+ cmd->len = 4;
-+ cmd++;
-+
-+ /*************************************************************/
-+ /* Write the data ram area in the onenand buffer ram */
-+ /*************************************************************/
-+
-+ if (ops->datbuf) {
-+ dma_buffer->data.data3 = (CLEAN_DATA_16 << 16) |
-+ (ONENAND_CMDPROG);
-+
-+ for (i = 0; i < 4; i++) {
-+
-+ /* Block on cmd ready and write CMD register */
-+ cmd->cmd = DST_CRCI_NAND_CMD;
-+ cmd->src = msm_virt_to_dma(chip,
-+ &dma_buffer->data.sfcmd[1+i]);
-+ cmd->dst = MSM_NAND_SFLASHC_CMD;
-+ cmd->len = 4;
-+ cmd++;
-+
-+ /* Trnsfr usr buf contents to nand ctlr buf */
-+ cmd->cmd = 0;
-+ cmd->src = data_dma_addr_curr;
-+ cmd->dst = MSM_NAND_FLASH_BUFFER;
-+ cmd->len = 512;
-+ data_dma_addr_curr += 512;
-+ cmd++;
-+
-+ /* Write the MACRO1 register */
-+ cmd->cmd = 0;
-+ cmd->src = msm_virt_to_dma(chip,
-+ &dma_buffer->data.macro[i]);
-+ cmd->dst = MSM_NAND_MACRO1_REG;
-+ cmd->len = 4;
-+ cmd++;
-+
-+ /* Kick the execute command */
-+ cmd->cmd = 0;
-+ cmd->src = msm_virt_to_dma(chip,
-+ &dma_buffer->data.sfexec);
-+ cmd->dst = MSM_NAND_SFLASHC_EXEC_CMD;
-+ cmd->len = 4;
-+ cmd++;
-+
-+ /* Block on data rdy, & read status register */
-+ cmd->cmd = SRC_CRCI_NAND_DATA;
-+ cmd->src = MSM_NAND_SFLASHC_STATUS;
-+ cmd->dst = msm_virt_to_dma(chip,
-+ &dma_buffer->data.sfstat[1+i]);
-+ cmd->len = 4;
-+ cmd++;
-+
-+ }
-+ }
-+
-+ /* Block on cmd ready and write CMD register */
-+ cmd->cmd = DST_CRCI_NAND_CMD;
-+ cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.sfcmd[5]);
-+ cmd->dst = MSM_NAND_SFLASHC_CMD;
-+ cmd->len = 4;
-+ cmd++;
-+
-+ if ((ops->oobbuf) || (ops->mode == MTD_OPS_RAW)) {
-+
-+ /* Transfer user buf contents into nand ctlr buffer */
-+ if (ops->mode == MTD_OPS_AUTO_OOB) {
-+ cmd->cmd = 0;
-+ cmd->src = init_dma_addr;
-+ cmd->dst = MSM_NAND_FLASH_BUFFER;
-+ cmd->len = mtd->oobsize;
-+ cmd++;
-+ }
-+ if (ops->mode == MTD_OPS_PLACE_OOB) {
-+ cmd->cmd = 0;
-+ cmd->src = oob_dma_addr_curr;
-+ cmd->dst = MSM_NAND_FLASH_BUFFER;
-+ cmd->len = mtd->oobsize;
-+ oob_dma_addr_curr += mtd->oobsize;
-+ cmd++;
-+ }
-+ if (ops->mode == MTD_OPS_RAW) {
-+ cmd->cmd = 0;
-+ cmd->src = data_dma_addr_curr;
-+ cmd->dst = MSM_NAND_FLASH_BUFFER;
-+ cmd->len = mtd->oobsize;
-+ data_dma_addr_curr += mtd->oobsize;
-+ cmd++;
-+ }
-+ } else {
-+ cmd->cmd = 0;
-+ cmd->src = init_dma_addr;
-+ cmd->dst = MSM_NAND_FLASH_BUFFER;
-+ cmd->len = mtd->oobsize;
-+ cmd++;
-+ }
-+
-+ /* Write the MACRO1 register */
-+ cmd->cmd = 0;
-+ cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.macro[4]);
-+ cmd->dst = MSM_NAND_MACRO1_REG;
-+ cmd->len = 4;
-+ cmd++;
-+
-+ /* Kick the execute command */
-+ cmd->cmd = 0;
-+ cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.sfexec);
-+ cmd->dst = MSM_NAND_SFLASHC_EXEC_CMD;
-+ cmd->len = 4;
-+ cmd++;
-+
-+ /* Block on data ready, and read the status register */
-+ cmd->cmd = SRC_CRCI_NAND_DATA;
-+ cmd->src = MSM_NAND_SFLASHC_STATUS;
-+ cmd->dst = msm_virt_to_dma(chip, &dma_buffer->data.sfstat[5]);
-+ cmd->len = 4;
-+ cmd++;
-+
-+ /*********************************************************/
-+ /* Issuing write command */
-+ /*********************************************************/
-+
-+ /* Block on cmd ready and write CMD register */
-+ cmd->cmd = DST_CRCI_NAND_CMD;
-+ cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.sfcmd[6]);
-+ cmd->dst = MSM_NAND_SFLASHC_CMD;
-+ cmd->len = 4;
-+ cmd++;
-+
-+ /* Kick the execute command */
-+ cmd->cmd = 0;
-+ cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.sfexec);
-+ cmd->dst = MSM_NAND_SFLASHC_EXEC_CMD;
-+ cmd->len = 4;
-+ cmd++;
-+
-+ /* Block on data ready, and read the status register */
-+ cmd->cmd = SRC_CRCI_NAND_DATA;
-+ cmd->src = MSM_NAND_SFLASHC_STATUS;
-+ cmd->dst = msm_virt_to_dma(chip, &dma_buffer->data.sfstat[6]);
-+ cmd->len = 4;
-+ cmd++;
-+
-+ /*************************************************************/
-+ /* Wait for the interrupt from the Onenand device controller */
-+ /*************************************************************/
-+
-+ /* Block on cmd ready and write CMD register */
-+ cmd->cmd = DST_CRCI_NAND_CMD;
-+ cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.sfcmd[7]);
-+ cmd->dst = MSM_NAND_SFLASHC_CMD;
-+ cmd->len = 4;
-+ cmd++;
-+
-+ /* Kick the execute command */
-+ cmd->cmd = 0;
-+ cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.sfexec);
-+ cmd->dst = MSM_NAND_SFLASHC_EXEC_CMD;
-+ cmd->len = 4;
-+ cmd++;
-+
-+ /* Block on data ready, and read the status register */
-+ cmd->cmd = SRC_CRCI_NAND_DATA;
-+ cmd->src = MSM_NAND_SFLASHC_STATUS;
-+ cmd->dst = msm_virt_to_dma(chip, &dma_buffer->data.sfstat[7]);
-+ cmd->len = 4;
-+ cmd++;
-+
-+ /*************************************************************/
-+ /* Read necessary status registers from the onenand device */
-+ /*************************************************************/
-+
-+ /* Block on cmd ready and write CMD register */
-+ cmd->cmd = DST_CRCI_NAND_CMD;
-+ cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.sfcmd[8]);
-+ cmd->dst = MSM_NAND_SFLASHC_CMD;
-+ cmd->len = 4;
-+ cmd++;
-+
-+ /* Kick the execute command */
-+ cmd->cmd = 0;
-+ cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.sfexec);
-+ cmd->dst = MSM_NAND_SFLASHC_EXEC_CMD;
-+ cmd->len = 4;
-+ cmd++;
-+
-+ /* Block on data ready, and read the status register */
-+ cmd->cmd = SRC_CRCI_NAND_DATA;
-+ cmd->src = MSM_NAND_SFLASHC_STATUS;
-+ cmd->dst = msm_virt_to_dma(chip, &dma_buffer->data.sfstat[8]);
-+ cmd->len = 4;
-+ cmd++;
-+
-+ /* Read the GENP3 register */
-+ cmd->cmd = 0;
-+ cmd->src = MSM_NAND_GENP_REG3;
-+ cmd->dst = msm_virt_to_dma(chip, &dma_buffer->data.data3);
-+ cmd->len = 4;
-+ cmd++;
-+
-+ /* Read the DEVCMD4 register */
-+ cmd->cmd = 0;
-+ cmd->src = MSM_NAND_DEV_CMD4;
-+ cmd->dst = msm_virt_to_dma(chip, &dma_buffer->data.data4);
-+ cmd->len = 4;
-+ cmd++;
-+
-+ /*************************************************************/
-+ /* Restore the necessary registers to proper values */
-+ /*************************************************************/
-+
-+ /* Block on cmd ready and write CMD register */
-+ cmd->cmd = DST_CRCI_NAND_CMD;
-+ cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.sfcmd[9]);
-+ cmd->dst = MSM_NAND_SFLASHC_CMD;
-+ cmd->len = 4;
-+ cmd++;
-+
-+ /* Kick the execute command */
-+ cmd->cmd = 0;
-+ cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.sfexec);
-+ cmd->dst = MSM_NAND_SFLASHC_EXEC_CMD;
-+ cmd->len = 4;
-+ cmd++;
-+
-+ /* Block on data ready, and read the status register */
-+ cmd->cmd = SRC_CRCI_NAND_DATA;
-+ cmd->src = MSM_NAND_SFLASHC_STATUS;
-+ cmd->dst = msm_virt_to_dma(chip, &dma_buffer->data.sfstat[9]);
-+ cmd->len = 4;
-+ cmd++;
-+
-+
-+ BUILD_BUG_ON(53 != ARRAY_SIZE(dma_buffer->cmd));
-+ BUG_ON(cmd - dma_buffer->cmd > ARRAY_SIZE(dma_buffer->cmd));
-+ dma_buffer->cmd[0].cmd |= CMD_OCB;
-+ cmd[-1].cmd |= CMD_OCU | CMD_LC;
-+
-+ dma_buffer->cmdptr = (msm_virt_to_dma(chip, dma_buffer->cmd)
-+ >> 3) | CMD_PTR_LP;
-+
-+ mb();
-+ msm_dmov_exec_cmd(chip->dma_channel,
-+ DMOV_CMD_PTR_LIST | DMOV_CMD_ADDR(msm_virt_to_dma(chip,
-+ &dma_buffer->cmdptr)));
-+ mb();
-+
-+ ecc_status = (dma_buffer->data.data3 >> 16) & 0x0000FFFF;
-+ interrupt_status = (dma_buffer->data.data4 >> 0)&0x0000FFFF;
-+ controller_status = (dma_buffer->data.data4 >> 16)&0x0000FFFF;
-+
-+#if VERBOSE
-+ pr_info("\n%s: sflash status %x %x %x %x %x %x %x"
-+ " %x %x %x\n", __func__,
-+ dma_buffer->data.sfstat[0],
-+ dma_buffer->data.sfstat[1],
-+ dma_buffer->data.sfstat[2],
-+ dma_buffer->data.sfstat[3],
-+ dma_buffer->data.sfstat[4],
-+ dma_buffer->data.sfstat[5],
-+ dma_buffer->data.sfstat[6],
-+ dma_buffer->data.sfstat[7],
-+ dma_buffer->data.sfstat[8],
-+ dma_buffer->data.sfstat[9]);
-+
-+ pr_info("%s: controller_status = %x\n", __func__,
-+ controller_status);
-+ pr_info("%s: interrupt_status = %x\n", __func__,
-+ interrupt_status);
-+ pr_info("%s: ecc_status = %x\n", __func__,
-+ ecc_status);
-+#endif
-+ /* Check for errors, protection violations etc */
-+ if ((controller_status != 0)
-+ || (dma_buffer->data.sfstat[0] & 0x110)
-+ || (dma_buffer->data.sfstat[6] & 0x110)
-+ || (dma_buffer->data.sfstat[7] & 0x110)
-+ || (dma_buffer->data.sfstat[8] & 0x110)
-+ || (dma_buffer->data.sfstat[9] & 0x110)
-+ || ((dma_buffer->data.sfstat[1] & 0x110) &&
-+ (ops->datbuf))
-+ || ((dma_buffer->data.sfstat[2] & 0x110) &&
-+ (ops->datbuf))
-+ || ((dma_buffer->data.sfstat[3] & 0x110) &&
-+ (ops->datbuf))
-+ || ((dma_buffer->data.sfstat[4] & 0x110) &&
-+ (ops->datbuf))
-+ || ((dma_buffer->data.sfstat[5] & 0x110) &&
-+ ((ops->oobbuf)
-+ || (ops->mode == MTD_OPS_RAW)))) {
-+ pr_info("%s: ECC/MPU/OP error\n", __func__);
-+ err = -EIO;
-+ }
-+
-+ if (err)
-+ break;
-+ pages_written++;
-+ to_curr += mtd->writesize;
-+ }
-+
-+ msm_nand_release_dma_buffer(chip, dma_buffer, sizeof(*dma_buffer));
-+
-+ dma_unmap_page(chip->dev, init_dma_addr, 64, DMA_TO_DEVICE);
-+
-+err_dma_map_initbuf_failed:
-+ if (ops->oobbuf) {
-+ dma_unmap_page(chip->dev, oob_dma_addr, ops->ooblen,
-+ DMA_TO_DEVICE);
-+ }
-+err_dma_map_oobbuf_failed:
-+ if (ops->datbuf) {
-+ dma_unmap_page(chip->dev, data_dma_addr, ops->len,
-+ DMA_TO_DEVICE);
-+ }
-+
-+ if (err) {
-+ pr_err("%s: %llx %x %x failed\n", __func__, to_curr,
-+ ops->datbuf ? ops->len : 0, ops->ooblen);
-+ } else {
-+ ops->retlen = ops->oobretlen = 0;
-+ if (ops->datbuf != NULL) {
-+ if (ops->mode != MTD_OPS_RAW)
-+ ops->retlen = mtd->writesize * pages_written;
-+ else
-+ ops->retlen = (mtd->writesize + mtd->oobsize)
-+ * pages_written;
-+ }
-+ if (ops->oobbuf != NULL) {
-+ if (ops->mode == MTD_OPS_AUTO_OOB)
-+ ops->oobretlen = mtd->oobavail * pages_written;
-+ else
-+ ops->oobretlen = mtd->oobsize * pages_written;
-+ }
-+ }
-+
-+#if VERBOSE
-+ pr_info("\n%s: ret %d, retlen %d oobretlen %d\n",
-+ __func__, err, ops->retlen, ops->oobretlen);
-+
-+ pr_info("================================================="
-+ "================\n");
-+#endif
-+ kfree(init_spare_bytes);
-+ return err;
-+}
-+
-+static int msm_onenand_write(struct mtd_info *mtd, loff_t to, size_t len,
-+ size_t *retlen, const u_char *buf)
-+{
-+ int ret;
-+ struct mtd_oob_ops ops;
-+
-+ ops.mode = MTD_OPS_PLACE_OOB;
-+ ops.datbuf = (uint8_t *)buf;
-+ ops.len = len;
-+ ops.retlen = 0;
-+ ops.oobbuf = NULL;
-+ ops.ooblen = 0;
-+ ops.oobretlen = 0;
-+ ret = msm_onenand_write_oob(mtd, to, &ops);
-+ *retlen = ops.retlen;
-+
-+ return ret;
-+}
-+
-+static int msm_onenand_erase(struct mtd_info *mtd, struct erase_info *instr)
-+{
-+ struct msm_nand_chip *chip = mtd->priv;
-+
-+ struct {
-+ dmov_s cmd[20];
-+ unsigned cmdptr;
-+ struct {
-+ uint32_t sfbcfg;
-+ uint32_t sfcmd[4];
-+ uint32_t sfexec;
-+ uint32_t sfstat[4];
-+ uint32_t addr0;
-+ uint32_t addr1;
-+ uint32_t addr2;
-+ uint32_t addr3;
-+ uint32_t addr4;
-+ uint32_t addr5;
-+ uint32_t addr6;
-+ uint32_t data0;
-+ uint32_t data1;
-+ uint32_t data2;
-+ uint32_t data3;
-+ uint32_t data4;
-+ uint32_t data5;
-+ uint32_t data6;
-+ } data;
-+ } *dma_buffer;
-+ dmov_s *cmd;
-+
-+ int err = 0;
-+
-+ uint16_t onenand_startaddr1;
-+ uint16_t onenand_startaddr8;
-+ uint16_t onenand_startaddr2;
-+ uint16_t onenand_startbuffer;
-+
-+ uint16_t controller_status;
-+ uint16_t interrupt_status;
-+ uint16_t ecc_status;
-+
-+ uint64_t temp;
-+
-+#if VERBOSE
-+ pr_info("================================================="
-+ "================\n");
-+ pr_info("%s: addr 0x%llx len 0x%llx\n",
-+ __func__, instr->addr, instr->len);
-+#endif
-+ if (instr->addr & (mtd->erasesize - 1)) {
-+ pr_err("%s: Unsupported erase address, 0x%llx\n",
-+ __func__, instr->addr);
-+ return -EINVAL;
-+ }
-+ if (instr->len != mtd->erasesize) {
-+ pr_err("%s: Unsupported erase len, %lld\n",
-+ __func__, instr->len);
-+ return -EINVAL;
-+ }
-+
-+ wait_event(chip->wait_queue, (dma_buffer = msm_nand_get_dma_buffer
-+ (chip, sizeof(*dma_buffer))));
-+
-+ cmd = dma_buffer->cmd;
-+
-+ temp = instr->addr;
-+
-+ if ((onenand_info.device_id & ONENAND_DEVICE_IS_DDP)
-+ && (temp >= (mtd->size>>1))) { /* DDP Device */
-+ onenand_startaddr1 = DEVICE_FLASHCORE_1 |
-+ (((uint32_t)(temp-(mtd->size>>1))
-+ / mtd->erasesize));
-+ onenand_startaddr2 = DEVICE_BUFFERRAM_1;
-+ } else {
-+ onenand_startaddr1 = DEVICE_FLASHCORE_0 |
-+ ((uint32_t)temp / mtd->erasesize) ;
-+ onenand_startaddr2 = DEVICE_BUFFERRAM_0;
-+ }
-+
-+ onenand_startaddr8 = 0x0000;
-+ onenand_startbuffer = DATARAM0_0 << 8;
-+
-+ dma_buffer->data.sfbcfg = SFLASH_BCFG |
-+ (nand_sfcmd_mode ? 0 : (1 << 24));
-+ dma_buffer->data.sfcmd[0] = SFLASH_PREPCMD(7, 0, 0,
-+ MSM_NAND_SFCMD_CMDXS,
-+ nand_sfcmd_mode,
-+ MSM_NAND_SFCMD_REGWR);
-+ dma_buffer->data.sfcmd[1] = SFLASH_PREPCMD(0, 0, 32,
-+ MSM_NAND_SFCMD_CMDXS,
-+ nand_sfcmd_mode,
-+ MSM_NAND_SFCMD_INTHI);
-+ dma_buffer->data.sfcmd[2] = SFLASH_PREPCMD(3, 7, 0,
-+ MSM_NAND_SFCMD_DATXS,
-+ nand_sfcmd_mode,
-+ MSM_NAND_SFCMD_REGRD);
-+ dma_buffer->data.sfcmd[3] = SFLASH_PREPCMD(4, 10, 0,
-+ MSM_NAND_SFCMD_CMDXS,
-+ nand_sfcmd_mode,
-+ MSM_NAND_SFCMD_REGWR);
-+ dma_buffer->data.sfexec = 1;
-+ dma_buffer->data.sfstat[0] = CLEAN_DATA_32;
-+ dma_buffer->data.sfstat[1] = CLEAN_DATA_32;
-+ dma_buffer->data.sfstat[2] = CLEAN_DATA_32;
-+ dma_buffer->data.sfstat[3] = CLEAN_DATA_32;
-+ dma_buffer->data.addr0 = (ONENAND_INTERRUPT_STATUS << 16) |
-+ (ONENAND_SYSTEM_CONFIG_1);
-+ dma_buffer->data.addr1 = (ONENAND_START_ADDRESS_8 << 16) |
-+ (ONENAND_START_ADDRESS_1);
-+ dma_buffer->data.addr2 = (ONENAND_START_BUFFER << 16) |
-+ (ONENAND_START_ADDRESS_2);
-+ dma_buffer->data.addr3 = (ONENAND_ECC_STATUS << 16) |
-+ (ONENAND_COMMAND);
-+ dma_buffer->data.addr4 = (ONENAND_CONTROLLER_STATUS << 16) |
-+ (ONENAND_INTERRUPT_STATUS);
-+ dma_buffer->data.addr5 = (ONENAND_INTERRUPT_STATUS << 16) |
-+ (ONENAND_SYSTEM_CONFIG_1);
-+ dma_buffer->data.addr6 = (ONENAND_START_ADDRESS_3 << 16) |
-+ (ONENAND_START_ADDRESS_1);
-+ dma_buffer->data.data0 = (ONENAND_CLRINTR << 16) |
-+ (ONENAND_SYSCFG1_ECCENA(nand_sfcmd_mode));
-+ dma_buffer->data.data1 = (onenand_startaddr8 << 16) |
-+ (onenand_startaddr1);
-+ dma_buffer->data.data2 = (onenand_startbuffer << 16) |
-+ (onenand_startaddr2);
-+ dma_buffer->data.data3 = (CLEAN_DATA_16 << 16) |
-+ (ONENAND_CMDERAS);
-+ dma_buffer->data.data4 = (CLEAN_DATA_16 << 16) |
-+ (CLEAN_DATA_16);
-+ dma_buffer->data.data5 = (ONENAND_CLRINTR << 16) |
-+ (ONENAND_SYSCFG1_ECCENA(nand_sfcmd_mode));
-+ dma_buffer->data.data6 = (ONENAND_STARTADDR3_RES << 16) |
-+ (ONENAND_STARTADDR1_RES);
-+
-+ /***************************************************************/
-+ /* Write the necessary address registers in the onenand device */
-+ /***************************************************************/
-+
-+ /* Enable and configure the SFlash controller */
-+ cmd->cmd = 0;
-+ cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.sfbcfg);
-+ cmd->dst = MSM_NAND_SFLASHC_BURST_CFG;
-+ cmd->len = 4;
-+ cmd++;
-+
-+ /* Block on cmd ready and write CMD register */
-+ cmd->cmd = DST_CRCI_NAND_CMD;
-+ cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.sfcmd[0]);
-+ cmd->dst = MSM_NAND_SFLASHC_CMD;
-+ cmd->len = 4;
-+ cmd++;
-+
-+ /* Write the ADDR0 and ADDR1 registers */
-+ cmd->cmd = 0;
-+ cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.addr0);
-+ cmd->dst = MSM_NAND_ADDR0;
-+ cmd->len = 8;
-+ cmd++;
-+
-+ /* Write the ADDR2 ADDR3 ADDR4 ADDR5 registers */
-+ cmd->cmd = 0;
-+ cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.addr2);
-+ cmd->dst = MSM_NAND_ADDR2;
-+ cmd->len = 16;
-+ cmd++;
-+
-+ /* Write the ADDR6 registers */
-+ cmd->cmd = 0;
-+ cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.addr6);
-+ cmd->dst = MSM_NAND_ADDR6;
-+ cmd->len = 4;
-+ cmd++;
-+
-+ /* Write the GENP0, GENP1, GENP2, GENP3, GENP4 registers */
-+ cmd->cmd = 0;
-+ cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.data0);
-+ cmd->dst = MSM_NAND_GENP_REG0;
-+ cmd->len = 16;
-+ cmd++;
-+
-+ /* Write the FLASH_DEV_CMD4,5,6 registers */
-+ cmd->cmd = 0;
-+ cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.data4);
-+ cmd->dst = MSM_NAND_DEV_CMD4;
-+ cmd->len = 12;
-+ cmd++;
-+
-+ /* Kick the execute command */
-+ cmd->cmd = 0;
-+ cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.sfexec);
-+ cmd->dst = MSM_NAND_SFLASHC_EXEC_CMD;
-+ cmd->len = 4;
-+ cmd++;
-+
-+ /* Block on data ready, and read the status register */
-+ cmd->cmd = SRC_CRCI_NAND_DATA;
-+ cmd->src = MSM_NAND_SFLASHC_STATUS;
-+ cmd->dst = msm_virt_to_dma(chip, &dma_buffer->data.sfstat[0]);
-+ cmd->len = 4;
-+ cmd++;
-+
-+ /***************************************************************/
-+ /* Wait for the interrupt from the Onenand device controller */
-+ /***************************************************************/
-+
-+ /* Block on cmd ready and write CMD register */
-+ cmd->cmd = DST_CRCI_NAND_CMD;
-+ cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.sfcmd[1]);
-+ cmd->dst = MSM_NAND_SFLASHC_CMD;
-+ cmd->len = 4;
-+ cmd++;
-+
-+ /* Kick the execute command */
-+ cmd->cmd = 0;
-+ cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.sfexec);
-+ cmd->dst = MSM_NAND_SFLASHC_EXEC_CMD;
-+ cmd->len = 4;
-+ cmd++;
-+
-+ /* Block on data ready, and read the status register */
-+ cmd->cmd = SRC_CRCI_NAND_DATA;
-+ cmd->src = MSM_NAND_SFLASHC_STATUS;
-+ cmd->dst = msm_virt_to_dma(chip, &dma_buffer->data.sfstat[1]);
-+ cmd->len = 4;
-+ cmd++;
-+
-+ /***************************************************************/
-+ /* Read the necessary status registers from the onenand device */
-+ /***************************************************************/
-+
-+ /* Block on cmd ready and write CMD register */
-+ cmd->cmd = DST_CRCI_NAND_CMD;
-+ cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.sfcmd[2]);
-+ cmd->dst = MSM_NAND_SFLASHC_CMD;
-+ cmd->len = 4;
-+ cmd++;
-+
-+ /* Kick the execute command */
-+ cmd->cmd = 0;
-+ cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.sfexec);
-+ cmd->dst = MSM_NAND_SFLASHC_EXEC_CMD;
-+ cmd->len = 4;
-+ cmd++;
-+
-+ /* Block on data ready, and read the status register */
-+ cmd->cmd = SRC_CRCI_NAND_DATA;
-+ cmd->src = MSM_NAND_SFLASHC_STATUS;
-+ cmd->dst = msm_virt_to_dma(chip, &dma_buffer->data.sfstat[2]);
-+ cmd->len = 4;
-+ cmd++;
-+
-+ /* Read the GENP3 register */
-+ cmd->cmd = 0;
-+ cmd->src = MSM_NAND_GENP_REG3;
-+ cmd->dst = msm_virt_to_dma(chip, &dma_buffer->data.data3);
-+ cmd->len = 4;
-+ cmd++;
-+
-+ /* Read the DEVCMD4 register */
-+ cmd->cmd = 0;
-+ cmd->src = MSM_NAND_DEV_CMD4;
-+ cmd->dst = msm_virt_to_dma(chip, &dma_buffer->data.data4);
-+ cmd->len = 4;
-+ cmd++;
-+
-+ /***************************************************************/
-+ /* Restore the necessary registers to proper values */
-+ /***************************************************************/
-+
-+ /* Block on cmd ready and write CMD register */
-+ cmd->cmd = DST_CRCI_NAND_CMD;
-+ cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.sfcmd[3]);
-+ cmd->dst = MSM_NAND_SFLASHC_CMD;
-+ cmd->len = 4;
-+ cmd++;
-+
-+ /* Kick the execute command */
-+ cmd->cmd = 0;
-+ cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.sfexec);
-+ cmd->dst = MSM_NAND_SFLASHC_EXEC_CMD;
-+ cmd->len = 4;
-+ cmd++;
-+
-+ /* Block on data ready, and read the status register */
-+ cmd->cmd = SRC_CRCI_NAND_DATA;
-+ cmd->src = MSM_NAND_SFLASHC_STATUS;
-+ cmd->dst = msm_virt_to_dma(chip, &dma_buffer->data.sfstat[3]);
-+ cmd->len = 4;
-+ cmd++;
-+
-+
-+ BUILD_BUG_ON(20 != ARRAY_SIZE(dma_buffer->cmd));
-+ BUG_ON(cmd - dma_buffer->cmd > ARRAY_SIZE(dma_buffer->cmd));
-+ dma_buffer->cmd[0].cmd |= CMD_OCB;
-+ cmd[-1].cmd |= CMD_OCU | CMD_LC;
-+
-+ dma_buffer->cmdptr = (msm_virt_to_dma(chip, dma_buffer->cmd)
-+ >> 3) | CMD_PTR_LP;
-+
-+ mb();
-+ msm_dmov_exec_cmd(chip->dma_channel, DMOV_CMD_PTR_LIST
-+ | DMOV_CMD_ADDR(msm_virt_to_dma(chip,
-+ &dma_buffer->cmdptr)));
-+ mb();
-+
-+ ecc_status = (dma_buffer->data.data3 >> 16) & 0x0000FFFF;
-+ interrupt_status = (dma_buffer->data.data4 >> 0) & 0x0000FFFF;
-+ controller_status = (dma_buffer->data.data4 >> 16) & 0x0000FFFF;
-+
-+#if VERBOSE
-+ pr_info("\n%s: sflash status %x %x %x %x\n", __func__,
-+ dma_buffer->data.sfstat[0],
-+ dma_buffer->data.sfstat[1],
-+ dma_buffer->data.sfstat[2],
-+ dma_buffer->data.sfstat[3]);
-+
-+ pr_info("%s: controller_status = %x\n", __func__,
-+ controller_status);
-+ pr_info("%s: interrupt_status = %x\n", __func__,
-+ interrupt_status);
-+ pr_info("%s: ecc_status = %x\n", __func__,
-+ ecc_status);
-+#endif
-+ /* Check for errors, protection violations etc */
-+ if ((controller_status != 0)
-+ || (dma_buffer->data.sfstat[0] & 0x110)
-+ || (dma_buffer->data.sfstat[1] & 0x110)
-+ || (dma_buffer->data.sfstat[2] & 0x110)
-+ || (dma_buffer->data.sfstat[3] & 0x110)) {
-+ pr_err("%s: ECC/MPU/OP error\n", __func__);
-+ err = -EIO;
-+ }
-+
-+ msm_nand_release_dma_buffer(chip, dma_buffer, sizeof(*dma_buffer));
-+
-+ if (err) {
-+ pr_err("%s: Erase failed, 0x%llx\n", __func__,
-+ instr->addr);
-+ instr->fail_addr = instr->addr;
-+ instr->state = MTD_ERASE_FAILED;
-+ } else {
-+ instr->state = MTD_ERASE_DONE;
-+ instr->fail_addr = 0xffffffff;
-+ mtd_erase_callback(instr);
-+ }
-+
-+#if VERBOSE
-+ pr_info("\n%s: ret %d\n", __func__, err);
-+ pr_info("===================================================="
-+ "=============\n");
-+#endif
-+ return err;
-+}
-+
-+static int msm_onenand_block_isbad(struct mtd_info *mtd, loff_t ofs)
-+{
-+ struct mtd_oob_ops ops;
-+ int rval, i;
-+ int ret = 0;
-+ uint8_t *buffer;
-+ uint8_t *oobptr;
-+
-+ if ((ofs > mtd->size) || (ofs & (mtd->erasesize - 1))) {
-+ pr_err("%s: unsupported block address, 0x%x\n",
-+ __func__, (uint32_t)ofs);
-+ return -EINVAL;
-+ }
-+
-+ buffer = kmalloc(2112, GFP_KERNEL|GFP_DMA);
-+ if (buffer == 0) {
-+ pr_err("%s: Could not kmalloc for buffer\n",
-+ __func__);
-+ return -ENOMEM;
-+ }
-+
-+ memset(buffer, 0x00, 2112);
-+ oobptr = &(buffer[2048]);
-+
-+ ops.mode = MTD_OPS_RAW;
-+ ops.len = 2112;
-+ ops.retlen = 0;
-+ ops.ooblen = 0;
-+ ops.oobretlen = 0;
-+ ops.ooboffs = 0;
-+ ops.datbuf = buffer;
-+ ops.oobbuf = NULL;
-+
-+ for (i = 0; i < 2; i++) {
-+ ofs = ofs + i*mtd->writesize;
-+ rval = msm_onenand_read_oob(mtd, ofs, &ops);
-+ if (rval) {
-+ pr_err("%s: Error in reading bad blk info\n",
-+ __func__);
-+ ret = rval;
-+ break;
-+ }
-+ if ((oobptr[0] != 0xFF) || (oobptr[1] != 0xFF) ||
-+ (oobptr[16] != 0xFF) || (oobptr[17] != 0xFF) ||
-+ (oobptr[32] != 0xFF) || (oobptr[33] != 0xFF) ||
-+ (oobptr[48] != 0xFF) || (oobptr[49] != 0xFF)
-+ ) {
-+ ret = 1;
-+ break;
-+ }
-+ }
-+
-+ kfree(buffer);
-+
-+#if VERBOSE
-+ if (ret == 1)
-+ pr_info("%s : Block containing 0x%x is bad\n",
-+ __func__, (unsigned int)ofs);
-+#endif
-+ return ret;
-+}
-+
-+static int msm_onenand_block_markbad(struct mtd_info *mtd, loff_t ofs)
-+{
-+ struct mtd_oob_ops ops;
-+ int rval, i;
-+ int ret = 0;
-+ uint8_t *buffer;
-+
-+ if ((ofs > mtd->size) || (ofs & (mtd->erasesize - 1))) {
-+ pr_err("%s: unsupported block address, 0x%x\n",
-+ __func__, (uint32_t)ofs);
-+ return -EINVAL;
-+ }
-+
-+ buffer = page_address(ZERO_PAGE());
-+
-+ ops.mode = MTD_OPS_RAW;
-+ ops.len = 2112;
-+ ops.retlen = 0;
-+ ops.ooblen = 0;
-+ ops.oobretlen = 0;
-+ ops.ooboffs = 0;
-+ ops.datbuf = buffer;
-+ ops.oobbuf = NULL;
-+
-+ for (i = 0; i < 2; i++) {
-+ ofs = ofs + i*mtd->writesize;
-+ rval = msm_onenand_write_oob(mtd, ofs, &ops);
-+ if (rval) {
-+ pr_err("%s: Error in writing bad blk info\n",
-+ __func__);
-+ ret = rval;
-+ break;
-+ }
-+ }
-+
-+ return ret;
-+}
-+
-+static int msm_onenand_unlock(struct mtd_info *mtd, loff_t ofs, uint64_t len)
-+{
-+ struct msm_nand_chip *chip = mtd->priv;
-+
-+ struct {
-+ dmov_s cmd[20];
-+ unsigned cmdptr;
-+ struct {
-+ uint32_t sfbcfg;
-+ uint32_t sfcmd[4];
-+ uint32_t sfexec;
-+ uint32_t sfstat[4];
-+ uint32_t addr0;
-+ uint32_t addr1;
-+ uint32_t addr2;
-+ uint32_t addr3;
-+ uint32_t addr4;
-+ uint32_t addr5;
-+ uint32_t addr6;
-+ uint32_t data0;
-+ uint32_t data1;
-+ uint32_t data2;
-+ uint32_t data3;
-+ uint32_t data4;
-+ uint32_t data5;
-+ uint32_t data6;
-+ } data;
-+ } *dma_buffer;
-+ dmov_s *cmd;
-+
-+ int err = 0;
-+
-+ uint16_t onenand_startaddr1;
-+ uint16_t onenand_startaddr8;
-+ uint16_t onenand_startaddr2;
-+ uint16_t onenand_startblock;
-+
-+ uint16_t controller_status;
-+ uint16_t interrupt_status;
-+ uint16_t write_prot_status;
-+
-+ uint64_t start_ofs;
-+
-+#if VERBOSE
-+ pr_info("===================================================="
-+ "=============\n");
-+ pr_info("%s: ofs 0x%llx len %lld\n", __func__, ofs, len);
-+#endif
-+ /* 'ofs' & 'len' should align to block size */
-+ if (ofs&(mtd->erasesize - 1)) {
-+ pr_err("%s: Unsupported ofs address, 0x%llx\n",
-+ __func__, ofs);
-+ return -EINVAL;
-+ }
-+
-+ if (len&(mtd->erasesize - 1)) {
-+ pr_err("%s: Unsupported len, %lld\n",
-+ __func__, len);
-+ return -EINVAL;
-+ }
-+
-+ if (ofs+len > mtd->size) {
-+ pr_err("%s: Maximum chip size exceeded\n", __func__);
-+ return -EINVAL;
-+ }
-+
-+ wait_event(chip->wait_queue, (dma_buffer = msm_nand_get_dma_buffer
-+ (chip, sizeof(*dma_buffer))));
-+
-+ for (start_ofs = ofs; ofs < start_ofs+len; ofs = ofs+mtd->erasesize) {
-+#if VERBOSE
-+ pr_info("%s: ofs 0x%llx len %lld\n", __func__, ofs, len);
-+#endif
-+
-+ cmd = dma_buffer->cmd;
-+ if ((onenand_info.device_id & ONENAND_DEVICE_IS_DDP)
-+ && (ofs >= (mtd->size>>1))) { /* DDP Device */
-+ onenand_startaddr1 = DEVICE_FLASHCORE_1 |
-+ (((uint32_t)(ofs - (mtd->size>>1))
-+ / mtd->erasesize));
-+ onenand_startaddr2 = DEVICE_BUFFERRAM_1;
-+ onenand_startblock = ((uint32_t)(ofs - (mtd->size>>1))
-+ / mtd->erasesize);
-+ } else {
-+ onenand_startaddr1 = DEVICE_FLASHCORE_0 |
-+ ((uint32_t)ofs / mtd->erasesize) ;
-+ onenand_startaddr2 = DEVICE_BUFFERRAM_0;
-+ onenand_startblock = ((uint32_t)ofs
-+ / mtd->erasesize);
-+ }
-+
-+ onenand_startaddr8 = 0x0000;
-+ dma_buffer->data.sfbcfg = SFLASH_BCFG |
-+ (nand_sfcmd_mode ? 0 : (1 << 24));
-+ dma_buffer->data.sfcmd[0] = SFLASH_PREPCMD(7, 0, 0,
-+ MSM_NAND_SFCMD_CMDXS,
-+ nand_sfcmd_mode,
-+ MSM_NAND_SFCMD_REGWR);
-+ dma_buffer->data.sfcmd[1] = SFLASH_PREPCMD(0, 0, 32,
-+ MSM_NAND_SFCMD_CMDXS,
-+ nand_sfcmd_mode,
-+ MSM_NAND_SFCMD_INTHI);
-+ dma_buffer->data.sfcmd[2] = SFLASH_PREPCMD(3, 7, 0,
-+ MSM_NAND_SFCMD_DATXS,
-+ nand_sfcmd_mode,
-+ MSM_NAND_SFCMD_REGRD);
-+ dma_buffer->data.sfcmd[3] = SFLASH_PREPCMD(4, 10, 0,
-+ MSM_NAND_SFCMD_CMDXS,
-+ nand_sfcmd_mode,
-+ MSM_NAND_SFCMD_REGWR);
-+ dma_buffer->data.sfexec = 1;
-+ dma_buffer->data.sfstat[0] = CLEAN_DATA_32;
-+ dma_buffer->data.sfstat[1] = CLEAN_DATA_32;
-+ dma_buffer->data.sfstat[2] = CLEAN_DATA_32;
-+ dma_buffer->data.sfstat[3] = CLEAN_DATA_32;
-+ dma_buffer->data.addr0 = (ONENAND_INTERRUPT_STATUS << 16) |
-+ (ONENAND_SYSTEM_CONFIG_1);
-+ dma_buffer->data.addr1 = (ONENAND_START_ADDRESS_8 << 16) |
-+ (ONENAND_START_ADDRESS_1);
-+ dma_buffer->data.addr2 = (ONENAND_START_BLOCK_ADDRESS << 16) |
-+ (ONENAND_START_ADDRESS_2);
-+ dma_buffer->data.addr3 = (ONENAND_WRITE_PROT_STATUS << 16) |
-+ (ONENAND_COMMAND);
-+ dma_buffer->data.addr4 = (ONENAND_CONTROLLER_STATUS << 16) |
-+ (ONENAND_INTERRUPT_STATUS);
-+ dma_buffer->data.addr5 = (ONENAND_INTERRUPT_STATUS << 16) |
-+ (ONENAND_SYSTEM_CONFIG_1);
-+ dma_buffer->data.addr6 = (ONENAND_START_ADDRESS_3 << 16) |
-+ (ONENAND_START_ADDRESS_1);
-+ dma_buffer->data.data0 = (ONENAND_CLRINTR << 16) |
-+ (ONENAND_SYSCFG1_ECCENA(nand_sfcmd_mode));
-+ dma_buffer->data.data1 = (onenand_startaddr8 << 16) |
-+ (onenand_startaddr1);
-+ dma_buffer->data.data2 = (onenand_startblock << 16) |
-+ (onenand_startaddr2);
-+ dma_buffer->data.data3 = (CLEAN_DATA_16 << 16) |
-+ (ONENAND_CMD_UNLOCK);
-+ dma_buffer->data.data4 = (CLEAN_DATA_16 << 16) |
-+ (CLEAN_DATA_16);
-+ dma_buffer->data.data5 = (ONENAND_CLRINTR << 16) |
-+ (ONENAND_SYSCFG1_ECCENA(nand_sfcmd_mode));
-+ dma_buffer->data.data6 = (ONENAND_STARTADDR3_RES << 16) |
-+ (ONENAND_STARTADDR1_RES);
-+
-+ /*************************************************************/
-+ /* Write the necessary address reg in the onenand device */
-+ /*************************************************************/
-+
-+ /* Enable and configure the SFlash controller */
-+ cmd->cmd = 0;
-+ cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.sfbcfg);
-+ cmd->dst = MSM_NAND_SFLASHC_BURST_CFG;
-+ cmd->len = 4;
-+ cmd++;
-+
-+ /* Block on cmd ready and write CMD register */
-+ cmd->cmd = DST_CRCI_NAND_CMD;
-+ cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.sfcmd[0]);
-+ cmd->dst = MSM_NAND_SFLASHC_CMD;
-+ cmd->len = 4;
-+ cmd++;
-+
-+ /* Write the ADDR0 and ADDR1 registers */
-+ cmd->cmd = 0;
-+ cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.addr0);
-+ cmd->dst = MSM_NAND_ADDR0;
-+ cmd->len = 8;
-+ cmd++;
-+
-+ /* Write the ADDR2 ADDR3 ADDR4 ADDR5 registers */
-+ cmd->cmd = 0;
-+ cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.addr2);
-+ cmd->dst = MSM_NAND_ADDR2;
-+ cmd->len = 16;
-+ cmd++;
-+
-+ /* Write the ADDR6 registers */
-+ cmd->cmd = 0;
-+ cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.addr6);
-+ cmd->dst = MSM_NAND_ADDR6;
-+ cmd->len = 4;
-+ cmd++;
-+
-+ /* Write the GENP0, GENP1, GENP2, GENP3, GENP4 registers */
-+ cmd->cmd = 0;
-+ cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.data0);
-+ cmd->dst = MSM_NAND_GENP_REG0;
-+ cmd->len = 16;
-+ cmd++;
-+
-+ /* Write the FLASH_DEV_CMD4,5,6 registers */
-+ cmd->cmd = 0;
-+ cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.data4);
-+ cmd->dst = MSM_NAND_DEV_CMD4;
-+ cmd->len = 12;
-+ cmd++;
-+
-+ /* Kick the execute command */
-+ cmd->cmd = 0;
-+ cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.sfexec);
-+ cmd->dst = MSM_NAND_SFLASHC_EXEC_CMD;
-+ cmd->len = 4;
-+ cmd++;
-+
-+ /* Block on data ready, and read the status register */
-+ cmd->cmd = SRC_CRCI_NAND_DATA;
-+ cmd->src = MSM_NAND_SFLASHC_STATUS;
-+ cmd->dst = msm_virt_to_dma(chip, &dma_buffer->data.sfstat[0]);
-+ cmd->len = 4;
-+ cmd++;
-+
-+ /*************************************************************/
-+ /* Wait for the interrupt from the Onenand device controller */
-+ /*************************************************************/
-+
-+ /* Block on cmd ready and write CMD register */
-+ cmd->cmd = DST_CRCI_NAND_CMD;
-+ cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.sfcmd[1]);
-+ cmd->dst = MSM_NAND_SFLASHC_CMD;
-+ cmd->len = 4;
-+ cmd++;
-+
-+ /* Kick the execute command */
-+ cmd->cmd = 0;
-+ cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.sfexec);
-+ cmd->dst = MSM_NAND_SFLASHC_EXEC_CMD;
-+ cmd->len = 4;
-+ cmd++;
-+
-+ /* Block on data ready, and read the status register */
-+ cmd->cmd = SRC_CRCI_NAND_DATA;
-+ cmd->src = MSM_NAND_SFLASHC_STATUS;
-+ cmd->dst = msm_virt_to_dma(chip, &dma_buffer->data.sfstat[1]);
-+ cmd->len = 4;
-+ cmd++;
-+
-+ /*********************************************************/
-+ /* Read the necessary status reg from the onenand device */
-+ /*********************************************************/
-+
-+ /* Block on cmd ready and write CMD register */
-+ cmd->cmd = DST_CRCI_NAND_CMD;
-+ cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.sfcmd[2]);
-+ cmd->dst = MSM_NAND_SFLASHC_CMD;
-+ cmd->len = 4;
-+ cmd++;
-+
-+ /* Kick the execute command */
-+ cmd->cmd = 0;
-+ cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.sfexec);
-+ cmd->dst = MSM_NAND_SFLASHC_EXEC_CMD;
-+ cmd->len = 4;
-+ cmd++;
-+
-+ /* Block on data ready, and read the status register */
-+ cmd->cmd = SRC_CRCI_NAND_DATA;
-+ cmd->src = MSM_NAND_SFLASHC_STATUS;
-+ cmd->dst = msm_virt_to_dma(chip, &dma_buffer->data.sfstat[2]);
-+ cmd->len = 4;
-+ cmd++;
-+
-+ /* Read the GENP3 register */
-+ cmd->cmd = 0;
-+ cmd->src = MSM_NAND_GENP_REG3;
-+ cmd->dst = msm_virt_to_dma(chip, &dma_buffer->data.data3);
-+ cmd->len = 4;
-+ cmd++;
-+
-+ /* Read the DEVCMD4 register */
-+ cmd->cmd = 0;
-+ cmd->src = MSM_NAND_DEV_CMD4;
-+ cmd->dst = msm_virt_to_dma(chip, &dma_buffer->data.data4);
-+ cmd->len = 4;
-+ cmd++;
-+
-+ /************************************************************/
-+ /* Restore the necessary registers to proper values */
-+ /************************************************************/
-+
-+ /* Block on cmd ready and write CMD register */
-+ cmd->cmd = DST_CRCI_NAND_CMD;
-+ cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.sfcmd[3]);
-+ cmd->dst = MSM_NAND_SFLASHC_CMD;
-+ cmd->len = 4;
-+ cmd++;
-+
-+ /* Kick the execute command */
-+ cmd->cmd = 0;
-+ cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.sfexec);
-+ cmd->dst = MSM_NAND_SFLASHC_EXEC_CMD;
-+ cmd->len = 4;
-+ cmd++;
-+
-+ /* Block on data ready, and read the status register */
-+ cmd->cmd = SRC_CRCI_NAND_DATA;
-+ cmd->src = MSM_NAND_SFLASHC_STATUS;
-+ cmd->dst = msm_virt_to_dma(chip, &dma_buffer->data.sfstat[3]);
-+ cmd->len = 4;
-+ cmd++;
-+
-+
-+ BUILD_BUG_ON(20 != ARRAY_SIZE(dma_buffer->cmd));
-+ BUG_ON(cmd - dma_buffer->cmd > ARRAY_SIZE(dma_buffer->cmd));
-+ dma_buffer->cmd[0].cmd |= CMD_OCB;
-+ cmd[-1].cmd |= CMD_OCU | CMD_LC;
-+
-+ dma_buffer->cmdptr = (msm_virt_to_dma(chip, dma_buffer->cmd)
-+ >> 3) | CMD_PTR_LP;
-+
-+ mb();
-+ msm_dmov_exec_cmd(chip->dma_channel,
-+ DMOV_CMD_PTR_LIST | DMOV_CMD_ADDR(msm_virt_to_dma(chip,
-+ &dma_buffer->cmdptr)));
-+ mb();
-+
-+ write_prot_status = (dma_buffer->data.data3 >> 16) & 0x0000FFFF;
-+ interrupt_status = (dma_buffer->data.data4 >> 0) & 0x0000FFFF;
-+ controller_status = (dma_buffer->data.data4 >> 16) & 0x0000FFFF;
-+
-+#if VERBOSE
-+ pr_info("\n%s: sflash status %x %x %x %x\n", __func__,
-+ dma_buffer->data.sfstat[0],
-+ dma_buffer->data.sfstat[1],
-+ dma_buffer->data.sfstat[2],
-+ dma_buffer->data.sfstat[3]);
-+
-+ pr_info("%s: controller_status = %x\n", __func__,
-+ controller_status);
-+ pr_info("%s: interrupt_status = %x\n", __func__,
-+ interrupt_status);
-+ pr_info("%s: write_prot_status = %x\n", __func__,
-+ write_prot_status);
-+#endif
-+ /* Check for errors, protection violations etc */
-+ if ((controller_status != 0)
-+ || (dma_buffer->data.sfstat[0] & 0x110)
-+ || (dma_buffer->data.sfstat[1] & 0x110)
-+ || (dma_buffer->data.sfstat[2] & 0x110)
-+ || (dma_buffer->data.sfstat[3] & 0x110)) {
-+ pr_err("%s: ECC/MPU/OP error\n", __func__);
-+ err = -EIO;
-+ }
-+
-+ if (!(write_prot_status & ONENAND_WP_US)) {
-+ pr_err("%s: Unexpected status ofs = 0x%llx,"
-+ "wp_status = %x\n",
-+ __func__, ofs, write_prot_status);
-+ err = -EIO;
-+ }
-+
-+ if (err)
-+ break;
-+ }
-+
-+ msm_nand_release_dma_buffer(chip, dma_buffer, sizeof(*dma_buffer));
-+
-+#if VERBOSE
-+ pr_info("\n%s: ret %d\n", __func__, err);
-+ pr_info("===================================================="
-+ "=============\n");
-+#endif
-+ return err;
-+}
-+
-+static int msm_onenand_lock(struct mtd_info *mtd, loff_t ofs, uint64_t len)
-+{
-+ struct msm_nand_chip *chip = mtd->priv;
-+
-+ struct {
-+ dmov_s cmd[20];
-+ unsigned cmdptr;
-+ struct {
-+ uint32_t sfbcfg;
-+ uint32_t sfcmd[4];
-+ uint32_t sfexec;
-+ uint32_t sfstat[4];
-+ uint32_t addr0;
-+ uint32_t addr1;
-+ uint32_t addr2;
-+ uint32_t addr3;
-+ uint32_t addr4;
-+ uint32_t addr5;
-+ uint32_t addr6;
-+ uint32_t data0;
-+ uint32_t data1;
-+ uint32_t data2;
-+ uint32_t data3;
-+ uint32_t data4;
-+ uint32_t data5;
-+ uint32_t data6;
-+ } data;
-+ } *dma_buffer;
-+ dmov_s *cmd;
-+
-+ int err = 0;
-+
-+ uint16_t onenand_startaddr1;
-+ uint16_t onenand_startaddr8;
-+ uint16_t onenand_startaddr2;
-+ uint16_t onenand_startblock;
-+
-+ uint16_t controller_status;
-+ uint16_t interrupt_status;
-+ uint16_t write_prot_status;
-+
-+ uint64_t start_ofs;
-+
-+#if VERBOSE
-+ pr_info("===================================================="
-+ "=============\n");
-+ pr_info("%s: ofs 0x%llx len %lld\n", __func__, ofs, len);
-+#endif
-+ /* 'ofs' & 'len' should align to block size */
-+ if (ofs&(mtd->erasesize - 1)) {
-+ pr_err("%s: Unsupported ofs address, 0x%llx\n",
-+ __func__, ofs);
-+ return -EINVAL;
-+ }
-+
-+ if (len&(mtd->erasesize - 1)) {
-+ pr_err("%s: Unsupported len, %lld\n",
-+ __func__, len);
-+ return -EINVAL;
-+ }
-+
-+ if (ofs+len > mtd->size) {
-+ pr_err("%s: Maximum chip size exceeded\n", __func__);
-+ return -EINVAL;
-+ }
-+
-+ wait_event(chip->wait_queue, (dma_buffer = msm_nand_get_dma_buffer
-+ (chip, sizeof(*dma_buffer))));
-+
-+ for (start_ofs = ofs; ofs < start_ofs+len; ofs = ofs+mtd->erasesize) {
-+#if VERBOSE
-+ pr_info("%s: ofs 0x%llx len %lld\n", __func__, ofs, len);
-+#endif
-+
-+ cmd = dma_buffer->cmd;
-+ if ((onenand_info.device_id & ONENAND_DEVICE_IS_DDP)
-+ && (ofs >= (mtd->size>>1))) { /* DDP Device */
-+ onenand_startaddr1 = DEVICE_FLASHCORE_1 |
-+ (((uint32_t)(ofs - (mtd->size>>1))
-+ / mtd->erasesize));
-+ onenand_startaddr2 = DEVICE_BUFFERRAM_1;
-+ onenand_startblock = ((uint32_t)(ofs - (mtd->size>>1))
-+ / mtd->erasesize);
-+ } else {
-+ onenand_startaddr1 = DEVICE_FLASHCORE_0 |
-+ ((uint32_t)ofs / mtd->erasesize) ;
-+ onenand_startaddr2 = DEVICE_BUFFERRAM_0;
-+ onenand_startblock = ((uint32_t)ofs
-+ / mtd->erasesize);
-+ }
-+
-+ onenand_startaddr8 = 0x0000;
-+ dma_buffer->data.sfbcfg = SFLASH_BCFG |
-+ (nand_sfcmd_mode ? 0 : (1 << 24));
-+ dma_buffer->data.sfcmd[0] = SFLASH_PREPCMD(7, 0, 0,
-+ MSM_NAND_SFCMD_CMDXS,
-+ nand_sfcmd_mode,
-+ MSM_NAND_SFCMD_REGWR);
-+ dma_buffer->data.sfcmd[1] = SFLASH_PREPCMD(0, 0, 32,
-+ MSM_NAND_SFCMD_CMDXS,
-+ nand_sfcmd_mode,
-+ MSM_NAND_SFCMD_INTHI);
-+ dma_buffer->data.sfcmd[2] = SFLASH_PREPCMD(3, 7, 0,
-+ MSM_NAND_SFCMD_DATXS,
-+ nand_sfcmd_mode,
-+ MSM_NAND_SFCMD_REGRD);
-+ dma_buffer->data.sfcmd[3] = SFLASH_PREPCMD(4, 10, 0,
-+ MSM_NAND_SFCMD_CMDXS,
-+ nand_sfcmd_mode,
-+ MSM_NAND_SFCMD_REGWR);
-+ dma_buffer->data.sfexec = 1;
-+ dma_buffer->data.sfstat[0] = CLEAN_DATA_32;
-+ dma_buffer->data.sfstat[1] = CLEAN_DATA_32;
-+ dma_buffer->data.sfstat[2] = CLEAN_DATA_32;
-+ dma_buffer->data.sfstat[3] = CLEAN_DATA_32;
-+ dma_buffer->data.addr0 = (ONENAND_INTERRUPT_STATUS << 16) |
-+ (ONENAND_SYSTEM_CONFIG_1);
-+ dma_buffer->data.addr1 = (ONENAND_START_ADDRESS_8 << 16) |
-+ (ONENAND_START_ADDRESS_1);
-+ dma_buffer->data.addr2 = (ONENAND_START_BLOCK_ADDRESS << 16) |
-+ (ONENAND_START_ADDRESS_2);
-+ dma_buffer->data.addr3 = (ONENAND_WRITE_PROT_STATUS << 16) |
-+ (ONENAND_COMMAND);
-+ dma_buffer->data.addr4 = (ONENAND_CONTROLLER_STATUS << 16) |
-+ (ONENAND_INTERRUPT_STATUS);
-+ dma_buffer->data.addr5 = (ONENAND_INTERRUPT_STATUS << 16) |
-+ (ONENAND_SYSTEM_CONFIG_1);
-+ dma_buffer->data.addr6 = (ONENAND_START_ADDRESS_3 << 16) |
-+ (ONENAND_START_ADDRESS_1);
-+ dma_buffer->data.data0 = (ONENAND_CLRINTR << 16) |
-+ (ONENAND_SYSCFG1_ECCENA(nand_sfcmd_mode));
-+ dma_buffer->data.data1 = (onenand_startaddr8 << 16) |
-+ (onenand_startaddr1);
-+ dma_buffer->data.data2 = (onenand_startblock << 16) |
-+ (onenand_startaddr2);
-+ dma_buffer->data.data3 = (CLEAN_DATA_16 << 16) |
-+ (ONENAND_CMD_LOCK);
-+ dma_buffer->data.data4 = (CLEAN_DATA_16 << 16) |
-+ (CLEAN_DATA_16);
-+ dma_buffer->data.data5 = (ONENAND_CLRINTR << 16) |
-+ (ONENAND_SYSCFG1_ECCENA(nand_sfcmd_mode));
-+ dma_buffer->data.data6 = (ONENAND_STARTADDR3_RES << 16) |
-+ (ONENAND_STARTADDR1_RES);
-+
-+ /*************************************************************/
-+ /* Write the necessary address reg in the onenand device */
-+ /*************************************************************/
-+
-+ /* Enable and configure the SFlash controller */
-+ cmd->cmd = 0;
-+ cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.sfbcfg);
-+ cmd->dst = MSM_NAND_SFLASHC_BURST_CFG;
-+ cmd->len = 4;
-+ cmd++;
-+
-+ /* Block on cmd ready and write CMD register */
-+ cmd->cmd = DST_CRCI_NAND_CMD;
-+ cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.sfcmd[0]);
-+ cmd->dst = MSM_NAND_SFLASHC_CMD;
-+ cmd->len = 4;
-+ cmd++;
-+
-+ /* Write the ADDR0 and ADDR1 registers */
-+ cmd->cmd = 0;
-+ cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.addr0);
-+ cmd->dst = MSM_NAND_ADDR0;
-+ cmd->len = 8;
-+ cmd++;
-+
-+ /* Write the ADDR2 ADDR3 ADDR4 ADDR5 registers */
-+ cmd->cmd = 0;
-+ cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.addr2);
-+ cmd->dst = MSM_NAND_ADDR2;
-+ cmd->len = 16;
-+ cmd++;
-+
-+ /* Write the ADDR6 registers */
-+ cmd->cmd = 0;
-+ cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.addr6);
-+ cmd->dst = MSM_NAND_ADDR6;
-+ cmd->len = 4;
-+ cmd++;
-+
-+ /* Write the GENP0, GENP1, GENP2, GENP3, GENP4 registers */
-+ cmd->cmd = 0;
-+ cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.data0);
-+ cmd->dst = MSM_NAND_GENP_REG0;
-+ cmd->len = 16;
-+ cmd++;
-+
-+ /* Write the FLASH_DEV_CMD4,5,6 registers */
-+ cmd->cmd = 0;
-+ cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.data4);
-+ cmd->dst = MSM_NAND_DEV_CMD4;
-+ cmd->len = 12;
-+ cmd++;
-+
-+ /* Kick the execute command */
-+ cmd->cmd = 0;
-+ cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.sfexec);
-+ cmd->dst = MSM_NAND_SFLASHC_EXEC_CMD;
-+ cmd->len = 4;
-+ cmd++;
-+
-+ /* Block on data ready, and read the status register */
-+ cmd->cmd = SRC_CRCI_NAND_DATA;
-+ cmd->src = MSM_NAND_SFLASHC_STATUS;
-+ cmd->dst = msm_virt_to_dma(chip, &dma_buffer->data.sfstat[0]);
-+ cmd->len = 4;
-+ cmd++;
-+
-+ /*************************************************************/
-+ /* Wait for the interrupt from the Onenand device controller */
-+ /*************************************************************/
-+
-+ /* Block on cmd ready and write CMD register */
-+ cmd->cmd = DST_CRCI_NAND_CMD;
-+ cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.sfcmd[1]);
-+ cmd->dst = MSM_NAND_SFLASHC_CMD;
-+ cmd->len = 4;
-+ cmd++;
-+
-+ /* Kick the execute command */
-+ cmd->cmd = 0;
-+ cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.sfexec);
-+ cmd->dst = MSM_NAND_SFLASHC_EXEC_CMD;
-+ cmd->len = 4;
-+ cmd++;
-+
-+ /* Block on data ready, and read the status register */
-+ cmd->cmd = SRC_CRCI_NAND_DATA;
-+ cmd->src = MSM_NAND_SFLASHC_STATUS;
-+ cmd->dst = msm_virt_to_dma(chip, &dma_buffer->data.sfstat[1]);
-+ cmd->len = 4;
-+ cmd++;
-+
-+ /*********************************************************/
-+ /* Read the necessary status reg from the onenand device */
-+ /*********************************************************/
-+
-+ /* Block on cmd ready and write CMD register */
-+ cmd->cmd = DST_CRCI_NAND_CMD;
-+ cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.sfcmd[2]);
-+ cmd->dst = MSM_NAND_SFLASHC_CMD;
-+ cmd->len = 4;
-+ cmd++;
-+
-+ /* Kick the execute command */
-+ cmd->cmd = 0;
-+ cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.sfexec);
-+ cmd->dst = MSM_NAND_SFLASHC_EXEC_CMD;
-+ cmd->len = 4;
-+ cmd++;
-+
-+ /* Block on data ready, and read the status register */
-+ cmd->cmd = SRC_CRCI_NAND_DATA;
-+ cmd->src = MSM_NAND_SFLASHC_STATUS;
-+ cmd->dst = msm_virt_to_dma(chip, &dma_buffer->data.sfstat[2]);
-+ cmd->len = 4;
-+ cmd++;
-+
-+ /* Read the GENP3 register */
-+ cmd->cmd = 0;
-+ cmd->src = MSM_NAND_GENP_REG3;
-+ cmd->dst = msm_virt_to_dma(chip, &dma_buffer->data.data3);
-+ cmd->len = 4;
-+ cmd++;
-+
-+ /* Read the DEVCMD4 register */
-+ cmd->cmd = 0;
-+ cmd->src = MSM_NAND_DEV_CMD4;
-+ cmd->dst = msm_virt_to_dma(chip, &dma_buffer->data.data4);
-+ cmd->len = 4;
-+ cmd++;
-+
-+ /************************************************************/
-+ /* Restore the necessary registers to proper values */
-+ /************************************************************/
-+
-+ /* Block on cmd ready and write CMD register */
-+ cmd->cmd = DST_CRCI_NAND_CMD;
-+ cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.sfcmd[3]);
-+ cmd->dst = MSM_NAND_SFLASHC_CMD;
-+ cmd->len = 4;
-+ cmd++;
-+
-+ /* Kick the execute command */
-+ cmd->cmd = 0;
-+ cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.sfexec);
-+ cmd->dst = MSM_NAND_SFLASHC_EXEC_CMD;
-+ cmd->len = 4;
-+ cmd++;
-+
-+ /* Block on data ready, and read the status register */
-+ cmd->cmd = SRC_CRCI_NAND_DATA;
-+ cmd->src = MSM_NAND_SFLASHC_STATUS;
-+ cmd->dst = msm_virt_to_dma(chip, &dma_buffer->data.sfstat[3]);
-+ cmd->len = 4;
-+ cmd++;
-+
-+
-+ BUILD_BUG_ON(20 != ARRAY_SIZE(dma_buffer->cmd));
-+ BUG_ON(cmd - dma_buffer->cmd > ARRAY_SIZE(dma_buffer->cmd));
-+ dma_buffer->cmd[0].cmd |= CMD_OCB;
-+ cmd[-1].cmd |= CMD_OCU | CMD_LC;
-+
-+ dma_buffer->cmdptr = (msm_virt_to_dma(chip, dma_buffer->cmd)
-+ >> 3) | CMD_PTR_LP;
-+
-+ mb();
-+ msm_dmov_exec_cmd(chip->dma_channel,
-+ DMOV_CMD_PTR_LIST | DMOV_CMD_ADDR(msm_virt_to_dma(chip,
-+ &dma_buffer->cmdptr)));
-+ mb();
-+
-+ write_prot_status = (dma_buffer->data.data3 >> 16) & 0x0000FFFF;
-+ interrupt_status = (dma_buffer->data.data4 >> 0) & 0x0000FFFF;
-+ controller_status = (dma_buffer->data.data4 >> 16) & 0x0000FFFF;
-+
-+#if VERBOSE
-+ pr_info("\n%s: sflash status %x %x %x %x\n", __func__,
-+ dma_buffer->data.sfstat[0],
-+ dma_buffer->data.sfstat[1],
-+ dma_buffer->data.sfstat[2],
-+ dma_buffer->data.sfstat[3]);
-+
-+ pr_info("%s: controller_status = %x\n", __func__,
-+ controller_status);
-+ pr_info("%s: interrupt_status = %x\n", __func__,
-+ interrupt_status);
-+ pr_info("%s: write_prot_status = %x\n", __func__,
-+ write_prot_status);
-+#endif
-+ /* Check for errors, protection violations etc */
-+ if ((controller_status != 0)
-+ || (dma_buffer->data.sfstat[0] & 0x110)
-+ || (dma_buffer->data.sfstat[1] & 0x110)
-+ || (dma_buffer->data.sfstat[2] & 0x110)
-+ || (dma_buffer->data.sfstat[3] & 0x110)) {
-+ pr_err("%s: ECC/MPU/OP error\n", __func__);
-+ err = -EIO;
-+ }
-+
-+ if (!(write_prot_status & ONENAND_WP_LS)) {
-+ pr_err("%s: Unexpected status ofs = 0x%llx,"
-+ "wp_status = %x\n",
-+ __func__, ofs, write_prot_status);
-+ err = -EIO;
-+ }
-+
-+ if (err)
-+ break;
-+ }
-+
-+ msm_nand_release_dma_buffer(chip, dma_buffer, sizeof(*dma_buffer));
-+
-+#if VERBOSE
-+ pr_info("\n%s: ret %d\n", __func__, err);
-+ pr_info("===================================================="
-+ "=============\n");
-+#endif
-+ return err;
-+}
-+
-+static int msm_onenand_suspend(struct mtd_info *mtd)
-+{
-+ return 0;
-+}
-+
-+static void msm_onenand_resume(struct mtd_info *mtd)
-+{
-+}
-+
-+int msm_onenand_scan(struct mtd_info *mtd, int maxchips)
-+{
-+ struct msm_nand_chip *chip = mtd->priv;
-+
-+ /* Probe and check whether onenand device is present */
-+ if (flash_onenand_probe(chip))
-+ return -ENODEV;
-+
-+ mtd->size = 0x1000000 << ((onenand_info.device_id & 0xF0) >> 4);
-+ mtd->writesize = onenand_info.data_buf_size;
-+ mtd->oobsize = mtd->writesize >> 5;
-+ mtd->erasesize = mtd->writesize << 6;
-+ mtd->oobavail = msm_onenand_oob_64.oobavail;
-+ mtd->ecclayout = &msm_onenand_oob_64;
-+
-+ mtd->type = MTD_NANDFLASH;
-+ mtd->flags = MTD_CAP_NANDFLASH;
-+ mtd->_erase = msm_onenand_erase;
-+ mtd->_point = NULL;
-+ mtd->_unpoint = NULL;
-+ mtd->_read = msm_onenand_read;
-+ mtd->_write = msm_onenand_write;
-+ mtd->_read_oob = msm_onenand_read_oob;
-+ mtd->_write_oob = msm_onenand_write_oob;
-+ mtd->_lock = msm_onenand_lock;
-+ mtd->_unlock = msm_onenand_unlock;
-+ mtd->_suspend = msm_onenand_suspend;
-+ mtd->_resume = msm_onenand_resume;
-+ mtd->_block_isbad = msm_onenand_block_isbad;
-+ mtd->_block_markbad = msm_onenand_block_markbad;
-+ mtd->owner = THIS_MODULE;
-+
-+ pr_info("Found a supported onenand device\n");
-+
-+ return 0;
-+}
-+
-+static const unsigned int bch_sup_cntrl[] = {
-+ 0x307, /* MSM7x2xA */
-+ 0x4030, /* MDM 9x15 */
-+};
-+
-+static inline bool msm_nand_has_bch_ecc_engine(unsigned int hw_id)
-+{
-+ int i;
-+
-+ for (i = 0; i < ARRAY_SIZE(bch_sup_cntrl); i++) {
-+ if (hw_id == bch_sup_cntrl[i])
-+ return true;
-+ }
-+
-+ return false;
-+}
-+
-+/**
-+ * msm_nand_scan - [msm_nand Interface] Scan for the msm_nand device
-+ * @param mtd MTD device structure
-+ * @param maxchips Number of chips to scan for
-+ *
-+ * This fills out all the not initialized function pointers
-+ * with the defaults.
-+ * The flash ID is read and the mtd/chip structures are
-+ * filled with the appropriate values.
-+ */
-+int msm_nand_scan(struct mtd_info *mtd, int maxchips)
-+{
-+ struct msm_nand_chip *chip = mtd->priv;
-+ uint32_t flash_id = 0, i, mtd_writesize;
-+ uint8_t dev_found = 0;
-+ uint8_t wide_bus;
-+ uint32_t manid;
-+ uint32_t devid;
-+ uint32_t devcfg;
-+ struct nand_flash_dev *flashdev = NULL;
-+ struct nand_manufacturers *flashman = NULL;
-+ unsigned int hw_id;
-+
-+ /*
-+ * Some Spansion parts, like the S34MS04G2, requires that the
-+ * NAND Flash be reset before issuing an ONFI probe.
-+ */
-+ flash_reset(chip);
-+
-+ /* Probe the Flash device for ONFI compliance */
-+ if (!flash_onfi_probe(chip)) {
-+ dev_found = 1;
-+ } else {
-+ /* Read the Flash ID from the Nand Flash Device */
-+ flash_id = flash_read_id(chip);
-+ manid = flash_id & 0xFF;
-+ devid = (flash_id >> 8) & 0xFF;
-+ devcfg = (flash_id >> 24) & 0xFF;
-+
-+ for (i = 0; !flashman && nand_manuf_ids[i].id; ++i)
-+ if (nand_manuf_ids[i].id == manid)
-+ flashman = &nand_manuf_ids[i];
-+ for (i = 0; !flashdev && nand_flash_ids[i].id; ++i)
-+ if (nand_flash_ids[i].id == devid)
-+ flashdev = &nand_flash_ids[i];
-+ if (!flashdev || !flashman) {
-+ pr_err("ERROR: unknown nand device manuf=%x devid=%x\n",
-+ manid, devid);
-+ return -ENOENT;
-+ } else
-+ dev_found = 1;
-+
-+ if (!flashdev->pagesize) {
-+ supported_flash.flash_id = flash_id;
-+ supported_flash.density = flashdev->chipsize << 20;
-+ supported_flash.widebus = devcfg & (1 << 6) ? 1 : 0;
-+ supported_flash.pagesize = 1024 << (devcfg & 0x3);
-+ supported_flash.blksize = (64 * 1024) <<
-+ ((devcfg >> 4) & 0x3);
-+ supported_flash.oobsize = (8 << ((devcfg >> 2) & 0x3)) *
-+ (supported_flash.pagesize >> 9);
-+
-+ if ((supported_flash.oobsize > 64) &&
-+ (supported_flash.pagesize == 2048)) {
-+ pr_info("msm_nand: Found a 2K page device with"
-+ " %d oobsize - changing oobsize to 64 "
-+ "bytes.\n", supported_flash.oobsize);
-+ supported_flash.oobsize = 64;
-+ }
-+ } else {
-+ supported_flash.flash_id = flash_id;
-+ supported_flash.density = flashdev->chipsize << 20;
-+ supported_flash.widebus = flashdev->options &
-+ NAND_BUSWIDTH_16 ? 1 : 0;
-+ supported_flash.pagesize = flashdev->pagesize;
-+ supported_flash.blksize = flashdev->erasesize;
-+ supported_flash.oobsize = flashdev->pagesize >> 5;
-+ }
-+ }
-+
-+ if (dev_found) {
-+ (!interleave_enable) ? (i = 1) : (i = 2);
-+ wide_bus = supported_flash.widebus;
-+ mtd->size = supported_flash.density * i;
-+ mtd->writesize = supported_flash.pagesize * i;
-+ mtd->oobsize = supported_flash.oobsize * i;
-+ mtd->erasesize = supported_flash.blksize * i;
-+ mtd->writebufsize = mtd->writesize;
-+
-+ if (!interleave_enable)
-+ mtd_writesize = mtd->writesize;
-+ else
-+ mtd_writesize = mtd->writesize >> 1;
-+
-+ /* Check whether controller and NAND device support 8bit ECC*/
-+ hw_id = flash_rd_reg(chip, MSM_NAND_HW_INFO);
-+ if (msm_nand_has_bch_ecc_engine(hw_id)
-+ && (supported_flash.ecc_correctability >= 8)) {
-+ pr_info("Found supported NAND device for %dbit ECC\n",
-+ supported_flash.ecc_correctability);
-+ enable_bch_ecc = 1;
-+ } else {
-+ pr_info("Found a supported NAND device\n");
-+ }
-+ pr_info("NAND Controller ID : 0x%x\n", hw_id);
-+ pr_info("NAND Device ID : 0x%x\n", supported_flash.flash_id);
-+ pr_info("Buswidth : %d Bits\n", (wide_bus) ? 16 : 8);
-+ pr_info("Density : %lld MByte\n", (mtd->size>>20));
-+ pr_info("Pagesize : %d Bytes\n", mtd->writesize);
-+ pr_info("Erasesize: %d Bytes\n", mtd->erasesize);
-+ pr_info("Oobsize : %d Bytes\n", mtd->oobsize);
-+ } else {
-+ pr_err("Unsupported Nand,Id: 0x%x \n", flash_id);
-+ return -ENODEV;
-+ }
-+
-+ /* Size of each codeword is 532Bytes incase of 8bit BCH ECC*/
-+ chip->cw_size = enable_bch_ecc ? 532 : 528;
-+ chip->CFG0 = (((mtd_writesize >> 9)-1) << 6) /* 4/8 cw/pg for 2/4k */
-+ | (516 << 9) /* 516 user data bytes */
-+ | (10 << 19) /* 10 parity bytes */
-+ | (5 << 27) /* 5 address cycles */
-+ | (0 << 30) /* Do not read status before data */
-+ | (1 << 31) /* Send read cmd */
-+ /* 0 spare bytes for 16 bit nand or 1/2 spare bytes for 8 bit */
-+ | (wide_bus ? 0 << 23 : (enable_bch_ecc ? 2 << 23 : 1 << 23));
-+
-+ chip->CFG1 = (0 << 0) /* Enable ecc */
-+ | (7 << 2) /* 8 recovery cycles */
-+ | (0 << 5) /* Allow CS deassertion */
-+ /* Bad block marker location */
-+ | ((mtd_writesize - (chip->cw_size * (
-+ (mtd_writesize >> 9) - 1)) + 1) << 6)
-+ | (0 << 16) /* Bad block in user data area */
-+ | (2 << 17) /* 6 cycle tWB/tRB */
-+ | ((wide_bus) ? CFG1_WIDE_FLASH : 0); /* Wide flash bit */
-+
-+ chip->ecc_buf_cfg = 0x203;
-+ chip->CFG0_RAW = 0xA80420C0;
-+ chip->CFG1_RAW = 0x5045D;
-+
-+ if (enable_bch_ecc) {
-+ chip->CFG1 |= (1 << 27); /* Enable BCH engine */
-+ chip->ecc_bch_cfg = (0 << 0) /* Enable ECC*/
-+ | (0 << 1) /* Enable/Disable SW reset of ECC engine */
-+ | (1 << 4) /* 8bit ecc*/
-+ | ((wide_bus) ? (14 << 8) : (13 << 8))/*parity bytes*/
-+ | (516 << 16) /* 516 user data bytes */
-+ | (1 << 30); /* Turn on ECC engine clocks always */
-+ chip->CFG0_RAW = 0xA80428C0; /* CW size is increased to 532B */
-+ }
-+
-+ /*
-+ * For 4bit RS ECC (default ECC), parity bytes = 10 (for x8 and x16 I/O)
-+ * For 8bit BCH ECC, parity bytes = 13 (x8) or 14 (x16 I/O).
-+ */
-+ chip->ecc_parity_bytes = enable_bch_ecc ? (wide_bus ? 14 : 13) : 10;
-+
-+ pr_info("CFG0 Init : 0x%08x\n", chip->CFG0);
-+ pr_info("CFG1 Init : 0x%08x\n", chip->CFG1);
-+ pr_info("ECCBUFCFG : 0x%08x\n", chip->ecc_buf_cfg);
-+
-+ if (mtd->oobsize == 64) {
-+ mtd->oobavail = msm_nand_oob_64.oobavail;
-+ mtd->ecclayout = &msm_nand_oob_64;
-+ } else if (mtd->oobsize == 128) {
-+ mtd->oobavail = msm_nand_oob_128.oobavail;
-+ mtd->ecclayout = &msm_nand_oob_128;
-+ } else if (mtd->oobsize == 224) {
-+ mtd->oobavail = wide_bus ? msm_nand_oob_224_x16.oobavail :
-+ msm_nand_oob_224_x8.oobavail;
-+ mtd->ecclayout = wide_bus ? &msm_nand_oob_224_x16 :
-+ &msm_nand_oob_224_x8;
-+ } else if (mtd->oobsize == 256) {
-+ mtd->oobavail = msm_nand_oob_256.oobavail;
-+ mtd->ecclayout = &msm_nand_oob_256;
-+ } else {
-+ pr_err("Unsupported Nand, oobsize: 0x%x \n",
-+ mtd->oobsize);
-+ return -ENODEV;
-+ }
-+
-+ /* Fill in remaining MTD driver data */
-+ mtd->type = MTD_NANDFLASH;
-+ mtd->flags = MTD_CAP_NANDFLASH;
-+ /* mtd->ecctype = MTD_ECC_SW; */
-+ mtd->_erase = msm_nand_erase;
-+ mtd->_block_isbad = msm_nand_block_isbad;
-+ mtd->_block_markbad = msm_nand_block_markbad;
-+ mtd->_point = NULL;
-+ mtd->_unpoint = NULL;
-+ mtd->_read = msm_nand_read;
-+ mtd->_write = msm_nand_write;
-+ mtd->_read_oob = msm_nand_read_oob;
-+ mtd->_write_oob = msm_nand_write_oob;
-+ if (dual_nand_ctlr_present) {
-+ mtd->_read_oob = msm_nand_read_oob_dualnandc;
-+ mtd->_write_oob = msm_nand_write_oob_dualnandc;
-+ if (interleave_enable) {
-+ mtd->_erase = msm_nand_erase_dualnandc;
-+ mtd->_block_isbad = msm_nand_block_isbad_dualnandc;
-+ }
-+ }
-+
-+ /* mtd->sync = msm_nand_sync; */
-+ mtd->_lock = NULL;
-+ /* mtd->_unlock = msm_nand_unlock; */
-+ mtd->_suspend = msm_nand_suspend;
-+ mtd->_resume = msm_nand_resume;
-+ mtd->owner = THIS_MODULE;
-+
-+ /* Unlock whole block */
-+ /* msm_nand_unlock_all(mtd); */
-+
-+ /* return this->scan_bbt(mtd); */
-+ return 0;
-+}
-+EXPORT_SYMBOL_GPL(msm_nand_scan);
-+
-+/**
-+ * msm_nand_release - [msm_nand Interface] Free resources held by the msm_nand device
-+ * @param mtd MTD device structure
-+ */
-+void msm_nand_release(struct mtd_info *mtd)
-+{
-+ /* struct msm_nand_chip *this = mtd->priv; */
-+
-+ /* Deregister the device */
-+ mtd_device_unregister(mtd);
-+}
-+EXPORT_SYMBOL_GPL(msm_nand_release);
-+
-+struct msm_nand_info {
-+ struct mtd_info mtd;
-+ struct mtd_partition *parts;
-+ struct msm_nand_chip msm_nand;
-+};
-+
-+/* duplicating the NC01 XFR contents to NC10 */
-+static int msm_nand_nc10_xfr_settings(struct mtd_info *mtd)
-+{
-+ struct msm_nand_chip *chip = mtd->priv;
-+
-+ struct {
-+ dmov_s cmd[2];
-+ unsigned cmdptr;
-+ } *dma_buffer;
-+ dmov_s *cmd;
-+
-+ wait_event(chip->wait_queue,
-+ (dma_buffer = msm_nand_get_dma_buffer(
-+ chip, sizeof(*dma_buffer))));
-+
-+ cmd = dma_buffer->cmd;
-+
-+ /* Copying XFR register contents from NC01 --> NC10 */
-+ cmd->cmd = 0;
-+ cmd->src = NC01(MSM_NAND_XFR_STEP1);
-+ cmd->dst = NC10(MSM_NAND_XFR_STEP1);
-+ cmd->len = 28;
-+ cmd++;
-+
-+ BUILD_BUG_ON(2 != ARRAY_SIZE(dma_buffer->cmd));
-+ BUG_ON(cmd - dma_buffer->cmd > ARRAY_SIZE(dma_buffer->cmd));
-+ dma_buffer->cmd[0].cmd |= CMD_OCB;
-+ cmd[-1].cmd |= CMD_OCU | CMD_LC;
-+ dma_buffer->cmdptr = (msm_virt_to_dma(chip, dma_buffer->cmd) >> 3)
-+ | CMD_PTR_LP;
-+
-+ mb();
-+ msm_dmov_exec_cmd(chip->dma_channel, DMOV_CMD_PTR_LIST
-+ | DMOV_CMD_ADDR(msm_virt_to_dma(chip,
-+ &dma_buffer->cmdptr)));
-+ mb();
-+ msm_nand_release_dma_buffer(chip, dma_buffer, sizeof(*dma_buffer));
-+ return 0;
-+}
-+
-+static ssize_t boot_layout_show(struct device *dev,
-+ struct device_attribute *attr,
-+ char *buf)
-+{
-+ return sprintf(buf, "%d\n", boot_layout);
-+}
-+
-+static ssize_t boot_layout_store(struct device *dev,
-+ struct device_attribute *attr,
-+ const char *buf, size_t n)
-+{
-+ struct msm_nand_info *info = dev_get_drvdata(dev);
-+ struct msm_nand_chip *chip = info->mtd.priv;
-+ unsigned int ud_size;
-+ unsigned int spare_size;
-+ unsigned int ecc_num_data_bytes;
-+
-+ sscanf(buf, "%d", &boot_layout);
-+
-+ ud_size = boot_layout? 512: 516;
-+ spare_size = boot_layout? (chip->cw_size -
-+ (chip->ecc_parity_bytes+ 1+ ud_size)):
-+ (enable_bch_ecc ? 2 : 1);
-+ ecc_num_data_bytes = boot_layout? 512: 516;
-+
-+ chip->CFG0 = (chip->CFG0 & ~SPARE_SIZE_BYTES_MASK);
-+ chip->CFG0 |= (spare_size << 23);
-+
-+ chip->CFG0 = (chip->CFG0 & ~UD_SIZE_BYTES_MASK);
-+ chip->CFG0 |= (ud_size << 9);
-+
-+ chip->ecc_buf_cfg = (chip->ecc_buf_cfg & ~ECC_NUM_DATA_BYTES_MASK)
-+ | (ecc_num_data_bytes << 16);
-+
-+ return n;
-+}
-+
-+static const DEVICE_ATTR(boot_layout, 0644, boot_layout_show, boot_layout_store);
-+
-+static int msm_nand_probe(struct platform_device *pdev)
-+
-+{
-+ struct msm_nand_info *info;
-+ struct resource *res;
-+ int err;
-+ struct mtd_part_parser_data ppdata = {};
-+
-+
-+ res = platform_get_resource(pdev,
-+ IORESOURCE_MEM, 0);
-+ if (!res || !res->start) {
-+ pr_err("%s: msm_nand_phys resource invalid/absent\n",
-+ __func__);
-+ return -ENODEV;
-+ }
-+ msm_nand_phys = res->start;
-+
-+ info = devm_kzalloc(&pdev->dev, sizeof(struct msm_nand_info), GFP_KERNEL);
-+ if (!info) {
-+ pr_err("%s: No memory for msm_nand_info\n", __func__);
-+ return -ENOMEM;
-+ }
-+
-+ info->msm_nand.dev = &pdev->dev;
-+
-+ init_waitqueue_head(&info->msm_nand.wait_queue);
-+
-+ info->msm_nand.dma_channel = 3;
-+ pr_info("%s: dmac 0x%x\n", __func__, info->msm_nand.dma_channel);
-+
-+ /* this currently fails if dev is passed in */
-+ info->msm_nand.dma_buffer =
-+ dma_alloc_coherent(/*dev*/ NULL, MSM_NAND_DMA_BUFFER_SIZE,
-+ &info->msm_nand.dma_addr, GFP_KERNEL);
-+ if (info->msm_nand.dma_buffer == NULL) {
-+ pr_err("%s: No memory for msm_nand.dma_buffer\n", __func__);
-+ err = -ENOMEM;
-+ goto out_free_info;
-+ }
-+
-+ pr_info("%s: allocated dma buffer at %p, dma_addr %x\n",
-+ __func__, info->msm_nand.dma_buffer, info->msm_nand.dma_addr);
-+
-+ /* Let default be VERSION_1 for backward compatibility */
-+ info->msm_nand.uncorrectable_bit_mask = BIT(8);
-+ info->msm_nand.num_err_mask = 0x1F;
-+
-+ info->mtd.name = dev_name(&pdev->dev);
-+ info->mtd.priv = &info->msm_nand;
-+ info->mtd.owner = THIS_MODULE;
-+
-+ /* config ebi2_cfg register only for ping pong mode!!! */
-+ if (!interleave_enable && dual_nand_ctlr_present)
-+ flash_wr_reg(&info->msm_nand, EBI2_CFG_REG, 0x4010080);
-+
-+ if (dual_nand_ctlr_present)
-+ msm_nand_nc10_xfr_settings(&info->mtd);
-+
-+ if (msm_nand_scan(&info->mtd, 1))
-+ if (msm_onenand_scan(&info->mtd, 1)) {
-+ pr_err("%s: No nand device found\n", __func__);
-+ err = -ENXIO;
-+ goto out_free_dma_buffer;
-+ }
-+
-+ flash_wr_reg(&info->msm_nand, MSM_NAND_DEV_CMD_VLD,
-+ DEV_CMD_VLD_SEQ_READ_START_VLD |
-+ DEV_CMD_VLD_ERASE_START_VLD |
-+ DEV_CMD_VLD_WRITE_START_VLD |
-+ DEV_CMD_VLD_READ_START_VLD);
-+
-+ ppdata.of_node = pdev->dev.of_node;
-+ err = mtd_device_parse_register(&info->mtd, NULL, &ppdata, NULL, 0);
-+
-+ if (err < 0) {
-+ pr_err("%s: mtd_device_parse_register failed with err=%d\n",
-+ __func__, err);
-+ goto out_free_dma_buffer;
-+ }
-+
-+ err = sysfs_create_file(&pdev->dev.kobj, &dev_attr_boot_layout.attr);
-+ if (err)
-+ goto out_free_dma_buffer;
-+
-+ dev_set_drvdata(&pdev->dev, info);
-+
-+ return 0;
-+
-+out_free_dma_buffer:
-+ dma_free_coherent(NULL, MSM_NAND_DMA_BUFFER_SIZE,
-+ info->msm_nand.dma_buffer,
-+ info->msm_nand.dma_addr);
-+out_free_info:
-+ return err;
-+}
-+
-+static int msm_nand_remove(struct platform_device *pdev)
-+{
-+ struct msm_nand_info *info = dev_get_drvdata(&pdev->dev);
-+
-+ dev_set_drvdata(&pdev->dev, NULL);
-+
-+ if (info) {
-+ msm_nand_release(&info->mtd);
-+ dma_free_coherent(NULL, MSM_NAND_DMA_BUFFER_SIZE,
-+ info->msm_nand.dma_buffer,
-+ info->msm_nand.dma_addr);
-+ }
-+
-+ sysfs_remove_file(&pdev->dev.kobj, &dev_attr_boot_layout.attr);
-+
-+ return 0;
-+}
-+
-+
-+#ifdef CONFIG_OF
-+static const struct of_device_id msm_nand_of_match[] = {
-+ { .compatible = "qcom,qcom_nand", },
-+ {},
-+};
-+MODULE_DEVICE_TABLE(of, msm_nand_of_match);
-+#endif
-+
-+
-+static struct platform_driver msm_nand_driver = {
-+ .probe = msm_nand_probe,
-+ .remove = msm_nand_remove,
-+ .driver = {
-+ .name = "qcom_nand",
-+ .owner = THIS_MODULE,
-+ .of_match_table = msm_nand_of_match,
-+ }
-+};
-+
-+
-+module_platform_driver(msm_nand_driver);
-+
-+MODULE_LICENSE("GPL");
-+MODULE_DESCRIPTION("msm_nand flash driver code");
---- /dev/null
-+++ b/drivers/mtd/nand/qcom_nand.h
-@@ -0,0 +1,196 @@
-+/* drivers/mtd/devices/msm_nand.h
-+ *
-+ * Copyright (c) 2008-2011, The Linux Foundation. All rights reserved.
-+ * Copyright (C) 2007 Google, Inc.
-+ *
-+ * This software is licensed under the terms of the GNU General Public
-+ * License version 2, as published by the Free Software Foundation, and
-+ * may be copied, distributed, and modified under those terms.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ * GNU General Public License for more details.
-+ *
-+ */
-+
-+#ifndef __DRIVERS_MTD_DEVICES_MSM_NAND_H
-+#define __DRIVERS_MTD_DEVICES_MSM_NAND_H
-+
-+extern unsigned long msm_nand_phys;
-+extern unsigned long msm_nandc01_phys;
-+extern unsigned long msm_nandc10_phys;
-+extern unsigned long msm_nandc11_phys;
-+extern unsigned long ebi2_register_base;
-+
-+#define NC01(X) ((X) + msm_nandc01_phys - msm_nand_phys)
-+#define NC10(X) ((X) + msm_nandc10_phys - msm_nand_phys)
-+#define NC11(X) ((X) + msm_nandc11_phys - msm_nand_phys)
-+
-+#define MSM_NAND_REG(off) (msm_nand_phys + (off))
-+
-+#define MSM_NAND_FLASH_CMD MSM_NAND_REG(0x0000)
-+#define MSM_NAND_ADDR0 MSM_NAND_REG(0x0004)
-+#define MSM_NAND_ADDR1 MSM_NAND_REG(0x0008)
-+#define MSM_NAND_FLASH_CHIP_SELECT MSM_NAND_REG(0x000C)
-+#define MSM_NAND_EXEC_CMD MSM_NAND_REG(0x0010)
-+#define MSM_NAND_FLASH_STATUS MSM_NAND_REG(0x0014)
-+#define MSM_NAND_BUFFER_STATUS MSM_NAND_REG(0x0018)
-+#define MSM_NAND_SFLASHC_STATUS MSM_NAND_REG(0x001C)
-+#define MSM_NAND_DEV0_CFG0 MSM_NAND_REG(0x0020)
-+#define MSM_NAND_DEV0_CFG1 MSM_NAND_REG(0x0024)
-+#define MSM_NAND_DEV0_ECC_CFG MSM_NAND_REG(0x0028)
-+#define MSM_NAND_DEV1_ECC_CFG MSM_NAND_REG(0x002C)
-+#define MSM_NAND_DEV1_CFG0 MSM_NAND_REG(0x0030)
-+#define MSM_NAND_DEV1_CFG1 MSM_NAND_REG(0x0034)
-+#define MSM_NAND_SFLASHC_CMD MSM_NAND_REG(0x0038)
-+#define MSM_NAND_SFLASHC_EXEC_CMD MSM_NAND_REG(0x003C)
-+#define MSM_NAND_READ_ID MSM_NAND_REG(0x0040)
-+#define MSM_NAND_READ_STATUS MSM_NAND_REG(0x0044)
-+#define MSM_NAND_CONFIG_DATA MSM_NAND_REG(0x0050)
-+#define MSM_NAND_CONFIG MSM_NAND_REG(0x0054)
-+#define MSM_NAND_CONFIG_MODE MSM_NAND_REG(0x0058)
-+#define MSM_NAND_CONFIG_STATUS MSM_NAND_REG(0x0060)
-+#define MSM_NAND_MACRO1_REG MSM_NAND_REG(0x0064)
-+#define MSM_NAND_XFR_STEP1 MSM_NAND_REG(0x0070)
-+#define MSM_NAND_XFR_STEP2 MSM_NAND_REG(0x0074)
-+#define MSM_NAND_XFR_STEP3 MSM_NAND_REG(0x0078)
-+#define MSM_NAND_XFR_STEP4 MSM_NAND_REG(0x007C)
-+#define MSM_NAND_XFR_STEP5 MSM_NAND_REG(0x0080)
-+#define MSM_NAND_XFR_STEP6 MSM_NAND_REG(0x0084)
-+#define MSM_NAND_XFR_STEP7 MSM_NAND_REG(0x0088)
-+#define MSM_NAND_GENP_REG0 MSM_NAND_REG(0x0090)
-+#define MSM_NAND_GENP_REG1 MSM_NAND_REG(0x0094)
-+#define MSM_NAND_GENP_REG2 MSM_NAND_REG(0x0098)
-+#define MSM_NAND_GENP_REG3 MSM_NAND_REG(0x009C)
-+#define MSM_NAND_DEV_CMD0 MSM_NAND_REG(0x00A0)
-+#define MSM_NAND_DEV_CMD1 MSM_NAND_REG(0x00A4)
-+#define MSM_NAND_DEV_CMD2 MSM_NAND_REG(0x00A8)
-+#define MSM_NAND_DEV_CMD_VLD MSM_NAND_REG(0x00AC)
-+#define DEV_CMD_VLD_SEQ_READ_START_VLD 0x10
-+#define DEV_CMD_VLD_ERASE_START_VLD 0x8
-+#define DEV_CMD_VLD_WRITE_START_VLD 0x4
-+#define DEV_CMD_VLD_READ_STOP_VLD 0x2
-+#define DEV_CMD_VLD_READ_START_VLD 0x1
-+
-+#define MSM_NAND_EBI2_MISR_SIG_REG MSM_NAND_REG(0x00B0)
-+#define MSM_NAND_ADDR2 MSM_NAND_REG(0x00C0)
-+#define MSM_NAND_ADDR3 MSM_NAND_REG(0x00C4)
-+#define MSM_NAND_ADDR4 MSM_NAND_REG(0x00C8)
-+#define MSM_NAND_ADDR5 MSM_NAND_REG(0x00CC)
-+#define MSM_NAND_DEV_CMD3 MSM_NAND_REG(0x00D0)
-+#define MSM_NAND_DEV_CMD4 MSM_NAND_REG(0x00D4)
-+#define MSM_NAND_DEV_CMD5 MSM_NAND_REG(0x00D8)
-+#define MSM_NAND_DEV_CMD6 MSM_NAND_REG(0x00DC)
-+#define MSM_NAND_SFLASHC_BURST_CFG MSM_NAND_REG(0x00E0)
-+#define MSM_NAND_ADDR6 MSM_NAND_REG(0x00E4)
-+#define MSM_NAND_EBI2_ECC_BUF_CFG MSM_NAND_REG(0x00F0)
-+#define MSM_NAND_HW_INFO MSM_NAND_REG(0x00FC)
-+#define MSM_NAND_FLASH_BUFFER MSM_NAND_REG(0x0100)
-+
-+/* device commands */
-+
-+#define MSM_NAND_CMD_SOFT_RESET 0x01
-+#define MSM_NAND_CMD_PAGE_READ 0x32
-+#define MSM_NAND_CMD_PAGE_READ_ECC 0x33
-+#define MSM_NAND_CMD_PAGE_READ_ALL 0x34
-+#define MSM_NAND_CMD_SEQ_PAGE_READ 0x15
-+#define MSM_NAND_CMD_PRG_PAGE 0x36
-+#define MSM_NAND_CMD_PRG_PAGE_ECC 0x37
-+#define MSM_NAND_CMD_PRG_PAGE_ALL 0x39
-+#define MSM_NAND_CMD_BLOCK_ERASE 0x3A
-+#define MSM_NAND_CMD_FETCH_ID 0x0B
-+#define MSM_NAND_CMD_STATUS 0x0C
-+#define MSM_NAND_CMD_RESET 0x0D
-+
-+/* Sflash Commands */
-+
-+#define MSM_NAND_SFCMD_DATXS 0x0
-+#define MSM_NAND_SFCMD_CMDXS 0x1
-+#define MSM_NAND_SFCMD_BURST 0x0
-+#define MSM_NAND_SFCMD_ASYNC 0x1
-+#define MSM_NAND_SFCMD_ABORT 0x1
-+#define MSM_NAND_SFCMD_REGRD 0x2
-+#define MSM_NAND_SFCMD_REGWR 0x3
-+#define MSM_NAND_SFCMD_INTLO 0x4
-+#define MSM_NAND_SFCMD_INTHI 0x5
-+#define MSM_NAND_SFCMD_DATRD 0x6
-+#define MSM_NAND_SFCMD_DATWR 0x7
-+
-+#define SFLASH_PREPCMD(numxfr, offval, delval, trnstp, mode, opcode) \
-+ ((numxfr<<20)|(offval<<12)|(delval<<6)|(trnstp<<5)|(mode<<4)|opcode)
-+
-+#define SFLASH_BCFG 0x20100327
-+
-+/* Onenand addresses */
-+
-+#define ONENAND_MANUFACTURER_ID 0xF000
-+#define ONENAND_DEVICE_ID 0xF001
-+#define ONENAND_VERSION_ID 0xF002
-+#define ONENAND_DATA_BUFFER_SIZE 0xF003
-+#define ONENAND_BOOT_BUFFER_SIZE 0xF004
-+#define ONENAND_AMOUNT_OF_BUFFERS 0xF005
-+#define ONENAND_TECHNOLOGY 0xF006
-+#define ONENAND_START_ADDRESS_1 0xF100
-+#define ONENAND_START_ADDRESS_2 0xF101
-+#define ONENAND_START_ADDRESS_3 0xF102
-+#define ONENAND_START_ADDRESS_4 0xF103
-+#define ONENAND_START_ADDRESS_5 0xF104
-+#define ONENAND_START_ADDRESS_6 0xF105
-+#define ONENAND_START_ADDRESS_7 0xF106
-+#define ONENAND_START_ADDRESS_8 0xF107
-+#define ONENAND_START_BUFFER 0xF200
-+#define ONENAND_COMMAND 0xF220
-+#define ONENAND_SYSTEM_CONFIG_1 0xF221
-+#define ONENAND_SYSTEM_CONFIG_2 0xF222
-+#define ONENAND_CONTROLLER_STATUS 0xF240
-+#define ONENAND_INTERRUPT_STATUS 0xF241
-+#define ONENAND_START_BLOCK_ADDRESS 0xF24C
-+#define ONENAND_WRITE_PROT_STATUS 0xF24E
-+#define ONENAND_ECC_STATUS 0xFF00
-+#define ONENAND_ECC_ERRPOS_MAIN0 0xFF01
-+#define ONENAND_ECC_ERRPOS_SPARE0 0xFF02
-+#define ONENAND_ECC_ERRPOS_MAIN1 0xFF03
-+#define ONENAND_ECC_ERRPOS_SPARE1 0xFF04
-+#define ONENAND_ECC_ERRPOS_MAIN2 0xFF05
-+#define ONENAND_ECC_ERRPOS_SPARE2 0xFF06
-+#define ONENAND_ECC_ERRPOS_MAIN3 0xFF07
-+#define ONENAND_ECC_ERRPOS_SPARE3 0xFF08
-+
-+/* Onenand commands */
-+#define ONENAND_WP_US (1 << 2)
-+#define ONENAND_WP_LS (1 << 1)
-+
-+#define ONENAND_CMDLOAD 0x0000
-+#define ONENAND_CMDLOADSPARE 0x0013
-+#define ONENAND_CMDPROG 0x0080
-+#define ONENAND_CMDPROGSPARE 0x001A
-+#define ONENAND_CMDERAS 0x0094
-+#define ONENAND_CMD_UNLOCK 0x0023
-+#define ONENAND_CMD_LOCK 0x002A
-+
-+#define ONENAND_SYSCFG1_ECCENA(mode) (0x40E0 | (mode ? 0 : 0x8002))
-+#define ONENAND_SYSCFG1_ECCDIS(mode) (0x41E0 | (mode ? 0 : 0x8002))
-+
-+#define ONENAND_CLRINTR 0x0000
-+#define ONENAND_STARTADDR1_RES 0x07FF
-+#define ONENAND_STARTADDR3_RES 0x07FF
-+
-+#define DATARAM0_0 0x8
-+#define DEVICE_FLASHCORE_0 (0 << 15)
-+#define DEVICE_FLASHCORE_1 (1 << 15)
-+#define DEVICE_BUFFERRAM_0 (0 << 15)
-+#define DEVICE_BUFFERRAM_1 (1 << 15)
-+#define ONENAND_DEVICE_IS_DDP (1 << 3)
-+
-+#define CLEAN_DATA_16 0xFFFF
-+#define CLEAN_DATA_32 0xFFFFFFFF
-+
-+#define EBI2_REG(off) (ebi2_register_base + (off))
-+#define EBI2_CHIP_SELECT_CFG0 EBI2_REG(0x0000)
-+#define EBI2_CFG_REG EBI2_REG(0x0004)
-+#define EBI2_NAND_ADM_MUX EBI2_REG(0x005C)
-+
-+extern struct flash_platform_data msm_nand_data;
-+
-+#endif
diff --git a/target/linux/ipq806x/patches/0151-ARM-ipq8064-Add-nand-device-info.patch b/target/linux/ipq806x/patches/0151-ARM-ipq8064-Add-nand-device-info.patch
deleted file mode 100644
index b460454..0000000
--- a/target/linux/ipq806x/patches/0151-ARM-ipq8064-Add-nand-device-info.patch
+++ /dev/null
@@ -1,108 +0,0 @@
-From 4490cfa66379909cdddc3518c8e75b7cd26d8f69 Mon Sep 17 00:00:00 2001
-From: Andy Gross <agross@codeaurora.org>
-Date: Mon, 16 Jun 2014 16:53:49 -0500
-Subject: [PATCH 151/182] ARM: ipq8064: Add nand device info
-
-Signed-off-by: Andy Gross <agross@codeaurora.org>
----
- arch/arm/boot/dts/qcom-ipq8064-ap148.dts | 34 ++++++++++++++++++++++++++++++
- arch/arm/boot/dts/qcom-ipq8064.dtsi | 33 +++++++++++++++++++++++++++++
- 2 files changed, 67 insertions(+)
-
---- a/arch/arm/boot/dts/qcom-ipq8064-ap148.dts
-+++ b/arch/arm/boot/dts/qcom-ipq8064-ap148.dts
-@@ -45,6 +45,29 @@
- bias-none;
- };
- };
-+ nand_pins: nand_pins {
-+ mux {
-+ pins = "gpio34", "gpio35", "gpio36",
-+ "gpio37", "gpio38", "gpio39",
-+ "gpio40", "gpio41", "gpio42",
-+ "gpio43", "gpio44", "gpio45",
-+ "gpio46", "gpio47";
-+ function = "nand";
-+ drive-strength = <10>;
-+ bias-disable;
-+ };
-+ pullups {
-+ pins = "gpio39";
-+ bias-pull-up;
-+ };
-+ hold {
-+ pins = "gpio40", "gpio41", "gpio42",
-+ "gpio43", "gpio44", "gpio45",
-+ "gpio46", "gpio47";
-+ bias-bus-hold;
-+ };
-+ };
-+
- };
-
- gsbi@16300000 {
-@@ -126,5 +149,16 @@
- sata@29000000 {
- status = "ok";
- };
-+
-+ dma@18300000 {
-+ status = "ok";
-+ };
-+
-+ nand@0x1ac00000 {
-+ status = "ok";
-+
-+ pinctrl-0 = <&nand_pins>;
-+ pinctrl-names = "default";
-+ };
- };
- };
---- a/arch/arm/boot/dts/qcom-ipq8064.dtsi
-+++ b/arch/arm/boot/dts/qcom-ipq8064.dtsi
-@@ -76,6 +76,7 @@
- interrupt-controller;
- #interrupt-cells = <2>;
- interrupts = <0 32 0x4>;
-+
- };
-
- intc: interrupt-controller@2000000 {
-@@ -369,5 +370,37 @@
- phy-names = "sata-phy";
- status = "disabled";
- };
-+
-+ adm_dma: dma@18300000 {
-+ compatible = "qcom,adm";
-+ reg = <0x18300000 0x100000>;
-+ interrupts = <0 170 0>;
-+
-+ clocks = <&gcc ADM0_CLK>, <&gcc ADM0_PBUS_CLK>;
-+ clock-names = "core_clk", "iface_clk";
-+
-+ resets = <&gcc ADM0_RESET>,
-+ <&gcc ADM0_PBUS_RESET>,
-+ <&gcc ADM0_C0_RESET>,
-+ <&gcc ADM0_C1_RESET>,
-+ <&gcc ADM0_C2_RESET>;
-+
-+ reset-names = "adm", "pbus", "c0", "c1", "c2";
-+
-+ status = "disabled";
-+ };
-+
-+ nand@0x1ac00000 {
-+ compatible = "qcom,qcom_nand";
-+ reg = <0x1ac00000 0x800>;
-+ #address-cells = <1>;
-+ #size-cells = <1>;
-+
-+ clocks = <&gcc EBI2_CLK>;
-+ clock-names = "core_clk";
-+
-+
-+ status = "disabled";
-+ };
- };
- };
diff --git a/target/linux/ipq806x/patches/0152-ARM-qcom-config-Add-NAND-config-options.patch b/target/linux/ipq806x/patches/0152-ARM-qcom-config-Add-NAND-config-options.patch
deleted file mode 100644
index a2489e4..0000000
--- a/target/linux/ipq806x/patches/0152-ARM-qcom-config-Add-NAND-config-options.patch
+++ /dev/null
@@ -1,22 +0,0 @@
-From d04f697bf7cfe756de6187be1d0e5669d4d5bca0 Mon Sep 17 00:00:00 2001
-From: Andy Gross <agross@codeaurora.org>
-Date: Mon, 16 Jun 2014 17:30:04 -0500
-Subject: [PATCH 152/182] ARM: qcom: config: Add NAND config options
-
-Add NAND config options to enable QCOM NAND controller
-
-Signed-off-by: Andy Gross <agross@codeaurora.org>
----
- arch/arm/configs/qcom_defconfig | 1 +
- 1 file changed, 1 insertion(+)
-
---- a/arch/arm/configs/qcom_defconfig
-+++ b/arch/arm/configs/qcom_defconfig
-@@ -56,6 +56,7 @@ CONFIG_DEVTMPFS_MOUNT=y
- CONFIG_MTD=y
- CONFIG_MTD_BLOCK=y
- CONFIG_MTD_M25P80=y
-+CONFIG_MTD_NAND=y
- CONFIG_BLK_DEV_LOOP=y
- CONFIG_BLK_DEV_RAM=y
- CONFIG_SCSI_TGT=y
diff --git a/target/linux/ipq806x/patches/0153-soc-qcom-tcsr-Add-TCSR-driver.patch b/target/linux/ipq806x/patches/0153-soc-qcom-tcsr-Add-TCSR-driver.patch
deleted file mode 100644
index 65e4c2f..0000000
--- a/target/linux/ipq806x/patches/0153-soc-qcom-tcsr-Add-TCSR-driver.patch
+++ /dev/null
@@ -1,153 +0,0 @@
-From 0b469f3f4c0e6a0e0b1b60a059600e325a03b6f5 Mon Sep 17 00:00:00 2001
-From: Andy Gross <agross@codeaurora.org>
-Date: Thu, 12 Jun 2014 00:52:06 -0500
-Subject: [PATCH 153/182] soc: qcom: tcsr: Add TCSR driver
-
-This patch adds support for the TCSR IP block present in Qualcomm processors.
-
-Signed-off-by: Andy Gross <agross@codeaurora.org>
----
- .../devicetree/bindings/soc/qcom/qcom,tcsr.txt | 25 ++++++++
- drivers/soc/qcom/Kconfig | 6 ++
- drivers/soc/qcom/Makefile | 1 +
- drivers/soc/qcom/qcom_tcsr.c | 64 ++++++++++++++++++++
- include/dt-bindings/soc/qcom,tcsr.h | 19 ++++++
- 5 files changed, 115 insertions(+)
- create mode 100644 Documentation/devicetree/bindings/soc/qcom/qcom,tcsr.txt
- create mode 100644 drivers/soc/qcom/qcom_tcsr.c
- create mode 100644 include/dt-bindings/soc/qcom,tcsr.h
-
---- /dev/null
-+++ b/Documentation/devicetree/bindings/soc/qcom/qcom,tcsr.txt
-@@ -0,0 +1,25 @@
-+QCOM TCSR (Top Control and Status Register) Driver
-+
-+The TCSR provides miscellaneous control functions and status registers for
-+Qualcomm processors.
-+
-+Required properties:
-+- compatible: must contain "qcom,tcsr" for IPQ806x
-+- reg: Address range for TCSR registers
-+
-+Optional properties:
-+- qcom,usb-ctrl-select : indicates USB port type selection. Please reference
-+ dt-bindings/soc/qcom,tcsr.h for valid USB port selection values.
-+
-+Example for IPQ8064:
-+
-+#include <dt-bindings/soc/qcom,tcsr.h>
-+
-+ tcsr: tcsr@1a400000 {
-+ compatible = "qcom,tcsr";
-+ reg = <0x1a400000 0x100>;
-+
-+ qcom,usb-ctrl-select = <TCSR_USB_SELECT_USB3_DUAL>;
-+ };
-+
-+
---- a/drivers/soc/qcom/Kconfig
-+++ b/drivers/soc/qcom/Kconfig
-@@ -9,3 +9,9 @@ config QCOM_GSBI
- functions for connecting the underlying serial UART, SPI, and I2C
- devices to the output pins.
-
-+config QCOM_TCSR
-+ tristate "QCOM Top Control and Status Registers"
-+ depends on ARCH_QCOM
-+ help
-+ Say y here to enable TCSR support. The TCSR provides control
-+ functions for various peripherals.
---- a/drivers/soc/qcom/Makefile
-+++ b/drivers/soc/qcom/Makefile
-@@ -1 +1,2 @@
- obj-$(CONFIG_QCOM_GSBI) += qcom_gsbi.o
-+obj-$(CONFIG_QCOM_TCSR) += qcom_tcsr.o
---- /dev/null
-+++ b/drivers/soc/qcom/qcom_tcsr.c
-@@ -0,0 +1,64 @@
-+/*
-+ * Copyright (c) 2014, The Linux foundation. All rights reserved.
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License rev 2 and
-+ * only rev 2 as published by the free Software foundation.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or fITNESS fOR A PARTICULAR PURPOSE. See the
-+ * GNU General Public License for more details.
-+ */
-+
-+#include <linux/clk.h>
-+#include <linux/err.h>
-+#include <linux/io.h>
-+#include <linux/module.h>
-+#include <linux/of.h>
-+#include <linux/of_platform.h>
-+#include <linux/platform_device.h>
-+
-+#define TCSR_USB_PORT_SEL 0xb0
-+
-+static int tcsr_probe(struct platform_device *pdev)
-+{
-+ struct resource *res;
-+ const struct device_node *node = pdev->dev.of_node;
-+ void __iomem *base;
-+ u32 val;
-+
-+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-+ base = devm_ioremap_resource(&pdev->dev, res);
-+ if (IS_ERR(base))
-+ return PTR_ERR(base);
-+
-+ if (!of_property_read_u32(node, "qcom,usb-ctrl-select", &val)) {
-+ dev_err(&pdev->dev, "setting usb port select = %d\n", val);
-+ writel(val, base + TCSR_USB_PORT_SEL);
-+ }
-+
-+ return 0;
-+}
-+
-+static const struct of_device_id tcsr_dt_match[] = {
-+ { .compatible = "qcom,tcsr", },
-+ { },
-+};
-+
-+MODULE_DEVICE_TABLE(of, tcsr_dt_match);
-+
-+static struct platform_driver tcsr_driver = {
-+ .driver = {
-+ .name = "tcsr",
-+ .owner = THIS_MODULE,
-+ .of_match_table = tcsr_dt_match,
-+ },
-+ .probe = tcsr_probe,
-+};
-+
-+module_platform_driver(tcsr_driver);
-+
-+MODULE_AUTHOR("Andy Gross <agross@codeaurora.org>");
-+MODULE_DESCRIPTION("QCOM TCSR driver");
-+MODULE_LICENSE("GPL v2");
---- /dev/null
-+++ b/include/dt-bindings/soc/qcom,tcsr.h
-@@ -0,0 +1,19 @@
-+/* Copyright (c) 2014, The Linux Foundation. All rights reserved.
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 and
-+ * only version 2 as published by the Free Software Foundation.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ * GNU General Public License for more details.
-+ */
-+#ifndef __DT_BINDINGS_QCOM_TCSR_H
-+#define __DT_BINDINGS_QCOM_TCSR_H
-+
-+#define TCSR_USB_SELECT_USB3_P0 0x1
-+#define TCSR_USB_SELECT_USB3_P1 0x2
-+#define TCSR_USB_SELECT_USB3_DUAL 0x3
-+
-+#endif
diff --git a/target/linux/ipq806x/patches/0154-clk-qcom-Correct-UTMI-clock-frequency-table.patch b/target/linux/ipq806x/patches/0154-clk-qcom-Correct-UTMI-clock-frequency-table.patch
deleted file mode 100644
index 1d81970..0000000
--- a/target/linux/ipq806x/patches/0154-clk-qcom-Correct-UTMI-clock-frequency-table.patch
+++ /dev/null
@@ -1,24 +0,0 @@
-From 2561c49dcf5cb35ad72df34bf225a51fe2fa87e5 Mon Sep 17 00:00:00 2001
-From: Andy Gross <agross@codeaurora.org>
-Date: Thu, 12 Jun 2014 00:53:19 -0500
-Subject: [PATCH 154/182] clk: qcom: Correct UTMI clock frequency table
-
-This patch changes the UTMI clock frequency from 20MHz to the correct value of
-60MHz.
-
-Signed-off-by: Andy Gross <agross@codeaurora.org>
----
- drivers/clk/qcom/gcc-ipq806x.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/drivers/clk/qcom/gcc-ipq806x.c
-+++ b/drivers/clk/qcom/gcc-ipq806x.c
-@@ -1992,7 +1992,7 @@ static struct clk_branch usb30_1_branch_
- };
-
- static const struct freq_tbl clk_tbl_usb30_utmi[] = {
-- { 60000000, P_PLL0, 1, 1, 40 },
-+ { 60000000, P_PLL8, 1, 5, 32 },
- { }
- };
-
diff --git a/target/linux/ipq806x/patches/0155-clk-qcom-Fix-incorrect-UTMI-DT-include-values.patch b/target/linux/ipq806x/patches/0155-clk-qcom-Fix-incorrect-UTMI-DT-include-values.patch
deleted file mode 100644
index a05fc2c..0000000
--- a/target/linux/ipq806x/patches/0155-clk-qcom-Fix-incorrect-UTMI-DT-include-values.patch
+++ /dev/null
@@ -1,58 +0,0 @@
-From 9ab5cb48696dca02bf43170b50d1034a96fb9e85 Mon Sep 17 00:00:00 2001
-From: Andy Gross <agross@codeaurora.org>
-Date: Sun, 15 Jun 2014 00:39:57 -0500
-Subject: [PATCH 155/182] clk: qcom: Fix incorrect UTMI DT include values
-
-Corrected values for UTMI clock definitions.
-
-Signed-off-by: Andy Gross <agross@codeaurora.org>
----
- include/dt-bindings/clock/qcom,gcc-ipq806x.h | 38 +++++++++++++-------------
- 1 file changed, 19 insertions(+), 19 deletions(-)
-
---- a/include/dt-bindings/clock/qcom,gcc-ipq806x.h
-+++ b/include/dt-bindings/clock/qcom,gcc-ipq806x.h
-@@ -273,24 +273,24 @@
- #define USB30_SLEEP_CLK 262
- #define USB30_UTMI_SRC 263
- #define USB30_0_UTMI_CLK 264
--#define USB30_1_UTMI_CLK 264
--#define USB30_MASTER_SRC 265
--#define USB30_0_MASTER_CLK 266
--#define USB30_1_MASTER_CLK 267
--#define GMAC_CORE1_CLK_SRC 268
--#define GMAC_CORE2_CLK_SRC 269
--#define GMAC_CORE3_CLK_SRC 270
--#define GMAC_CORE4_CLK_SRC 271
--#define GMAC_CORE1_CLK 272
--#define GMAC_CORE2_CLK 273
--#define GMAC_CORE3_CLK 274
--#define GMAC_CORE4_CLK 275
--#define UBI32_CORE1_CLK_SRC 276
--#define UBI32_CORE2_CLK_SRC 277
--#define UBI32_CORE1_CLK 278
--#define UBI32_CORE2_CLK 279
--#define NSSTCM_CLK_SRC 280
--#define NSSTCM_CLK 281
--#define NSS_CORE_CLK 282 /* Virtual */
-+#define USB30_1_UTMI_CLK 265
-+#define USB30_MASTER_SRC 266
-+#define USB30_0_MASTER_CLK 267
-+#define USB30_1_MASTER_CLK 268
-+#define GMAC_CORE1_CLK_SRC 269
-+#define GMAC_CORE2_CLK_SRC 270
-+#define GMAC_CORE3_CLK_SRC 271
-+#define GMAC_CORE4_CLK_SRC 272
-+#define GMAC_CORE1_CLK 273
-+#define GMAC_CORE2_CLK 274
-+#define GMAC_CORE3_CLK 275
-+#define GMAC_CORE4_CLK 276
-+#define UBI32_CORE1_CLK_SRC 277
-+#define UBI32_CORE2_CLK_SRC 278
-+#define UBI32_CORE1_CLK 279
-+#define UBI32_CORE2_CLK 280
-+#define NSSTCM_CLK_SRC 281
-+#define NSSTCM_CLK 282
-+#define NSS_CORE_CLK 283 /* Virtual */
-
- #endif
diff --git a/target/linux/ipq806x/patches/0156-usb-dwc3-Add-Qualcomm-DWC3-glue-layer-driver.patch b/target/linux/ipq806x/patches/0156-usb-dwc3-Add-Qualcomm-DWC3-glue-layer-driver.patch
deleted file mode 100644
index a69a5bd..0000000
--- a/target/linux/ipq806x/patches/0156-usb-dwc3-Add-Qualcomm-DWC3-glue-layer-driver.patch
+++ /dev/null
@@ -1,202 +0,0 @@
-From 364532aeb9024d0ff7b88121f9a953f559b1c136 Mon Sep 17 00:00:00 2001
-From: "Ivan T. Ivanov" <iivanov@mm-sol.com>
-Date: Mon, 7 Oct 2013 10:44:57 +0300
-Subject: [PATCH 156/182] usb: dwc3: Add Qualcomm DWC3 glue layer driver
-
-DWC3 glue layer is hardware layer around Synopsys DesignWare
-USB3 core. Its purpose is to supply Synopsys IP with required
-clocks, voltages and interface it with the rest of the SoC.
-
-Signed-off-by: Ivan T. Ivanov <iivanov@mm-sol.com>
----
- drivers/usb/dwc3/Kconfig | 8 +++
- drivers/usb/dwc3/Makefile | 1 +
- drivers/usb/dwc3/dwc3-qcom.c | 156 ++++++++++++++++++++++++++++++++++++++++++
- 3 files changed, 165 insertions(+)
- create mode 100644 drivers/usb/dwc3/dwc3-qcom.c
-
---- a/drivers/usb/dwc3/Kconfig
-+++ b/drivers/usb/dwc3/Kconfig
-@@ -59,6 +59,14 @@ config USB_DWC3_EXYNOS
- Recent Exynos5 SoCs ship with one DesignWare Core USB3 IP inside,
- say 'Y' or 'M' if you have one such device.
-
-+config USB_DWC3_QCOM
-+ tristate "Qualcomm Platforms"
-+ default USB_DWC3
-+ select USB_QCOM_DWC3_PHYS
-+ help
-+ Recent Qualcomm SoCs ship with one DesignWare Core USB3 IP inside,
-+ say 'Y' or 'M' if you have one such device.
-+
- config USB_DWC3_PCI
- tristate "PCIe-based Platforms"
- depends on PCI
---- a/drivers/usb/dwc3/Makefile
-+++ b/drivers/usb/dwc3/Makefile
-@@ -31,5 +31,6 @@ endif
-
- obj-$(CONFIG_USB_DWC3_OMAP) += dwc3-omap.o
- obj-$(CONFIG_USB_DWC3_EXYNOS) += dwc3-exynos.o
-+obj-$(CONFIG_USB_DWC3_QCOM) += dwc3-qcom.o
- obj-$(CONFIG_USB_DWC3_PCI) += dwc3-pci.o
- obj-$(CONFIG_USB_DWC3_KEYSTONE) += dwc3-keystone.o
---- /dev/null
-+++ b/drivers/usb/dwc3/dwc3-qcom.c
-@@ -0,0 +1,156 @@
-+/* Copyright (c) 2013-2014, The Linux Foundation. All rights reserved.
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 and
-+ * only version 2 as published by the Free Software Foundation.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ * GNU General Public License for more details.
-+ */
-+
-+#include <linux/clk.h>
-+#include <linux/err.h>
-+#include <linux/io.h>
-+#include <linux/module.h>
-+#include <linux/of.h>
-+#include <linux/of_platform.h>
-+#include <linux/platform_device.h>
-+#include <linux/regulator/consumer.h>
-+#include <linux/usb/phy.h>
-+
-+#include "core.h"
-+
-+
-+struct dwc3_qcom {
-+ struct device *dev;
-+
-+ struct clk *core_clk;
-+ struct clk *iface_clk;
-+ struct clk *sleep_clk;
-+
-+ struct regulator *gdsc;
-+};
-+
-+static int dwc3_qcom_probe(struct platform_device *pdev)
-+{
-+ struct device_node *node = pdev->dev.of_node;
-+ struct dwc3_qcom *mdwc;
-+ int ret = 0;
-+
-+ mdwc = devm_kzalloc(&pdev->dev, sizeof(*mdwc), GFP_KERNEL);
-+ if (!mdwc)
-+ return -ENOMEM;
-+
-+ platform_set_drvdata(pdev, mdwc);
-+
-+ mdwc->dev = &pdev->dev;
-+
-+ mdwc->gdsc = devm_regulator_get(mdwc->dev, "gdsc");
-+
-+ mdwc->core_clk = devm_clk_get(mdwc->dev, "core");
-+ if (IS_ERR(mdwc->core_clk)) {
-+ dev_dbg(mdwc->dev, "failed to get core clock\n");
-+ return PTR_ERR(mdwc->core_clk);
-+ }
-+
-+ mdwc->iface_clk = devm_clk_get(mdwc->dev, "iface");
-+ if (IS_ERR(mdwc->iface_clk)) {
-+ dev_dbg(mdwc->dev, "failed to get iface clock, skipping\n");
-+ mdwc->iface_clk = NULL;
-+ }
-+
-+ mdwc->sleep_clk = devm_clk_get(mdwc->dev, "sleep");
-+ if (IS_ERR(mdwc->sleep_clk)) {
-+ dev_dbg(mdwc->dev, "failed to get sleep clock, skipping\n");
-+ mdwc->sleep_clk = NULL;
-+ }
-+
-+ if (!IS_ERR(mdwc->gdsc)) {
-+ ret = regulator_enable(mdwc->gdsc);
-+ if (ret)
-+ dev_err(mdwc->dev, "cannot enable gdsc\n");
-+ }
-+
-+ clk_prepare_enable(mdwc->core_clk);
-+
-+ if (mdwc->iface_clk)
-+ clk_prepare_enable(mdwc->iface_clk);
-+
-+ if (mdwc->sleep_clk)
-+ clk_prepare_enable(mdwc->sleep_clk);
-+
-+ ret = of_platform_populate(node, NULL, NULL, mdwc->dev);
-+ if (ret) {
-+ dev_err(mdwc->dev, "failed to register core - %d\n", ret);
-+ dev_dbg(mdwc->dev, "failed to add create dwc3 core\n");
-+ goto dis_clks;
-+ }
-+
-+ return 0;
-+
-+dis_clks:
-+
-+ dev_err(mdwc->dev, "disabling clocks\n");
-+
-+ if (mdwc->sleep_clk)
-+ clk_disable_unprepare(mdwc->sleep_clk);
-+
-+ if (mdwc->iface_clk)
-+ clk_disable_unprepare(mdwc->iface_clk);
-+
-+ clk_disable_unprepare(mdwc->core_clk);
-+
-+ if (!IS_ERR(mdwc->gdsc)) {
-+ ret = regulator_disable(mdwc->gdsc);
-+ if (ret)
-+ dev_dbg(mdwc->dev, "cannot disable gdsc\n");
-+ }
-+
-+ return ret;
-+}
-+
-+static int dwc3_qcom_remove(struct platform_device *pdev)
-+{
-+ int ret = 0;
-+
-+ struct dwc3_qcom *mdwc = platform_get_drvdata(pdev);
-+
-+ if (mdwc->sleep_clk)
-+ clk_disable_unprepare(mdwc->sleep_clk);
-+
-+ if (mdwc->iface_clk)
-+ clk_disable_unprepare(mdwc->iface_clk);
-+
-+ clk_disable_unprepare(mdwc->core_clk);
-+
-+ if (!IS_ERR(mdwc->gdsc)) {
-+ ret = regulator_disable(mdwc->gdsc);
-+ if (ret)
-+ dev_dbg(mdwc->dev, "cannot disable gdsc\n");
-+ }
-+ return ret;
-+}
-+
-+static const struct of_device_id of_dwc3_match[] = {
-+ { .compatible = "qcom,dwc3" },
-+ { /* Sentinel */ }
-+};
-+MODULE_DEVICE_TABLE(of, of_dwc3_match);
-+
-+static struct platform_driver dwc3_qcom_driver = {
-+ .probe = dwc3_qcom_probe,
-+ .remove = dwc3_qcom_remove,
-+ .driver = {
-+ .name = "qcom-dwc3",
-+ .owner = THIS_MODULE,
-+ .of_match_table = of_dwc3_match,
-+ },
-+};
-+
-+module_platform_driver(dwc3_qcom_driver);
-+
-+MODULE_ALIAS("platform:qcom-dwc3");
-+MODULE_LICENSE("GPL v2");
-+MODULE_DESCRIPTION("DesignWare USB3 QCOM Glue Layer");
diff --git a/target/linux/ipq806x/patches/0157-usb-phy-Add-Qualcomm-DWC3-HS-SS-PHY-drivers.patch b/target/linux/ipq806x/patches/0157-usb-phy-Add-Qualcomm-DWC3-HS-SS-PHY-drivers.patch
deleted file mode 100644
index d7fafed..0000000
--- a/target/linux/ipq806x/patches/0157-usb-phy-Add-Qualcomm-DWC3-HS-SS-PHY-drivers.patch
+++ /dev/null
@@ -1,861 +0,0 @@
-From d968f8c82db73141c6bc145148642391cb698442 Mon Sep 17 00:00:00 2001
-From: "Ivan T. Ivanov" <iivanov@mm-sol.com>
-Date: Mon, 7 Oct 2013 10:44:56 +0300
-Subject: [PATCH 157/182] usb: phy: Add Qualcomm DWC3 HS/SS PHY drivers
-
-These drivers handles control and configuration of the HS
-and SS USB PHY transceivers. They are part of the driver
-which manage Synopsys DesignWare USB3 controller stack
-inside Qualcomm SoC's.
-
-Signed-off-by: Ivan T. Ivanov <iivanov@mm-sol.com>
----
- drivers/usb/phy/Kconfig | 13 +-
- drivers/usb/phy/Makefile | 2 +
- drivers/usb/phy/phy-qcom-hsusb.c | 340 ++++++++++++++++++++++++++++
- drivers/usb/phy/phy-qcom-ssusb.c | 455 ++++++++++++++++++++++++++++++++++++++
- 4 files changed, 809 insertions(+), 1 deletion(-)
- create mode 100644 drivers/usb/phy/phy-qcom-hsusb.c
- create mode 100644 drivers/usb/phy/phy-qcom-ssusb.c
-
---- a/drivers/usb/phy/Kconfig
-+++ b/drivers/usb/phy/Kconfig
-@@ -193,7 +193,7 @@ config USB_ISP1301
-
- config USB_MSM_OTG
- tristate "OTG support for Qualcomm on-chip USB controller"
-- depends on (USB || USB_GADGET) && ARCH_MSM
-+ depends on (USB || USB_GADGET) && ARCH_QCOM
- select USB_PHY
- help
- Enable this to support the USB OTG transceiver on MSM chips. It
-@@ -251,6 +251,17 @@ config USB_RCAR_GEN2_PHY
- To compile this driver as a module, choose M here: the
- module will be called phy-rcar-gen2-usb.
-
-+config USB_QCOM_DWC3_PHY
-+ tristate "Qualcomm USB controller DWC3 PHY wrappers support"
-+ depends on (USB || USB_GADGET) && ARCH_QCOM
-+ select USB_PHY
-+ help
-+ Enable this to support the DWC3 USB PHY transceivers on QCOM chips
-+ with DWC3 USB core. It handles PHY initialization, clock
-+ management required after resetting the hardware and power
-+ management. This driver is required even for peripheral only or
-+ host only mode configurations.
-+
- config USB_ULPI
- bool "Generic ULPI Transceiver Driver"
- depends on ARM
---- a/drivers/usb/phy/Makefile
-+++ b/drivers/usb/phy/Makefile
-@@ -26,6 +26,8 @@ obj-$(CONFIG_USB_EHCI_TEGRA) += phy-teg
- obj-$(CONFIG_USB_GPIO_VBUS) += phy-gpio-vbus-usb.o
- obj-$(CONFIG_USB_ISP1301) += phy-isp1301.o
- obj-$(CONFIG_USB_MSM_OTG) += phy-msm-usb.o
-+obj-$(CONFIG_USB_QCOM_DWC3_PHY) += phy-qcom-hsusb.o
-+obj-$(CONFIG_USB_QCOM_DWC3_PHY) += phy-qcom-ssusb.o
- obj-$(CONFIG_USB_MV_OTG) += phy-mv-usb.o
- obj-$(CONFIG_USB_MXS_PHY) += phy-mxs-usb.o
- obj-$(CONFIG_USB_RCAR_PHY) += phy-rcar-usb.o
---- /dev/null
-+++ b/drivers/usb/phy/phy-qcom-hsusb.c
-@@ -0,0 +1,340 @@
-+/* Copyright (c) 2013-2014, Code Aurora Forum. All rights reserved.
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 and
-+ * only version 2 as published by the Free Software Foundation.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ * GNU General Public License for more details.
-+ */
-+
-+#include <linux/clk.h>
-+#include <linux/err.h>
-+#include <linux/io.h>
-+#include <linux/module.h>
-+#include <linux/of.h>
-+#include <linux/platform_device.h>
-+#include <linux/regulator/consumer.h>
-+#include <linux/usb/phy.h>
-+
-+/**
-+ * USB QSCRATCH Hardware registers
-+ */
-+#define QSCRATCH_CTRL_REG (0x04)
-+#define QSCRATCH_GENERAL_CFG (0x08)
-+#define PHY_CTRL_REG (0x10)
-+#define PARAMETER_OVERRIDE_X_REG (0x14)
-+#define CHARGING_DET_CTRL_REG (0x18)
-+#define CHARGING_DET_OUTPUT_REG (0x1c)
-+#define ALT_INTERRUPT_EN_REG (0x20)
-+#define PHY_IRQ_STAT_REG (0x24)
-+#define CGCTL_REG (0x28)
-+
-+#define PHY_3P3_VOL_MIN 3050000 /* uV */
-+#define PHY_3P3_VOL_MAX 3300000 /* uV */
-+#define PHY_3P3_HPM_LOAD 16000 /* uA */
-+
-+#define PHY_1P8_VOL_MIN 1800000 /* uV */
-+#define PHY_1P8_VOL_MAX 1800000 /* uV */
-+#define PHY_1P8_HPM_LOAD 19000 /* uA */
-+
-+/* TODO: these are suspicious */
-+#define USB_VDDCX_NO 1 /* index */
-+#define USB_VDDCX_MIN 5 /* index */
-+#define USB_VDDCX_MAX 7 /* index */
-+
-+struct qcom_dwc3_hs_phy {
-+ struct usb_phy phy;
-+ void __iomem *base;
-+ struct device *dev;
-+
-+ struct clk *xo_clk;
-+ struct clk *utmi_clk;
-+
-+ struct regulator *v3p3;
-+ struct regulator *v1p8;
-+ struct regulator *vddcx;
-+ struct regulator *vbus;
-+};
-+
-+#define phy_to_dw_phy(x) container_of((x), struct qcom_dwc3_hs_phy, phy)
-+
-+
-+/**
-+ * Write register.
-+ *
-+ * @base - QCOM DWC3 PHY base virtual address.
-+ * @offset - register offset.
-+ * @val - value to write.
-+ */
-+static inline void qcom_dwc3_hs_write(void __iomem *base, u32 offset, u32 val)
-+{
-+ writel(val, base + offset);
-+}
-+
-+/**
-+ * Write register and read back masked value to confirm it is written
-+ *
-+ * @base - QCOM DWC3 PHY base virtual address.
-+ * @offset - register offset.
-+ * @mask - register bitmask specifying what should be updated
-+ * @val - value to write.
-+ */
-+static inline void qcom_dwc3_hs_write_readback(void __iomem *base, u32 offset,
-+ const u32 mask, u32 val)
-+{
-+ u32 write_val, tmp = readl(base + offset);
-+
-+ tmp &= ~mask; /* retain other bits */
-+ write_val = tmp | val;
-+
-+ writel(write_val, base + offset);
-+
-+ /* Read back to see if val was written */
-+ tmp = readl(base + offset);
-+ tmp &= mask; /* clear other bits */
-+
-+ if (tmp != val)
-+ pr_err("write: %x to QSCRATCH: %x FAILED\n", val, offset);
-+}
-+
-+static int qcom_dwc3_hs_notify_connect(struct usb_phy *x,
-+ enum usb_device_speed speed)
-+{
-+ struct qcom_dwc3_hs_phy *phy = phy_to_dw_phy(x);
-+
-+ dev_err(phy->dev, "notify connect\n");
-+ return 0;
-+}
-+
-+static int qcom_dwc3_hs_notify_disconnect(struct usb_phy *x,
-+ enum usb_device_speed speed)
-+{
-+ struct qcom_dwc3_hs_phy *phy = phy_to_dw_phy(x);
-+
-+ dev_err(phy->dev, "notify disconnect\n");
-+ return 0;
-+}
-+
-+
-+static void qcom_dwc3_hs_phy_shutdown(struct usb_phy *x)
-+{
-+ struct qcom_dwc3_hs_phy *phy = phy_to_dw_phy(x);
-+ int ret;
-+
-+ ret = regulator_set_voltage(phy->v3p3, 0, PHY_3P3_VOL_MAX);
-+ if (ret)
-+ dev_err(phy->dev, "cannot set voltage for v3p3\n");
-+
-+ ret = regulator_set_voltage(phy->v1p8, 0, PHY_1P8_VOL_MAX);
-+ if (ret)
-+ dev_err(phy->dev, "cannot set voltage for v1p8\n");
-+
-+ ret = regulator_disable(phy->v1p8);
-+ if (ret)
-+ dev_err(phy->dev, "cannot disable v1p8\n");
-+
-+ ret = regulator_disable(phy->v3p3);
-+ if (ret)
-+ dev_err(phy->dev, "cannot disable v3p3\n");
-+
-+ ret = regulator_set_voltage(phy->vddcx, USB_VDDCX_NO, USB_VDDCX_MAX);
-+ if (ret)
-+ dev_err(phy->dev, "cannot set voltage for vddcx\n");
-+
-+ ret = regulator_disable(phy->vddcx);
-+ if (ret)
-+ dev_err(phy->dev, "cannot enable vddcx\n");
-+
-+ clk_disable_unprepare(phy->utmi_clk);
-+}
-+
-+static int qcom_dwc3_hs_phy_init(struct usb_phy *x)
-+{
-+ struct qcom_dwc3_hs_phy *phy = phy_to_dw_phy(x);
-+ int ret;
-+ u32 val;
-+
-+ clk_prepare_enable(phy->utmi_clk);
-+
-+ ret = regulator_set_voltage(phy->vddcx, USB_VDDCX_MIN, USB_VDDCX_MAX);
-+ if (ret)
-+ dev_err(phy->dev, "cannot set voltage for vddcx\n");
-+
-+ ret = regulator_enable(phy->vddcx);
-+ if (ret)
-+ dev_err(phy->dev, "cannot enable vddcx\n");
-+
-+ ret = regulator_set_voltage(phy->v3p3, PHY_3P3_VOL_MIN,
-+ PHY_3P3_VOL_MAX);
-+ if (ret)
-+ dev_err(phy->dev, "cannot set voltage for v3p3\n");
-+
-+ ret = regulator_set_voltage(phy->v1p8, PHY_1P8_VOL_MIN,
-+ PHY_1P8_VOL_MAX);
-+ if (ret)
-+ dev_err(phy->dev, "cannot set voltage for v1p8\n");
-+
-+ ret = regulator_set_optimum_mode(phy->v1p8, PHY_1P8_HPM_LOAD);
-+ if (ret < 0)
-+ dev_err(phy->dev, "cannot set HPM of regulator v1p8\n");
-+
-+ ret = regulator_enable(phy->v1p8);
-+ if (ret)
-+ dev_err(phy->dev, "cannot enable v1p8\n");
-+
-+ ret = regulator_set_optimum_mode(phy->v3p3, PHY_3P3_HPM_LOAD);
-+ if (ret < 0)
-+ dev_err(phy->dev, "cannot set HPM of regulator v3p3\n");
-+
-+ ret = regulator_enable(phy->v3p3);
-+ if (ret)
-+ dev_err(phy->dev, "cannot enable v3p3\n");
-+
-+ /*
-+ * HSPHY Initialization: Enable UTMI clock and clamp enable HVINTs,
-+ * and disable RETENTION (power-on default is ENABLED)
-+ */
-+ val = readl(phy->base + PHY_CTRL_REG);
-+ val |= BIT(18) | BIT(20) | BIT(11) | 0x70;
-+ qcom_dwc3_hs_write(phy->base, PHY_CTRL_REG, val);
-+ usleep_range(2000, 2200);
-+
-+ /*
-+ * write HSPHY init value to QSCRATCH reg to set HSPHY parameters like
-+ * VBUS valid threshold, disconnect valid threshold, DC voltage level,
-+ * preempasis and rise/fall time.
-+ */
-+ qcom_dwc3_hs_write_readback(phy->base, PARAMETER_OVERRIDE_X_REG,
-+ 0x03ffffff, 0x00d191a4);
-+
-+ /* Disable (bypass) VBUS and ID filters */
-+ qcom_dwc3_hs_write(phy->base, QSCRATCH_GENERAL_CFG, BIT(2));
-+
-+ return 0;
-+}
-+
-+static int qcom_dwc3_hs_phy_set_vbus(struct usb_phy *x, int on)
-+{
-+ struct qcom_dwc3_hs_phy *phy = phy_to_dw_phy(x);
-+ int ret = 0;
-+
-+ if (IS_ERR(phy->vbus))
-+ return on ? PTR_ERR(phy->vbus) : 0;
-+
-+ if (on)
-+ ret = regulator_enable(phy->vbus);
-+ else
-+ ret = regulator_disable(phy->vbus);
-+
-+ if (ret)
-+ dev_err(x->dev, "Cannot %s Vbus\n", on ? "set" : "off");
-+ return ret;
-+}
-+
-+static int qcom_dwc3_hs_probe(struct platform_device *pdev)
-+{
-+ struct qcom_dwc3_hs_phy *phy;
-+ struct resource *res;
-+ void __iomem *base;
-+
-+ phy = devm_kzalloc(&pdev->dev, sizeof(*phy), GFP_KERNEL);
-+ if (!phy)
-+ return -ENOMEM;
-+
-+ platform_set_drvdata(pdev, phy);
-+
-+ phy->dev = &pdev->dev;
-+
-+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-+ base = devm_ioremap_resource(phy->dev, res);
-+ if (IS_ERR(base))
-+ return PTR_ERR(base);
-+
-+ phy->vddcx = devm_regulator_get(phy->dev, "vddcx");
-+ if (IS_ERR(phy->vddcx)) {
-+ dev_dbg(phy->dev, "cannot get vddcx\n");
-+ return PTR_ERR(phy->vddcx);
-+ }
-+
-+ phy->v3p3 = devm_regulator_get(phy->dev, "v3p3");
-+ if (IS_ERR(phy->v3p3)) {
-+ dev_dbg(phy->dev, "cannot get v3p3\n");
-+ return PTR_ERR(phy->v3p3);
-+ }
-+
-+ phy->v1p8 = devm_regulator_get(phy->dev, "v1p8");
-+ if (IS_ERR(phy->v1p8)) {
-+ dev_dbg(phy->dev, "cannot get v1p8\n");
-+ return PTR_ERR(phy->v1p8);
-+ }
-+
-+ phy->vbus = devm_regulator_get(phy->dev, "vbus");
-+ if (IS_ERR(phy->vbus))
-+ dev_dbg(phy->dev, "Failed to get vbus\n");
-+
-+ phy->utmi_clk = devm_clk_get(phy->dev, "utmi");
-+ if (IS_ERR(phy->utmi_clk)) {
-+ dev_dbg(phy->dev, "cannot get UTMI handle\n");
-+ return PTR_ERR(phy->utmi_clk);
-+ }
-+
-+ phy->xo_clk = devm_clk_get(phy->dev, "xo");
-+ if (IS_ERR(phy->xo_clk)) {
-+ dev_dbg(phy->dev, "cannot get TCXO buffer handle\n");
-+ phy->xo_clk = NULL;
-+ }
-+
-+ clk_set_rate(phy->utmi_clk, 60000000);
-+
-+ if (phy->xo_clk)
-+ clk_prepare_enable(phy->xo_clk);
-+
-+ phy->base = base;
-+ phy->phy.dev = phy->dev;
-+ phy->phy.label = "qcom-dwc3-hsphy";
-+ phy->phy.init = qcom_dwc3_hs_phy_init;
-+ phy->phy.notify_connect = qcom_dwc3_hs_notify_connect;
-+ phy->phy.notify_disconnect = qcom_dwc3_hs_notify_disconnect;
-+ phy->phy.shutdown = qcom_dwc3_hs_phy_shutdown;
-+ phy->phy.set_vbus = qcom_dwc3_hs_phy_set_vbus;
-+ phy->phy.type = USB_PHY_TYPE_USB2;
-+ phy->phy.state = OTG_STATE_UNDEFINED;
-+
-+ usb_add_phy_dev(&phy->phy);
-+ return 0;
-+}
-+
-+static int qcom_dwc3_hs_remove(struct platform_device *pdev)
-+{
-+ struct qcom_dwc3_hs_phy *phy = platform_get_drvdata(pdev);
-+
-+ if (phy->xo_clk)
-+ clk_disable_unprepare(phy->xo_clk);
-+ usb_remove_phy(&phy->phy);
-+ return 0;
-+}
-+
-+static const struct of_device_id qcom_dwc3_hs_id_table[] = {
-+ { .compatible = "qcom,dwc3-hsphy" },
-+ { /* Sentinel */ }
-+};
-+MODULE_DEVICE_TABLE(of, qcom_dwc3_hs_id_table);
-+
-+static struct platform_driver qcom_dwc3_hs_driver = {
-+ .probe = qcom_dwc3_hs_probe,
-+ .remove = qcom_dwc3_hs_remove,
-+ .driver = {
-+ .name = "qcom-dwc3-hsphy",
-+ .owner = THIS_MODULE,
-+ .of_match_table = qcom_dwc3_hs_id_table,
-+ },
-+};
-+
-+module_platform_driver(qcom_dwc3_hs_driver);
-+
-+MODULE_ALIAS("platform:qcom-dwc3-hsphy");
-+MODULE_LICENSE("GPL v2");
-+MODULE_DESCRIPTION("DesignWare USB3 QCOM HSPHY driver");
---- /dev/null
-+++ b/drivers/usb/phy/phy-qcom-ssusb.c
-@@ -0,0 +1,455 @@
-+/* Copyright (c) 2013-2014, Code Aurora Forum. All rights reserved.
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 and
-+ * only version 2 as published by the Free Software Foundation.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ * GNU General Public License for more details.
-+ */
-+
-+#include <linux/clk.h>
-+#include <linux/err.h>
-+#include <linux/io.h>
-+#include <linux/module.h>
-+#include <linux/of.h>
-+#include <linux/platform_device.h>
-+#include <linux/regulator/consumer.h>
-+#include <linux/usb/phy.h>
-+
-+/**
-+ * USB QSCRATCH Hardware registers
-+ */
-+#define PHY_CTRL_REG (0x00)
-+#define PHY_PARAM_CTRL_1 (0x04)
-+#define PHY_PARAM_CTRL_2 (0x08)
-+#define CR_PROTOCOL_DATA_IN_REG (0x0c)
-+#define CR_PROTOCOL_DATA_OUT_REG (0x10)
-+#define CR_PROTOCOL_CAP_ADDR_REG (0x14)
-+#define CR_PROTOCOL_CAP_DATA_REG (0x18)
-+#define CR_PROTOCOL_READ_REG (0x1c)
-+#define CR_PROTOCOL_WRITE_REG (0x20)
-+
-+#define PHY_1P8_VOL_MIN 1800000 /* uV */
-+#define PHY_1P8_VOL_MAX 1800000 /* uV */
-+#define PHY_1P8_HPM_LOAD 23000 /* uA */
-+
-+/* TODO: these are suspicious */
-+#define USB_VDDCX_NO 1 /* index */
-+#define USB_VDDCX_MIN 5 /* index */
-+#define USB_VDDCX_MAX 7 /* index */
-+
-+struct qcom_dwc3_ss_phy {
-+ struct usb_phy phy;
-+ void __iomem *base;
-+ struct device *dev;
-+
-+ struct regulator *v1p8;
-+ struct regulator *vddcx;
-+
-+ struct clk *xo_clk;
-+ struct clk *ref_clk;
-+};
-+
-+#define phy_to_dw_phy(x) container_of((x), struct qcom_dwc3_ss_phy, phy)
-+
-+
-+/**
-+ * Write register
-+ *
-+ * @base - QCOM DWC3 PHY base virtual address.
-+ * @offset - register offset.
-+ * @val - value to write.
-+ */
-+static inline void qcom_dwc3_ss_write(void __iomem *base, u32 offset, u32 val)
-+{
-+ writel(val, base + offset);
-+}
-+
-+/**
-+ * Write register and read back masked value to confirm it is written
-+ *
-+ * @base - QCOM DWC3 PHY base virtual address.
-+ * @offset - register offset.
-+ * @mask - register bitmask specifying what should be updated
-+ * @val - value to write.
-+ */
-+static inline void qcom_dwc3_ss_write_readback(void __iomem *base, u32 offset,
-+ const u32 mask, u32 val)
-+{
-+ u32 write_val, tmp = readl(base + offset);
-+
-+ tmp &= ~mask; /* retain other bits */
-+ write_val = tmp | val;
-+
-+ writel(write_val, base + offset);
-+
-+ /* Read back to see if val was written */
-+ tmp = readl(base + offset);
-+ tmp &= mask; /* clear other bits */
-+
-+ if (tmp != val)
-+ pr_err("write: %x to QSCRATCH: %x FAILED\n", val, offset);
-+}
-+
-+/**
-+ * Write SSPHY register
-+ *
-+ * @base - QCOM DWC3 PHY base virtual address.
-+ * @addr - SSPHY address to write.
-+ * @val - value to write.
-+ */
-+static void qcom_dwc3_ss_write_phycreg(void __iomem *base, u32 addr, u32 val)
-+{
-+ writel(addr, base + CR_PROTOCOL_DATA_IN_REG);
-+ writel(0x1, base + CR_PROTOCOL_CAP_ADDR_REG);
-+ while (readl(base + CR_PROTOCOL_CAP_ADDR_REG))
-+ cpu_relax();
-+
-+ writel(val, base + CR_PROTOCOL_DATA_IN_REG);
-+ writel(0x1, base + CR_PROTOCOL_CAP_DATA_REG);
-+ while (readl(base + CR_PROTOCOL_CAP_DATA_REG))
-+ cpu_relax();
-+
-+ writel(0x1, base + CR_PROTOCOL_WRITE_REG);
-+ while (readl(base + CR_PROTOCOL_WRITE_REG))
-+ cpu_relax();
-+}
-+
-+/**
-+ * Read SSPHY register.
-+ *
-+ * @base - QCOM DWC3 PHY base virtual address.
-+ * @addr - SSPHY address to read.
-+ */
-+static u32 qcom_dwc3_ss_read_phycreg(void __iomem *base, u32 addr)
-+{
-+ bool first_read = true;
-+
-+ writel(addr, base + CR_PROTOCOL_DATA_IN_REG);
-+ writel(0x1, base + CR_PROTOCOL_CAP_ADDR_REG);
-+ while (readl(base + CR_PROTOCOL_CAP_ADDR_REG))
-+ cpu_relax();
-+
-+ /*
-+ * Due to hardware bug, first read of SSPHY register might be
-+ * incorrect. Hence as workaround, SW should perform SSPHY register
-+ * read twice, but use only second read and ignore first read.
-+ */
-+retry:
-+ writel(0x1, base + CR_PROTOCOL_READ_REG);
-+ while (readl(base + CR_PROTOCOL_READ_REG))
-+ cpu_relax();
-+
-+ if (first_read) {
-+ readl(base + CR_PROTOCOL_DATA_OUT_REG);
-+ first_read = false;
-+ goto retry;
-+ }
-+
-+ return readl(base + CR_PROTOCOL_DATA_OUT_REG);
-+}
-+
-+static void qcom_dwc3_ss_phy_shutdown(struct usb_phy *x)
-+{
-+ struct qcom_dwc3_ss_phy *phy = phy_to_dw_phy(x);
-+ int ret;
-+
-+ /* Sequence to put SSPHY in low power state:
-+ * 1. Clear REF_PHY_EN in PHY_CTRL_REG
-+ * 2. Clear REF_USE_PAD in PHY_CTRL_REG
-+ * 3. Set TEST_POWERED_DOWN in PHY_CTRL_REG to enable PHY retention
-+ * 4. Disable SSPHY ref clk
-+ */
-+ qcom_dwc3_ss_write_readback(phy->base, PHY_CTRL_REG, (1 << 8), 0x0);
-+ qcom_dwc3_ss_write_readback(phy->base, PHY_CTRL_REG, (1 << 28), 0x0);
-+ qcom_dwc3_ss_write_readback(phy->base, PHY_CTRL_REG,
-+ (1 << 26), (1 << 26));
-+
-+ usleep_range(1000, 1200);
-+ clk_disable_unprepare(phy->ref_clk);
-+
-+ ret = regulator_set_voltage(phy->vddcx, USB_VDDCX_NO, USB_VDDCX_MAX);
-+ if (ret)
-+ dev_err(phy->dev, "cannot set voltage for vddcx\n");
-+
-+ regulator_disable(phy->vddcx);
-+
-+ ret = regulator_set_voltage(phy->v1p8, 0, PHY_1P8_VOL_MAX);
-+ if (ret)
-+ dev_err(phy->dev, "cannot set v1p8\n");
-+
-+ regulator_disable(phy->v1p8);
-+}
-+
-+static int qcom_dwc3_ss_phy_init(struct usb_phy *x)
-+{
-+ struct qcom_dwc3_ss_phy *phy = phy_to_dw_phy(x);
-+ u32 data = 0;
-+ int ret;
-+
-+ ret = regulator_set_voltage(phy->vddcx, USB_VDDCX_MIN, USB_VDDCX_MAX);
-+ if (ret) {
-+ dev_err(phy->dev, "cannot set voltage for vddcx\n");
-+ return ret;
-+ }
-+
-+ ret = regulator_enable(phy->vddcx);
-+ if (ret) {
-+ dev_err(phy->dev, "cannot enable vddcx\n");
-+ return ret;
-+ }
-+
-+ ret = regulator_set_voltage(phy->v1p8, PHY_1P8_VOL_MIN,
-+ PHY_1P8_VOL_MAX);
-+ if (ret) {
-+ regulator_disable(phy->vddcx);
-+ dev_err(phy->dev, "cannot set v1p8\n");
-+ return ret;
-+ }
-+
-+ ret = regulator_enable(phy->v1p8);
-+ if (ret) {
-+ regulator_disable(phy->vddcx);
-+ dev_err(phy->dev, "cannot enable v1p8\n");
-+ return ret;
-+ }
-+
-+ clk_prepare_enable(phy->ref_clk);
-+ usleep_range(1000, 1200);
-+
-+ /* reset phy */
-+ data = readl_relaxed(phy->base + PHY_CTRL_REG);
-+ writel_relaxed(data | BIT(7), phy->base + PHY_CTRL_REG);
-+ usleep_range(2000, 2200);
-+ writel_relaxed(data, phy->base + PHY_CTRL_REG);
-+
-+ /* clear REF_PAD, we don't have XO clk */
-+ data &= ~BIT(28);
-+ writel_relaxed(data, phy->base + PHY_CTRL_REG);
-+ msleep(30);
-+
-+ data |= BIT(8) | BIT(24);
-+ writel_relaxed(data, phy->base + PHY_CTRL_REG);
-+
-+ /*
-+ * WORKAROUND: There is SSPHY suspend bug due to which USB enumerates
-+ * in HS mode instead of SS mode. Workaround it by asserting
-+ * LANE0.TX_ALT_BLOCK.EN_ALT_BUS to enable TX to use alt bus mode
-+ */
-+ data = qcom_dwc3_ss_read_phycreg(phy->base, 0x102d);
-+ data |= (1 << 7);
-+ qcom_dwc3_ss_write_phycreg(phy->base, 0x102D, data);
-+
-+ data = qcom_dwc3_ss_read_phycreg(phy->base, 0x1010);
-+ data &= ~0xff0;
-+ data |= 0x20;
-+ qcom_dwc3_ss_write_phycreg(phy->base, 0x1010, data);
-+
-+ /*
-+ * Fix RX Equalization setting as follows
-+ * LANE0.RX_OVRD_IN_HI. RX_EQ_EN set to 0
-+ * LANE0.RX_OVRD_IN_HI.RX_EQ_EN_OVRD set to 1
-+ * LANE0.RX_OVRD_IN_HI.RX_EQ set to 3
-+ * LANE0.RX_OVRD_IN_HI.RX_EQ_OVRD set to 1
-+ */
-+ data = qcom_dwc3_ss_read_phycreg(phy->base, 0x1006);
-+ data &= ~(1 << 6);
-+ data |= (1 << 7);
-+ data &= ~(0x7 << 8);
-+ data |= (0x3 << 8);
-+ data |= (0x1 << 11);
-+ qcom_dwc3_ss_write_phycreg(phy->base, 0x1006, data);
-+
-+ /*
-+ * Set EQ and TX launch amplitudes as follows
-+ * LANE0.TX_OVRD_DRV_LO.PREEMPH set to 22
-+ * LANE0.TX_OVRD_DRV_LO.AMPLITUDE set to 127
-+ * LANE0.TX_OVRD_DRV_LO.EN set to 1.
-+ */
-+ data = qcom_dwc3_ss_read_phycreg(phy->base, 0x1002);
-+ data &= ~0x3f80;
-+ data |= (0x16 << 7);
-+ data &= ~0x7f;
-+ data |= (0x7f | (1 << 14));
-+ qcom_dwc3_ss_write_phycreg(phy->base, 0x1002, data);
-+
-+ /*
-+ * Set the QSCRATCH PHY_PARAM_CTRL1 parameters as follows
-+ * TX_FULL_SWING [26:20] amplitude to 127
-+ * TX_DEEMPH_3_5DB [13:8] to 22
-+ * LOS_BIAS [2:0] to 0x5
-+ */
-+ qcom_dwc3_ss_write_readback(phy->base, PHY_PARAM_CTRL_1,
-+ 0x07f03f07, 0x07f01605);
-+ return 0;
-+}
-+
-+static int qcom_dwc3_ss_set_suspend(struct usb_phy *x, int suspend)
-+{
-+ struct qcom_dwc3_ss_phy *phy = phy_to_dw_phy(x);
-+ u32 data;
-+
-+ if (!suspend) {
-+ /* reset phy */
-+ data = readl_relaxed(phy->base + PHY_CTRL_REG);
-+ writel_relaxed(data | BIT(7), phy->base + PHY_CTRL_REG);
-+ usleep_range(2000, 2200);
-+ writel_relaxed(data, phy->base + PHY_CTRL_REG);
-+
-+ /* clear REF_PAD, we don't have XO clk */
-+ data &= ~BIT(28);
-+ writel_relaxed(data, phy->base + PHY_CTRL_REG);
-+ msleep(30);
-+
-+ data |= BIT(8) | BIT(24);
-+ writel_relaxed(data, phy->base + PHY_CTRL_REG);
-+
-+ /*
-+ * WORKAROUND: There is SSPHY suspend bug due to which USB
-+ * enumerates in HS mode instead of SS mode. Workaround it by
-+ * asserting LANE0.TX_ALT_BLOCK.EN_ALT_BUS to enable TX to use
-+ * alt bus mode
-+ */
-+ data = qcom_dwc3_ss_read_phycreg(phy->base, 0x102d);
-+ data |= (1 << 7);
-+ qcom_dwc3_ss_write_phycreg(phy->base, 0x102D, data);
-+
-+ data = qcom_dwc3_ss_read_phycreg(phy->base, 0x1010);
-+ data &= ~0xff0;
-+ data |= 0x20;
-+ qcom_dwc3_ss_write_phycreg(phy->base, 0x1010, data);
-+
-+ /*
-+ * Fix RX Equalization setting as follows
-+ * LANE0.RX_OVRD_IN_HI. RX_EQ_EN set to 0
-+ * LANE0.RX_OVRD_IN_HI.RX_EQ_EN_OVRD set to 1
-+ * LANE0.RX_OVRD_IN_HI.RX_EQ set to 3
-+ * LANE0.RX_OVRD_IN_HI.RX_EQ_OVRD set to 1
-+ */
-+ data = qcom_dwc3_ss_read_phycreg(phy->base, 0x1006);
-+ data &= ~(1 << 6);
-+ data |= (1 << 7);
-+ data &= ~(0x7 << 8);
-+ data |= (0x3 << 8);
-+ data |= (0x1 << 11);
-+ qcom_dwc3_ss_write_phycreg(phy->base, 0x1006, data);
-+
-+ /*
-+ * Set EQ and TX launch amplitudes as follows
-+ * LANE0.TX_OVRD_DRV_LO.PREEMPH set to 22
-+ * LANE0.TX_OVRD_DRV_LO.AMPLITUDE set to 127
-+ * LANE0.TX_OVRD_DRV_LO.EN set to 1.
-+ */
-+ data = qcom_dwc3_ss_read_phycreg(phy->base, 0x1002);
-+ data &= ~0x3f80;
-+ data |= (0x16 << 7);
-+ data &= ~0x7f;
-+ data |= (0x7f | (1 << 14));
-+ qcom_dwc3_ss_write_phycreg(phy->base, 0x1002, data);
-+
-+ /*
-+ * Set the QSCRATCH PHY_PARAM_CTRL1 parameters as follows
-+ * TX_FULL_SWING [26:20] amplitude to 127
-+ * TX_DEEMPH_3_5DB [13:8] to 22
-+ * LOS_BIAS [2:0] to 0x5
-+ */
-+ qcom_dwc3_ss_write_readback(phy->base, PHY_PARAM_CTRL_1,
-+ 0x07f03f07, 0x07f01605);
-+ }
-+ return 0;
-+}
-+
-+static int qcom_dwc3_ss_probe(struct platform_device *pdev)
-+{
-+ struct qcom_dwc3_ss_phy *phy;
-+ struct resource *res;
-+ void __iomem *base;
-+ int ret;
-+
-+ phy = devm_kzalloc(&pdev->dev, sizeof(*phy), GFP_KERNEL);
-+ if (!phy)
-+ return -ENOMEM;
-+
-+ platform_set_drvdata(pdev, phy);
-+
-+ phy->dev = &pdev->dev;
-+
-+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-+ base = devm_ioremap_resource(phy->dev, res);
-+ if (IS_ERR(base))
-+ return PTR_ERR(base);
-+
-+ phy->vddcx = devm_regulator_get(phy->dev, "vddcx");
-+ if (IS_ERR(phy->vddcx)) {
-+ dev_dbg(phy->dev, "cannot get vddcx\n");
-+ return PTR_ERR(phy->vddcx);
-+ }
-+
-+ phy->v1p8 = devm_regulator_get(phy->dev, "v1p8");
-+ if (IS_ERR(phy->v1p8)) {
-+ dev_dbg(phy->dev, "cannot get v1p8\n");
-+ return PTR_ERR(phy->v1p8);
-+ }
-+
-+ phy->xo_clk = devm_clk_get(phy->dev, "xo");
-+ if (IS_ERR(phy->xo_clk)) {
-+ dev_dbg(phy->dev, "cannot get XO clk, assuming not present\n");
-+ phy->xo_clk = NULL;
-+ }
-+
-+ phy->ref_clk = devm_clk_get(phy->dev, "ref");
-+ if (IS_ERR(phy->ref_clk)) {
-+ dev_dbg(phy->dev, "cannot get ref clock handle\n");
-+ return PTR_ERR(phy->ref_clk);
-+ }
-+
-+ clk_set_rate(phy->ref_clk, 125000000);
-+ if (phy->xo_clk)
-+ clk_prepare_enable(phy->xo_clk);
-+
-+ phy->base = base;
-+ phy->phy.dev = phy->dev;
-+ phy->phy.label = "qcom-dwc3-ssphy";
-+ phy->phy.init = qcom_dwc3_ss_phy_init;
-+ phy->phy.shutdown = qcom_dwc3_ss_phy_shutdown;
-+ phy->phy.set_suspend = qcom_dwc3_ss_set_suspend;
-+ phy->phy.type = USB_PHY_TYPE_USB3;
-+
-+ ret = usb_add_phy_dev(&phy->phy);
-+ return ret;
-+}
-+
-+static int qcom_dwc3_ss_remove(struct platform_device *pdev)
-+{
-+ struct qcom_dwc3_ss_phy *phy = platform_get_drvdata(pdev);
-+
-+ if (phy->xo_clk)
-+ clk_disable_unprepare(phy->xo_clk);
-+ usb_remove_phy(&phy->phy);
-+ return 0;
-+}
-+
-+static const struct of_device_id qcom_dwc3_ss_id_table[] = {
-+ { .compatible = "qcom,dwc3-ssphy" },
-+ { /* Sentinel */ }
-+};
-+MODULE_DEVICE_TABLE(of, qcom_dwc3_ss_id_table);
-+
-+static struct platform_driver qcom_dwc3_ss_driver = {
-+ .probe = qcom_dwc3_ss_probe,
-+ .remove = qcom_dwc3_ss_remove,
-+ .driver = {
-+ .name = "qcom-dwc3-ssphy",
-+ .owner = THIS_MODULE,
-+ .of_match_table = qcom_dwc3_ss_id_table,
-+ },
-+};
-+
-+module_platform_driver(qcom_dwc3_ss_driver);
-+
-+MODULE_ALIAS("platform:qcom-dwc3-ssphy");
-+MODULE_LICENSE("GPL v2");
-+MODULE_DESCRIPTION("DesignWare USB3 QCOM SSPHY driver");
diff --git a/target/linux/ipq806x/patches/0158-usb-dwc3-qcom-Add-device-tree-binding.patch b/target/linux/ipq806x/patches/0158-usb-dwc3-qcom-Add-device-tree-binding.patch
deleted file mode 100644
index ffe2a8d..0000000
--- a/target/linux/ipq806x/patches/0158-usb-dwc3-qcom-Add-device-tree-binding.patch
+++ /dev/null
@@ -1,125 +0,0 @@
-From c7045330c5976eb31bd79bc57c5db684588d595e Mon Sep 17 00:00:00 2001
-From: "Ivan T. Ivanov" <iivanov@mm-sol.com>
-Date: Mon, 7 Oct 2013 10:44:55 +0300
-Subject: [PATCH 158/182] usb: dwc3: qcom: Add device tree binding
-
-QCOM USB3.0 core wrapper consist of USB3.0 IP from Synopsys
-(SNPS) and HS, SS PHY's control and configuration registers.
-
-It could operate in device mode (SS, HS, FS) and host
-mode (SS, HS, FS, LS).
-
-Signed-off-by: Ivan T. Ivanov <iivanov@mm-sol.com>
-Acked-by: Stephen Warren <swarren@nvidia.com>
----
- .../devicetree/bindings/usb/qcom,dwc3.txt | 104 ++++++++++++++++++++
- 1 file changed, 104 insertions(+)
- create mode 100644 Documentation/devicetree/bindings/usb/qcom,dwc3.txt
-
---- /dev/null
-+++ b/Documentation/devicetree/bindings/usb/qcom,dwc3.txt
-@@ -0,0 +1,104 @@
-+Qualcomm SuperSpeed DWC3 USB SoC controller
-+
-+
-+QCOM DWC3 Highspeed USB PHY
-+========================
-+Required properities:
-+- compatible: should contain "qcom,dwc3-hsphy";
-+- reg: offset and length of the register set in the memory map
-+- clocks: A list of phandle + clock-specifier pairs for the
-+ clocks listed in clock-names
-+- clock-names: Should contain the following:
-+ "utmi" UTMI clock
-+- v1p8-supply: phandle to the regulator for the 1.8v supply to HSPHY.
-+- v3p3-supply: phandle to the regulator for the 3.3v supply to HSPHY.
-+- vbus-supply: phandle to the regulator for the vbus supply for host
-+ mode.
-+- vddcx-supply: phandle to the regulator for the vdd supply for HSPHY
-+ digital circuit operation.
-+
-+Optional clocks:
-+ "xo" External reference clock
-+
-+
-+QCOM DWC3 Superspeed USB PHY
-+=========================
-+Required properities:
-+- compatible: should contain "qcom,dwc3-ssphy";
-+- reg: offset and length of the register set in the memory map
-+- clocks: A list of phandle + clock-specifier pairs for the
-+ clocks listed in clock-names
-+- clock-names: Should contain the following:
-+ "ref" Reference clock used in host mode.
-+- v1p8-supply: phandle to the regulator for the 1.8v supply to HSPHY.
-+- vddcx-supply: phandle to the regulator for the vdd supply for HSPHY
-+ digital circuit operation.
-+
-+Optional clocks:
-+ "xo" External reference clock
-+
-+QCOM DWC3 controller wrapper
-+===========================
-+Required properties:
-+- compatible: should contain "qcom,dwc3"
-+- clocks: A list of phandle + clock-specifier pairs for the
-+ clocks listed in clock-names
-+- clock-names: Should contain the following:
-+ "core" Master/Core clock, have to be >= 125 MHz for SS
-+ operation and >= 60MHz for HS operation
-+
-+Optional clocks:
-+ "iface" System bus AXI clock. Not present on all platforms
-+ "sleep" Sleep clock, used when USB3 core goes into low
-+ power mode (U3).
-+
-+Optional regulator:
-+- gdsc-supply: phandle to the regulator from globally distributed
-+ switch controller
-+
-+Required child node:
-+A child node must exist to represent the core DWC3 IP block. The name of
-+the node is not important. The content of the node is defined in dwc3.txt.
-+
-+Example device nodes:
-+
-+ hs_phy_0: phy@110f8800 {
-+ compatible = "qcom,dwc3-hsphy";
-+ reg = <0x110f8800 0x30>;
-+ clocks = <&gcc USB30_0_UTMI_CLK>;
-+ clock-names = "utmi";
-+
-+ status = "disabled";
-+ };
-+
-+ ss_phy_0: phy@110f8830 {
-+ compatible = "qcom,dwc3-ssphy";
-+ reg = <0x110f8830 0x30>;
-+
-+ clocks = <&gcc USB30_0_MASTER_CLK>;
-+ clock-names = "ref";
-+
-+ status = "disabled";
-+ };
-+
-+ usb3_0: usb30@0 {
-+ compatible = "qcom,dwc3";
-+ #address-cells = <1>;
-+ #size-cells = <1>;
-+ clocks = <&gcc USB30_0_MASTER_CLK>;
-+ clock-names = "core";
-+
-+ ranges;
-+
-+ status = "disabled";
-+
-+ dwc3@11000000 {
-+ compatible = "snps,dwc3";
-+ reg = <0x11000000 0xcd00>;
-+ interrupts = <0 110 0x4>;
-+ usb-phy = <&hs_phy_0>, <&ss_phy_0>;
-+ phy-names = "usb2-phy", "usb3-phy";
-+ tx-fifo-resize;
-+ dr_mode = "host";
-+ };
-+ };
diff --git a/target/linux/ipq806x/patches/0159-arm-ipq8064-Add-USB3-DT-information.patch b/target/linux/ipq806x/patches/0159-arm-ipq8064-Add-USB3-DT-information.patch
deleted file mode 100644
index 843e94f..0000000
--- a/target/linux/ipq806x/patches/0159-arm-ipq8064-Add-USB3-DT-information.patch
+++ /dev/null
@@ -1,155 +0,0 @@
-From 269a71c81438604d27f01ec703daa7f5e3f39e8b Mon Sep 17 00:00:00 2001
-From: Andy Gross <agross@codeaurora.org>
-Date: Sun, 15 Jun 2014 00:48:18 -0500
-Subject: [PATCH 159/182] arm: ipq8064: Add USB3 DT information
-
-This patch fleshes out the USB3 specific information for the IPQ8064 platform.
-
-Signed-off-by: Andy Gross <agross@codeaurora.org>
----
- arch/arm/boot/dts/qcom-ipq8064-ap148.dts | 29 ++++++++++
- arch/arm/boot/dts/qcom-ipq8064.dtsi | 90 ++++++++++++++++++++++++++++++
- 2 files changed, 119 insertions(+)
-
---- a/arch/arm/boot/dts/qcom-ipq8064-ap148.dts
-+++ b/arch/arm/boot/dts/qcom-ipq8064-ap148.dts
-@@ -160,5 +160,34 @@
- pinctrl-0 = <&nand_pins>;
- pinctrl-names = "default";
- };
-+
-+ tcsr@1a400000 {
-+ status = "ok";
-+ qcom,usb-ctrl-select = <TCSR_USB_SELECT_USB3_DUAL>;
-+ };
-+
-+ phy@100f8800 { /* USB3 port 1 HS phy */
-+ status = "ok";
-+ };
-+
-+ phy@100f8830 { /* USB3 port 1 SS phy */
-+ status = "ok";
-+ };
-+
-+ phy@110f8800 { /* USB3 port 0 HS phy */
-+ status = "ok";
-+ };
-+
-+ phy@110f8830 { /* USB3 port 0 SS phy */
-+ status = "ok";
-+ };
-+
-+ usb30@0 {
-+ status = "ok";
-+ };
-+
-+ usb30@1 {
-+ status = "ok";
-+ };
- };
- };
---- a/arch/arm/boot/dts/qcom-ipq8064.dtsi
-+++ b/arch/arm/boot/dts/qcom-ipq8064.dtsi
-@@ -4,6 +4,7 @@
- #include <dt-bindings/clock/qcom,gcc-ipq806x.h>
- #include <dt-bindings/reset/qcom,gcc-ipq806x.h>
- #include <dt-bindings/soc/qcom,gsbi.h>
-+#include <dt-bindings/soc/qcom,tcsr.h>
-
- / {
- model = "Qualcomm IPQ8064";
-@@ -402,5 +403,94 @@
-
- status = "disabled";
- };
-+
-+ tcsr: tcsr@1a400000 {
-+ compatible = "qcom,tcsr";
-+ reg = <0x1a400000 0x100>;
-+
-+ status = "disabled";
-+ };
-+
-+ hs_phy_1: phy@100f8800 {
-+ compatible = "qcom,dwc3-hsphy";
-+ reg = <0x100f8800 0x30>;
-+ clocks = <&gcc USB30_1_UTMI_CLK>;
-+ clock-names = "utmi";
-+
-+ status = "disabled";
-+ };
-+
-+ ss_phy_1: phy@100f8830 {
-+ compatible = "qcom,dwc3-ssphy";
-+ reg = <0x100f8830 0x30>;
-+
-+ clocks = <&gcc USB30_1_MASTER_CLK>;
-+ clock-names = "ref";
-+
-+ status = "disabled";
-+ };
-+
-+ hs_phy_0: phy@110f8800 {
-+ compatible = "qcom,dwc3-hsphy";
-+ reg = <0x110f8800 0x30>;
-+ clocks = <&gcc USB30_0_UTMI_CLK>;
-+ clock-names = "utmi";
-+
-+ status = "disabled";
-+ };
-+
-+ ss_phy_0: phy@110f8830 {
-+ compatible = "qcom,dwc3-ssphy";
-+ reg = <0x110f8830 0x30>;
-+
-+ clocks = <&gcc USB30_0_MASTER_CLK>;
-+ clock-names = "ref";
-+
-+ status = "disabled";
-+ };
-+
-+ usb3_0: usb30@0 {
-+ compatible = "qcom,dwc3";
-+ #address-cells = <1>;
-+ #size-cells = <1>;
-+ clocks = <&gcc USB30_0_MASTER_CLK>;
-+ clock-names = "core";
-+
-+ ranges;
-+
-+ status = "disabled";
-+
-+ dwc3@11000000 {
-+ compatible = "snps,dwc3";
-+ reg = <0x11000000 0xcd00>;
-+ interrupts = <0 110 0x4>;
-+ usb-phy = <&hs_phy_0>, <&ss_phy_0>;
-+ phy-names = "usb2-phy", "usb3-phy";
-+ tx-fifo-resize;
-+ dr_mode = "host";
-+ };
-+ };
-+
-+ usb3_1: usb30@1 {
-+ compatible = "qcom,dwc3";
-+ #address-cells = <1>;
-+ #size-cells = <1>;
-+ clocks = <&gcc USB30_1_MASTER_CLK>;
-+ clock-names = "core";
-+
-+ ranges;
-+
-+ status = "disabled";
-+
-+ dwc3@10000000 {
-+ compatible = "snps,dwc3";
-+ reg = <0x10000000 0xcd00>;
-+ interrupts = <0 205 0x4>;
-+ usb-phy = <&hs_phy_1>, <&ss_phy_1>;
-+ phy-names = "usb2-phy", "usb3-phy";
-+ tx-fifo-resize;
-+ dr_mode = "host";
-+ };
-+ };
- };
- };
diff --git a/target/linux/ipq806x/patches/0160-ARM-qcom-config-Add-TCSR-and-USB3-options.patch b/target/linux/ipq806x/patches/0160-ARM-qcom-config-Add-TCSR-and-USB3-options.patch
deleted file mode 100644
index 400c87e..0000000
--- a/target/linux/ipq806x/patches/0160-ARM-qcom-config-Add-TCSR-and-USB3-options.patch
+++ /dev/null
@@ -1,37 +0,0 @@
-From 8e69ee9a592f363476f18e91f57d871662e9a393 Mon Sep 17 00:00:00 2001
-From: Andy Gross <agross@codeaurora.org>
-Date: Mon, 16 Jun 2014 16:37:22 -0500
-Subject: [PATCH 160/182] ARM: qcom: config: Add TCSR and USB3 options
-
-Enable TCSR and USB3 options.
-
-Signed-off-by: Andy Gross <agross@codeaurora.org>
----
- arch/arm/configs/qcom_defconfig | 6 ++++++
- 1 file changed, 6 insertions(+)
-
---- a/arch/arm/configs/qcom_defconfig
-+++ b/arch/arm/configs/qcom_defconfig
-@@ -122,9 +122,14 @@ CONFIG_HID_BATTERY_STRENGTH=y
- CONFIG_USB=y
- CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
- CONFIG_USB_MON=y
-+CONFIG_USB_XHCI_HCD=y
- CONFIG_USB_EHCI_HCD=y
- CONFIG_USB_ACM=y
-+CONFIG_USB_STORAGE=y
-+CONFIG_USB_DWC3=y
-+CONFIG_USB_DWC3_HOST=y
- CONFIG_USB_SERIAL=y
-+CONFIG_USB_QCOM_DWC3_PHY=y
- CONFIG_USB_GADGET=y
- CONFIG_USB_GADGET_DEBUG_FILES=y
- CONFIG_USB_GADGET_VBUS_DRAW=500
-@@ -138,6 +143,7 @@ CONFIG_DMADEVICES=y
- CONFIG_QCOM_BAM_DMA=y
- CONFIG_STAGING=y
- CONFIG_QCOM_GSBI=y
-+CONFIG_QCOM_TCSR=y
- CONFIG_COMMON_CLK_QCOM=y
- CONFIG_IPQ_GCC_806X=y
- CONFIG_MSM_GCC_8660=y
diff --git a/target/linux/ipq806x/patches/0161-ARM-Remove-ARCH_HAS_CPUFREQ-config-option.patch b/target/linux/ipq806x/patches/0161-ARM-Remove-ARCH_HAS_CPUFREQ-config-option.patch
deleted file mode 100644
index 32f2b5d..0000000
--- a/target/linux/ipq806x/patches/0161-ARM-Remove-ARCH_HAS_CPUFREQ-config-option.patch
+++ /dev/null
@@ -1,234 +0,0 @@
-From 5d102a45ee224fa32c775deb75bf7eb9d2ee2cf0 Mon Sep 17 00:00:00 2001
-From: Stephen Boyd <sboyd@codeaurora.org>
-Date: Tue, 3 Jun 2014 11:24:23 -0700
-Subject: [PATCH 161/182] ARM: Remove ARCH_HAS_CPUFREQ config option
-
-This config exists entirely to hide the cpufreq menu from the
-kernel configuration unless a platform has selected it. Nothing
-is actually built if this config is 'Y' and it just leads to more
-patches that add a select under a platform Kconfig so that some
-other CPUfreq option can be chosen. Let's remove the option so
-that we can always enable CPUfreq drivers on ARM platforms.
-
-Acked-by: Viresh Kumar <viresh.kumar@linaro.org>
-Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
-Signed-off-by: Arnd Bergmann <arnd@arndb.de>
-Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
----
- arch/arm/Kconfig | 17 -----------------
- arch/arm/mach-davinci/Kconfig | 1 -
- arch/arm/mach-highbank/Kconfig | 1 -
- arch/arm/mach-imx/Kconfig | 2 --
- arch/arm/mach-omap2/Kconfig | 1 -
- arch/arm/mach-shmobile/Kconfig | 2 --
- arch/arm/mach-spear/Kconfig | 1 -
- arch/arm/mach-tegra/Kconfig | 1 -
- arch/arm/mach-ux500/Kconfig | 1 -
- arch/arm/mach-vexpress/Kconfig | 1 -
- arch/arm/mach-vt8500/Kconfig | 1 -
- 11 files changed, 29 deletions(-)
-
---- a/arch/arm/Kconfig
-+++ b/arch/arm/Kconfig
-@@ -181,13 +181,6 @@ config ARCH_HAS_ILOG2_U32
- config ARCH_HAS_ILOG2_U64
- bool
-
--config ARCH_HAS_CPUFREQ
-- bool
-- help
-- Internal node to signify that the ARCH has CPUFREQ support
-- and that the relevant menu configurations are displayed for
-- it.
--
- config ARCH_HAS_BANDGAP
- bool
-
-@@ -316,7 +309,6 @@ config ARCH_MULTIPLATFORM
-
- config ARCH_INTEGRATOR
- bool "ARM Ltd. Integrator family"
-- select ARCH_HAS_CPUFREQ
- select ARM_AMBA
- select ARM_PATCH_PHYS_VIRT
- select AUTO_ZRELADDR
-@@ -541,7 +533,6 @@ config ARCH_DOVE
-
- config ARCH_KIRKWOOD
- bool "Marvell Kirkwood"
-- select ARCH_HAS_CPUFREQ
- select ARCH_REQUIRE_GPIOLIB
- select CPU_FEROCEON
- select GENERIC_CLOCKEVENTS
-@@ -642,7 +633,6 @@ config ARCH_LPC32XX
- config ARCH_PXA
- bool "PXA2xx/PXA3xx-based"
- depends on MMU
-- select ARCH_HAS_CPUFREQ
- select ARCH_MTD_XIP
- select ARCH_REQUIRE_GPIOLIB
- select ARM_CPU_SUSPEND if PM
-@@ -711,7 +701,6 @@ config ARCH_RPC
-
- config ARCH_SA1100
- bool "SA1100-based"
-- select ARCH_HAS_CPUFREQ
- select ARCH_MTD_XIP
- select ARCH_REQUIRE_GPIOLIB
- select ARCH_SPARSEMEM_ENABLE
-@@ -729,7 +718,6 @@ config ARCH_SA1100
-
- config ARCH_S3C24XX
- bool "Samsung S3C24XX SoCs"
-- select ARCH_HAS_CPUFREQ
- select ARCH_REQUIRE_GPIOLIB
- select CLKDEV_LOOKUP
- select CLKSRC_SAMSUNG_PWM
-@@ -749,7 +737,6 @@ config ARCH_S3C24XX
-
- config ARCH_S3C64XX
- bool "Samsung S3C64XX"
-- select ARCH_HAS_CPUFREQ
- select ARCH_REQUIRE_GPIOLIB
- select ARM_AMBA
- select ARM_VIC
-@@ -810,7 +797,6 @@ config ARCH_S5PC100
-
- config ARCH_S5PV210
- bool "Samsung S5PV210/S5PC110"
-- select ARCH_HAS_CPUFREQ
- select ARCH_HAS_HOLES_MEMORYMODEL
- select ARCH_SPARSEMEM_ENABLE
- select CLKDEV_LOOKUP
-@@ -864,7 +850,6 @@ config ARCH_DAVINCI
- config ARCH_OMAP1
- bool "TI OMAP1"
- depends on MMU
-- select ARCH_HAS_CPUFREQ
- select ARCH_HAS_HOLES_MEMORYMODEL
- select ARCH_OMAP
- select ARCH_REQUIRE_GPIOLIB
-@@ -2171,9 +2156,7 @@ endmenu
-
- menu "CPU Power Management"
-
--if ARCH_HAS_CPUFREQ
- source "drivers/cpufreq/Kconfig"
--endif
-
- source "drivers/cpuidle/Kconfig"
-
---- a/arch/arm/mach-davinci/Kconfig
-+++ b/arch/arm/mach-davinci/Kconfig
-@@ -39,7 +39,6 @@ config ARCH_DAVINCI_DA830
- config ARCH_DAVINCI_DA850
- bool "DA850/OMAP-L138/AM18x based system"
- select ARCH_DAVINCI_DA8XX
-- select ARCH_HAS_CPUFREQ
- select CP_INTC
-
- config ARCH_DAVINCI_DA8XX
---- a/arch/arm/mach-highbank/Kconfig
-+++ b/arch/arm/mach-highbank/Kconfig
-@@ -1,7 +1,6 @@
- config ARCH_HIGHBANK
- bool "Calxeda ECX-1000/2000 (Highbank/Midway)" if ARCH_MULTI_V7
- select ARCH_DMA_ADDR_T_64BIT if ARM_LPAE
-- select ARCH_HAS_CPUFREQ
- select ARCH_HAS_HOLES_MEMORYMODEL
- select ARCH_HAS_OPP
- select ARCH_SUPPORTS_BIG_ENDIAN
---- a/arch/arm/mach-imx/Kconfig
-+++ b/arch/arm/mach-imx/Kconfig
-@@ -103,7 +103,6 @@ config SOC_IMX25
-
- config SOC_IMX27
- bool
-- select ARCH_HAS_CPUFREQ
- select ARCH_HAS_OPP
- select CPU_ARM926T
- select IMX_HAVE_IOMUX_V1
-@@ -129,7 +128,6 @@ config SOC_IMX35
-
- config SOC_IMX5
- bool
-- select ARCH_HAS_CPUFREQ
- select ARCH_HAS_OPP
- select ARCH_MXC_IOMUX_V3
- select CPU_V7
---- a/arch/arm/mach-omap2/Kconfig
-+++ b/arch/arm/mach-omap2/Kconfig
-@@ -93,7 +93,6 @@ config SOC_DRA7XX
- config ARCH_OMAP2PLUS
- bool
- select ARCH_HAS_BANDGAP
-- select ARCH_HAS_CPUFREQ
- select ARCH_HAS_HOLES_MEMORYMODEL
- select ARCH_OMAP
- select ARCH_REQUIRE_GPIOLIB
---- a/arch/arm/mach-shmobile/Kconfig
-+++ b/arch/arm/mach-shmobile/Kconfig
-@@ -85,7 +85,6 @@ config ARCH_R8A73A4
- select CPU_V7
- select SH_CLK_CPG
- select RENESAS_IRQC
-- select ARCH_HAS_CPUFREQ
- select ARCH_HAS_OPP
-
- config ARCH_R8A7740
-@@ -271,7 +270,6 @@ config MACH_KOELSCH
- config MACH_KZM9G
- bool "KZM-A9-GT board"
- depends on ARCH_SH73A0
-- select ARCH_HAS_CPUFREQ
- select ARCH_HAS_OPP
- select ARCH_REQUIRE_GPIOLIB
- select REGULATOR_FIXED_VOLTAGE if REGULATOR
---- a/arch/arm/mach-spear/Kconfig
-+++ b/arch/arm/mach-spear/Kconfig
-@@ -16,7 +16,6 @@ if PLAT_SPEAR
- config ARCH_SPEAR13XX
- bool "ST SPEAr13xx"
- depends on ARCH_MULTI_V7 || PLAT_SPEAR_SINGLE
-- select ARCH_HAS_CPUFREQ
- select ARM_GIC
- select CPU_V7
- select GPIO_SPEAR_SPICS
---- a/arch/arm/mach-tegra/Kconfig
-+++ b/arch/arm/mach-tegra/Kconfig
-@@ -1,6 +1,5 @@
- config ARCH_TEGRA
- bool "NVIDIA Tegra" if ARCH_MULTI_V7
-- select ARCH_HAS_CPUFREQ
- select ARCH_REQUIRE_GPIOLIB
- select ARCH_SUPPORTS_TRUSTED_FOUNDATIONS
- select ARM_GIC
---- a/arch/arm/mach-ux500/Kconfig
-+++ b/arch/arm/mach-ux500/Kconfig
-@@ -3,7 +3,6 @@ config ARCH_U8500
- depends on MMU
- select AB8500_CORE
- select ABX500_CORE
-- select ARCH_HAS_CPUFREQ
- select ARCH_REQUIRE_GPIOLIB
- select ARM_AMBA
- select ARM_ERRATA_754322
---- a/arch/arm/mach-vexpress/Kconfig
-+++ b/arch/arm/mach-vexpress/Kconfig
-@@ -67,7 +67,6 @@ config ARCH_VEXPRESS_DCSCB
-
- config ARCH_VEXPRESS_SPC
- bool "Versatile Express Serial Power Controller (SPC)"
-- select ARCH_HAS_CPUFREQ
- select ARCH_HAS_OPP
- select PM_OPP
- help
---- a/arch/arm/mach-vt8500/Kconfig
-+++ b/arch/arm/mach-vt8500/Kconfig
-@@ -1,6 +1,5 @@
- config ARCH_VT8500
- bool
-- select ARCH_HAS_CPUFREQ
- select ARCH_REQUIRE_GPIOLIB
- select CLKDEV_LOOKUP
- select CLKSRC_OF
diff --git a/target/linux/ipq806x/patches/0162-PM-OPP-Remove-ARCH_HAS_OPP.patch b/target/linux/ipq806x/patches/0162-PM-OPP-Remove-ARCH_HAS_OPP.patch
deleted file mode 100644
index d07b9e0..0000000
--- a/target/linux/ipq806x/patches/0162-PM-OPP-Remove-ARCH_HAS_OPP.patch
+++ /dev/null
@@ -1,115 +0,0 @@
-From 18e4542f7b02f586d46594977818cd6b24d9cbcb Mon Sep 17 00:00:00 2001
-From: Mark Brown <broonie@linaro.org>
-Date: Fri, 6 Jun 2014 11:36:56 +0100
-Subject: [PATCH 162/182] PM / OPP: Remove ARCH_HAS_OPP
-
-Since the OPP layer is a kernel library which has been converted to be
-directly selectable by its callers rather than user selectable and
-requiring architectures to enable it explicitly the ARCH_HAS_OPP symbol
-has become redundant and can be removed. Do so.
-
-Signed-off-by: Mark Brown <broonie@linaro.org>
-Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
----
- Documentation/power/opp.txt | 3 ---
- arch/arm/mach-exynos/Kconfig | 1 -
- arch/arm/mach-highbank/Kconfig | 1 -
- arch/arm/mach-omap2/Kconfig | 1 -
- arch/arm/mach-shmobile/Kconfig | 2 --
- arch/arm/mach-vexpress/Kconfig | 1 -
- drivers/devfreq/Kconfig | 1 -
- kernel/power/Kconfig | 3 ---
- 8 files changed, 13 deletions(-)
-
---- a/Documentation/power/opp.txt
-+++ b/Documentation/power/opp.txt
-@@ -52,9 +52,6 @@ Typical usage of the OPP library is as f
- SoC framework -> modifies on required cases certain OPPs -> OPP layer
- -> queries to search/retrieve information ->
-
--Architectures that provide a SoC framework for OPP should select ARCH_HAS_OPP
--to make the OPP layer available.
--
- OPP layer expects each domain to be represented by a unique device pointer. SoC
- framework registers a set of initial OPPs per device with the OPP layer. This
- list is expected to be an optimally small number typically around 5 per device.
---- a/arch/arm/mach-exynos/Kconfig
-+++ b/arch/arm/mach-exynos/Kconfig
-@@ -107,7 +107,6 @@ config SOC_EXYNOS5440
- depends on ARCH_EXYNOS5
- select ARCH_DMA_ADDR_T_64BIT if ARM_LPAE
- select ARCH_HAS_BANDGAP
-- select ARCH_HAS_OPP
- select HAVE_ARM_ARCH_TIMER
- select AUTO_ZRELADDR
- select MIGHT_HAVE_PCI
---- a/arch/arm/mach-highbank/Kconfig
-+++ b/arch/arm/mach-highbank/Kconfig
-@@ -2,7 +2,6 @@ config ARCH_HIGHBANK
- bool "Calxeda ECX-1000/2000 (Highbank/Midway)" if ARCH_MULTI_V7
- select ARCH_DMA_ADDR_T_64BIT if ARM_LPAE
- select ARCH_HAS_HOLES_MEMORYMODEL
-- select ARCH_HAS_OPP
- select ARCH_SUPPORTS_BIG_ENDIAN
- select ARCH_WANT_OPTIONAL_GPIOLIB
- select ARM_AMBA
---- a/arch/arm/mach-omap2/Kconfig
-+++ b/arch/arm/mach-omap2/Kconfig
-@@ -13,7 +13,6 @@ config ARCH_OMAP3
- bool "TI OMAP3"
- depends on ARCH_MULTI_V7
- select ARCH_OMAP2PLUS
-- select ARCH_HAS_OPP
- select ARM_CPU_SUSPEND if PM
- select CPU_V7
- select MULTI_IRQ_HANDLER
---- a/arch/arm/mach-shmobile/Kconfig
-+++ b/arch/arm/mach-shmobile/Kconfig
-@@ -85,7 +85,6 @@ config ARCH_R8A73A4
- select CPU_V7
- select SH_CLK_CPG
- select RENESAS_IRQC
-- select ARCH_HAS_OPP
-
- config ARCH_R8A7740
- bool "R-Mobile A1 (R8A77400)"
-@@ -270,7 +269,6 @@ config MACH_KOELSCH
- config MACH_KZM9G
- bool "KZM-A9-GT board"
- depends on ARCH_SH73A0
-- select ARCH_HAS_OPP
- select ARCH_REQUIRE_GPIOLIB
- select REGULATOR_FIXED_VOLTAGE if REGULATOR
- select SND_SOC_AK4642 if SND_SIMPLE_CARD
---- a/arch/arm/mach-vexpress/Kconfig
-+++ b/arch/arm/mach-vexpress/Kconfig
-@@ -67,7 +67,6 @@ config ARCH_VEXPRESS_DCSCB
-
- config ARCH_VEXPRESS_SPC
- bool "Versatile Express Serial Power Controller (SPC)"
-- select ARCH_HAS_OPP
- select PM_OPP
- help
- The TC2 (A15x2 A7x3) versatile express core tile integrates a logic
---- a/drivers/devfreq/Kconfig
-+++ b/drivers/devfreq/Kconfig
-@@ -68,7 +68,6 @@ comment "DEVFREQ Drivers"
- config ARM_EXYNOS4_BUS_DEVFREQ
- bool "ARM Exynos4210/4212/4412 Memory Bus DEVFREQ Driver"
- depends on (CPU_EXYNOS4210 || SOC_EXYNOS4212 || SOC_EXYNOS4412) && !ARCH_MULTIPLATFORM
-- select ARCH_HAS_OPP
- select DEVFREQ_GOV_SIMPLE_ONDEMAND
- help
- This adds the DEVFREQ driver for Exynos4210 memory bus (vdd_int)
---- a/kernel/power/Kconfig
-+++ b/kernel/power/Kconfig
-@@ -253,9 +253,6 @@ config APM_EMULATION
- anything, try disabling/enabling this option (or disabling/enabling
- APM in your BIOS).
-
--config ARCH_HAS_OPP
-- bool
--
- config PM_OPP
- bool "Operating Performance Point (OPP) Layer library"
- depends on ARCH_HAS_OPP
diff --git a/target/linux/ipq806x/patches/0163-clk-return-probe-defer-when-DT-clock-not-yet-ready.patch b/target/linux/ipq806x/patches/0163-clk-return-probe-defer-when-DT-clock-not-yet-ready.patch
deleted file mode 100644
index 76956d5..0000000
--- a/target/linux/ipq806x/patches/0163-clk-return-probe-defer-when-DT-clock-not-yet-ready.patch
+++ /dev/null
@@ -1,42 +0,0 @@
-From 1ce8667062bc7b8813adf6103ad2374d9dd52fb0 Mon Sep 17 00:00:00 2001
-From: Jean-Francois Moine <moinejf@free.fr>
-Date: Mon, 25 Nov 2013 19:47:04 +0100
-Subject: [PATCH 163/182] clk: return probe defer when DT clock not yet ready
-
-At probe time, a clock device may not be ready when some other device
-wants to use it.
-
-This patch lets the functions clk_get/devm_clk_get return a probe defer
-when the clock is defined in the DT but not yet available.
-
-Signed-off-by: Jean-Francois Moine <moinejf@free.fr>
-Reviewed-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
-Tested-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
-Signed-off-by: Mike Turquette <mturquette@linaro.org>
----
- drivers/clk/clk.c | 2 +-
- drivers/clk/clkdev.c | 2 ++
- 2 files changed, 3 insertions(+), 1 deletion(-)
-
---- a/drivers/clk/clk.c
-+++ b/drivers/clk/clk.c
-@@ -2507,7 +2507,7 @@ EXPORT_SYMBOL_GPL(of_clk_del_provider);
- struct clk *__of_clk_get_from_provider(struct of_phandle_args *clkspec)
- {
- struct of_clk_provider *provider;
-- struct clk *clk = ERR_PTR(-ENOENT);
-+ struct clk *clk = ERR_PTR(-EPROBE_DEFER);
-
- /* Check if we have such a provider in our array */
- list_for_each_entry(provider, &of_clk_providers, link) {
---- a/drivers/clk/clkdev.c
-+++ b/drivers/clk/clkdev.c
-@@ -167,6 +167,8 @@ struct clk *clk_get(struct device *dev,
- clk = of_clk_get_by_name(dev->of_node, con_id);
- if (!IS_ERR(clk))
- return clk;
-+ if (PTR_ERR(clk) == -EPROBE_DEFER)
-+ return clk;
- }
-
- return clk_get_sys(dev_id, con_id);
diff --git a/target/linux/ipq806x/patches/0164-ARM-Add-Krait-L2-register-accessor-functions.patch b/target/linux/ipq806x/patches/0164-ARM-Add-Krait-L2-register-accessor-functions.patch
deleted file mode 100644
index 1eb450e..0000000
--- a/target/linux/ipq806x/patches/0164-ARM-Add-Krait-L2-register-accessor-functions.patch
+++ /dev/null
@@ -1,133 +0,0 @@
-From d8bf5e13683e027c52476b89b874d50e5281c130 Mon Sep 17 00:00:00 2001
-From: Stephen Boyd <sboyd@codeaurora.org>
-Date: Fri, 18 Oct 2013 16:45:05 -0700
-Subject: [PATCH 164/182] ARM: Add Krait L2 register accessor functions
-
-Krait CPUs have a handful of L2 cache controller registers that
-live behind a cp15 based indirection register. First you program
-the indirection register (l2cpselr) to point the L2 'window'
-register (l2cpdr) at what you want to read/write. Then you
-read/write the 'window' register to do what you want. The
-l2cpselr register is not banked per-cpu so we must lock around
-accesses to it to prevent other CPUs from re-pointing l2cpdr
-underneath us.
-
-Cc: Mark Rutland <mark.rutland@arm.com>
-Cc: Russell King <linux@arm.linux.org.uk>
-Cc: Courtney Cavin <courtney.cavin@sonymobile.com>
-Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
----
- arch/arm/common/Kconfig | 3 ++
- arch/arm/common/Makefile | 1 +
- arch/arm/common/krait-l2-accessors.c | 58 +++++++++++++++++++++++++++++
- arch/arm/include/asm/krait-l2-accessors.h | 20 ++++++++++
- 4 files changed, 82 insertions(+)
- create mode 100644 arch/arm/common/krait-l2-accessors.c
- create mode 100644 arch/arm/include/asm/krait-l2-accessors.h
-
---- a/arch/arm/common/Kconfig
-+++ b/arch/arm/common/Kconfig
-@@ -9,6 +9,9 @@ config DMABOUNCE
- bool
- select ZONE_DMA
-
-+config KRAIT_L2_ACCESSORS
-+ bool
-+
- config SHARP_LOCOMO
- bool
-
---- a/arch/arm/common/Makefile
-+++ b/arch/arm/common/Makefile
-@@ -7,6 +7,7 @@ obj-y += firmware.o
- obj-$(CONFIG_ICST) += icst.o
- obj-$(CONFIG_SA1111) += sa1111.o
- obj-$(CONFIG_DMABOUNCE) += dmabounce.o
-+obj-$(CONFIG_KRAIT_L2_ACCESSORS) += krait-l2-accessors.o
- obj-$(CONFIG_SHARP_LOCOMO) += locomo.o
- obj-$(CONFIG_SHARP_PARAM) += sharpsl_param.o
- obj-$(CONFIG_SHARP_SCOOP) += scoop.o
---- /dev/null
-+++ b/arch/arm/common/krait-l2-accessors.c
-@@ -0,0 +1,58 @@
-+/*
-+ * Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 and
-+ * only version 2 as published by the Free Software Foundation.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ * GNU General Public License for more details.
-+ */
-+
-+#include <linux/spinlock.h>
-+#include <linux/export.h>
-+
-+#include <asm/barrier.h>
-+#include <asm/krait-l2-accessors.h>
-+
-+static DEFINE_RAW_SPINLOCK(krait_l2_lock);
-+
-+void krait_set_l2_indirect_reg(u32 addr, u32 val)
-+{
-+ unsigned long flags;
-+
-+ raw_spin_lock_irqsave(&krait_l2_lock, flags);
-+ /*
-+ * Select the L2 window by poking l2cpselr, then write to the window
-+ * via l2cpdr.
-+ */
-+ asm volatile ("mcr p15, 3, %0, c15, c0, 6 @ l2cpselr" : : "r" (addr));
-+ isb();
-+ asm volatile ("mcr p15, 3, %0, c15, c0, 7 @ l2cpdr" : : "r" (val));
-+ isb();
-+
-+ raw_spin_unlock_irqrestore(&krait_l2_lock, flags);
-+}
-+EXPORT_SYMBOL(krait_set_l2_indirect_reg);
-+
-+u32 krait_get_l2_indirect_reg(u32 addr)
-+{
-+ u32 val;
-+ unsigned long flags;
-+
-+ raw_spin_lock_irqsave(&krait_l2_lock, flags);
-+ /*
-+ * Select the L2 window by poking l2cpselr, then read from the window
-+ * via l2cpdr.
-+ */
-+ asm volatile ("mcr p15, 3, %0, c15, c0, 6 @ l2cpselr" : : "r" (addr));
-+ isb();
-+ asm volatile ("mrc p15, 3, %0, c15, c0, 7 @ l2cpdr" : "=r" (val));
-+
-+ raw_spin_unlock_irqrestore(&krait_l2_lock, flags);
-+
-+ return val;
-+}
-+EXPORT_SYMBOL(krait_get_l2_indirect_reg);
---- /dev/null
-+++ b/arch/arm/include/asm/krait-l2-accessors.h
-@@ -0,0 +1,20 @@
-+/*
-+ * Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 and
-+ * only version 2 as published by the Free Software Foundation.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ * GNU General Public License for more details.
-+ */
-+
-+#ifndef __ASMARM_KRAIT_L2_ACCESSORS_H
-+#define __ASMARM_KRAIT_L2_ACCESSORS_H
-+
-+extern void krait_set_l2_indirect_reg(u32 addr, u32 val);
-+extern u32 krait_get_l2_indirect_reg(u32 addr);
-+
-+#endif
diff --git a/target/linux/ipq806x/patches/0165-clk-qcom-Add-support-for-muxes-dividers-and-mux-divi.patch b/target/linux/ipq806x/patches/0165-clk-qcom-Add-support-for-muxes-dividers-and-mux-divi.patch
deleted file mode 100644
index fa7b4e9..0000000
--- a/target/linux/ipq806x/patches/0165-clk-qcom-Add-support-for-muxes-dividers-and-mux-divi.patch
+++ /dev/null
@@ -1,652 +0,0 @@
-From 151d7e91baaa4016ba687b80e8f7ccead62d6c72 Mon Sep 17 00:00:00 2001
-From: Stephen Boyd <sboyd@codeaurora.org>
-Date: Tue, 25 Mar 2014 13:37:55 -0700
-Subject: [PATCH 165/182] clk: qcom: Add support for muxes, dividers, and mux
- dividers
-
-The Krait CPU clocks are made up of muxes and dividers with a
-handful of sources. Add a set of clk_ops that allow us to
-configure these clocks so we can support CPU frequency scaling on
-Krait CPUs.
-
-Based on code originally written by Saravana Kannan.
-
-Cc: Saravana Kannan <skannan@codeaurora.org>
-Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
----
- drivers/clk/qcom/Makefile | 1 +
- drivers/clk/qcom/clk-generic.c | 405 +++++++++++++++++++++++++++++++++++
- include/linux/clk/msm-clk-generic.h | 208 ++++++++++++++++++
- 3 files changed, 614 insertions(+)
- create mode 100644 drivers/clk/qcom/clk-generic.c
- create mode 100644 include/linux/clk/msm-clk-generic.h
-
---- a/drivers/clk/qcom/Makefile
-+++ b/drivers/clk/qcom/Makefile
-@@ -6,6 +6,7 @@ clk-qcom-y += clk-pll.o
- clk-qcom-y += clk-rcg.o
- clk-qcom-y += clk-rcg2.o
- clk-qcom-y += clk-branch.o
-+clk-qcom-y += clk-generic.o
- clk-qcom-y += reset.o
-
- obj-$(CONFIG_IPQ_GCC_806X) += gcc-ipq806x.o
---- /dev/null
-+++ b/drivers/clk/qcom/clk-generic.c
-@@ -0,0 +1,405 @@
-+/*
-+ * Copyright (c) 2014, The Linux Foundation. All rights reserved.
-+ *
-+ * This software is licensed under the terms of the GNU General Public
-+ * License version 2, as published by the Free Software Foundation, and
-+ * may be copied, distributed, and modified under those terms.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ * GNU General Public License for more details.
-+ */
-+
-+#include <linux/kernel.h>
-+#include <linux/export.h>
-+#include <linux/bug.h>
-+#include <linux/err.h>
-+#include <linux/clk-provider.h>
-+#include <linux/clk/msm-clk-generic.h>
-+
-+
-+/* ==================== Mux clock ==================== */
-+
-+static int mux_set_parent(struct clk_hw *hw, u8 sel)
-+{
-+ struct mux_clk *mux = to_mux_clk(hw);
-+
-+ if (mux->parent_map)
-+ sel = mux->parent_map[sel];
-+
-+ return mux->ops->set_mux_sel(mux, sel);
-+}
-+
-+static u8 mux_get_parent(struct clk_hw *hw)
-+{
-+ struct mux_clk *mux = to_mux_clk(hw);
-+ int num_parents = __clk_get_num_parents(hw->clk);
-+ int i;
-+ u8 sel;
-+
-+ sel = mux->ops->get_mux_sel(mux);
-+ if (mux->parent_map) {
-+ for (i = 0; i < num_parents; i++)
-+ if (sel == mux->parent_map[i])
-+ return i;
-+ WARN(1, "Can't find parent\n");
-+ return -EINVAL;
-+ }
-+
-+ return sel;
-+}
-+
-+static int mux_enable(struct clk_hw *hw)
-+{
-+ struct mux_clk *mux = to_mux_clk(hw);
-+ if (mux->ops->enable)
-+ return mux->ops->enable(mux);
-+ return 0;
-+}
-+
-+static void mux_disable(struct clk_hw *hw)
-+{
-+ struct mux_clk *mux = to_mux_clk(hw);
-+ if (mux->ops->disable)
-+ return mux->ops->disable(mux);
-+}
-+
-+static struct clk *mux_get_safe_parent(struct clk_hw *hw)
-+{
-+ int i;
-+ struct mux_clk *mux = to_mux_clk(hw);
-+ int num_parents = __clk_get_num_parents(hw->clk);
-+
-+ if (!mux->has_safe_parent)
-+ return NULL;
-+
-+ i = mux->safe_sel;
-+ if (mux->parent_map)
-+ for (i = 0; i < num_parents; i++)
-+ if (mux->safe_sel == mux->parent_map[i])
-+ break;
-+
-+ return clk_get_parent_by_index(hw->clk, i);
-+}
-+
-+const struct clk_ops clk_ops_gen_mux = {
-+ .enable = mux_enable,
-+ .disable = mux_disable,
-+ .set_parent = mux_set_parent,
-+ .get_parent = mux_get_parent,
-+ .determine_rate = __clk_mux_determine_rate,
-+ .get_safe_parent = mux_get_safe_parent,
-+};
-+EXPORT_SYMBOL_GPL(clk_ops_gen_mux);
-+
-+/* ==================== Divider clock ==================== */
-+
-+static long __div_round_rate(struct div_data *data, unsigned long rate,
-+ struct clk *parent, unsigned int *best_div, unsigned long *best_prate,
-+ bool set_parent)
-+{
-+ unsigned int div, min_div, max_div, _best_div = 1;
-+ unsigned long prate, _best_prate = 0, rrate = 0, req_prate, actual_rate;
-+ unsigned int numer;
-+
-+ rate = max(rate, 1UL);
-+
-+ min_div = max(data->min_div, 1U);
-+ max_div = min(data->max_div, (unsigned int) (ULONG_MAX / rate));
-+
-+ /*
-+ * div values are doubled for half dividers.
-+ * Adjust for that by picking a numer of 2.
-+ */
-+ numer = data->is_half_divider ? 2 : 1;
-+
-+ if (!set_parent) {
-+ prate = *best_prate * numer;
-+ div = DIV_ROUND_UP(prate, rate);
-+ div = clamp(1U, div, max_div);
-+ if (best_div)
-+ *best_div = div;
-+ return mult_frac(*best_prate, numer, div);
-+ }
-+
-+ for (div = min_div; div <= max_div; div++) {
-+ req_prate = mult_frac(rate, div, numer);
-+ prate = __clk_round_rate(parent, req_prate);
-+ if (IS_ERR_VALUE(prate))
-+ break;
-+
-+ actual_rate = mult_frac(prate, numer, div);
-+ if (is_better_rate(rate, rrate, actual_rate)) {
-+ rrate = actual_rate;
-+ _best_div = div;
-+ _best_prate = prate;
-+ }
-+
-+ /*
-+ * Trying higher dividers is only going to ask the parent for
-+ * a higher rate. If it can't even output a rate higher than
-+ * the one we request for this divider, the parent is not
-+ * going to be able to output an even higher rate required
-+ * for a higher divider. So, stop trying higher dividers.
-+ */
-+ if (actual_rate < rate)
-+ break;
-+
-+ if (rrate <= rate)
-+ break;
-+ }
-+
-+ if (!rrate)
-+ return -EINVAL;
-+ if (best_div)
-+ *best_div = _best_div;
-+ if (best_prate)
-+ *best_prate = _best_prate;
-+
-+ return rrate;
-+}
-+
-+static long div_round_rate(struct clk_hw *hw, unsigned long rate,
-+ unsigned long *parent_rate)
-+{
-+ struct div_clk *d = to_div_clk(hw);
-+ bool set_parent = __clk_get_flags(hw->clk) & CLK_SET_RATE_PARENT;
-+
-+ return __div_round_rate(&d->data, rate, __clk_get_parent(hw->clk),
-+ NULL, parent_rate, set_parent);
-+}
-+
-+static int div_set_rate(struct clk_hw *hw, unsigned long rate, unsigned long
-+ parent_rate)
-+{
-+ struct div_clk *d = to_div_clk(hw);
-+ int div, rc = 0;
-+ struct div_data *data = &d->data;
-+
-+ div = parent_rate / rate;
-+ if (div != data->div)
-+ rc = d->ops->set_div(d, div);
-+ data->div = div;
-+
-+ return rc;
-+}
-+
-+static int div_enable(struct clk_hw *hw)
-+{
-+ struct div_clk *d = to_div_clk(hw);
-+ if (d->ops && d->ops->enable)
-+ return d->ops->enable(d);
-+ return 0;
-+}
-+
-+static void div_disable(struct clk_hw *hw)
-+{
-+ struct div_clk *d = to_div_clk(hw);
-+ if (d->ops && d->ops->disable)
-+ return d->ops->disable(d);
-+}
-+
-+static unsigned long div_recalc_rate(struct clk_hw *hw, unsigned long prate)
-+{
-+ struct div_clk *d = to_div_clk(hw);
-+ unsigned int div = d->data.div;
-+
-+ if (d->ops && d->ops->get_div)
-+ div = max(d->ops->get_div(d), 1);
-+ div = max(div, 1U);
-+
-+ if (!d->ops || !d->ops->set_div)
-+ d->data.min_div = d->data.max_div = div;
-+ d->data.div = div;
-+
-+ return prate / div;
-+}
-+
-+const struct clk_ops clk_ops_div = {
-+ .enable = div_enable,
-+ .disable = div_disable,
-+ .round_rate = div_round_rate,
-+ .set_rate = div_set_rate,
-+ .recalc_rate = div_recalc_rate,
-+};
-+EXPORT_SYMBOL_GPL(clk_ops_div);
-+
-+/* ==================== Mux_div clock ==================== */
-+
-+static int mux_div_clk_enable(struct clk_hw *hw)
-+{
-+ struct mux_div_clk *md = to_mux_div_clk(hw);
-+
-+ if (md->ops->enable)
-+ return md->ops->enable(md);
-+ return 0;
-+}
-+
-+static void mux_div_clk_disable(struct clk_hw *hw)
-+{
-+ struct mux_div_clk *md = to_mux_div_clk(hw);
-+
-+ if (md->ops->disable)
-+ return md->ops->disable(md);
-+}
-+
-+static long __mux_div_round_rate(struct clk_hw *hw, unsigned long rate,
-+ struct clk **best_parent, int *best_div, unsigned long *best_prate)
-+{
-+ struct mux_div_clk *md = to_mux_div_clk(hw);
-+ unsigned int i;
-+ unsigned long rrate, best = 0, _best_div = 0, _best_prate = 0;
-+ struct clk *_best_parent = 0;
-+ int num_parents = __clk_get_num_parents(hw->clk);
-+ bool set_parent = __clk_get_flags(hw->clk) & CLK_SET_RATE_PARENT;
-+
-+ for (i = 0; i < num_parents; i++) {
-+ int div;
-+ unsigned long prate;
-+ struct clk *p = clk_get_parent_by_index(hw->clk, i);
-+
-+ rrate = __div_round_rate(&md->data, rate, p, &div, &prate,
-+ set_parent);
-+
-+ if (is_better_rate(rate, best, rrate)) {
-+ best = rrate;
-+ _best_div = div;
-+ _best_prate = prate;
-+ _best_parent = p;
-+ }
-+
-+ if (rate <= rrate)
-+ break;
-+ }
-+
-+ if (best_div)
-+ *best_div = _best_div;
-+ if (best_prate)
-+ *best_prate = _best_prate;
-+ if (best_parent)
-+ *best_parent = _best_parent;
-+
-+ if (best)
-+ return best;
-+ return -EINVAL;
-+}
-+
-+static long mux_div_clk_round_rate(struct clk_hw *hw, unsigned long rate,
-+ unsigned long *parent_rate)
-+{
-+ return __mux_div_round_rate(hw, rate, NULL, NULL, parent_rate);
-+}
-+
-+/* requires enable lock to be held */
-+static int __set_src_div(struct mux_div_clk *md, u8 src_sel, u32 div)
-+{
-+ int rc;
-+
-+ rc = md->ops->set_src_div(md, src_sel, div);
-+ if (!rc) {
-+ md->data.div = div;
-+ md->src_sel = src_sel;
-+ }
-+
-+ return rc;
-+}
-+
-+/* Must be called after handoff to ensure parent clock rates are initialized */
-+static int safe_parent_init_once(struct clk_hw *hw)
-+{
-+ unsigned long rrate;
-+ u32 best_div;
-+ struct clk *best_parent;
-+ struct mux_div_clk *md = to_mux_div_clk(hw);
-+
-+ if (IS_ERR(md->safe_parent))
-+ return -EINVAL;
-+ if (!md->safe_freq || md->safe_parent)
-+ return 0;
-+
-+ rrate = __mux_div_round_rate(hw, md->safe_freq, &best_parent,
-+ &best_div, NULL);
-+
-+ if (rrate == md->safe_freq) {
-+ md->safe_div = best_div;
-+ md->safe_parent = best_parent;
-+ } else {
-+ md->safe_parent = ERR_PTR(-EINVAL);
-+ return -EINVAL;
-+ }
-+ return 0;
-+}
-+
-+static int
-+__mux_div_clk_set_rate_and_parent(struct clk_hw *hw, u8 index, u32 div)
-+{
-+ struct mux_div_clk *md = to_mux_div_clk(hw);
-+ int rc;
-+
-+ rc = safe_parent_init_once(hw);
-+ if (rc)
-+ return rc;
-+
-+ return __set_src_div(md, index, div);
-+}
-+
-+static int mux_div_clk_set_rate_and_parent(struct clk_hw *hw,
-+ unsigned long rate, unsigned long parent_rate, u8 index)
-+{
-+ return __mux_div_clk_set_rate_and_parent(hw, index, parent_rate / rate);
-+}
-+
-+static int mux_div_clk_set_rate(struct clk_hw *hw,
-+ unsigned long rate, unsigned long parent_rate)
-+{
-+ struct mux_div_clk *md = to_mux_div_clk(hw);
-+ return __mux_div_clk_set_rate_and_parent(hw, md->src_sel,
-+ parent_rate / rate);
-+}
-+
-+static int mux_div_clk_set_parent(struct clk_hw *hw, u8 index)
-+{
-+ struct mux_div_clk *md = to_mux_div_clk(hw);
-+ return __mux_div_clk_set_rate_and_parent(hw, md->parent_map[index],
-+ md->data.div);
-+}
-+
-+static u8 mux_div_clk_get_parent(struct clk_hw *hw)
-+{
-+ struct mux_div_clk *md = to_mux_div_clk(hw);
-+ int num_parents = __clk_get_num_parents(hw->clk);
-+ u32 i, div, sel;
-+
-+ md->ops->get_src_div(md, &sel, &div);
-+ md->src_sel = sel;
-+
-+ for (i = 0; i < num_parents; i++)
-+ if (sel == md->parent_map[i])
-+ return i;
-+ WARN(1, "Can't find parent\n");
-+ return -EINVAL;
-+}
-+
-+static unsigned long
-+mux_div_clk_recalc_rate(struct clk_hw *hw, unsigned long prate)
-+{
-+ struct mux_div_clk *md = to_mux_div_clk(hw);
-+ u32 div, sel;
-+
-+ md->ops->get_src_div(md, &sel, &div);
-+
-+ return prate / div;
-+}
-+
-+const struct clk_ops clk_ops_mux_div_clk = {
-+ .enable = mux_div_clk_enable,
-+ .disable = mux_div_clk_disable,
-+ .set_rate_and_parent = mux_div_clk_set_rate_and_parent,
-+ .set_rate = mux_div_clk_set_rate,
-+ .set_parent = mux_div_clk_set_parent,
-+ .round_rate = mux_div_clk_round_rate,
-+ .get_parent = mux_div_clk_get_parent,
-+ .recalc_rate = mux_div_clk_recalc_rate,
-+};
-+EXPORT_SYMBOL_GPL(clk_ops_mux_div_clk);
---- /dev/null
-+++ b/include/linux/clk/msm-clk-generic.h
-@@ -0,0 +1,208 @@
-+/*
-+ * Copyright (c) 2014, The Linux Foundation. All rights reserved.
-+ *
-+ * This software is licensed under the terms of the GNU General Public
-+ * License version 2, as published by the Free Software Foundation, and
-+ * may be copied, distributed, and modified under those terms.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ * GNU General Public License for more details.
-+ */
-+
-+#ifndef __QCOM_CLK_GENERIC_H__
-+#define __QCOM_CLK_GENERIC_H__
-+
-+#include <linux/err.h>
-+#include <linux/clk-provider.h>
-+
-+static inline bool is_better_rate(unsigned long req, unsigned long best,
-+ unsigned long new)
-+{
-+ if (IS_ERR_VALUE(new))
-+ return false;
-+
-+ return (req <= new && new < best) || (best < req && best < new);
-+}
-+
-+/* ==================== Mux clock ==================== */
-+
-+struct mux_clk;
-+
-+struct clk_mux_ops {
-+ int (*set_mux_sel)(struct mux_clk *clk, int sel);
-+ int (*get_mux_sel)(struct mux_clk *clk);
-+
-+ /* Optional */
-+ bool (*is_enabled)(struct mux_clk *clk);
-+ int (*enable)(struct mux_clk *clk);
-+ void (*disable)(struct mux_clk *clk);
-+};
-+
-+struct mux_clk {
-+ /* Parents in decreasing order of preference for obtaining rates. */
-+ u8 *parent_map;
-+ bool has_safe_parent;
-+ u8 safe_sel;
-+ const struct clk_mux_ops *ops;
-+
-+ /* Fields not used by helper function. */
-+ void __iomem *base;
-+ u32 offset;
-+ u32 en_offset;
-+ int en_reg;
-+ u32 mask;
-+ u32 shift;
-+ u32 en_mask;
-+ void *priv;
-+
-+ struct clk_hw hw;
-+};
-+
-+static inline struct mux_clk *to_mux_clk(struct clk_hw *hw)
-+{
-+ return container_of(hw, struct mux_clk, hw);
-+}
-+
-+extern const struct clk_ops clk_ops_gen_mux;
-+
-+/* ==================== Divider clock ==================== */
-+
-+struct div_clk;
-+
-+struct clk_div_ops {
-+ int (*set_div)(struct div_clk *clk, int div);
-+ int (*get_div)(struct div_clk *clk);
-+ bool (*is_enabled)(struct div_clk *clk);
-+ int (*enable)(struct div_clk *clk);
-+ void (*disable)(struct div_clk *clk);
-+};
-+
-+struct div_data {
-+ unsigned int div;
-+ unsigned int min_div;
-+ unsigned int max_div;
-+ /*
-+ * Indicate whether this divider clock supports half-interger divider.
-+ * If it is, all the min_div and max_div have been doubled. It means
-+ * they are 2*N.
-+ */
-+ bool is_half_divider;
-+};
-+
-+struct div_clk {
-+ struct div_data data;
-+
-+ /* Optional */
-+ const struct clk_div_ops *ops;
-+
-+ /* Fields not used by helper function. */
-+ void __iomem *base;
-+ u32 offset;
-+ u32 mask;
-+ u32 shift;
-+ u32 en_mask;
-+ void *priv;
-+ struct clk_hw hw;
-+};
-+
-+static inline struct div_clk *to_div_clk(struct clk_hw *hw)
-+{
-+ return container_of(hw, struct div_clk, hw);
-+}
-+
-+extern const struct clk_ops clk_ops_div;
-+
-+#define DEFINE_FIXED_DIV_CLK(clk_name, _div, _parent) \
-+static struct div_clk clk_name = { \
-+ .data = { \
-+ .max_div = _div, \
-+ .min_div = _div, \
-+ .div = _div, \
-+ }, \
-+ .hw.init = &(struct clk_init_data){ \
-+ .parent_names = (const char *[]){ _parent }, \
-+ .num_parents = 1, \
-+ .name = #clk_name, \
-+ .ops = &clk_ops_div, \
-+ .flags = CLK_SET_RATE_PARENT, \
-+ } \
-+}
-+
-+/* ==================== Mux Div clock ==================== */
-+
-+struct mux_div_clk;
-+
-+/*
-+ * struct mux_div_ops
-+ * the enable and disable ops are optional.
-+ */
-+
-+struct mux_div_ops {
-+ int (*set_src_div)(struct mux_div_clk *, u32 src_sel, u32 div);
-+ void (*get_src_div)(struct mux_div_clk *, u32 *src_sel, u32 *div);
-+ int (*enable)(struct mux_div_clk *);
-+ void (*disable)(struct mux_div_clk *);
-+ bool (*is_enabled)(struct mux_div_clk *);
-+};
-+
-+/*
-+ * struct mux_div_clk - combined mux/divider clock
-+ * @priv
-+ parameters needed by ops
-+ * @safe_freq
-+ when switching rates from A to B, the mux div clock will
-+ instead switch from A -> safe_freq -> B. This allows the
-+ mux_div clock to change rates while enabled, even if this
-+ behavior is not supported by the parent clocks.
-+
-+ If changing the rate of parent A also causes the rate of
-+ parent B to change, then safe_freq must be defined.
-+
-+ safe_freq is expected to have a source clock which is always
-+ on and runs at only one rate.
-+ * @parents
-+ list of parents and mux indicies
-+ * @ops
-+ function pointers for hw specific operations
-+ * @src_sel
-+ the mux index which will be used if the clock is enabled.
-+ */
-+
-+struct mux_div_clk {
-+ /* Required parameters */
-+ const struct mux_div_ops *ops;
-+ struct div_data data;
-+ u8 *parent_map;
-+
-+ struct clk_hw hw;
-+
-+ /* Internal */
-+ u32 src_sel;
-+
-+ /* Optional parameters */
-+ void *priv;
-+ void __iomem *base;
-+ u32 div_mask;
-+ u32 div_offset;
-+ u32 div_shift;
-+ u32 src_mask;
-+ u32 src_offset;
-+ u32 src_shift;
-+ u32 en_mask;
-+ u32 en_offset;
-+
-+ u32 safe_div;
-+ struct clk *safe_parent;
-+ unsigned long safe_freq;
-+};
-+
-+static inline struct mux_div_clk *to_mux_div_clk(struct clk_hw *hw)
-+{
-+ return container_of(hw, struct mux_div_clk, hw);
-+}
-+
-+extern const struct clk_ops clk_ops_mux_div_clk;
-+
-+#endif
diff --git a/target/linux/ipq806x/patches/0166-clk-qcom-Add-support-for-High-Frequency-PLLs-HFPLLs.patch b/target/linux/ipq806x/patches/0166-clk-qcom-Add-support-for-High-Frequency-PLLs-HFPLLs.patch
deleted file mode 100644
index 037c6c4..0000000
--- a/target/linux/ipq806x/patches/0166-clk-qcom-Add-support-for-High-Frequency-PLLs-HFPLLs.patch
+++ /dev/null
@@ -1,348 +0,0 @@
-From 8a51ac2a4e36505e1ff82b0e49fd8b2edd0b7695 Mon Sep 17 00:00:00 2001
-From: Stephen Boyd <sboyd@codeaurora.org>
-Date: Wed, 18 Jun 2014 14:15:58 -0700
-Subject: [PATCH 166/182] clk: qcom: Add support for High-Frequency PLLs
- (HFPLLs)
-
-HFPLLs are the main frequency source for Krait CPU clocks. Add
-support for changing the rate of these PLLs.
-
-Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
----
- drivers/clk/qcom/Makefile | 1 +
- drivers/clk/qcom/clk-hfpll.c | 260 ++++++++++++++++++++++++++++++++++++++++++
- drivers/clk/qcom/clk-hfpll.h | 54 +++++++++
- 3 files changed, 315 insertions(+)
- create mode 100644 drivers/clk/qcom/clk-hfpll.c
- create mode 100644 drivers/clk/qcom/clk-hfpll.h
-
---- a/drivers/clk/qcom/Makefile
-+++ b/drivers/clk/qcom/Makefile
-@@ -7,6 +7,7 @@ clk-qcom-y += clk-rcg.o
- clk-qcom-y += clk-rcg2.o
- clk-qcom-y += clk-branch.o
- clk-qcom-y += clk-generic.o
-+clk-qcom-y += clk-hfpll.o
- clk-qcom-y += reset.o
-
- obj-$(CONFIG_IPQ_GCC_806X) += gcc-ipq806x.o
---- /dev/null
-+++ b/drivers/clk/qcom/clk-hfpll.c
-@@ -0,0 +1,260 @@
-+/*
-+ * Copyright (c) 2013-2014, The Linux Foundation. All rights reserved.
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 and
-+ * only version 2 as published by the Free Software Foundation.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ * GNU General Public License for more details.
-+ */
-+#include <linux/kernel.h>
-+#include <linux/module.h>
-+#include <linux/init.h>
-+#include <linux/regmap.h>
-+#include <linux/delay.h>
-+#include <linux/err.h>
-+#include <linux/clk-provider.h>
-+#include <linux/spinlock.h>
-+
-+#include "clk-regmap.h"
-+#include "clk-hfpll.h"
-+
-+#define PLL_OUTCTRL BIT(0)
-+#define PLL_BYPASSNL BIT(1)
-+#define PLL_RESET_N BIT(2)
-+
-+/* Initialize a HFPLL at a given rate and enable it. */
-+static void __clk_hfpll_init_once(struct clk_hw *hw)
-+{
-+ struct clk_hfpll *h = to_clk_hfpll(hw);
-+ struct hfpll_data const *hd = h->d;
-+ struct regmap *regmap = h->clkr.regmap;
-+
-+ if (likely(h->init_done))
-+ return;
-+
-+ /* Configure PLL parameters for integer mode. */
-+ if (hd->config_val)
-+ regmap_write(regmap, hd->config_reg, hd->config_val);
-+ regmap_write(regmap, hd->m_reg, 0);
-+ regmap_write(regmap, hd->n_reg, 1);
-+
-+ if (hd->user_reg) {
-+ u32 regval = hd->user_val;
-+ unsigned long rate;
-+
-+ rate = __clk_get_rate(hw->clk);
-+
-+ /* Pick the right VCO. */
-+ if (hd->user_vco_mask && rate > hd->low_vco_max_rate)
-+ regval |= hd->user_vco_mask;
-+ regmap_write(regmap, hd->user_reg, regval);
-+ }
-+
-+ if (hd->droop_reg)
-+ regmap_write(regmap, hd->droop_reg, hd->droop_val);
-+
-+ h->init_done = true;
-+}
-+
-+static void __clk_hfpll_enable(struct clk_hw *hw)
-+{
-+ struct clk_hfpll *h = to_clk_hfpll(hw);
-+ struct hfpll_data const *hd = h->d;
-+ struct regmap *regmap = h->clkr.regmap;
-+ u32 val;
-+
-+ __clk_hfpll_init_once(hw);
-+
-+ /* Disable PLL bypass mode. */
-+ regmap_update_bits(regmap, hd->mode_reg, PLL_BYPASSNL, PLL_BYPASSNL);
-+
-+ /*
-+ * H/W requires a 5us delay between disabling the bypass and
-+ * de-asserting the reset. Delay 10us just to be safe.
-+ */
-+ mb();
-+ udelay(10);
-+
-+ /* De-assert active-low PLL reset. */
-+ regmap_update_bits(regmap, hd->mode_reg, PLL_RESET_N, PLL_RESET_N);
-+
-+ /* Wait for PLL to lock. */
-+ if (hd->status_reg) {
-+ do {
-+ regmap_read(regmap, hd->status_reg, &val);
-+ } while (!(val & BIT(hd->lock_bit)));
-+ } else {
-+ mb();
-+ udelay(60);
-+ }
-+
-+ /* Enable PLL output. */
-+ regmap_update_bits(regmap, hd->mode_reg, PLL_OUTCTRL, PLL_OUTCTRL);
-+
-+ /* Make sure the enable is done before returning. */
-+ mb();
-+}
-+
-+/* Enable an already-configured HFPLL. */
-+static int clk_hfpll_enable(struct clk_hw *hw)
-+{
-+ unsigned long flags;
-+ struct clk_hfpll *h = to_clk_hfpll(hw);
-+ struct hfpll_data const *hd = h->d;
-+ struct regmap *regmap = h->clkr.regmap;
-+ u32 mode;
-+
-+ spin_lock_irqsave(&h->lock, flags);
-+ regmap_read(regmap, hd->mode_reg, &mode);
-+ if (!(mode & (PLL_BYPASSNL | PLL_RESET_N | PLL_OUTCTRL)))
-+ __clk_hfpll_enable(hw);
-+ spin_unlock_irqrestore(&h->lock, flags);
-+
-+ return 0;
-+}
-+
-+static void __clk_hfpll_disable(struct clk_hw *hw)
-+{
-+ struct clk_hfpll *h = to_clk_hfpll(hw);
-+ struct hfpll_data const *hd = h->d;
-+ struct regmap *regmap = h->clkr.regmap;
-+
-+ /*
-+ * Disable the PLL output, disable test mode, enable the bypass mode,
-+ * and assert the reset.
-+ */
-+ regmap_update_bits(regmap, hd->mode_reg,
-+ PLL_BYPASSNL | PLL_RESET_N | PLL_OUTCTRL, 0);
-+}
-+
-+static void clk_hfpll_disable(struct clk_hw *hw)
-+{
-+ struct clk_hfpll *h = to_clk_hfpll(hw);
-+ unsigned long flags;
-+
-+ spin_lock_irqsave(&h->lock, flags);
-+ __clk_hfpll_disable(hw);
-+ spin_unlock_irqrestore(&h->lock, flags);
-+}
-+
-+static long clk_hfpll_round_rate(struct clk_hw *hw, unsigned long rate,
-+ unsigned long *parent_rate)
-+{
-+ struct clk_hfpll *h = to_clk_hfpll(hw);
-+ struct hfpll_data const *hd = h->d;
-+ unsigned long rrate;
-+
-+ rate = clamp(rate, hd->min_rate, hd->max_rate);
-+
-+ rrate = DIV_ROUND_UP(rate, *parent_rate) * *parent_rate;
-+ if (rrate > hd->max_rate)
-+ rrate -= *parent_rate;
-+
-+ return rrate;
-+}
-+
-+/*
-+ * For optimization reasons, assumes no downstream clocks are actively using
-+ * it.
-+ */
-+static int clk_hfpll_set_rate(struct clk_hw *hw, unsigned long rate,
-+ unsigned long parent_rate)
-+{
-+ struct clk_hfpll *h = to_clk_hfpll(hw);
-+ struct hfpll_data const *hd = h->d;
-+ struct regmap *regmap = h->clkr.regmap;
-+ unsigned long flags;
-+ u32 l_val, val;
-+ bool enabled;
-+
-+ l_val = rate / parent_rate;
-+
-+ spin_lock_irqsave(&h->lock, flags);
-+
-+ enabled = __clk_is_enabled(hw->clk);
-+ if (enabled)
-+ __clk_hfpll_disable(hw);
-+
-+ /* Pick the right VCO. */
-+ if (hd->user_reg && hd->user_vco_mask) {
-+ regmap_read(regmap, hd->user_reg, &val);
-+ if (rate <= hd->low_vco_max_rate)
-+ val &= ~hd->user_vco_mask;
-+ else
-+ val |= hd->user_vco_mask;
-+ regmap_write(regmap, hd->user_reg, val);
-+ }
-+
-+ regmap_write(regmap, hd->l_reg, l_val);
-+
-+ if (enabled)
-+ __clk_hfpll_enable(hw);
-+
-+ spin_unlock_irqrestore(&h->lock, flags);
-+
-+ return 0;
-+}
-+
-+static unsigned long clk_hfpll_recalc_rate(struct clk_hw *hw,
-+ unsigned long parent_rate)
-+{
-+ struct clk_hfpll *h = to_clk_hfpll(hw);
-+ struct hfpll_data const *hd = h->d;
-+ struct regmap *regmap = h->clkr.regmap;
-+ u32 l_val;
-+
-+ regmap_read(regmap, hd->l_reg, &l_val);
-+
-+ return l_val * parent_rate;
-+}
-+
-+static void clk_hfpll_init(struct clk_hw *hw)
-+{
-+ struct clk_hfpll *h = to_clk_hfpll(hw);
-+ struct hfpll_data const *hd = h->d;
-+ struct regmap *regmap = h->clkr.regmap;
-+ u32 mode, status;
-+
-+ regmap_read(regmap, hd->mode_reg, &mode);
-+ if (mode != (PLL_BYPASSNL | PLL_RESET_N | PLL_OUTCTRL)) {
-+ __clk_hfpll_init_once(hw);
-+ return;
-+ }
-+
-+ if (hd->status_reg) {
-+ regmap_read(regmap, hd->status_reg, &status);
-+ if (!(status & BIT(hd->lock_bit))) {
-+ WARN(1, "HFPLL %s is ON, but not locked!\n",
-+ __clk_get_name(hw->clk));
-+ clk_hfpll_disable(hw);
-+ __clk_hfpll_init_once(hw);
-+ }
-+ }
-+}
-+
-+static int hfpll_is_enabled(struct clk_hw *hw)
-+{
-+ struct clk_hfpll *h = to_clk_hfpll(hw);
-+ struct hfpll_data const *hd = h->d;
-+ struct regmap *regmap = h->clkr.regmap;
-+ u32 mode;
-+
-+ regmap_read(regmap, hd->mode_reg, &mode);
-+ mode &= 0x7;
-+ return mode == (PLL_BYPASSNL | PLL_RESET_N | PLL_OUTCTRL);
-+}
-+
-+const struct clk_ops clk_ops_hfpll = {
-+ .enable = clk_hfpll_enable,
-+ .disable = clk_hfpll_disable,
-+ .is_enabled = hfpll_is_enabled,
-+ .round_rate = clk_hfpll_round_rate,
-+ .set_rate = clk_hfpll_set_rate,
-+ .recalc_rate = clk_hfpll_recalc_rate,
-+ .init = clk_hfpll_init,
-+};
-+EXPORT_SYMBOL_GPL(clk_ops_hfpll);
---- /dev/null
-+++ b/drivers/clk/qcom/clk-hfpll.h
-@@ -0,0 +1,54 @@
-+/*
-+ * Copyright (c) 2013-2014, The Linux Foundation. All rights reserved.
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 and
-+ * only version 2 as published by the Free Software Foundation.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ * GNU General Public License for more details.
-+ */
-+#ifndef __QCOM_CLK_HFPLL_H__
-+#define __QCOM_CLK_HFPLL_H__
-+
-+#include <linux/clk-provider.h>
-+#include <linux/spinlock.h>
-+#include "clk-regmap.h"
-+
-+struct hfpll_data {
-+ u32 mode_reg;
-+ u32 l_reg;
-+ u32 m_reg;
-+ u32 n_reg;
-+ u32 user_reg;
-+ u32 droop_reg;
-+ u32 config_reg;
-+ u32 status_reg;
-+ u8 lock_bit;
-+
-+ u32 droop_val;
-+ u32 config_val;
-+ u32 user_val;
-+ u32 user_vco_mask;
-+ unsigned long low_vco_max_rate;
-+
-+ unsigned long min_rate;
-+ unsigned long max_rate;
-+};
-+
-+struct clk_hfpll {
-+ struct hfpll_data const *d;
-+ int init_done;
-+
-+ struct clk_regmap clkr;
-+ spinlock_t lock;
-+};
-+
-+#define to_clk_hfpll(_hw) \
-+ container_of(to_clk_regmap(_hw), struct clk_hfpll, clkr)
-+
-+extern const struct clk_ops clk_ops_hfpll;
-+
-+#endif
diff --git a/target/linux/ipq806x/patches/0167-clk-qcom-Add-HFPLL-driver.patch b/target/linux/ipq806x/patches/0167-clk-qcom-Add-HFPLL-driver.patch
deleted file mode 100644
index 1aedbda..0000000
--- a/target/linux/ipq806x/patches/0167-clk-qcom-Add-HFPLL-driver.patch
+++ /dev/null
@@ -1,152 +0,0 @@
-From 49134da893bc11e833e3d87139c57e3b84e65219 Mon Sep 17 00:00:00 2001
-From: Stephen Boyd <sboyd@codeaurora.org>
-Date: Thu, 19 Jun 2014 18:46:31 -0700
-Subject: [PATCH 167/182] clk: qcom: Add HFPLL driver
-
-On some devices (MSM8974 for example), the HFPLLs are
-instantiated within the Krait processor subsystem as separate
-register regions. Add a driver for these PLLs so that we can
-provide HFPLL clocks for use by the system.
-
-Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
----
- drivers/clk/qcom/Kconfig | 8 ++++
- drivers/clk/qcom/Makefile | 1 +
- drivers/clk/qcom/hfpll.c | 110 +++++++++++++++++++++++++++++++++++++++++++++
- 3 files changed, 119 insertions(+)
- create mode 100644 drivers/clk/qcom/hfpll.c
-
---- a/drivers/clk/qcom/Kconfig
-+++ b/drivers/clk/qcom/Kconfig
-@@ -53,3 +53,11 @@ config MSM_MMCC_8974
- Support for the multimedia clock controller on msm8974 devices.
- Say Y if you want to support multimedia devices such as display,
- graphics, video encode/decode, camera, etc.
-+
-+config QCOM_HFPLL
-+ tristate "High-Frequency PLL (HFPLL) Clock Controller"
-+ depends on COMMON_CLK_QCOM
-+ help
-+ Support for the high-frequency PLLs present on Qualcomm devices.
-+ Say Y if you want to support CPU frequency scaling on devices
-+ such as MSM8974, APQ8084, etc.
---- a/drivers/clk/qcom/Makefile
-+++ b/drivers/clk/qcom/Makefile
-@@ -16,3 +16,4 @@ obj-$(CONFIG_MSM_GCC_8960) += gcc-msm896
- obj-$(CONFIG_MSM_GCC_8974) += gcc-msm8974.o
- obj-$(CONFIG_MSM_MMCC_8960) += mmcc-msm8960.o
- obj-$(CONFIG_MSM_MMCC_8974) += mmcc-msm8974.o
-+obj-$(CONFIG_QCOM_HFPLL) += hfpll.o
---- /dev/null
-+++ b/drivers/clk/qcom/hfpll.c
-@@ -0,0 +1,110 @@
-+/*
-+ * Copyright (c) 2013-2014, The Linux Foundation. All rights reserved.
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 and
-+ * only version 2 as published by the Free Software Foundation.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ * GNU General Public License for more details.
-+ */
-+
-+#include <linux/kernel.h>
-+#include <linux/init.h>
-+#include <linux/module.h>
-+#include <linux/platform_device.h>
-+#include <linux/of.h>
-+#include <linux/clk.h>
-+#include <linux/clk-provider.h>
-+#include <linux/regmap.h>
-+
-+#include "clk-regmap.h"
-+#include "clk-hfpll.h"
-+
-+static const struct hfpll_data hdata = {
-+ .mode_reg = 0x00,
-+ .l_reg = 0x04,
-+ .m_reg = 0x08,
-+ .n_reg = 0x0c,
-+ .user_reg = 0x10,
-+ .config_reg = 0x14,
-+ .config_val = 0x430405d,
-+ .status_reg = 0x1c,
-+ .lock_bit = 16,
-+
-+ .user_val = 0x8,
-+ .user_vco_mask = 0x100000,
-+ .low_vco_max_rate = 1248000000,
-+ .min_rate = 537600000UL,
-+ .max_rate = 2900000000UL,
-+};
-+
-+static const struct of_device_id qcom_hfpll_match_table[] = {
-+ { .compatible = "qcom,hfpll" },
-+ { }
-+};
-+MODULE_DEVICE_TABLE(of, qcom_hfpll_match_table);
-+
-+static struct regmap_config hfpll_regmap_config = {
-+ .reg_bits = 32,
-+ .reg_stride = 4,
-+ .val_bits = 32,
-+ .max_register = 0x30,
-+ .fast_io = true,
-+};
-+
-+static int qcom_hfpll_probe(struct platform_device *pdev)
-+{
-+ struct clk *clk;
-+ struct resource *res;
-+ struct device *dev = &pdev->dev;
-+ void __iomem *base;
-+ struct regmap *regmap;
-+ struct clk_hfpll *h;
-+ struct clk_init_data init = {
-+ .parent_names = (const char *[]){ "xo" },
-+ .num_parents = 1,
-+ .ops = &clk_ops_hfpll,
-+ };
-+
-+ h = devm_kzalloc(dev, sizeof(*h), GFP_KERNEL);
-+ if (!h)
-+ return -ENOMEM;
-+
-+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-+ base = devm_ioremap_resource(dev, res);
-+ if (IS_ERR(base))
-+ return PTR_ERR(base);
-+
-+ regmap = devm_regmap_init_mmio(&pdev->dev, base, &hfpll_regmap_config);
-+ if (IS_ERR(regmap))
-+ return PTR_ERR(regmap);
-+
-+ if (of_property_read_string_index(dev->of_node, "clock-output-names",
-+ 0, &init.name))
-+ return -ENODEV;
-+
-+ h->d = &hdata;
-+ h->clkr.hw.init = &init;
-+ spin_lock_init(&h->lock);
-+
-+ clk = devm_clk_register_regmap(&pdev->dev, &h->clkr);
-+
-+ return PTR_ERR_OR_ZERO(clk);
-+}
-+
-+static struct platform_driver qcom_hfpll_driver = {
-+ .probe = qcom_hfpll_probe,
-+ .driver = {
-+ .name = "qcom-hfpll",
-+ .owner = THIS_MODULE,
-+ .of_match_table = qcom_hfpll_match_table,
-+ },
-+};
-+module_platform_driver(qcom_hfpll_driver);
-+
-+MODULE_DESCRIPTION("QCOM HFPLL Clock Driver");
-+MODULE_LICENSE("GPL v2");
-+MODULE_ALIAS("platform:qcom-hfpll");
diff --git a/target/linux/ipq806x/patches/0168-clk-qcom-Add-MSM8960-s-HFPLLs.patch b/target/linux/ipq806x/patches/0168-clk-qcom-Add-MSM8960-s-HFPLLs.patch
deleted file mode 100644
index 04ff371..0000000
--- a/target/linux/ipq806x/patches/0168-clk-qcom-Add-MSM8960-s-HFPLLs.patch
+++ /dev/null
@@ -1,117 +0,0 @@
-From 0a38d7a21ef0e851d025e4e16f096d5579226299 Mon Sep 17 00:00:00 2001
-From: Stephen Boyd <sboyd@codeaurora.org>
-Date: Mon, 16 Jun 2014 17:44:08 -0700
-Subject: [PATCH 168/182] clk: qcom: Add MSM8960's HFPLLs
-
-Describe the HFPLLs present on MSM8960 devices.
-
-Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
----
- drivers/clk/qcom/gcc-msm8960.c | 82 ++++++++++++++++++++++++++++++++++++++++
- 1 file changed, 82 insertions(+)
-
---- a/drivers/clk/qcom/gcc-msm8960.c
-+++ b/drivers/clk/qcom/gcc-msm8960.c
-@@ -30,6 +30,7 @@
- #include "clk-pll.h"
- #include "clk-rcg.h"
- #include "clk-branch.h"
-+#include "clk-hfpll.h"
- #include "reset.h"
-
- static struct clk_pll pll3 = {
-@@ -75,6 +76,84 @@ static struct clk_regmap pll8_vote = {
- },
- };
-
-+static struct hfpll_data hfpll0_data = {
-+ .mode_reg = 0x3200,
-+ .l_reg = 0x3208,
-+ .m_reg = 0x320c,
-+ .n_reg = 0x3210,
-+ .config_reg = 0x3204,
-+ .status_reg = 0x321c,
-+ .config_val = 0x7845c665,
-+ .droop_reg = 0x3214,
-+ .droop_val = 0x0108c000,
-+ .min_rate = 600000000UL,
-+ .max_rate = 1800000000UL,
-+};
-+
-+static struct clk_hfpll hfpll0 = {
-+ .d = &hfpll0_data,
-+ .clkr.hw.init = &(struct clk_init_data){
-+ .parent_names = (const char *[]){ "pxo" },
-+ .num_parents = 1,
-+ .name = "hfpll0",
-+ .ops = &clk_ops_hfpll,
-+ .flags = CLK_IGNORE_UNUSED,
-+ },
-+ .lock = __SPIN_LOCK_UNLOCKED(hfpll0.lock),
-+};
-+
-+static struct hfpll_data hfpll1_data = {
-+ .mode_reg = 0x3300,
-+ .l_reg = 0x3308,
-+ .m_reg = 0x330c,
-+ .n_reg = 0x3310,
-+ .config_reg = 0x3304,
-+ .status_reg = 0x331c,
-+ .config_val = 0x7845c665,
-+ .droop_reg = 0x3314,
-+ .droop_val = 0x0108c000,
-+ .min_rate = 600000000UL,
-+ .max_rate = 1800000000UL,
-+};
-+
-+static struct clk_hfpll hfpll1 = {
-+ .d = &hfpll1_data,
-+ .clkr.hw.init = &(struct clk_init_data){
-+ .parent_names = (const char *[]){ "pxo" },
-+ .num_parents = 1,
-+ .name = "hfpll1",
-+ .ops = &clk_ops_hfpll,
-+ .flags = CLK_IGNORE_UNUSED,
-+ },
-+ .lock = __SPIN_LOCK_UNLOCKED(hfpll1.lock),
-+};
-+
-+static struct hfpll_data hfpll_l2_data = {
-+ .mode_reg = 0x3400,
-+ .l_reg = 0x3408,
-+ .m_reg = 0x340c,
-+ .n_reg = 0x3410,
-+ .config_reg = 0x3404,
-+ .status_reg = 0x341c,
-+ .config_val = 0x7845c665,
-+ .droop_reg = 0x3414,
-+ .droop_val = 0x0108c000,
-+ .min_rate = 600000000UL,
-+ .max_rate = 1800000000UL,
-+};
-+
-+static struct clk_hfpll hfpll_l2 = {
-+ .d = &hfpll_l2_data,
-+ .clkr.hw.init = &(struct clk_init_data){
-+ .parent_names = (const char *[]){ "pxo" },
-+ .num_parents = 1,
-+ .name = "hfpll_l2",
-+ .ops = &clk_ops_hfpll,
-+ .flags = CLK_IGNORE_UNUSED,
-+ },
-+ .lock = __SPIN_LOCK_UNLOCKED(hfpll_l2.lock),
-+};
-+
- static struct clk_pll pll14 = {
- .l_reg = 0x31c4,
- .m_reg = 0x31c8,
-@@ -2763,6 +2842,9 @@ static struct clk_regmap *gcc_msm8960_cl
- [PMIC_ARB1_H_CLK] = &pmic_arb1_h_clk.clkr,
- [PMIC_SSBI2_CLK] = &pmic_ssbi2_clk.clkr,
- [RPM_MSG_RAM_H_CLK] = &rpm_msg_ram_h_clk.clkr,
-+ [PLL9] = &hfpll0.clkr,
-+ [PLL10] = &hfpll1.clkr,
-+ [PLL12] = &hfpll_l2.clkr,
- };
-
- static const struct qcom_reset_map gcc_msm8960_resets[] = {
diff --git a/target/linux/ipq806x/patches/0169-clk-qcom-Add-support-for-Krait-clocks.patch b/target/linux/ipq806x/patches/0169-clk-qcom-Add-support-for-Krait-clocks.patch
deleted file mode 100644
index 6e17acd..0000000
--- a/target/linux/ipq806x/patches/0169-clk-qcom-Add-support-for-Krait-clocks.patch
+++ /dev/null
@@ -1,190 +0,0 @@
-From 63ecfef8560631a15ee13129b2778cd4dffbcfe2 Mon Sep 17 00:00:00 2001
-From: Stephen Boyd <sboyd@codeaurora.org>
-Date: Wed, 18 Jun 2014 14:18:31 -0700
-Subject: [PATCH 169/182] clk: qcom: Add support for Krait clocks
-
-The Krait clocks are made up of a series of muxes and a divider
-that choose between a fixed rate clock and dedicated HFPLLs for
-each CPU. Instead of using mmio accesses to remux parents, the
-Krait implementation exposes the remux control via cp15
-registers. Support these clocks.
-
-Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
----
- drivers/clk/qcom/Kconfig | 4 ++
- drivers/clk/qcom/Makefile | 1 +
- drivers/clk/qcom/clk-krait.c | 121 ++++++++++++++++++++++++++++++++++++++++++
- drivers/clk/qcom/clk-krait.h | 22 ++++++++
- 4 files changed, 148 insertions(+)
- create mode 100644 drivers/clk/qcom/clk-krait.c
- create mode 100644 drivers/clk/qcom/clk-krait.h
-
---- a/drivers/clk/qcom/Kconfig
-+++ b/drivers/clk/qcom/Kconfig
-@@ -61,3 +61,7 @@ config QCOM_HFPLL
- Support for the high-frequency PLLs present on Qualcomm devices.
- Say Y if you want to support CPU frequency scaling on devices
- such as MSM8974, APQ8084, etc.
-+
-+config KRAIT_CLOCKS
-+ bool
-+ select KRAIT_L2_ACCESSORS
---- a/drivers/clk/qcom/Makefile
-+++ b/drivers/clk/qcom/Makefile
-@@ -7,6 +7,7 @@ clk-qcom-y += clk-rcg.o
- clk-qcom-y += clk-rcg2.o
- clk-qcom-y += clk-branch.o
- clk-qcom-y += clk-generic.o
-+clk-qcom-$(CONFIG_KRAIT_CLOCKS) += clk-krait.o
- clk-qcom-y += clk-hfpll.o
- clk-qcom-y += reset.o
-
---- /dev/null
-+++ b/drivers/clk/qcom/clk-krait.c
-@@ -0,0 +1,121 @@
-+/*
-+ * Copyright (c) 2013-2014, The Linux Foundation. All rights reserved.
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 and
-+ * only version 2 as published by the Free Software Foundation.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ * GNU General Public License for more details.
-+ */
-+
-+#include <linux/kernel.h>
-+#include <linux/module.h>
-+#include <linux/init.h>
-+#include <linux/io.h>
-+#include <linux/delay.h>
-+#include <linux/err.h>
-+#include <linux/clk-provider.h>
-+#include <linux/spinlock.h>
-+
-+#include <asm/krait-l2-accessors.h>
-+
-+#include "clk-krait.h"
-+
-+/* Secondary and primary muxes share the same cp15 register */
-+static DEFINE_SPINLOCK(kpss_clock_reg_lock);
-+
-+#define LPL_SHIFT 8
-+static void __kpss_mux_set_sel(struct mux_clk *mux, int sel)
-+{
-+ unsigned long flags;
-+ u32 regval;
-+
-+ spin_lock_irqsave(&kpss_clock_reg_lock, flags);
-+ regval = krait_get_l2_indirect_reg(mux->offset);
-+ regval &= ~(mux->mask << mux->shift);
-+ regval |= (sel & mux->mask) << mux->shift;
-+ if (mux->priv) {
-+ regval &= ~(mux->mask << (mux->shift + LPL_SHIFT));
-+ regval |= (sel & mux->mask) << (mux->shift + LPL_SHIFT);
-+ }
-+ krait_set_l2_indirect_reg(mux->offset, regval);
-+ spin_unlock_irqrestore(&kpss_clock_reg_lock, flags);
-+
-+ /* Wait for switch to complete. */
-+ mb();
-+ udelay(1);
-+}
-+
-+static int kpss_mux_set_sel(struct mux_clk *mux, int sel)
-+{
-+ mux->en_mask = sel;
-+ /* Don't touch mux if CPU is off as it won't work */
-+ if (__clk_is_enabled(mux->hw.clk))
-+ __kpss_mux_set_sel(mux, sel);
-+ return 0;
-+}
-+
-+static int kpss_mux_get_sel(struct mux_clk *mux)
-+{
-+ u32 sel;
-+
-+ sel = krait_get_l2_indirect_reg(mux->offset);
-+ sel >>= mux->shift;
-+ sel &= mux->mask;
-+ mux->en_mask = sel;
-+
-+ return sel;
-+}
-+
-+static int kpss_mux_enable(struct mux_clk *mux)
-+{
-+ __kpss_mux_set_sel(mux, mux->en_mask);
-+ return 0;
-+}
-+
-+static void kpss_mux_disable(struct mux_clk *mux)
-+{
-+ __kpss_mux_set_sel(mux, mux->safe_sel);
-+}
-+
-+const struct clk_mux_ops clk_mux_ops_kpss = {
-+ .enable = kpss_mux_enable,
-+ .disable = kpss_mux_disable,
-+ .set_mux_sel = kpss_mux_set_sel,
-+ .get_mux_sel = kpss_mux_get_sel,
-+};
-+EXPORT_SYMBOL_GPL(clk_mux_ops_kpss);
-+
-+/*
-+ * The divider can divide by 2, 4, 6 and 8. But we only really need div-2. So
-+ * force it to div-2 during handoff and treat it like a fixed div-2 clock.
-+ */
-+static int kpss_div2_get_div(struct div_clk *div)
-+{
-+ unsigned long flags;
-+ u32 regval;
-+ int val;
-+
-+ spin_lock_irqsave(&kpss_clock_reg_lock, flags);
-+ regval = krait_get_l2_indirect_reg(div->offset);
-+ val = (regval >> div->shift) & div->mask;
-+ regval &= ~(div->mask << div->shift);
-+ if (div->priv)
-+ regval &= ~(div->mask << (div->shift + LPL_SHIFT));
-+ krait_set_l2_indirect_reg(div->offset, regval);
-+ spin_unlock_irqrestore(&kpss_clock_reg_lock, flags);
-+
-+ val = (val + 1) * 2;
-+ WARN(val != 2, "Divider %s was configured to div-%d instead of 2!\n",
-+ __clk_get_name(div->hw.clk), val);
-+
-+ return 2;
-+}
-+
-+const struct clk_div_ops clk_div_ops_kpss_div2 = {
-+ .get_div = kpss_div2_get_div,
-+};
-+EXPORT_SYMBOL_GPL(clk_div_ops_kpss_div2);
---- /dev/null
-+++ b/drivers/clk/qcom/clk-krait.h
-@@ -0,0 +1,22 @@
-+/*
-+ * Copyright (c) 2013, The Linux Foundation. All rights reserved.
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 and
-+ * only version 2 as published by the Free Software Foundation.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ * GNU General Public License for more details.
-+ */
-+
-+#ifndef __SOC_QCOM_CLOCK_KRAIT_H
-+#define __SOC_QCOM_CLOCK_KRAIT_H
-+
-+#include <linux/clk/msm-clk-generic.h>
-+
-+extern const struct clk_mux_ops clk_mux_ops_kpss;
-+extern const struct clk_div_ops clk_div_ops_kpss_div2;
-+
-+#endif
diff --git a/target/linux/ipq806x/patches/0170-clk-qcom-Add-KPSS-ACC-GCC-driver.patch b/target/linux/ipq806x/patches/0170-clk-qcom-Add-KPSS-ACC-GCC-driver.patch
deleted file mode 100644
index b16108e..0000000
--- a/target/linux/ipq806x/patches/0170-clk-qcom-Add-KPSS-ACC-GCC-driver.patch
+++ /dev/null
@@ -1,161 +0,0 @@
-From 67a9d5a02b178644da624ef9c32b4e6abb2c4f6e Mon Sep 17 00:00:00 2001
-From: Stephen Boyd <sboyd@codeaurora.org>
-Date: Wed, 18 Jun 2014 14:25:41 -0700
-Subject: [PATCH 170/182] clk: qcom: Add KPSS ACC/GCC driver
-
-The ACC and GCC regions present in KPSSv1 contain registers to
-control clocks and power to each Krait CPU and L2. For CPUfreq
-purposes probe these devices and expose a mux clock that chooses
-between PXO and PLL8.
-
-Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
----
- drivers/clk/qcom/Kconfig | 8 +++
- drivers/clk/qcom/Makefile | 1 +
- drivers/clk/qcom/kpss-xcc.c | 115 +++++++++++++++++++++++++++++++++++++++++++
- 3 files changed, 124 insertions(+)
- create mode 100644 drivers/clk/qcom/kpss-xcc.c
-
---- a/drivers/clk/qcom/Kconfig
-+++ b/drivers/clk/qcom/Kconfig
-@@ -62,6 +62,14 @@ config QCOM_HFPLL
- Say Y if you want to support CPU frequency scaling on devices
- such as MSM8974, APQ8084, etc.
-
-+config KPSS_XCC
-+ tristate "KPSS Clock Controller"
-+ depends on COMMON_CLK_QCOM
-+ help
-+ Support for the Krait ACC and GCC clock controllers. Say Y
-+ if you want to support CPU frequency scaling on devices such
-+ as MSM8960, APQ8064, etc.
-+
- config KRAIT_CLOCKS
- bool
- select KRAIT_L2_ACCESSORS
---- a/drivers/clk/qcom/Makefile
-+++ b/drivers/clk/qcom/Makefile
-@@ -17,4 +17,5 @@ obj-$(CONFIG_MSM_GCC_8960) += gcc-msm896
- obj-$(CONFIG_MSM_GCC_8974) += gcc-msm8974.o
- obj-$(CONFIG_MSM_MMCC_8960) += mmcc-msm8960.o
- obj-$(CONFIG_MSM_MMCC_8974) += mmcc-msm8974.o
-+obj-$(CONFIG_KPSS_XCC) += kpss-xcc.o
- obj-$(CONFIG_QCOM_HFPLL) += hfpll.o
---- /dev/null
-+++ b/drivers/clk/qcom/kpss-xcc.c
-@@ -0,0 +1,115 @@
-+/* Copyright (c) 2014, The Linux Foundation. All rights reserved.
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 and
-+ * only version 2 as published by the Free Software Foundation.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ * GNU General Public License for more details.
-+ */
-+
-+#include <linux/kernel.h>
-+#include <linux/init.h>
-+#include <linux/module.h>
-+#include <linux/platform_device.h>
-+#include <linux/err.h>
-+#include <linux/io.h>
-+#include <linux/of.h>
-+#include <linux/of_device.h>
-+#include <linux/clk.h>
-+#include <linux/clk-provider.h>
-+#include <linux/clk/msm-clk-generic.h>
-+
-+static int kpss_xcc_set_mux_sel(struct mux_clk *clk, int sel)
-+{
-+ writel_relaxed(sel, clk->base + clk->offset);
-+ return 0;
-+}
-+
-+static int kpss_xcc_get_mux_sel(struct mux_clk *clk)
-+{
-+ return readl_relaxed(clk->base + clk->offset);
-+}
-+
-+static const struct clk_mux_ops kpss_xcc_ops = {
-+ .set_mux_sel = kpss_xcc_set_mux_sel,
-+ .get_mux_sel = kpss_xcc_get_mux_sel,
-+};
-+
-+static const char *aux_parents[] = {
-+ "pll8_vote",
-+ "pxo",
-+};
-+
-+static u8 aux_parent_map[] = {
-+ 3,
-+ 0,
-+};
-+
-+static const struct of_device_id kpss_xcc_match_table[] = {
-+ { .compatible = "qcom,kpss-acc-v1", .data = (void *)1UL },
-+ { .compatible = "qcom,kpss-gcc" },
-+ {}
-+};
-+MODULE_DEVICE_TABLE(of, kpss_xcc_match_table);
-+
-+static int kpss_xcc_driver_probe(struct platform_device *pdev)
-+{
-+ const struct of_device_id *id;
-+ struct clk *clk;
-+ struct resource *res;
-+ void __iomem *base;
-+ struct mux_clk *mux_clk;
-+ struct clk_init_data init = {
-+ .parent_names = aux_parents,
-+ .num_parents = 2,
-+ .ops = &clk_ops_gen_mux,
-+ };
-+
-+ id = of_match_device(kpss_xcc_match_table, &pdev->dev);
-+ if (!id)
-+ return -ENODEV;
-+
-+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-+ base = devm_ioremap_resource(&pdev->dev, res);
-+ if (IS_ERR(base))
-+ return PTR_ERR(base);
-+
-+ mux_clk = devm_kzalloc(&pdev->dev, sizeof(*mux_clk), GFP_KERNEL);
-+ if (!mux_clk)
-+ return -ENOMEM;
-+
-+ mux_clk->mask = 0x3;
-+ mux_clk->parent_map = aux_parent_map;
-+ mux_clk->ops = &kpss_xcc_ops;
-+ mux_clk->base = base;
-+ mux_clk->hw.init = &init;
-+
-+ if (id->data) {
-+ if (of_property_read_string_index(pdev->dev.of_node,
-+ "clock-output-names", 0, &init.name))
-+ return -ENODEV;
-+ mux_clk->offset = 0x14;
-+ } else {
-+ init.name = "acpu_l2_aux";
-+ mux_clk->offset = 0x28;
-+ }
-+
-+ clk = devm_clk_register(&pdev->dev, &mux_clk->hw);
-+
-+ return PTR_ERR_OR_ZERO(clk);
-+}
-+
-+static struct platform_driver kpss_xcc_driver = {
-+ .probe = kpss_xcc_driver_probe,
-+ .driver = {
-+ .name = "kpss-xcc",
-+ .of_match_table = kpss_xcc_match_table,
-+ .owner = THIS_MODULE,
-+ },
-+};
-+module_platform_driver(kpss_xcc_driver);
-+
-+MODULE_LICENSE("GPL v2");
diff --git a/target/linux/ipq806x/patches/0171-clk-qcom-Add-Krait-clock-controller-driver.patch b/target/linux/ipq806x/patches/0171-clk-qcom-Add-Krait-clock-controller-driver.patch
deleted file mode 100644
index 6d0619a..0000000
--- a/target/linux/ipq806x/patches/0171-clk-qcom-Add-Krait-clock-controller-driver.patch
+++ /dev/null
@@ -1,410 +0,0 @@
-From 6912e27d97ba5671e8c2434bed0ebd23fde5e13d Mon Sep 17 00:00:00 2001
-From: Stephen Boyd <sboyd@codeaurora.org>
-Date: Wed, 18 Jun 2014 14:29:29 -0700
-Subject: [PATCH 171/182] clk: qcom: Add Krait clock controller driver
-
-The Krait CPU clocks are made up of a primary mux and secondary
-mux for each CPU and the L2, controlled via cp15 accessors. For
-Kraits within KPSSv1 each secondary mux accepts a different aux
-source, but on KPSSv2 each secondary mux accepts the same aux
-source.
-
-Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
----
- drivers/clk/qcom/Kconfig | 8 +
- drivers/clk/qcom/Makefile | 1 +
- drivers/clk/qcom/krait-cc.c | 364 +++++++++++++++++++++++++++++++++++++++++++
- 3 files changed, 373 insertions(+)
- create mode 100644 drivers/clk/qcom/krait-cc.c
-
---- a/drivers/clk/qcom/Kconfig
-+++ b/drivers/clk/qcom/Kconfig
-@@ -70,6 +70,14 @@ config KPSS_XCC
- if you want to support CPU frequency scaling on devices such
- as MSM8960, APQ8064, etc.
-
-+config KRAITCC
-+ tristate "Krait Clock Controller"
-+ depends on COMMON_CLK_QCOM && ARM
-+ select KRAIT_CLOCKS
-+ help
-+ Support for the Krait CPU clocks on Qualcomm devices.
-+ Say Y if you want to support CPU frequency scaling.
-+
- config KRAIT_CLOCKS
- bool
- select KRAIT_L2_ACCESSORS
---- a/drivers/clk/qcom/Makefile
-+++ b/drivers/clk/qcom/Makefile
-@@ -19,3 +19,4 @@ obj-$(CONFIG_MSM_MMCC_8960) += mmcc-msm8
- obj-$(CONFIG_MSM_MMCC_8974) += mmcc-msm8974.o
- obj-$(CONFIG_KPSS_XCC) += kpss-xcc.o
- obj-$(CONFIG_QCOM_HFPLL) += hfpll.o
-+obj-$(CONFIG_KRAITCC) += krait-cc.o
---- /dev/null
-+++ b/drivers/clk/qcom/krait-cc.c
-@@ -0,0 +1,364 @@
-+/* Copyright (c) 2013-2014, The Linux Foundation. All rights reserved.
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 and
-+ * only version 2 as published by the Free Software Foundation.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ * GNU General Public License for more details.
-+ */
-+
-+#include <linux/kernel.h>
-+#include <linux/init.h>
-+#include <linux/module.h>
-+#include <linux/platform_device.h>
-+#include <linux/err.h>
-+#include <linux/io.h>
-+#include <linux/of.h>
-+#include <linux/of_device.h>
-+#include <linux/clk.h>
-+#include <linux/clk-provider.h>
-+#include <linux/slab.h>
-+
-+#include <asm/smp_plat.h>
-+
-+#include "clk-krait.h"
-+
-+DEFINE_FIXED_DIV_CLK(acpu_aux, 2, "gpll0_vote");
-+
-+static u8 sec_mux_map[] = {
-+ 2,
-+ 0,
-+};
-+
-+static u8 pri_mux_map[] = {
-+ 1,
-+ 2,
-+ 0,
-+};
-+
-+static int
-+krait_add_div(struct device *dev, int id, const char *s, unsigned offset)
-+{
-+ struct div_clk *div;
-+ struct clk_init_data init = {
-+ .num_parents = 1,
-+ .ops = &clk_ops_div,
-+ .flags = CLK_SET_RATE_PARENT,
-+ };
-+ const char *p_names[1];
-+ struct clk *clk;
-+
-+ div = devm_kzalloc(dev, sizeof(*dev), GFP_KERNEL);
-+ if (!div)
-+ return -ENOMEM;
-+
-+ div->data.div = 2;
-+ div->data.min_div = 2;
-+ div->data.max_div = 2;
-+ div->ops = &clk_div_ops_kpss_div2;
-+ div->mask = 0x3;
-+ div->shift = 6;
-+ div->priv = (void *)(id >= 0);
-+ div->offset = offset;
-+ div->hw.init = &init;
-+
-+ init.name = kasprintf(GFP_KERNEL, "hfpll%s_div", s);
-+ if (!init.name)
-+ return -ENOMEM;
-+
-+ init.parent_names = p_names;
-+ p_names[0] = kasprintf(GFP_KERNEL, "hfpll%s", s);
-+ if (!p_names[0]) {
-+ kfree(init.name);
-+ return -ENOMEM;
-+ }
-+
-+ clk = devm_clk_register(dev, &div->hw);
-+ kfree(p_names[0]);
-+ kfree(init.name);
-+
-+ return PTR_ERR_OR_ZERO(clk);
-+}
-+
-+static int
-+krait_add_sec_mux(struct device *dev, int id, const char *s, unsigned offset,
-+ bool unique_aux)
-+{
-+ struct mux_clk *mux;
-+ static const char *sec_mux_list[] = {
-+ "acpu_aux",
-+ "qsb",
-+ };
-+ struct clk_init_data init = {
-+ .parent_names = sec_mux_list,
-+ .num_parents = ARRAY_SIZE(sec_mux_list),
-+ .ops = &clk_ops_gen_mux,
-+ .flags = CLK_SET_RATE_PARENT,
-+ };
-+ struct clk *clk;
-+
-+ mux = devm_kzalloc(dev, sizeof(*mux), GFP_KERNEL);
-+ if (!mux)
-+ return -ENOMEM;
-+
-+ mux->offset = offset;
-+ mux->priv = (void *)(id >= 0);
-+ mux->has_safe_parent = true;
-+ mux->safe_sel = 2;
-+ mux->ops = &clk_mux_ops_kpss;
-+ mux->mask = 0x3;
-+ mux->shift = 2;
-+ mux->parent_map = sec_mux_map;
-+ mux->hw.init = &init;
-+
-+ init.name = kasprintf(GFP_KERNEL, "krait%s_sec_mux", s);
-+ if (!init.name)
-+ return -ENOMEM;
-+
-+ if (unique_aux) {
-+ sec_mux_list[0] = kasprintf(GFP_KERNEL, "acpu%s_aux", s);
-+ if (!sec_mux_list[0]) {
-+ clk = ERR_PTR(-ENOMEM);
-+ goto err_aux;
-+ }
-+ }
-+
-+ clk = devm_clk_register(dev, &mux->hw);
-+
-+ if (unique_aux)
-+ kfree(sec_mux_list[0]);
-+err_aux:
-+ kfree(init.name);
-+ return PTR_ERR_OR_ZERO(clk);
-+}
-+
-+static struct clk *
-+krait_add_pri_mux(struct device *dev, int id, const char * s, unsigned offset)
-+{
-+ struct mux_clk *mux;
-+ const char *p_names[3];
-+ struct clk_init_data init = {
-+ .parent_names = p_names,
-+ .num_parents = ARRAY_SIZE(p_names),
-+ .ops = &clk_ops_gen_mux,
-+ .flags = CLK_SET_RATE_PARENT,
-+ };
-+ struct clk *clk;
-+
-+ mux = devm_kzalloc(dev, sizeof(*mux), GFP_KERNEL);
-+ if (!mux)
-+ return ERR_PTR(-ENOMEM);
-+
-+ mux->has_safe_parent = true;
-+ mux->safe_sel = 0;
-+ mux->ops = &clk_mux_ops_kpss;
-+ mux->mask = 0x3;
-+ mux->shift = 0;
-+ mux->offset = offset;
-+ mux->priv = (void *)(id >= 0);
-+ mux->parent_map = pri_mux_map;
-+ mux->hw.init = &init;
-+
-+ init.name = kasprintf(GFP_KERNEL, "krait%s_pri_mux", s);
-+ if (!init.name)
-+ return ERR_PTR(-ENOMEM);
-+
-+ p_names[0] = kasprintf(GFP_KERNEL, "hfpll%s", s);
-+ if (!p_names[0]) {
-+ clk = ERR_PTR(-ENOMEM);
-+ goto err_p0;
-+ }
-+
-+ p_names[1] = kasprintf(GFP_KERNEL, "hfpll%s_div", s);
-+ if (!p_names[1]) {
-+ clk = ERR_PTR(-ENOMEM);
-+ goto err_p1;
-+ }
-+
-+ p_names[2] = kasprintf(GFP_KERNEL, "krait%s_sec_mux", s);
-+ if (!p_names[2]) {
-+ clk = ERR_PTR(-ENOMEM);
-+ goto err_p2;
-+ }
-+
-+ clk = devm_clk_register(dev, &mux->hw);
-+
-+ kfree(p_names[2]);
-+err_p2:
-+ kfree(p_names[1]);
-+err_p1:
-+ kfree(p_names[0]);
-+err_p0:
-+ kfree(init.name);
-+ return clk;
-+}
-+
-+/* id < 0 for L2, otherwise id == physical CPU number */
-+static struct clk *krait_add_clks(struct device *dev, int id, bool unique_aux)
-+{
-+ int ret;
-+ unsigned offset;
-+ void *p = NULL;
-+ const char *s;
-+ struct clk *clk;
-+
-+ if (id >= 0) {
-+ offset = 0x4501 + (0x1000 * id);
-+ s = p = kasprintf(GFP_KERNEL, "%d", id);
-+ if (!s)
-+ return ERR_PTR(-ENOMEM);
-+ } else {
-+ offset = 0x500;
-+ s = "_l2";
-+ }
-+
-+ ret = krait_add_div(dev, id, s, offset);
-+ if (ret) {
-+ clk = ERR_PTR(ret);
-+ goto err;
-+ }
-+
-+ ret = krait_add_sec_mux(dev, id, s, offset, unique_aux);
-+ if (ret) {
-+ clk = ERR_PTR(ret);
-+ goto err;
-+ }
-+
-+ clk = krait_add_pri_mux(dev, id, s, offset);
-+err:
-+ kfree(p);
-+ return clk;
-+}
-+
-+static struct clk *krait_of_get(struct of_phandle_args *clkspec, void *data)
-+{
-+ unsigned int idx = clkspec->args[0];
-+ struct clk **clks = data;
-+
-+ if (idx >= 5) {
-+ pr_err("%s: invalid clock index %d\n", __func__, idx);
-+ return ERR_PTR(-EINVAL);
-+ }
-+
-+ return clks[idx] ? : ERR_PTR(-ENODEV);
-+}
-+
-+static const struct of_device_id krait_cc_match_table[] = {
-+ { .compatible = "qcom,krait-cc-v1", (void *)1UL },
-+ { .compatible = "qcom,krait-cc-v2" },
-+ {}
-+};
-+MODULE_DEVICE_TABLE(of, krait_cc_match_table);
-+
-+static int krait_cc_probe(struct platform_device *pdev)
-+{
-+ struct device *dev = &pdev->dev;
-+ const struct of_device_id *id;
-+ unsigned long cur_rate, aux_rate;
-+ int i, cpu;
-+ struct clk *clk;
-+ struct clk **clks;
-+ struct clk *l2_pri_mux_clk;
-+
-+ id = of_match_device(krait_cc_match_table, &pdev->dev);
-+ if (!id)
-+ return -ENODEV;
-+
-+ /* Rate is 1 because 0 causes problems for __clk_mux_determine_rate */
-+ clk = clk_register_fixed_rate(dev, "qsb", NULL, CLK_IS_ROOT, 1);
-+ if (IS_ERR(clk))
-+ return PTR_ERR(clk);
-+
-+ if (!id->data) {
-+ clk = devm_clk_register(dev, &acpu_aux.hw);
-+ if (IS_ERR(clk))
-+ return PTR_ERR(clk);
-+ }
-+
-+ /* Krait configurations have at most 4 CPUs and one L2 */
-+ clks = devm_kcalloc(dev, 5, sizeof(*clks), GFP_KERNEL);
-+ if (!clks)
-+ return -ENOMEM;
-+
-+ for_each_possible_cpu(i) {
-+ cpu = cpu_logical_map(i);
-+ clk = krait_add_clks(dev, cpu, id->data);
-+ if (IS_ERR(clk))
-+ return PTR_ERR(clk);
-+ clks[cpu] = clk;
-+ }
-+
-+ l2_pri_mux_clk = krait_add_clks(dev, -1, id->data);
-+ if (IS_ERR(l2_pri_mux_clk))
-+ return PTR_ERR(l2_pri_mux_clk);
-+ clks[4] = l2_pri_mux_clk;
-+
-+ /*
-+ * We don't want the CPU or L2 clocks to be turned off at late init
-+ * if CPUFREQ or HOTPLUG configs are disabled. So, bump up the
-+ * refcount of these clocks. Any cpufreq/hotplug manager can assume
-+ * that the clocks have already been prepared and enabled by the time
-+ * they take over.
-+ */
-+ for_each_online_cpu(i) {
-+ cpu = cpu_logical_map(i);
-+ clk_prepare_enable(l2_pri_mux_clk);
-+ WARN(clk_prepare_enable(clks[cpu]),
-+ "Unable to turn on CPU%d clock", cpu);
-+ }
-+
-+ /*
-+ * Force reinit of HFPLLs and muxes to overwrite any potential
-+ * incorrect configuration of HFPLLs and muxes by the bootloader.
-+ * While at it, also make sure the cores are running at known rates
-+ * and print the current rate.
-+ *
-+ * The clocks are set to aux clock rate first to make sure the
-+ * secondary mux is not sourcing off of QSB. The rate is then set to
-+ * two different rates to force a HFPLL reinit under all
-+ * circumstances.
-+ */
-+ cur_rate = clk_get_rate(l2_pri_mux_clk);
-+ aux_rate = 384000000;
-+ if (cur_rate == 1) {
-+ pr_info("L2 @ QSB rate. Forcing new rate.\n");
-+ cur_rate = aux_rate;
-+ }
-+ clk_set_rate(l2_pri_mux_clk, aux_rate);
-+ clk_set_rate(l2_pri_mux_clk, 2);
-+ clk_set_rate(l2_pri_mux_clk, cur_rate);
-+ pr_info("L2 @ %lu KHz\n", clk_get_rate(l2_pri_mux_clk) / 1000);
-+ for_each_possible_cpu(i) {
-+ cpu = cpu_logical_map(i);
-+ clk = clks[cpu];
-+ cur_rate = clk_get_rate(clk);
-+ if (cur_rate == 1) {
-+ pr_info("CPU%d @ QSB rate. Forcing new rate.\n", i);
-+ cur_rate = aux_rate;
-+ }
-+ clk_set_rate(clk, aux_rate);
-+ clk_set_rate(clk, 2);
-+ clk_set_rate(clk, cur_rate);
-+ pr_info("CPU%d @ %lu KHz\n", i, clk_get_rate(clk) / 1000);
-+ }
-+
-+ of_clk_add_provider(dev->of_node, krait_of_get, clks);
-+
-+ return 0;
-+}
-+
-+static struct platform_driver krait_cc_driver = {
-+ .probe = krait_cc_probe,
-+ .driver = {
-+ .name = "clock-krait",
-+ .of_match_table = krait_cc_match_table,
-+ .owner = THIS_MODULE,
-+ },
-+};
-+module_platform_driver(krait_cc_driver);
-+
-+MODULE_DESCRIPTION("Krait CPU Clock Driver");
-+MODULE_LICENSE("GPL v2");
diff --git a/target/linux/ipq806x/patches/0172-cpufreq-Add-a-cpufreq-krait-based-on-cpufreq-cpu0.patch b/target/linux/ipq806x/patches/0172-cpufreq-Add-a-cpufreq-krait-based-on-cpufreq-cpu0.patch
deleted file mode 100644
index ea07fc1..0000000
--- a/target/linux/ipq806x/patches/0172-cpufreq-Add-a-cpufreq-krait-based-on-cpufreq-cpu0.patch
+++ /dev/null
@@ -1,245 +0,0 @@
-From 5cf343c60d7557aefb468603065cac5062f11b8d Mon Sep 17 00:00:00 2001
-From: Stephen Boyd <sboyd@codeaurora.org>
-Date: Fri, 30 May 2014 16:36:11 -0700
-Subject: [PATCH 172/182] cpufreq: Add a cpufreq-krait based on cpufreq-cpu0
-
-Krait processors have individual clocks for each CPU that can
-scale independently from one another. cpufreq-cpu0 is fairly
-close to this, but assumes that there is only one clock for all
-CPUs. Add a driver to support the Krait configuration.
-
-TODO: Merge into cpufreq-cpu0? Or make generic?
-
-Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
----
- drivers/cpufreq/Kconfig | 13 +++
- drivers/cpufreq/Makefile | 1 +
- drivers/cpufreq/cpufreq-krait.c | 190 +++++++++++++++++++++++++++++++++++++++
- 3 files changed, 204 insertions(+)
- create mode 100644 drivers/cpufreq/cpufreq-krait.c
-
---- a/drivers/cpufreq/Kconfig
-+++ b/drivers/cpufreq/Kconfig
-@@ -194,6 +194,19 @@ config GENERIC_CPUFREQ_CPU0
-
- If in doubt, say N.
-
-+config GENERIC_CPUFREQ_KRAIT
-+ tristate "Krait cpufreq driver"
-+ depends on HAVE_CLK && OF
-+ # if CPU_THERMAL is on and THERMAL=m, CPU0 cannot be =y:
-+ depends on !CPU_THERMAL || THERMAL
-+ select PM_OPP
-+ help
-+ This adds a generic cpufreq driver for CPU0 frequency management.
-+ It supports both uniprocessor (UP) and symmetric multiprocessor (SMP)
-+ systems which share clock and voltage across all CPUs.
-+
-+ If in doubt, say N.
-+
- menu "x86 CPU frequency scaling drivers"
- depends on X86
- source "drivers/cpufreq/Kconfig.x86"
---- a/drivers/cpufreq/Makefile
-+++ b/drivers/cpufreq/Makefile
-@@ -12,6 +12,7 @@ obj-$(CONFIG_CPU_FREQ_GOV_CONSERVATIVE)
- obj-$(CONFIG_CPU_FREQ_GOV_COMMON) += cpufreq_governor.o
-
- obj-$(CONFIG_GENERIC_CPUFREQ_CPU0) += cpufreq-cpu0.o
-+obj-$(CONFIG_GENERIC_CPUFREQ_KRAIT) += cpufreq-krait.o
-
- ##################################################################################
- # x86 drivers.
---- /dev/null
-+++ b/drivers/cpufreq/cpufreq-krait.c
-@@ -0,0 +1,190 @@
-+/*
-+ * Copyright (C) 2012 Freescale Semiconductor, Inc.
-+ * Copyright (c) 2014, The Linux Foundation. All rights reserved.
-+ *
-+ * The OPP code in function krait_set_target() is reused from
-+ * drivers/cpufreq/omap-cpufreq.c
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation.
-+ */
-+
-+#include <linux/clk.h>
-+#include <linux/cpu.h>
-+#include <linux/cpu_cooling.h>
-+#include <linux/cpufreq.h>
-+#include <linux/cpumask.h>
-+#include <linux/err.h>
-+#include <linux/module.h>
-+#include <linux/of.h>
-+#include <linux/pm_opp.h>
-+#include <linux/platform_device.h>
-+#include <linux/slab.h>
-+#include <linux/thermal.h>
-+
-+static unsigned int transition_latency;
-+
-+static struct device *cpu_dev;
-+static DEFINE_PER_CPU(struct clk *, krait_cpu_clks);
-+static struct cpufreq_frequency_table *freq_table;
-+static struct thermal_cooling_device *cdev;
-+
-+static int krait_set_target(struct cpufreq_policy *policy, unsigned int index)
-+{
-+ unsigned long volt = 0, volt_old = 0;
-+ unsigned int old_freq, new_freq;
-+ long freq_Hz, freq_exact;
-+ int ret;
-+ struct clk *cpu_clk;
-+
-+ cpu_clk = per_cpu(krait_cpu_clks, policy->cpu);
-+
-+ freq_Hz = clk_round_rate(cpu_clk, freq_table[index].frequency * 1000);
-+ if (freq_Hz <= 0)
-+ freq_Hz = freq_table[index].frequency * 1000;
-+
-+ freq_exact = freq_Hz;
-+ new_freq = freq_Hz / 1000;
-+ old_freq = clk_get_rate(cpu_clk) / 1000;
-+
-+ pr_debug("%u MHz, %ld mV --> %u MHz, %ld mV\n",
-+ old_freq / 1000, volt_old ? volt_old / 1000 : -1,
-+ new_freq / 1000, volt ? volt / 1000 : -1);
-+
-+ ret = clk_set_rate(cpu_clk, freq_exact);
-+ if (ret)
-+ pr_err("failed to set clock rate: %d\n", ret);
-+
-+ return ret;
-+}
-+
-+static int krait_cpufreq_init(struct cpufreq_policy *policy)
-+{
-+ int ret;
-+
-+ policy->clk = per_cpu(krait_cpu_clks, policy->cpu);
-+
-+ ret = cpufreq_table_validate_and_show(policy, freq_table);
-+ if (ret) {
-+ pr_err("%s: invalid frequency table: %d\n", __func__, ret);
-+ return ret;
-+ }
-+
-+ policy->cpuinfo.transition_latency = transition_latency;
-+
-+ return 0;
-+}
-+
-+static struct cpufreq_driver krait_cpufreq_driver = {
-+ .flags = CPUFREQ_STICKY,
-+ .verify = cpufreq_generic_frequency_table_verify,
-+ .target_index = krait_set_target,
-+ .get = cpufreq_generic_get,
-+ .init = krait_cpufreq_init,
-+ .name = "generic_krait",
-+ .attr = cpufreq_generic_attr,
-+};
-+
-+static int krait_cpufreq_probe(struct platform_device *pdev)
-+{
-+ struct device_node *np;
-+ int ret;
-+ unsigned int cpu;
-+ struct device *dev;
-+ struct clk *clk;
-+
-+ cpu_dev = get_cpu_device(0);
-+ if (!cpu_dev) {
-+ pr_err("failed to get krait device\n");
-+ return -ENODEV;
-+ }
-+
-+ np = of_node_get(cpu_dev->of_node);
-+ if (!np) {
-+ pr_err("failed to find krait node\n");
-+ return -ENOENT;
-+ }
-+
-+ for_each_possible_cpu(cpu) {
-+ dev = get_cpu_device(cpu);
-+ if (!dev) {
-+ pr_err("failed to get krait device\n");
-+ ret = -ENOENT;
-+ goto out_put_node;
-+ }
-+ per_cpu(krait_cpu_clks, cpu) = clk = devm_clk_get(dev, NULL);
-+ if (IS_ERR(clk)) {
-+ ret = PTR_ERR(clk);
-+ goto out_put_node;
-+ }
-+ }
-+
-+ ret = of_init_opp_table(cpu_dev);
-+ if (ret) {
-+ pr_err("failed to init OPP table: %d\n", ret);
-+ goto out_put_node;
-+ }
-+
-+ ret = dev_pm_opp_init_cpufreq_table(cpu_dev, &freq_table);
-+ if (ret) {
-+ pr_err("failed to init cpufreq table: %d\n", ret);
-+ goto out_put_node;
-+ }
-+
-+ if (of_property_read_u32(np, "clock-latency", &transition_latency))
-+ transition_latency = CPUFREQ_ETERNAL;
-+
-+ ret = cpufreq_register_driver(&krait_cpufreq_driver);
-+ if (ret) {
-+ pr_err("failed register driver: %d\n", ret);
-+ goto out_free_table;
-+ }
-+ of_node_put(np);
-+
-+ /*
-+ * For now, just loading the cooling device;
-+ * thermal DT code takes care of matching them.
-+ */
-+ for_each_possible_cpu(cpu) {
-+ dev = get_cpu_device(cpu);
-+ np = of_node_get(dev->of_node);
-+ if (of_find_property(np, "#cooling-cells", NULL)) {
-+ cdev = of_cpufreq_cooling_register(np, cpumask_of(cpu));
-+ if (IS_ERR(cdev))
-+ pr_err("running cpufreq without cooling device: %ld\n",
-+ PTR_ERR(cdev));
-+ }
-+ of_node_put(np);
-+ }
-+
-+ return 0;
-+
-+out_free_table:
-+ dev_pm_opp_free_cpufreq_table(cpu_dev, &freq_table);
-+out_put_node:
-+ of_node_put(np);
-+ return ret;
-+}
-+
-+static int krait_cpufreq_remove(struct platform_device *pdev)
-+{
-+ cpufreq_cooling_unregister(cdev);
-+ cpufreq_unregister_driver(&krait_cpufreq_driver);
-+ dev_pm_opp_free_cpufreq_table(cpu_dev, &freq_table);
-+
-+ return 0;
-+}
-+
-+static struct platform_driver krait_cpufreq_platdrv = {
-+ .driver = {
-+ .name = "cpufreq-krait",
-+ .owner = THIS_MODULE,
-+ },
-+ .probe = krait_cpufreq_probe,
-+ .remove = krait_cpufreq_remove,
-+};
-+module_platform_driver(krait_cpufreq_platdrv);
-+
-+MODULE_DESCRIPTION("Krait CPUfreq driver");
-+MODULE_LICENSE("GPL v2");
diff --git a/target/linux/ipq806x/patches/0173-cpufreq-Add-module-to-register-cpufreq-krait-device.patch b/target/linux/ipq806x/patches/0173-cpufreq-Add-module-to-register-cpufreq-krait-device.patch
deleted file mode 100644
index 373c402..0000000
--- a/target/linux/ipq806x/patches/0173-cpufreq-Add-module-to-register-cpufreq-krait-device.patch
+++ /dev/null
@@ -1,94 +0,0 @@
-From f1db56284b01b1212a211023dcaa7846fd07d0ec Mon Sep 17 00:00:00 2001
-From: Stephen Boyd <sboyd@codeaurora.org>
-Date: Fri, 30 May 2014 17:16:53 -0700
-Subject: [PATCH 173/182] cpufreq: Add module to register cpufreq-krait device
-
-Register a cpufreq-krait device whenever we detect that a
-"qcom,krait" compatible CPU is present in DT.
-
-Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
----
- drivers/cpufreq/Kconfig.arm | 8 +++++++
- drivers/cpufreq/Makefile | 1 +
- drivers/cpufreq/qcom-cpufreq.c | 48 ++++++++++++++++++++++++++++++++++++++++
- 3 files changed, 57 insertions(+)
- create mode 100644 drivers/cpufreq/qcom-cpufreq.c
-
---- a/drivers/cpufreq/Kconfig.arm
-+++ b/drivers/cpufreq/Kconfig.arm
-@@ -123,6 +123,14 @@ config ARM_OMAP2PLUS_CPUFREQ
- depends on ARCH_OMAP2PLUS
- default ARCH_OMAP2PLUS
-
-+config ARM_QCOM_CPUFREQ
-+ tristate "Qualcomm based"
-+ depends on ARCH_QCOM
-+ help
-+ This adds the CPUFreq driver for Qualcomm SoC based boards.
-+
-+ If in doubt, say N.
-+
- config ARM_S3C_CPUFREQ
- bool
- help
---- a/drivers/cpufreq/Makefile
-+++ b/drivers/cpufreq/Makefile
-@@ -60,6 +60,7 @@ obj-$(CONFIG_ARM_IMX6Q_CPUFREQ) += imx6
- obj-$(CONFIG_ARM_INTEGRATOR) += integrator-cpufreq.o
- obj-$(CONFIG_ARM_KIRKWOOD_CPUFREQ) += kirkwood-cpufreq.o
- obj-$(CONFIG_ARM_OMAP2PLUS_CPUFREQ) += omap-cpufreq.o
-+obj-$(CONFIG_ARM_QCOM_CPUFREQ) += qcom-cpufreq.o
- obj-$(CONFIG_PXA25x) += pxa2xx-cpufreq.o
- obj-$(CONFIG_PXA27x) += pxa2xx-cpufreq.o
- obj-$(CONFIG_PXA3xx) += pxa3xx-cpufreq.o
---- /dev/null
-+++ b/drivers/cpufreq/qcom-cpufreq.c
-@@ -0,0 +1,48 @@
-+/* Copyright (c) 2014, The Linux Foundation. All rights reserved.
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 and
-+ * only version 2 as published by the Free Software Foundation.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ * GNU General Public License for more details.
-+ */
-+
-+#include <linux/kernel.h>
-+#include <linux/module.h>
-+#include <linux/cpu.h>
-+#include <linux/of.h>
-+#include <linux/platform_device.h>
-+#include <linux/err.h>
-+
-+static int qcom_cpufreq_driver_init(void)
-+{
-+ struct platform_device_info devinfo = { .name = "cpufreq-krait", };
-+ struct device *cpu_dev;
-+ struct device_node *np;
-+ struct platform_device *pdev;
-+
-+ cpu_dev = get_cpu_device(0);
-+ if (!cpu_dev)
-+ return -ENODEV;
-+
-+ np = of_node_get(cpu_dev->of_node);
-+ if (!np)
-+ return -ENOENT;
-+
-+ if (!of_device_is_compatible(np, "qcom,krait")) {
-+ of_node_put(np);
-+ return -ENODEV;
-+ }
-+ of_node_put(np);
-+
-+ pdev = platform_device_register_full(&devinfo);
-+
-+ return PTR_ERR_OR_ZERO(pdev);
-+}
-+module_init(qcom_cpufreq_driver_init);
-+
-+MODULE_DESCRIPTION("Qualcomm CPUfreq driver");
-+MODULE_LICENSE("GPL v2");
diff --git a/target/linux/ipq806x/patches/0174-clk-qcom-Add-HFPLLs-to-IPQ806X-driver.patch b/target/linux/ipq806x/patches/0174-clk-qcom-Add-HFPLLs-to-IPQ806X-driver.patch
deleted file mode 100644
index 682a519..0000000
--- a/target/linux/ipq806x/patches/0174-clk-qcom-Add-HFPLLs-to-IPQ806X-driver.patch
+++ /dev/null
@@ -1,116 +0,0 @@
-From b9b3815f2a71af88ca68d3524ee4d9b6b4739257 Mon Sep 17 00:00:00 2001
-From: Stephen Boyd <sboyd@codeaurora.org>
-Date: Wed, 18 Jun 2014 15:57:06 -0700
-Subject: [PATCH 174/182] clk: qcom: Add HFPLLs to IPQ806X driver
-
-Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
----
- drivers/clk/qcom/gcc-ipq806x.c | 83 ++++++++++++++++++++++++++++++++++++++++
- 1 file changed, 83 insertions(+)
-
---- a/drivers/clk/qcom/gcc-ipq806x.c
-+++ b/drivers/clk/qcom/gcc-ipq806x.c
-@@ -30,6 +30,7 @@
- #include "clk-pll.h"
- #include "clk-rcg.h"
- #include "clk-branch.h"
-+#include "clk-hfpll.h"
- #include "reset.h"
-
- static struct clk_pll pll0 = {
-@@ -102,6 +103,85 @@ static struct clk_regmap pll8_vote = {
- },
- };
-
-+static struct hfpll_data hfpll0_data = {
-+ .mode_reg = 0x3200,
-+ .l_reg = 0x3208,
-+ .m_reg = 0x320c,
-+ .n_reg = 0x3210,
-+ .config_reg = 0x3204,
-+ .status_reg = 0x321c,
-+ .config_val = 0x7845c665,
-+ .droop_reg = 0x3214,
-+ .droop_val = 0x0108c000,
-+ .min_rate = 600000000UL,
-+ .max_rate = 1800000000UL,
-+};
-+
-+static struct clk_hfpll hfpll0 = {
-+ .d = &hfpll0_data,
-+ .clkr.hw.init = &(struct clk_init_data){
-+ .parent_names = (const char *[]){ "pxo" },
-+ .num_parents = 1,
-+ .name = "hfpll0",
-+ .ops = &clk_ops_hfpll,
-+ .flags = CLK_IGNORE_UNUSED,
-+ },
-+ .lock = __SPIN_LOCK_UNLOCKED(hfpll0.lock),
-+};
-+
-+static struct hfpll_data hfpll1_data = {
-+ .mode_reg = 0x3240,
-+ .l_reg = 0x3248,
-+ .m_reg = 0x324c,
-+ .n_reg = 0x3250,
-+ .config_reg = 0x3244,
-+ .status_reg = 0x325c,
-+ .config_val = 0x7845c665,
-+ .droop_reg = 0x3314,
-+ .droop_val = 0x0108c000,
-+ .min_rate = 600000000UL,
-+ .max_rate = 1800000000UL,
-+};
-+
-+static struct clk_hfpll hfpll1 = {
-+ .d = &hfpll1_data,
-+ .clkr.hw.init = &(struct clk_init_data){
-+ .parent_names = (const char *[]){ "pxo" },
-+ .num_parents = 1,
-+ .name = "hfpll1",
-+ .ops = &clk_ops_hfpll,
-+ .flags = CLK_IGNORE_UNUSED,
-+ },
-+ .lock = __SPIN_LOCK_UNLOCKED(hfpll1.lock),
-+};
-+
-+static struct hfpll_data hfpll_l2_data = {
-+ .mode_reg = 0x3300,
-+ .l_reg = 0x3308,
-+ .m_reg = 0x330c,
-+ .n_reg = 0x3310,
-+ .config_reg = 0x3304,
-+ .status_reg = 0x331c,
-+ .config_val = 0x7845c665,
-+ .droop_reg = 0x3314,
-+ .droop_val = 0x0108c000,
-+ .min_rate = 600000000UL,
-+ .max_rate = 1800000000UL,
-+};
-+
-+static struct clk_hfpll hfpll_l2 = {
-+ .d = &hfpll_l2_data,
-+ .clkr.hw.init = &(struct clk_init_data){
-+ .parent_names = (const char *[]){ "pxo" },
-+ .num_parents = 1,
-+ .name = "hfpll_l2",
-+ .ops = &clk_ops_hfpll,
-+ .flags = CLK_IGNORE_UNUSED,
-+ },
-+ .lock = __SPIN_LOCK_UNLOCKED(hfpll_l2.lock),
-+};
-+
-+
- static struct clk_pll pll14 = {
- .l_reg = 0x31c4,
- .m_reg = 0x31c8,
-@@ -2878,6 +2958,9 @@ static struct clk_regmap *gcc_ipq806x_cl
- [NSSTCM_CLK_SRC] = &nss_tcm_src.clkr,
- [NSSTCM_CLK] = &nss_tcm_clk.clkr,
- [NSS_CORE_CLK] = &nss_core_clk,
-+ [PLL9] = &hfpll0.clkr,
-+ [PLL10] = &hfpll1.clkr,
-+ [PLL12] = &hfpll_l2.clkr,
- };
-
- static const struct qcom_reset_map gcc_ipq806x_resets[] = {
diff --git a/target/linux/ipq806x/patches/0175-ARM-dts-ipq8064-Add-necessary-DT-data-for-Krait-cpuf.patch b/target/linux/ipq806x/patches/0175-ARM-dts-ipq8064-Add-necessary-DT-data-for-Krait-cpuf.patch
deleted file mode 100644
index 3fddd61..0000000
--- a/target/linux/ipq806x/patches/0175-ARM-dts-ipq8064-Add-necessary-DT-data-for-Krait-cpuf.patch
+++ /dev/null
@@ -1,91 +0,0 @@
-From 258a3ea23ec048603debe1621c681b0cc733f236 Mon Sep 17 00:00:00 2001
-From: Stephen Boyd <sboyd@codeaurora.org>
-Date: Wed, 18 Jun 2014 16:04:37 -0700
-Subject: [PATCH 175/182] ARM: dts: ipq8064: Add necessary DT data for Krait
- cpufreq
-
-Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
----
- arch/arm/boot/dts/qcom-ipq8064.dtsi | 45 +++++++++++++++++++++++++++++++++++
- 1 file changed, 45 insertions(+)
-
---- a/arch/arm/boot/dts/qcom-ipq8064.dtsi
-+++ b/arch/arm/boot/dts/qcom-ipq8064.dtsi
-@@ -23,6 +23,22 @@
- next-level-cache = <&L2>;
- qcom,acc = <&acc0>;
- qcom,saw = <&saw0>;
-+ clocks = <&kraitcc 0>;
-+ clock-names = "cpu";
-+ operating-points = <
-+ /* kHz ignored */
-+ 1400000 1000000
-+ 1200000 1000000
-+ 1000000 1000000
-+ 800000 1000000
-+ 600000 1000000
-+ 384000 1000000
-+ >;
-+ clock-latency = <100000>;
-+
-+ cooling-min-state = <0>;
-+ cooling-max-state = <10>;
-+ #cooling-cells = <2>;
- };
-
- cpu@1 {
-@@ -33,6 +49,22 @@
- next-level-cache = <&L2>;
- qcom,acc = <&acc1>;
- qcom,saw = <&saw1>;
-+ clocks = <&kraitcc 1>;
-+ clock-names = "cpu";
-+ operating-points = <
-+ /* kHz ignored */
-+ 1400000 1000000
-+ 1200000 1000000
-+ 1000000 1000000
-+ 800000 1000000
-+ 600000 1000000
-+ 384000 1000000
-+ >;
-+ clock-latency = <100000>;
-+
-+ cooling-min-state = <0>;
-+ cooling-max-state = <10>;
-+ #cooling-cells = <2>;
- };
-
- L2: l2-cache {
-@@ -46,6 +78,11 @@
- interrupts = <1 10 0x304>;
- };
-
-+ kraitcc: clock-controller {
-+ compatible = "qcom,krait-cc-v1";
-+ #clock-cells = <1>;
-+ };
-+
- reserved-memory {
- #address-cells = <1>;
- #size-cells = <1>;
-@@ -102,11 +139,19 @@
- acc0: clock-controller@2088000 {
- compatible = "qcom,kpss-acc-v1";
- reg = <0x02088000 0x1000>, <0x02008000 0x1000>;
-+ clock-output-names = "acpu0_aux";
- };
-
- acc1: clock-controller@2098000 {
- compatible = "qcom,kpss-acc-v1";
- reg = <0x02098000 0x1000>, <0x02008000 0x1000>;
-+ clock-output-names = "acpu1_aux";
-+ };
-+
-+ l2cc: clock-controller@2011000 {
-+ compatible = "qcom,kpss-gcc";
-+ reg = <0x2011000 0x1000>;
-+ clock-output-names = "acpu_l2_aux";
- };
-
- saw0: regulator@2089000 {
diff --git a/target/linux/ipq806x/patches/0176-ARM-qcom_defconfig-Enable-CPUfreq-options.patch b/target/linux/ipq806x/patches/0176-ARM-qcom_defconfig-Enable-CPUfreq-options.patch
deleted file mode 100644
index 188580a..0000000
--- a/target/linux/ipq806x/patches/0176-ARM-qcom_defconfig-Enable-CPUfreq-options.patch
+++ /dev/null
@@ -1,39 +0,0 @@
-From e8f4d4bf1e4974bf8d17c6702fa4c410637216f3 Mon Sep 17 00:00:00 2001
-From: Stephen Boyd <sboyd@codeaurora.org>
-Date: Mon, 30 Jun 2014 10:50:14 -0700
-Subject: [PATCH 176/182] ARM: qcom_defconfig: Enable CPUfreq options
-
-Enable required options to allow the CPUfreq driver to probe on
-Krait based platforms.
-
-Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
----
- arch/arm/configs/qcom_defconfig | 10 ++++++++++
- 1 file changed, 10 insertions(+)
-
---- a/arch/arm/configs/qcom_defconfig
-+++ b/arch/arm/configs/qcom_defconfig
-@@ -31,6 +31,13 @@ CONFIG_HIGHPTE=y
- CONFIG_CLEANCACHE=y
- CONFIG_ARM_APPENDED_DTB=y
- CONFIG_ARM_ATAG_DTB_COMPAT=y
-+CONFIG_CPU_FREQ=y
-+CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y
-+CONFIG_CPU_FREQ_GOV_POWERSAVE=y
-+CONFIG_CPU_FREQ_GOV_USERSPACE=y
-+CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y
-+CONFIG_GENERIC_CPUFREQ_KRAIT=y
-+CONFIG_ARM_QCOM_CPUFREQ=y
- CONFIG_CPU_IDLE=y
- CONFIG_VFP=y
- CONFIG_NEON=y
-@@ -149,6 +156,9 @@ CONFIG_IPQ_GCC_806X=y
- CONFIG_MSM_GCC_8660=y
- CONFIG_MSM_MMCC_8960=y
- CONFIG_MSM_MMCC_8974=y
-+CONFIG_QCOM_HFPLL=y
-+CONFIG_KPSS_XCC=y
-+CONFIG_KRAITCC=y
- CONFIG_MSM_IOMMU=y
- CONFIG_PHY_QCOM_IPQ806X_SATA=y
- CONFIG_EXT2_FS=y
diff --git a/target/linux/ipq806x/patches/0177-dmaengine-Add-QCOM-ADM-DMA-driver.patch b/target/linux/ipq806x/patches/0177-dmaengine-Add-QCOM-ADM-DMA-driver.patch
deleted file mode 100644
index 05c6706..0000000
--- a/target/linux/ipq806x/patches/0177-dmaengine-Add-QCOM-ADM-DMA-driver.patch
+++ /dev/null
@@ -1,921 +0,0 @@
-From 8984e3fc6db029479d6aa78882b39235379aebff Mon Sep 17 00:00:00 2001
-From: Andy Gross <agross@codeaurora.org>
-Date: Wed, 14 May 2014 13:45:07 -0500
-Subject: [PATCH 177/182] dmaengine: Add QCOM ADM DMA driver
-
-Add the DMA engine driver for the QCOM Application Data Mover (ADM) DMA
-controller found in the MSM8960 and IPQ/APQ8064 platforms.
-
-The ADM supports both memory to memory transactions and memory
-to/from peripheral device transactions. The controller also provides flow
-control capabilities for transactions to/from peripheral devices.
-
-The initial release of this driver supports slave transfers to/from peripherals
-and also incorporates CRCI (client rate control interface) flow control.
-
-Signed-off-by: Andy Gross <agross@codeaurora.org>
----
- drivers/dma/Kconfig | 10 +
- drivers/dma/Makefile | 1 +
- drivers/dma/qcom_adm.c | 871 ++++++++++++++++++++++++++++++++++++++++++++++++
- 3 files changed, 882 insertions(+)
- create mode 100644 drivers/dma/qcom_adm.c
-
---- a/drivers/dma/Kconfig
-+++ b/drivers/dma/Kconfig
-@@ -410,4 +410,14 @@ config QCOM_BAM_DMA
- Enable support for the QCOM BAM DMA controller. This controller
- provides DMA capabilities for a variety of on-chip devices.
-
-+config QCOM_ADM
-+ tristate "Qualcomm ADM support"
-+ depends on ARCH_QCOM || (COMPILE_TEST && OF && ARM)
-+ select DMA_ENGINE
-+ select DMA_VIRTUAL_CHANNELS
-+ ---help---
-+ Enable support for the Qualcomm ADM DMA controller. This controller
-+ provides DMA capabilities for both general purpose and on-chip
-+ peripheral devices.
-+
- endif
---- a/drivers/dma/Makefile
-+++ b/drivers/dma/Makefile
-@@ -46,3 +46,4 @@ obj-$(CONFIG_K3_DMA) += k3dma.o
- obj-$(CONFIG_MOXART_DMA) += moxart-dma.o
- obj-$(CONFIG_FSL_EDMA) += fsl-edma.o
- obj-$(CONFIG_QCOM_BAM_DMA) += qcom_bam_dma.o
-+obj-$(CONFIG_QCOM_ADM) += qcom_adm.o
---- /dev/null
-+++ b/drivers/dma/qcom_adm.c
-@@ -0,0 +1,871 @@
-+/*
-+ * Copyright (c) 2013-2014, The Linux Foundation. All rights reserved.
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 and
-+ * only version 2 as published by the Free Software Foundation.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ * GNU General Public License for more details.
-+ *
-+ */
-+
-+#include <linux/kernel.h>
-+#include <linux/io.h>
-+#include <linux/init.h>
-+#include <linux/slab.h>
-+#include <linux/module.h>
-+#include <linux/interrupt.h>
-+#include <linux/dma-mapping.h>
-+#include <linux/scatterlist.h>
-+#include <linux/device.h>
-+#include <linux/platform_device.h>
-+#include <linux/of.h>
-+#include <linux/of_address.h>
-+#include <linux/of_irq.h>
-+#include <linux/of_dma.h>
-+#include <linux/reset.h>
-+#include <linux/clk.h>
-+#include <linux/dmaengine.h>
-+
-+#include "dmaengine.h"
-+#include "virt-dma.h"
-+
-+/* ADM registers - calculated from channel number and security domain */
-+#define HI_CH_CMD_PTR(chan, ee) (4*chan + 0x20800*ee)
-+#define HI_CH_RSLT(chan, ee) (0x40 + 4*chan + 0x20800*ee)
-+#define HI_CH_FLUSH_STATE0(chan, ee) (0x80 + 4*chan + 0x20800*ee)
-+#define HI_CH_FLUSH_STATE1(chan, ee) (0xc0 + 4*chan + 0x20800*ee)
-+#define HI_CH_FLUSH_STATE2(chan, ee) (0x100 + 4*chan + 0x20800*ee)
-+#define HI_CH_FLUSH_STATE3(chan, ee) (0x140 + 4*chan + 0x20800*ee)
-+#define HI_CH_FLUSH_STATE4(chan, ee) (0x180 + 4*chan + 0x20800*ee)
-+#define HI_CH_FLUSH_STATE5(chan, ee) (0x1c0 + 4*chan + 0x20800*ee)
-+#define HI_CH_STATUS_SD(chan, ee) (0x200 + 4*chan + 0x20800*ee)
-+#define HI_CH_CONF(chan) (0x240 + 4*chan)
-+#define HI_CH_RSLT_CONF(chan, ee) (0x300 + 4*chan + 0x20800*ee)
-+#define HI_SEC_DOMAIN_IRQ_STATUS(ee) (0x380 + 0x20800*ee)
-+#define HI_CI_CONF(ci) (0x390 + 4*ci)
-+#define HI_CRCI_CONF0 0x3d0
-+#define HI_CRCI_CONF1 0x3d4
-+#define HI_GP_CTL 0x3d8
-+#define HI_CRCI_CTL(chan, ee) (0x400 + 0x4*chan + 0x20800*ee)
-+
-+/* channel status */
-+#define CH_STATUS_VALID BIT(1)
-+
-+/* channel result */
-+#define CH_RSLT_VALID BIT(31)
-+#define CH_RSLT_ERR BIT(3)
-+#define CH_RSLT_FLUSH BIT(2)
-+#define CH_RSLT_TPD BIT(1)
-+
-+/* channel conf */
-+#define CH_CONF_MPU_DISABLE BIT(11)
-+#define CH_CONF_PERM_MPU_CONF BIT(9)
-+#define CH_CONF_FLUSH_RSLT_EN BIT(8)
-+#define CH_CONF_FORCE_RSLT_EN BIT(7)
-+#define CH_CONF_IRQ_EN BIT(6)
-+
-+/* channel result conf */
-+#define CH_RSLT_CONF_FLUSH_EN BIT(1)
-+#define CH_RSLT_CONF_IRQ_EN BIT(0)
-+
-+/* CRCI CTL */
-+#define CRCI_CTL_RST BIT(17)
-+
-+/* CI configuration */
-+#define CI_RANGE_END(x) (x << 24)
-+#define CI_RANGE_START(x) (x << 16)
-+#define CI_BURST_4_WORDS 0x4
-+#define CI_BURST_8_WORDS 0x8
-+
-+/* GP CTL */
-+#define GP_CTL_LP_EN BIT(12)
-+#define GP_CTL_LP_CNT(x) (x << 8)
-+
-+/* Command pointer list entry */
-+#define CPLE_LP BIT(31)
-+
-+/* Command list entry */
-+#define CMD_LC BIT(31)
-+#define CMD_DST_CRCI(n) (((n) & 0xf) << 7)
-+#define CMD_SRC_CRCI(n) (((n) & 0xf) << 3)
-+
-+#define CMD_TYPE_SINGLE 0x0
-+#define CMD_TYPE_BOX 0x3
-+
-+#define ADM_DESC_ALIGN 8
-+#define ADM_MAX_XFER (SZ_64K-1)
-+#define ADM_MAX_ROWS (SZ_64K-1)
-+
-+/* Command Pointer List Entry */
-+#define CMD_LP BIT(31)
-+#define CMD_PT_MASK (0x3 << 29)
-+#define CMD_ADDR_MASK 0x3fffffff
-+
-+struct adm_desc_hw {
-+ u32 cmd;
-+ u32 src_addr;
-+ u32 dst_addr;
-+ u32 row_len;
-+ u32 num_rows;
-+ u32 row_offset;
-+};
-+
-+struct adm_cmd_ptr_list {
-+ u32 cple; /* command ptr list entry */
-+ struct adm_desc_hw desc[0];
-+};
-+
-+struct adm_async_desc {
-+ struct virt_dma_desc vd;
-+ struct adm_device *adev;
-+
-+ size_t length;
-+ enum dma_transfer_direction dir;
-+ dma_addr_t dma_addr;
-+ size_t dma_len;
-+
-+ struct adm_cmd_ptr_list *cpl;
-+ u32 num_desc;
-+};
-+
-+struct adm_chan {
-+ struct virt_dma_chan vc;
-+ struct adm_device *adev;
-+
-+ /* parsed from DT */
-+ u32 id; /* channel id */
-+ u32 crci; /* CRCI to be used for transfers */
-+ u32 blk_size; /* block size for CRCI, default 16 byte */
-+
-+ struct adm_async_desc *curr_txd;
-+ struct dma_slave_config slave;
-+ struct list_head node;
-+
-+ int error;
-+ int initialized;
-+};
-+
-+static inline struct adm_chan *to_adm_chan(struct dma_chan *common)
-+{
-+ return container_of(common, struct adm_chan, vc.chan);
-+}
-+
-+struct adm_device {
-+ void __iomem *regs;
-+ struct device *dev;
-+ struct dma_device common;
-+ struct device_dma_parameters dma_parms;
-+ struct adm_chan *channels;
-+ u32 num_channels;
-+
-+ u32 ee;
-+
-+ struct clk *core_clk;
-+ struct clk *iface_clk;
-+
-+ struct reset_control *clk_reset;
-+ struct reset_control *c0_reset;
-+ struct reset_control *c1_reset;
-+ struct reset_control *c2_reset;
-+ int irq;
-+};
-+
-+/**
-+ * adm_alloc_chan - Allocates channel resources for DMA channel
-+ *
-+ * This function is effectively a stub, as we don't need to setup any resources
-+ */
-+static int adm_alloc_chan(struct dma_chan *chan)
-+{
-+ return 0;
-+}
-+
-+/**
-+ * adm_free_chan - Frees dma resources associated with the specific channel
-+ *
-+ * Free all allocated descriptors associated with this channel
-+ *
-+ */
-+static void adm_free_chan(struct dma_chan *chan)
-+{
-+ /* free all queued descriptors */
-+ vchan_free_chan_resources(to_virt_chan(chan));
-+}
-+
-+/**
-+ * adm_prep_slave_sg - Prep slave sg transaction
-+ *
-+ * @chan: dma channel
-+ * @sgl: scatter gather list
-+ * @sg_len: length of sg
-+ * @direction: DMA transfer direction
-+ * @flags: DMA flags
-+ * @context: transfer context (unused)
-+ */
-+static struct dma_async_tx_descriptor *adm_prep_slave_sg(struct dma_chan *chan,
-+ struct scatterlist *sgl, unsigned int sg_len,
-+ enum dma_transfer_direction direction, unsigned long flags,
-+ void *context)
-+{
-+ struct adm_chan *achan = to_adm_chan(chan);
-+ struct adm_device *adev = achan->adev;
-+ struct adm_async_desc *async_desc;
-+ struct scatterlist *sg;
-+ u32 i, rows, num_desc = 0, idx = 0, desc_offset;
-+ struct adm_desc_hw *desc;
-+ struct adm_cmd_ptr_list *cpl;
-+ u32 burst = ADM_MAX_XFER;
-+
-+
-+ if (!is_slave_direction(direction)) {
-+ dev_err(adev->dev, "invalid dma direction\n");
-+ return NULL;
-+ }
-+
-+ /* if using CRCI flow control, validate burst settings */
-+ if (achan->slave.device_fc) {
-+ burst = (direction == DMA_MEM_TO_DEV) ?
-+ achan->slave.dst_maxburst :
-+ achan->slave.src_maxburst;
-+
-+ if (!burst) {
-+ dev_err(adev->dev, "invalid burst value w/ crci: %d\n",
-+ burst);
-+ return ERR_PTR(-EINVAL);
-+ }
-+ }
-+
-+ /* iterate through sgs and compute allocation size of structures */
-+ for_each_sg(sgl, sg, sg_len, i) {
-+
-+ /* calculate boxes using burst */
-+ rows = DIV_ROUND_UP(sg_dma_len(sg), burst);
-+ num_desc += DIV_ROUND_UP(rows, ADM_MAX_ROWS);
-+
-+ /* flow control requires length as a multiple of burst */
-+ if (achan->slave.device_fc && (sg_dma_len(sg) % burst)) {
-+ dev_err(adev->dev, "length is not multiple of burst\n");
-+ return ERR_PTR(-EINVAL);
-+ }
-+ }
-+
-+ async_desc = kzalloc(sizeof(*async_desc), GFP_NOWAIT);
-+ if (!async_desc)
-+ return ERR_PTR(-ENOMEM);
-+
-+ async_desc->dma_len = num_desc * sizeof(*desc) + sizeof(*cpl) +
-+ ADM_DESC_ALIGN;
-+ async_desc->cpl = dma_alloc_writecombine(adev->dev, async_desc->dma_len,
-+ &async_desc->dma_addr, GFP_NOWAIT);
-+
-+ if (!async_desc->cpl) {
-+ kfree(async_desc);
-+ return ERR_PTR(-ENOMEM);
-+ }
-+
-+ async_desc->num_desc = num_desc;
-+ async_desc->adev = adev;
-+ cpl = PTR_ALIGN(async_desc->cpl, ADM_DESC_ALIGN);
-+ desc = PTR_ALIGN(&cpl->desc[0], ADM_DESC_ALIGN);
-+ desc_offset = (u32)desc - (u32)async_desc->cpl;
-+
-+ /* init cmd list */
-+ cpl->cple |= CPLE_LP;
-+ cpl->cple |= (async_desc->dma_addr + desc_offset) >> 3;
-+
-+ for_each_sg(sgl, sg, sg_len, i) {
-+ unsigned int remainder = sg_dma_len(sg);
-+ unsigned int curr_offset = 0;
-+ unsigned int row_len;
-+
-+ do {
-+ desc[idx].cmd = CMD_TYPE_BOX;
-+ desc[idx].row_offset = 0;
-+
-+ if (direction == DMA_DEV_TO_MEM) {
-+ desc[idx].dst_addr = sg_dma_address(sg) +
-+ curr_offset;
-+ desc[idx].src_addr = achan->slave.src_addr;
-+ desc[idx].cmd |= CMD_SRC_CRCI(achan->crci);
-+ desc[idx].row_offset = burst;
-+ } else {
-+ desc[idx].src_addr = sg_dma_address(sg) +
-+ curr_offset;
-+ desc[idx].dst_addr = achan->slave.dst_addr;
-+ desc[idx].cmd |= CMD_DST_CRCI(achan->crci);
-+ desc[idx].row_offset = burst << 16;
-+ }
-+
-+ if (remainder < burst) {
-+ rows = 1;
-+ row_len = remainder;
-+ } else {
-+ rows = remainder / burst;
-+ rows = min_t(u32, rows, ADM_MAX_ROWS);
-+ row_len = burst;
-+ }
-+
-+ desc[idx].num_rows = rows << 16 | rows;
-+ desc[idx].row_len = row_len << 16 | row_len;
-+
-+ remainder -= row_len * rows;
-+ async_desc->length += row_len * rows;
-+ curr_offset += row_len * rows;
-+
-+ idx++;
-+ } while (remainder > 0);
-+ }
-+
-+ /* set last command flag */
-+ desc[idx - 1].cmd |= CMD_LC;
-+
-+ /* reset channel error */
-+ achan->error = 0;
-+
-+ return vchan_tx_prep(&achan->vc, &async_desc->vd, flags);
-+}
-+
-+/**
-+ * adm_slave_config - set slave configuration for channel
-+ * @chan: dma channel
-+ * @cfg: slave configuration
-+ *
-+ * Sets slave configuration for channel
-+ *
-+ */
-+static int adm_slave_config(struct adm_chan *achan,
-+ struct dma_slave_config *cfg)
-+{
-+ int ret = 0;
-+ u32 burst;
-+ struct adm_device *adev = achan->adev;
-+
-+ memcpy(&achan->slave, cfg, sizeof(*cfg));
-+
-+ /* set channel CRCI burst, if applicable */
-+ if (achan->crci) {
-+ burst = max_t(u32, cfg->src_maxburst, cfg->dst_maxburst);
-+
-+ switch (burst) {
-+ case 16:
-+ achan->blk_size = 0;
-+ break;
-+ case 32:
-+ achan->blk_size = 1;
-+ break;
-+ case 64:
-+ achan->blk_size = 2;
-+ break;
-+ case 128:
-+ achan->blk_size = 3;
-+ break;
-+ case 192:
-+ achan->blk_size = 4;
-+ break;
-+ case 256:
-+ achan->blk_size = 5;
-+ break;
-+ default:
-+ achan->slave.src_maxburst = 0;
-+ achan->slave.dst_maxburst = 0;
-+ ret = -EINVAL;
-+ break;
-+ }
-+
-+ if (!ret)
-+ writel(achan->blk_size,
-+ adev->regs + HI_CRCI_CTL(achan->id, adev->ee));
-+ }
-+
-+ return ret;
-+}
-+
-+/**
-+ * adm_terminate_all - terminate all transactions on a channel
-+ * @achan: adm dma channel
-+ *
-+ * Dequeues and frees all transactions, aborts current transaction
-+ * No callbacks are done
-+ *
-+ */
-+static void adm_terminate_all(struct adm_chan *achan)
-+{
-+ struct adm_device *adev = achan->adev;
-+ unsigned long flags;
-+ LIST_HEAD(head);
-+
-+ /* send flush command to terminate current transaction */
-+ writel_relaxed(0x0,
-+ adev->regs + HI_CH_FLUSH_STATE0(achan->id, adev->ee));
-+
-+ spin_lock_irqsave(&achan->vc.lock, flags);
-+ vchan_get_all_descriptors(&achan->vc, &head);
-+ spin_unlock_irqrestore(&achan->vc.lock, flags);
-+
-+ vchan_dma_desc_free_list(&achan->vc, &head);
-+}
-+
-+/**
-+ * adm_control - DMA device control
-+ * @chan: dma channel
-+ * @cmd: control cmd
-+ * @arg: cmd argument
-+ *
-+ * Perform DMA control command
-+ *
-+ */
-+static int adm_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd,
-+ unsigned long arg)
-+{
-+ struct adm_chan *achan = to_adm_chan(chan);
-+ unsigned long flag;
-+ int ret = 0;
-+
-+ switch (cmd) {
-+ case DMA_SLAVE_CONFIG:
-+ spin_lock_irqsave(&achan->vc.lock, flag);
-+ ret = adm_slave_config(achan, (struct dma_slave_config *)arg);
-+ spin_unlock_irqrestore(&achan->vc.lock, flag);
-+ break;
-+
-+ case DMA_TERMINATE_ALL:
-+ adm_terminate_all(achan);
-+ break;
-+
-+ default:
-+ ret = -ENXIO;
-+ break;
-+ };
-+
-+ return ret;
-+}
-+
-+/**
-+ * adm_start_dma - start next transaction
-+ * @achan - ADM dma channel
-+ */
-+static void adm_start_dma(struct adm_chan *achan)
-+{
-+ struct virt_dma_desc *vd = vchan_next_desc(&achan->vc);
-+ struct adm_device *adev = achan->adev;
-+ struct adm_async_desc *async_desc;
-+ struct adm_desc_hw *desc;
-+ struct adm_cmd_ptr_list *cpl;
-+
-+ lockdep_assert_held(&achan->vc.lock);
-+
-+ if (!vd)
-+ return;
-+
-+ list_del(&vd->node);
-+
-+ /* write next command list out to the CMD FIFO */
-+ async_desc = container_of(vd, struct adm_async_desc, vd);
-+ achan->curr_txd = async_desc;
-+
-+ cpl = PTR_ALIGN(async_desc->cpl, ADM_DESC_ALIGN);
-+ desc = PTR_ALIGN(&cpl->desc[0], ADM_DESC_ALIGN);
-+
-+ if (!achan->initialized) {
-+ /* enable interrupts */
-+ writel(CH_CONF_IRQ_EN | CH_CONF_FLUSH_RSLT_EN |
-+ CH_CONF_FORCE_RSLT_EN | CH_CONF_PERM_MPU_CONF |
-+ CH_CONF_MPU_DISABLE,
-+ adev->regs + HI_CH_CONF(achan->id));
-+
-+ writel(CH_RSLT_CONF_IRQ_EN | CH_RSLT_CONF_FLUSH_EN,
-+ adev->regs + HI_CH_RSLT_CONF(achan->id, adev->ee));
-+
-+ if (achan->crci)
-+ writel(achan->blk_size, adev->regs +
-+ HI_CRCI_CTL(achan->crci, adev->ee));
-+
-+ achan->initialized = 1;
-+ }
-+
-+ /* make sure IRQ enable doesn't get reordered */
-+ wmb();
-+
-+ /* write next command list out to the CMD FIFO */
-+ writel(round_up(async_desc->dma_addr, ADM_DESC_ALIGN) >> 3,
-+ adev->regs + HI_CH_CMD_PTR(achan->id, adev->ee));
-+}
-+
-+/**
-+ * adm_dma_irq - irq handler for ADM controller
-+ * @irq: IRQ of interrupt
-+ * @data: callback data
-+ *
-+ * IRQ handler for the bam controller
-+ */
-+static irqreturn_t adm_dma_irq(int irq, void *data)
-+{
-+ struct adm_device *adev = data;
-+ u32 srcs, i;
-+ struct adm_async_desc *async_desc;
-+ unsigned long flags;
-+
-+ srcs = readl_relaxed(adev->regs +
-+ HI_SEC_DOMAIN_IRQ_STATUS(adev->ee));
-+
-+ for (i = 0; i < 16; i++) {
-+ struct adm_chan *achan = &adev->channels[i];
-+ u32 status, result;
-+ if (srcs & BIT(i)) {
-+ status = readl_relaxed(adev->regs +
-+ HI_CH_STATUS_SD(i, adev->ee));
-+
-+ /* if no result present, skip */
-+ if (!(status & CH_STATUS_VALID))
-+ continue;
-+
-+ result = readl_relaxed(adev->regs +
-+ HI_CH_RSLT(i, adev->ee));
-+
-+ /* no valid results, skip */
-+ if (!(result & CH_RSLT_VALID))
-+ continue;
-+
-+ /* flag error if transaction was flushed or failed */
-+ if (result & (CH_RSLT_ERR | CH_RSLT_FLUSH))
-+ achan->error = 1;
-+
-+ spin_lock_irqsave(&achan->vc.lock, flags);
-+ async_desc = achan->curr_txd;
-+
-+ achan->curr_txd = NULL;
-+
-+ if (async_desc) {
-+ vchan_cookie_complete(&async_desc->vd);
-+
-+ /* kick off next DMA */
-+ adm_start_dma(achan);
-+ }
-+
-+ spin_unlock_irqrestore(&achan->vc.lock, flags);
-+ }
-+ }
-+
-+ return IRQ_HANDLED;
-+}
-+
-+/**
-+ * adm_tx_status - returns status of transaction
-+ * @chan: dma channel
-+ * @cookie: transaction cookie
-+ * @txstate: DMA transaction state
-+ *
-+ * Return status of dma transaction
-+ */
-+static enum dma_status adm_tx_status(struct dma_chan *chan, dma_cookie_t cookie,
-+ struct dma_tx_state *txstate)
-+{
-+ struct adm_chan *achan = to_adm_chan(chan);
-+ struct virt_dma_desc *vd;
-+ enum dma_status ret;
-+ unsigned long flags;
-+ size_t residue = 0;
-+
-+ ret = dma_cookie_status(chan, cookie, txstate);
-+
-+ spin_lock_irqsave(&achan->vc.lock, flags);
-+
-+ vd = vchan_find_desc(&achan->vc, cookie);
-+ if (vd)
-+ residue = container_of(vd, struct adm_async_desc, vd)->length;
-+ else if (achan->curr_txd && achan->curr_txd->vd.tx.cookie == cookie)
-+ residue = achan->curr_txd->length;
-+
-+ spin_unlock_irqrestore(&achan->vc.lock, flags);
-+
-+ dma_set_residue(txstate, residue);
-+
-+ if (achan->error)
-+ return DMA_ERROR;
-+
-+ return ret;
-+}
-+
-+static struct dma_chan *adm_dma_xlate(struct of_phandle_args *dma_spec,
-+ struct of_dma *of)
-+{
-+ struct adm_device *adev = container_of(of->of_dma_data,
-+ struct adm_device, common);
-+ struct adm_chan *achan;
-+ struct dma_chan *chan;
-+ unsigned int request;
-+ unsigned int crci;
-+
-+ if (dma_spec->args_count != 2) {
-+ dev_err(adev->dev, "incorrect number of dma arguments\n");
-+ return NULL;
-+ }
-+
-+ request = dma_spec->args[0];
-+ if (request >= adev->num_channels)
-+ return NULL;
-+
-+ crci = dma_spec->args[1];
-+
-+ chan = dma_get_slave_channel(&(adev->channels[request].vc.chan));
-+
-+ if (!chan)
-+ return NULL;
-+
-+ achan = to_adm_chan(chan);
-+ achan->crci = crci;
-+
-+ return chan;
-+}
-+
-+/**
-+ * adm_issue_pending - starts pending transactions
-+ * @chan: dma channel
-+ *
-+ * Issues all pending transactions and starts DMA
-+ */
-+static void adm_issue_pending(struct dma_chan *chan)
-+{
-+ struct adm_chan *achan = to_adm_chan(chan);
-+ unsigned long flags;
-+
-+ spin_lock_irqsave(&achan->vc.lock, flags);
-+
-+ if (vchan_issue_pending(&achan->vc) && !achan->curr_txd)
-+ adm_start_dma(achan);
-+ spin_unlock_irqrestore(&achan->vc.lock, flags);
-+}
-+
-+/**
-+ * adm_dma_free_desc - free descriptor memory
-+ * @vd: virtual descriptor
-+ *
-+ */
-+static void adm_dma_free_desc(struct virt_dma_desc *vd)
-+{
-+ struct adm_async_desc *async_desc = container_of(vd,
-+ struct adm_async_desc, vd);
-+
-+ dma_free_writecombine(async_desc->adev->dev, async_desc->dma_len,
-+ async_desc->cpl, async_desc->dma_addr);
-+ kfree(async_desc);
-+}
-+
-+static void adm_channel_init(struct adm_device *adev, struct adm_chan *achan,
-+ u32 index)
-+{
-+ achan->id = index;
-+ achan->adev = adev;
-+
-+ vchan_init(&achan->vc, &adev->common);
-+ achan->vc.desc_free = adm_dma_free_desc;
-+}
-+
-+static int adm_dma_probe(struct platform_device *pdev)
-+{
-+ struct adm_device *adev;
-+ struct resource *iores;
-+ int ret;
-+ u32 i;
-+
-+ adev = devm_kzalloc(&pdev->dev, sizeof(*adev), GFP_KERNEL);
-+ if (!adev)
-+ return -ENOMEM;
-+
-+ adev->dev = &pdev->dev;
-+
-+ iores = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-+ adev->regs = devm_ioremap_resource(&pdev->dev, iores);
-+ if (IS_ERR(adev->regs))
-+ return PTR_ERR(adev->regs);
-+
-+ adev->irq = platform_get_irq(pdev, 0);
-+ if (adev->irq < 0)
-+ return adev->irq;
-+
-+ ret = of_property_read_u32(pdev->dev.of_node, "qcom,ee", &adev->ee);
-+ if (ret) {
-+ dev_err(adev->dev, "Execution environment unspecified\n");
-+ return ret;
-+ }
-+
-+ adev->core_clk = devm_clk_get(adev->dev, "core");
-+ if (IS_ERR(adev->core_clk))
-+ return PTR_ERR(adev->core_clk);
-+
-+ ret = clk_prepare_enable(adev->core_clk);
-+ if (ret) {
-+ dev_err(adev->dev, "failed to prepare/enable core clock\n");
-+ return ret;
-+ }
-+
-+ adev->iface_clk = devm_clk_get(adev->dev, "iface");
-+ if (IS_ERR(adev->iface_clk))
-+ return PTR_ERR(adev->iface_clk);
-+
-+ ret = clk_prepare_enable(adev->iface_clk);
-+ if (ret) {
-+ dev_err(adev->dev, "failed to prepare/enable iface clock\n");
-+ return ret;
-+ }
-+
-+ adev->clk_reset = devm_reset_control_get(&pdev->dev, "clk");
-+ if (IS_ERR(adev->clk_reset)) {
-+ dev_err(adev->dev, "failed to get ADM0 reset\n");
-+ return PTR_ERR(adev->clk_reset);
-+ }
-+
-+ adev->c0_reset = devm_reset_control_get(&pdev->dev, "c0");
-+ if (IS_ERR(adev->c0_reset)) {
-+ dev_err(adev->dev, "failed to get ADM0 C0 reset\n");
-+ return PTR_ERR(adev->c0_reset);
-+ }
-+
-+ adev->c1_reset = devm_reset_control_get(&pdev->dev, "c1");
-+ if (IS_ERR(adev->c1_reset)) {
-+ dev_err(adev->dev, "failed to get ADM0 C1 reset\n");
-+ return PTR_ERR(adev->c1_reset);
-+ }
-+
-+ adev->c2_reset = devm_reset_control_get(&pdev->dev, "c2");
-+ if (IS_ERR(adev->c2_reset)) {
-+ dev_err(adev->dev, "failed to get ADM0 C2 reset\n");
-+ return PTR_ERR(adev->c2_reset);
-+ }
-+
-+ reset_control_assert(adev->clk_reset);
-+ reset_control_assert(adev->c0_reset);
-+ reset_control_assert(adev->c1_reset);
-+ reset_control_assert(adev->c2_reset);
-+
-+ reset_control_deassert(adev->clk_reset);
-+ reset_control_deassert(adev->c0_reset);
-+ reset_control_deassert(adev->c1_reset);
-+ reset_control_deassert(adev->c2_reset);
-+
-+ adev->num_channels = 16;
-+
-+ adev->channels = devm_kcalloc(adev->dev, adev->num_channels,
-+ sizeof(*adev->channels), GFP_KERNEL);
-+
-+ if (!adev->channels) {
-+ ret = -ENOMEM;
-+ goto err_disable_clk;
-+ }
-+
-+ /* allocate and initialize channels */
-+ INIT_LIST_HEAD(&adev->common.channels);
-+
-+ for (i = 0; i < adev->num_channels; i++)
-+ adm_channel_init(adev, &adev->channels[i], i);
-+
-+ /* reset CRCIs */
-+ for (i = 0; i < 16; i++)
-+ writel(CRCI_CTL_RST, adev->regs + HI_CRCI_CTL(i, adev->ee));
-+
-+ /* configure client interfaces */
-+ writel(CI_RANGE_START(0x40) | CI_RANGE_END(0xb0) | CI_BURST_8_WORDS,
-+ adev->regs + HI_CI_CONF(0));
-+ writel(CI_RANGE_START(0x2a) | CI_RANGE_END(0x2c) | CI_BURST_8_WORDS,
-+ adev->regs + HI_CI_CONF(1));
-+ writel(CI_RANGE_START(0x12) | CI_RANGE_END(0x28) | CI_BURST_8_WORDS,
-+ adev->regs + HI_CI_CONF(2));
-+ writel(GP_CTL_LP_EN | GP_CTL_LP_CNT(0xf), adev->regs + HI_GP_CTL);
-+
-+ ret = devm_request_irq(adev->dev, adev->irq, adm_dma_irq,
-+ 0, "adm_dma", adev);
-+ if (ret)
-+ goto err_disable_clk;
-+
-+ platform_set_drvdata(pdev, adev);
-+
-+ adev->common.dev = adev->dev;
-+ adev->common.dev->dma_parms = &adev->dma_parms;
-+
-+ /* set capabilities */
-+ dma_cap_zero(adev->common.cap_mask);
-+ dma_cap_set(DMA_SLAVE, adev->common.cap_mask);
-+ dma_cap_set(DMA_PRIVATE, adev->common.cap_mask);
-+
-+ /* initialize dmaengine apis */
-+ adev->common.device_alloc_chan_resources = adm_alloc_chan;
-+ adev->common.device_free_chan_resources = adm_free_chan;
-+ adev->common.device_prep_slave_sg = adm_prep_slave_sg;
-+ adev->common.device_control = adm_control;
-+ adev->common.device_issue_pending = adm_issue_pending;
-+ adev->common.device_tx_status = adm_tx_status;
-+
-+ ret = dma_async_device_register(&adev->common);
-+ if (ret) {
-+ dev_err(adev->dev, "failed to register dma async device\n");
-+ goto err_disable_clk;
-+ }
-+
-+ ret = of_dma_controller_register(pdev->dev.of_node, adm_dma_xlate,
-+ &adev->common);
-+ if (ret)
-+ goto err_unregister_dma;
-+
-+ return 0;
-+
-+err_unregister_dma:
-+ dma_async_device_unregister(&adev->common);
-+err_disable_clk:
-+ clk_disable_unprepare(adev->core_clk);
-+ clk_disable_unprepare(adev->iface_clk);
-+
-+ return ret;
-+}
-+
-+static int adm_dma_remove(struct platform_device *pdev)
-+{
-+ struct adm_device *adev = platform_get_drvdata(pdev);
-+ struct adm_chan *achan;
-+ u32 i;
-+
-+ of_dma_controller_free(pdev->dev.of_node);
-+ dma_async_device_unregister(&adev->common);
-+
-+ devm_free_irq(adev->dev, adev->irq, adev);
-+
-+ for (i = 0; i < adev->num_channels; i++) {
-+ achan = &adev->channels[i];
-+ writel(CH_CONF_FLUSH_RSLT_EN,
-+ adev->regs + HI_CH_CONF(achan->id));
-+ writel(CH_RSLT_CONF_FLUSH_EN,
-+ adev->regs + HI_CH_RSLT_CONF(achan->id, adev->ee));
-+
-+ adm_terminate_all(&adev->channels[i]);
-+ }
-+
-+ clk_disable_unprepare(adev->core_clk);
-+ clk_disable_unprepare(adev->iface_clk);
-+
-+ return 0;
-+}
-+
-+static const struct of_device_id adm_of_match[] = {
-+ { .compatible = "qcom,adm", },
-+ {}
-+};
-+MODULE_DEVICE_TABLE(of, adm_of_match);
-+
-+static struct platform_driver adm_dma_driver = {
-+ .probe = adm_dma_probe,
-+ .remove = adm_dma_remove,
-+ .driver = {
-+ .name = "adm-dma-engine",
-+ .owner = THIS_MODULE,
-+ .of_match_table = adm_of_match,
-+ },
-+};
-+
-+module_platform_driver(adm_dma_driver);
-+
-+MODULE_AUTHOR("Andy Gross <agross@codeaurora.org>");
-+MODULE_DESCRIPTION("QCOM ADM DMA engine driver");
-+MODULE_LICENSE("GPL v2");
diff --git a/target/linux/ipq806x/patches/0178-dmaengine-qcom_adm-Add-device-tree-binding.patch b/target/linux/ipq806x/patches/0178-dmaengine-qcom_adm-Add-device-tree-binding.patch
deleted file mode 100644
index 1c72a2f..0000000
--- a/target/linux/ipq806x/patches/0178-dmaengine-qcom_adm-Add-device-tree-binding.patch
+++ /dev/null
@@ -1,76 +0,0 @@
-From 331294fa5c703536e27b79e9c112d162393f725a Mon Sep 17 00:00:00 2001
-From: Andy Gross <agross@codeaurora.org>
-Date: Thu, 26 Jun 2014 13:55:10 -0500
-Subject: [PATCH 178/182] dmaengine: qcom_adm: Add device tree binding
-
-Add device tree binding support for the QCOM ADM DMA driver.
-
-Signed-off-by: Andy Gross <agross@codeaurora.org>
----
- Documentation/devicetree/bindings/dma/qcom_adm.txt | 60 ++++++++++++++++++++
- 1 file changed, 60 insertions(+)
- create mode 100644 Documentation/devicetree/bindings/dma/qcom_adm.txt
-
---- /dev/null
-+++ b/Documentation/devicetree/bindings/dma/qcom_adm.txt
-@@ -0,0 +1,60 @@
-+QCOM ADM DMA Controller
-+
-+Required properties:
-+- compatible: must contain "qcom,adm" for IPQ/APQ8064 and MSM8960
-+- reg: Address range for DMA registers
-+- interrupts: Should contain one interrupt shared by all channels
-+- #dma-cells: must be <2>. First cell denotes the channel number. Second cell
-+ denotes CRCI (client rate control interface) flow control assignment.
-+- clocks: Should contain the core clock and interface clock.
-+- clock-names: Must contain "core" for the core clock and "iface" for the
-+ interface clock.
-+- resets: Must contain an entry for each entry in reset names.
-+- reset-names: Must include the following entries:
-+ - clk
-+ - c0
-+ - c1
-+ - c2
-+- qcom,ee: indicates the security domain identifier used in the secure world.
-+
-+Example:
-+ adm_dma: dma@18300000 {
-+ compatible = "qcom,adm";
-+ reg = <0x18300000 0x100000>;
-+ interrupts = <0 170 0>;
-+ #dma-cells = <2>;
-+
-+ clocks = <&gcc ADM0_CLK>, <&gcc ADM0_PBUS_CLK>;
-+ clock-names = "core", "iface";
-+
-+ resets = <&gcc ADM0_RESET>,
-+ <&gcc ADM0_C0_RESET>,
-+ <&gcc ADM0_C1_RESET>,
-+ <&gcc ADM0_C2_RESET>;
-+ reset-names = "clk", "c0", "c1", "c2";
-+ qcom,ee = <0>;
-+ };
-+
-+DMA clients must use the format descripted in the dma.txt file, using a three
-+cell specifier for each channel.
-+
-+Each dmas request consists of 3 cells:
-+ 1. phandle pointing to the DMA controller
-+ 2. channel number
-+ 3. CRCI assignment, if applicable. If no CRCI flow control is required, use 0.
-+
-+Example:
-+
-+ spi4: spi@1a280000 {
-+ status = "ok";
-+ spi-max-frequency = <50000000>;
-+
-+ pinctrl-0 = <&spi_pins>;
-+ pinctrl-names = "default";
-+
-+ cs-gpios = <&qcom_pinmux 20 0>;
-+
-+ dmas = <&adm_dma 6 9>,
-+ <&adm_dma 5 10>;
-+ dma-names = "rx", "tx";
-+ };
diff --git a/target/linux/ipq806x/patches/0180-ARM-dts-Add-ADM-DMA-nodes-and-SPI-linkage.patch b/target/linux/ipq806x/patches/0180-ARM-dts-Add-ADM-DMA-nodes-and-SPI-linkage.patch
deleted file mode 100644
index 05279de..0000000
--- a/target/linux/ipq806x/patches/0180-ARM-dts-Add-ADM-DMA-nodes-and-SPI-linkage.patch
+++ /dev/null
@@ -1,83 +0,0 @@
-From c78ae23b6c174c9f2e0973a247942b6b4adb7e82 Mon Sep 17 00:00:00 2001
-From: Andy Gross <agross@codeaurora.org>
-Date: Thu, 26 Jun 2014 13:02:59 -0500
-Subject: [PATCH 180/182] ARM: dts: Add ADM DMA nodes and SPI linkage
-
-This patch adds the ADM DMA controller DT nodes and also enables the use of dma
-in SPI.
-
-Signed-off-by: Andy Gross <agross@codeaurora.org>
----
- arch/arm/boot/dts/qcom-ipq8064-ap148.dts | 11 +++++++++++
- arch/arm/boot/dts/qcom-ipq8064.dtsi | 8 +++++---
- 2 files changed, 16 insertions(+), 3 deletions(-)
-
---- a/arch/arm/boot/dts/qcom-ipq8064-ap148.dts
-+++ b/arch/arm/boot/dts/qcom-ipq8064-ap148.dts
-@@ -44,6 +44,10 @@
- drive-strength = <10>;
- bias-none;
- };
-+ cs {
-+ pins = "gpio20";
-+ drive-strength = <12>;
-+ };
- };
- nand_pins: nand_pins {
- mux {
-@@ -100,12 +104,17 @@
-
- cs-gpios = <&qcom_pinmux 20 0>;
-
-+ dmas = <&adm_dma 6 9>,
-+ <&adm_dma 5 10>;
-+ dma-names = "rx", "tx";
-+
- flash: m25p80@0 {
- compatible = "s25fl256s1";
- #address-cells = <1>;
- #size-cells = <1>;
- spi-max-frequency = <50000000>;
- reg = <0>;
-+ m25p,fast-read;
-
- partition@0 {
- label = "rootfs";
-@@ -140,8 +149,10 @@
- ranges = <0x00000000 0 0x00000000 0x31f00000 0 0x00100000 /* configuration space */
- 0x81000000 0 0 0x31e00000 0 0x00100000 /* downstream I/O */
- 0x82000000 0 0x00000000 0x2e000000 0 0x03e00000>; /* non-prefetchable memory */
-+
- };
-
-+
- sata-phy@1b400000 {
- status = "ok";
- };
---- a/arch/arm/boot/dts/qcom-ipq8064.dtsi
-+++ b/arch/arm/boot/dts/qcom-ipq8064.dtsi
-@@ -421,19 +421,21 @@
- compatible = "qcom,adm";
- reg = <0x18300000 0x100000>;
- interrupts = <0 170 0>;
-+ #dma-cells = <2>;
-
- clocks = <&gcc ADM0_CLK>, <&gcc ADM0_PBUS_CLK>;
-- clock-names = "core_clk", "iface_clk";
-+ clock-names = "core", "iface";
-
- resets = <&gcc ADM0_RESET>,
- <&gcc ADM0_PBUS_RESET>,
- <&gcc ADM0_C0_RESET>,
- <&gcc ADM0_C1_RESET>,
- <&gcc ADM0_C2_RESET>;
--
-- reset-names = "adm", "pbus", "c0", "c1", "c2";
-+ reset-names = "clk", "pbus", "c0", "c1", "c2";
-+ qcom,ee = <0>;
-
- status = "disabled";
-+
- };
-
- nand@0x1ac00000 {
diff --git a/target/linux/ipq806x/patches/0181-mtd-nand-qcom-Align-clk-and-reset-names.patch b/target/linux/ipq806x/patches/0181-mtd-nand-qcom-Align-clk-and-reset-names.patch
deleted file mode 100644
index e2e313c..0000000
--- a/target/linux/ipq806x/patches/0181-mtd-nand-qcom-Align-clk-and-reset-names.patch
+++ /dev/null
@@ -1,41 +0,0 @@
-From ae0e9ee3bcfafc5bd5932b544e0a5c107948fc97 Mon Sep 17 00:00:00 2001
-From: Andy Gross <agross@codeaurora.org>
-Date: Mon, 30 Jun 2014 21:17:26 -0500
-Subject: [PATCH 181/182] mtd: nand: qcom: Align clk and reset names
-
-This patch aligns the clk and reset names to the same ones that the dmaengine
-driver uses.
-
-Signed-off-by: Andy Gross <agross@codeaurora.org>
----
- drivers/mtd/nand/qcom_adm_dma.c | 6 +++---
- 1 file changed, 3 insertions(+), 3 deletions(-)
-
---- a/drivers/mtd/nand/qcom_adm_dma.c
-+++ b/drivers/mtd/nand/qcom_adm_dma.c
-@@ -568,14 +568,14 @@ static int msm_dmov_init_clocks(struct p
- int adm = (pdev->id >= 0) ? pdev->id : 0;
- int ret;
-
-- dmov_conf[adm].clk = devm_clk_get(&pdev->dev, "core_clk");
-+ dmov_conf[adm].clk = devm_clk_get(&pdev->dev, "core");
- if (IS_ERR(dmov_conf[adm].clk)) {
- printk(KERN_ERR "%s: Error getting adm_clk\n", __func__);
- dmov_conf[adm].clk = NULL;
- return -ENOENT;
- }
-
-- dmov_conf[adm].pclk = devm_clk_get(&pdev->dev, "iface_clk");
-+ dmov_conf[adm].pclk = devm_clk_get(&pdev->dev, "iface");
- if (IS_ERR(dmov_conf[adm].pclk)) {
- dmov_conf[adm].pclk = NULL;
- /* pclk not present on all SoCs, don't bail on failure */
-@@ -690,7 +690,7 @@ static int msm_dmov_probe(struct platfor
- }
-
- /* get resets */
-- dmov_conf[adm].adm_reset = devm_reset_control_get(&pdev->dev, "adm");
-+ dmov_conf[adm].adm_reset = devm_reset_control_get(&pdev->dev, "clk");
- if (IS_ERR(dmov_conf[adm].adm_reset)) {
- dev_err(&pdev->dev, "failed to get adm reset\n");
- ret = PTR_ERR(dmov_conf[adm].adm_reset);
diff --git a/target/linux/ipq806x/patches/0182-qcom-Kconfig-Make-drivers-mutually-exclusive.patch b/target/linux/ipq806x/patches/0182-qcom-Kconfig-Make-drivers-mutually-exclusive.patch
deleted file mode 100644
index f4b551b..0000000
--- a/target/linux/ipq806x/patches/0182-qcom-Kconfig-Make-drivers-mutually-exclusive.patch
+++ /dev/null
@@ -1,47 +0,0 @@
-From 0771849495b4128cac2faf7d49c85c729fc48b20 Mon Sep 17 00:00:00 2001
-From: Andy Gross <agross@codeaurora.org>
-Date: Mon, 30 Jun 2014 21:18:39 -0500
-Subject: [PATCH 182/182] qcom: Kconfig: Make drivers mutually exclusive
-
-This patch makes sure QCOM ADM dmaengine and QCOM Nand cannot be enabled at the
-same time. This is an issue because the dma drivers will conflict with one
-another.
-
-Signed-off-by: Andy Gross <agross@codeaurora.org>
----
- drivers/dma/Kconfig | 2 +-
- drivers/mtd/nand/Kconfig | 6 +++---
- 2 files changed, 4 insertions(+), 4 deletions(-)
-
---- a/drivers/dma/Kconfig
-+++ b/drivers/dma/Kconfig
-@@ -412,7 +412,7 @@ config QCOM_BAM_DMA
-
- config QCOM_ADM
- tristate "Qualcomm ADM support"
-- depends on ARCH_QCOM || (COMPILE_TEST && OF && ARM)
-+ depends on !MTD_QCOM_ADM && (ARCH_QCOM || (COMPILE_TEST && OF && ARM))
- select DMA_ENGINE
- select DMA_VIRTUAL_CHANNELS
- ---help---
---- a/drivers/mtd/nand/Kconfig
-+++ b/drivers/mtd/nand/Kconfig
-@@ -511,15 +511,15 @@ config MTD_NAND_XWAY
- to the External Bus Unit (EBU).
-
- config MTD_QCOM_DMA
-- tristate "QCMO NAND DMA Support"
-- depends on ARCH_QCOM && MTD_QCOM_NAND
-+ tristate "QCOM NAND DMA Support"
-+ depends on !QCOM_ADM && ARCH_QCOM && MTD_QCOM_NAND
- default n
- help
- DMA support for QCOM NAND
-
- config MTD_QCOM_NAND
- tristate "QCOM NAND Device Support"
-- depends on MTD && ARCH_QCOM
-+ depends on MTD && ARCH_QCOM && !QCOM_ADM
- select CRC16
- select BITREVERSE
- select MTD_NAND_IDS