ipq806x: Add support for IPQ806x chip family
authorJohn Crispin <john@openwrt.org>
Sat, 30 Aug 2014 09:32:58 +0000 (09:32 +0000)
committerJohn Crispin <john@openwrt.org>
Sat, 30 Aug 2014 09:32:58 +0000 (09:32 +0000)
Patches are generated using the "format-patch" command from the
following location:
*https://www.codeaurora.org/cgit/quic/kernel/galak-msm/log/?h=apq_ipq_base
*rev=0771849495b4128cac2faf7d49c85c729fc48b20
Patches numbered 76/77/102/103 have already been integrated in 3.14.12,
so they're not in this list.

All these patches are either integrated are pending integration into
kernel.org, therefore these patches should go away once the kernel
gets upgraded to 3.16.

Support is currently limited to AP148 board but can be extended to other
platforms in the future.

These changes do not cover ethernet connectivity.

Signed-off-by: Mathieu Olivari <mathieu@codeaurora.org>
SVN-Revision: 42334

186 files changed:
target/linux/ipq806x/Makefile [new file with mode: 0644]
target/linux/ipq806x/base-files.mk [new file with mode: 0644]
target/linux/ipq806x/base-files/etc/inittab [new file with mode: 0644]
target/linux/ipq806x/base-files/lib/ipq806x.sh [new file with mode: 0644]
target/linux/ipq806x/base-files/lib/preinit/03_preinit_do_ipq806x.sh [new file with mode: 0644]
target/linux/ipq806x/config-3.14 [new file with mode: 0644]
target/linux/ipq806x/image/Makefile [new file with mode: 0644]
target/linux/ipq806x/patches/0001-ARM-dts-msm-split-out-msm8660-and-msm8960-soc-into-d.patch [new file with mode: 0644]
target/linux/ipq806x/patches/0002-ARM-msm-Remove-pen_release-usage.patch [new file with mode: 0644]
target/linux/ipq806x/patches/0003-ARM-msm-kill-off-hotplug.c.patch [new file with mode: 0644]
target/linux/ipq806x/patches/0004-clocksource-qcom-Move-clocksource-code-out-of-mach-m.patch [new file with mode: 0644]
target/linux/ipq806x/patches/0005-ARM-qcom-Split-Qualcomm-support-into-legacy-and-mult.patch [new file with mode: 0644]
target/linux/ipq806x/patches/0006-clocksource-qcom-split-building-of-legacy-vs-multipl.patch [new file with mode: 0644]
target/linux/ipq806x/patches/0007-ARM-qcom-Rename-various-msm-prefixed-functions-to-qc.patch [new file with mode: 0644]
target/linux/ipq806x/patches/0008-ARM-Introduce-CPU_METHOD_OF_DECLARE-for-cpu-hotplug-.patch [new file with mode: 0644]
target/linux/ipq806x/patches/0009-ARM-qcom-Re-organize-platsmp-to-make-it-extensible.patch [new file with mode: 0644]
target/linux/ipq806x/patches/0010-devicetree-bindings-Document-Krait-Scorpion-cpus-and.patch [new file with mode: 0644]
target/linux/ipq806x/patches/0011-devicetree-bindings-Document-qcom-kpss-acc.patch [new file with mode: 0644]
target/linux/ipq806x/patches/0012-devicetree-bindings-Document-qcom-saw2-node.patch [new file with mode: 0644]
target/linux/ipq806x/patches/0013-ARM-qcom-Add-SMP-support-for-KPSSv1.patch [new file with mode: 0644]
target/linux/ipq806x/patches/0014-ARM-qcom-Add-SMP-support-for-KPSSv2.patch [new file with mode: 0644]
target/linux/ipq806x/patches/0015-tty-serial-msm-Enable-building-msm_serial-for-ARCH_Q.patch [new file with mode: 0644]
target/linux/ipq806x/patches/0016-drm-msm-drop-ARCH_MSM-Kconfig-depend.patch [new file with mode: 0644]
target/linux/ipq806x/patches/0017-power-reset-msm-switch-Kconfig-to-ARCH_QCOM-depends.patch [new file with mode: 0644]
target/linux/ipq806x/patches/0018-hwrng-msm-switch-Kconfig-to-ARCH_QCOM-depends.patch [new file with mode: 0644]
target/linux/ipq806x/patches/0019-gpio-msm-switch-Kconfig-to-ARCH_QCOM-depends.patch [new file with mode: 0644]
target/linux/ipq806x/patches/0020-ARM-qcom-Enable-basic-support-for-Qualcomm-platforms.patch [new file with mode: 0644]
target/linux/ipq806x/patches/0021-ARM-dts-qcom-Add-nodes-necessary-for-SMP-boot.patch [new file with mode: 0644]
target/linux/ipq806x/patches/0022-ARM-dts-qcom-Add-RNG-device-tree-node.patch [new file with mode: 0644]
target/linux/ipq806x/patches/0023-ARM-dts-qcom-msm8960-cdp-Add-RNG-device-tree-node.patch [new file with mode: 0644]
target/linux/ipq806x/patches/0024-ARM-dts-msm-Add-krait-pmu-to-platforms-with-Krait-CP.patch [new file with mode: 0644]
target/linux/ipq806x/patches/0025-pinctrl-msm-drop-wake_irqs-bitmap.patch [new file with mode: 0644]
target/linux/ipq806x/patches/0026-pinctrl-msm-Silence-recursive-lockdep-warning.patch [new file with mode: 0644]
target/linux/ipq806x/patches/0027-pinctrl-msm-Check-for-ngpios-MAX_NR_GPIO.patch [new file with mode: 0644]
target/linux/ipq806x/patches/0028-pinctrl-msm-Drop-unused-includes.patch [new file with mode: 0644]
target/linux/ipq806x/patches/0029-pinctrl-msm-Drop-OF_IRQ-dependency.patch [new file with mode: 0644]
target/linux/ipq806x/patches/0030-pinctrl-msm-Replace-lookup-tables-with-math.patch [new file with mode: 0644]
target/linux/ipq806x/patches/0031-pinctrl-msm-Remove-impossible-WARN_ON-s.patch [new file with mode: 0644]
target/linux/ipq806x/patches/0032-pinctrl-msm-Simplify-msm_config_reg-and-callers.patch [new file with mode: 0644]
target/linux/ipq806x/patches/0033-pinctrl-msm-Support-output-high-low-configuration.patch [new file with mode: 0644]
target/linux/ipq806x/patches/0034-pinctrl-msm-Add-SPI8-pin-definitions.patch [new file with mode: 0644]
target/linux/ipq806x/patches/0035-pinctrl-msm-fix-up-out-of-order-merge-conflict.patch [new file with mode: 0644]
target/linux/ipq806x/patches/0036-pinctrl-msm-Correct-interrupt-code-for-TLMM-v2.patch [new file with mode: 0644]
target/linux/ipq806x/patches/0037-pinctrl-msm-Make-number-of-functions-variable.patch [new file with mode: 0644]
target/linux/ipq806x/patches/0038-pinctrl-msm-Add-definitions-for-the-APQ8064-platform.patch [new file with mode: 0644]
target/linux/ipq806x/patches/0039-pinctrl-msm8x74-make-Kconfig-dependency-more-strict.patch [new file with mode: 0644]
target/linux/ipq806x/patches/0040-pinctrl-qcom-Add-definitions-for-IPQ8064.patch [new file with mode: 0644]
target/linux/ipq806x/patches/0041-dt-Document-Qualcomm-IPQ8064-pinctrl-binding.patch [new file with mode: 0644]
target/linux/ipq806x/patches/0042-ARM-qcom-Select-PINCTRL-by-default-for-ARCH_QCOM.patch [new file with mode: 0644]
target/linux/ipq806x/patches/0043-pinctrl-qcom-Correct-name-for-pin-0.patch [new file with mode: 0644]
target/linux/ipq806x/patches/0044-dmaengine-qcom_bam_dma-Add-device-tree-binding.patch [new file with mode: 0644]
target/linux/ipq806x/patches/0045-dmaengine-add-Qualcomm-BAM-dma-driver.patch [new file with mode: 0644]
target/linux/ipq806x/patches/0046-mmc-sdhci-msm-Qualcomm-SDHCI-binding-documentation.patch [new file with mode: 0644]
target/linux/ipq806x/patches/0047-mmc-sdhci-msm-Initial-support-for-Qualcomm-chipsets.patch [new file with mode: 0644]
target/linux/ipq806x/patches/0048-mmc-sdhci-msm-Add-platform_execute_tuning-implementa.patch [new file with mode: 0644]
target/linux/ipq806x/patches/0049-drivers-of-add-initialization-code-for-static-reserv.patch [new file with mode: 0644]
target/linux/ipq806x/patches/0050-drivers-of-add-initialization-code-for-dynamic-reser.patch [new file with mode: 0644]
target/linux/ipq806x/patches/0051-drivers-of-add-support-for-custom-reserved-memory-dr.patch [new file with mode: 0644]
target/linux/ipq806x/patches/0052-arm-add-support-for-reserved-memory-defined-by-devic.patch [new file with mode: 0644]
target/linux/ipq806x/patches/0053-of-document-bindings-for-reserved-memory-nodes.patch [new file with mode: 0644]
target/linux/ipq806x/patches/0054-of-only-scan-for-reserved-mem-when-fdt-present.patch [new file with mode: 0644]
target/linux/ipq806x/patches/0055-spmi-Linux-driver-framework-for-SPMI.patch [new file with mode: 0644]
target/linux/ipq806x/patches/0056-spmi-Add-MSM-PMIC-Arbiter-SPMI-controller.patch [new file with mode: 0644]
target/linux/ipq806x/patches/0057-spmi-pmic_arb-add-support-for-interrupt-handling.patch [new file with mode: 0644]
target/linux/ipq806x/patches/0058-spmi-pmic_arb-make-selectable-on-ARCH_QCOM.patch [new file with mode: 0644]
target/linux/ipq806x/patches/0059-spmi-pm-drop-bus-level-PM-suspend-resume-routines.patch [new file with mode: 0644]
target/linux/ipq806x/patches/0060-i2c-qup-New-bus-driver-for-the-Qualcomm-QUP-I2C-cont.patch [new file with mode: 0644]
target/linux/ipq806x/patches/0061-i2c-qup-Add-device-tree-bindings-information.patch [new file with mode: 0644]
target/linux/ipq806x/patches/0062-i2c-qup-off-by-ones-in-qup_i2c_probe.patch [new file with mode: 0644]
target/linux/ipq806x/patches/0063-i2c-qup-use-proper-type-fro-clk_freq.patch [new file with mode: 0644]
target/linux/ipq806x/patches/0064-i2c-qup-Fix-pm_runtime_get_sync-usage.patch [new file with mode: 0644]
target/linux/ipq806x/patches/0065-spi-Add-Qualcomm-QUP-SPI-controller-support.patch [new file with mode: 0644]
target/linux/ipq806x/patches/0066-spi-qup-Add-device-tree-bindings-information.patch [new file with mode: 0644]
target/linux/ipq806x/patches/0067-spi-qup-Remove-spi_master_put-in-spi_qup_remove.patch [new file with mode: 0644]
target/linux/ipq806x/patches/0068-spi-qup-Convert-ot-let-spi-core-handle-checking-tran.patch [new file with mode: 0644]
target/linux/ipq806x/patches/0069-spi-qup-Fix-build-error-due-to-a-typo.patch [new file with mode: 0644]
target/linux/ipq806x/patches/0070-spi-qup-Enable-driver-compilation-with-COMPILE_TEST.patch [new file with mode: 0644]
target/linux/ipq806x/patches/0071-spi-qup-Depend-on-ARM-COMPILE_TEST-to-avoid-build-er.patch [new file with mode: 0644]
target/linux/ipq806x/patches/0072-spi-qup-Remove-module-version.patch [new file with mode: 0644]
target/linux/ipq806x/patches/0073-spi-qup-Get-rid-of-using-struct-spi_qup_device.patch [new file with mode: 0644]
target/linux/ipq806x/patches/0074-spi-qup-Depend-on-ARCH_QCOM.patch [new file with mode: 0644]
target/linux/ipq806x/patches/0075-spi-qup-Correct-selection-of-FIFO-Block-mode.patch [new file with mode: 0644]
target/linux/ipq806x/patches/0078-clk-qcom-Consolidate-common-probe-code.patch [new file with mode: 0644]
target/linux/ipq806x/patches/0079-clk-qcom-Add-basic-support-for-APQ8064-global-clock-.patch [new file with mode: 0644]
target/linux/ipq806x/patches/0080-clk-qcom-Various-fixes-for-MSM8960-s-global-clock-co.patch [new file with mode: 0644]
target/linux/ipq806x/patches/0081-ARM-config-Add-qcom_defconfig.patch [new file with mode: 0644]
target/linux/ipq806x/patches/0082-ARM-qcom-Enable-GSBI-driver-in-defconfig.patch [new file with mode: 0644]
target/linux/ipq806x/patches/0083-soc-Introduce-drivers-soc-place-holder-for-SOC-speci.patch [new file with mode: 0644]
target/linux/ipq806x/patches/0084-soc-qcom-Add-GSBI-driver.patch [new file with mode: 0644]
target/linux/ipq806x/patches/0085-soc-qcom-fix-of_device_id-table.patch [new file with mode: 0644]
target/linux/ipq806x/patches/0086-msm_serial-Add-support-for-poll_-get-put-_char.patch [new file with mode: 0644]
target/linux/ipq806x/patches/0087-tty-serial-msm-Remove-direct-access-to-GSBI.patch [new file with mode: 0644]
target/linux/ipq806x/patches/0088-soc-qcom-Add-device-tree-binding-for-GSBI.patch [new file with mode: 0644]
target/linux/ipq806x/patches/0089-ARM-dts-MSM8974-Add-pinctrl-node.patch [new file with mode: 0644]
target/linux/ipq806x/patches/0090-ARM-dts-msm-Add-SDHC-controller-nodes-for-MSM8974-an.patch [new file with mode: 0644]
target/linux/ipq806x/patches/0091-ARM-dts-qcom-Update-msm8974-apq8074-device-trees.patch [new file with mode: 0644]
target/linux/ipq806x/patches/0092-ARM-dts-qcom-Update-msm8960-device-trees.patch [new file with mode: 0644]
target/linux/ipq806x/patches/0093-ARM-dts-qcom-Update-msm8660-device-trees.patch [new file with mode: 0644]
target/linux/ipq806x/patches/0094-ARM-dts-qcom-Add-initial-APQ8064-SoC-and-IFC6410-boa.patch [new file with mode: 0644]
target/linux/ipq806x/patches/0095-ARM-dts-qcom-Add-APQ8084-MTP-board-support.patch [new file with mode: 0644]
target/linux/ipq806x/patches/0096-ARM-dts-qcom-Add-APQ8084-SoC-support.patch [new file with mode: 0644]
target/linux/ipq806x/patches/0097-ARM-debug-qcom-make-UART-address-selection-configura.patch [new file with mode: 0644]
target/linux/ipq806x/patches/0098-ARM-debug-qcom-add-UART-addresses-to-Kconfig-help-fo.patch [new file with mode: 0644]
target/linux/ipq806x/patches/0099-ARM-qcom-Enable-ARM_AMBA-option-for-Qualcomm-SOCs.patch [new file with mode: 0644]
target/linux/ipq806x/patches/0100-clk-qcom-Fix-msm8660-GCC-probe.patch [new file with mode: 0644]
target/linux/ipq806x/patches/0101-clk-qcom-Fix-blsp2_ahb_clk-register-offset.patch [new file with mode: 0644]
target/linux/ipq806x/patches/0104-clk-qcom-Return-highest-rate-when-round_rate-exceeds.patch [new file with mode: 0644]
target/linux/ipq806x/patches/0105-clk-qcom-Support-display-RCG-clocks.patch [new file with mode: 0644]
target/linux/ipq806x/patches/0106-clk-qcom-Properly-support-display-clocks-on-msm8974.patch [new file with mode: 0644]
target/linux/ipq806x/patches/0107-clk-qcom-Support-msm8974pro-global-clock-control-har.patch [new file with mode: 0644]
target/linux/ipq806x/patches/0108-clk-qcom-Return-error-pointers-for-unimplemented-clo.patch [new file with mode: 0644]
target/linux/ipq806x/patches/0109-libahci-Allow-drivers-to-override-start_engine.patch [new file with mode: 0644]
target/linux/ipq806x/patches/0110-ahci-platform-Add-support-for-devices-with-more-then.patch [new file with mode: 0644]
target/linux/ipq806x/patches/0111-ahci-platform-Add-support-for-an-optional-regulator-.patch [new file with mode: 0644]
target/linux/ipq806x/patches/0112-ahci-platform-Add-enable_-disable_resources-helper-f.patch [new file with mode: 0644]
target/linux/ipq806x/patches/0113-ata-delete-non-required-instances-of-include-linux-i.patch [new file with mode: 0644]
target/linux/ipq806x/patches/0114-ahci-platform-Library-ise-ahci_probe-functionality.patch [new file with mode: 0644]
target/linux/ipq806x/patches/0115-ahci-platform-Library-ise-suspend-resume-functionali.patch [new file with mode: 0644]
target/linux/ipq806x/patches/0116-ata-ahci_platform-Add-DT-compatible-for-Synopsis-DWC.patch [new file with mode: 0644]
target/linux/ipq806x/patches/0117-ata-ahci_platform-Manage-SATA-PHY.patch [new file with mode: 0644]
target/linux/ipq806x/patches/0118-ata-ahci_platform-runtime-resume-the-device-before-u.patch [new file with mode: 0644]
target/linux/ipq806x/patches/0119-ahci_platform-Drop-support-for-ahci-strict-platform-.patch [new file with mode: 0644]
target/linux/ipq806x/patches/0120-ahci_platform-Drop-support-for-imx53-ahci-platform-d.patch [new file with mode: 0644]
target/linux/ipq806x/patches/0121-ahci_platform-Drop-unused-ahci_platform_data-members.patch [new file with mode: 0644]
target/linux/ipq806x/patches/0122-ata-ahci_platform-fix-devm_ioremap_resource-return-v.patch [new file with mode: 0644]
target/linux/ipq806x/patches/0123-ata-ahci_platform-fix-ahci_platform_data-suspend-met.patch [new file with mode: 0644]
target/linux/ipq806x/patches/0124-ata-move-library-code-from-ahci_platform.c-to-libahc.patch [new file with mode: 0644]
target/linux/ipq806x/patches/0125-clk-qcom-Add-support-for-IPQ8064-s-global-clock-cont.patch [new file with mode: 0644]
target/linux/ipq806x/patches/0126-clk-Add-safe-switch-hook.patch [new file with mode: 0644]
target/linux/ipq806x/patches/0127-clk-qcom-Add-support-for-setting-rates-on-PLLs.patch [new file with mode: 0644]
target/linux/ipq806x/patches/0128-clk-qcom-Add-support-for-banked-MD-RCGs.patch [new file with mode: 0644]
target/linux/ipq806x/patches/0129-clk-qcom-Add-support-for-NSS-GMAC-clocks-and-resets.patch [new file with mode: 0644]
target/linux/ipq806x/patches/0130-ARM-qcom-Add-initial-IPQ8064-SoC-and-AP148-device-tr.patch [new file with mode: 0644]
target/linux/ipq806x/patches/0131-ARM-qcom-config-Enable-IPQ806x-support.patch [new file with mode: 0644]
target/linux/ipq806x/patches/0132-XXX-Add-boot-support-for-u-boot.ipq-image.patch [new file with mode: 0644]
target/linux/ipq806x/patches/0133-spi-qup-Remove-chip-select-function.patch [new file with mode: 0644]
target/linux/ipq806x/patches/0134-spi-qup-Fix-order-of-spi_register_master.patch [new file with mode: 0644]
target/linux/ipq806x/patches/0135-spi-qup-Add-support-for-v1.1.1.patch [new file with mode: 0644]
target/linux/ipq806x/patches/0136-ARM-ipq8064-ap148-Add-i2c-pinctrl-nodes.patch [new file with mode: 0644]
target/linux/ipq806x/patches/0137-ARM-qcom-ipq8064-ap148-Add-SPI-related-bindings.patch [new file with mode: 0644]
target/linux/ipq806x/patches/0138-PCI-qcom-Add-support-for-pcie-controllers-on-IPQ8064.patch [new file with mode: 0644]
target/linux/ipq806x/patches/0139-ARM-dts-msm-Add-PCIe-related-nodes-for-IPQ8064-AP148.patch [new file with mode: 0644]
target/linux/ipq806x/patches/0140-ARM-qcom-config-Enable-PCI-support-for-IPQ806x.patch [new file with mode: 0644]
target/linux/ipq806x/patches/0141-ahci-platform-Bump-max-number-of-clocks-to-5.patch [new file with mode: 0644]
target/linux/ipq806x/patches/0142-ata-Add-Qualcomm-ARM-SoC-AHCI-SATA-host-controller-d.patch [new file with mode: 0644]
target/linux/ipq806x/patches/0143-ata-qcom-Add-device-tree-bindings-information.patch [new file with mode: 0644]
target/linux/ipq806x/patches/0144-phy-qcom-Add-driver-for-QCOM-IPQ806x-SATA-PHY.patch [new file with mode: 0644]
target/linux/ipq806x/patches/0145-phy-qcom-Add-device-tree-bindings-information.patch [new file with mode: 0644]
target/linux/ipq806x/patches/0146-ARM-dts-qcom-Add-SATA-support-for-IPQ8064-and-AP148-.patch [new file with mode: 0644]
target/linux/ipq806x/patches/0147-ARM-qcom-Enable-SATA-SATA-PHY-drivers-in-defconfig.patch [new file with mode: 0644]
target/linux/ipq806x/patches/0148-ARM-qcom-enable-default-CPU_IDLE-to-get-wfi-support-.patch [new file with mode: 0644]
target/linux/ipq806x/patches/0149-pinctrl-qcom-Add-BUS_HOLD-Keeper-bias.patch [new file with mode: 0644]
target/linux/ipq806x/patches/0150-mtd-nand-Add-Qualcomm-NAND-controller.patch [new file with mode: 0644]
target/linux/ipq806x/patches/0151-ARM-ipq8064-Add-nand-device-info.patch [new file with mode: 0644]
target/linux/ipq806x/patches/0152-ARM-qcom-config-Add-NAND-config-options.patch [new file with mode: 0644]
target/linux/ipq806x/patches/0153-soc-qcom-tcsr-Add-TCSR-driver.patch [new file with mode: 0644]
target/linux/ipq806x/patches/0154-clk-qcom-Correct-UTMI-clock-frequency-table.patch [new file with mode: 0644]
target/linux/ipq806x/patches/0155-clk-qcom-Fix-incorrect-UTMI-DT-include-values.patch [new file with mode: 0644]
target/linux/ipq806x/patches/0156-usb-dwc3-Add-Qualcomm-DWC3-glue-layer-driver.patch [new file with mode: 0644]
target/linux/ipq806x/patches/0157-usb-phy-Add-Qualcomm-DWC3-HS-SS-PHY-drivers.patch [new file with mode: 0644]
target/linux/ipq806x/patches/0158-usb-dwc3-qcom-Add-device-tree-binding.patch [new file with mode: 0644]
target/linux/ipq806x/patches/0159-arm-ipq8064-Add-USB3-DT-information.patch [new file with mode: 0644]
target/linux/ipq806x/patches/0160-ARM-qcom-config-Add-TCSR-and-USB3-options.patch [new file with mode: 0644]
target/linux/ipq806x/patches/0161-ARM-Remove-ARCH_HAS_CPUFREQ-config-option.patch [new file with mode: 0644]
target/linux/ipq806x/patches/0162-PM-OPP-Remove-ARCH_HAS_OPP.patch [new file with mode: 0644]
target/linux/ipq806x/patches/0163-clk-return-probe-defer-when-DT-clock-not-yet-ready.patch [new file with mode: 0644]
target/linux/ipq806x/patches/0164-ARM-Add-Krait-L2-register-accessor-functions.patch [new file with mode: 0644]
target/linux/ipq806x/patches/0165-clk-qcom-Add-support-for-muxes-dividers-and-mux-divi.patch [new file with mode: 0644]
target/linux/ipq806x/patches/0166-clk-qcom-Add-support-for-High-Frequency-PLLs-HFPLLs.patch [new file with mode: 0644]
target/linux/ipq806x/patches/0167-clk-qcom-Add-HFPLL-driver.patch [new file with mode: 0644]
target/linux/ipq806x/patches/0168-clk-qcom-Add-MSM8960-s-HFPLLs.patch [new file with mode: 0644]
target/linux/ipq806x/patches/0169-clk-qcom-Add-support-for-Krait-clocks.patch [new file with mode: 0644]
target/linux/ipq806x/patches/0170-clk-qcom-Add-KPSS-ACC-GCC-driver.patch [new file with mode: 0644]
target/linux/ipq806x/patches/0171-clk-qcom-Add-Krait-clock-controller-driver.patch [new file with mode: 0644]
target/linux/ipq806x/patches/0172-cpufreq-Add-a-cpufreq-krait-based-on-cpufreq-cpu0.patch [new file with mode: 0644]
target/linux/ipq806x/patches/0173-cpufreq-Add-module-to-register-cpufreq-krait-device.patch [new file with mode: 0644]
target/linux/ipq806x/patches/0174-clk-qcom-Add-HFPLLs-to-IPQ806X-driver.patch [new file with mode: 0644]
target/linux/ipq806x/patches/0175-ARM-dts-ipq8064-Add-necessary-DT-data-for-Krait-cpuf.patch [new file with mode: 0644]
target/linux/ipq806x/patches/0176-ARM-qcom_defconfig-Enable-CPUfreq-options.patch [new file with mode: 0644]
target/linux/ipq806x/patches/0177-dmaengine-Add-QCOM-ADM-DMA-driver.patch [new file with mode: 0644]
target/linux/ipq806x/patches/0178-dmaengine-qcom_adm-Add-device-tree-binding.patch [new file with mode: 0644]
target/linux/ipq806x/patches/0179-spi-qup-Add-DMA-capabilities.patch [new file with mode: 0644]
target/linux/ipq806x/patches/0180-ARM-dts-Add-ADM-DMA-nodes-and-SPI-linkage.patch [new file with mode: 0644]
target/linux/ipq806x/patches/0181-mtd-nand-qcom-Align-clk-and-reset-names.patch [new file with mode: 0644]
target/linux/ipq806x/patches/0182-qcom-Kconfig-Make-drivers-mutually-exclusive.patch [new file with mode: 0644]
target/linux/ipq806x/profiles/default.mk [new file with mode: 0644]

diff --git a/target/linux/ipq806x/Makefile b/target/linux/ipq806x/Makefile
new file mode 100644 (file)
index 0000000..7521e97
--- /dev/null
@@ -0,0 +1,17 @@
+# Copyright (c) 2013 The Linux Foundation. All rights reserved.
+#
+include $(TOPDIR)/rules.mk
+
+ARCH:=arm
+BOARD:=ipq806x
+BOARDNAME:=Qualcomm Atheros IPQ806X
+FEATURES:=squashfs
+CPU_TYPE:=cortex-a7
+
+LINUX_VERSION:=3.14.12
+
+KERNELNAME="Image dtbs"
+
+include $(INCLUDE_DIR)/target.mk
+
+$(eval $(call BuildTarget))
diff --git a/target/linux/ipq806x/base-files.mk b/target/linux/ipq806x/base-files.mk
new file mode 100644 (file)
index 0000000..fdd2c71
--- /dev/null
@@ -0,0 +1,3 @@
+define Package/base-files/install-target
+       rm -f $(1)/etc/config/network
+endef
diff --git a/target/linux/ipq806x/base-files/etc/inittab b/target/linux/ipq806x/base-files/etc/inittab
new file mode 100644 (file)
index 0000000..19a6e11
--- /dev/null
@@ -0,0 +1,4 @@
+# Copyright (c) 2013 The Linux Foundation. All rights reserved.
+::sysinit:/etc/init.d/rcS S boot
+::shutdown:/etc/init.d/rcS K shutdown
+ttyMSM0::askfirst:/bin/ash --login
diff --git a/target/linux/ipq806x/base-files/lib/ipq806x.sh b/target/linux/ipq806x/base-files/lib/ipq806x.sh
new file mode 100644 (file)
index 0000000..7c47fa2
--- /dev/null
@@ -0,0 +1,40 @@
+#!/bin/sh
+#
+# Copyright (c) 2014 The Linux Foundation. All rights reserved.
+# Copyright (C) 2011 OpenWrt.org
+#
+
+IPQ806X_BOARD_NAME=
+IPQ806X_MODEL=
+
+ipq806x_board_detect() {
+       local machine
+       local name
+
+       machine=$(cat /proc/device-tree/model)
+
+       case "$machine" in
+       *"AP148")
+               name="ap148"
+               ;;
+       esac
+
+       [ -z "$name" ] && name="unknown"
+
+       [ -z "$IPQ806X_BOARD_NAME" ] && IPQ806X_BOARD_NAME="$name"
+       [ -z "$IPQ806X_MODEL" ] && IPQ806X_MODEL="$machine"
+
+       [ -e "/tmp/sysinfo/" ] || mkdir -p "/tmp/sysinfo/"
+
+       echo "$IPQ806X_BOARD_NAME" > /tmp/sysinfo/board_name
+       echo "$IPQ806X_MODEL" > /tmp/sysinfo/model
+}
+
+ipq806x_board_name() {
+       local name
+
+       [ -f /tmp/sysinfo/board_name ] && name=$(cat /tmp/sysinfo/board_name)
+       [ -z "$name" ] && name="unknown"
+
+       echo "$name"
+}
diff --git a/target/linux/ipq806x/base-files/lib/preinit/03_preinit_do_ipq806x.sh b/target/linux/ipq806x/base-files/lib/preinit/03_preinit_do_ipq806x.sh
new file mode 100644 (file)
index 0000000..785f1eb
--- /dev/null
@@ -0,0 +1,12 @@
+#!/bin/sh
+#
+# Copyright (c) 2014 The Linux Foundation. All rights reserved.
+#
+
+do_ipq806x() {
+       . /lib/ipq806x.sh
+
+       ipq806x_board_detect
+}
+
+boot_hook_add preinit_main do_ipq806x
diff --git a/target/linux/ipq806x/config-3.14 b/target/linux/ipq806x/config-3.14
new file mode 100644 (file)
index 0000000..876e56d
--- /dev/null
@@ -0,0 +1,356 @@
+CONFIG_ALIGNMENT_TRAP=y
+# CONFIG_AMBA_PL08X is not set
+# CONFIG_APM_EMULATION is not set
+CONFIG_ARCH_BINFMT_ELF_RANDOMIZE_PIE=y
+CONFIG_ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE=y
+CONFIG_ARCH_HAS_TICK_BROADCAST=y
+CONFIG_ARCH_HAVE_CUSTOM_GPIO_H=y
+CONFIG_ARCH_MIGHT_HAVE_PC_PARPORT=y
+# CONFIG_ARCH_MSM is not set
+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_SUSPEND_POSSIBLE=y
+CONFIG_ARCH_USE_BUILTIN_BSWAP=y
+CONFIG_ARCH_USE_CMPXCHG_LOCKREF=y
+CONFIG_ARCH_WANT_GENERAL_HUGETLB=y
+CONFIG_ARCH_WANT_IPC_PARSE_VERSION=y
+CONFIG_ARM=y
+CONFIG_ARM_AMBA=y
+CONFIG_ARM_ARCH_TIMER=y
+CONFIG_ARM_ARCH_TIMER_EVTSTREAM=y
+CONFIG_ARM_CPU_SUSPEND=y
+CONFIG_ARM_GIC=y
+CONFIG_ARM_L1_CACHE_SHIFT=6
+CONFIG_ARM_L1_CACHE_SHIFT_6=y
+# CONFIG_ARM_LPAE is not set
+CONFIG_ARM_NR_BANKS=8
+CONFIG_ARM_PATCH_PHYS_VIRT=y
+# CONFIG_ARM_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_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_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_FREEZER=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_NET_UTILS=y
+CONFIG_GENERIC_PCI_IOMAP=y
+CONFIG_GENERIC_PHY=y
+CONFIG_GENERIC_PINCONF=y
+CONFIG_GENERIC_SCHED_CLOCK=y
+CONFIG_GENERIC_SMP_IDLE_THREAD=y
+CONFIG_GENERIC_STRNCPY_FROM_USER=y
+CONFIG_GENERIC_STRNLEN_USER=y
+CONFIG_GPIOLIB=y
+CONFIG_GPIO_DEVRES=y
+# CONFIG_GPIO_MSM_V2 is not set
+CONFIG_GPIO_SYSFS=y
+CONFIG_HARDIRQS_SW_RESEND=y
+CONFIG_HAS_DMA=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+# CONFIG_HAVE_64BIT_ALIGNED_ACCESS is not set
+CONFIG_HAVE_ARCH_JUMP_LABEL=y
+CONFIG_HAVE_ARCH_KGDB=y
+CONFIG_HAVE_ARCH_PFN_VALID=y
+CONFIG_HAVE_ARCH_SECCOMP_FILTER=y
+CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_ARM_ARCH_TIMER=y
+# CONFIG_HAVE_BOOTMEM_INFO_NODE is not set
+CONFIG_HAVE_BPF_JIT=y
+CONFIG_HAVE_CC_STACKPROTECTOR=y
+CONFIG_HAVE_CLK=y
+CONFIG_HAVE_CLK_PREPARE=y
+CONFIG_HAVE_CONTEXT_TRACKING=y
+CONFIG_HAVE_C_RECORDMCOUNT=y
+CONFIG_HAVE_DEBUG_KMEMLEAK=y
+CONFIG_HAVE_DMA_API_DEBUG=y
+CONFIG_HAVE_DMA_ATTRS=y
+CONFIG_HAVE_DMA_CONTIGUOUS=y
+CONFIG_HAVE_DYNAMIC_FTRACE=y
+CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y
+CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
+CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
+CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_HAVE_GENERIC_DMA_COHERENT=y
+CONFIG_HAVE_HW_BREAKPOINT=y
+CONFIG_HAVE_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_KPSS_XCC=y
+CONFIG_KRAITCC=y
+CONFIG_KRAIT_CLOCKS=y
+CONFIG_KRAIT_L2_ACCESSORS=y
+CONFIG_KTIME_SCALAR=y
+# CONFIG_LEDS_REGULATOR is not set
+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_MIGHT_HAVE_PCI=y
+CONFIG_MIGRATION=y
+# CONFIG_MLX5_CORE is not set
+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_SPLIT_SQUASHFS_ROOT=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_RX_BUSY_POLL=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_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_DOMAINS=y
+CONFIG_PCI_MSI=y
+CONFIG_PERF_EVENTS=y
+CONFIG_PERF_USE_VMALLOC=y
+CONFIG_PHYLIB=y
+CONFIG_PHY_QCOM_IPQ806X_SATA=y
+CONFIG_PINCTRL=y
+CONFIG_PINCTRL_APQ8064=y
+CONFIG_PINCTRL_IPQ8064=y
+CONFIG_PINCTRL_MSM=y
+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_GPIO is not set
+CONFIG_POWER_RESET_MSM=y
+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_DEVICETREE=y
+CONFIG_PROC_PAGE_MONITOR=y
+# CONFIG_QCOM_ADM is not set
+CONFIG_QCOM_BAM_DMA=y
+CONFIG_QCOM_GSBI=y
+CONFIG_QCOM_HFPLL=y
+CONFIG_QCOM_SCM=y
+CONFIG_QCOM_TCSR=y
+# CONFIG_RCU_BOOST is not set
+CONFIG_RCU_CPU_STALL_TIMEOUT=21
+CONFIG_RCU_CPU_STALL_VERBOSE=y
+CONFIG_RCU_STALL_COMMON=y
+CONFIG_RD_GZIP=y
+CONFIG_REGMAP=y
+CONFIG_REGMAP_MMIO=y
+CONFIG_REGULATOR=y
+# CONFIG_REGULATOR_DEBUG is not set
+# CONFIG_REGULATOR_USERSPACE_CONSUMER is not set
+CONFIG_RESET_CONTROLLER=y
+# CONFIG_RFKILL_REGULATOR is not set
+CONFIG_RFS_ACCEL=y
+CONFIG_RPS=y
+CONFIG_RTC_CLASS=y
+# CONFIG_RTC_DRV_CMOS is not set
+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_ZBUD is not set
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZONE_DMA_FLAG=0
diff --git a/target/linux/ipq806x/image/Makefile b/target/linux/ipq806x/image/Makefile
new file mode 100644 (file)
index 0000000..977e674
--- /dev/null
@@ -0,0 +1,32 @@
+# Copyright (c) 2014 The Linux Foundation. All rights reserved.
+#
+include $(TOPDIR)/rules.mk
+include $(INCLUDE_DIR)/image.mk
+
+UBIFS_OPTS = -m 2048 -e 124KiB -c 4096 -U -F
+UBINIZE_OPTS = -m 2048 -p 128KiB
+
+E2SIZE=$(shell echo $$(($(CONFIG_TARGET_ROOTFS_PARTSIZE)*1024)))
+
+define Image/BuildKernel/FIT
+       gzip -9 -c $(KDIR)/Image > $(KDIR)/Image.gz
+       $(call CompressLzma,$(KDIR)/Image,$(KDIR)/Image.gz)
+       $(call Image/BuildKernel/MkFIT,$(1), $(KDIR)/Image.gz, $(LINUX_DIR)/arch/arm/boot/dts/$(1).dtb,gzip,0x42208000,0x42208000)
+       $(CP) $(KDIR)/fit-$(1).itb $(BIN_DIR)/$(IMG_PREFIX)-$(1)-fit-uImage.itb
+ifneq ($(CONFIG_TARGET_ROOTFS_INITRAMFS),)
+       $(call Image/BuildKernel/MkFIT,$(1), $(KDIR)/Image-initramfs, $(LINUX_DIR)/arch/arm/boot/dts/$(1).dtb, none,0x42208000,0x42208000)
+       $(CP) $(KDIR)/fit-$(1).itb $(BIN_DIR)/$(IMG_PREFIX)-$(1)-fit-uImage-initramfs.itb
+endif
+endef
+
+define Image/BuildKernel
+       $(CP) $(LINUX_DIR)/vmlinux $(BIN_DIR)/$(IMG_PREFIX)-vmlinux.elf
+       $(call Image/BuildKernel/FIT,qcom-ipq8064-ap148)
+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
+endef
+
+$(eval $(call BuildImage))
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
new file mode 100644 (file)
index 0000000..52d4cf3
--- /dev/null
@@ -0,0 +1,313 @@
+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
+
+diff --git a/arch/arm/boot/dts/qcom-msm8660-surf.dts b/arch/arm/boot/dts/qcom-msm8660-surf.dts
+index 68a72f5..169bad9 100644
+--- 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";
+-      };
+ };
+diff --git a/arch/arm/boot/dts/qcom-msm8660.dtsi b/arch/arm/boot/dts/qcom-msm8660.dtsi
+new file mode 100644
+index 0000000..69d6c4e
+--- /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";
++      };
++};
+diff --git a/arch/arm/boot/dts/qcom-msm8960-cdp.dts b/arch/arm/boot/dts/qcom-msm8960-cdp.dts
+index 7c30de4..a58fb88 100644
+--- 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";
+-      };
+ };
+diff --git a/arch/arm/boot/dts/qcom-msm8960.dtsi b/arch/arm/boot/dts/qcom-msm8960.dtsi
+new file mode 100644
+index 0000000..ff00282
+--- /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";
++      };
++};
+-- 
+1.7.10.4
+
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
new file mode 100644 (file)
index 0000000..72b6618
--- /dev/null
@@ -0,0 +1,223 @@
+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
+
+diff --git a/arch/arm/mach-msm/Makefile b/arch/arm/mach-msm/Makefile
+index 8e307a1..721f27f 100644
+--- a/arch/arm/mach-msm/Makefile
++++ b/arch/arm/mach-msm/Makefile
+@@ -19,7 +19,7 @@ obj-$(CONFIG_MSM_SCM) += scm.o scm-boot.o
+ 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
+diff --git a/arch/arm/mach-msm/headsmp.S b/arch/arm/mach-msm/headsmp.S
+deleted file mode 100644
+index 6c62c3f..0000000
+--- 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
+diff --git a/arch/arm/mach-msm/hotplug.c b/arch/arm/mach-msm/hotplug.c
+index 326a872..cea80fc 100644
+--- a/arch/arm/mach-msm/hotplug.c
++++ b/arch/arm/mach-msm/hotplug.c
+@@ -24,33 +24,10 @@ static inline void cpu_leave_lowpower(void)
+ 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");
+ }
+ /*
+diff --git a/arch/arm/mach-msm/platsmp.c b/arch/arm/mach-msm/platsmp.c
+index f10a1f5..3721b31 100644
+--- 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 int cpu)
+ 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 int cpu)
+ 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 int cpu, struct task_struct *idle)
+       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;
+ }
+ /*
+-- 
+1.7.10.4
+
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
new file mode 100644 (file)
index 0000000..b6e9bba
--- /dev/null
@@ -0,0 +1,120 @@
+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
+
+diff --git a/arch/arm/mach-msm/Makefile b/arch/arm/mach-msm/Makefile
+index 721f27f..8327f60 100644
+--- a/arch/arm/mach-msm/Makefile
++++ b/arch/arm/mach-msm/Makefile
+@@ -18,7 +18,6 @@ obj-$(CONFIG_MSM_SCM) += scm.o scm-boot.o
+ 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
+diff --git a/arch/arm/mach-msm/common.h b/arch/arm/mach-msm/common.h
+index 33c7725..0a4899b 100644
+--- a/arch/arm/mach-msm/common.h
++++ b/arch/arm/mach-msm/common.h
+@@ -24,7 +24,6 @@ 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;
+-extern void msm_cpu_die(unsigned int cpu);
+ struct msm_mmc_platform_data;
+diff --git a/arch/arm/mach-msm/hotplug.c b/arch/arm/mach-msm/hotplug.c
+deleted file mode 100644
+index cea80fc..0000000
+--- 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();
+-}
+diff --git a/arch/arm/mach-msm/platsmp.c b/arch/arm/mach-msm/platsmp.c
+index 3721b31..251a91e 100644
+--- 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 */
+-- 
+1.7.10.4
+
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
new file mode 100644 (file)
index 0000000..fd730c1
--- /dev/null
@@ -0,0 +1,788 @@
+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
+
+diff --git a/arch/arm/mach-msm/Kconfig b/arch/arm/mach-msm/Kconfig
+index 9625cf3..3c4eca7 100644
+--- 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
+diff --git a/arch/arm/mach-msm/Makefile b/arch/arm/mach-msm/Makefile
+index 8327f60..04b1bee 100644
+--- 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
+diff --git a/arch/arm/mach-msm/timer.c b/arch/arm/mach-msm/timer.c
+deleted file mode 100644
+index fd16449..0000000
+--- 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);
+-}
+diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig
+index cd6950f..6510ec4 100644
+--- 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
+diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile
+index c7ca50a..2e0c0cc 100644
+--- a/drivers/clocksource/Makefile
++++ b/drivers/clocksource/Makefile
+@@ -32,6 +32,7 @@ obj-$(CONFIG_CLKSRC_EFM32)   += time-efm32.o
+ 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
+diff --git a/drivers/clocksource/qcom-timer.c b/drivers/clocksource/qcom-timer.c
+new file mode 100644
+index 0000000..dca829e
+--- /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);
++}
+-- 
+1.7.10.4
+
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
new file mode 100644 (file)
index 0000000..c23faf0
--- /dev/null
@@ -0,0 +1,1482 @@
+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
+
+diff --git a/MAINTAINERS b/MAINTAINERS
+index 900d98e..7d23402 100644
+--- a/MAINTAINERS
++++ b/MAINTAINERS
+@@ -1168,6 +1168,14 @@ L:      linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
+ 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)
+diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
+index 1594945..d02ce70 100644
+--- a/arch/arm/Kconfig
++++ b/arch/arm/Kconfig
+@@ -657,9 +657,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
+@@ -1005,6 +1004,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"
+diff --git a/arch/arm/Kconfig.debug b/arch/arm/Kconfig.debug
+index 0531da8..4491c7b 100644
+--- 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
+diff --git a/arch/arm/Makefile b/arch/arm/Makefile
+index 08a9ef5..51e5bed 100644
+--- a/arch/arm/Makefile
++++ b/arch/arm/Makefile
+@@ -180,6 +180,7 @@ machine-$(CONFIG_ARCH_OMAP2PLUS)   += omap2
+ 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
+diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
+index 0320303..4a89023 100644
+--- a/arch/arm/boot/dts/Makefile
++++ b/arch/arm/boot/dts/Makefile
+@@ -119,9 +119,6 @@ dtb-$(CONFIG_ARCH_KIRKWOOD) += kirkwood-cloudbox.dtb \
+       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-h4.dtb \
+       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 \
+diff --git a/arch/arm/mach-msm/Kconfig b/arch/arm/mach-msm/Kconfig
+index 3c4eca7..a7f959e 100644
+--- 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
+diff --git a/arch/arm/mach-msm/Makefile b/arch/arm/mach-msm/Makefile
+index 04b1bee..27c078a 100644
+--- 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
+diff --git a/arch/arm/mach-msm/board-dt.c b/arch/arm/mach-msm/board-dt.c
+deleted file mode 100644
+index 1f11d93..0000000
+--- 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
+diff --git a/arch/arm/mach-msm/platsmp.c b/arch/arm/mach-msm/platsmp.c
+deleted file mode 100644
+index 251a91e..0000000
+--- 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
+-};
+diff --git a/arch/arm/mach-msm/scm-boot.c b/arch/arm/mach-msm/scm-boot.c
+deleted file mode 100644
+index 45cee3e..0000000
+--- 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);
+diff --git a/arch/arm/mach-msm/scm-boot.h b/arch/arm/mach-msm/scm-boot.h
+deleted file mode 100644
+index 7be32ff..0000000
+--- 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
+diff --git a/arch/arm/mach-msm/scm.c b/arch/arm/mach-msm/scm.c
+deleted file mode 100644
+index c536fd6..0000000
+--- 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);
+diff --git a/arch/arm/mach-msm/scm.h b/arch/arm/mach-msm/scm.h
+deleted file mode 100644
+index 00b31ea..0000000
+--- 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
+diff --git a/arch/arm/mach-qcom/Kconfig b/arch/arm/mach-qcom/Kconfig
+new file mode 100644
+index 0000000..a028be2
+--- /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
+diff --git a/arch/arm/mach-qcom/Makefile b/arch/arm/mach-qcom/Makefile
+new file mode 100644
+index 0000000..8f756ae
+--- /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)
+diff --git a/arch/arm/mach-qcom/board.c b/arch/arm/mach-qcom/board.c
+new file mode 100644
+index 0000000..4529f6b
+--- /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
+diff --git a/arch/arm/mach-qcom/platsmp.c b/arch/arm/mach-qcom/platsmp.c
+new file mode 100644
+index 0000000..67823a7
+--- /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
++};
+diff --git a/arch/arm/mach-qcom/scm-boot.c b/arch/arm/mach-qcom/scm-boot.c
+new file mode 100644
+index 0000000..45cee3e
+--- /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);
+diff --git a/arch/arm/mach-qcom/scm-boot.h b/arch/arm/mach-qcom/scm-boot.h
+new file mode 100644
+index 0000000..7be32ff
+--- /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
+diff --git a/arch/arm/mach-qcom/scm.c b/arch/arm/mach-qcom/scm.c
+new file mode 100644
+index 0000000..c536fd6
+--- /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);
+diff --git a/arch/arm/mach-qcom/scm.h b/arch/arm/mach-qcom/scm.h
+new file mode 100644
+index 0000000..00b31ea
+--- /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
+-- 
+1.7.10.4
+
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
new file mode 100644 (file)
index 0000000..5cb6bf3
--- /dev/null
@@ -0,0 +1,78 @@
+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(-)
+
+diff --git a/drivers/clocksource/qcom-timer.c b/drivers/clocksource/qcom-timer.c
+index dca829e..e807acf 100644
+--- a/drivers/clocksource/qcom-timer.c
++++ b/drivers/clocksource/qcom-timer.c
+@@ -106,15 +106,6 @@ 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,
+@@ -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(struct device_node *np)
+ }
+ 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_addr_t addr, u32 event, u32 source,
+       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
+-- 
+1.7.10.4
+
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
new file mode 100644 (file)
index 0000000..fc064b2
--- /dev/null
@@ -0,0 +1,105 @@
+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(-)
+
+diff --git a/arch/arm/mach-qcom/board.c b/arch/arm/mach-qcom/board.c
+index 4529f6b..830f69c 100644
+--- 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_match[] __initconst = {
+ };
+ 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
+diff --git a/arch/arm/mach-qcom/platsmp.c b/arch/arm/mach-qcom/platsmp.c
+index 67823a7..9c53ea7 100644
+--- 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 int cpu)
+                                 "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 int cpu, struct task_struct *idle)
+  * 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(void)
+               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
+ };
+-- 
+1.7.10.4
+
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
new file mode 100644 (file)
index 0000000..9579ac2
--- /dev/null
@@ -0,0 +1,159 @@
+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(+)
+
+diff --git a/arch/arm/include/asm/smp.h b/arch/arm/include/asm/smp.h
+index 22a3b9b..772435b 100644
+--- 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
+  */
+diff --git a/arch/arm/kernel/devtree.c b/arch/arm/kernel/devtree.c
+index f751714..c7419a5 100644
+--- 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;
+diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h
+index bc2121f..bd02ca7 100644
+--- a/include/asm-generic/vmlinux.lds.h
++++ b/include/asm-generic/vmlinux.lds.h
+@@ -167,6 +167,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) = .;                                \
+@@ -491,6 +500,7 @@
+       MEM_DISCARD(init.rodata)                                        \
+       CLK_OF_TABLES()                                                 \
+       CLKSRC_OF_TABLES()                                              \
++      CPU_METHOD_OF_TABLES()                                          \
+       KERNEL_DTB()                                                    \
+       IRQCHIP_OF_MATCH_TABLE()
+-- 
+1.7.10.4
+
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
new file mode 100644 (file)
index 0000000..6601ad4
--- /dev/null
@@ -0,0 +1,249 @@
+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(-)
+
+diff --git a/arch/arm/mach-msm/common.h b/arch/arm/mach-msm/common.h
+index 0a4899b..572479a 100644
+--- 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);
+diff --git a/arch/arm/mach-qcom/board.c b/arch/arm/mach-qcom/board.c
+index 830f69c..bae617e 100644
+--- 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
+diff --git a/arch/arm/mach-qcom/platsmp.c b/arch/arm/mach-qcom/platsmp.c
+index 9c53ea7..ec8604d 100644
+--- 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 int cpu)
+ }
+ #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 int cpu)
+       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 int cpu, struct task_struct *idle)
+        */
+       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)
++static int msm8660_boot_secondary(unsigned int cpu, struct task_struct *idle)
+ {
+-      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);
++      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);
+-- 
+1.7.10.4
+
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
new file mode 100644 (file)
index 0000000..0bcd3e8
--- /dev/null
@@ -0,0 +1,70 @@
+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(-)
+
+diff --git a/Documentation/devicetree/bindings/arm/cpus.txt b/Documentation/devicetree/bindings/arm/cpus.txt
+index 9130435..333f4ae 100644
+--- 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 properties described below.
+                         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 properties described below.
+                         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
+-- 
+1.7.10.4
+
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
new file mode 100644 (file)
index 0000000..fc57727
--- /dev/null
@@ -0,0 +1,55 @@
+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
+
+diff --git a/Documentation/devicetree/bindings/arm/msm/qcom,kpss-acc.txt b/Documentation/devicetree/bindings/arm/msm/qcom,kpss-acc.txt
+new file mode 100644
+index 0000000..1333db9
+--- /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>;
++      };
+-- 
+1.7.10.4
+
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
new file mode 100644 (file)
index 0000000..5bf18c1
--- /dev/null
@@ -0,0 +1,60 @@
+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
+
+diff --git a/Documentation/devicetree/bindings/arm/msm/qcom,saw2.txt b/Documentation/devicetree/bindings/arm/msm/qcom,saw2.txt
+new file mode 100644
+index 0000000..1505fb8
+--- /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>;
++      };
+-- 
+1.7.10.4
+
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
new file mode 100644 (file)
index 0000000..66f667c
--- /dev/null
@@ -0,0 +1,181 @@
+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(-)
+
+diff --git a/arch/arm/mach-qcom/platsmp.c b/arch/arm/mach-qcom/platsmp.c
+index ec8604d..cb0783f 100644
+--- 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(unsigned int cpu)
+       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(unsigned int cpu, struct task_struct *idle)
+       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(unsigned int max_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_ops __initdata = {
+ #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);
+diff --git a/arch/arm/mach-qcom/scm-boot.h b/arch/arm/mach-qcom/scm-boot.h
+index 7be32ff..6aabb24 100644
+--- 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);
+-- 
+1.7.10.4
+
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
new file mode 100644 (file)
index 0000000..03fdaf3
--- /dev/null
@@ -0,0 +1,172 @@
+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(+)
+
+diff --git a/arch/arm/mach-qcom/platsmp.c b/arch/arm/mach-qcom/platsmp.c
+index cb0783f..d690856 100644
+--- 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(unsigned int cpu, struct task_struct *idle)
+       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_kpssv1_ops __initdata = {
+ #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);
+-- 
+1.7.10.4
+
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
new file mode 100644 (file)
index 0000000..9dbc06d
--- /dev/null
@@ -0,0 +1,32 @@
+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(-)
+
+diff --git a/drivers/tty/serial/Kconfig b/drivers/tty/serial/Kconfig
+index a3815ea..ce9b12d 100644
+--- 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
+-- 
+1.7.10.4
+
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
new file mode 100644 (file)
index 0000000..46e1fb7
--- /dev/null
@@ -0,0 +1,33 @@
+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(-)
+
+diff --git a/drivers/gpu/drm/msm/Kconfig b/drivers/gpu/drm/msm/Kconfig
+index c69d1e0..b698497 100644
+--- 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
+-- 
+1.7.10.4
+
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
new file mode 100644 (file)
index 0000000..868146c
--- /dev/null
@@ -0,0 +1,32 @@
+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(-)
+
+diff --git a/drivers/power/reset/Kconfig b/drivers/power/reset/Kconfig
+index 6d452a7..fa0e4e0 100644
+--- 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.
+-- 
+1.7.10.4
+
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
new file mode 100644 (file)
index 0000000..b375fec
--- /dev/null
@@ -0,0 +1,38 @@
+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(-)
+
+diff --git a/drivers/char/hw_random/Kconfig b/drivers/char/hw_random/Kconfig
+index 2f2b084..244759b 100644
+--- 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.
+-- 
+1.7.10.4
+
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
new file mode 100644 (file)
index 0000000..210f760
--- /dev/null
@@ -0,0 +1,32 @@
+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(-)
+
+diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
+index 903f24d..2c38d95 100644
+--- 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
+-- 
+1.7.10.4
+
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
new file mode 100644 (file)
index 0000000..ba25b46
--- /dev/null
@@ -0,0 +1,54 @@
+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(+)
+
+diff --git a/arch/arm/configs/multi_v7_defconfig b/arch/arm/configs/multi_v7_defconfig
+index ee69829..1a61bd8 100644
+--- 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
+-- 
+1.7.10.4
+
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
new file mode 100644 (file)
index 0000000..b23ee3b
--- /dev/null
@@ -0,0 +1,214 @@
+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(+)
+
+diff --git a/arch/arm/boot/dts/qcom-msm8660.dtsi b/arch/arm/boot/dts/qcom-msm8660.dtsi
+index 69d6c4e..c52a9e9 100644
+--- 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;
+diff --git a/arch/arm/boot/dts/qcom-msm8960.dtsi b/arch/arm/boot/dts/qcom-msm8960.dtsi
+index ff00282..02231a5 100644
+--- 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>,
+diff --git a/arch/arm/boot/dts/qcom-msm8974.dtsi b/arch/arm/boot/dts/qcom-msm8974.dtsi
+index 9e5dadb..39eebc5 100644
+--- 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>;
+-- 
+1.7.10.4
+
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
new file mode 100644 (file)
index 0000000..23edfe7
--- /dev/null
@@ -0,0 +1,35 @@
+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(+)
+
+diff --git a/arch/arm/boot/dts/qcom-msm8974.dtsi b/arch/arm/boot/dts/qcom-msm8974.dtsi
+index 39eebc5..011eb09 100644
+--- 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";
++              };
+       };
+ };
+-- 
+1.7.10.4
+
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
new file mode 100644 (file)
index 0000000..a3e69f3
--- /dev/null
@@ -0,0 +1,34 @@
+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(+)
+
+diff --git a/arch/arm/boot/dts/qcom-msm8960.dtsi b/arch/arm/boot/dts/qcom-msm8960.dtsi
+index 02231a5..ecfba72 100644
+--- 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";
++      };
+ };
+-- 
+1.7.10.4
+
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
new file mode 100644 (file)
index 0000000..013d45c
--- /dev/null
@@ -0,0 +1,53 @@
+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(+)
+
+diff --git a/arch/arm/boot/dts/qcom-msm8960.dtsi b/arch/arm/boot/dts/qcom-msm8960.dtsi
+index ecfba72..997b7b9 100644
+--- 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;
+diff --git a/arch/arm/boot/dts/qcom-msm8974.dtsi b/arch/arm/boot/dts/qcom-msm8974.dtsi
+index 011eb09..f687239 100644
+--- 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>;
+-- 
+1.7.10.4
+
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
new file mode 100644 (file)
index 0000000..fba5e4f
--- /dev/null
@@ -0,0 +1,71 @@
+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(-)
+
+diff --git a/drivers/pinctrl/pinctrl-msm.c b/drivers/pinctrl/pinctrl-msm.c
+index ef2bf31..0e43fdd 100644
+--- 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 irq_data *d, unsigned int on)
+ {
+       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);
+-- 
+1.7.10.4
+
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
new file mode 100644 (file)
index 0000000..fd2e10f
--- /dev/null
@@ -0,0 +1,73 @@
+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(+)
+
+diff --git a/drivers/pinctrl/pinctrl-msm.c b/drivers/pinctrl/pinctrl-msm.c
+index 0e43fdd..e61b30a 100644
+--- a/drivers/pinctrl/pinctrl-msm.c
++++ b/drivers/pinctrl/pinctrl-msm.c
+@@ -857,6 +857,12 @@ static void msm_gpio_irq_handler(unsigned int irq, struct irq_desc *desc)
+       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_pinctrl *pctrl)
+       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);
+       }
+-- 
+1.7.10.4
+
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
new file mode 100644 (file)
index 0000000..c2b7487
--- /dev/null
@@ -0,0 +1,39 @@
+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(-)
+
+diff --git a/drivers/pinctrl/pinctrl-msm.c b/drivers/pinctrl/pinctrl-msm.c
+index e61b30a..90ac995 100644
+--- a/drivers/pinctrl/pinctrl-msm.c
++++ b/drivers/pinctrl/pinctrl-msm.c
+@@ -870,10 +870,14 @@ static int msm_gpio_init(struct msm_pinctrl *pctrl)
+       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;
+-- 
+1.7.10.4
+
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
new file mode 100644 (file)
index 0000000..8f864f2
--- /dev/null
@@ -0,0 +1,60 @@
+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(-)
+
+diff --git a/drivers/pinctrl/pinctrl-msm.c b/drivers/pinctrl/pinctrl-msm.c
+index 90ac995..4474e00 100644
+--- 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"
+diff --git a/drivers/pinctrl/pinctrl-msm.h b/drivers/pinctrl/pinctrl-msm.h
+index 206e782..8fbe9fb 100644
+--- 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
+diff --git a/drivers/pinctrl/pinctrl-msm8x74.c b/drivers/pinctrl/pinctrl-msm8x74.c
+index f944bf2..bb5ded69f 100644
+--- 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"
+-- 
+1.7.10.4
+
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
new file mode 100644 (file)
index 0000000..6a33a9d
--- /dev/null
@@ -0,0 +1,31 @@
+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(-)
+
+diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig
+index 1e4e693..06cee01 100644
+--- 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
+-- 
+1.7.10.4
+
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
new file mode 100644 (file)
index 0000000..975e11a
--- /dev/null
@@ -0,0 +1,66 @@
+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(-)
+
+diff --git a/drivers/pinctrl/pinctrl-msm.c b/drivers/pinctrl/pinctrl-msm.c
+index 4474e00..87f6c3c 100644
+--- a/drivers/pinctrl/pinctrl-msm.c
++++ b/drivers/pinctrl/pinctrl-msm.c
+@@ -258,8 +258,10 @@ static int msm_config_set(struct pinctrl_dev *pctldev, unsigned int pin,
+ #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 pinctrl_dev *pctldev,
+               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 pinctrl_dev *pctldev,
+                       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 seq_file *s,
+       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]);
+ }
+-- 
+1.7.10.4
+
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
new file mode 100644 (file)
index 0000000..61c8ac1
--- /dev/null
@@ -0,0 +1,95 @@
+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(-)
+
+diff --git a/drivers/pinctrl/pinctrl-msm.c b/drivers/pinctrl/pinctrl-msm.c
+index 87f6c3c..ab46e3a 100644
+--- a/drivers/pinctrl/pinctrl-msm.c
++++ b/drivers/pinctrl/pinctrl-msm.c
+@@ -401,8 +401,6 @@ static int msm_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
+       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(struct gpio_chip *chip, unsigned offset, in
+       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 *chip, unsigned offset)
+       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_chip *chip, unsigned offset, int value)
+       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_data *d)
+       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 irq_data *d)
+       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_data *d)
+       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 irq_data *d, unsigned int type)
+       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);
+-- 
+1.7.10.4
+
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
new file mode 100644 (file)
index 0000000..d656978
--- /dev/null
@@ -0,0 +1,115 @@
+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(-)
+
+diff --git a/drivers/pinctrl/pinctrl-msm.c b/drivers/pinctrl/pinctrl-msm.c
+index ab46e3a..91de8bc 100644
+--- a/drivers/pinctrl/pinctrl-msm.c
++++ b/drivers/pinctrl/pinctrl-msm.c
+@@ -200,28 +200,17 @@ static const struct pinmux_ops msm_pinmux_ops = {
+ 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_pinctrl *pctrl,
+               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 pinctrl_dev *pctldev,
+       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 pinctrl_dev *pctldev,
+       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 pinctrl_dev *pctldev,
+               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 pinctrl_dev *pctldev,
+               }
+               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);
+       }
+-- 
+1.7.10.4
+
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
new file mode 100644 (file)
index 0000000..18c72cc
--- /dev/null
@@ -0,0 +1,69 @@
+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(+)
+
+diff --git a/drivers/pinctrl/pinctrl-msm.c b/drivers/pinctrl/pinctrl-msm.c
+index 91de8bc..19d2feb 100644
+--- a/drivers/pinctrl/pinctrl-msm.c
++++ b/drivers/pinctrl/pinctrl-msm.c
+@@ -214,6 +214,11 @@ static int msm_config_reg(struct msm_pinctrl *pctrl,
+               *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 pinctrl_dev *pctldev,
+       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 pinctrl_dev *pctldev,
+                       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);
+-- 
+1.7.10.4
+
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
new file mode 100644 (file)
index 0000000..b8df704
--- /dev/null
@@ -0,0 +1,63 @@
+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(-)
+
+diff --git a/drivers/pinctrl/pinctrl-msm8x74.c b/drivers/pinctrl/pinctrl-msm8x74.c
+index bb5ded69f..dde5529 100644
+--- 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_groups[] = { "gpio6", "gpio7" };
+ 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_functions[] = {
+       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_groups[] = {
+       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),
+-- 
+1.7.10.4
+
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
new file mode 100644 (file)
index 0000000..c141a0b
--- /dev/null
@@ -0,0 +1,38 @@
+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(-)
+
+diff --git a/drivers/pinctrl/pinctrl-msm.c b/drivers/pinctrl/pinctrl-msm.c
+index 19d2feb..343f421 100644
+--- a/drivers/pinctrl/pinctrl-msm.c
++++ b/drivers/pinctrl/pinctrl-msm.c
+@@ -215,7 +215,6 @@ static int msm_config_reg(struct msm_pinctrl *pctrl,
+               *mask = 7;
+               break;
+       case PIN_CONFIG_OUTPUT:
+-              *reg = g->ctl_reg;
+               *bit = g->oe_bit;
+               *mask = 1;
+               break;
+-- 
+1.7.10.4
+
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
new file mode 100644 (file)
index 0000000..b44fb6a
--- /dev/null
@@ -0,0 +1,55 @@
+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(-)
+
+diff --git a/drivers/pinctrl/pinctrl-msm.c b/drivers/pinctrl/pinctrl-msm.c
+index 343f421..706809e 100644
+--- a/drivers/pinctrl/pinctrl-msm.c
++++ b/drivers/pinctrl/pinctrl-msm.c
+@@ -665,7 +665,10 @@ static void msm_gpio_irq_ack(struct irq_data *d)
+       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 irq_data *d, unsigned int type)
+                       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;
+diff --git a/drivers/pinctrl/pinctrl-msm.h b/drivers/pinctrl/pinctrl-msm.h
+index 8fbe9fb..6e26f1b 100644
+--- 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;
+-- 
+1.7.10.4
+
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
new file mode 100644 (file)
index 0000000..346dcd0
--- /dev/null
@@ -0,0 +1,74 @@
+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(-)
+
+diff --git a/drivers/pinctrl/pinctrl-msm.c b/drivers/pinctrl/pinctrl-msm.c
+index 706809e..7d67d34 100644
+--- a/drivers/pinctrl/pinctrl-msm.c
++++ b/drivers/pinctrl/pinctrl-msm.c
+@@ -145,12 +145,12 @@ static int msm_pinmux_enable(struct pinctrl_dev *pctldev,
+       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);
+diff --git a/drivers/pinctrl/pinctrl-msm.h b/drivers/pinctrl/pinctrl-msm.h
+index 6e26f1b..7b2a227 100644
+--- 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;
+diff --git a/drivers/pinctrl/pinctrl-msm8x74.c b/drivers/pinctrl/pinctrl-msm8x74.c
+index dde5529..57766d5 100644
+--- a/drivers/pinctrl/pinctrl-msm8x74.c
++++ b/drivers/pinctrl/pinctrl-msm8x74.c
+@@ -341,7 +341,7 @@ static const unsigned int sdc2_data_pins[] = { 151 };
+               .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[] = { 151 };
+                       MSM_MUX_##f6,                   \
+                       MSM_MUX_##f7                    \
+               },                                      \
++              .nfuncs = 8,                            \
+               .ctl_reg = 0x1000 + 0x10 * id,          \
+               .io_reg = 0x1004 + 0x10 * id,           \
+               .intr_cfg_reg = 0x1008 + 0x10 * id,     \
+-- 
+1.7.10.4
+
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
new file mode 100644 (file)
index 0000000..20e5a1d
--- /dev/null
@@ -0,0 +1,624 @@
+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
+
+diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig
+index 06cee01..91993a6 100644
+--- 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
+diff --git a/drivers/pinctrl/Makefile b/drivers/pinctrl/Makefile
+index 4b83588..9e1fb67 100644
+--- a/drivers/pinctrl/Makefile
++++ b/drivers/pinctrl/Makefile
+@@ -38,6 +38,7 @@ obj-$(CONFIG_PINCTRL_IMX23)  += pinctrl-imx23.o
+ 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
+diff --git a/drivers/pinctrl/pinctrl-apq8064.c b/drivers/pinctrl/pinctrl-apq8064.c
+new file mode 100644
+index 0000000..7c2a8ba
+--- /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);
+-- 
+1.7.10.4
+
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
new file mode 100644 (file)
index 0000000..51ed6d6
--- /dev/null
@@ -0,0 +1,36 @@
+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(-)
+
+diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig
+index 91993a6..d34639d 100644
+--- 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
+-- 
+1.7.10.4
+
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
new file mode 100644 (file)
index 0000000..6b48085
--- /dev/null
@@ -0,0 +1,711 @@
+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
+
+diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig
+index d34639d..232e6bc 100644
+--- 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)
+diff --git a/drivers/pinctrl/Makefile b/drivers/pinctrl/Makefile
+index 9e1fb67..6b8474a 100644
+--- a/drivers/pinctrl/Makefile
++++ b/drivers/pinctrl/Makefile
+@@ -39,6 +39,7 @@ 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_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
+diff --git a/drivers/pinctrl/pinctrl-ipq8064.c b/drivers/pinctrl/pinctrl-ipq8064.c
+new file mode 100644
+index 0000000..1700b49
+--- /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);
+-- 
+1.7.10.4
+
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
new file mode 100644 (file)
index 0000000..2a7c870
--- /dev/null
@@ -0,0 +1,120 @@
+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
+
+diff --git a/Documentation/devicetree/bindings/pinctrl/qcom,ipq8064-pinctrl.txt b/Documentation/devicetree/bindings/pinctrl/qcom,ipq8064-pinctrl.txt
+new file mode 100644
+index 0000000..e0d35a4
+--- /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;
++                      };
++              };
++      };
+-- 
+1.7.10.4
+
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
new file mode 100644 (file)
index 0000000..c1c116f
--- /dev/null
@@ -0,0 +1,29 @@
+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(+)
+
+diff --git a/arch/arm/mach-qcom/Kconfig b/arch/arm/mach-qcom/Kconfig
+index a028be2..6440c11 100644
+--- 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.
+-- 
+1.7.10.4
+
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
new file mode 100644 (file)
index 0000000..71e5572
--- /dev/null
@@ -0,0 +1,28 @@
+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(-)
+
+diff --git a/drivers/pinctrl/pinctrl-ipq8064.c b/drivers/pinctrl/pinctrl-ipq8064.c
+index 1700b49..54aba9f 100644
+--- 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"),
+-- 
+1.7.10.4
+
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
new file mode 100644 (file)
index 0000000..148959a
--- /dev/null
@@ -0,0 +1,65 @@
+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
+
+diff --git a/Documentation/devicetree/bindings/dma/qcom_bam_dma.txt b/Documentation/devicetree/bindings/dma/qcom_bam_dma.txt
+new file mode 100644
+index 0000000..d75a9d7
+--- /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";
++      };
+-- 
+1.7.10.4
+
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
new file mode 100644 (file)
index 0000000..6dcba78
--- /dev/null
@@ -0,0 +1,1174 @@
+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
+
+diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig
+index 605b016..f87cef9 100644
+--- 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
+diff --git a/drivers/dma/Makefile b/drivers/dma/Makefile
+index a029d0f4..5150c82 100644
+--- 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
+diff --git a/drivers/dma/qcom_bam_dma.c b/drivers/dma/qcom_bam_dma.c
+new file mode 100644
+index 0000000..82c9231
+--- /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;