OSDN Git Service

Merge tag 'armsoc-soc' into test-merge
authorKevin Hilman <khilman@linaro.org>
Thu, 25 Jun 2015 04:32:13 +0000 (21:32 -0700)
committerKevin Hilman <khilman@linaro.org>
Thu, 25 Jun 2015 04:32:13 +0000 (21:32 -0700)
ARM: SoC: platform support for v4.2

Our SoC branch usually contains expanded support for new SoCs and
other core platform code. Some highlights from this round:

- sunxi: SMP support for A23 SoC
- socpga: big-endian support
- pxa: conversion to common clock framework
- bcm: SMP support for BCM63138
- imx: support new I.MX7D SoC
- zte: basic support for ZX296702 SoC

 Conflicts:
arch/arm/mach-socfpga/core.h

Trivial remove/remove conflict with our cleanup branch.
Resolution: remove both sides

# gpg: Signature made Wed Jun 24 21:32:12 2015 PDT using RSA key ID D3FBC665
# gpg: Good signature from "Kevin Hilman <khilman@deeprootsystems.com>"
# gpg:                 aka "Kevin Hilman <khilman@linaro.org>"
# gpg:                 aka "Kevin Hilman <khilman@kernel.org>"

# Conflicts:
# arch/arm/mach-socfpga/core.h

225 files changed:
Documentation/arm/stm32/overview.txt [new file with mode: 0644]
Documentation/arm/stm32/stm32f429-overview.txt [new file with mode: 0644]
Documentation/devicetree/bindings/arm/cpus.txt
Documentation/devicetree/bindings/arm/exynos/power_domain.txt
Documentation/devicetree/bindings/arm/fsl.txt
Documentation/devicetree/bindings/arm/zte.txt [new file with mode: 0644]
Documentation/devicetree/bindings/clock/zx296702-clk.txt [new file with mode: 0644]
Documentation/devicetree/bindings/serial/pl011.txt
Documentation/devicetree/bindings/vendor-prefixes.txt
MAINTAINERS
arch/arm/Kconfig
arch/arm/Kconfig.debug
arch/arm/Makefile
arch/arm/boot/dts/Makefile
arch/arm/boot/dts/zx296702-ad1.dts [new file with mode: 0644]
arch/arm/boot/dts/zx296702.dtsi [new file with mode: 0644]
arch/arm/configs/efm32_defconfig
arch/arm/configs/zx_defconfig [new file with mode: 0644]
arch/arm/include/asm/firmware.h
arch/arm/include/asm/vfp.h
arch/arm/include/debug/8250.S
arch/arm/include/debug/efm32.S
arch/arm/include/debug/imx-uart.h
arch/arm/include/debug/pl01x.S
arch/arm/kernel/debug.S
arch/arm/mach-bcm/Kconfig
arch/arm/mach-bcm/Makefile
arch/arm/mach-bcm/bcm63xx_headsmp.S [new file with mode: 0644]
arch/arm/mach-bcm/bcm63xx_pmb.c [new file with mode: 0644]
arch/arm/mach-bcm/bcm63xx_smp.c [new file with mode: 0644]
arch/arm/mach-bcm/bcm63xx_smp.h [new file with mode: 0644]
arch/arm/mach-bcm/bcm_5301x.c
arch/arm/mach-bcm/board_bcm2835.c
arch/arm/mach-ep93xx/simone.c
arch/arm/mach-exynos/common.h
arch/arm/mach-exynos/exynos.c
arch/arm/mach-exynos/firmware.c
arch/arm/mach-exynos/platsmp.c
arch/arm/mach-exynos/pm.c
arch/arm/mach-exynos/pm_domains.c
arch/arm/mach-exynos/pmu.c
arch/arm/mach-exynos/suspend.c
arch/arm/mach-imx/Kconfig
arch/arm/mach-imx/Makefile
arch/arm/mach-imx/Makefile.boot [new file with mode: 0644]
arch/arm/mach-imx/anatop.c
arch/arm/mach-imx/common.h
arch/arm/mach-imx/cpu.c
arch/arm/mach-imx/cpuidle-imx6q.c
arch/arm/mach-imx/cpuidle-imx6sl.c
arch/arm/mach-imx/cpuidle-imx6sx.c
arch/arm/mach-imx/gpc.c
arch/arm/mach-imx/hardware.h
arch/arm/mach-imx/iomux-imx31.c
arch/arm/mach-imx/mach-imx6q.c
arch/arm/mach-imx/mach-imx6sl.c
arch/arm/mach-imx/mach-imx6sx.c
arch/arm/mach-imx/mach-imx7d.c [new file with mode: 0644]
arch/arm/mach-imx/mach-vf610.c
arch/arm/mach-imx/mmdc.c
arch/arm/mach-imx/mx27.h
arch/arm/mach-imx/mx3x.h
arch/arm/mach-imx/mxc.h
arch/arm/mach-imx/pm-imx5.c
arch/arm/mach-imx/pm-imx6.c
arch/arm/mach-imx/suspend-imx53.S [new file with mode: 0644]
arch/arm/mach-imx/time.c [deleted file]
arch/arm/mach-lpc18xx/Makefile [new file with mode: 0644]
arch/arm/mach-lpc18xx/Makefile.boot [new file with mode: 0644]
arch/arm/mach-lpc18xx/board-dt.c [new file with mode: 0644]
arch/arm/mach-omap1/ams-delta-fiq-handler.S
arch/arm/mach-omap1/board-ams-delta.c
arch/arm/mach-omap1/board-fsample.c
arch/arm/mach-omap1/board-generic.c
arch/arm/mach-omap1/board-h2.c
arch/arm/mach-omap1/board-h3-mmc.c
arch/arm/mach-omap1/board-h3.c
arch/arm/mach-omap1/board-htcherald.c
arch/arm/mach-omap1/board-innovator.c
arch/arm/mach-omap1/board-nokia770.c
arch/arm/mach-omap1/board-osk.c
arch/arm/mach-omap1/board-palmte.c
arch/arm/mach-omap1/board-palmtt.c
arch/arm/mach-omap1/board-palmz71.c
arch/arm/mach-omap1/board-perseus2.c
arch/arm/mach-omap1/board-sx1.c
arch/arm/mach-omap1/board-voiceblue.c
arch/arm/mach-omap1/common.h
arch/arm/mach-omap1/dma.c
arch/arm/mach-omap1/gpio16xx.c
arch/arm/mach-omap1/gpio7xx.c
arch/arm/mach-omap1/i2c.c
arch/arm/mach-omap1/include/mach/entry-macro.S [deleted file]
arch/arm/mach-omap1/include/mach/irqs.h
arch/arm/mach-omap1/include/mach/memory.h
arch/arm/mach-omap1/include/mach/serial.h
arch/arm/mach-omap1/include/mach/soc.h
arch/arm/mach-omap1/irq.c
arch/arm/mach-omap1/mux.c
arch/arm/mach-omap1/pm.c
arch/arm/mach-omap1/serial.c
arch/arm/mach-omap1/timer.c
arch/arm/mach-omap2/omap_device.c
arch/arm/mach-omap2/omap_hwmod.c
arch/arm/mach-omap2/omap_hwmod.h
arch/arm/mach-omap2/omap_hwmod_2xxx_ipblock_data.c
arch/arm/mach-omap2/omap_hwmod_33xx_43xx_common_data.h
arch/arm/mach-omap2/omap_hwmod_33xx_43xx_ipblock_data.c
arch/arm/mach-omap2/omap_hwmod_33xx_data.c
arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
arch/arm/mach-omap2/omap_hwmod_43xx_data.c
arch/arm/mach-omap2/omap_hwmod_44xx_data.c
arch/arm/mach-omap2/omap_hwmod_7xx_data.c
arch/arm/mach-omap2/omap_hwmod_81xx_data.c
arch/arm/mach-omap2/prcm43xx.h
arch/arm/mach-pxa/Makefile
arch/arm/mach-pxa/clock-pxa2xx.c [deleted file]
arch/arm/mach-pxa/clock-pxa3xx.c [deleted file]
arch/arm/mach-pxa/clock.c [deleted file]
arch/arm/mach-pxa/clock.h [deleted file]
arch/arm/mach-pxa/eseries.c
arch/arm/mach-pxa/generic.c
arch/arm/mach-pxa/generic.h
arch/arm/mach-pxa/irq.c
arch/arm/mach-pxa/lubbock.c
arch/arm/mach-pxa/pxa25x.c
arch/arm/mach-pxa/pxa27x.c
arch/arm/mach-pxa/pxa300.c
arch/arm/mach-pxa/pxa320.c
arch/arm/mach-pxa/pxa3xx.c
arch/arm/mach-pxa/raumfeld.c
arch/arm/mach-pxa/tosa.c
arch/arm/mach-shmobile/Kconfig
arch/arm/mach-socfpga/Kconfig
arch/arm/mach-socfpga/Makefile
arch/arm/mach-socfpga/core.h
arch/arm/mach-socfpga/headsmp.S
arch/arm/mach-socfpga/platsmp.c
arch/arm/mach-socfpga/pm.c [new file with mode: 0644]
arch/arm/mach-socfpga/self-refresh.S [new file with mode: 0644]
arch/arm/mach-socfpga/socfpga.c
arch/arm/mach-stm32/Makefile [new file with mode: 0644]
arch/arm/mach-stm32/Makefile.boot [new file with mode: 0644]
arch/arm/mach-stm32/board-dt.c [new file with mode: 0644]
arch/arm/mach-sunxi/platsmp.c
arch/arm/mach-tegra/cpuidle-tegra20.c
arch/arm/mach-tegra/reset-handler.S
arch/arm/mach-tegra/reset.h
arch/arm/mach-tegra/sleep-tegra20.S
arch/arm/mach-tegra/sleep.h
arch/arm/mach-tegra/tegra.c
arch/arm/mach-uniphier/Kconfig [new file with mode: 0644]
arch/arm/mach-uniphier/Makefile [new file with mode: 0644]
arch/arm/mach-uniphier/platsmp.c [new file with mode: 0644]
arch/arm/mach-uniphier/uniphier.c [new file with mode: 0644]
arch/arm/mach-zx/Kconfig [new file with mode: 0644]
arch/arm/mach-zx/Makefile [new file with mode: 0644]
arch/arm/mach-zx/core.h [new file with mode: 0644]
arch/arm/mach-zx/headsmp.S [new file with mode: 0644]
arch/arm/mach-zx/platsmp.c [new file with mode: 0644]
arch/arm/mach-zx/zx296702.c [new file with mode: 0644]
arch/arm/mach-zynq/common.c
arch/arm/mach-zynq/common.h
arch/arm/mach-zynq/slcr.c
arch/arm/plat-omap/dma.c
arch/arm/plat-samsung/adc.c
arch/arm/vfp/vfpmodule.c
arch/arm64/Kconfig
arch/arm64/configs/defconfig
drivers/bus/brcmstb_gisb.c
drivers/clk/Makefile
drivers/clk/imx/Makefile [new file with mode: 0644]
drivers/clk/imx/clk-busy.c [moved from arch/arm/mach-imx/clk-busy.c with 100% similarity]
drivers/clk/imx/clk-cpu.c [moved from arch/arm/mach-imx/clk-cpu.c with 99% similarity]
drivers/clk/imx/clk-fixup-div.c [moved from arch/arm/mach-imx/clk-fixup-div.c with 100% similarity]
drivers/clk/imx/clk-fixup-mux.c [moved from arch/arm/mach-imx/clk-fixup-mux.c with 100% similarity]
drivers/clk/imx/clk-gate-exclusive.c [moved from arch/arm/mach-imx/clk-gate-exclusive.c with 100% similarity]
drivers/clk/imx/clk-gate2.c [moved from arch/arm/mach-imx/clk-gate2.c with 100% similarity]
drivers/clk/imx/clk-imx1.c [moved from arch/arm/mach-imx/clk-imx1.c with 91% similarity]
drivers/clk/imx/clk-imx21.c [moved from arch/arm/mach-imx/clk-imx21.c with 95% similarity]
drivers/clk/imx/clk-imx25.c [moved from arch/arm/mach-imx/clk-imx25.c with 98% similarity]
drivers/clk/imx/clk-imx27.c [moved from arch/arm/mach-imx/clk-imx27.c with 97% similarity]
drivers/clk/imx/clk-imx31.c [moved from arch/arm/mach-imx/clk-imx31.c with 91% similarity]
drivers/clk/imx/clk-imx35.c [moved from arch/arm/mach-imx/clk-imx35.c with 94% similarity]
drivers/clk/imx/clk-imx51-imx53.c [moved from arch/arm/mach-imx/clk-imx51-imx53.c with 99% similarity]
drivers/clk/imx/clk-imx6q.c [moved from arch/arm/mach-imx/clk-imx6q.c with 98% similarity]
drivers/clk/imx/clk-imx6sl.c [moved from arch/arm/mach-imx/clk-imx6sl.c with 99% similarity]
drivers/clk/imx/clk-imx6sx.c [moved from arch/arm/mach-imx/clk-imx6sx.c with 99% similarity]
drivers/clk/imx/clk-imx7d.c [new file with mode: 0644]
drivers/clk/imx/clk-pfd.c [moved from arch/arm/mach-imx/clk-pfd.c with 100% similarity]
drivers/clk/imx/clk-pllv1.c [moved from arch/arm/mach-imx/clk-pllv1.c with 75% similarity]
drivers/clk/imx/clk-pllv2.c [moved from arch/arm/mach-imx/clk-pllv2.c with 100% similarity]
drivers/clk/imx/clk-pllv3.c [moved from arch/arm/mach-imx/clk-pllv3.c with 96% similarity]
drivers/clk/imx/clk-vf610.c [moved from arch/arm/mach-imx/clk-vf610.c with 98% similarity]
drivers/clk/imx/clk.c [moved from arch/arm/mach-imx/clk.c with 100% similarity]
drivers/clk/imx/clk.h [moved from arch/arm/mach-imx/clk.h with 94% similarity]
drivers/clk/pxa/clk-pxa27x.c
drivers/clk/zte/Makefile [new file with mode: 0644]
drivers/clk/zte/clk-pll.c [new file with mode: 0644]
drivers/clk/zte/clk-zx296702.c [new file with mode: 0644]
drivers/clk/zte/clk.h [new file with mode: 0644]
drivers/clocksource/Kconfig
drivers/clocksource/Makefile
drivers/clocksource/timer-imx-gpt.c [new file with mode: 0644]
drivers/irqchip/Kconfig
drivers/irqchip/irq-nvic.c
drivers/irqchip/irq-vf610-mscm-ir.c
drivers/memory/Kconfig
drivers/memory/omap-gpmc.c
drivers/soc/tegra/fuse/fuse-tegra20.c
drivers/soc/tegra/pmc.c
drivers/watchdog/bcm2835_wdt.c
include/dt-bindings/clock/imx7d-clock.h [new file with mode: 0644]
include/dt-bindings/clock/vf610-clock.h
include/dt-bindings/clock/zx296702-clock.h [new file with mode: 0644]
include/linux/irq.h
include/linux/irqdomain.h
include/linux/reset/bcm63xx_pmb.h [new file with mode: 0644]
include/soc/imx/revision.h [new file with mode: 0644]
include/soc/imx/timer.h [new file with mode: 0644]
include/soc/tegra/pmc.h
include/uapi/linux/serial_reg.h
kernel/irq/chip.c
kernel/irq/generic-chip.c
kernel/irq/irqdomain.c

diff --git a/Documentation/arm/stm32/overview.txt b/Documentation/arm/stm32/overview.txt
new file mode 100644 (file)
index 0000000..09aed55
--- /dev/null
@@ -0,0 +1,32 @@
+                       STM32 ARM Linux Overview
+                       ========================
+
+Introduction
+------------
+
+  The STMicroelectronics family of Cortex-M based MCUs are supported by the
+  'STM32' platform of ARM Linux. Currently only the STM32F429 is supported.
+
+
+Configuration
+-------------
+
+  A generic configuration is provided for STM32 family, and can be used as the
+  default by
+       make stm32_defconfig
+
+Layout
+------
+
+  All the files for multiple machine families are located in the platform code
+  contained in arch/arm/mach-stm32
+
+  There is a generic board board-dt.c in the mach folder which support
+  Flattened Device Tree, which means, it works with any compatible board with
+  Device Trees.
+
+
+Document Author
+---------------
+
+  Maxime Coquelin <mcoquelin.stm32@gmail.com>
diff --git a/Documentation/arm/stm32/stm32f429-overview.txt b/Documentation/arm/stm32/stm32f429-overview.txt
new file mode 100644 (file)
index 0000000..5206822
--- /dev/null
@@ -0,0 +1,22 @@
+                       STM32F429 Overview
+                       ==================
+
+  Introduction
+  ------------
+       The STM32F429 is a Cortex-M4 MCU aimed at various applications.
+       It features:
+       - ARM Cortex-M4 up to 180MHz with FPU
+       - 2MB internal Flash Memory
+       - External memory support through FMC controller (PSRAM, SDRAM, NOR, NAND)
+       - I2C, SPI, SAI, CAN, USB OTG, Ethernet controllers
+       - LCD controller & Camera interface
+       - Cryptographic processor
+
+  Resources
+  ---------
+       Datasheet and reference manual are publicly available on ST website:
+       - http://www.st.com/web/en/catalog/mmc/FM141/SC1169/SS1577/LN1806?ecmp=stm32f429-439_pron_pr-ces2014_nov2013
+
+  Document Author
+  ---------------
+       Maxime Coquelin <mcoquelin.stm32@gmail.com>
index 6aa331d..d6b794c 100644 (file)
@@ -188,6 +188,7 @@ nodes to be present and contain the properties described below.
                        # On ARM 32-bit systems this property is optional and
                          can be one of:
                            "allwinner,sun6i-a31"
+                           "allwinner,sun8i-a23"
                            "arm,psci"
                            "brcm,brahma-b15"
                            "marvell,armada-375-smp"
index 5da38c5..e151057 100644 (file)
@@ -19,9 +19,10 @@ Optional Properties:
        domains.
 - clock-names: The following clocks can be specified:
        - oscclk: Oscillator clock.
-       - pclkN, clkN: Pairs of parent of input clock and input clock to the
-               devices in this power domain. Maximum of 4 pairs (N = 0 to 3)
-               are supported currently.
+       - clkN: Input clocks to the devices in this power domain. These clocks
+               will be reparented to oscclk before swithing power domain off.
+               Their original parent will be brought back after turning on
+               the domain. Maximum of 4 clocks (N = 0 to 3) are supported.
        - asbN: Clocks required by asynchronous bridges (ASB) present in
                the power domain. These clock should be enabled during power
                domain on/off operations.
index a5462b6..2a3ba73 100644 (file)
@@ -81,12 +81,15 @@ Freescale Vybrid Platform Device Tree Bindings
 For the Vybrid SoC familiy all variants with DDR controller are supported,
 which is the VF5xx and VF6xx series. Out of historical reasons, in most
 places the kernel uses vf610 to refer to the whole familiy.
+The compatible string "fsl,vf610m4" is used for the secondary Cortex-M4
+core support.
 
 Required root node compatible property (one of them):
     - compatible = "fsl,vf500";
     - compatible = "fsl,vf510";
     - compatible = "fsl,vf600";
     - compatible = "fsl,vf610";
+    - compatible = "fsl,vf610m4";
 
 Freescale LS1021A Platform Device Tree Bindings
 ------------------------------------------------
diff --git a/Documentation/devicetree/bindings/arm/zte.txt b/Documentation/devicetree/bindings/arm/zte.txt
new file mode 100644 (file)
index 0000000..3ff5c9e
--- /dev/null
@@ -0,0 +1,15 @@
+ZTE platforms device tree bindings
+---------------------------------------
+
+-  ZX296702 board:
+    Required root node properties:
+      - compatible = "zte,zx296702-ad1", "zte,zx296702"
+
+System management required properties:
+      - compatible = "zte,sysctrl"
+
+Low power management required properties:
+      - compatible = "zte,zx296702-pcu"
+
+Bus matrix required properties:
+      - compatible = "zte,zx-bus-matrix"
diff --git a/Documentation/devicetree/bindings/clock/zx296702-clk.txt b/Documentation/devicetree/bindings/clock/zx296702-clk.txt
new file mode 100644 (file)
index 0000000..750442b
--- /dev/null
@@ -0,0 +1,35 @@
+Device Tree Clock bindings for ZTE zx296702
+
+This binding uses the common clock binding[1].
+
+[1] Documentation/devicetree/bindings/clock/clock-bindings.txt
+
+Required properties:
+- compatible : shall be one of the following:
+       "zte,zx296702-topcrm-clk":
+               zx296702 top clock selection, divider and gating
+
+       "zte,zx296702-lsp0crpm-clk" and
+       "zte,zx296702-lsp1crpm-clk":
+               zx296702 device level clock selection and gating
+
+- reg: Address and length of the register set
+
+The clock consumer should specify the desired clock by having the clock
+ID in its "clocks" phandle cell. See include/dt-bindings/clock/zx296702-clock.h
+for the full list of zx296702 clock IDs.
+
+
+topclk: topcrm@0x09800000 {
+        compatible = "zte,zx296702-topcrm-clk";
+        reg = <0x09800000 0x1000>;
+        #clock-cells = <1>;
+};
+
+uart0: serial@0x09405000 {
+        compatible = "zte,zx296702-uart";
+        reg = <0x09405000 0x1000>;
+        interrupts = <GIC_SPI 37 IRQ_TYPE_LEVEL_HIGH>;
+        clocks = <&lsp1clk ZX296702_UART0_PCLK>;
+        status = "disabled";
+};
index ba3ecb8..cbae3d9 100644 (file)
@@ -1,7 +1,7 @@
 * ARM AMBA Primecell PL011 serial UART
 
 Required properties:
-- compatible: must be "arm,primecell", "arm,pl011"
+- compatible: must be "arm,primecell", "arm,pl011", "zte,zx296702-uart"
 - reg: exactly one register range with length 0x1000
 - interrupts: exactly one interrupt specifier
 
index 8033919..717ffd5 100644 (file)
@@ -211,3 +211,4 @@ xillybus    Xillybus Ltd.
 xlnx   Xilinx
 zyxel  ZyXEL Communications Corp.
 zarlink        Zarlink Semiconductor
+zte    ZTE Corp.
index d8afd29..beed981 100644 (file)
@@ -1035,7 +1035,7 @@ F:        arch/arm/include/asm/hardware/dec21285.h
 F:     arch/arm/mach-footbridge/
 
 ARM/FREESCALE IMX / MXC ARM ARCHITECTURE
-M:     Shawn Guo <shawn.guo@linaro.org>
+M:     Shawn Guo <shawnguo@kernel.org>
 M:     Sascha Hauer <kernel@pengutronix.de>
 L:     linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
 S:     Maintained
@@ -1044,9 +1044,11 @@ F:       arch/arm/mach-imx/
 F:     arch/arm/mach-mxs/
 F:     arch/arm/boot/dts/imx*
 F:     arch/arm/configs/imx*_defconfig
+F:     drivers/clk/imx/
+F:     include/soc/imx/
 
 ARM/FREESCALE VYBRID ARM ARCHITECTURE
-M:     Shawn Guo <shawn.guo@linaro.org>
+M:     Shawn Guo <shawnguo@kernel.org>
 M:     Sascha Hauer <kernel@pengutronix.de>
 R:     Stefan Agner <stefan@agner.ch>
 L:     linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
@@ -1189,6 +1191,12 @@ M:       Lennert Buytenhek <kernel@wantstofly.org>
 L:     linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
 S:     Maintained
 
+ARM/LPC18XX ARCHITECTURE
+M:     Joachim Eastwood <manabian@gmail.com>
+L:     linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
+S:     Maintained
+N:     lpc18xx
+
 ARM/MAGICIAN MACHINE SUPPORT
 M:     Philipp Zabel <philipp.zabel@gmail.com>
 S:     Maintained
@@ -1385,6 +1393,7 @@ L:        linux-samsung-soc@vger.kernel.org (moderated for non-subscribers)
 S:     Maintained
 F:     arch/arm/boot/dts/s3c*
 F:     arch/arm/boot/dts/exynos*
+F:     arch/arm64/boot/dts/exynos/
 F:     arch/arm/plat-samsung/
 F:     arch/arm/mach-s3c24*/
 F:     arch/arm/mach-s3c64xx/
@@ -1494,6 +1503,14 @@ F:       drivers/usb/host/ehci-st.c
 F:     drivers/usb/host/ohci-st.c
 F:     drivers/ata/ahci_st.c
 
+ARM/STM32 ARCHITECTURE
+M:     Maxime Coquelin <mcoquelin.stm32@gmail.com>
+L:     linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
+S:     Maintained
+T:     git git://git.kernel.org/pub/scm/linux/kernel/git/mcoquelin/stm32.git
+N:     stm32
+F:     drivers/clocksource/armv7m_systick.c
+
 ARM/TECHNOLOGIC SYSTEMS TS7250 MACHINE SUPPORT
 M:     Lennert Buytenhek <kernel@wantstofly.org>
 L:     linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
@@ -1540,6 +1557,13 @@ F:       drivers/rtc/rtc-ab3100.c
 F:     drivers/rtc/rtc-coh901331.c
 T:     git git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-stericsson.git
 
+ARM/UNIPHIER ARCHITECTURE
+M:     Masahiro Yamada <yamada.masahiro@socionext.com>
+L:     linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
+S:     Maintained
+F:     arch/arm/mach-uniphier/
+N:     uniphier
+
 ARM/Ux500 ARM ARCHITECTURE
 M:     Linus Walleij <linus.walleij@linaro.org>
 L:     linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
@@ -1617,6 +1641,15 @@ S:       Maintained
 F:     arch/arm/mach-pxa/z2.c
 F:     arch/arm/mach-pxa/include/mach/z2.h
 
+ARM/ZTE ARCHITECTURE
+M:     Jun Nie <jun.nie@linaro.org>
+L:     linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
+S:     Maintained
+F:     arch/arm/mach-zx/
+F:     drivers/clk/zte/
+F:     Documentation/devicetree/bindings/arm/zte.txt
+F:     Documentation/devicetree/bindings/clock/zx296702-clk.txt
+
 ARM/ZYNQ ARCHITECTURE
 M:     Michal Simek <michal.simek@xilinx.com>
 R:     Sören Brinkmann <soren.brinkmann@xilinx.com>
@@ -2193,6 +2226,7 @@ S:        Maintained
 F:     arch/arm/mach-bcm/*brcmstb*
 F:     arch/arm/boot/dts/bcm7*.dts*
 F:     drivers/bus/brcmstb_gisb.c
+N:     brcmstb
 
 BROADCOM BMIPS MIPS ARCHITECTURE
 M:     Kevin Cernekee <cernekee@gmail.com>
index 45df48b..72c4273 100644 (file)
@@ -329,6 +329,20 @@ config ARCH_MULTIPLATFORM
        select SPARSE_IRQ
        select USE_OF
 
+config ARM_SINGLE_ARMV7M
+       bool "ARMv7-M based platforms (Cortex-M0/M3/M4)"
+       depends on !MMU
+       select ARCH_WANT_OPTIONAL_GPIOLIB
+       select ARM_NVIC
+       select AUTO_ZRELADDR
+       select CLKSRC_OF
+       select COMMON_CLK
+       select CPU_V7M
+       select GENERIC_CLOCKEVENTS
+       select NO_IOPORT_MAP
+       select SPARSE_IRQ
+       select USE_OF
+
 config ARCH_REALVIEW
        bool "ARM Ltd. RealView family"
        select ARCH_WANT_OPTIONAL_GPIOLIB
@@ -398,24 +412,6 @@ config ARCH_EBSA110
          Ethernet interface, two PCMCIA sockets, two serial ports and a
          parallel port.
 
-config ARCH_EFM32
-       bool "Energy Micro efm32"
-       depends on !MMU
-       select ARCH_REQUIRE_GPIOLIB
-       select ARM_NVIC
-       select AUTO_ZRELADDR
-       select CLKSRC_OF
-       select COMMON_CLK
-       select CPU_V7M
-       select GENERIC_CLOCKEVENTS
-       select NO_DMA
-       select NO_IOPORT_MAP
-       select SPARSE_IRQ
-       select USE_OF
-       help
-         Support for Energy Micro's (now Silicon Labs) efm32 Giant Gecko
-         processors.
-
 config ARCH_EP93XX
        bool "EP93xx-based"
        select ARCH_HAS_HOLES_MEMORYMODEL
@@ -606,6 +602,7 @@ config ARCH_PXA
        select ARCH_REQUIRE_GPIOLIB
        select ARM_CPU_SUSPEND if PM
        select AUTO_ZRELADDR
+       select COMMON_CLK
        select CLKDEV_LOOKUP
        select CLKSRC_MMIO
        select CLKSRC_OF
@@ -752,8 +749,10 @@ config ARCH_OMAP1
        select GENERIC_IRQ_CHIP
        select HAVE_IDE
        select IRQ_DOMAIN
+       select MULTI_IRQ_HANDLER
        select NEED_MACH_IO_H if PCCARD
        select NEED_MACH_MEMORY_H
+       select SPARSE_IRQ
        help
          Support for older TI OMAP1 (omap7xx, omap15xx or omap16xx)
 
@@ -937,6 +936,8 @@ source "arch/arm/mach-tegra/Kconfig"
 
 source "arch/arm/mach-u300/Kconfig"
 
+source "arch/arm/mach-uniphier/Kconfig"
+
 source "arch/arm/mach-ux500/Kconfig"
 
 source "arch/arm/mach-versatile/Kconfig"
@@ -948,8 +949,40 @@ source "arch/arm/mach-vt8500/Kconfig"
 
 source "arch/arm/mach-w90x900/Kconfig"
 
+source "arch/arm/mach-zx/Kconfig"
+
 source "arch/arm/mach-zynq/Kconfig"
 
+# ARMv7-M architecture
+config ARCH_EFM32
+       bool "Energy Micro efm32"
+       depends on ARM_SINGLE_ARMV7M
+       select ARCH_REQUIRE_GPIOLIB
+       help
+         Support for Energy Micro's (now Silicon Labs) efm32 Giant Gecko
+         processors.
+
+config ARCH_LPC18XX
+       bool "NXP LPC18xx/LPC43xx"
+       depends on ARM_SINGLE_ARMV7M
+       select ARCH_HAS_RESET_CONTROLLER
+       select ARM_AMBA
+       select CLKSRC_LPC32XX
+       select PINCTRL
+       help
+         Support for NXP's LPC18xx Cortex-M3 and LPC43xx Cortex-M4
+         high performance microcontrollers.
+
+config ARCH_STM32
+       bool "STMicrolectronics STM32"
+       depends on ARM_SINGLE_ARMV7M
+       select ARCH_HAS_RESET_CONTROLLER
+       select ARMV7M_SYSTICK
+       select CLKSRC_STM32
+       select RESET_CONTROLLER
+       help
+         Support for STMicroelectronics STM32 processors.
+
 # Definitions to make life easier
 config ARCH_ACORN
        bool
@@ -1477,7 +1510,8 @@ config ARM_PSCI
 # selected platforms.
 config ARCH_NR_GPIO
        int
-       default 1024 if ARCH_SHMOBILE || ARCH_TEGRA || ARCH_ZYNQ
+       default 1024 if ARCH_BRCMSTB || ARCH_SHMOBILE || ARCH_TEGRA || \
+               ARCH_ZYNQ
        default 512 if ARCH_EXYNOS || ARCH_KEYSTONE || SOC_OMAP5 || \
                SOC_DRA7XX || ARCH_S3C24XX || ARCH_S3C64XX || ARCH_S5PV210
        default 416 if ARCH_SUNXI
index 0c12ffb..a6b5d0e 100644 (file)
@@ -410,6 +410,13 @@ choice
                  Say Y here if you want kernel low-level debugging support
                  on i.MX6SX.
 
+       config DEBUG_IMX7D_UART
+               bool "i.MX7D Debug UART"
+               depends on SOC_IMX7D
+               help
+                 Say Y here if you want kernel low-level debugging support
+                 on i.MX7D.
+
        config DEBUG_KEYSTONE_UART0
                bool "Kernel low-level debugging on KEYSTONE2 using UART0"
                depends on ARCH_KEYSTONE
@@ -433,6 +440,14 @@ choice
                  Say Y here if you want kernel low-level debugging support
                  on KS8695.
 
+       config DEBUG_LPC18XX_UART0
+               bool "Kernel low-level debugging via LPC18xx/43xx UART0"
+               depends on ARCH_LPC18XX
+               select DEBUG_UART_8250
+               help
+                 Say Y here if you want kernel low-level debugging support
+                 on NXP LPC18xx/43xx UART0.
+
        config DEBUG_MESON_UARTAO
                bool "Kernel low-level debugging via Meson6 UARTAO"
                depends on ARCH_MESON
@@ -908,13 +923,22 @@ choice
                  on SA-11x0 UART ports. The kernel will check for the first
                  enabled UART in a sequence 3-1-2.
 
-       config DEBUG_SOCFPGA_UART
+       config DEBUG_SOCFPGA_UART0
+               depends on ARCH_SOCFPGA
+               bool "Use SOCFPGA UART0 for low-level debug"
+               select DEBUG_UART_8250
+               help
+                 Say Y here if you want kernel low-level debugging support
+                 on SOCFPGA(Cyclone 5 and Arria 5) based platforms.
+
+       config DEBUG_SOCFPGA_UART1
                depends on ARCH_SOCFPGA
-               bool "Use SOCFPGA UART for low-level debug"
+               bool "Use SOCFPGA UART1 for low-level debug"
                select DEBUG_UART_8250
                help
                  Say Y here if you want kernel low-level debugging support
-                 on SOCFPGA based platforms.
+                 on SOCFPGA(Arria 10) based platforms.
+
 
        config DEBUG_SUN9I_UART0
                bool "Kernel low-level debugging messages via sun9i UART0"
@@ -1157,6 +1181,18 @@ choice
                  For more details about semihosting, please see
                  chapter 8 of DUI0203I_rvct_developer_guide.pdf from ARM Ltd.
 
+       config DEBUG_ZTE_ZX
+               bool "Use ZTE ZX UART"
+               select DEBUG_UART_PL01X
+               depends on ARCH_ZX
+               help
+                 Say Y here if you are enabling ZTE ZX296702 SOC and need
+                 debug uart support.
+
+                 This option is preferred over the platform specific
+                 options; the platform specific options are deprecated
+                 and will be soon removed.
+
        config DEBUG_LL_UART_8250
                bool "Kernel low-level debugging via 8250 UART"
                help
@@ -1231,7 +1267,8 @@ config DEBUG_IMX_UART_PORT
                                                DEBUG_IMX53_UART || \
                                                DEBUG_IMX6Q_UART || \
                                                DEBUG_IMX6SL_UART || \
-                                               DEBUG_IMX6SX_UART
+                                               DEBUG_IMX6SX_UART || \
+                                               DEBUG_IMX7D_UART
        default 1
        depends on ARCH_MXC
        help
@@ -1281,7 +1318,8 @@ config DEBUG_LL_INCLUDE
                                 DEBUG_IMX53_UART ||\
                                 DEBUG_IMX6Q_UART || \
                                 DEBUG_IMX6SL_UART || \
-                                DEBUG_IMX6SX_UART
+                                DEBUG_IMX6SX_UART || \
+                                DEBUG_IMX7D_UART
        default "debug/ks8695.S" if DEBUG_KS8695_UART
        default "debug/msm.S" if DEBUG_QCOM_UARTDM
        default "debug/netx.S" if DEBUG_NETX_UART
@@ -1337,6 +1375,7 @@ config DEBUG_UART_PHYS
        default 0x02531000 if DEBUG_KEYSTONE_UART1
        default 0x03010fe0 if ARCH_RPC
        default 0x07000000 if DEBUG_SUN9I_UART0
+       default 0x09405000 if DEBUG_ZTE_ZX
        default 0x10009000 if DEBUG_REALVIEW_STD_PORT || \
                                DEBUG_VEXPRESS_UART0_CA9
        default 0x1010c000 if DEBUG_REALVIEW_PB1176_PORT
@@ -1359,6 +1398,7 @@ config DEBUG_UART_PHYS
        default 0x20201000 if DEBUG_BCM2835
        default 0x3e000000 if DEBUG_BCM_KONA_UART
        default 0x4000e400 if DEBUG_LL_UART_EFM32
+       default 0x40081000 if DEBUG_LPC18XX_UART0
        default 0x40090000 if ARCH_LPC32XX
        default 0x40100000 if DEBUG_PXA_UART1
        default 0x42000000 if ARCH_GEMINI
@@ -1407,7 +1447,8 @@ config DEBUG_UART_PHYS
        default 0xfd883000 if DEBUG_ALPINE_UART0
        default 0xfe800000 if ARCH_IOP32X
        default 0xff690000 if DEBUG_RK32_UART2
-       default 0xffc02000 if DEBUG_SOCFPGA_UART
+       default 0xffc02000 if DEBUG_SOCFPGA_UART0
+       default 0xffc02100 if DEBUG_SOCFPGA_UART1
        default 0xffd82340 if ARCH_IOP13XX
        default 0xffe40000 if DEBUG_RCAR_GEN1_SCIF0
        default 0xffe42000 if DEBUG_RCAR_GEN1_SCIF2
@@ -1466,6 +1507,7 @@ config DEBUG_UART_VIRT
        default 0xfb009000 if DEBUG_REALVIEW_STD_PORT
        default 0xfb10c000 if DEBUG_REALVIEW_PB1176_PORT
        default 0xfc40ab00 if DEBUG_BRCMSTB_UART
+       default 0xfc705000 if DEBUG_ZTE_ZX
        default 0xfcfe8600 if DEBUG_UART_BCM63XX
        default 0xfd000000 if ARCH_SPEAR3XX || ARCH_SPEAR6XX
        default 0xfd000000 if ARCH_SPEAR13XX
@@ -1485,7 +1527,8 @@ config DEBUG_UART_VIRT
        default 0xfeb26000 if DEBUG_RK3X_UART1
        default 0xfeb30c00 if DEBUG_KEYSTONE_UART0
        default 0xfeb31000 if DEBUG_KEYSTONE_UART1
-       default 0xfec02000 if DEBUG_SOCFPGA_UART
+       default 0xfec02000 if DEBUG_SOCFPGA_UART0
+       default 0xfec02100 if DEBUG_SOCFPGA_UART1
        default 0xfec12000 if DEBUG_MVEBU_UART0 || DEBUG_MVEBU_UART0_ALTERNATE
        default 0xfec12100 if DEBUG_MVEBU_UART1_ALTERNATE
        default 0xfec10000 if DEBUG_SIRFATLAS7_UART0
@@ -1530,8 +1573,9 @@ config DEBUG_UART_8250_WORD
        bool "Use 32-bit accesses for 8250 UART"
        depends on DEBUG_LL_UART_8250 || DEBUG_UART_8250
        depends on DEBUG_UART_8250_SHIFT >= 2
-       default y if DEBUG_PICOXCELL_UART || DEBUG_SOCFPGA_UART || \
-               ARCH_KEYSTONE || DEBUG_ALPINE_UART0 || \
+       default y if DEBUG_PICOXCELL_UART || DEBUG_SOCFPGA_UART0 || \
+               DEBUG_SOCFPGA_UART1 || ARCH_KEYSTONE || \
+               DEBUG_ALPINE_UART0 || \
                DEBUG_DAVINCI_DMx_UART0 || DEBUG_DAVINCI_DA8XX_UART1 || \
                DEBUG_DAVINCI_DA8XX_UART2 || \
                DEBUG_BCM_KONA_UART || DEBUG_RK32_UART2 || \
@@ -1544,7 +1588,7 @@ config DEBUG_UART_8250_FLOW_CONTROL
 
 config DEBUG_UNCOMPRESS
        bool
-       depends on ARCH_MULTIPLATFORM || PLAT_SAMSUNG
+       depends on ARCH_MULTIPLATFORM || PLAT_SAMSUNG || ARM_SINGLE_ARMV7M
        default y if DEBUG_LL && !DEBUG_OMAP2PLUS_UART && \
                     (!DEBUG_TEGRA_UART || !ZBOOT_ROM)
        help
@@ -1561,7 +1605,7 @@ config DEBUG_UNCOMPRESS
 config UNCOMPRESS_INCLUDE
        string
        default "debug/uncompress.h" if ARCH_MULTIPLATFORM || ARCH_MSM || \
-                                       PLAT_SAMSUNG || ARCH_EFM32 || \
+                                       PLAT_SAMSUNG || ARM_SINGLE_ARMV7M || \
                                        ARCH_SHMOBILE_LEGACY
        default "mach/uncompress.h"
 
index 985227c..2a4fae7 100644 (file)
@@ -167,6 +167,7 @@ machine-$(CONFIG_ARCH_IOP33X)               += iop33x
 machine-$(CONFIG_ARCH_IXP4XX)          += ixp4xx
 machine-$(CONFIG_ARCH_KEYSTONE)                += keystone
 machine-$(CONFIG_ARCH_KS8695)          += ks8695
+machine-$(CONFIG_ARCH_LPC18XX)         += lpc18xx
 machine-$(CONFIG_ARCH_LPC32XX)         += lpc32xx
 machine-$(CONFIG_ARCH_MESON)           += meson
 machine-$(CONFIG_ARCH_MMP)             += mmp
@@ -196,14 +197,17 @@ machine-$(CONFIG_ARCH_SHMOBILE)   += shmobile
 machine-$(CONFIG_ARCH_SIRF)            += prima2
 machine-$(CONFIG_ARCH_SOCFPGA)         += socfpga
 machine-$(CONFIG_ARCH_STI)             += sti
+machine-$(CONFIG_ARCH_STM32)           += stm32
 machine-$(CONFIG_ARCH_SUNXI)           += sunxi
 machine-$(CONFIG_ARCH_TEGRA)           += tegra
 machine-$(CONFIG_ARCH_U300)            += u300
 machine-$(CONFIG_ARCH_U8500)           += ux500
+machine-$(CONFIG_ARCH_UNIPHIER)                += uniphier
 machine-$(CONFIG_ARCH_VERSATILE)       += versatile
 machine-$(CONFIG_ARCH_VEXPRESS)                += vexpress
 machine-$(CONFIG_ARCH_VT8500)          += vt8500
 machine-$(CONFIG_ARCH_W90X900)         += w90x900
+machine-$(CONFIG_ARCH_ZX)              += zx
 machine-$(CONFIG_ARCH_ZYNQ)            += zynq
 machine-$(CONFIG_PLAT_SPEAR)           += spear
 
index 992736b..c52002c 100644 (file)
@@ -660,6 +660,7 @@ dtb-$(CONFIG_ARCH_MEDIATEK) += \
        mt6592-evb.dtb \
        mt8127-moose.dtb \
        mt8135-evbp1.dtb
+dtb-$(CONFIG_ARCH_ZX) += zx296702-ad1.dtb
 endif
 
 always         := $(dtb-y)
diff --git a/arch/arm/boot/dts/zx296702-ad1.dts b/arch/arm/boot/dts/zx296702-ad1.dts
new file mode 100644 (file)
index 0000000..081f980
--- /dev/null
@@ -0,0 +1,48 @@
+
+/dts-v1/;
+
+#include "zx296702.dtsi"
+
+/ {
+       model = "ZTE ZX296702 AD1 Board";
+       compatible = "zte,zx296702-ad1", "zte,zx296702";
+
+       aliases {
+               serial0 = &uart0;
+               serial1 = &uart1;
+       };
+
+       memory {
+               reg = <0x50000000 0x20000000>;
+       };
+};
+
+&mmc0 {
+       num-slots = <1>;
+       supports-highspeed;
+       non-removable;
+       disable-wp;
+       status = "okay";
+
+       slot@0 {
+               reg = <0>;
+               bus-width = <4>;
+       };
+};
+
+&mmc1 {
+       num-slots = <1>;
+       supports-highspeed;
+       non-removable;
+       disable-wp;
+       status = "okay";
+
+       slot@0 {
+               reg = <0>;
+               bus-width = <8>;
+       };
+};
+
+&uart0 {
+       status = "okay";
+};
diff --git a/arch/arm/boot/dts/zx296702.dtsi b/arch/arm/boot/dts/zx296702.dtsi
new file mode 100644 (file)
index 0000000..d45c8fc
--- /dev/null
@@ -0,0 +1,139 @@
+
+#include "skeleton.dtsi"
+#include <dt-bindings/clock/zx296702-clock.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+
+/ {
+       cpus {
+               #address-cells = <1>;
+               #size-cells = <0>;
+               enable-method = "zte,zx296702-smp";
+
+               cpu@0 {
+                       compatible = "arm,cortex-a9";
+                       device_type = "cpu";
+                       next-level-cache = <&l2cc>;
+                       reg = <0>;
+               };
+
+               cpu@1 {
+                       compatible = "arm,cortex-a9";
+                       device_type = "cpu";
+                       next-level-cache = <&l2cc>;
+                       reg = <1>;
+               };
+       };
+
+
+       soc {
+               #address-cells = <1>;
+               #size-cells = <1>;
+               compatible = "simple-bus";
+               interrupt-parent = <&intc>;
+               ranges;
+
+               matrix: bus-matrix@400000 {
+                       compatible = "zte,zx-bus-matrix";
+                       reg = <0x00400000 0x1000>;
+               };
+
+               intc: interrupt-controller@00801000 {
+                       compatible = "arm,cortex-a9-gic";
+                       #interrupt-cells = <3>;
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       interrupt-controller;
+                       reg = <0x00801000 0x1000>,
+                             <0x00800100 0x100>;
+               };
+
+               global_timer: timer@008000200 {
+                       compatible = "arm,cortex-a9-global-timer";
+                       reg = <0x00800200 0x20>;
+                       interrupts = <GIC_PPI 11 IRQ_TYPE_LEVEL_HIGH>;
+                       interrupt-parent = <&intc>;
+                       clocks = <&topclk ZX296702_A9_PERIPHCLK>;
+               };
+
+               l2cc: l2-cache-controller@0x00c00000 {
+                       compatible = "arm,pl310-cache";
+                       reg = <0x00c00000 0x1000>;
+                       cache-unified;
+                       cache-level = <2>;
+                       arm,data-latency = <1 1 1>;
+                       arm,tag-latency = <1 1 1>;
+                       arm,double-linefill = <1>;
+                       arm,double-linefill-incr = <0>;
+               };
+
+               pcu: pcu@0xa0008000 {
+                       compatible = "zte,zx296702-pcu";
+                       reg = <0xa0008000 0x1000>;
+               };
+
+               topclk: topclk@0x09800000 {
+                       compatible = "zte,zx296702-topcrm-clk";
+                       reg = <0x09800000 0x1000>;
+                       #clock-cells = <1>;
+               };
+
+               lsp1clk: lsp1clk@0x09400000 {
+                       compatible = "zte,zx296702-lsp1crpm-clk";
+                       reg = <0x09400000 0x1000>;
+                       #clock-cells = <1>;
+               };
+
+               lsp0clk: lsp0clk@0x0b000000 {
+                       compatible = "zte,zx296702-lsp0crpm-clk";
+                       reg = <0x0b000000 0x1000>;
+                       #clock-cells = <1>;
+               };
+
+               uart0: serial@0x09405000 {
+                       compatible = "zte,zx296702-uart";
+                       reg = <0x09405000 0x1000>;
+                       interrupts = <GIC_SPI 37 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&lsp1clk ZX296702_UART0_WCLK>;
+                       status = "disabled";
+               };
+
+               uart1: serial@0x09406000 {
+                       compatible = "zte,zx296702-uart";
+                       reg = <0x09406000 0x1000>;
+                       interrupts = <GIC_SPI 38 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&lsp1clk ZX296702_UART1_WCLK>;
+                       status = "disabled";
+               };
+
+               mmc0: mmc@0x09408000 {
+                       compatible = "snps,dw-mshc";
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       reg = <0x09408000 0x1000>;
+                       interrupts = <GIC_SPI 40 IRQ_TYPE_LEVEL_HIGH>;
+                       fifo-depth = <32>;
+                       clocks = <&lsp1clk ZX296702_SDMMC0_PCLK>,
+                                <&lsp1clk ZX296702_SDMMC0_WCLK>;
+                       clock-names = "biu", "ciu";
+                       status = "disabled";
+               };
+
+               mmc1: mmc@0x0b003000 {
+                       compatible = "snps,dw-mshc";
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       reg = <0x0b003000 0x1000>;
+                       interrupts = <GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH>;
+                       fifo-depth = <32>;
+                       clocks = <&lsp0clk ZX296702_SDMMC1_PCLK>,
+                                <&lsp0clk ZX296702_SDMMC1_WCLK>;
+                       clock-names = "biu", "ciu";
+                       status = "disabled";
+               };
+
+               sysctrl: sysctrl@0xa0007000 {
+                       compatible = "zte,sysctrl", "syscon";
+                       reg = <0xa0007000 0x1000>;
+               };
+       };
+};
index c4c17e3..e969f78 100644 (file)
@@ -16,6 +16,7 @@ CONFIG_EMBEDDED=y
 # CONFIG_IOSCHED_DEADLINE is not set
 # CONFIG_IOSCHED_CFQ is not set
 # CONFIG_MMU is not set
+CONFIG_ARM_SINGLE_ARMV7M=y
 CONFIG_ARCH_EFM32=y
 CONFIG_SET_MEM_PARAM=y
 CONFIG_DRAM_BASE=0x88000000
diff --git a/arch/arm/configs/zx_defconfig b/arch/arm/configs/zx_defconfig
new file mode 100644 (file)
index 0000000..b200bb0
--- /dev/null
@@ -0,0 +1,129 @@
+CONFIG_EXPERIMENTAL=y
+CONFIG_SYSVIPC=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_CGROUPS=y
+CONFIG_CGROUP_DEBUG=y
+CONFIG_CGROUP_FREEZER=y
+CONFIG_CGROUP_CPUACCT=y
+CONFIG_RESOURCE_COUNTERS=y
+CONFIG_CGROUP_SCHED=y
+CONFIG_RT_GROUP_SCHED=y
+CONFIG_NAMESPACES=y
+CONFIG_USER_NS=y
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_KALLSYMS_ALL=y
+CONFIG_EMBEDDED=y
+CONFIG_PERF_EVENTS=y
+CONFIG_SLAB=y
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_IOSCHED_CFQ is not set
+CONFIG_ARCH_ZX=y
+CONFIG_SOC_ZX296702=y
+# CONFIG_SWP_EMULATE is not set
+CONFIG_ARM_ERRATA_754322=y
+CONFIG_ARM_ERRATA_775420=y
+CONFIG_SMP=y
+CONFIG_VMSPLIT_2G=y
+CONFIG_PREEMPT=y
+CONFIG_AEABI=y
+CONFIG_KSM=y
+# CONFIG_IOMMU_SUPPORT is not set
+CONFIG_VFP=y
+CONFIG_NEON=y
+CONFIG_KERNEL_MODE_NEON=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+CONFIG_HIBERNATION=y
+CONFIG_PM_RUNTIME=y
+CONFIG_PM_DEBUG=y
+CONFIG_SUSPEND_TIME=y
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE="console=ttyAMA0,115200 debug earlyprintk root=/dev/ram rw rootwait"
+#CONFIG_NET is not set
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_DEVTMPFS=y
+CONFIG_DEVTMPFS_MOUNT=y
+CONFIG_DMA_CMA=y
+CONFIG_CMA_SIZE_MBYTES=192
+CONFIG_BLK_DEV_LOOP=y
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=1
+CONFIG_BLK_DEV_RAM_SIZE=8192
+CONFIG_UID_STAT=y
+CONFIG_SCSI=y
+CONFIG_BLK_DEV_SD=y
+CONFIG_CHR_DEV_SG=y
+CONFIG_CHR_DEV_SCH=y
+CONFIG_SCSI_MULTI_LUN=y
+CONFIG_MD=y
+CONFIG_BLK_DEV_DM=y
+CONFIG_DM_CRYPT=y
+CONFIG_DM_UEVENT=y
+CONFIG_DM_VERITY=y
+CONFIG_NETDEVICES=y
+# CONFIG_INPUT_MOUSE is not set
+CONFIG_SERIO=y
+CONFIG_SERIO_LIBPS2=y
+CONFIG_SPI=y
+CONFIG_LOGO=y
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_CONSOLE_POLL=y
+CONFIG_SERIAL_AMBA_PL011=y
+CONFIG_SERIAL_AMBA_PL011_CONSOLE=y
+CONFIG_SERIAL_OF_PLATFORM=y
+# CONFIG_LEGACY_PTYS is not set
+# CONFIG_HW_RANDOM is not set
+# CONFIG_HWMON is not set
+# CONFIG_USB_SUPPORT is not set
+CONFIG_MMC=y
+CONFIG_MMC_UNSAFE_RESUME=y
+CONFIG_MMC_BLOCK_MINORS=16
+CONFIG_MMC_DW=y
+CONFIG_MMC_DW_IDMAC=y
+CONFIG_EXT2_FS=y
+CONFIG_EXT4_FS=y
+CONFIG_EXT4_FS_POSIX_ACL=y
+CONFIG_EXT4_FS_SECURITY=y
+CONFIG_EXT4_DEBUG=y
+CONFIG_FUSE_FS=y
+CONFIG_MSDOS_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_FAT_DEFAULT_CODEPAGE=936
+CONFIG_TMPFS=y
+CONFIG_TMPFS_POSIX_ACL=y
+#CONFIG_NFS_FS is not set
+CONFIG_NLS_CODEPAGE_936=y
+CONFIG_NLS_ISO8859_1=y
+CONFIG_NLS_UTF8=y
+CONFIG_PRINTK_TIME=y
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_DEBUG_KERNEL=y
+CONFIG_DEBUG_INFO=y
+CONFIG_FRAME_WARN=4096
+CONFIG_DEBUG_FS=y
+CONFIG_DEBUG_MEMORY_INIT=y
+CONFIG_PANIC_TIMEOUT=5
+# CONFIG_SCHED_DEBUG is not set
+CONFIG_SCHEDSTATS=y
+CONFIG_TIMER_STATS=y
+CONFIG_DEBUG_RT_MUTEXES=y
+CONFIG_DEBUG_SPINLOCK=y
+CONFIG_DEBUG_MUTEXES=y
+CONFIG_RCU_CPU_STALL_TIMEOUT=60
+# CONFIG_FTRACE is not set
+CONFIG_KGDB=y
+CONFIG_KGDB_KDB=y
+# CONFIG_ARM_UNWIND is not set
+CONFIG_DEBUG_PREEMPT=y
+CONFIG_DEBUG_USER=y
+CONFIG_DEBUG_LL=y
+CONFIG_DYNAMIC_DEBUG=y
+CONFIG_STACKTRACE=y
+CONFIG_DEBUG_ZTE_ZX=y
+CONFIG_EARLY_PRINTK=y
+CONFIG_CRYPTO_LZO=y
+CONFIG_GPIOLIB=y
index 89aefe1..34c1d96 100644 (file)
@@ -34,6 +34,10 @@ struct firmware_ops {
         */
        int (*set_cpu_boot_addr)(int cpu, unsigned long boot_addr);
        /*
+        * Gets boot address of specified physical CPU
+        */
+       int (*get_cpu_boot_addr)(int cpu, unsigned long *boot_addr);
+       /*
         * Boots specified physical CPU
         */
        int (*cpu_boot)(int cpu);
index ee5f308..22e4140 100644 (file)
@@ -5,6 +5,9 @@
  * First, the standard VFP set.
  */
 
+#ifndef __ASM_VFP_H
+#define __ASM_VFP_H
+
 #define FPSID                  cr0
 #define FPSCR                  cr1
 #define MVFR1                  cr6
@@ -87,3 +90,9 @@
 #define VFPOPDESC_UNUSED_BIT   (24)
 #define VFPOPDESC_UNUSED_MASK  (0xFF << VFPOPDESC_UNUSED_BIT)
 #define VFPOPDESC_OPDESC_MASK  (~(VFPOPDESC_LENGTH_MASK | VFPOPDESC_UNUSED_MASK))
+
+#ifndef __ASSEMBLY__
+void vfp_disable(void);
+#endif
+
+#endif /* __ASM_VFP_H */
index 7a2baf9..7f7446f 100644 (file)
 
 #ifdef CONFIG_DEBUG_UART_8250_WORD
                .macro  store, rd, rx:vararg
+        ARM_BE8(rev \rd, \rd)
                str     \rd, \rx
+        ARM_BE8(rev \rd, \rd)
                .endm
 
                .macro  load, rd, rx:vararg
                ldr     \rd, \rx
+       ARM_BE8(rev \rd, \rd)
                .endm
 #else
                .macro  store, rd, rx:vararg
index 2265a19..660fa1e 100644 (file)
@@ -16,7 +16,7 @@
 
 #define        UARTn_TXDATA            0x0034
 
-               .macro  addruart, rx, tmp
+               .macro  addruart, rx, tmp, tmp2
                ldr     \rx, =(CONFIG_DEBUG_UART_PHYS)
 
                /*
index 032a316..66f736f 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2012 Freescale Semiconductor, Inc.
+ * Copyright (C) 2012-2015 Freescale Semiconductor, Inc.
  *
  * 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
 #define IMX6SX_UART_BASE_ADDR(n) IMX6SX_UART##n##_BASE_ADDR
 #define IMX6SX_UART_BASE(n)    IMX6SX_UART_BASE_ADDR(n)
 
+#define IMX7D_UART1_BASE_ADDR  0x30860000
+#define IMX7D_UART2_BASE_ADDR  0x30890000
+#define IMX7D_UART3_BASE_ADDR  0x30880000
+#define IMX7D_UART4_BASE_ADDR  0x30a60000
+#define IMX7D_UART5_BASE_ADDR  0x30a70000
+#define IMX7D_UART6_BASE_ADDR  0x30a80000
+#define IMX7D_UART7_BASE_ADDR  0x30a90000
+#define IMX7D_UART_BASE_ADDR(n) IMX7D_UART##n##_BASE_ADDR
+#define IMX7D_UART_BASE(n)     IMX7D_UART_BASE_ADDR(n)
+
 #define IMX_DEBUG_UART_BASE(soc) soc##_UART_BASE(CONFIG_DEBUG_IMX_UART_PORT)
 
 #ifdef CONFIG_DEBUG_IMX1_UART
 #define UART_PADDR     IMX_DEBUG_UART_BASE(IMX6SL)
 #elif defined(CONFIG_DEBUG_IMX6SX_UART)
 #define UART_PADDR     IMX_DEBUG_UART_BASE(IMX6SX)
+#elif defined(CONFIG_DEBUG_IMX7D_UART)
+#define UART_PADDR     IMX_DEBUG_UART_BASE(IMX7D)
+
 #endif
 
 #endif /* __DEBUG_IMX_UART_H */
index 92ef808..f7d8323 100644 (file)
 */
 #include <linux/amba/serial.h>
 
+#ifdef CONFIG_DEBUG_ZTE_ZX
+#undef UART01x_DR
+#undef UART01x_FR
+#define UART01x_DR     0x04
+#define UART01x_FR     0x14
+#endif
+
 #ifdef CONFIG_DEBUG_UART_PHYS
                .macro  addruart, rp, rv, tmp
                ldr     \rp, =CONFIG_DEBUG_UART_PHYS
index 78c91b5..ea9646c 100644 (file)
@@ -35,7 +35,7 @@
 
 #else /* !CONFIG_MMU */
                .macro  addruart_current, rx, tmp1, tmp2
-               addruart        \rx, \tmp1
+               addruart        \rx, \tmp1, \tmp2
                .endm
 
 #endif /* CONFIG_MMU */
index 8b11f44..e9184fe 100644 (file)
@@ -19,6 +19,7 @@ config ARCH_BCM_IPROC
        select ARCH_REQUIRE_GPIOLIB
        select ARM_AMBA
        select PINCTRL
+       select MTD_NAND_BRCMNAND
        help
          This enables support for systems based on Broadcom IPROC architected SoCs.
          The IPROC complex contains one or more ARM CPUs along with common
@@ -144,6 +145,7 @@ config ARCH_BRCMSTB
        select BRCMSTB_GISB_ARB
        select BRCMSTB_L2_IRQ
        select BCM7120_L2_IRQ
+       select ARCH_WANT_OPTIONAL_GPIOLIB
        help
          Say Y if you intend to run the kernel on a Broadcom ARM-based STB
          chipset.
index 54d274d..4fb0da4 100644 (file)
@@ -38,7 +38,12 @@ obj-$(CONFIG_ARCH_BCM2835)   += board_bcm2835.o
 obj-$(CONFIG_ARCH_BCM_5301X)   += bcm_5301x.o
 
 # BCM63XXx
-obj-$(CONFIG_ARCH_BCM_63XX)    := bcm63xx.o
+ifeq ($(CONFIG_ARCH_BCM_63XX),y)
+CFLAGS_bcm63xx_headsmp.o       += -march=armv7-a
+obj-y                          += bcm63xx.o
+obj-$(CONFIG_SMP)              += bcm63xx_smp.o bcm63xx_headsmp.o \
+                                  bcm63xx_pmb.o
+endif
 
 ifeq ($(CONFIG_ARCH_BRCMSTB),y)
 CFLAGS_platsmp-brcmstb.o       += -march=armv7-a
diff --git a/arch/arm/mach-bcm/bcm63xx_headsmp.S b/arch/arm/mach-bcm/bcm63xx_headsmp.S
new file mode 100644 (file)
index 0000000..c7af397
--- /dev/null
@@ -0,0 +1,23 @@
+/*
+ *  Copyright (C) 2015, Broadcom Corporation
+ *  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>
+#include <asm/assembler.h>
+
+ENTRY(bcm63138_secondary_startup)
+ ARM_BE8(setend        be)
+       /*
+        * L1 cache does have unpredictable contents at power-up clean its
+        * contents without flushing
+        */
+       bl      v7_invalidate_l1
+       nop
+
+       b       secondary_startup
+ENDPROC(bcm63138_secondary_startup)
diff --git a/arch/arm/mach-bcm/bcm63xx_pmb.c b/arch/arm/mach-bcm/bcm63xx_pmb.c
new file mode 100644 (file)
index 0000000..de061ec
--- /dev/null
@@ -0,0 +1,221 @@
+/*
+ * Broadcom BCM63138 PMB initialization for secondary CPU(s)
+ *
+ * Copyright (C) 2015 Broadcom Corporation
+ * Author: Florian Fainelli <f.fainelli@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+#include <linux/kernel.h>
+#include <linux/io.h>
+#include <linux/spinlock.h>
+#include <linux/reset/bcm63xx_pmb.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+
+#include "bcm63xx_smp.h"
+
+/* ARM Control register definitions */
+#define CORE_PWR_CTRL_SHIFT    0
+#define CORE_PWR_CTRL_MASK     0x3
+#define PLL_PWR_ON             BIT(8)
+#define PLL_LDO_PWR_ON         BIT(9)
+#define PLL_CLAMP_ON           BIT(10)
+#define CPU_RESET_N(x)         BIT(13 + (x))
+#define NEON_RESET_N           BIT(15)
+#define PWR_CTRL_STATUS_SHIFT  28
+#define PWR_CTRL_STATUS_MASK   0x3
+#define PWR_DOWN_SHIFT         30
+#define PWR_DOWN_MASK          0x3
+
+/* CPU Power control register definitions */
+#define MEM_PWR_OK             BIT(0)
+#define MEM_PWR_ON             BIT(1)
+#define MEM_CLAMP_ON           BIT(2)
+#define MEM_PWR_OK_STATUS      BIT(4)
+#define MEM_PWR_ON_STATUS      BIT(5)
+#define MEM_PDA_SHIFT          8
+#define MEM_PDA_MASK           0xf
+#define  MEM_PDA_CPU_MASK      0x1
+#define  MEM_PDA_NEON_MASK     0xf
+#define CLAMP_ON               BIT(15)
+#define PWR_OK_SHIFT           16
+#define PWR_OK_MASK            0xf
+#define PWR_ON_SHIFT           20
+#define  PWR_CPU_MASK          0x03
+#define  PWR_NEON_MASK         0x01
+#define PWR_ON_MASK            0xf
+#define PWR_OK_STATUS_SHIFT    24
+#define PWR_OK_STATUS_MASK     0xf
+#define PWR_ON_STATUS_SHIFT    28
+#define PWR_ON_STATUS_MASK     0xf
+
+#define ARM_CONTROL            0x30
+#define ARM_PWR_CONTROL_BASE   0x34
+#define ARM_PWR_CONTROL(x)     (ARM_PWR_CONTROL_BASE + (x) * 0x4)
+#define ARM_NEON_L2            0x3c
+
+/* Perform a value write, then spin until the value shifted by
+ * shift is seen, masked with mask and is different from cond.
+ */
+static int bpcm_wr_rd_mask(void __iomem *master,
+                          unsigned int addr, u32 off, u32 *val,
+                          u32 shift, u32 mask, u32 cond)
+{
+       int ret;
+
+       ret = bpcm_wr(master, addr, off, *val);
+       if (ret)
+               return ret;
+
+       do {
+               ret = bpcm_rd(master, addr, off, val);
+               if (ret)
+                       return ret;
+
+               cpu_relax();
+       } while (((*val >> shift) & mask) != cond);
+
+       return ret;
+}
+
+/* Global lock to serialize accesses to the PMB registers while we
+ * are bringing up the secondary CPU
+ */
+static DEFINE_SPINLOCK(pmb_lock);
+
+static int bcm63xx_pmb_get_resources(struct device_node *dn,
+                                    void __iomem **base,
+                                    unsigned int *cpu,
+                                    unsigned int *addr)
+{
+       struct device_node *pmb_dn;
+       struct of_phandle_args args;
+       int ret;
+
+       ret = of_property_read_u32(dn, "reg", cpu);
+       if (ret) {
+               pr_err("CPU is missing a reg node\n");
+               return ret;
+       }
+
+       ret = of_parse_phandle_with_args(dn, "resets", "#reset-cells",
+                                        0, &args);
+       if (ret) {
+               pr_err("CPU is missing a resets phandle\n");
+               return ret;
+       }
+
+       pmb_dn = args.np;
+       if (args.args_count != 2) {
+               pr_err("reset-controller does not conform to reset-cells\n");
+               return -EINVAL;
+       }
+
+       *base = of_iomap(args.np, 0);
+       if (!*base) {
+               pr_err("failed remapping PMB register\n");
+               return -ENOMEM;
+       }
+
+       /* We do not need the number of zones */
+       *addr = args.args[0];
+
+       return 0;
+}
+
+int bcm63xx_pmb_power_on_cpu(struct device_node *dn)
+{
+       void __iomem *base;
+       unsigned int cpu, addr;
+       unsigned long flags;
+       u32 val, ctrl;
+       int ret;
+
+       ret = bcm63xx_pmb_get_resources(dn, &base, &cpu, &addr);
+       if (ret)
+               return ret;
+
+       /* We would not know how to enable a third and greater CPU */
+       WARN_ON(cpu > 1);
+
+       spin_lock_irqsave(&pmb_lock, flags);
+
+       /* Check if the CPU is already on and save the ARM_CONTROL register
+        * value since we will use it later for CPU de-assert once done with
+        * the CPU-specific power sequence
+        */
+       ret = bpcm_rd(base, addr, ARM_CONTROL, &ctrl);
+       if (ret)
+               goto out;
+
+       if (ctrl & CPU_RESET_N(cpu)) {
+               pr_info("PMB: CPU%d is already powered on\n", cpu);
+               ret = 0;
+               goto out;
+       }
+
+       /* Power on PLL */
+       ret = bpcm_rd(base, addr, ARM_PWR_CONTROL(cpu), &val);
+       if (ret)
+               goto out;
+
+       val |= (PWR_CPU_MASK << PWR_ON_SHIFT);
+
+       ret = bpcm_wr_rd_mask(base, addr, ARM_PWR_CONTROL(cpu), &val,
+                       PWR_ON_STATUS_SHIFT, PWR_CPU_MASK, PWR_CPU_MASK);
+       if (ret)
+               goto out;
+
+       val |= (PWR_CPU_MASK << PWR_OK_SHIFT);
+
+       ret = bpcm_wr_rd_mask(base, addr, ARM_PWR_CONTROL(cpu), &val,
+                       PWR_OK_STATUS_SHIFT, PWR_CPU_MASK, PWR_CPU_MASK);
+       if (ret)
+               goto out;
+
+       val &= ~CLAMP_ON;
+
+       ret = bpcm_wr(base, addr, ARM_PWR_CONTROL(cpu), val);
+       if (ret)
+               goto out;
+
+       /* Power on CPU<N> RAM */
+       val &= ~(MEM_PDA_MASK << MEM_PDA_SHIFT);
+
+       ret = bpcm_wr(base, addr, ARM_PWR_CONTROL(cpu), val);
+       if (ret)
+               goto out;
+
+       val |= MEM_PWR_ON;
+
+       ret = bpcm_wr_rd_mask(base, addr, ARM_PWR_CONTROL(cpu), &val,
+                       0, MEM_PWR_ON_STATUS, MEM_PWR_ON_STATUS);
+       if (ret)
+               goto out;
+
+       val |= MEM_PWR_OK;
+
+       ret = bpcm_wr_rd_mask(base, addr, ARM_PWR_CONTROL(cpu), &val,
+                       0, MEM_PWR_OK_STATUS, MEM_PWR_OK_STATUS);
+       if (ret)
+               goto out;
+
+       val &= ~MEM_CLAMP_ON;
+
+       ret = bpcm_wr(base, addr, ARM_PWR_CONTROL(cpu), val);
+       if (ret)
+               goto out;
+
+       /* De-assert CPU reset */
+       ctrl |= CPU_RESET_N(cpu);
+
+       ret = bpcm_wr(base, addr, ARM_CONTROL, ctrl);
+out:
+       spin_unlock_irqrestore(&pmb_lock, flags);
+       iounmap(base);
+       return ret;
+}
diff --git a/arch/arm/mach-bcm/bcm63xx_smp.c b/arch/arm/mach-bcm/bcm63xx_smp.c
new file mode 100644 (file)
index 0000000..3f014f1
--- /dev/null
@@ -0,0 +1,169 @@
+/*
+ * Broadcom BCM63138 DSL SoCs SMP support code
+ *
+ * Copyright (C) 2015, Broadcom Corporation
+ *
+ * Licensed under the terms of the GPLv2
+ */
+
+#include <linux/delay.h>
+#include <linux/init.h>
+#include <linux/smp.h>
+#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+
+#include <asm/cacheflush.h>
+#include <asm/smp_scu.h>
+#include <asm/smp_plat.h>
+#include <asm/vfp.h>
+
+#include "bcm63xx_smp.h"
+
+/* Size of mapped Cortex A9 SCU address space */
+#define CORTEX_A9_SCU_SIZE     0x58
+
+/*
+ * Enable the Cortex A9 Snoop Control Unit
+ *
+ * By the time this is called we already know there are multiple
+ * cores present.  We assume we're running on a Cortex A9 processor,
+ * so any trouble getting the base address register or getting the
+ * SCU base is a problem.
+ *
+ * Return 0 if successful or an error code otherwise.
+ */
+static int __init scu_a9_enable(void)
+{
+       unsigned long config_base;
+       void __iomem *scu_base;
+       unsigned int i, ncores;
+
+       if (!scu_a9_has_base()) {
+               pr_err("no configuration base address register!\n");
+               return -ENXIO;
+       }
+
+       /* Config base address register value is zero for uniprocessor */
+       config_base = scu_a9_get_base();
+       if (!config_base) {
+               pr_err("hardware reports only one core\n");
+               return -ENOENT;
+       }
+
+       scu_base = ioremap((phys_addr_t)config_base, CORTEX_A9_SCU_SIZE);
+       if (!scu_base) {
+               pr_err("failed to remap config base (%lu/%u) for SCU\n",
+                       config_base, CORTEX_A9_SCU_SIZE);
+               return -ENOMEM;
+       }
+
+       scu_enable(scu_base);
+
+       ncores = scu_base ? scu_get_core_count(scu_base) : 1;
+
+       if (ncores > nr_cpu_ids) {
+               pr_warn("SMP: %u cores greater than maximum (%u), clipping\n",
+                               ncores, nr_cpu_ids);
+               ncores = nr_cpu_ids;
+       }
+
+       /* The BCM63138 SoC has two Cortex-A9 CPUs, CPU0 features a complete
+        * and fully functional VFP unit that can be used, but CPU1 does not.
+        * Since we will not be able to trap kernel-mode NEON to force
+        * migration to CPU0, just do not advertise VFP support at all.
+        *
+        * This will make vfp_init bail out and do not attempt to use VFP at
+        * all, for kernel-mode NEON, we do not want to introduce any
+        * conditionals in hot-paths, so we just restrict the system to UP.
+        */
+#ifdef CONFIG_VFP
+       if (ncores > 1) {
+               pr_warn("SMP: secondary CPUs lack VFP unit, disabling VFP\n");
+               vfp_disable();
+
+#ifdef CONFIG_KERNEL_MODE_NEON
+               WARN(1, "SMP: kernel-mode NEON enabled, restricting to UP\n");
+               ncores = 1;
+#endif
+       }
+#endif
+
+       for (i = 0; i < ncores; i++)
+               set_cpu_possible(i, true);
+
+       iounmap(scu_base);      /* That's the last we'll need of this */
+
+       return 0;
+}
+
+static const struct of_device_id bcm63138_bootlut_ids[] = {
+       { .compatible = "brcm,bcm63138-bootlut", },
+       { /* sentinel */ },
+};
+
+#define BOOTLUT_RESET_VECT     0x20
+
+static int bcm63138_smp_boot_secondary(unsigned int cpu,
+                                      struct task_struct *idle)
+{
+       void __iomem *bootlut_base;
+       struct device_node *dn;
+       int ret = 0;
+       u32 val;
+
+       dn = of_find_matching_node(NULL, bcm63138_bootlut_ids);
+       if (!dn) {
+               pr_err("SMP: unable to find bcm63138 boot LUT node\n");
+               return -ENODEV;
+       }
+
+       bootlut_base = of_iomap(dn, 0);
+       of_node_put(dn);
+
+       if (!bootlut_base) {
+               pr_err("SMP: unable to remap boot LUT base register\n");
+               return -ENOMEM;
+       }
+
+       /* Locate the secondary CPU node */
+       dn = of_get_cpu_node(cpu_logical_map(cpu), NULL);
+       if (!dn) {
+               pr_err("SMP: failed to locate secondary CPU%d node\n", cpu);
+               ret = -ENODEV;
+               goto out;
+       }
+
+       /* Write the secondary init routine to the BootLUT reset vector */
+       val = virt_to_phys(bcm63138_secondary_startup);
+       writel_relaxed(val, bootlut_base + BOOTLUT_RESET_VECT);
+
+       /* Power up the core, will jump straight to its reset vector when we
+        * return
+        */
+       ret = bcm63xx_pmb_power_on_cpu(dn);
+       if (ret)
+               goto out;
+out:
+       iounmap(bootlut_base);
+
+       return ret;
+}
+
+static void __init bcm63138_smp_prepare_cpus(unsigned int max_cpus)
+{
+       int ret;
+
+       ret = scu_a9_enable();
+       if (ret) {
+               pr_warn("SMP: Cortex-A9 SCU setup failed\n");
+               return;
+       }
+}
+
+struct smp_operations bcm63138_smp_ops __initdata = {
+       .smp_prepare_cpus       = bcm63138_smp_prepare_cpus,
+       .smp_boot_secondary     = bcm63138_smp_boot_secondary,
+};
+
+CPU_METHOD_OF_DECLARE(bcm63138_smp, "brcm,bcm63138", &bcm63138_smp_ops);
diff --git a/arch/arm/mach-bcm/bcm63xx_smp.h b/arch/arm/mach-bcm/bcm63xx_smp.h
new file mode 100644 (file)
index 0000000..50b7604
--- /dev/null
@@ -0,0 +1,9 @@
+#ifndef __BCM63XX_SMP_H
+#define __BCM63XX_SMP_H
+
+struct device_node;
+
+extern void bcm63138_secondary_startup(void);
+extern int bcm63xx_pmb_power_on_cpu(struct device_node *dn);
+
+#endif /* __BCM63XX_SMP_H */
index e9bcbdb..7aef927 100644 (file)
@@ -18,15 +18,16 @@ static bool first_fault = true;
 static int bcm5301x_abort_handler(unsigned long addr, unsigned int fsr,
                                 struct pt_regs *regs)
 {
-       if (fsr == 0x1c06 && first_fault) {
+       if ((fsr == 0x1406 || fsr == 0x1c06) && first_fault) {
                first_fault = false;
 
                /*
-                * These faults with code 0x1c06 happens for no good reason,
-                * possibly left over from the CFE boot loader.
+                * These faults with codes 0x1406 (BCM4709) or 0x1c06 happens
+                * for no good reason, possibly left over from the CFE boot
+                * loader.
                 */
                pr_warn("External imprecise Data abort at addr=%#lx, fsr=%#x ignored.\n",
-               addr, fsr);
+                       addr, fsr);
 
                /* Returning non-zero causes fault display and panic */
                return 0;
index 70f2f39..0f7b9ea 100644 (file)
@@ -12,7 +12,6 @@
  * GNU General Public License for more details.
  */
 
-#include <linux/delay.h>
 #include <linux/init.h>
 #include <linux/irqchip.h>
 #include <linux/of_address.h>
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
 
-#define PM_RSTC                                0x1c
-#define PM_RSTS                                0x20
-#define PM_WDOG                                0x24
-
-#define PM_PASSWORD                    0x5a000000
-#define PM_RSTC_WRCFG_MASK             0x00000030
-#define PM_RSTC_WRCFG_FULL_RESET       0x00000020
-#define PM_RSTS_HADWRH_SET             0x00000040
-
-#define BCM2835_PERIPH_PHYS    0x20000000
-#define BCM2835_PERIPH_VIRT    0xf0000000
-#define BCM2835_PERIPH_SIZE    SZ_16M
-
-static void __iomem *wdt_regs;
-
-/*
- * The machine restart method can be called from an atomic context so we won't
- * be able to ioremap the regs then.
- */
-static void bcm2835_setup_restart(void)
-{
-       struct device_node *np = of_find_compatible_node(NULL, NULL,
-                                               "brcm,bcm2835-pm-wdt");
-       if (WARN(!np, "unable to setup watchdog restart"))
-               return;
-
-       wdt_regs = of_iomap(np, 0);
-       WARN(!wdt_regs, "failed to remap watchdog regs");
-}
-
-static void bcm2835_restart(enum reboot_mode mode, const char *cmd)
-{
-       u32 val;
-
-       if (!wdt_regs)
-               return;
-
-       /* use a timeout of 10 ticks (~150us) */
-       writel_relaxed(10 | PM_PASSWORD, wdt_regs + PM_WDOG);
-       val = readl_relaxed(wdt_regs + PM_RSTC);
-       val &= ~PM_RSTC_WRCFG_MASK;
-       val |= PM_PASSWORD | PM_RSTC_WRCFG_FULL_RESET;
-       writel_relaxed(val, wdt_regs + PM_RSTC);
-
-       /* No sleeping, possibly atomic. */
-       mdelay(1);
-}
-
-/*
- * We can't really power off, but if we do the normal reset scheme, and
- * indicate to bootcode.bin not to reboot, then most of the chip will be
- * powered off.
- */
-static void bcm2835_power_off(void)
-{
-       u32 val;
-
-       /*
-        * We set the watchdog hard reset bit here to distinguish this reset
-        * from the normal (full) reset. bootcode.bin will not reboot after a
-        * hard reset.
-        */
-       val = readl_relaxed(wdt_regs + PM_RSTS);
-       val &= ~PM_RSTC_WRCFG_MASK;
-       val |= PM_PASSWORD | PM_RSTS_HADWRH_SET;
-       writel_relaxed(val, wdt_regs + PM_RSTS);
-
-       /* Continue with normal reset mechanism */
-       bcm2835_restart(REBOOT_HARD, "");
-}
-
-static struct map_desc io_map __initdata = {
-       .virtual = BCM2835_PERIPH_VIRT,
-       .pfn = __phys_to_pfn(BCM2835_PERIPH_PHYS),
-       .length = BCM2835_PERIPH_SIZE,
-       .type = MT_DEVICE
-};
-
-static void __init bcm2835_map_io(void)
-{
-       iotable_init(&io_map, 1);
-}
-
 static void __init bcm2835_init(void)
 {
        int ret;
 
-       bcm2835_setup_restart();
-       if (wdt_regs)
-               pm_power_off = bcm2835_power_off;
-
        bcm2835_init_clocks();
 
        ret = of_platform_populate(NULL, of_default_bus_match_table, NULL,
@@ -129,9 +41,6 @@ static const char * const bcm2835_compat[] = {
 };
 
 DT_MACHINE_START(BCM2835, "BCM2835")
-       .map_io = bcm2835_map_io,
-       .init_irq = irqchip_init,
        .init_machine = bcm2835_init,
-       .restart = bcm2835_restart,
        .dt_compat = bcm2835_compat
 MACHINE_END
index 36f22c1..3c950f5 100644 (file)
 #include <linux/platform_device.h>
 #include <linux/i2c.h>
 #include <linux/i2c-gpio.h>
+#include <linux/mmc/host.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/mmc_spi.h>
+#include <linux/platform_data/video-ep93xx.h>
+#include <linux/platform_data/spi-ep93xx.h>
+#include <linux/gpio.h>
 
 #include <mach/hardware.h>
-#include <linux/platform_data/video-ep93xx.h>
 #include <mach/gpio-ep93xx.h>
 
 #include <asm/mach-types.h>
@@ -40,6 +45,132 @@ static struct ep93xxfb_mach_info __initdata simone_fb_info = {
        .flags          = EP93XXFB_USE_SDCSN0 | EP93XXFB_PCLK_FALLING,
 };
 
+/*
+ * GPIO lines used for MMC card detection.
+ */
+#define MMC_CARD_DETECT_GPIO EP93XX_GPIO_LINE_EGPIO0
+
+/*
+ * Up to v1.3, the Sim.One used SFRMOUT as SD card chip select, but this goes
+ * low between multi-message command blocks. From v1.4, it uses a GPIO instead.
+ * v1.3 parts will still work, since the signal on SFRMOUT is automatic.
+ */
+#define MMC_CHIP_SELECT_GPIO EP93XX_GPIO_LINE_EGPIO1
+
+/*
+ * MMC SPI chip select GPIO handling. If you are using SFRMOUT (SFRM1) signal,
+ * you can leave these empty and pass NULL as .controller_data.
+ */
+
+static int simone_mmc_spi_setup(struct spi_device *spi)
+{
+       unsigned int gpio = MMC_CHIP_SELECT_GPIO;
+       int err;
+
+       err = gpio_request(gpio, spi->modalias);
+       if (err)
+               return err;
+
+       err = gpio_direction_output(gpio, 1);
+       if (err) {
+               gpio_free(gpio);
+               return err;
+       }
+
+       return 0;
+}
+
+static void simone_mmc_spi_cleanup(struct spi_device *spi)
+{
+       unsigned int gpio = MMC_CHIP_SELECT_GPIO;
+
+       gpio_set_value(gpio, 1);
+       gpio_direction_input(gpio);
+       gpio_free(gpio);
+}
+
+static void simone_mmc_spi_cs_control(struct spi_device *spi, int value)
+{
+       gpio_set_value(MMC_CHIP_SELECT_GPIO, value);
+}
+
+static struct ep93xx_spi_chip_ops simone_mmc_spi_ops = {
+       .setup          = simone_mmc_spi_setup,
+       .cleanup        = simone_mmc_spi_cleanup,
+       .cs_control     = simone_mmc_spi_cs_control,
+};
+
+/*
+ * MMC card detection GPIO setup.
+ */
+
+static int simone_mmc_spi_init(struct device *dev,
+       irqreturn_t (*irq_handler)(int, void *), void *mmc)
+{
+       unsigned int gpio = MMC_CARD_DETECT_GPIO;
+       int irq, err;
+
+       err = gpio_request(gpio, dev_name(dev));
+       if (err)
+               return err;
+
+       err = gpio_direction_input(gpio);
+       if (err)
+               goto fail;
+
+       irq = gpio_to_irq(gpio);
+       if (irq < 0)
+               goto fail;
+
+       err = request_irq(irq, irq_handler, IRQF_TRIGGER_FALLING,
+                         "MMC card detect", mmc);
+       if (err)
+               goto fail;
+
+       printk(KERN_INFO "%s: using irq %d for MMC card detection\n",
+              dev_name(dev), irq);
+
+       return 0;
+fail:
+       gpio_free(gpio);
+       return err;
+}
+
+static void simone_mmc_spi_exit(struct device *dev, void *mmc)
+{
+       unsigned int gpio = MMC_CARD_DETECT_GPIO;
+
+       free_irq(gpio_to_irq(gpio), mmc);
+       gpio_free(gpio);
+}
+
+static struct mmc_spi_platform_data simone_mmc_spi_data = {
+       .init           = simone_mmc_spi_init,
+       .exit           = simone_mmc_spi_exit,
+       .detect_delay   = 500,
+       .ocr_mask       = MMC_VDD_32_33 | MMC_VDD_33_34,
+};
+
+static struct spi_board_info simone_spi_devices[] __initdata = {
+       {
+               .modalias               = "mmc_spi",
+               .controller_data        = &simone_mmc_spi_ops,
+               .platform_data          = &simone_mmc_spi_data,
+               /*
+                * We use 10 MHz even though the maximum is 3.7 MHz. The driver
+                * will limit it automatically to max. frequency.
+                */
+               .max_speed_hz           = 10 * 1000 * 1000,
+               .bus_num                = 0,
+               .chip_select            = 0,
+               .mode                   = SPI_MODE_3,
+       },
+};
+
+static struct ep93xx_spi_info simone_spi_info __initdata = {
+       .num_chipselect = ARRAY_SIZE(simone_spi_devices),
+};
+
 static struct i2c_gpio_platform_data __initdata simone_i2c_gpio_data = {
        .sda_pin                = EP93XX_GPIO_LINE_EEDAT,
        .sda_is_open_drain      = 0,
@@ -74,6 +205,8 @@ static void __init simone_init_machine(void)
        ep93xx_register_fb(&simone_fb_info);
        ep93xx_register_i2c(&simone_i2c_gpio_data, simone_i2c_board_info,
                            ARRAY_SIZE(simone_i2c_board_info));
+       ep93xx_register_spi(&simone_spi_info, simone_spi_devices,
+                           ARRAY_SIZE(simone_spi_devices));
        simone_register_audio();
 }
 
index 5f5cd56..e3a9256 100644 (file)
@@ -163,7 +163,9 @@ extern void exynos_set_delayed_reset_assertion(bool enable);
 
 extern void s5p_init_cpu(void __iomem *cpuid_addr);
 extern unsigned int samsung_rev(void);
-extern void __iomem *cpu_boot_reg_base(void);
+extern void exynos_core_restart(u32 core_id);
+extern int exynos_set_boot_addr(u32 core_id, unsigned long boot_addr);
+extern int exynos_get_boot_addr(u32 core_id, unsigned long *boot_addr);
 
 static inline void pmu_raw_writel(u32 val, u32 offset)
 {
index 5917a30..4bd8b76 100644 (file)
@@ -234,7 +234,8 @@ static void __init exynos_dt_machine_init(void)
                exynos_sysram_init();
 
 #if defined(CONFIG_SMP) && defined(CONFIG_ARM_EXYNOS_CPUIDLE)
-       if (of_machine_is_compatible("samsung,exynos4210"))
+       if (of_machine_is_compatible("samsung,exynos4210") ||
+           of_machine_is_compatible("samsung,exynos3250"))
                exynos_cpuidle.dev.platform_data = &cpuidle_coupled_exynos_data;
 #endif
        if (of_machine_is_compatible("samsung,exynos4210") ||
index 1bd3576..245f6de 100644 (file)
@@ -49,6 +49,7 @@ static int exynos_do_idle(unsigned long mode)
                             sysram_ns_base_addr + 0x24);
                __raw_writel(EXYNOS_AFTR_MAGIC, sysram_ns_base_addr + 0x20);
                if (soc_is_exynos3250()) {
+                       flush_cache_all();
                        exynos_smc(SMC_CMD_SAVE, OP_TYPE_CORE,
                                   SMC_POWERSTATE_IDLE, 0);
                        exynos_smc(SMC_CMD_SHUTDOWN, OP_TYPE_CLUSTER,
@@ -104,6 +105,22 @@ static int exynos_set_cpu_boot_addr(int cpu, unsigned long boot_addr)
        return 0;
 }
 
+static int exynos_get_cpu_boot_addr(int cpu, unsigned long *boot_addr)
+{
+       void __iomem *boot_reg;
+
+       if (!sysram_ns_base_addr)
+               return -ENODEV;
+
+       boot_reg = sysram_ns_base_addr + 0x1c;
+
+       if (soc_is_exynos4412())
+               boot_reg += 4 * cpu;
+
+       *boot_addr = __raw_readl(boot_reg);
+       return 0;
+}
+
 static int exynos_cpu_suspend(unsigned long arg)
 {
        flush_cache_all();
@@ -138,6 +155,7 @@ static int exynos_resume(void)
 static const struct firmware_ops exynos_firmware_ops = {
        .do_idle                = IS_ENABLED(CONFIG_EXYNOS_CPU_SUSPEND) ? exynos_do_idle : NULL,
        .set_cpu_boot_addr      = exynos_set_cpu_boot_addr,
+       .get_cpu_boot_addr      = exynos_get_cpu_boot_addr,
        .cpu_boot               = exynos_cpu_boot,
        .suspend                = IS_ENABLED(CONFIG_PM_SLEEP) ? exynos_suspend : NULL,
        .resume                 = IS_ENABLED(CONFIG_EXYNOS_CPU_SUSPEND) ? exynos_resume : NULL,
index a825bca..58e05a2 100644 (file)
@@ -169,7 +169,7 @@ int exynos_cluster_power_state(int cluster)
                S5P_CORE_LOCAL_PWR_EN);
 }
 
-void __iomem *cpu_boot_reg_base(void)
+static void __iomem *cpu_boot_reg_base(void)
 {
        if (soc_is_exynos4210() && samsung_rev() == EXYNOS4210_REV_1_1)
                return pmu_base_addr + S5P_INFORM5;
@@ -195,7 +195,7 @@ static inline void __iomem *cpu_boot_reg(int cpu)
  *
  * Currently this is needed only when booting secondary CPU on Exynos3250.
  */
-static void exynos_core_restart(u32 core_id)
+void exynos_core_restart(u32 core_id)
 {
        u32 val;
 
@@ -210,7 +210,6 @@ static void exynos_core_restart(u32 core_id)
        val |= S5P_CORE_WAKEUP_FROM_LOCAL_CFG;
        pmu_raw_writel(val, EXYNOS_ARM_CORE_STATUS(core_id));
 
-       pr_info("CPU%u: Software reset\n", core_id);
        pmu_raw_writel(EXYNOS_CORE_PO_RESET(core_id), EXYNOS_SWRESET);
 }
 
@@ -248,6 +247,56 @@ static void exynos_secondary_init(unsigned int cpu)
        spin_unlock(&boot_lock);
 }
 
+int exynos_set_boot_addr(u32 core_id, unsigned long boot_addr)
+{
+       int ret;
+
+       /*
+        * Try to set boot address using firmware first
+        * and fall back to boot register if it fails.
+        */
+       ret = call_firmware_op(set_cpu_boot_addr, core_id, boot_addr);
+       if (ret && ret != -ENOSYS)
+               goto fail;
+       if (ret == -ENOSYS) {
+               void __iomem *boot_reg = cpu_boot_reg(core_id);
+
+               if (IS_ERR(boot_reg)) {
+                       ret = PTR_ERR(boot_reg);
+                       goto fail;
+               }
+               __raw_writel(boot_addr, boot_reg);
+               ret = 0;
+       }
+fail:
+       return ret;
+}
+
+int exynos_get_boot_addr(u32 core_id, unsigned long *boot_addr)
+{
+       int ret;
+
+       /*
+        * Try to get boot address using firmware first
+        * and fall back to boot register if it fails.
+        */
+       ret = call_firmware_op(get_cpu_boot_addr, core_id, boot_addr);
+       if (ret && ret != -ENOSYS)
+               goto fail;
+       if (ret == -ENOSYS) {
+               void __iomem *boot_reg = cpu_boot_reg(core_id);
+
+               if (IS_ERR(boot_reg)) {
+                       ret = PTR_ERR(boot_reg);
+                       goto fail;
+               }
+               *boot_addr = __raw_readl(boot_reg);
+               ret = 0;
+       }
+fail:
+       return ret;
+}
+
 static int exynos_boot_secondary(unsigned int cpu, struct task_struct *idle)
 {
        unsigned long timeout;
@@ -307,22 +356,9 @@ static int exynos_boot_secondary(unsigned int cpu, struct task_struct *idle)
 
                boot_addr = virt_to_phys(exynos4_secondary_startup);
 
-               /*
-                * Try to set boot address using firmware first
-                * and fall back to boot register if it fails.
-                */
-               ret = call_firmware_op(set_cpu_boot_addr, core_id, boot_addr);
-               if (ret && ret != -ENOSYS)
+               ret = exynos_set_boot_addr(core_id, boot_addr);
+               if (ret)
                        goto fail;
-               if (ret == -ENOSYS) {
-                       void __iomem *boot_reg = cpu_boot_reg(core_id);
-
-                       if (IS_ERR(boot_reg)) {
-                               ret = PTR_ERR(boot_reg);
-                               goto fail;
-                       }
-                       __raw_writel(boot_addr, boot_reg);
-               }
 
                call_firmware_op(cpu_boot, core_id);
 
@@ -337,6 +373,9 @@ static int exynos_boot_secondary(unsigned int cpu, struct task_struct *idle)
                udelay(10);
        }
 
+       if (pen_release != -1)
+               ret = -ETIMEDOUT;
+
        /*
         * now the secondary core is starting up let it run its
         * calibrations, then wait for it to finish
@@ -407,16 +446,9 @@ static void __init exynos_smp_prepare_cpus(unsigned int max_cpus)
                core_id = MPIDR_AFFINITY_LEVEL(mpidr, 0);
                boot_addr = virt_to_phys(exynos4_secondary_startup);
 
-               ret = call_firmware_op(set_cpu_boot_addr, core_id, boot_addr);
-               if (ret && ret != -ENOSYS)
+               ret = exynos_set_boot_addr(core_id, boot_addr);
+               if (ret)
                        break;
-               if (ret == -ENOSYS) {
-                       void __iomem *boot_reg = cpu_boot_reg(core_id);
-
-                       if (IS_ERR(boot_reg))
-                               break;
-                       __raw_writel(boot_addr, boot_reg);
-               }
        }
 }
 
index cc75ab4..9c1506b 100644 (file)
@@ -22,6 +22,7 @@
 #include <asm/firmware.h>
 #include <asm/smp_scu.h>
 #include <asm/suspend.h>
+#include <asm/cacheflush.h>
 
 #include <mach/map.h>
 
@@ -209,6 +210,8 @@ static int exynos_cpu0_enter_aftr(void)
                 * sequence, let's wait for one of these to happen
                 */
                while (exynos_cpu_power_state(1)) {
+                       unsigned long boot_addr;
+
                        /*
                         * The other cpu may skip idle and boot back
                         * up again
@@ -221,7 +224,11 @@ static int exynos_cpu0_enter_aftr(void)
                         * boot back up again, getting stuck in the
                         * boot rom code
                         */
-                       if (__raw_readl(cpu_boot_reg_base()) == 0)
+                       ret = exynos_get_boot_addr(1, &boot_addr);
+                       if (ret)
+                               goto fail;
+                       ret = -1;
+                       if (boot_addr == 0)
                                goto abort;
 
                        cpu_relax();
@@ -233,11 +240,14 @@ static int exynos_cpu0_enter_aftr(void)
 
 abort:
        if (cpu_online(1)) {
+               unsigned long boot_addr = virt_to_phys(exynos_cpu_resume);
+
                /*
                 * Set the boot vector to something non-zero
                 */
-               __raw_writel(virt_to_phys(exynos_cpu_resume),
-                            cpu_boot_reg_base());
+               ret = exynos_set_boot_addr(1, boot_addr);
+               if (ret)
+                       goto fail;
                dsb();
 
                /*
@@ -247,22 +257,42 @@ abort:
                while (exynos_cpu_power_state(1) != S5P_CORE_LOCAL_PWR_EN)
                        cpu_relax();
 
+               if (soc_is_exynos3250()) {
+                       while (!pmu_raw_readl(S5P_PMU_SPARE2) &&
+                              !atomic_read(&cpu1_wakeup))
+                               cpu_relax();
+
+                       if (!atomic_read(&cpu1_wakeup))
+                               exynos_core_restart(1);
+               }
+
                while (!atomic_read(&cpu1_wakeup)) {
+                       smp_rmb();
+
                        /*
                         * Poke cpu1 out of the boot rom
                         */
-                       __raw_writel(virt_to_phys(exynos_cpu_resume),
-                                    cpu_boot_reg_base());
 
-                       arch_send_wakeup_ipi_mask(cpumask_of(1));
+                       ret = exynos_set_boot_addr(1, boot_addr);
+                       if (ret)
+                               goto fail;
+
+                       call_firmware_op(cpu_boot, 1);
+
+                       if (soc_is_exynos3250())
+                               dsb_sev();
+                       else
+                               arch_send_wakeup_ipi_mask(cpumask_of(1));
                }
        }
-
+fail:
        return ret;
 }
 
 static int exynos_wfi_finisher(unsigned long flags)
 {
+       if (soc_is_exynos3250())
+               flush_cache_all();
        cpu_do_idle();
 
        return -1;
@@ -283,6 +313,9 @@ static int exynos_cpu1_powerdown(void)
         */
        exynos_cpu_power_down(1);
 
+       if (soc_is_exynos3250())
+               pmu_raw_writel(0, S5P_PMU_SPARE2);
+
        ret = cpu_suspend(0, exynos_wfi_finisher);
 
        cpu_pm_exit();
@@ -299,7 +332,9 @@ cpu1_aborted:
 
 static void exynos_pre_enter_aftr(void)
 {
-       __raw_writel(virt_to_phys(exynos_cpu_resume), cpu_boot_reg_base());
+       unsigned long boot_addr = virt_to_phys(exynos_cpu_resume);
+
+       (void)exynos_set_boot_addr(1, boot_addr);
 }
 
 static void exynos_post_enter_aftr(void)
index a968653..6001f1c 100644 (file)
@@ -62,6 +62,7 @@ static int exynos_pd_power(struct generic_pm_domain *domain, bool power_on)
                for (i = 0; i < MAX_CLK_PER_DOMAIN; i++) {
                        if (IS_ERR(pd->clk[i]))
                                break;
+                       pd->pclk[i] = clk_get_parent(pd->clk[i]);
                        if (clk_set_parent(pd->clk[i], pd->oscclk))
                                pr_err("%s: error setting oscclk as parent to clock %d\n",
                                                pd->name, i);
@@ -90,6 +91,9 @@ static int exynos_pd_power(struct generic_pm_domain *domain, bool power_on)
                for (i = 0; i < MAX_CLK_PER_DOMAIN; i++) {
                        if (IS_ERR(pd->clk[i]))
                                break;
+
+                       if (IS_ERR(pd->clk[i]))
+                               continue; /* Skip on first power up */
                        if (clk_set_parent(pd->clk[i], pd->pclk[i]))
                                pr_err("%s: error setting parent to clock%d\n",
                                                pd->name, i);
@@ -117,27 +121,37 @@ static int exynos_pd_power_off(struct generic_pm_domain *domain)
 
 static __init int exynos4_pm_init_power_domain(void)
 {
-       struct platform_device *pdev;
        struct device_node *np;
 
        for_each_compatible_node(np, NULL, "samsung,exynos4210-pd") {
                struct exynos_pm_domain *pd;
                int on, i;
-               struct device *dev;
-
-               pdev = of_find_device_by_node(np);
-               dev = &pdev->dev;
 
                pd = kzalloc(sizeof(*pd), GFP_KERNEL);
                if (!pd) {
                        pr_err("%s: failed to allocate memory for domain\n",
                                        __func__);
+                       of_node_put(np);
+                       return -ENOMEM;
+               }
+               pd->pd.name = kstrdup_const(strrchr(np->full_name, '/') + 1,
+                                           GFP_KERNEL);
+               if (!pd->pd.name) {
+                       kfree(pd);
+                       of_node_put(np);
                        return -ENOMEM;
                }
 
-               pd->pd.name = kstrdup(dev_name(dev), GFP_KERNEL);
                pd->name = pd->pd.name;
                pd->base = of_iomap(np, 0);
+               if (!pd->base) {
+                       pr_warn("%s: failed to map memory\n", __func__);
+                       kfree(pd->pd.name);
+                       kfree(pd);
+                       of_node_put(np);
+                       continue;
+               }
+
                pd->pd.power_off = exynos_pd_power_off;
                pd->pd.power_on = exynos_pd_power_on;
 
@@ -145,12 +159,12 @@ static __init int exynos4_pm_init_power_domain(void)
                        char clk_name[8];
 
                        snprintf(clk_name, sizeof(clk_name), "asb%d", i);
-                       pd->asb_clk[i] = clk_get(dev, clk_name);
+                       pd->asb_clk[i] = of_clk_get_by_name(np, clk_name);
                        if (IS_ERR(pd->asb_clk[i]))
                                break;
                }
 
-               pd->oscclk = clk_get(dev, "oscclk");
+               pd->oscclk = of_clk_get_by_name(np, "oscclk");
                if (IS_ERR(pd->oscclk))
                        goto no_clk;
 
@@ -158,16 +172,14 @@ static __init int exynos4_pm_init_power_domain(void)
                        char clk_name[8];
 
                        snprintf(clk_name, sizeof(clk_name), "clk%d", i);
-                       pd->clk[i] = clk_get(dev, clk_name);
+                       pd->clk[i] = of_clk_get_by_name(np, clk_name);
                        if (IS_ERR(pd->clk[i]))
                                break;
-                       snprintf(clk_name, sizeof(clk_name), "pclk%d", i);
-                       pd->pclk[i] = clk_get(dev, clk_name);
-                       if (IS_ERR(pd->pclk[i])) {
-                               clk_put(pd->clk[i]);
-                               pd->clk[i] = ERR_PTR(-EINVAL);
-                               break;
-                       }
+                       /*
+                        * Skip setting parent on first power up.
+                        * The parent at this time may not be useful at all.
+                        */
+                       pd->pclk[i] = ERR_PTR(-EINVAL);
                }
 
                if (IS_ERR(pd->clk[0]))
@@ -189,15 +201,15 @@ no_clk:
                args.args_count = 0;
                child_domain = of_genpd_get_from_provider(&args);
                if (IS_ERR(child_domain))
-                       continue;
+                       goto next_pd;
 
                if (of_parse_phandle_with_args(np, "power-domains",
                                         "#power-domain-cells", 0, &args) != 0)
-                       continue;
+                       goto next_pd;
 
                parent_domain = of_genpd_get_from_provider(&args);
                if (IS_ERR(parent_domain))
-                       continue;
+                       goto next_pd;
 
                if (pm_genpd_add_subdomain(parent_domain, child_domain))
                        pr_warn("%s failed to add subdomain: %s\n",
@@ -205,9 +217,10 @@ no_clk:
                else
                        pr_info("%s has as child subdomain: %s.\n",
                                parent_domain->name, child_domain->name);
+next_pd:
                of_node_put(np);
        }
 
        return 0;
 }
-arch_initcall(exynos4_pm_init_power_domain);
+core_initcall(exynos4_pm_init_power_domain);
index c15761c..e812c1c 100644 (file)
@@ -681,7 +681,7 @@ static unsigned int const exynos5420_list_disable_pmu_reg[] = {
        EXYNOS5420_CMU_RESET_FSYS_SYS_PWR_REG,
 };
 
-static void exynos5_power_off(void)
+static void exynos_power_off(void)
 {
        unsigned int tmp;
 
@@ -872,8 +872,6 @@ static void exynos5420_pmu_init(void)
                        EXYNOS5420_ARM_INTR_SPREAD_USE_STANDBYWFI);
 
        pmu_raw_writel(0x1, EXYNOS5420_UP_SCHEDULER);
-
-       pm_power_off = exynos5_power_off;
        pr_info("EXYNOS5420 PMU initialized\n");
 }
 
@@ -984,6 +982,8 @@ static int exynos_pmu_probe(struct platform_device *pdev)
        if (ret)
                dev_warn(dev, "can't register restart handler err=%d\n", ret);
 
+       pm_power_off = exynos_power_off;
+
        dev_dbg(dev, "Exynos PMU Driver probe done\n");
        return 0;
 }
index 7d23ce0..96866d0 100644 (file)
@@ -223,7 +223,7 @@ static int exynos_pmu_domain_alloc(struct irq_domain *domain,
        return irq_domain_alloc_irqs_parent(domain, virq, nr_irqs, &parent_args);
 }
 
-static struct irq_domain_ops exynos_pmu_domain_ops = {
+static const struct irq_domain_ops exynos_pmu_domain_ops = {
        .xlate  = exynos_pmu_domain_xlate,
        .alloc  = exynos_pmu_domain_alloc,
        .free   = irq_domain_free_irqs_common,
index 388232c..573536f 100644 (file)
@@ -1,8 +1,8 @@
 menuconfig ARCH_MXC
-       bool "Freescale i.MX family" if ARCH_MULTI_V4_V5 || ARCH_MULTI_V6_V7
+       bool "Freescale i.MX family" if ARCH_MULTI_V4_V5 || ARCH_MULTI_V6_V7 || ARM_SINGLE_ARMV7M
        select ARCH_REQUIRE_GPIOLIB
        select ARM_CPU_SUSPEND if PM
-       select CLKSRC_MMIO
+       select CLKSRC_IMX_GPT
        select GENERIC_IRQ_CHIP
        select PINCTRL
        select PM_OPP if PM
@@ -462,10 +462,10 @@ config MACH_VPR200
 
 endif
 
-if ARCH_MULTI_V5
-
 comment "Device tree only"
 
+if ARCH_MULTI_V5
+
 config SOC_IMX25
        bool "i.MX25 support"
        select ARCH_MXC_IOMUX_V3
@@ -478,7 +478,7 @@ endif
 
 if ARCH_MULTI_V7
 
-comment "Device tree only"
+comment "Cortex-A platforms"
 
 config SOC_IMX5
        bool
@@ -548,10 +548,33 @@ config SOC_IMX6SX
        help
          This enables support for Freescale i.MX6 SoloX processor.
 
+config SOC_IMX7D
+       bool "i.MX7 Dual support"
+       select PINCTRL_IMX7D
+       select ARM_GIC
+       select HAVE_IMX_ANATOP
+       select HAVE_IMX_MMDC
+       help
+               This enables support for Freescale i.MX7 Dual processor.
+
+config SOC_LS1021A
+       bool "Freescale LS1021A support"
+       select ARM_GIC
+       select HAVE_ARM_ARCH_TIMER
+       select PCI_DOMAINS if PCI
+       select ZONE_DMA if ARM_LPAE
+       help
+         This enables support for Freescale LS1021A processor.
+
+endif
+
+comment "Cortex-A/Cortex-M asymmetric multiprocessing platforms"
+
+if ARCH_MULTI_V7 || ARM_SINGLE_ARMV7M
+
 config SOC_VF610
        bool "Vybrid Family VF610 support"
-       select IRQ_DOMAIN_HIERARCHY
-       select ARM_GIC
+       select ARM_GIC if ARCH_MULTI_V7
        select PINCTRL_VF610
        select PL310_ERRATA_769419 if CACHE_L2X0
        select SMP_ON_UP if SMP
@@ -565,7 +588,7 @@ choice
        default VF_USE_ARM_GLOBAL_TIMER
 
        config VF_USE_ARM_GLOBAL_TIMER
-               bool "Use ARM Global Timer"
+               bool "Use ARM Global Timer" if ARCH_MULTI_V7
                select ARM_GLOBAL_TIMER
                select CLKSRC_ARM_GLOBAL_TIMER_SCHED_CLOCK
                help
@@ -579,16 +602,6 @@ choice
 
 endchoice
 
-config SOC_LS1021A
-       bool "Freescale LS1021A support"
-       select ARM_GIC
-       select HAVE_ARM_ARCH_TIMER
-       select PCI_DOMAINS if PCI
-       select ZONE_DMA if ARM_LPAE
-
-       help
-         This enables support for Freescale LS1021A processor.
-
 endif
 
 source "arch/arm/mach-imx/devices/Kconfig"
index eed6098..37c502a 100644 (file)
@@ -1,23 +1,18 @@
-obj-y := time.o cpu.o system.o irq-common.o
+obj-y := cpu.o system.o irq-common.o
 
-obj-$(CONFIG_SOC_IMX1) += clk-imx1.o mm-imx1.o
-obj-$(CONFIG_SOC_IMX21) += clk-imx21.o mm-imx21.o
+obj-$(CONFIG_SOC_IMX1) += mm-imx1.o
+obj-$(CONFIG_SOC_IMX21) += mm-imx21.o
 
-obj-$(CONFIG_SOC_IMX25) += clk-imx25.o cpu-imx25.o mach-imx25.o
+obj-$(CONFIG_SOC_IMX25) += cpu-imx25.o mach-imx25.o
 
 obj-$(CONFIG_SOC_IMX27) += cpu-imx27.o pm-imx27.o
-obj-$(CONFIG_SOC_IMX27) += clk-imx27.o mm-imx27.o ehci-imx27.o
+obj-$(CONFIG_SOC_IMX27) += mm-imx27.o ehci-imx27.o
 
-obj-$(CONFIG_SOC_IMX31) += mm-imx3.o cpu-imx31.o clk-imx31.o iomux-imx31.o ehci-imx31.o pm-imx3.o
-obj-$(CONFIG_SOC_IMX35) += mm-imx3.o cpu-imx35.o clk-imx35.o ehci-imx35.o pm-imx3.o
+obj-$(CONFIG_SOC_IMX31) += mm-imx3.o cpu-imx31.o iomux-imx31.o ehci-imx31.o pm-imx3.o
+obj-$(CONFIG_SOC_IMX35) += mm-imx3.o cpu-imx35.o ehci-imx35.o pm-imx3.o
 
 imx5-pm-$(CONFIG_PM) += pm-imx5.o
-obj-$(CONFIG_SOC_IMX5) += cpu-imx5.o clk-imx51-imx53.o clk-cpu.o $(imx5-pm-y)
-
-obj-$(CONFIG_COMMON_CLK) += clk-pllv1.o clk-pllv2.o clk-pllv3.o clk-gate2.o \
-                           clk-pfd.o clk-busy.o clk.o \
-                           clk-fixup-div.o clk-fixup-mux.o \
-                           clk-gate-exclusive.o
+obj-$(CONFIG_SOC_IMX5) += cpu-imx5.o $(imx5-pm-y)
 
 obj-$(CONFIG_IMX_HAVE_IOMUX_V1) += iomux-v1.o
 obj-$(CONFIG_ARCH_MXC_IOMUX_V3) += iomux-v3.o
@@ -85,13 +80,15 @@ AFLAGS_headsmp.o :=-Wa,-march=armv7-a
 obj-$(CONFIG_SMP) += headsmp.o platsmp.o
 obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o
 endif
-obj-$(CONFIG_SOC_IMX6Q) += clk-imx6q.o mach-imx6q.o
-obj-$(CONFIG_SOC_IMX6SL) += clk-imx6sl.o mach-imx6sl.o
-obj-$(CONFIG_SOC_IMX6SX) += clk-imx6sx.o mach-imx6sx.o
+obj-$(CONFIG_SOC_IMX6Q) += mach-imx6q.o
+obj-$(CONFIG_SOC_IMX6SL) += mach-imx6sl.o
+obj-$(CONFIG_SOC_IMX6SX) += mach-imx6sx.o
+obj-$(CONFIG_SOC_IMX7D) += mach-imx7d.o
 
 ifeq ($(CONFIG_SUSPEND),y)
 AFLAGS_suspend-imx6.o :=-Wa,-march=armv7-a
 obj-$(CONFIG_SOC_IMX6) += suspend-imx6.o
+obj-$(CONFIG_SOC_IMX53) += suspend-imx53.o
 endif
 obj-$(CONFIG_SOC_IMX6) += pm-imx6.o
 
@@ -99,7 +96,7 @@ obj-$(CONFIG_SOC_IMX50) += mach-imx50.o
 obj-$(CONFIG_SOC_IMX51) += mach-imx51.o
 obj-$(CONFIG_SOC_IMX53) += mach-imx53.o
 
-obj-$(CONFIG_SOC_VF610) += clk-vf610.o mach-vf610.o
+obj-$(CONFIG_SOC_VF610) += mach-vf610.o
 
 obj-$(CONFIG_SOC_LS1021A) += mach-ls1021a.o
 
diff --git a/arch/arm/mach-imx/Makefile.boot b/arch/arm/mach-imx/Makefile.boot
new file mode 100644 (file)
index 0000000..e69de29
index 7f262fe..231bb25 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013 Freescale Semiconductor, Inc.
+ * Copyright (C) 2013-2015 Freescale Semiconductor, Inc.
  *
  * The code contained herein is licensed under the GNU General Public
  * License. You may obtain a copy of the GNU General Public License
@@ -28,6 +28,7 @@
 #define ANADIG_USB2_CHRG_DETECT        0x210
 #define ANADIG_DIGPROG         0x260
 #define ANADIG_DIGPROG_IMX6SL  0x280
+#define ANADIG_DIGPROG_IMX7D   0x800
 
 #define BM_ANADIG_REG_2P5_ENABLE_WEAK_LINREG   0x40000
 #define BM_ANADIG_REG_2P5_ENABLE_PULLDOWN      0x8
@@ -121,6 +122,8 @@ void __init imx_init_revision_from_anatop(void)
        WARN_ON(!anatop_base);
        if (of_device_is_compatible(np, "fsl,imx6sl-anatop"))
                offset = ANADIG_DIGPROG_IMX6SL;
+       if (of_device_is_compatible(np, "fsl,imx7d-anatop"))
+               offset = ANADIG_DIGPROG_IMX7D;
        digprog = readl_relaxed(anatop_base + offset);
        iounmap(anatop_base);
 
index 0f04e30..21e4e86 100644 (file)
@@ -44,7 +44,6 @@ void imx27_soc_init(void);
 void imx31_soc_init(void);
 void imx35_soc_init(void);
 void epit_timer_init(void __iomem *base, int irq);
-void mxc_timer_init(void __iomem *, int);
 int mx1_clocks_init(unsigned long fref);
 int mx21_clocks_init(unsigned long lref, unsigned long fref);
 int mx27_clocks_init(unsigned long fref);
@@ -56,13 +55,10 @@ struct platform_device *mxc_register_gpio(char *name, int id,
 void mxc_set_cpu_type(unsigned int type);
 void mxc_restart(enum reboot_mode, const char *);
 void mxc_arch_reset_init(void __iomem *);
-int mx51_revision(void);
-int mx53_revision(void);
 void imx_set_aips(void __iomem *);
 void imx_aips_allow_unprivileged_access(const char *compat);
 int mxc_device_init(void);
 void imx_set_soc_revision(unsigned int rev);
-unsigned int imx_get_soc_revision(void);
 void imx_init_revision_from_anatop(void);
 struct device *imx_soc_device_init(void);
 void imx6_enable_rbc(bool enable);
@@ -87,7 +83,6 @@ enum mx3_cpu_pwr_mode {
 };
 
 void mx3_cpu_lp_set(enum mx3_cpu_pwr_mode mode);
-void imx_print_silicon_rev(const char *cpu, int srev);
 
 void imx_enable_cpu(int cpu, bool enable);
 void imx_set_cpu_jump(int cpu, void *jump_addr);
@@ -111,7 +106,7 @@ void imx_gpc_hwirq_unmask(unsigned int hwirq);
 void imx_anatop_init(void);
 void imx_anatop_pre_suspend(void);
 void imx_anatop_post_resume(void);
-int imx6q_set_lpm(enum mxc_cpu_pwr_mode mode);
+int imx6_set_lpm(enum mxc_cpu_pwr_mode mode);
 void imx6q_set_int_mem_clk_lpm(bool enable);
 void imx6sl_set_wait_clk(bool enter);
 int imx_mmdc_get_ddr_type(void);
@@ -121,26 +116,28 @@ int imx_cpu_kill(unsigned int cpu);
 
 #ifdef CONFIG_SUSPEND
 void v7_cpu_resume(void);
+void imx53_suspend(void __iomem *ocram_vbase);
+extern const u32 imx53_suspend_sz;
 void imx6_suspend(void __iomem *ocram_vbase);
 #else
 static inline void v7_cpu_resume(void) {}
+static inline void imx53_suspend(void __iomem *ocram_vbase) {}
+static const u32 imx53_suspend_sz;
 static inline void imx6_suspend(void __iomem *ocram_vbase) {}
 #endif
 
+void imx6_pm_ccm_init(const char *ccm_compat);
 void imx6q_pm_init(void);
 void imx6dl_pm_init(void);
 void imx6sl_pm_init(void);
 void imx6sx_pm_init(void);
-void imx6q_pm_set_ccm_base(void __iomem *base);
 
 #ifdef CONFIG_PM
 void imx51_pm_init(void);
 void imx53_pm_init(void);
-void imx5_pm_set_ccm_base(void __iomem *base);
 #else
 static inline void imx51_pm_init(void) {}
 static inline void imx53_pm_init(void) {}
-static inline void imx5_pm_set_ccm_base(void __iomem *base) {}
 #endif
 
 #ifdef CONFIG_NEON
index df42c14..a7fa92a 100644 (file)
@@ -130,6 +130,9 @@ struct device * __init imx_soc_device_init(void)
        case MXC_CPU_IMX6Q:
                soc_id = "i.MX6Q";
                break;
+       case MXC_CPU_IMX7D:
+               soc_id = "i.MX7D";
+               break;
        default:
                soc_id = "Unknown";
        }
index 8e21ccc..353bb87 100644 (file)
@@ -27,9 +27,9 @@ static int imx6q_enter_wait(struct cpuidle_device *dev,
                 */
                if (!spin_trylock(&master_lock))
                        goto idle;
-               imx6q_set_lpm(WAIT_UNCLOCKED);
+               imx6_set_lpm(WAIT_UNCLOCKED);
                cpu_do_idle();
-               imx6q_set_lpm(WAIT_CLOCKED);
+               imx6_set_lpm(WAIT_CLOCKED);
                spin_unlock(&master_lock);
                goto done;
        }
index 5742a9f..8d866fb 100644 (file)
@@ -16,7 +16,7 @@
 static int imx6sl_enter_wait(struct cpuidle_device *dev,
                            struct cpuidle_driver *drv, int index)
 {
-       imx6q_set_lpm(WAIT_UNCLOCKED);
+       imx6_set_lpm(WAIT_UNCLOCKED);
        /*
         * Software workaround for ERR005311, see function
         * description for details.
@@ -24,7 +24,7 @@ static int imx6sl_enter_wait(struct cpuidle_device *dev,
        imx6sl_set_wait_clk(true);
        cpu_do_idle();
        imx6sl_set_wait_clk(false);
-       imx6q_set_lpm(WAIT_CLOCKED);
+       imx6_set_lpm(WAIT_CLOCKED);
 
        return index;
 }
index 2c9f1a8..3c6672b 100644 (file)
@@ -25,7 +25,7 @@ static int imx6sx_idle_finish(unsigned long val)
 static int imx6sx_enter_wait(struct cpuidle_device *dev,
                            struct cpuidle_driver *drv, int index)
 {
-       imx6q_set_lpm(WAIT_UNCLOCKED);
+       imx6_set_lpm(WAIT_UNCLOCKED);
 
        switch (index) {
        case 1:
@@ -50,7 +50,7 @@ static int imx6sx_enter_wait(struct cpuidle_device *dev,
                break;
        }
 
-       imx6q_set_lpm(WAIT_CLOCKED);
+       imx6_set_lpm(WAIT_CLOCKED);
 
        return index;
 }
index 0ea77ed..80bad29 100644 (file)
@@ -227,7 +227,7 @@ static int imx_gpc_domain_alloc(struct irq_domain *domain,
        return irq_domain_alloc_irqs_parent(domain, irq, nr_irqs, &parent_args);
 }
 
-static struct irq_domain_ops imx_gpc_domain_ops = {
+static const struct irq_domain_ops imx_gpc_domain_ops = {
        .xlate  = imx_gpc_domain_xlate,
        .alloc  = imx_gpc_domain_alloc,
        .free   = irq_domain_free_irqs_common,
index 76af2c0..d737f95 100644 (file)
@@ -22,6 +22,7 @@
 
 #ifndef __ASSEMBLY__
 #include <asm/io.h>
+#include <soc/imx/revision.h>
 #endif
 #include <asm/sizes.h>
 
index d6a3075..6dd22ca 100644 (file)
@@ -40,7 +40,7 @@ static DEFINE_SPINLOCK(gpio_mux_lock);
 
 #define IOMUX_REG_MASK (IOMUX_PADNUM_MASK & ~0x3)
 
-static unsigned long mxc_pin_alloc_map[NB_PORTS * 32 / BITS_PER_LONG];
+static DECLARE_BITMAP(mxc_pin_alloc_map, NB_PORTS * 32);
 /*
  * set the mode for a IOMUX pin.
  */
index 3ab6154..9602cc1 100644 (file)
@@ -393,6 +393,7 @@ static void __init imx6q_init_irq(void)
        imx_init_l2cache();
        imx_src_init();
        irqchip_init();
+       imx6_pm_ccm_init("fsl,imx6q-ccm");
 }
 
 static const char * const imx6q_dt_compat[] __initconst = {
index 12a1b09..3003263 100644 (file)
@@ -66,6 +66,7 @@ static void __init imx6sl_init_irq(void)
        imx_init_l2cache();
        imx_src_init();
        irqchip_init();
+       imx6_pm_ccm_init("fsl,imx6sl-ccm");
 }
 
 static const char * const imx6sl_dt_compat[] __initconst = {
index f17b700..6a0b061 100644 (file)
@@ -86,6 +86,7 @@ static void __init imx6sx_init_irq(void)
        imx_init_l2cache();
        imx_src_init();
        irqchip_init();
+       imx6_pm_ccm_init("fsl,imx6sx-ccm");
 }
 
 static void __init imx6sx_init_late(void)
diff --git a/arch/arm/mach-imx/mach-imx7d.c b/arch/arm/mach-imx/mach-imx7d.c
new file mode 100644 (file)
index 0000000..4d4a190
--- /dev/null
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2015 Freescale Semiconductor, Inc.
+ *
+ * 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/irqchip.h>
+#include <linux/of_platform.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+#include "common.h"
+
+static void __init imx7d_init_machine(void)
+{
+       struct device *parent;
+
+       parent = imx_soc_device_init();
+       if (parent == NULL)
+               pr_warn("failed to initialize soc device\n");
+
+       of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
+       imx_anatop_init();
+}
+
+static void __init imx7d_init_irq(void)
+{
+       imx_init_revision_from_anatop();
+       imx_src_init();
+       irqchip_init();
+}
+
+static const char *imx7d_dt_compat[] __initconst = {
+       "fsl,imx7d",
+       NULL,
+};
+
+DT_MACHINE_START(IMX7D, "Freescale i.MX7 Dual (Device Tree)")
+       .init_irq       = imx7d_init_irq,
+       .init_machine   = imx7d_init_machine,
+       .dt_compat      = imx7d_dt_compat,
+MACHINE_END
index 2e7c75b..b20f6c1 100644 (file)
@@ -17,6 +17,7 @@ static const char * const vf610_dt_compat[] __initconst = {
        "fsl,vf510",
        "fsl,vf600",
        "fsl,vf610",
+       "fsl,vf610m4",
        NULL,
 };
 
index 0411f06..db9621c 100644 (file)
@@ -17,6 +17,8 @@
 #include <linux/of_address.h>
 #include <linux/of_device.h>
 
+#include "common.h"
+
 #define MMDC_MAPSR             0x404
 #define BP_MMDC_MAPSR_PSD      0
 #define BP_MMDC_MAPSR_PSS      4
index 8a65f19..f96bb26 100644 (file)
 #define MX27_DMA_REQ_SDHC3     36
 #define MX27_DMA_REQ_NFC       37
 
-#ifndef __ASSEMBLY__
-extern int mx27_revision(void);
-#endif
-
 #endif /* ifndef __MACH_MX27_H__ */
index 96fb4fb..6fec611 100644 (file)
 
 #define MX3x_PROD_SIGNATURE            0x1     /* For MX31 */
 
-/* Mandatory defines used globally */
-
-#if !defined(__ASSEMBLY__) && !defined(__MXC_BOOT_UNCOMPRESS)
-extern int mx35_revision(void);
-extern int mx31_revision(void);
-#endif
-
 #endif /* ifndef __MACH_MX3x_H__ */
index 4c1343d..c4436d4 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2004-2007, 2010 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2004-2007, 2010-2015 Freescale Semiconductor, Inc.
  * Copyright (C) 2008 Juergen Beisert (kernel@pengutronix.de)
  *
  * This program is free software; you can redistribute it and/or
 #define MXC_CPU_IMX6DL         0x61
 #define MXC_CPU_IMX6SX         0x62
 #define MXC_CPU_IMX6Q          0x63
-
-#define IMX_CHIP_REVISION_1_0          0x10
-#define IMX_CHIP_REVISION_1_1          0x11
-#define IMX_CHIP_REVISION_1_2          0x12
-#define IMX_CHIP_REVISION_1_3          0x13
-#define IMX_CHIP_REVISION_1_4          0x14
-#define IMX_CHIP_REVISION_1_5          0x15
-#define IMX_CHIP_REVISION_2_0          0x20
-#define IMX_CHIP_REVISION_2_1          0x21
-#define IMX_CHIP_REVISION_2_2          0x22
-#define IMX_CHIP_REVISION_2_3          0x23
-#define IMX_CHIP_REVISION_3_0          0x30
-#define IMX_CHIP_REVISION_3_1          0x31
-#define IMX_CHIP_REVISION_3_2          0x32
-#define IMX_CHIP_REVISION_3_3          0x33
-#define IMX_CHIP_REVISION_UNKNOWN      0xff
+#define MXC_CPU_IMX7D          0x72
 
 #define IMX_DDR_TYPE_LPDDR2            1
 
@@ -185,6 +170,11 @@ static inline bool cpu_is_imx6q(void)
        return __mxc_cpu_type == MXC_CPU_IMX6Q;
 }
 
+static inline bool cpu_is_imx7d(void)
+{
+       return __mxc_cpu_type == MXC_CPU_IMX7D;
+}
+
 struct cpu_op {
        u32 cpu_rate;
 };
index f1f80ab..0309ccd 100644 (file)
 #include <linux/io.h>
 #include <linux/err.h>
 #include <linux/export.h>
+
+#include <linux/genalloc.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_platform.h>
+
 #include <asm/cacheflush.h>
+#include <asm/fncpy.h>
 #include <asm/system_misc.h>
 #include <asm/tlbflush.h>
 
  */
 #define IMX5_DEFAULT_CPU_IDLE_STATE WAIT_UNCLOCKED_POWER_OFF
 
+struct imx5_suspend_io_state {
+       u32     offset;
+       u32     clear;
+       u32     set;
+       u32     saved_value;
+};
+
 struct imx5_pm_data {
+       phys_addr_t ccm_addr;
        phys_addr_t cortex_addr;
        phys_addr_t gpc_addr;
+       phys_addr_t m4if_addr;
+       phys_addr_t iomuxc_addr;
+       void (*suspend_asm)(void __iomem *ocram_vbase);
+       const u32 *suspend_asm_sz;
+       const struct imx5_suspend_io_state *suspend_io_config;
+       int suspend_io_count;
+};
+
+static const struct imx5_suspend_io_state imx53_suspend_io_config[] = {
+#define MX53_DSE_HIGHZ_MASK (0x7 << 19)
+       {.offset = 0x584, .clear = MX53_DSE_HIGHZ_MASK}, /* DQM0 */
+       {.offset = 0x594, .clear = MX53_DSE_HIGHZ_MASK}, /* DQM1 */
+       {.offset = 0x560, .clear = MX53_DSE_HIGHZ_MASK}, /* DQM2 */
+       {.offset = 0x554, .clear = MX53_DSE_HIGHZ_MASK}, /* DQM3 */
+       {.offset = 0x574, .clear = MX53_DSE_HIGHZ_MASK}, /* CAS */
+       {.offset = 0x588, .clear = MX53_DSE_HIGHZ_MASK}, /* RAS */
+       {.offset = 0x578, .clear = MX53_DSE_HIGHZ_MASK}, /* SDCLK_0 */
+       {.offset = 0x570, .clear = MX53_DSE_HIGHZ_MASK}, /* SDCLK_1 */
+
+       {.offset = 0x580, .clear = MX53_DSE_HIGHZ_MASK}, /* SDODT0 */
+       {.offset = 0x564, .clear = MX53_DSE_HIGHZ_MASK}, /* SDODT1 */
+       {.offset = 0x57c, .clear = MX53_DSE_HIGHZ_MASK}, /* SDQS0 */
+       {.offset = 0x590, .clear = MX53_DSE_HIGHZ_MASK}, /* SDQS1 */
+       {.offset = 0x568, .clear = MX53_DSE_HIGHZ_MASK}, /* SDQS2 */
+       {.offset = 0x558, .clear = MX53_DSE_HIGHZ_MASK}, /* SDSQ3 */
+       {.offset = 0x6f0, .clear = MX53_DSE_HIGHZ_MASK}, /* GRP_ADDS */
+       {.offset = 0x718, .clear = MX53_DSE_HIGHZ_MASK}, /* GRP_BODS */
+       {.offset = 0x71c, .clear = MX53_DSE_HIGHZ_MASK}, /* GRP_B1DS */
+       {.offset = 0x728, .clear = MX53_DSE_HIGHZ_MASK}, /* GRP_B2DS */
+       {.offset = 0x72c, .clear = MX53_DSE_HIGHZ_MASK}, /* GRP_B3DS */
+
+       /* Controls the CKE signal which is required to leave self refresh */
+       {.offset = 0x720, .clear = MX53_DSE_HIGHZ_MASK, .set = 1 << 19}, /* CTLDS */
 };
 
 static const struct imx5_pm_data imx51_pm_data __initconst = {
+       .ccm_addr = 0x73fd4000,
        .cortex_addr = 0x83fa0000,
        .gpc_addr = 0x73fd8000,
 };
 
 static const struct imx5_pm_data imx53_pm_data __initconst = {
+       .ccm_addr = 0x53fd4000,
        .cortex_addr = 0x63fa0000,
        .gpc_addr = 0x53fd8000,
+       .m4if_addr = 0x63fd8000,
+       .iomuxc_addr = 0x53fa8000,
+       .suspend_asm = &imx53_suspend,
+       .suspend_asm_sz = &imx53_suspend_sz,
+       .suspend_io_config = imx53_suspend_io_config,
+       .suspend_io_count = ARRAY_SIZE(imx53_suspend_io_config),
 };
 
+#define MX5_MAX_SUSPEND_IOSTATE ARRAY_SIZE(imx53_suspend_io_config)
+
+/*
+ * This structure is for passing necessary data for low level ocram
+ * suspend code(arch/arm/mach-imx/suspend-imx53.S), if this struct
+ * definition is changed, the offset definition in that file
+ * must be also changed accordingly otherwise, the suspend to ocram
+ * function will be broken!
+ */
+struct imx5_cpu_suspend_info {
+       void __iomem    *m4if_base;
+       void __iomem    *iomuxc_base;
+       u32             io_count;
+       struct imx5_suspend_io_state io_state[MX5_MAX_SUSPEND_IOSTATE];
+} __aligned(8);
+
 static void __iomem *ccm_base;
 static void __iomem *cortex_base;
 static void __iomem *gpc_base;
-
-void __init imx5_pm_set_ccm_base(void __iomem *base)
-{
-       ccm_base = base;
-}
+static void __iomem *suspend_ocram_base;
+static void (*imx5_suspend_in_ocram_fn)(void __iomem *ocram_vbase);
 
 /*
  * set cpu low power mode before WFI instruction. This function is called
@@ -161,8 +230,15 @@ static int mx5_suspend_enter(suspend_state_t state)
                /*clear the EMPGC0/1 bits */
                __raw_writel(0, gpc_base + MXC_SRPG_EMPGC0_SRPGCR);
                __raw_writel(0, gpc_base + MXC_SRPG_EMPGC1_SRPGCR);
+
+               if (imx5_suspend_in_ocram_fn)
+                       imx5_suspend_in_ocram_fn(suspend_ocram_base);
+               else
+                       cpu_do_idle();
+
+       } else {
+               cpu_do_idle();
        }
-       cpu_do_idle();
 
        /* return registers to default idle state */
        mx5_cpu_lp_set(IMX5_DEFAULT_CPU_IDLE_STATE);
@@ -194,6 +270,111 @@ static void imx5_pm_idle(void)
        imx5_cpu_do_idle();
 }
 
+static int __init imx_suspend_alloc_ocram(
+                               size_t size,
+                               void __iomem **virt_out,
+                               phys_addr_t *phys_out)
+{
+       struct device_node *node;
+       struct platform_device *pdev;
+       struct gen_pool *ocram_pool;
+       unsigned long ocram_base;
+       void __iomem *virt;
+       phys_addr_t phys;
+       int ret = 0;
+
+       /* Copied from imx6: TODO factorize */
+       node = of_find_compatible_node(NULL, NULL, "mmio-sram");
+       if (!node) {
+               pr_warn("%s: failed to find ocram node!\n", __func__);
+               return -ENODEV;
+       }
+
+       pdev = of_find_device_by_node(node);
+       if (!pdev) {
+               pr_warn("%s: failed to find ocram device!\n", __func__);
+               ret = -ENODEV;
+               goto put_node;
+       }
+
+       ocram_pool = dev_get_gen_pool(&pdev->dev);
+       if (!ocram_pool) {
+               pr_warn("%s: ocram pool unavailable!\n", __func__);
+               ret = -ENODEV;
+               goto put_node;
+       }
+
+       ocram_base = gen_pool_alloc(ocram_pool, size);
+       if (!ocram_base) {
+               pr_warn("%s: unable to alloc ocram!\n", __func__);
+               ret = -ENOMEM;
+               goto put_node;
+       }
+
+       phys = gen_pool_virt_to_phys(ocram_pool, ocram_base);
+       virt = __arm_ioremap_exec(phys, size, false);
+       if (phys_out)
+               *phys_out = phys;
+       if (virt_out)
+               *virt_out = virt;
+
+put_node:
+       of_node_put(node);
+
+       return ret;
+}
+
+static int __init imx5_suspend_init(const struct imx5_pm_data *soc_data)
+{
+       struct imx5_cpu_suspend_info *suspend_info;
+       int ret;
+       /* Need this to avoid compile error due to const typeof in fncpy.h */
+       void (*suspend_asm)(void __iomem *) = soc_data->suspend_asm;
+
+       if (!suspend_asm)
+               return 0;
+
+       if (!soc_data->suspend_asm_sz || !*soc_data->suspend_asm_sz)
+               return -EINVAL;
+
+       ret = imx_suspend_alloc_ocram(
+               *soc_data->suspend_asm_sz + sizeof(*suspend_info),
+               &suspend_ocram_base, NULL);
+       if (ret)
+               return ret;
+
+       suspend_info = suspend_ocram_base;
+
+       suspend_info->io_count = soc_data->suspend_io_count;
+       memcpy(suspend_info->io_state, soc_data->suspend_io_config,
+              sizeof(*suspend_info->io_state) * soc_data->suspend_io_count);
+
+       suspend_info->m4if_base = ioremap(soc_data->m4if_addr, SZ_16K);
+       if (!suspend_info->m4if_base) {
+               ret = -ENOMEM;
+               goto failed_map_m4if;
+       }
+
+       suspend_info->iomuxc_base = ioremap(soc_data->iomuxc_addr, SZ_16K);
+       if (!suspend_info->iomuxc_base) {
+               ret = -ENOMEM;
+               goto failed_map_iomuxc;
+       }
+
+       imx5_suspend_in_ocram_fn = fncpy(
+               suspend_ocram_base + sizeof(*suspend_info),
+               suspend_asm,
+               *soc_data->suspend_asm_sz);
+
+       return 0;
+
+failed_map_iomuxc:
+       iounmap(suspend_info->m4if_base);
+
+failed_map_m4if:
+       return ret;
+}
+
 static int __init imx5_pm_common_init(const struct imx5_pm_data *data)
 {
        int ret;
@@ -208,6 +389,7 @@ static int __init imx5_pm_common_init(const struct imx5_pm_data *data)
 
        arm_pm_idle = imx5_pm_idle;
 
+       ccm_base = ioremap(data->ccm_addr, SZ_16K);
        cortex_base = ioremap(data->cortex_addr, SZ_16K);
        gpc_base = ioremap(data->gpc_addr, SZ_16K);
        WARN_ON(!ccm_base || !cortex_base || !gpc_base);
@@ -219,6 +401,11 @@ static int __init imx5_pm_common_init(const struct imx5_pm_data *data)
        if (ret)
                pr_warn("%s: cpuidle init failed %d\n", __func__, ret);
 
+       ret = imx5_suspend_init(data);
+       if (ret)
+               pr_warn("%s: No DDR LPM support with suspend %d!\n",
+                       __func__, ret);
+
        suspend_set_ops(&mx5_suspend_ops);
 
        return 0;
@@ -226,10 +413,12 @@ static int __init imx5_pm_common_init(const struct imx5_pm_data *data)
 
 void __init imx51_pm_init(void)
 {
-       imx5_pm_common_init(&imx51_pm_data);
+       if (IS_ENABLED(CONFIG_SOC_IMX51))
+               imx5_pm_common_init(&imx51_pm_data);
 }
 
 void __init imx53_pm_init(void)
 {
-       imx5_pm_common_init(&imx53_pm_data);
+       if (IS_ENABLED(CONFIG_SOC_IMX53))
+               imx5_pm_common_init(&imx53_pm_data);
 }
index 6a7c6fc..b01650d 100644 (file)
@@ -255,7 +255,7 @@ static void imx6q_enable_wb(bool enable)
        writel_relaxed(val, ccm_base + CCR);
 }
 
-int imx6q_set_lpm(enum mxc_cpu_pwr_mode mode)
+int imx6_set_lpm(enum mxc_cpu_pwr_mode mode)
 {
        u32 val = readl_relaxed(ccm_base + CLPCR);
 
@@ -340,7 +340,7 @@ static int imx6q_pm_enter(suspend_state_t state)
 {
        switch (state) {
        case PM_SUSPEND_STANDBY:
-               imx6q_set_lpm(STOP_POWER_ON);
+               imx6_set_lpm(STOP_POWER_ON);
                imx6q_set_int_mem_clk_lpm(true);
                imx_gpc_pre_suspend(false);
                if (cpu_is_imx6sl())
@@ -350,10 +350,10 @@ static int imx6q_pm_enter(suspend_state_t state)
                if (cpu_is_imx6sl())
                        imx6sl_set_wait_clk(false);
                imx_gpc_post_resume();
-               imx6q_set_lpm(WAIT_CLOCKED);
+               imx6_set_lpm(WAIT_CLOCKED);
                break;
        case PM_SUSPEND_MEM:
-               imx6q_set_lpm(STOP_POWER_OFF);
+               imx6_set_lpm(STOP_POWER_OFF);
                imx6q_set_int_mem_clk_lpm(false);
                imx6q_enable_wb(true);
                /*
@@ -373,7 +373,7 @@ static int imx6q_pm_enter(suspend_state_t state)
                imx6_enable_rbc(false);
                imx6q_enable_wb(false);
                imx6q_set_int_mem_clk_lpm(true);
-               imx6q_set_lpm(WAIT_CLOCKED);
+               imx6_set_lpm(WAIT_CLOCKED);
                break;
        default:
                return -EINVAL;
@@ -392,11 +392,6 @@ static const struct platform_suspend_ops imx6q_pm_ops = {
        .valid = imx6q_pm_valid,
 };
 
-void __init imx6q_pm_set_ccm_base(void __iomem *base)
-{
-       ccm_base = base;
-}
-
 static int __init imx6_pm_get_base(struct imx6_pm_base *base,
                                const char *compat)
 {
@@ -482,8 +477,7 @@ static int __init imx6q_suspend_init(const struct imx6_pm_socdata *socdata)
 
        /*
         * ccm physical address is not used by asm code currently,
-        * so get ccm virtual address directly, as we already have
-        * it from ccm driver.
+        * so get ccm virtual address directly.
         */
        pm_info->ccm_base.vbase = ccm_base;
 
@@ -568,7 +562,7 @@ static void __init imx6_pm_common_init(const struct imx6_pm_socdata
 
        /*
         * This is for SW workaround step #1 of ERR007265, see comments
-        * in imx6q_set_lpm for details of this errata.
+        * in imx6_set_lpm for details of this errata.
         * Force IOMUXC irq pending, so that the interrupt to GPC can be
         * used to deassert dsm_request signal when the signal gets
         * asserted unexpectedly.
@@ -579,6 +573,24 @@ static void __init imx6_pm_common_init(const struct imx6_pm_socdata
                                   IMX6Q_GPR1_GINT);
 }
 
+void __init imx6_pm_ccm_init(const char *ccm_compat)
+{
+       struct device_node *np;
+       u32 val;
+
+       np = of_find_compatible_node(NULL, NULL, ccm_compat);
+       ccm_base = of_iomap(np, 0);
+       BUG_ON(!ccm_base);
+
+       /*
+        * Initialize CCM_CLPCR_LPM into RUN mode to avoid ARM core
+        * clock being shut down unexpectedly by WAIT mode.
+        */
+       val = readl_relaxed(ccm_base + CLPCR);
+       val &= ~BM_CLPCR_LPM;
+       writel_relaxed(val, ccm_base + CLPCR);
+}
+
 void __init imx6q_pm_init(void)
 {
        imx6_pm_common_init(&imx6q_pm_data);
diff --git a/arch/arm/mach-imx/suspend-imx53.S b/arch/arm/mach-imx/suspend-imx53.S
new file mode 100644 (file)
index 0000000..5ed078a
--- /dev/null
@@ -0,0 +1,139 @@
+/*
+ * Copyright (C) 2008-2011 Freescale Semiconductor, Inc.
+ */
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include <linux/linkage.h>
+
+#define M4IF_MCR0_OFFSET                       (0x008C)
+#define M4IF_MCR0_FDVFS                                (0x1 << 11)
+#define M4IF_MCR0_FDVACK                       (0x1 << 27)
+
+       .align 3
+
+/*
+ * ==================== low level suspend ====================
+ *
+ * On entry
+ * r0: pm_info structure address;
+ *
+ * suspend ocram space layout:
+ * ======================== high address ======================
+ *                              .
+ *                              .
+ *                              .
+ *                              ^
+ *                              ^
+ *                              ^
+ *                      imx53_suspend code
+ *              PM_INFO structure(imx53_suspend_info)
+ * ======================== low address =======================
+ */
+
+/* Offsets of members of struct imx53_suspend_info */
+#define SUSPEND_INFO_MX53_M4IF_V_OFFSET                0x0
+#define SUSPEND_INFO_MX53_IOMUXC_V_OFFSET      0x4
+#define SUSPEND_INFO_MX53_IO_COUNT_OFFSET      0x8
+#define SUSPEND_INFO_MX53_IO_STATE_OFFSET      0xc
+
+ENTRY(imx53_suspend)
+       stmfd   sp!, {r4,r5,r6,r7}
+
+       /* Save pad config */
+       ldr     r1, [r0, #SUSPEND_INFO_MX53_IO_COUNT_OFFSET]
+       cmp     r1, #0
+       beq     skip_pad_conf_1
+
+       add     r2, r0, #SUSPEND_INFO_MX53_IO_STATE_OFFSET
+       ldr     r3, [r0, #SUSPEND_INFO_MX53_IOMUXC_V_OFFSET]
+
+1:
+       ldr     r5, [r2], #12   /* IOMUXC register offset */
+       ldr     r6, [r3, r5]    /* current value */
+       str     r6, [r2], #4    /* save area */
+       subs    r1, r1, #1
+       bne     1b
+
+skip_pad_conf_1:
+       /* Set FDVFS bit of M4IF_MCR0 to request DDR to enter self-refresh */
+       ldr     r1, [r0, #SUSPEND_INFO_MX53_M4IF_V_OFFSET]
+       ldr     r2,[r1, #M4IF_MCR0_OFFSET]
+       orr     r2, r2, #M4IF_MCR0_FDVFS
+       str     r2,[r1, #M4IF_MCR0_OFFSET]
+
+       /* Poll FDVACK bit of M4IF_MCR to wait for DDR to enter self-refresh */
+wait_sr_ack:
+       ldr     r2,[r1, #M4IF_MCR0_OFFSET]
+       ands    r2, r2, #M4IF_MCR0_FDVACK
+       beq     wait_sr_ack
+
+       /* Set pad config */
+       ldr     r1, [r0, #SUSPEND_INFO_MX53_IO_COUNT_OFFSET]
+       cmp     r1, #0
+       beq     skip_pad_conf_2
+
+       add     r2, r0, #SUSPEND_INFO_MX53_IO_STATE_OFFSET
+       ldr     r3, [r0, #SUSPEND_INFO_MX53_IOMUXC_V_OFFSET]
+
+2:
+       ldr     r5, [r2], #4    /* IOMUXC register offset */
+       ldr     r6, [r2], #4    /* clear */
+       ldr     r7, [r3, r5]
+       bic     r7, r7, r6
+       ldr     r6, [r2], #8    /* set */
+       orr     r7, r7, r6
+       str     r7, [r3, r5]
+       subs    r1, r1, #1
+       bne     2b
+
+skip_pad_conf_2:
+       /* Zzz, enter stop mode */
+       wfi
+       nop
+       nop
+       nop
+       nop
+
+       /* Restore pad config */
+       ldr     r1, [r0, #SUSPEND_INFO_MX53_IO_COUNT_OFFSET]
+       cmp     r1, #0
+       beq     skip_pad_conf_3
+
+       add     r2, r0, #SUSPEND_INFO_MX53_IO_STATE_OFFSET
+       ldr     r3, [r0, #SUSPEND_INFO_MX53_IOMUXC_V_OFFSET]
+
+3:
+       ldr     r5, [r2], #12   /* IOMUXC register offset */
+       ldr     r6, [r2], #4    /* saved value */
+       str     r6, [r3, r5]
+       subs    r1, r1, #1
+       bne     3b
+
+skip_pad_conf_3:
+       /* Clear FDVFS bit of M4IF_MCR0 to request DDR to exit self-refresh */
+       ldr     r1, [r0, #SUSPEND_INFO_MX53_M4IF_V_OFFSET]
+       ldr     r2,[r1, #M4IF_MCR0_OFFSET]
+       bic     r2, r2, #M4IF_MCR0_FDVFS
+       str     r2,[r1, #M4IF_MCR0_OFFSET]
+
+       /* Poll FDVACK bit of M4IF_MCR to wait for DDR to exit self-refresh */
+wait_ar_ack:
+       ldr     r2,[r1, #M4IF_MCR0_OFFSET]
+       ands    r2, r2, #M4IF_MCR0_FDVACK
+       bne     wait_ar_ack
+
+       /* Restore registers */
+       ldmfd   sp!, {r4,r5,r6,r7}
+       mov     pc, lr
+
+ENDPROC(imx53_suspend)
+
+ENTRY(imx53_suspend_sz)
+        .word   . - imx53_suspend
diff --git a/arch/arm/mach-imx/time.c b/arch/arm/mach-imx/time.c
deleted file mode 100644 (file)
index 15d18e1..0000000
+++ /dev/null
@@ -1,385 +0,0 @@
-/*
- *  linux/arch/arm/plat-mxc/time.c
- *
- *  Copyright (C) 2000-2001 Deep Blue Solutions
- *  Copyright (C) 2002 Shane Nay (shane@minirl.com)
- *  Copyright (C) 2006-2007 Pavel Pisa (ppisa@pikron.com)
- *  Copyright (C) 2008 Juergen Beisert (kernel@pengutronix.de)
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * 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/interrupt.h>
-#include <linux/irq.h>
-#include <linux/clockchips.h>
-#include <linux/clk.h>
-#include <linux/delay.h>
-#include <linux/err.h>
-#include <linux/sched_clock.h>
-#include <linux/of.h>
-#include <linux/of_address.h>
-#include <linux/of_irq.h>
-
-#include <asm/mach/time.h>
-
-#include "common.h"
-#include "hardware.h"
-
-/*
- * There are 2 versions of the timer hardware on Freescale MXC hardware.
- * Version 1: MX1/MXL, MX21, MX27.
- * Version 2: MX25, MX31, MX35, MX37, MX51
- */
-
-/* defines common for all i.MX */
-#define MXC_TCTL               0x00
-#define MXC_TCTL_TEN           (1 << 0) /* Enable module */
-#define MXC_TPRER              0x04
-
-/* MX1, MX21, MX27 */
-#define MX1_2_TCTL_CLK_PCLK1   (1 << 1)
-#define MX1_2_TCTL_IRQEN       (1 << 4)
-#define MX1_2_TCTL_FRR         (1 << 8)
-#define MX1_2_TCMP             0x08
-#define MX1_2_TCN              0x10
-#define MX1_2_TSTAT            0x14
-
-/* MX21, MX27 */
-#define MX2_TSTAT_CAPT         (1 << 1)
-#define MX2_TSTAT_COMP         (1 << 0)
-
-/* MX31, MX35, MX25, MX5, MX6 */
-#define V2_TCTL_WAITEN         (1 << 3) /* Wait enable mode */
-#define V2_TCTL_CLK_IPG                (1 << 6)
-#define V2_TCTL_CLK_PER                (2 << 6)
-#define V2_TCTL_CLK_OSC_DIV8   (5 << 6)
-#define V2_TCTL_FRR            (1 << 9)
-#define V2_TCTL_24MEN          (1 << 10)
-#define V2_TPRER_PRE24M                12
-#define V2_IR                  0x0c
-#define V2_TSTAT               0x08
-#define V2_TSTAT_OF1           (1 << 0)
-#define V2_TCN                 0x24
-#define V2_TCMP                        0x10
-
-#define V2_TIMER_RATE_OSC_DIV8 3000000
-
-#define timer_is_v1()  (cpu_is_mx1() || cpu_is_mx21() || cpu_is_mx27())
-#define timer_is_v2()  (!timer_is_v1())
-
-static struct clock_event_device clockevent_mxc;
-static enum clock_event_mode clockevent_mode = CLOCK_EVT_MODE_UNUSED;
-
-static void __iomem *timer_base;
-
-static inline void gpt_irq_disable(void)
-{
-       unsigned int tmp;
-
-       if (timer_is_v2())
-               __raw_writel(0, timer_base + V2_IR);
-       else {
-               tmp = __raw_readl(timer_base + MXC_TCTL);
-               __raw_writel(tmp & ~MX1_2_TCTL_IRQEN, timer_base + MXC_TCTL);
-       }
-}
-
-static inline void gpt_irq_enable(void)
-{
-       if (timer_is_v2())
-               __raw_writel(1<<0, timer_base + V2_IR);
-       else {
-               __raw_writel(__raw_readl(timer_base + MXC_TCTL) | MX1_2_TCTL_IRQEN,
-                       timer_base + MXC_TCTL);
-       }
-}
-
-static void gpt_irq_acknowledge(void)
-{
-       if (timer_is_v1()) {
-               if (cpu_is_mx1())
-                       __raw_writel(0, timer_base + MX1_2_TSTAT);
-               else
-                       __raw_writel(MX2_TSTAT_CAPT | MX2_TSTAT_COMP,
-                               timer_base + MX1_2_TSTAT);
-       } else if (timer_is_v2())
-               __raw_writel(V2_TSTAT_OF1, timer_base + V2_TSTAT);
-}
-
-static void __iomem *sched_clock_reg;
-
-static u64 notrace mxc_read_sched_clock(void)
-{
-       return sched_clock_reg ? __raw_readl(sched_clock_reg) : 0;
-}
-
-static struct delay_timer imx_delay_timer;
-
-static unsigned long imx_read_current_timer(void)
-{
-       return __raw_readl(sched_clock_reg);
-}
-
-static int __init mxc_clocksource_init(struct clk *timer_clk)
-{
-       unsigned int c = clk_get_rate(timer_clk);
-       void __iomem *reg = timer_base + (timer_is_v2() ? V2_TCN : MX1_2_TCN);
-
-       imx_delay_timer.read_current_timer = &imx_read_current_timer;
-       imx_delay_timer.freq = c;
-       register_current_timer_delay(&imx_delay_timer);
-
-       sched_clock_reg = reg;
-
-       sched_clock_register(mxc_read_sched_clock, 32, c);
-       return clocksource_mmio_init(reg, "mxc_timer1", c, 200, 32,
-                       clocksource_mmio_readl_up);
-}
-
-/* clock event */
-
-static int mx1_2_set_next_event(unsigned long evt,
-                             struct clock_event_device *unused)
-{
-       unsigned long tcmp;
-
-       tcmp = __raw_readl(timer_base + MX1_2_TCN) + evt;
-
-       __raw_writel(tcmp, timer_base + MX1_2_TCMP);
-
-       return (int)(tcmp - __raw_readl(timer_base + MX1_2_TCN)) < 0 ?
-                               -ETIME : 0;
-}
-
-static int v2_set_next_event(unsigned long evt,
-                             struct clock_event_device *unused)
-{
-       unsigned long tcmp;
-
-       tcmp = __raw_readl(timer_base + V2_TCN) + evt;
-
-       __raw_writel(tcmp, timer_base + V2_TCMP);
-
-       return evt < 0x7fffffff &&
-               (int)(tcmp - __raw_readl(timer_base + V2_TCN)) < 0 ?
-                               -ETIME : 0;
-}
-
-#ifdef DEBUG
-static const char *clock_event_mode_label[] = {
-       [CLOCK_EVT_MODE_PERIODIC] = "CLOCK_EVT_MODE_PERIODIC",
-       [CLOCK_EVT_MODE_ONESHOT]  = "CLOCK_EVT_MODE_ONESHOT",
-       [CLOCK_EVT_MODE_SHUTDOWN] = "CLOCK_EVT_MODE_SHUTDOWN",
-       [CLOCK_EVT_MODE_UNUSED]   = "CLOCK_EVT_MODE_UNUSED",
-       [CLOCK_EVT_MODE_RESUME]   = "CLOCK_EVT_MODE_RESUME",
-};
-#endif /* DEBUG */
-
-static void mxc_set_mode(enum clock_event_mode mode,
-                               struct clock_event_device *evt)
-{
-       unsigned long flags;
-
-       /*
-        * The timer interrupt generation is disabled at least
-        * for enough time to call mxc_set_next_event()
-        */
-       local_irq_save(flags);
-
-       /* Disable interrupt in GPT module */
-       gpt_irq_disable();
-
-       if (mode != clockevent_mode) {
-               /* Set event time into far-far future */
-               if (timer_is_v2())
-                       __raw_writel(__raw_readl(timer_base + V2_TCN) - 3,
-                                       timer_base + V2_TCMP);
-               else
-                       __raw_writel(__raw_readl(timer_base + MX1_2_TCN) - 3,
-                                       timer_base + MX1_2_TCMP);
-
-               /* Clear pending interrupt */
-               gpt_irq_acknowledge();
-       }
-
-#ifdef DEBUG
-       printk(KERN_INFO "mxc_set_mode: changing mode from %s to %s\n",
-               clock_event_mode_label[clockevent_mode],
-               clock_event_mode_label[mode]);
-#endif /* DEBUG */
-
-       /* Remember timer mode */
-       clockevent_mode = mode;
-       local_irq_restore(flags);
-
-       switch (mode) {
-       case CLOCK_EVT_MODE_PERIODIC:
-               printk(KERN_ERR"mxc_set_mode: Periodic mode is not "
-                               "supported for i.MX\n");
-               break;
-       case CLOCK_EVT_MODE_ONESHOT:
-       /*
-        * Do not put overhead of interrupt enable/disable into
-        * mxc_set_next_event(), the core has about 4 minutes
-        * to call mxc_set_next_event() or shutdown clock after
-        * mode switching
-        */
-               local_irq_save(flags);
-               gpt_irq_enable();
-               local_irq_restore(flags);
-               break;
-       case CLOCK_EVT_MODE_SHUTDOWN:
-       case CLOCK_EVT_MODE_UNUSED:
-       case CLOCK_EVT_MODE_RESUME:
-               /* Left event sources disabled, no more interrupts appear */
-               break;
-       }
-}
-
-/*
- * IRQ handler for the timer
- */
-static irqreturn_t mxc_timer_interrupt(int irq, void *dev_id)
-{
-       struct clock_event_device *evt = &clockevent_mxc;
-       uint32_t tstat;
-
-       if (timer_is_v2())
-               tstat = __raw_readl(timer_base + V2_TSTAT);
-       else
-               tstat = __raw_readl(timer_base + MX1_2_TSTAT);
-
-       gpt_irq_acknowledge();
-
-       evt->event_handler(evt);
-
-       return IRQ_HANDLED;
-}
-
-static struct irqaction mxc_timer_irq = {
-       .name           = "i.MX Timer Tick",
-       .flags          = IRQF_TIMER | IRQF_IRQPOLL,
-       .handler        = mxc_timer_interrupt,
-};
-
-static struct clock_event_device clockevent_mxc = {
-       .name           = "mxc_timer1",
-       .features       = CLOCK_EVT_FEAT_ONESHOT,
-       .set_mode       = mxc_set_mode,
-       .set_next_event = mx1_2_set_next_event,
-       .rating         = 200,
-};
-
-static int __init mxc_clockevent_init(struct clk *timer_clk)
-{
-       if (timer_is_v2())
-               clockevent_mxc.set_next_event = v2_set_next_event;
-
-       clockevent_mxc.cpumask = cpumask_of(0);
-       clockevents_config_and_register(&clockevent_mxc,
-                                       clk_get_rate(timer_clk),
-                                       0xff, 0xfffffffe);
-
-       return 0;
-}
-
-static void __init _mxc_timer_init(int irq,
-                                  struct clk *clk_per, struct clk *clk_ipg)
-{
-       uint32_t tctl_val;
-
-       if (IS_ERR(clk_per)) {
-               pr_err("i.MX timer: unable to get clk\n");
-               return;
-       }
-
-       if (!IS_ERR(clk_ipg))
-               clk_prepare_enable(clk_ipg);
-
-       clk_prepare_enable(clk_per);
-
-       /*
-        * Initialise to a known state (all timers off, and timing reset)
-        */
-
-       __raw_writel(0, timer_base + MXC_TCTL);
-       __raw_writel(0, timer_base + MXC_TPRER); /* see datasheet note */
-
-       if (timer_is_v2()) {
-               tctl_val = V2_TCTL_FRR | V2_TCTL_WAITEN | MXC_TCTL_TEN;
-               if (clk_get_rate(clk_per) == V2_TIMER_RATE_OSC_DIV8) {
-                       tctl_val |= V2_TCTL_CLK_OSC_DIV8;
-                       if (cpu_is_imx6dl() || cpu_is_imx6sx()) {
-                               /* 24 / 8 = 3 MHz */
-                               __raw_writel(7 << V2_TPRER_PRE24M,
-                                       timer_base + MXC_TPRER);
-                               tctl_val |= V2_TCTL_24MEN;
-                       }
-               } else {
-                       tctl_val |= V2_TCTL_CLK_PER;
-               }
-       } else {
-               tctl_val = MX1_2_TCTL_FRR | MX1_2_TCTL_CLK_PCLK1 | MXC_TCTL_TEN;
-       }
-
-       __raw_writel(tctl_val, timer_base + MXC_TCTL);
-
-       /* init and register the timer to the framework */
-       mxc_clocksource_init(clk_per);
-       mxc_clockevent_init(clk_per);
-
-       /* Make irqs happen */
-       setup_irq(irq, &mxc_timer_irq);
-}
-
-void __init mxc_timer_init(void __iomem *base, int irq)
-{
-       struct clk *clk_per = clk_get_sys("imx-gpt.0", "per");
-       struct clk *clk_ipg = clk_get_sys("imx-gpt.0", "ipg");
-
-       timer_base = base;
-
-       _mxc_timer_init(irq, clk_per, clk_ipg);
-}
-
-static void __init mxc_timer_init_dt(struct device_node *np)
-{
-       struct clk *clk_per, *clk_ipg;
-       int irq;
-
-       if (timer_base)
-               return;
-
-       timer_base = of_iomap(np, 0);
-       WARN_ON(!timer_base);
-       irq = irq_of_parse_and_map(np, 0);
-
-       clk_ipg = of_clk_get_by_name(np, "ipg");
-
-       /* Try osc_per first, and fall back to per otherwise */
-       clk_per = of_clk_get_by_name(np, "osc_per");
-       if (IS_ERR(clk_per))
-               clk_per = of_clk_get_by_name(np, "per");
-
-       _mxc_timer_init(irq, clk_per, clk_ipg);
-}
-CLOCKSOURCE_OF_DECLARE(mx1_timer, "fsl,imx1-gpt", mxc_timer_init_dt);
-CLOCKSOURCE_OF_DECLARE(mx25_timer, "fsl,imx25-gpt", mxc_timer_init_dt);
-CLOCKSOURCE_OF_DECLARE(mx50_timer, "fsl,imx50-gpt", mxc_timer_init_dt);
-CLOCKSOURCE_OF_DECLARE(mx51_timer, "fsl,imx51-gpt", mxc_timer_init_dt);
-CLOCKSOURCE_OF_DECLARE(mx53_timer, "fsl,imx53-gpt", mxc_timer_init_dt);
-CLOCKSOURCE_OF_DECLARE(mx6q_timer, "fsl,imx6q-gpt", mxc_timer_init_dt);
-CLOCKSOURCE_OF_DECLARE(mx6sl_timer, "fsl,imx6sl-gpt", mxc_timer_init_dt);
-CLOCKSOURCE_OF_DECLARE(mx6sx_timer, "fsl,imx6sx-gpt", mxc_timer_init_dt);
diff --git a/arch/arm/mach-lpc18xx/Makefile b/arch/arm/mach-lpc18xx/Makefile
new file mode 100644 (file)
index 0000000..bd0b7b5
--- /dev/null
@@ -0,0 +1 @@
+obj-y += board-dt.o
diff --git a/arch/arm/mach-lpc18xx/Makefile.boot b/arch/arm/mach-lpc18xx/Makefile.boot
new file mode 100644 (file)
index 0000000..eacfc3f
--- /dev/null
@@ -0,0 +1,3 @@
+# Empty file waiting for deletion once Makefile.boot isn't needed any more.
+# Patch waits for application at
+# http://www.arm.linux.org.uk/developer/patches/viewpatch.php?id=7889/1 .
diff --git a/arch/arm/mach-lpc18xx/board-dt.c b/arch/arm/mach-lpc18xx/board-dt.c
new file mode 100644 (file)
index 0000000..fdcee78
--- /dev/null
@@ -0,0 +1,22 @@
+/*
+ * Device Tree board file for NXP LPC18xx/43xx
+ *
+ * Copyright (C) 2015 Joachim Eastwood <manabian@gmail.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <asm/mach/arch.h>
+
+static const char *const lpc18xx_43xx_compat[] __initconst = {
+       "nxp,lpc1850",
+       "nxp,lpc4350",
+       "nxp,lpc4370",
+       NULL
+};
+
+DT_MACHINE_START(LPC18XXDT, "NXP LPC18xx/43xx (Device Tree)")
+       .dt_compat = lpc18xx_43xx_compat,
+MACHINE_END
index 3d1e1c2..5d7fb59 100644 (file)
 #include <asm/assembler.h>
 
 #include <mach/board-ams-delta.h>
-
-#include <mach/irqs.h>
 #include <mach/ams-delta-fiq.h>
 
 #include "iomap.h"
+#include "soc.h"
 
 /*
  * GPIO related definitions, copied from arch/arm/plat-omap/gpio.c.
index 2aab761..a95499e 100644 (file)
@@ -626,6 +626,7 @@ MACHINE_START(AMS_DELTA, "Amstrad E3 (Delta)")
        .map_io         = ams_delta_map_io,
        .init_early     = omap1_init_early,
        .init_irq       = omap1_init_irq,
+       .handle_irq     = omap1_handle_irq,
        .init_machine   = ams_delta_init,
        .init_late      = ams_delta_init_late,
        .init_time      = omap1_timer_init,
index 702d580..0fb51d2 100644 (file)
@@ -362,6 +362,7 @@ MACHINE_START(OMAP_FSAMPLE, "OMAP730 F-Sample")
        .map_io         = omap_fsample_map_io,
        .init_early     = omap1_init_early,
        .init_irq       = omap1_init_irq,
+       .handle_irq     = omap1_handle_irq,
        .init_machine   = omap_fsample_init,
        .init_late      = omap1_init_late,
        .init_time      = omap1_timer_init,
index e1d9171..9708629 100644 (file)
@@ -82,6 +82,7 @@ MACHINE_START(OMAP_GENERIC, "Generic OMAP1510/1610/1710")
        .map_io         = omap16xx_map_io,
        .init_early     = omap1_init_early,
        .init_irq       = omap1_init_irq,
+       .handle_irq     = omap1_handle_irq,
        .init_machine   = omap_generic_init,
        .init_late      = omap1_init_late,
        .init_time      = omap1_timer_init,
index 5b45d26..8340d68 100644 (file)
@@ -426,6 +426,7 @@ MACHINE_START(OMAP_H2, "TI-H2")
        .map_io         = omap16xx_map_io,
        .init_early     = omap1_init_early,
        .init_irq       = omap1_init_irq,
+       .handle_irq     = omap1_handle_irq,
        .init_machine   = h2_init,
        .init_late      = omap1_init_late,
        .init_time      = omap1_timer_init,
index 17d7791..43aab63 100644 (file)
@@ -16,6 +16,7 @@
 
 #include <linux/i2c/tps65010.h>
 
+#include "common.h"
 #include "board-h3.h"
 #include "mmc.h"
 
index bfed4f9..086ff34 100644 (file)
@@ -452,6 +452,7 @@ MACHINE_START(OMAP_H3, "TI OMAP1710 H3 board")
        .map_io         = omap16xx_map_io,
        .init_early     = omap1_init_early,
        .init_irq       = omap1_init_irq,
+       .handle_irq     = omap1_handle_irq,
        .init_machine   = h3_init,
        .init_late      = omap1_init_late,
        .init_time      = omap1_timer_init,
index 35a2379..9525ef9 100644 (file)
@@ -601,6 +601,7 @@ MACHINE_START(HERALD, "HTC Herald")
        .map_io         = htcherald_map_io,
        .init_early     = omap1_init_early,
        .init_irq       = omap1_init_irq,
+       .handle_irq     = omap1_handle_irq,
        .init_machine   = htcherald_init,
        .init_late      = omap1_init_late,
        .init_time      = omap1_timer_init,
index c49ce83..ed4e045 100644 (file)
@@ -456,6 +456,7 @@ MACHINE_START(OMAP_INNOVATOR, "TI-Innovator")
        .map_io         = innovator_map_io,
        .init_early     = omap1_init_early,
        .init_irq       = omap1_init_irq,
+       .handle_irq     = omap1_handle_irq,
        .init_machine   = innovator_init,
        .init_late      = omap1_init_late,
        .init_time      = omap1_timer_init,
index 85089d8..9f6c7af 100644 (file)
@@ -294,6 +294,7 @@ MACHINE_START(NOKIA770, "Nokia 770")
        .map_io         = omap16xx_map_io,
        .init_early     = omap1_init_early,
        .init_irq       = omap1_init_irq,
+       .handle_irq     = omap1_handle_irq,
        .init_machine   = omap_nokia770_init,
        .init_late      = omap1_init_late,
        .init_time      = omap1_timer_init,
index 7436d4c..0efd165 100644 (file)
@@ -610,6 +610,7 @@ MACHINE_START(OMAP_OSK, "TI-OSK")
        .map_io         = omap16xx_map_io,
        .init_early     = omap1_init_early,
        .init_irq       = omap1_init_irq,
+       .handle_irq     = omap1_handle_irq,
        .init_machine   = osk_init,
        .init_late      = omap1_init_late,
        .init_time      = omap1_timer_init,
index 3b8e98f..1142ae4 100644 (file)
@@ -235,6 +235,7 @@ MACHINE_START(OMAP_PALMTE, "OMAP310 based Palm Tungsten E")
        .map_io         = omap15xx_map_io,
        .init_early     = omap1_init_early,
        .init_irq       = omap1_init_irq,
+       .handle_irq     = omap1_handle_irq,
        .init_machine   = omap_palmte_init,
        .init_late      = omap1_init_late,
        .init_time      = omap1_timer_init,
index ca50120..54a547a 100644 (file)
@@ -282,6 +282,7 @@ MACHINE_START(OMAP_PALMTT, "OMAP1510 based Palm Tungsten|T")
        .map_io         = omap15xx_map_io,
        .init_early     = omap1_init_early,
        .init_irq       = omap1_init_irq,
+       .handle_irq     = omap1_handle_irq,
        .init_machine   = omap_palmtt_init,
        .init_late      = omap1_init_late,
        .init_time      = omap1_timer_init,
index 470e12d..87ec04a 100644 (file)
@@ -297,6 +297,7 @@ MACHINE_START(OMAP_PALMZ71, "OMAP310 based Palm Zire71")
        .map_io         = omap15xx_map_io,
        .init_early     = omap1_init_early,
        .init_irq       = omap1_init_irq,
+       .handle_irq     = omap1_handle_irq,
        .init_machine   = omap_palmz71_init,
        .init_late      = omap1_init_late,
        .init_time      = omap1_timer_init,
index 8b2f712..3d76f05 100644 (file)
@@ -324,6 +324,7 @@ MACHINE_START(OMAP_PERSEUS2, "OMAP730 Perseus2")
        .map_io         = omap_perseus2_map_io,
        .init_early     = omap1_init_early,
        .init_irq       = omap1_init_irq,
+       .handle_irq     = omap1_handle_irq,
        .init_machine   = omap_perseus2_init,
        .init_late      = omap1_init_late,
        .init_time      = omap1_timer_init,
index 29e5262..939991e 100644 (file)
@@ -343,6 +343,7 @@ MACHINE_START(SX1, "OMAP310 based Siemens SX1")
        .map_io         = omap15xx_map_io,
        .init_early     = omap1_init_early,
        .init_irq       = omap1_init_irq,
+       .handle_irq     = omap1_handle_irq,
        .init_machine   = omap_sx1_init,
        .init_late      = omap1_init_late,
        .init_time      = omap1_timer_init,
index 4677a9c..e960687 100644 (file)
@@ -288,6 +288,7 @@ MACHINE_START(VOICEBLUE, "VoiceBlue OMAP5910")
        .map_io         = omap15xx_map_io,
        .init_early     = omap1_init_early,
        .init_irq       = omap1_init_irq,
+       .handle_irq     = omap1_handle_irq,
        .init_machine   = voiceblue_init,
        .init_late      = omap1_init_late,
        .init_time      = omap1_timer_init,
index 732f8ee..65bb6e8 100644 (file)
 #include <linux/i2c-omap.h>
 #include <linux/reboot.h>
 
+#include <asm/exception.h>
+
 #include <plat/i2c.h>
 
 #include <mach/irqs.h>
 
+#include "soc.h"
+
 #if defined(CONFIG_ARCH_OMAP730) || defined(CONFIG_ARCH_OMAP850)
 void omap7xx_map_io(void);
 #else
@@ -73,6 +77,7 @@ static inline int omap_serial_wakeup_init(void)
 
 void omap1_init_early(void);
 void omap1_init_irq(void);
+void __exception_irq_entry omap1_handle_irq(struct pt_regs *regs);
 void omap1_init_late(void);
 void omap1_restart(enum reboot_mode, const char *);
 
@@ -91,8 +96,6 @@ static inline int __init omap_32k_timer_init(void)
 }
 #endif
 
-extern u32 omap_irq_flags;
-
 #ifdef CONFIG_ARCH_OMAP16XX
 extern int ocpi_enable(void);
 #else
index 4be601b..7b02ed2 100644 (file)
@@ -28,7 +28,7 @@
 #include <linux/omap-dma.h>
 #include <mach/tc.h>
 
-#include <mach/irqs.h>
+#include "soc.h"
 
 #define OMAP1_DMA_BASE                 (0xfffed800)
 #define OMAP1_LOGICAL_DMA_CH_COUNT     17
index 6e6ec93..5b7a29b 100644 (file)
@@ -21,6 +21,8 @@
 
 #include <mach/irqs.h>
 
+#include "soc.h"
+
 #define OMAP1610_GPIO1_BASE            0xfffbe400
 #define OMAP1610_GPIO2_BASE            0xfffbec00
 #define OMAP1610_GPIO3_BASE            0xfffbb400
index 4612d25..0e5f68d 100644 (file)
@@ -21,6 +21,8 @@
 
 #include <mach/irqs.h>
 
+#include "soc.h"
+
 #define OMAP7XX_GPIO1_BASE             0xfffbc000
 #define OMAP7XX_GPIO2_BASE             0xfffbc800
 #define OMAP7XX_GPIO3_BASE             0xfffbd000
index 7f5761c..82887d6 100644 (file)
@@ -27,7 +27,6 @@
 
 #define OMAP_I2C_SIZE          0x3f
 #define OMAP1_I2C_BASE         0xfffb3800
-#define OMAP1_INT_I2C          (32 + 4)
 
 static const char name[] = "omap_i2c";
 
@@ -67,7 +66,7 @@ int __init omap_i2c_add_bus(struct omap_i2c_bus_platform_data *pdata,
        res[0].start = OMAP1_I2C_BASE;
        res[0].end = res[0].start + OMAP_I2C_SIZE;
        res[0].flags = IORESOURCE_MEM;
-       res[1].start = OMAP1_INT_I2C;
+       res[1].start = INT_I2C;
        res[1].flags = IORESOURCE_IRQ;
        pdev->resource = res;
 
diff --git a/arch/arm/mach-omap1/include/mach/entry-macro.S b/arch/arm/mach-omap1/include/mach/entry-macro.S
deleted file mode 100644 (file)
index 78a8c6c..0000000
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * arch/arm/mach-omap1/include/mach/entry-macro.S
- *
- * Low-level IRQ helper macros for OMAP-based platforms
- *
- * Copyright (C) 2009 Texas Instruments
- *
- * This file is licensed under  the terms of the GNU General Public
- * License version 2. This program is licensed "as is" without any
- * warranty of any kind, whether express or implied.
- */
-
-#include <mach/hardware.h>
-#include <mach/irqs.h>
-
-               .macro  get_irqnr_preamble, base, tmp
-               .endm
-
-               .macro  get_irqnr_and_base, irqnr, irqstat, base, tmp
-               ldr     \base, =OMAP1_IO_ADDRESS(OMAP_IH1_BASE)
-               ldr     \irqnr, [\base, #IRQ_ITR_REG_OFFSET]
-               ldr     \tmp, [\base, #IRQ_MIR_REG_OFFSET]
-               mov     \irqstat, #0xffffffff
-               bic     \tmp, \irqstat, \tmp
-               tst     \irqnr, \tmp
-               beq     1510f
-
-               ldr     \irqnr, [\base, #IRQ_SIR_FIQ_REG_OFFSET]
-               ldr     \tmp, =omap_irq_flags   @ irq flags address
-               ldr     \tmp, [\tmp, #0]        @ irq flags value
-               cmp     \irqnr, #0
-               ldreq   \irqnr, [\base, #IRQ_SIR_IRQ_REG_OFFSET]
-               cmpeq   \irqnr, \tmp
-               ldreq   \base, =OMAP1_IO_ADDRESS(OMAP_IH2_BASE)
-               ldreq   \irqnr, [\base, #IRQ_SIR_IRQ_REG_OFFSET]
-               addeqs  \irqnr, \irqnr, #32
-1510:
-               .endm
-
index 729992d..9050085 100644 (file)
  * NOTE: See also the OMAP-1510 and 1610 specific IRQ numbers below
  *
  */
-#define INT_CAMERA             1
-#define INT_FIQ                        3
-#define INT_RTDX               6
-#define INT_DSP_MMU_ABORT      7
-#define INT_HOST               8
-#define INT_ABORT              9
-#define INT_BRIDGE_PRIV                13
-#define INT_GPIO_BANK1         14
-#define INT_UART3              15
-#define INT_TIMER3             16
-#define INT_DMA_CH0_6          19
-#define INT_DMA_CH1_7          20
-#define INT_DMA_CH2_8          21
-#define INT_DMA_CH3            22
-#define INT_DMA_CH4            23
-#define INT_DMA_CH5            24
-#define INT_TIMER1             26
-#define INT_WD_TIMER           27
-#define INT_BRIDGE_PUB         28
-#define INT_TIMER2             30
-#define INT_LCD_CTRL           31
+#define INT_CAMERA             (NR_IRQS_LEGACY + 1)
+#define INT_FIQ                        (NR_IRQS_LEGACY + 3)
+#define INT_RTDX               (NR_IRQS_LEGACY + 6)
+#define INT_DSP_MMU_ABORT      (NR_IRQS_LEGACY + 7)
+#define INT_HOST               (NR_IRQS_LEGACY + 8)
+#define INT_ABORT              (NR_IRQS_LEGACY + 9)
+#define INT_BRIDGE_PRIV                (NR_IRQS_LEGACY + 13)
+#define INT_GPIO_BANK1         (NR_IRQS_LEGACY + 14)
+#define INT_UART3              (NR_IRQS_LEGACY + 15)
+#define INT_TIMER3             (NR_IRQS_LEGACY + 16)
+#define INT_DMA_CH0_6          (NR_IRQS_LEGACY + 19)
+#define INT_DMA_CH1_7          (NR_IRQS_LEGACY + 20)
+#define INT_DMA_CH2_8          (NR_IRQS_LEGACY + 21)
+#define INT_DMA_CH3            (NR_IRQS_LEGACY + 22)
+#define INT_DMA_CH4            (NR_IRQS_LEGACY + 23)
+#define INT_DMA_CH5            (NR_IRQS_LEGACY + 24)
+#define INT_TIMER1             (NR_IRQS_LEGACY + 26)
+#define INT_WD_TIMER           (NR_IRQS_LEGACY + 27)
+#define INT_BRIDGE_PUB         (NR_IRQS_LEGACY + 28)
+#define INT_TIMER2             (NR_IRQS_LEGACY + 30)
+#define INT_LCD_CTRL           (NR_IRQS_LEGACY + 31)
 
 /*
  * OMAP-1510 specific IRQ numbers for interrupt handler 1
  */
-#define INT_1510_IH2_IRQ       0
-#define INT_1510_RES2          2
-#define INT_1510_SPI_TX                4
-#define INT_1510_SPI_RX                5
-#define INT_1510_DSP_MAILBOX1  10
-#define INT_1510_DSP_MAILBOX2  11
-#define INT_1510_RES12         12
-#define INT_1510_LB_MMU                17
-#define INT_1510_RES18         18
-#define INT_1510_LOCAL_BUS     29
+#define INT_1510_IH2_IRQ       (NR_IRQS_LEGACY + 0)
+#define INT_1510_RES2          (NR_IRQS_LEGACY + 2)
+#define INT_1510_SPI_TX                (NR_IRQS_LEGACY + 4)
+#define INT_1510_SPI_RX                (NR_IRQS_LEGACY + 5)
+#define INT_1510_DSP_MAILBOX1  (NR_IRQS_LEGACY + 10)
+#define INT_1510_DSP_MAILBOX2  (NR_IRQS_LEGACY + 11)
+#define INT_1510_RES12         (NR_IRQS_LEGACY + 12)
+#define INT_1510_LB_MMU                (NR_IRQS_LEGACY + 17)
+#define INT_1510_RES18         (NR_IRQS_LEGACY + 18)
+#define INT_1510_LOCAL_BUS     (NR_IRQS_LEGACY + 29)
 
 /*
  * OMAP-1610 specific IRQ numbers for interrupt handler 1
  */
 #define INT_1610_IH2_IRQ       INT_1510_IH2_IRQ
-#define INT_1610_IH2_FIQ       2
-#define INT_1610_McBSP2_TX     4
-#define INT_1610_McBSP2_RX     5
-#define INT_1610_DSP_MAILBOX1  10
-#define INT_1610_DSP_MAILBOX2  11
-#define INT_1610_LCD_LINE      12
-#define INT_1610_GPTIMER1      17
-#define INT_1610_GPTIMER2      18
-#define INT_1610_SSR_FIFO_0    29
+#define INT_1610_IH2_FIQ       (NR_IRQS_LEGACY + 2)
+#define INT_1610_McBSP2_TX     (NR_IRQS_LEGACY + 4)
+#define INT_1610_McBSP2_RX     (NR_IRQS_LEGACY + 5)
+#define INT_1610_DSP_MAILBOX1  (NR_IRQS_LEGACY + 10)
+#define INT_1610_DSP_MAILBOX2  (NR_IRQS_LEGACY + 11)
+#define INT_1610_LCD_LINE      (NR_IRQS_LEGACY + 12)
+#define INT_1610_GPTIMER1      (NR_IRQS_LEGACY + 17)
+#define INT_1610_GPTIMER2      (NR_IRQS_LEGACY + 18)
+#define INT_1610_SSR_FIFO_0    (NR_IRQS_LEGACY + 29)
 
 /*
  * OMAP-7xx specific IRQ numbers for interrupt handler 1
  */
-#define INT_7XX_IH2_FIQ                0
-#define INT_7XX_IH2_IRQ                1
-#define INT_7XX_USB_NON_ISO    2
-#define INT_7XX_USB_ISO                3
-#define INT_7XX_ICR            4
-#define INT_7XX_EAC            5
-#define INT_7XX_GPIO_BANK1     6
-#define INT_7XX_GPIO_BANK2     7
-#define INT_7XX_GPIO_BANK3     8
-#define INT_7XX_McBSP2TX       10
-#define INT_7XX_McBSP2RX       11
-#define INT_7XX_McBSP2RX_OVF   12
-#define INT_7XX_LCD_LINE       14
-#define INT_7XX_GSM_PROTECT    15
-#define INT_7XX_TIMER3         16
-#define INT_7XX_GPIO_BANK5     17
-#define INT_7XX_GPIO_BANK6     18
-#define INT_7XX_SPGIO_WR       29
+#define INT_7XX_IH2_FIQ                (NR_IRQS_LEGACY + 0)
+#define INT_7XX_IH2_IRQ                (NR_IRQS_LEGACY + 1)
+#define INT_7XX_USB_NON_ISO    (NR_IRQS_LEGACY + 2)
+#define INT_7XX_USB_ISO                (NR_IRQS_LEGACY + 3)
+#define INT_7XX_ICR            (NR_IRQS_LEGACY + 4)
+#define INT_7XX_EAC            (NR_IRQS_LEGACY + 5)
+#define INT_7XX_GPIO_BANK1     (NR_IRQS_LEGACY + 6)
+#define INT_7XX_GPIO_BANK2     (NR_IRQS_LEGACY + 7)
+#define INT_7XX_GPIO_BANK3     (NR_IRQS_LEGACY + 8)
+#define INT_7XX_McBSP2TX       (NR_IRQS_LEGACY + 10)
+#define INT_7XX_McBSP2RX       (NR_IRQS_LEGACY + 11)
+#define INT_7XX_McBSP2RX_OVF   (NR_IRQS_LEGACY + 12)
+#define INT_7XX_LCD_LINE       (NR_IRQS_LEGACY + 14)
+#define INT_7XX_GSM_PROTECT    (NR_IRQS_LEGACY + 15)
+#define INT_7XX_TIMER3         (NR_IRQS_LEGACY + 16)
+#define INT_7XX_GPIO_BANK5     (NR_IRQS_LEGACY + 17)
+#define INT_7XX_GPIO_BANK6     (NR_IRQS_LEGACY + 18)
+#define INT_7XX_SPGIO_WR       (NR_IRQS_LEGACY + 29)
 
 /*
  * IRQ numbers for interrupt handler 2
  *
  * NOTE: See also the OMAP-1510 and 1610 specific IRQ numbers below
  */
-#define IH2_BASE               32
+#define IH2_BASE               (NR_IRQS_LEGACY + 32)
 
 #define INT_KEYBOARD           (1 + IH2_BASE)
 #define INT_uWireTX            (2 + IH2_BASE)
 #endif
 #define OMAP_FPGA_IRQ_END      (OMAP_FPGA_IRQ_BASE + OMAP_FPGA_NR_IRQS)
 
-#define NR_IRQS                        OMAP_FPGA_IRQ_END
-
-#define OMAP_IRQ_BIT(irq)      (1 << ((irq) % 32))
-
-#include <mach/hardware.h>
+#define OMAP_IRQ_BIT(irq)      (1 << ((irq - NR_IRQS_LEGACY) % 32))
 
 #ifdef CONFIG_FIQ
 #define FIQ_START              1024
index 058a4f7..d43ff0f 100644 (file)
@@ -5,6 +5,9 @@
 #ifndef __ASM_ARCH_MEMORY_H
 #define __ASM_ARCH_MEMORY_H
 
+/* REVISIT: omap1 legacy drivers still rely on this */
+#include <mach/soc.h>
+
 /*
  * Bus address is physical address, except for OMAP-1510 Local Bus.
  * OMAP-1510 bus address is translated into a Local Bus address if the
@@ -14,7 +17,6 @@
  * because of the strncmp().
  */
 #if defined(CONFIG_ARCH_OMAP15XX) && !defined(__ASSEMBLER__)
-#include <mach/soc.h>
 
 /*
  * OMAP-1510 Local Bus address offset
index 2ce6a2d..4700e38 100644 (file)
  */
 #define OMAP_UART_INFO_OFS     0x3ffc
 
-/* OMAP1 serial ports */
-#define OMAP1_UART1_BASE       0xfffb0000
-#define OMAP1_UART2_BASE       0xfffb0800
-#define OMAP1_UART3_BASE       0xfffb9800
-
 #define OMAP_PORT_SHIFT                2
 #define OMAP7XX_PORT_SHIFT     0
 
index 612bd1c..3d93557 100644 (file)
 #ifndef __ASM_ARCH_OMAP_CPU_H
 #define __ASM_ARCH_OMAP_CPU_H
 
+#include <asm/irq.h>
+#include <mach/hardware.h>
+#include <mach/irqs.h>
+
 #ifndef __ASSEMBLY__
 
 #include <linux/bitops.h>
index a8a533d..f4d346f 100644 (file)
@@ -43,6 +43,7 @@
 #include <linux/io.h>
 
 #include <asm/irq.h>
+#include <asm/exception.h>
 #include <asm/mach/irq.h>
 
 #include "soc.h"
 
 struct omap_irq_bank {
        unsigned long base_reg;
+       void __iomem *va;
        unsigned long trigger_map;
        unsigned long wake_enable;
 };
 
-u32 omap_irq_flags;
+static u32 omap_l2_irq;
 static unsigned int irq_bank_count;
 static struct omap_irq_bank *irq_banks;
+static struct irq_domain *domain;
 
-static inline void irq_bank_writel(unsigned long value, int bank, int offset)
-{
-       omap_writel(value, irq_banks[bank].base_reg + offset);
-}
-
-static void omap_ack_irq(struct irq_data *d)
+static inline unsigned int irq_bank_readl(int bank, int offset)
 {
-       if (d->irq > 31)
-               omap_writel(0x1, OMAP_IH2_BASE + IRQ_CONTROL_REG_OFFSET);
-
-       omap_writel(0x1, OMAP_IH1_BASE + IRQ_CONTROL_REG_OFFSET);
+       return readl_relaxed(irq_banks[bank].va + offset);
 }
-
-static void omap_mask_irq(struct irq_data *d)
+static inline void irq_bank_writel(unsigned long value, int bank, int offset)
 {
-       int bank = IRQ_BANK(d->irq);
-       u32 l;
-
-       l = omap_readl(irq_banks[bank].base_reg + IRQ_MIR_REG_OFFSET);
-       l |= 1 << IRQ_BIT(d->irq);
-       omap_writel(l, irq_banks[bank].base_reg + IRQ_MIR_REG_OFFSET);
+       writel_relaxed(value, irq_banks[bank].va + offset);
 }
 
-static void omap_unmask_irq(struct irq_data *d)
+static void omap_ack_irq(int irq)
 {
-       int bank = IRQ_BANK(d->irq);
-       u32 l;
+       if (irq > 31)
+               writel_relaxed(0x1, irq_banks[1].va + IRQ_CONTROL_REG_OFFSET);
 
-       l = omap_readl(irq_banks[bank].base_reg + IRQ_MIR_REG_OFFSET);
-       l &= ~(1 << IRQ_BIT(d->irq));
-       omap_writel(l, irq_banks[bank].base_reg + IRQ_MIR_REG_OFFSET);
+       writel_relaxed(0x1, irq_banks[0].va + IRQ_CONTROL_REG_OFFSET);
 }
 
 static void omap_mask_ack_irq(struct irq_data *d)
 {
-       omap_mask_irq(d);
-       omap_ack_irq(d);
-}
-
-static int omap_wake_irq(struct irq_data *d, unsigned int enable)
-{
-       int bank = IRQ_BANK(d->irq);
-
-       if (enable)
-               irq_banks[bank].wake_enable |= IRQ_BIT(d->irq);
-       else
-               irq_banks[bank].wake_enable &= ~IRQ_BIT(d->irq);
+       struct irq_chip_type *ct = irq_data_get_chip_type(d);
 
-       return 0;
+       ct->chip.irq_mask(d);
+       omap_ack_irq(d->irq);
 }
 
-
 /*
  * Allows tuning the IRQ type and priority
  *
@@ -165,46 +141,105 @@ static struct omap_irq_bank omap1610_irq_banks[] = {
 };
 #endif
 
-static struct irq_chip omap_irq_chip = {
-       .name           = "MPU",
-       .irq_ack        = omap_mask_ack_irq,
-       .irq_mask       = omap_mask_irq,
-       .irq_unmask     = omap_unmask_irq,
-       .irq_set_wake   = omap_wake_irq,
-};
+asmlinkage void __exception_irq_entry omap1_handle_irq(struct pt_regs *regs)
+{
+       void __iomem *l1 = irq_banks[0].va;
+       void __iomem *l2 = irq_banks[1].va;
+       u32 irqnr;
+
+       do {
+               irqnr = readl_relaxed(l1 + IRQ_ITR_REG_OFFSET);
+               irqnr &= ~(readl_relaxed(l1 + IRQ_MIR_REG_OFFSET) & 0xffffffff);
+               if (!irqnr)
+                       break;
+
+               irqnr = readl_relaxed(l1 + IRQ_SIR_FIQ_REG_OFFSET);
+               if (irqnr)
+                       goto irq;
+
+               irqnr = readl_relaxed(l1 + IRQ_SIR_IRQ_REG_OFFSET);
+               if (irqnr == omap_l2_irq) {
+                       irqnr = readl_relaxed(l2 + IRQ_SIR_IRQ_REG_OFFSET);
+                       if (irqnr)
+                               irqnr += 32;
+               }
+irq:
+               if (irqnr)
+                       handle_domain_irq(domain, irqnr, regs);
+               else
+                       break;
+       } while (irqnr);
+}
+
+static __init void
+omap_alloc_gc(void __iomem *base, unsigned int irq_start, unsigned int num)
+{
+       struct irq_chip_generic *gc;
+       struct irq_chip_type *ct;
+
+       gc = irq_alloc_generic_chip("MPU", 1, irq_start, base,
+                                   handle_level_irq);
+       ct = gc->chip_types;
+       ct->chip.irq_ack = omap_mask_ack_irq;
+       ct->chip.irq_mask = irq_gc_mask_set_bit;
+       ct->chip.irq_unmask = irq_gc_mask_clr_bit;
+       ct->chip.irq_set_wake = irq_gc_set_wake;
+       ct->regs.mask = IRQ_MIR_REG_OFFSET;
+       irq_setup_generic_chip(gc, IRQ_MSK(num), IRQ_GC_INIT_MASK_CACHE,
+                              IRQ_NOREQUEST | IRQ_NOPROBE, 0);
+}
 
 void __init omap1_init_irq(void)
 {
-       int i, j;
+       struct irq_chip_type *ct;
+       struct irq_data *d = NULL;
+       int i, j, irq_base;
+       unsigned long nr_irqs;
 
 #if defined(CONFIG_ARCH_OMAP730) || defined(CONFIG_ARCH_OMAP850)
        if (cpu_is_omap7xx()) {
-               omap_irq_flags = INT_7XX_IH2_IRQ;
                irq_banks = omap7xx_irq_banks;
                irq_bank_count = ARRAY_SIZE(omap7xx_irq_banks);
        }
 #endif
 #ifdef CONFIG_ARCH_OMAP15XX
        if (cpu_is_omap1510()) {
-               omap_irq_flags = INT_1510_IH2_IRQ;
                irq_banks = omap1510_irq_banks;
                irq_bank_count = ARRAY_SIZE(omap1510_irq_banks);
        }
        if (cpu_is_omap310()) {
-               omap_irq_flags = INT_1510_IH2_IRQ;
                irq_banks = omap310_irq_banks;
                irq_bank_count = ARRAY_SIZE(omap310_irq_banks);
        }
 #endif
 #if defined(CONFIG_ARCH_OMAP16XX)
        if (cpu_is_omap16xx()) {
-               omap_irq_flags = INT_1510_IH2_IRQ;
                irq_banks = omap1610_irq_banks;
                irq_bank_count = ARRAY_SIZE(omap1610_irq_banks);
        }
 #endif
-       printk("Total of %i interrupts in %i interrupt banks\n",
-              irq_bank_count * 32, irq_bank_count);
+
+       for (i = 0; i < irq_bank_count; i++) {
+               irq_banks[i].va = ioremap(irq_banks[i].base_reg, 0xff);
+               if (WARN_ON(!irq_banks[i].va))
+                       return;
+       }
+
+       nr_irqs = irq_bank_count * 32;
+
+       irq_base = irq_alloc_descs(-1, 0, nr_irqs, 0);
+       if (irq_base < 0) {
+               pr_warn("Couldn't allocate IRQ numbers\n");
+               irq_base = 0;
+       }
+       omap_l2_irq = cpu_is_omap7xx() ? irq_base + 1 : irq_base;
+       omap_l2_irq -= NR_IRQS_LEGACY;
+
+       domain = irq_domain_add_legacy(NULL, nr_irqs, irq_base, 0,
+                                      &irq_domain_simple_ops, NULL);
+
+       pr_info("Total of %lu interrupts in %i interrupt banks\n",
+               nr_irqs, irq_bank_count);
 
        /* Mask and clear all interrupts */
        for (i = 0; i < irq_bank_count; i++) {
@@ -227,19 +262,15 @@ void __init omap1_init_irq(void)
 
                        irq_trigger = irq_banks[i].trigger_map >> IRQ_BIT(j);
                        omap_irq_set_cfg(j, 0, 0, irq_trigger);
-
-                       irq_set_chip_and_handler(j, &omap_irq_chip,
-                                                handle_level_irq);
                        set_irq_flags(j, IRQF_VALID);
                }
+               omap_alloc_gc(irq_banks[i].va, irq_base + i * 32, 32);
        }
 
        /* Unmask level 2 handler */
-
-       if (cpu_is_omap7xx())
-               omap_unmask_irq(irq_get_irq_data(INT_7XX_IH2_IRQ));
-       else if (cpu_is_omap15xx())
-               omap_unmask_irq(irq_get_irq_data(INT_1510_IH2_IRQ));
-       else if (cpu_is_omap16xx())
-               omap_unmask_irq(irq_get_irq_data(INT_1610_IH2_IRQ));
+       d = irq_get_irq_data(irq_find_mapping(domain, omap_l2_irq));
+       if (d) {
+               ct = irq_data_get_chip_type(d);
+               ct->chip.irq_unmask(d);
+       }
 }
index 667ce50..599490a 100644 (file)
@@ -36,7 +36,7 @@
 static struct omap_mux_cfg arch_mux_cfg;
 
 #if defined(CONFIG_ARCH_OMAP730) || defined(CONFIG_ARCH_OMAP850)
-static struct pin_config __initdata_or_module omap7xx_pins[] = {
+static struct pin_config omap7xx_pins[] = {
 MUX_CFG_7XX("E2_7XX_KBR0",        12,   21,    0,   20,   1, 0)
 MUX_CFG_7XX("J7_7XX_KBR1",        12,   25,    0,   24,   1, 0)
 MUX_CFG_7XX("E1_7XX_KBR2",        12,   29,    0,   28,   1, 0)
@@ -82,7 +82,7 @@ MUX_CFG_7XX("UART_7XX_2",          8,    1,    6,    0,   0, 0)
 #endif /* CONFIG_ARCH_OMAP730 || CONFIG_ARCH_OMAP850 */
 
 #if defined(CONFIG_ARCH_OMAP15XX) || defined(CONFIG_ARCH_OMAP16XX)
-static struct pin_config __initdata_or_module omap1xxx_pins[] = {
+static struct pin_config omap1xxx_pins[] = {
 /*
  *      description            mux  mode   mux  pull pull  pull  pu_pd  pu  dbg
  *                             reg  offset mode reg  bit   ena   reg
@@ -343,7 +343,7 @@ MUX_CFG("Y14_1610_CCP_DATAM",        9,   21,    6,   2,   3,   1,    2,     0,  0)
 #define OMAP1XXX_PINS_SZ       0
 #endif /* CONFIG_ARCH_OMAP15XX || CONFIG_ARCH_OMAP16XX */
 
-static int __init_or_module omap1_cfg_reg(const struct pin_config *cfg)
+static int omap1_cfg_reg(const struct pin_config *cfg)
 {
        static DEFINE_SPINLOCK(mux_spin_lock);
        unsigned long flags;
@@ -469,7 +469,7 @@ int __init omap_mux_register(struct omap_mux_cfg *arch_mux_cfg)
 /*
  * Sets the Omap MUX and PULL_DWN registers based on the table
  */
-int __init_or_module omap_cfg_reg(const unsigned long index)
+int omap_cfg_reg(const unsigned long index)
 {
        struct pin_config *reg;
 
index dd94567..ee5460b 100644 (file)
@@ -62,6 +62,7 @@
 #include "iomap.h"
 #include "clock.h"
 #include "pm.h"
+#include "soc.h"
 #include "sram.h"
 
 static unsigned int arm_sleep_save[ARM_SLEEP_SAVE_SIZE];
index d1ac080..a65bd0c 100644 (file)
@@ -25,6 +25,7 @@
 #include <mach/mux.h>
 
 #include "pm.h"
+#include "soc.h"
 
 static struct clk * uart1_ck;
 static struct clk * uart2_ck;
index bde7a35..06c5ba7 100644 (file)
 #include <linux/platform_device.h>
 #include <linux/platform_data/dmtimer-omap.h>
 
-#include <mach/irqs.h>
-
 #include <plat/dmtimer.h>
 
+#include "soc.h"
+
 #define OMAP1610_GPTIMER1_BASE         0xfffb1400
 #define OMAP1610_GPTIMER2_BASE         0xfffb1c00
 #define OMAP1610_GPTIMER3_BASE         0xfffb2400
index 166b18f..4a7303c 100644 (file)
@@ -224,13 +224,13 @@ static int _omap_device_notifier_call(struct notifier_block *nb,
  */
 static int _omap_device_enable_hwmods(struct omap_device *od)
 {
+       int ret = 0;
        int i;
 
        for (i = 0; i < od->hwmods_cnt; i++)
-               omap_hwmod_enable(od->hwmods[i]);
+               ret |= omap_hwmod_enable(od->hwmods[i]);
 
-       /* XXX pass along return value here? */
-       return 0;
+       return ret;
 }
 
 /**
@@ -241,13 +241,13 @@ static int _omap_device_enable_hwmods(struct omap_device *od)
  */
 static int _omap_device_idle_hwmods(struct omap_device *od)
 {
+       int ret = 0;
        int i;
 
        for (i = 0; i < od->hwmods_cnt; i++)
-               omap_hwmod_idle(od->hwmods[i]);
+               ret |= omap_hwmod_idle(od->hwmods[i]);
 
-       /* XXX pass along return value here? */
-       return 0;
+       return ret;
 }
 
 /* Public functions for use by core code */
@@ -595,18 +595,20 @@ static int _od_runtime_suspend(struct device *dev)
        int ret;
 
        ret = pm_generic_runtime_suspend(dev);
+       if (ret)
+               return ret;
 
-       if (!ret)
-               omap_device_idle(pdev);
-
-       return ret;
+       return omap_device_idle(pdev);
 }
 
 static int _od_runtime_resume(struct device *dev)
 {
        struct platform_device *pdev = to_platform_device(dev);
+       int ret;
 
-       omap_device_enable(pdev);
+       ret = omap_device_enable(pdev);
+       if (ret)
+               return ret;
 
        return pm_generic_runtime_resume(dev);
 }
@@ -743,7 +745,8 @@ int omap_device_enable(struct platform_device *pdev)
 
        ret = _omap_device_enable_hwmods(od);
 
-       od->_state = OMAP_DEVICE_STATE_ENABLED;
+       if (ret == 0)
+               od->_state = OMAP_DEVICE_STATE_ENABLED;
 
        return ret;
 }
@@ -773,7 +776,8 @@ int omap_device_idle(struct platform_device *pdev)
 
        ret = _omap_device_idle_hwmods(od);
 
-       od->_state = OMAP_DEVICE_STATE_IDLE;
+       if (ret == 0)
+               od->_state = OMAP_DEVICE_STATE_IDLE;
 
        return ret;
 }
index 752969f..d78c12e 100644 (file)
@@ -3318,16 +3318,17 @@ int omap_hwmod_enable(struct omap_hwmod *oh)
  */
 int omap_hwmod_idle(struct omap_hwmod *oh)
 {
+       int r;
        unsigned long flags;
 
        if (!oh)
                return -EINVAL;
 
        spin_lock_irqsave(&oh->_lock, flags);
-       _idle(oh);
+       r = _idle(oh);
        spin_unlock_irqrestore(&oh->_lock, flags);
 
-       return 0;
+       return r;
 }
 
 /**
@@ -3340,16 +3341,17 @@ int omap_hwmod_idle(struct omap_hwmod *oh)
  */
 int omap_hwmod_shutdown(struct omap_hwmod *oh)
 {
+       int r;
        unsigned long flags;
 
        if (!oh)
                return -EINVAL;
 
        spin_lock_irqsave(&oh->_lock, flags);
-       _shutdown(oh);
+       r = _shutdown(oh);
        spin_unlock_irqrestore(&oh->_lock, flags);
 
-       return 0;
+       return r;
 }
 
 /*
index 9611c91..b5d27ec 100644 (file)
@@ -109,6 +109,12 @@ extern struct omap_hwmod_sysc_fields omap_hwmod_sysc_type3;
 
 #define DEBUG_OMAPUART_FLAGS   (HWMOD_INIT_NO_IDLE | HWMOD_INIT_NO_RESET)
 
+#ifdef CONFIG_OMAP_GPMC_DEBUG
+#define DEBUG_OMAP_GPMC_HWMOD_FLAGS    HWMOD_INIT_NO_RESET
+#else
+#define DEBUG_OMAP_GPMC_HWMOD_FLAGS    0
+#endif
+
 #if defined(CONFIG_DEBUG_OMAP2UART1)
 #undef DEBUG_OMAP2UART1_FLAGS
 #define DEBUG_OMAP2UART1_FLAGS DEBUG_OMAPUART_FLAGS
index 8821b9d..6dcfd03 100644 (file)
@@ -762,16 +762,8 @@ struct omap_hwmod omap2xxx_gpmc_hwmod = {
        .name           = "gpmc",
        .class          = &omap2xxx_gpmc_hwmod_class,
        .main_clk       = "gpmc_fck",
-       /*
-        * XXX HWMOD_INIT_NO_RESET should not be needed for this IP
-        * block.  It is not being added due to any known bugs with
-        * resetting the GPMC IP block, but rather because any timings
-        * set by the bootloader are not being correctly programmed by
-        * the kernel from the board file or DT data.
-        * HWMOD_INIT_NO_RESET should be removed ASAP.
-        */
-       .flags          = (HWMOD_INIT_NO_IDLE | HWMOD_INIT_NO_RESET |
-                          HWMOD_NO_IDLEST),
+       /* Skip reset for CONFIG_OMAP_GPMC_DEBUG for bootloader timings */
+       .flags          = HWMOD_NO_IDLEST | DEBUG_OMAP_GPMC_HWMOD_FLAGS,
        .prcm           = {
                .omap2  = {
                        .prcm_reg_id = 3,
index 130332c..7f73796 100644 (file)
@@ -145,6 +145,7 @@ extern struct omap_hwmod am33xx_uart5_hwmod;
 extern struct omap_hwmod am33xx_uart6_hwmod;
 extern struct omap_hwmod am33xx_wd_timer1_hwmod;
 
+extern struct omap_hwmod_class am33xx_emif_hwmod_class;
 extern struct omap_hwmod_class am33xx_l4_hwmod_class;
 extern struct omap_hwmod_class am33xx_wkup_m3_hwmod_class;
 extern struct omap_hwmod_class am33xx_control_hwmod_class;
index cabc569..907a452 100644 (file)
@@ -203,6 +203,19 @@ struct omap_hwmod am33xx_prcm_hwmod = {
 };
 
 /*
+ * 'emif' class
+ * instance(s): emif
+ */
+static struct omap_hwmod_class_sysconfig am33xx_emif_sysc = {
+       .rev_offs       = 0x0000,
+};
+
+struct omap_hwmod_class am33xx_emif_hwmod_class = {
+       .name           = "emif",
+       .sysc           = &am33xx_emif_sysc,
+};
+
+/*
  * 'aes0' class
  */
 static struct omap_hwmod_class_sysconfig am33xx_aes0_sysc = {
@@ -668,7 +681,8 @@ struct omap_hwmod am33xx_gpmc_hwmod = {
        .name           = "gpmc",
        .class          = &am33xx_gpmc_hwmod_class,
        .clkdm_name     = "l3s_clkdm",
-       .flags          = (HWMOD_INIT_NO_IDLE | HWMOD_INIT_NO_RESET),
+       /* Skip reset for CONFIG_OMAP_GPMC_DEBUG for bootloader timings */
+       .flags          = DEBUG_OMAP_GPMC_HWMOD_FLAGS,
        .main_clk       = "l3s_gclk",
        .prcm           = {
                .omap4  = {
index 0cf7b56..cc0791d 100644 (file)
  * IP blocks
  */
 
-/*
- * 'emif' class
- * instance(s): emif
- */
-static struct omap_hwmod_class_sysconfig am33xx_emif_sysc = {
-       .rev_offs       = 0x0000,
-};
-
-static struct omap_hwmod_class am33xx_emif_hwmod_class = {
-       .name           = "emif",
-       .sysc           = &am33xx_emif_sysc,
-};
-
 /* emif */
 static struct omap_hwmod am33xx_emif_hwmod = {
        .name           = "emif",
index 4e8e93c..dc55f8d 100644 (file)
@@ -2169,16 +2169,8 @@ static struct omap_hwmod omap3xxx_gpmc_hwmod = {
        .clkdm_name     = "core_l3_clkdm",
        .mpu_irqs       = omap3xxx_gpmc_irqs,
        .main_clk       = "gpmc_fck",
-       /*
-        * XXX HWMOD_INIT_NO_RESET should not be needed for this IP
-        * block.  It is not being added due to any known bugs with
-        * resetting the GPMC IP block, but rather because any timings
-        * set by the bootloader are not being correctly programmed by
-        * the kernel from the board file or DT data.
-        * HWMOD_INIT_NO_RESET should be removed ASAP.
-        */
-       .flags          = (HWMOD_INIT_NO_IDLE | HWMOD_INIT_NO_RESET |
-                          HWMOD_NO_IDLEST),
+       /* Skip reset for CONFIG_OMAP_GPMC_DEBUG for bootloader timings */
+       .flags          = HWMOD_NO_IDLEST | DEBUG_OMAP_GPMC_HWMOD_FLAGS,
 };
 
 /*
@@ -3744,29 +3736,54 @@ static struct omap_hwmod_ocp_if *omap3xxx_hwmod_ocp_ifs[] __initdata = {
 /* GP-only hwmod links */
 static struct omap_hwmod_ocp_if *omap34xx_gp_hwmod_ocp_ifs[] __initdata = {
        &omap3xxx_l4_sec__timer12,
-       &omap3xxx_l4_core__sham,
-       &omap3xxx_l4_core__aes,
        NULL
 };
 
 static struct omap_hwmod_ocp_if *omap36xx_gp_hwmod_ocp_ifs[] __initdata = {
        &omap3xxx_l4_sec__timer12,
-       &omap3xxx_l4_core__sham,
-       &omap3xxx_l4_core__aes,
        NULL
 };
 
 static struct omap_hwmod_ocp_if *am35xx_gp_hwmod_ocp_ifs[] __initdata = {
        &omap3xxx_l4_sec__timer12,
-       /*
-        * Apparently the SHA/MD5 and AES accelerator IP blocks are
-        * only present on some AM35xx chips, and no one knows which
-        * ones.  See
-        * http://www.spinics.net/lists/arm-kernel/msg215466.html So
-        * if you need these IP blocks on an AM35xx, try uncommenting
-        * the following lines.
-        */
+       NULL
+};
+
+/* crypto hwmod links */
+static struct omap_hwmod_ocp_if *omap34xx_sham_hwmod_ocp_ifs[] __initdata = {
+       &omap3xxx_l4_core__sham,
+       NULL
+};
+
+static struct omap_hwmod_ocp_if *omap34xx_aes_hwmod_ocp_ifs[] __initdata = {
+       &omap3xxx_l4_core__aes,
+       NULL
+};
+
+static struct omap_hwmod_ocp_if *omap36xx_sham_hwmod_ocp_ifs[] __initdata = {
+       &omap3xxx_l4_core__sham,
+       NULL
+};
+
+static struct omap_hwmod_ocp_if *omap36xx_aes_hwmod_ocp_ifs[] __initdata = {
+       &omap3xxx_l4_core__aes,
+       NULL
+};
+
+/*
+ * Apparently the SHA/MD5 and AES accelerator IP blocks are
+ * only present on some AM35xx chips, and no one knows which
+ * ones.  See
+ * http://www.spinics.net/lists/arm-kernel/msg215466.html So
+ * if you need these IP blocks on an AM35xx, try uncommenting
+ * the following lines.
+ */
+static struct omap_hwmod_ocp_if *am35xx_sham_hwmod_ocp_ifs[] __initdata = {
        /* &omap3xxx_l4_core__sham, */
+       NULL
+};
+
+static struct omap_hwmod_ocp_if *am35xx_aes_hwmod_ocp_ifs[] __initdata = {
        /* &omap3xxx_l4_core__aes, */
        NULL
 };
@@ -3868,10 +3885,41 @@ static struct omap_hwmod_ocp_if *omap3xxx_dss_hwmod_ocp_ifs[] __initdata = {
        NULL
 };
 
+/**
+ * omap3xxx_hwmod_is_hs_ip_block_usable - is a security IP block accessible?
+ * @bus: struct device_node * for the top-level OMAP DT data
+ * @dev_name: device name used in the DT file
+ *
+ * Determine whether a "secure" IP block @dev_name is usable by Linux.
+ * There doesn't appear to be a 100% reliable way to determine this,
+ * so we rely on heuristics.  If @bus is null, meaning there's no DT
+ * data, then we only assume the IP block is accessible if the OMAP is
+ * fused as a 'general-purpose' SoC.  If however DT data is present,
+ * test to see if the IP block is described in the DT data and set to
+ * 'status = "okay"'.  If so then we assume the ODM has configured the
+ * OMAP firewalls to allow access to the IP block.
+ *
+ * Return: 0 if device named @dev_name is not likely to be accessible,
+ * or 1 if it is likely to be accessible.
+ */
+static int __init omap3xxx_hwmod_is_hs_ip_block_usable(struct device_node *bus,
+                                                      const char *dev_name)
+{
+       if (!bus)
+               return (omap_type() == OMAP2_DEVICE_TYPE_GP) ? 1 : 0;
+
+       if (of_device_is_available(of_find_node_by_name(bus, dev_name)))
+               return 1;
+
+       return 0;
+}
+
 int __init omap3xxx_hwmod_init(void)
 {
        int r;
-       struct omap_hwmod_ocp_if **h = NULL, **h_gp = NULL;
+       struct omap_hwmod_ocp_if **h = NULL, **h_gp = NULL, **h_sham = NULL;
+       struct omap_hwmod_ocp_if **h_aes = NULL;
+       struct device_node *bus = NULL;
        unsigned int rev;
 
        omap_hwmod_init();
@@ -3893,13 +3941,19 @@ int __init omap3xxx_hwmod_init(void)
            rev == OMAP3430_REV_ES3_1 || rev == OMAP3430_REV_ES3_1_2) {
                h = omap34xx_hwmod_ocp_ifs;
                h_gp = omap34xx_gp_hwmod_ocp_ifs;
+               h_sham = omap34xx_sham_hwmod_ocp_ifs;
+               h_aes = omap34xx_aes_hwmod_ocp_ifs;
        } else if (rev == AM35XX_REV_ES1_0 || rev == AM35XX_REV_ES1_1) {
                h = am35xx_hwmod_ocp_ifs;
                h_gp = am35xx_gp_hwmod_ocp_ifs;
+               h_sham = am35xx_sham_hwmod_ocp_ifs;
+               h_aes = am35xx_aes_hwmod_ocp_ifs;
        } else if (rev == OMAP3630_REV_ES1_0 || rev == OMAP3630_REV_ES1_1 ||
                   rev == OMAP3630_REV_ES1_2) {
                h = omap36xx_hwmod_ocp_ifs;
                h_gp = omap36xx_gp_hwmod_ocp_ifs;
+               h_sham = omap36xx_sham_hwmod_ocp_ifs;
+               h_aes = omap36xx_aes_hwmod_ocp_ifs;
        } else {
                WARN(1, "OMAP3 hwmod family init: unknown chip type\n");
                return -EINVAL;
@@ -3916,6 +3970,25 @@ int __init omap3xxx_hwmod_init(void)
                        return r;
        }
 
+       /*
+        * Register crypto hwmod links only if they are not disabled in DT.
+        * If DT information is missing, enable them only for GP devices.
+        */
+
+       if (of_have_populated_dt())
+               bus = of_find_node_by_name(NULL, "ocp");
+
+       if (h_sham && omap3xxx_hwmod_is_hs_ip_block_usable(bus, "sham")) {
+               r = omap_hwmod_register_links(h_sham);
+               if (r < 0)
+                       return r;
+       }
+
+       if (h_aes && omap3xxx_hwmod_is_hs_ip_block_usable(bus, "aes")) {
+               r = omap_hwmod_register_links(h_aes);
+               if (r < 0)
+                       return r;
+       }
 
        /*
         * Register hwmod links specific to certain ES levels of a
index 17e8004..215d5ef 100644 (file)
 
 
 /* IP blocks */
+static struct omap_hwmod am43xx_emif_hwmod = {
+       .name           = "emif",
+       .class          = &am33xx_emif_hwmod_class,
+       .clkdm_name     = "emif_clkdm",
+       .flags          = HWMOD_INIT_NO_IDLE,
+       .main_clk       = "dpll_ddr_m2_ck",
+       .prcm           = {
+               .omap4  = {
+                       .clkctrl_offs   = AM43XX_CM_PER_EMIF_CLKCTRL_OFFSET,
+                       .modulemode     = MODULEMODE_SWCTRL,
+               },
+       },
+};
+
 static struct omap_hwmod am43xx_l4_hs_hwmod = {
        .name           = "l4_hs",
        .class          = &am33xx_l4_hwmod_class,
@@ -583,6 +597,13 @@ static struct omap_hwmod am43xx_vpfe1_hwmod = {
 };
 
 /* Interfaces */
+static struct omap_hwmod_ocp_if am43xx_l3_main__emif = {
+       .master         = &am33xx_l3_main_hwmod,
+       .slave          = &am43xx_emif_hwmod,
+       .clk            = "dpll_core_m4_ck",
+       .user           = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
 static struct omap_hwmod_ocp_if am43xx_l3_main__l4_hs = {
        .master         = &am33xx_l3_main_hwmod,
        .slave          = &am43xx_l4_hs_hwmod,
@@ -918,6 +939,7 @@ static struct omap_hwmod_ocp_if *am43xx_hwmod_ocp_ifs[] __initdata = {
        &am33xx_l3_main__l3_instr,
        &am33xx_l3_main__gfx,
        &am33xx_l3_s__l3_main,
+       &am43xx_l3_main__emif,
        &am33xx_pruss__l3_main,
        &am43xx_wkup_m3__l4_wkup,
        &am33xx_gfx__l3_main,
index f5e68a7..43eebf2 100644 (file)
@@ -1188,15 +1188,8 @@ static struct omap_hwmod omap44xx_gpmc_hwmod = {
        .name           = "gpmc",
        .class          = &omap44xx_gpmc_hwmod_class,
        .clkdm_name     = "l3_2_clkdm",
-       /*
-        * XXX HWMOD_INIT_NO_RESET should not be needed for this IP
-        * block.  It is not being added due to any known bugs with
-        * resetting the GPMC IP block, but rather because any timings
-        * set by the bootloader are not being correctly programmed by
-        * the kernel from the board file or DT data.
-        * HWMOD_INIT_NO_RESET should be removed ASAP.
-        */
-       .flags          = HWMOD_INIT_NO_IDLE | HWMOD_INIT_NO_RESET,
+       /* Skip reset for CONFIG_OMAP_GPMC_DEBUG for bootloader timings */
+       .flags          = DEBUG_OMAP_GPMC_HWMOD_FLAGS,
        .prcm = {
                .omap4 = {
                        .clkctrl_offs = OMAP4_CM_L3_2_GPMC_CLKCTRL_OFFSET,
index 0e64c2f..a0411f3 100644 (file)
@@ -819,8 +819,8 @@ static struct omap_hwmod dra7xx_gpmc_hwmod = {
        .name           = "gpmc",
        .class          = &dra7xx_gpmc_hwmod_class,
        .clkdm_name     = "l3main1_clkdm",
-       .flags          = (HWMOD_INIT_NO_IDLE | HWMOD_INIT_NO_RESET |
-                          HWMOD_SWSUP_SIDLE),
+       /* Skip reset for CONFIG_OMAP_GPMC_DEBUG for bootloader timings */
+       .flags          = HWMOD_SWSUP_SIDLE | DEBUG_OMAP_GPMC_HWMOD_FLAGS,
        .main_clk       = "l3_iclk_div",
        .prcm = {
                .omap4 = {
index cab1eb6..c924137 100644 (file)
@@ -478,6 +478,8 @@ static struct omap_hwmod dm81xx_gpmc_hwmod = {
        .clkdm_name     = "alwon_l3s_clkdm",
        .class          = &dm81xx_gpmc_hwmod_class,
        .main_clk       = "sysclk6_ck",
+       /* Skip reset for CONFIG_OMAP_GPMC_DEBUG for bootloader timings */
+       .flags          = DEBUG_OMAP_GPMC_HWMOD_FLAGS,
        .prcm = {
                .omap4 = {
                        .clkctrl_offs = DM816X_CM_ALWON_GPMC_CLKCTRL,
index d026199..7eebc27 100644 (file)
 #define AM43XX_CM_PER_HDQ1W_CLKCTRL_OFFSET             0x04a0
 #define AM43XX_CM_PER_VPFE0_CLKCTRL_OFFSET             0x0068
 #define AM43XX_CM_PER_VPFE1_CLKCTRL_OFFSET             0x0070
+#define AM43XX_CM_PER_EMIF_CLKCTRL_OFFSET              0x0720
+
 #endif
index 4087d33..2ceed40 100644 (file)
@@ -3,16 +3,15 @@
 #
 
 # Common support (must be linked before board specific support)
-obj-y                          += clock.o devices.o generic.o irq.o \
-                                  reset.o
+obj-y                          += devices.o generic.o irq.o reset.o
 obj-$(CONFIG_PM)               += pm.o sleep.o standby.o
 
 # Generic drivers that other drivers may depend upon
 
 # SoC-specific code
-obj-$(CONFIG_PXA25x)           += mfp-pxa2xx.o clock-pxa2xx.o pxa2xx.o pxa25x.o
-obj-$(CONFIG_PXA27x)           += mfp-pxa2xx.o clock-pxa2xx.o pxa2xx.o pxa27x.o
-obj-$(CONFIG_PXA3xx)           += mfp-pxa3xx.o clock-pxa3xx.o pxa3xx.o smemc.o pxa3xx-ulpi.o
+obj-$(CONFIG_PXA25x)           += mfp-pxa2xx.o pxa2xx.o pxa25x.o
+obj-$(CONFIG_PXA27x)           += mfp-pxa2xx.o pxa2xx.o pxa27x.o
+obj-$(CONFIG_PXA3xx)           += mfp-pxa3xx.o pxa3xx.o smemc.o pxa3xx-ulpi.o
 obj-$(CONFIG_CPU_PXA300)       += pxa300.o
 obj-$(CONFIG_CPU_PXA320)       += pxa320.o
 obj-$(CONFIG_CPU_PXA930)       += pxa930.o
diff --git a/arch/arm/mach-pxa/clock-pxa2xx.c b/arch/arm/mach-pxa/clock-pxa2xx.c
deleted file mode 100644 (file)
index 9ee2ad6..0000000
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * linux/arch/arm/mach-pxa/clock-pxa2xx.c
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/io.h>
-#include <linux/syscore_ops.h>
-
-#include <mach/pxa2xx-regs.h>
-
-#include "clock.h"
-
-void clk_pxa2xx_cken_enable(struct clk *clk)
-{
-       CKEN |= 1 << clk->cken;
-}
-
-void clk_pxa2xx_cken_disable(struct clk *clk)
-{
-       CKEN &= ~(1 << clk->cken);
-}
-
-const struct clkops clk_pxa2xx_cken_ops = {
-       .enable         = clk_pxa2xx_cken_enable,
-       .disable        = clk_pxa2xx_cken_disable,
-};
-
-#ifdef CONFIG_PM
-static uint32_t saved_cken;
-
-static int pxa2xx_clock_suspend(void)
-{
-       saved_cken = CKEN;
-       return 0;
-}
-
-static void pxa2xx_clock_resume(void)
-{
-       CKEN = saved_cken;
-}
-#else
-#define pxa2xx_clock_suspend   NULL
-#define pxa2xx_clock_resume    NULL
-#endif
-
-struct syscore_ops pxa2xx_clock_syscore_ops = {
-       .suspend        = pxa2xx_clock_suspend,
-       .resume         = pxa2xx_clock_resume,
-};
diff --git a/arch/arm/mach-pxa/clock-pxa3xx.c b/arch/arm/mach-pxa/clock-pxa3xx.c
deleted file mode 100644 (file)
index d4e9499..0000000
+++ /dev/null
@@ -1,212 +0,0 @@
-/*
- * linux/arch/arm/mach-pxa/clock-pxa3xx.c
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/io.h>
-#include <linux/syscore_ops.h>
-
-#include <mach/smemc.h>
-#include <mach/pxa3xx-regs.h>
-
-#include "clock.h"
-
-/* Crystal clock: 13MHz */
-#define BASE_CLK       13000000
-
-/* Ring Oscillator Clock: 60MHz */
-#define RO_CLK         60000000
-
-#define ACCR_D0CS      (1 << 26)
-#define ACCR_PCCE      (1 << 11)
-
-/* crystal frequency to HSIO bus frequency multiplier (HSS) */
-static unsigned char hss_mult[4] = { 8, 12, 16, 24 };
-
-/*
- * Get the clock frequency as reflected by CCSR and the turbo flag.
- * We assume these values have been applied via a fcs.
- * If info is not 0 we also display the current settings.
- */
-unsigned int pxa3xx_get_clk_frequency_khz(int info)
-{
-       unsigned long acsr, xclkcfg;
-       unsigned int t, xl, xn, hss, ro, XL, XN, CLK, HSS;
-
-       /* Read XCLKCFG register turbo bit */
-       __asm__ __volatile__("mrc\tp14, 0, %0, c6, c0, 0" : "=r"(xclkcfg));
-       t = xclkcfg & 0x1;
-
-       acsr = ACSR;
-
-       xl  = acsr & 0x1f;
-       xn  = (acsr >> 8) & 0x7;
-       hss = (acsr >> 14) & 0x3;
-
-       XL = xl * BASE_CLK;
-       XN = xn * XL;
-
-       ro = acsr & ACCR_D0CS;
-
-       CLK = (ro) ? RO_CLK : ((t) ? XN : XL);
-       HSS = (ro) ? RO_CLK : hss_mult[hss] * BASE_CLK;
-
-       if (info) {
-               pr_info("RO Mode clock: %d.%02dMHz (%sactive)\n",
-                       RO_CLK / 1000000, (RO_CLK % 1000000) / 10000,
-                       (ro) ? "" : "in");
-               pr_info("Run Mode clock: %d.%02dMHz (*%d)\n",
-                       XL / 1000000, (XL % 1000000) / 10000, xl);
-               pr_info("Turbo Mode clock: %d.%02dMHz (*%d, %sactive)\n",
-                       XN / 1000000, (XN % 1000000) / 10000, xn,
-                       (t) ? "" : "in");
-               pr_info("HSIO bus clock: %d.%02dMHz\n",
-                       HSS / 1000000, (HSS % 1000000) / 10000);
-       }
-
-       return CLK / 1000;
-}
-
-/*
- * Return the current AC97 clock frequency.
- */
-static unsigned long clk_pxa3xx_ac97_getrate(struct clk *clk)
-{
-       unsigned long rate = 312000000;
-       unsigned long ac97_div;
-
-       ac97_div = AC97_DIV;
-
-       /* This may loose precision for some rates but won't for the
-        * standard 24.576MHz.
-        */
-       rate /= (ac97_div >> 12) & 0x7fff;
-       rate *= (ac97_div & 0xfff);
-
-       return rate;
-}
-
-/*
- * Return the current HSIO bus clock frequency
- */
-static unsigned long clk_pxa3xx_hsio_getrate(struct clk *clk)
-{
-       unsigned long acsr;
-       unsigned int hss, hsio_clk;
-
-       acsr = ACSR;
-
-       hss = (acsr >> 14) & 0x3;
-       hsio_clk = (acsr & ACCR_D0CS) ? RO_CLK : hss_mult[hss] * BASE_CLK;
-
-       return hsio_clk;
-}
-
-/* crystal frequency to static memory controller multiplier (SMCFS) */
-static unsigned int smcfs_mult[8] = { 6, 0, 8, 0, 0, 16, };
-static unsigned int df_clkdiv[4] = { 1, 2, 4, 1 };
-
-static unsigned long clk_pxa3xx_smemc_getrate(struct clk *clk)
-{
-       unsigned long acsr = ACSR;
-       unsigned long memclkcfg = __raw_readl(MEMCLKCFG);
-
-       return BASE_CLK * smcfs_mult[(acsr >> 23) & 0x7] /
-                       df_clkdiv[(memclkcfg >> 16) & 0x3];
-}
-
-void clk_pxa3xx_cken_enable(struct clk *clk)
-{
-       unsigned long mask = 1ul << (clk->cken & 0x1f);
-
-       if (clk->cken < 32)
-               CKENA |= mask;
-       else if (clk->cken < 64)
-               CKENB |= mask;
-       else
-               CKENC |= mask;
-}
-
-void clk_pxa3xx_cken_disable(struct clk *clk)
-{
-       unsigned long mask = 1ul << (clk->cken & 0x1f);
-
-       if (clk->cken < 32)
-               CKENA &= ~mask;
-       else if (clk->cken < 64)
-               CKENB &= ~mask;
-       else
-               CKENC &= ~mask;
-}
-
-const struct clkops clk_pxa3xx_cken_ops = {
-       .enable         = clk_pxa3xx_cken_enable,
-       .disable        = clk_pxa3xx_cken_disable,
-};
-
-const struct clkops clk_pxa3xx_hsio_ops = {
-       .enable         = clk_pxa3xx_cken_enable,
-       .disable        = clk_pxa3xx_cken_disable,
-       .getrate        = clk_pxa3xx_hsio_getrate,
-};
-
-const struct clkops clk_pxa3xx_ac97_ops = {
-       .enable         = clk_pxa3xx_cken_enable,
-       .disable        = clk_pxa3xx_cken_disable,
-       .getrate        = clk_pxa3xx_ac97_getrate,
-};
-
-const struct clkops clk_pxa3xx_smemc_ops = {
-       .enable         = clk_pxa3xx_cken_enable,
-       .disable        = clk_pxa3xx_cken_disable,
-       .getrate        = clk_pxa3xx_smemc_getrate,
-};
-
-static void clk_pout_enable(struct clk *clk)
-{
-       OSCC |= OSCC_PEN;
-}
-
-static void clk_pout_disable(struct clk *clk)
-{
-       OSCC &= ~OSCC_PEN;
-}
-
-const struct clkops clk_pxa3xx_pout_ops = {
-       .enable         = clk_pout_enable,
-       .disable        = clk_pout_disable,
-};
-
-#ifdef CONFIG_PM
-static uint32_t cken[2];
-static uint32_t accr;
-
-static int pxa3xx_clock_suspend(void)
-{
-       cken[0] = CKENA;
-       cken[1] = CKENB;
-       accr = ACCR;
-       return 0;
-}
-
-static void pxa3xx_clock_resume(void)
-{
-       ACCR = accr;
-       CKENA = cken[0];
-       CKENB = cken[1];
-}
-#else
-#define pxa3xx_clock_suspend   NULL
-#define pxa3xx_clock_resume    NULL
-#endif
-
-struct syscore_ops pxa3xx_clock_syscore_ops = {
-       .suspend        = pxa3xx_clock_suspend,
-       .resume         = pxa3xx_clock_resume,
-};
diff --git a/arch/arm/mach-pxa/clock.c b/arch/arm/mach-pxa/clock.c
deleted file mode 100644 (file)
index 4d46610..0000000
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- *  linux/arch/arm/mach-sa1100/clock.c
- */
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/clk.h>
-#include <linux/spinlock.h>
-#include <linux/delay.h>
-#include <linux/clkdev.h>
-
-#include "clock.h"
-
-static DEFINE_SPINLOCK(clocks_lock);
-
-int clk_enable(struct clk *clk)
-{
-       unsigned long flags;
-
-       spin_lock_irqsave(&clocks_lock, flags);
-       if (clk->enabled++ == 0)
-               clk->ops->enable(clk);
-       spin_unlock_irqrestore(&clocks_lock, flags);
-
-       if (clk->delay)
-               udelay(clk->delay);
-
-       return 0;
-}
-EXPORT_SYMBOL(clk_enable);
-
-void clk_disable(struct clk *clk)
-{
-       unsigned long flags;
-
-       WARN_ON(clk->enabled == 0);
-
-       spin_lock_irqsave(&clocks_lock, flags);
-       if (--clk->enabled == 0)
-               clk->ops->disable(clk);
-       spin_unlock_irqrestore(&clocks_lock, flags);
-}
-EXPORT_SYMBOL(clk_disable);
-
-unsigned long clk_get_rate(struct clk *clk)
-{
-       unsigned long rate;
-
-       rate = clk->rate;
-       if (clk->ops->getrate)
-               rate = clk->ops->getrate(clk);
-
-       return rate;
-}
-EXPORT_SYMBOL(clk_get_rate);
-
-int clk_set_rate(struct clk *clk, unsigned long rate)
-{
-       unsigned long flags;
-       int ret = -EINVAL;
-
-       if (clk->ops->setrate) {
-               spin_lock_irqsave(&clocks_lock, flags);
-               ret = clk->ops->setrate(clk, rate);
-               spin_unlock_irqrestore(&clocks_lock, flags);
-       }
-
-       return ret;
-}
-EXPORT_SYMBOL(clk_set_rate);
-
-void clk_dummy_enable(struct clk *clk)
-{
-}
-
-void clk_dummy_disable(struct clk *clk)
-{
-}
-
-const struct clkops clk_dummy_ops = {
-       .enable         = clk_dummy_enable,
-       .disable        = clk_dummy_disable,
-};
-
-struct clk clk_dummy = {
-       .ops            = &clk_dummy_ops,
-};
diff --git a/arch/arm/mach-pxa/clock.h b/arch/arm/mach-pxa/clock.h
deleted file mode 100644 (file)
index 1f65d32..0000000
+++ /dev/null
@@ -1,80 +0,0 @@
-#include <linux/clkdev.h>
-#include <linux/syscore_ops.h>
-
-struct clkops {
-       void                    (*enable)(struct clk *);
-       void                    (*disable)(struct clk *);
-       unsigned long           (*getrate)(struct clk *);
-       int                     (*setrate)(struct clk *, unsigned long);
-};
-
-struct clk {
-       const struct clkops     *ops;
-       unsigned long           rate;
-       unsigned int            cken;
-       unsigned int            delay;
-       unsigned int            enabled;
-};
-
-void clk_dummy_enable(struct clk *);
-void clk_dummy_disable(struct clk *);
-
-extern const struct clkops clk_dummy_ops;
-extern struct clk clk_dummy;
-
-#define INIT_CLKREG(_clk,_devname,_conname)            \
-       {                                               \
-               .clk            = _clk,                 \
-               .dev_id         = _devname,             \
-               .con_id         = _conname,             \
-       }
-
-#define DEFINE_CK(_name, _cken, _ops)                  \
-struct clk clk_##_name = {                             \
-               .ops    = _ops,                         \
-               .cken   = CKEN_##_cken,                 \
-       }
-
-#define DEFINE_CLK(_name, _ops, _rate, _delay)         \
-struct clk clk_##_name = {                             \
-               .ops    = _ops,                         \
-               .rate   = _rate,                        \
-               .delay  = _delay,                       \
-       }
-
-#define DEFINE_PXA2_CKEN(_name, _cken, _rate, _delay)  \
-struct clk clk_##_name = {                             \
-               .ops    = &clk_pxa2xx_cken_ops,         \
-               .rate   = _rate,                        \
-               .cken   = CKEN_##_cken,                 \
-               .delay  = _delay,                       \
-       }
-
-extern const struct clkops clk_pxa2xx_cken_ops;
-
-void clk_pxa2xx_cken_enable(struct clk *clk);
-void clk_pxa2xx_cken_disable(struct clk *clk);
-
-extern struct syscore_ops pxa2xx_clock_syscore_ops;
-
-#if defined(CONFIG_PXA3xx)
-#define DEFINE_PXA3_CKEN(_name, _cken, _rate, _delay)  \
-struct clk clk_##_name = {                             \
-               .ops    = &clk_pxa3xx_cken_ops,         \
-               .rate   = _rate,                        \
-               .cken   = CKEN_##_cken,                 \
-               .delay  = _delay,                       \
-       }
-
-extern const struct clkops clk_pxa3xx_cken_ops;
-extern const struct clkops clk_pxa3xx_hsio_ops;
-extern const struct clkops clk_pxa3xx_ac97_ops;
-extern const struct clkops clk_pxa3xx_pout_ops;
-extern const struct clkops clk_pxa3xx_smemc_ops;
-
-extern void clk_pxa3xx_cken_enable(struct clk *);
-extern void clk_pxa3xx_cken_disable(struct clk *);
-
-extern struct syscore_ops pxa3xx_clock_syscore_ops;
-
-#endif
index cfb8641..11863be 100644 (file)
@@ -12,6 +12,7 @@
 
 #include <linux/kernel.h>
 #include <linux/init.h>
+#include <linux/clk-provider.h>
 #include <linux/gpio.h>
 #include <linux/delay.h>
 #include <linux/platform_device.h>
@@ -39,7 +40,6 @@
 
 #include "devices.h"
 #include "generic.h"
-#include "clock.h"
 
 /* Only e800 has 128MB RAM */
 void __init eseries_fixup(struct tag *tags, char **cmdline)
@@ -125,27 +125,9 @@ struct resource eseries_tmio_resources[] = {
 };
 
 /* Some e-series hardware cannot control the 32K clock */
-static void clk_32k_dummy(struct clk *clk)
-{
-}
-
-static const struct clkops clk_32k_dummy_ops = {
-       .enable         = clk_32k_dummy,
-       .disable        = clk_32k_dummy,
-};
-
-static struct clk tmio_dummy_clk = {
-       .ops    = &clk_32k_dummy_ops,
-       .rate   = 32768,
-};
-
-static struct clk_lookup eseries_clkregs[] = {
-       INIT_CLKREG(&tmio_dummy_clk, NULL, "CLK_CK32K"),
-};
-
 static void __init eseries_register_clks(void)
 {
-       clkdev_add_table(eseries_clkregs, ARRAY_SIZE(eseries_clkregs));
+       clk_register_fixed_rate(NULL, "CLK_CK32K", NULL, CLK_IS_ROOT, 32768);
 }
 
 #ifdef CONFIG_MACH_E330
@@ -683,7 +665,7 @@ static unsigned long e750_pin_config[] __initdata = {
        /* PC Card */
        GPIO8_GPIO,   /* CD0 */
        GPIO44_GPIO,  /* CD1 */
-       GPIO11_GPIO,  /* IRQ0 */
+       /* GPIO11_GPIO,  IRQ0 */
        GPIO6_GPIO,   /* IRQ1 */
        GPIO27_GPIO,  /* RST0 */
        GPIO24_GPIO,  /* RST1 */
@@ -778,6 +760,9 @@ static unsigned long e800_pin_config[] __initdata = {
        GPIO29_AC97_SDATA_IN_0,
        GPIO30_AC97_SDATA_OUT,
        GPIO31_AC97_SYNC,
+
+       /* tc6393xb */
+       GPIO11_3_6MHz,
 };
 
 static struct w100_gen_regs e800_lcd_regs = {
index 04b013f..ec510ec 100644 (file)
@@ -63,6 +63,12 @@ EXPORT_SYMBOL(get_clock_tick_rate);
  */
 void __init pxa_timer_init(void)
 {
+       if (cpu_is_pxa25x())
+               pxa25x_clocks_init();
+       if (cpu_is_pxa27x())
+               pxa27x_clocks_init();
+       if (cpu_is_pxa3xx())
+               pxa3xx_clocks_init();
        pxa_timer_nodt_init(IRQ_OST0, io_p2v(0x40a00000),
                            get_clock_tick_rate());
 }
index 7a9fa1a..0b1dbb5 100644 (file)
@@ -26,17 +26,20 @@ extern void pxa_timer_init(void);
 #define ARRAY_AND_SIZE(x)      (x), ARRAY_SIZE(x)
 
 #define pxa25x_handle_irq icip_handle_irq
+extern int __init pxa25x_clocks_init(void);
 extern void __init pxa25x_init_irq(void);
 extern void __init pxa25x_map_io(void);
 extern void __init pxa26x_init_irq(void);
 
 #define pxa27x_handle_irq ichp_handle_irq
+extern int __init pxa27x_clocks_init(void);
 extern void __init pxa27x_dt_init_irq(void);
 extern unsigned        pxa27x_get_clk_frequency_khz(int);
 extern void __init pxa27x_init_irq(void);
 extern void __init pxa27x_map_io(void);
 
 #define pxa3xx_handle_irq ichp_handle_irq
+extern int __init pxa3xx_clocks_init(void);
 extern void __init pxa3xx_dt_init_irq(void);
 extern void __init pxa3xx_init_irq(void);
 extern void __init pxa3xx_map_io(void);
index 89a7c06..98608c5 100644 (file)
@@ -138,7 +138,7 @@ static int pxa_irq_map(struct irq_domain *h, unsigned int virq,
        return 0;
 }
 
-static struct irq_domain_ops pxa_irq_ops = {
+static const struct irq_domain_ops pxa_irq_ops = {
        .map    = pxa_irq_map,
        .xlate  = irq_domain_xlate_onecell,
 };
index 4ac9ab8..2d4bf1f 100644 (file)
@@ -57,7 +57,6 @@
 #include <mach/smemc.h>
 
 #include "generic.h"
-#include "clock.h"
 #include "devices.h"
 
 static unsigned long lubbock_pin_config[] __initdata = {
@@ -102,6 +101,9 @@ static unsigned long lubbock_pin_config[] __initdata = {
        GPIO6_MMC_CLK,
        GPIO8_MMC_CS0,
 
+       /* SA1111 chip */
+       GPIO11_3_6MHz,
+
        /* wakeup */
        GPIO1_GPIO | WAKEUP_ON_EDGE_RISE,
 };
index 66e4a2b..23a90c6 100644 (file)
 
 #include "generic.h"
 #include "devices.h"
-#include "clock.h"
 
 /*
  * Various clock factors driven by the CCCR register.
  */
 
-/* Crystal Frequency to Memory Frequency Multiplier (L) */
-static unsigned char L_clk_mult[32] = { 0, 27, 32, 36, 40, 45, 0, };
-
-/* Memory Frequency to Run Mode Frequency Multiplier (M) */
-static unsigned char M_clk_mult[4] = { 0, 1, 2, 4 };
-
-/* Run Mode Frequency to Turbo Mode Frequency Multiplier (N) */
-/* Note: we store the value N * 2 here. */
-static unsigned char N2_clk_mult[8] = { 0, 0, 2, 3, 4, 0, 6, 0 };
-
-/* Crystal clock */
-#define BASE_CLK       3686400
-
-/*
- * Get the clock frequency as reflected by CCCR and the turbo flag.
- * We assume these values have been applied via a fcs.
- * If info is not 0 we also display the current settings.
- */
-unsigned int pxa25x_get_clk_frequency_khz(int info)
-{
-       unsigned long cccr, turbo;
-       unsigned int l, L, m, M, n2, N;
-
-       cccr = CCCR;
-       asm( "mrc\tp14, 0, %0, c6, c0, 0" : "=r" (turbo) );
-
-       l  =  L_clk_mult[(cccr >> 0) & 0x1f];
-       m  =  M_clk_mult[(cccr >> 5) & 0x03];
-       n2 = N2_clk_mult[(cccr >> 7) & 0x07];
-
-       L = l * BASE_CLK;
-       M = m * L;
-       N = n2 * M / 2;
-
-       if(info)
-       {
-               L += 5000;
-               printk( KERN_INFO "Memory clock: %d.%02dMHz (*%d)\n",
-                       L / 1000000, (L % 1000000) / 10000, l );
-               M += 5000;
-               printk( KERN_INFO "Run Mode clock: %d.%02dMHz (*%d)\n",
-                       M / 1000000, (M % 1000000) / 10000, m );
-               N += 5000;
-               printk( KERN_INFO "Turbo Mode clock: %d.%02dMHz (*%d.%d, %sactive)\n",
-                       N / 1000000, (N % 1000000) / 10000, n2 / 2, (n2 % 2) * 5,
-                       (turbo & 1) ? "" : "in" );
-       }
-
-       return (turbo & 1) ? (N/1000) : (M/1000);
-}
-
-static unsigned long clk_pxa25x_mem_getrate(struct clk *clk)
-{
-       return L_clk_mult[(CCCR >> 0) & 0x1f] * BASE_CLK;
-}
-
-static const struct clkops clk_pxa25x_mem_ops = {
-       .enable         = clk_dummy_enable,
-       .disable        = clk_dummy_disable,
-       .getrate        = clk_pxa25x_mem_getrate,
-};
-
-static const struct clkops clk_pxa25x_lcd_ops = {
-       .enable         = clk_pxa2xx_cken_enable,
-       .disable        = clk_pxa2xx_cken_disable,
-       .getrate        = clk_pxa25x_mem_getrate,
-};
-
-static unsigned long gpio12_config_32k[] = {
-       GPIO12_32KHz,
-};
-
-static unsigned long gpio12_config_gpio[] = {
-       GPIO12_GPIO,
-};
-
-static void clk_gpio12_enable(struct clk *clk)
-{
-       pxa2xx_mfp_config(gpio12_config_32k, 1);
-}
-
-static void clk_gpio12_disable(struct clk *clk)
-{
-       pxa2xx_mfp_config(gpio12_config_gpio, 1);
-}
-
-static const struct clkops clk_pxa25x_gpio12_ops = {
-       .enable         = clk_gpio12_enable,
-       .disable        = clk_gpio12_disable,
-};
-
-static unsigned long gpio11_config_3m6[] = {
-       GPIO11_3_6MHz,
-};
-
-static unsigned long gpio11_config_gpio[] = {
-       GPIO11_GPIO,
-};
-
-static void clk_gpio11_enable(struct clk *clk)
-{
-       pxa2xx_mfp_config(gpio11_config_3m6, 1);
-}
-
-static void clk_gpio11_disable(struct clk *clk)
-{
-       pxa2xx_mfp_config(gpio11_config_gpio, 1);
-}
-
-static const struct clkops clk_pxa25x_gpio11_ops = {
-       .enable         = clk_gpio11_enable,
-       .disable        = clk_gpio11_disable,
-};
-
-/*
- * 3.6864MHz -> OST, GPIO, SSP, PWM, PLLs (95.842MHz, 147.456MHz)
- * 95.842MHz -> MMC 19.169MHz, I2C 31.949MHz, FICP 47.923MHz, USB 47.923MHz
- * 147.456MHz -> UART 14.7456MHz, AC97 12.288MHz, I2S 5.672MHz (allegedly)
- */
-
-/*
- * PXA 2xx clock declarations.
- */
-static DEFINE_PXA2_CKEN(pxa25x_hwuart, HWUART, 14745600, 1);
-static DEFINE_PXA2_CKEN(pxa25x_ffuart, FFUART, 14745600, 1);
-static DEFINE_PXA2_CKEN(pxa25x_btuart, BTUART, 14745600, 1);
-static DEFINE_PXA2_CKEN(pxa25x_stuart, STUART, 14745600, 1);
-static DEFINE_PXA2_CKEN(pxa25x_usb, USB, 47923000, 5);
-static DEFINE_PXA2_CKEN(pxa25x_mmc, MMC, 19169000, 0);
-static DEFINE_PXA2_CKEN(pxa25x_i2c, I2C, 31949000, 0);
-static DEFINE_PXA2_CKEN(pxa25x_ssp, SSP, 3686400, 0);
-static DEFINE_PXA2_CKEN(pxa25x_nssp, NSSP, 3686400, 0);
-static DEFINE_PXA2_CKEN(pxa25x_assp, ASSP, 3686400, 0);
-static DEFINE_PXA2_CKEN(pxa25x_pwm0, PWM0, 3686400, 0);
-static DEFINE_PXA2_CKEN(pxa25x_pwm1, PWM1, 3686400, 0);
-static DEFINE_PXA2_CKEN(pxa25x_ac97, AC97, 24576000, 0);
-static DEFINE_PXA2_CKEN(pxa25x_i2s, I2S, 14745600, 0);
-static DEFINE_PXA2_CKEN(pxa25x_ficp, FICP, 47923000, 0);
-
-static DEFINE_CK(pxa25x_lcd, LCD, &clk_pxa25x_lcd_ops);
-static DEFINE_CLK(pxa25x_gpio11, &clk_pxa25x_gpio11_ops, 3686400, 0);
-static DEFINE_CLK(pxa25x_gpio12, &clk_pxa25x_gpio12_ops, 32768, 0);
-static DEFINE_CLK(pxa25x_mem, &clk_pxa25x_mem_ops, 0, 0);
-
-static struct clk_lookup pxa25x_clkregs[] = {
-       INIT_CLKREG(&clk_pxa25x_lcd, "pxa2xx-fb", NULL),
-       INIT_CLKREG(&clk_pxa25x_ffuart, "pxa2xx-uart.0", NULL),
-       INIT_CLKREG(&clk_pxa25x_btuart, "pxa2xx-uart.1", NULL),
-       INIT_CLKREG(&clk_pxa25x_stuart, "pxa2xx-uart.2", NULL),
-       INIT_CLKREG(&clk_pxa25x_usb, "pxa25x-udc", NULL),
-       INIT_CLKREG(&clk_pxa25x_mmc, "pxa2xx-mci.0", NULL),
-       INIT_CLKREG(&clk_pxa25x_i2c, "pxa2xx-i2c.0", NULL),
-       INIT_CLKREG(&clk_pxa25x_ssp, "pxa25x-ssp.0", NULL),
-       INIT_CLKREG(&clk_pxa25x_nssp, "pxa25x-nssp.1", NULL),
-       INIT_CLKREG(&clk_pxa25x_assp, "pxa25x-nssp.2", NULL),
-       INIT_CLKREG(&clk_pxa25x_pwm0, "pxa25x-pwm.0", NULL),
-       INIT_CLKREG(&clk_pxa25x_pwm1, "pxa25x-pwm.1", NULL),
-       INIT_CLKREG(&clk_pxa25x_i2s, "pxa2xx-i2s", NULL),
-       INIT_CLKREG(&clk_pxa25x_stuart, "pxa2xx-ir", "UARTCLK"),
-       INIT_CLKREG(&clk_pxa25x_ficp, "pxa2xx-ir", "FICPCLK"),
-       INIT_CLKREG(&clk_pxa25x_ac97, NULL, "AC97CLK"),
-       INIT_CLKREG(&clk_pxa25x_gpio11, NULL, "GPIO11_CLK"),
-       INIT_CLKREG(&clk_pxa25x_gpio12, NULL, "GPIO12_CLK"),
-       INIT_CLKREG(&clk_pxa25x_mem, "pxa2xx-pcmcia", NULL),
-#ifdef CONFIG_CPU_PXA26x
-       INIT_CLKREG(&clk_dummy, "pxa26x-gpio", NULL),
-#else
-       INIT_CLKREG(&clk_dummy, "pxa25x-gpio", NULL),
-#endif
-       INIT_CLKREG(&clk_dummy, "sa1100-rtc", NULL),
-};
-
-static struct clk_lookup pxa25x_hwuart_clkreg =
-       INIT_CLKREG(&clk_pxa25x_hwuart, "pxa2xx-uart.3", NULL);
-
 #ifdef CONFIG_PM
 
 #define SAVE(x)                sleep_save[SLEEP_SAVE_##x] = x
@@ -374,8 +198,6 @@ static int __init pxa25x_init(void)
 
                reset_status = RCSR;
 
-               clkdev_add_table(pxa25x_clkregs, ARRAY_SIZE(pxa25x_clkregs));
-
                if ((ret = pxa_init_dma(IRQ_DMA, 16)))
                        return ret;
 
@@ -383,7 +205,6 @@ static int __init pxa25x_init(void)
 
                register_syscore_ops(&pxa_irq_syscore_ops);
                register_syscore_ops(&pxa2xx_mfp_syscore_ops);
-               register_syscore_ops(&pxa2xx_clock_syscore_ops);
 
                pxa_register_device(&pxa25x_device_gpio, &pxa25x_gpio_info);
                ret = platform_add_devices(pxa25x_devices,
@@ -392,10 +213,6 @@ static int __init pxa25x_init(void)
                        return ret;
        }
 
-       /* Only add HWUART for PXA255/26x; PXA210/250 do not have it. */
-       if (cpu_is_pxa255())
-               clkdev_add(&pxa25x_hwuart_clkreg);
-
        return ret;
 }
 
index af423a4..b5abdeb 100644 (file)
@@ -37,7 +37,8 @@
 
 #include "generic.h"
 #include "devices.h"
-#include "clock.h"
+#include <linux/clk-provider.h>
+#include <linux/clkdev.h>
 
 void pxa27x_clear_otgph(void)
 {
@@ -73,174 +74,6 @@ void pxa27x_configure_ac97reset(int reset_gpio, bool to_gpio)
 }
 EXPORT_SYMBOL_GPL(pxa27x_configure_ac97reset);
 
-/* Crystal clock: 13MHz */
-#define BASE_CLK       13000000
-
-/*
- * Get the clock frequency as reflected by CCSR and the turbo flag.
- * We assume these values have been applied via a fcs.
- * If info is not 0 we also display the current settings.
- */
-unsigned int pxa27x_get_clk_frequency_khz(int info)
-{
-       unsigned long ccsr, clkcfg;
-       unsigned int l, L, m, M, n2, N, S;
-               int cccr_a, t, ht, b;
-
-       ccsr = CCSR;
-       cccr_a = CCCR & (1 << 25);
-
-       /* Read clkcfg register: it has turbo, b, half-turbo (and f) */
-       asm( "mrc\tp14, 0, %0, c6, c0, 0" : "=r" (clkcfg) );
-       t  = clkcfg & (1 << 0);
-       ht = clkcfg & (1 << 2);
-       b  = clkcfg & (1 << 3);
-
-       l  = ccsr & 0x1f;
-       n2 = (ccsr>>7) & 0xf;
-       m  = (l <= 10) ? 1 : (l <= 20) ? 2 : 4;
-
-       L  = l * BASE_CLK;
-       N  = (L * n2) / 2;
-       M  = (!cccr_a) ? (L/m) : ((b) ? L : (L/2));
-       S  = (b) ? L : (L/2);
-
-       if (info) {
-               printk( KERN_INFO "Run Mode clock: %d.%02dMHz (*%d)\n",
-                       L / 1000000, (L % 1000000) / 10000, l );
-               printk( KERN_INFO "Turbo Mode clock: %d.%02dMHz (*%d.%d, %sactive)\n",
-                       N / 1000000, (N % 1000000)/10000, n2 / 2, (n2 % 2)*5,
-                       (t) ? "" : "in" );
-               printk( KERN_INFO "Memory clock: %d.%02dMHz (/%d)\n",
-                       M / 1000000, (M % 1000000) / 10000, m );
-               printk( KERN_INFO "System bus clock: %d.%02dMHz \n",
-                       S / 1000000, (S % 1000000) / 10000 );
-       }
-
-       return (t) ? (N/1000) : (L/1000);
-}
-
-/*
- * Return the current mem clock frequency as reflected by CCCR[A], B, and L
- */
-static unsigned long clk_pxa27x_mem_getrate(struct clk *clk)
-{
-       unsigned long ccsr, clkcfg;
-       unsigned int l, L, m, M;
-               int cccr_a, b;
-
-       ccsr = CCSR;
-       cccr_a = CCCR & (1 << 25);
-
-       /* Read clkcfg register: it has turbo, b, half-turbo (and f) */
-       asm( "mrc\tp14, 0, %0, c6, c0, 0" : "=r" (clkcfg) );
-       b = clkcfg & (1 << 3);
-
-       l = ccsr & 0x1f;
-       m = (l <= 10) ? 1 : (l <= 20) ? 2 : 4;
-
-       L = l * BASE_CLK;
-       M = (!cccr_a) ? (L/m) : ((b) ? L : (L/2));
-
-       return M;
-}
-
-static const struct clkops clk_pxa27x_mem_ops = {
-       .enable         = clk_dummy_enable,
-       .disable        = clk_dummy_disable,
-       .getrate        = clk_pxa27x_mem_getrate,
-};
-
-/*
- * Return the current LCD clock frequency in units of 10kHz as
- */
-static unsigned int pxa27x_get_lcdclk_frequency_10khz(void)
-{
-       unsigned long ccsr;
-       unsigned int l, L, k, K;
-
-       ccsr = CCSR;
-
-       l = ccsr & 0x1f;
-       k = (l <= 7) ? 1 : (l <= 16) ? 2 : 4;
-
-       L = l * BASE_CLK;
-       K = L / k;
-
-       return (K / 10000);
-}
-
-static unsigned long clk_pxa27x_lcd_getrate(struct clk *clk)
-{
-       return pxa27x_get_lcdclk_frequency_10khz() * 10000;
-}
-
-static const struct clkops clk_pxa27x_lcd_ops = {
-       .enable         = clk_pxa2xx_cken_enable,
-       .disable        = clk_pxa2xx_cken_disable,
-       .getrate        = clk_pxa27x_lcd_getrate,
-};
-
-static DEFINE_PXA2_CKEN(pxa27x_ffuart, FFUART, 14857000, 1);
-static DEFINE_PXA2_CKEN(pxa27x_btuart, BTUART, 14857000, 1);
-static DEFINE_PXA2_CKEN(pxa27x_stuart, STUART, 14857000, 1);
-static DEFINE_PXA2_CKEN(pxa27x_i2s, I2S, 14682000, 0);
-static DEFINE_PXA2_CKEN(pxa27x_i2c, I2C, 32842000, 0);
-static DEFINE_PXA2_CKEN(pxa27x_usb, USB, 48000000, 5);
-static DEFINE_PXA2_CKEN(pxa27x_mmc, MMC, 19500000, 0);
-static DEFINE_PXA2_CKEN(pxa27x_ficp, FICP, 48000000, 0);
-static DEFINE_PXA2_CKEN(pxa27x_usbhost, USBHOST, 48000000, 0);
-static DEFINE_PXA2_CKEN(pxa27x_pwri2c, PWRI2C, 13000000, 0);
-static DEFINE_PXA2_CKEN(pxa27x_keypad, KEYPAD, 32768, 0);
-static DEFINE_PXA2_CKEN(pxa27x_ssp1, SSP1, 13000000, 0);
-static DEFINE_PXA2_CKEN(pxa27x_ssp2, SSP2, 13000000, 0);
-static DEFINE_PXA2_CKEN(pxa27x_ssp3, SSP3, 13000000, 0);
-static DEFINE_PXA2_CKEN(pxa27x_pwm0, PWM0, 13000000, 0);
-static DEFINE_PXA2_CKEN(pxa27x_pwm1, PWM1, 13000000, 0);
-static DEFINE_PXA2_CKEN(pxa27x_ac97, AC97, 24576000, 0);
-static DEFINE_PXA2_CKEN(pxa27x_ac97conf, AC97CONF, 24576000, 0);
-static DEFINE_PXA2_CKEN(pxa27x_msl, MSL, 48000000, 0);
-static DEFINE_PXA2_CKEN(pxa27x_usim, USIM, 48000000, 0);
-static DEFINE_PXA2_CKEN(pxa27x_memstk, MEMSTK, 19500000, 0);
-static DEFINE_PXA2_CKEN(pxa27x_im, IM, 0, 0);
-static DEFINE_PXA2_CKEN(pxa27x_memc, MEMC, 0, 0);
-
-static DEFINE_CK(pxa27x_lcd, LCD, &clk_pxa27x_lcd_ops);
-static DEFINE_CK(pxa27x_camera, CAMERA, &clk_pxa27x_lcd_ops);
-static DEFINE_CLK(pxa27x_mem, &clk_pxa27x_mem_ops, 0, 0);
-
-static struct clk_lookup pxa27x_clkregs[] = {
-       INIT_CLKREG(&clk_pxa27x_lcd, "pxa2xx-fb", NULL),
-       INIT_CLKREG(&clk_pxa27x_camera, "pxa27x-camera.0", NULL),
-       INIT_CLKREG(&clk_pxa27x_ffuart, "pxa2xx-uart.0", NULL),
-       INIT_CLKREG(&clk_pxa27x_btuart, "pxa2xx-uart.1", NULL),
-       INIT_CLKREG(&clk_pxa27x_stuart, "pxa2xx-uart.2", NULL),
-       INIT_CLKREG(&clk_pxa27x_i2s, "pxa2xx-i2s", NULL),
-       INIT_CLKREG(&clk_pxa27x_i2c, "pxa2xx-i2c.0", NULL),
-       INIT_CLKREG(&clk_pxa27x_usb, "pxa27x-udc", NULL),
-       INIT_CLKREG(&clk_pxa27x_mmc, "pxa2xx-mci.0", NULL),
-       INIT_CLKREG(&clk_pxa27x_stuart, "pxa2xx-ir", "UARTCLK"),
-       INIT_CLKREG(&clk_pxa27x_ficp, "pxa2xx-ir", "FICPCLK"),
-       INIT_CLKREG(&clk_pxa27x_usbhost, "pxa27x-ohci", NULL),
-       INIT_CLKREG(&clk_pxa27x_pwri2c, "pxa2xx-i2c.1", NULL),
-       INIT_CLKREG(&clk_pxa27x_keypad, "pxa27x-keypad", NULL),
-       INIT_CLKREG(&clk_pxa27x_ssp1, "pxa27x-ssp.0", NULL),
-       INIT_CLKREG(&clk_pxa27x_ssp2, "pxa27x-ssp.1", NULL),
-       INIT_CLKREG(&clk_pxa27x_ssp3, "pxa27x-ssp.2", NULL),
-       INIT_CLKREG(&clk_pxa27x_pwm0, "pxa27x-pwm.0", NULL),
-       INIT_CLKREG(&clk_pxa27x_pwm1, "pxa27x-pwm.1", NULL),
-       INIT_CLKREG(&clk_pxa27x_ac97, NULL, "AC97CLK"),
-       INIT_CLKREG(&clk_pxa27x_ac97conf, NULL, "AC97CONFCLK"),
-       INIT_CLKREG(&clk_pxa27x_msl, NULL, "MSLCLK"),
-       INIT_CLKREG(&clk_pxa27x_usim, NULL, "USIMCLK"),
-       INIT_CLKREG(&clk_pxa27x_memstk, NULL, "MSTKCLK"),
-       INIT_CLKREG(&clk_pxa27x_im, NULL, "IMCLK"),
-       INIT_CLKREG(&clk_pxa27x_memc, NULL, "MEMCLK"),
-       INIT_CLKREG(&clk_pxa27x_mem, "pxa2xx-pcmcia", NULL),
-       INIT_CLKREG(&clk_dummy, "pxa27x-gpio", NULL),
-       INIT_CLKREG(&clk_dummy, "sa1100-rtc", NULL),
-};
-
 #ifdef CONFIG_PM
 
 #define SAVE(x)                sleep_save[SLEEP_SAVE_##x] = x
@@ -466,8 +299,6 @@ static int __init pxa27x_init(void)
 
                reset_status = RCSR;
 
-               clkdev_add_table(pxa27x_clkregs, ARRAY_SIZE(pxa27x_clkregs));
-
                if ((ret = pxa_init_dma(IRQ_DMA, 32)))
                        return ret;
 
@@ -475,10 +306,13 @@ static int __init pxa27x_init(void)
 
                register_syscore_ops(&pxa_irq_syscore_ops);
                register_syscore_ops(&pxa2xx_mfp_syscore_ops);
-               register_syscore_ops(&pxa2xx_clock_syscore_ops);
 
-               pxa_register_device(&pxa27x_device_gpio, &pxa27x_gpio_info);
-               ret = platform_add_devices(devices, ARRAY_SIZE(devices));
+               if (!of_have_populated_dt()) {
+                       pxa_register_device(&pxa27x_device_gpio,
+                                           &pxa27x_gpio_info);
+                       ret = platform_add_devices(devices,
+                                                  ARRAY_SIZE(devices));
+               }
        }
 
        return ret;
index 17cbc0c..28c5b56 100644 (file)
@@ -22,7 +22,6 @@
 
 #include "generic.h"
 #include "devices.h"
-#include "clock.h"
 
 static struct mfp_addr_map pxa300_mfp_addr_map[] __initdata = {
 
@@ -84,32 +83,15 @@ static struct mfp_addr_map pxa310_mfp_addr_map[] __initdata = {
        MFP_ADDR_END,
 };
 
-static DEFINE_PXA3_CKEN(common_nand, NAND, 156000000, 0);
-static DEFINE_PXA3_CKEN(gcu, PXA300_GCU, 0, 0);
-
-static struct clk_lookup common_clkregs[] = {
-       INIT_CLKREG(&clk_common_nand, "pxa3xx-nand", NULL),
-       INIT_CLKREG(&clk_gcu, "pxa3xx-gcu", NULL),
-};
-
-static DEFINE_PXA3_CKEN(pxa310_mmc3, MMC3, 19500000, 0);
-
-static struct clk_lookup pxa310_clkregs[] = {
-       INIT_CLKREG(&clk_pxa310_mmc3, "pxa2xx-mci.2", NULL),
-};
-
 static int __init pxa300_init(void)
 {
        if (cpu_is_pxa300() || cpu_is_pxa310()) {
                mfp_init_base(io_p2v(MFPR_BASE));
                mfp_init_addr(pxa300_mfp_addr_map);
-               clkdev_add_table(ARRAY_AND_SIZE(common_clkregs));
        }
 
-       if (cpu_is_pxa310()) {
+       if (cpu_is_pxa310())
                mfp_init_addr(pxa310_mfp_addr_map);
-               clkdev_add_table(ARRAY_AND_SIZE(pxa310_clkregs));
-       }
 
        return 0;
 }
index 6dc99d4..2f55bb4 100644 (file)
@@ -22,7 +22,6 @@
 
 #include "generic.h"
 #include "devices.h"
-#include "clock.h"
 
 static struct mfp_addr_map pxa320_mfp_addr_map[] __initdata = {
 
@@ -78,20 +77,11 @@ static struct mfp_addr_map pxa320_mfp_addr_map[] __initdata = {
        MFP_ADDR_END,
 };
 
-static DEFINE_PXA3_CKEN(pxa320_nand, NAND, 104000000, 0);
-static DEFINE_PXA3_CKEN(gcu, PXA320_GCU, 0, 0);
-
-static struct clk_lookup pxa320_clkregs[] = {
-       INIT_CLKREG(&clk_pxa320_nand, "pxa3xx-nand", NULL),
-       INIT_CLKREG(&clk_gcu, "pxa3xx-gcu", NULL),
-};
-
 static int __init pxa320_init(void)
 {
        if (cpu_is_pxa320()) {
                mfp_init_base(io_p2v(MFPR_BASE));
                mfp_init_addr(pxa320_mfp_addr_map);
-               clkdev_add_table(ARRAY_AND_SIZE(pxa320_clkregs));
        }
 
        return 0;
index edcbd9c..bd4cbef 100644 (file)
 
 #include "generic.h"
 #include "devices.h"
-#include "clock.h"
 
 #define PECR_IE(n)     ((1 << ((n) * 2)) << 28)
 #define PECR_IS(n)     ((1 << ((n) * 2)) << 29)
 
 extern void __init pxa_dt_irq_init(int (*fn)(struct irq_data *, unsigned int));
-
-static DEFINE_PXA3_CKEN(pxa3xx_ffuart, FFUART, 14857000, 1);
-static DEFINE_PXA3_CKEN(pxa3xx_btuart, BTUART, 14857000, 1);
-static DEFINE_PXA3_CKEN(pxa3xx_stuart, STUART, 14857000, 1);
-static DEFINE_PXA3_CKEN(pxa3xx_i2c, I2C, 32842000, 0);
-static DEFINE_PXA3_CKEN(pxa3xx_udc, UDC, 48000000, 5);
-static DEFINE_PXA3_CKEN(pxa3xx_usbh, USBH, 48000000, 0);
-static DEFINE_PXA3_CKEN(pxa3xx_u2d, USB2, 48000000, 0);
-static DEFINE_PXA3_CKEN(pxa3xx_keypad, KEYPAD, 32768, 0);
-static DEFINE_PXA3_CKEN(pxa3xx_ssp1, SSP1, 13000000, 0);
-static DEFINE_PXA3_CKEN(pxa3xx_ssp2, SSP2, 13000000, 0);
-static DEFINE_PXA3_CKEN(pxa3xx_ssp3, SSP3, 13000000, 0);
-static DEFINE_PXA3_CKEN(pxa3xx_ssp4, SSP4, 13000000, 0);
-static DEFINE_PXA3_CKEN(pxa3xx_pwm0, PWM0, 13000000, 0);
-static DEFINE_PXA3_CKEN(pxa3xx_pwm1, PWM1, 13000000, 0);
-static DEFINE_PXA3_CKEN(pxa3xx_mmc1, MMC1, 19500000, 0);
-static DEFINE_PXA3_CKEN(pxa3xx_mmc2, MMC2, 19500000, 0);
-static DEFINE_PXA3_CKEN(pxa3xx_gpio, GPIO, 13000000, 0);
-
-static DEFINE_CK(pxa3xx_lcd, LCD, &clk_pxa3xx_hsio_ops);
-static DEFINE_CK(pxa3xx_smemc, SMC, &clk_pxa3xx_smemc_ops);
-static DEFINE_CK(pxa3xx_camera, CAMERA, &clk_pxa3xx_hsio_ops);
-static DEFINE_CK(pxa3xx_ac97, AC97, &clk_pxa3xx_ac97_ops);
-static DEFINE_CLK(pxa3xx_pout, &clk_pxa3xx_pout_ops, 13000000, 70);
-
-static struct clk_lookup pxa3xx_clkregs[] = {
-       INIT_CLKREG(&clk_pxa3xx_pout, NULL, "CLK_POUT"),
-       /* Power I2C clock is always on */
-       INIT_CLKREG(&clk_dummy, "pxa3xx-pwri2c.1", NULL),
-       INIT_CLKREG(&clk_pxa3xx_lcd, "pxa2xx-fb", NULL),
-       INIT_CLKREG(&clk_pxa3xx_camera, NULL, "CAMCLK"),
-       INIT_CLKREG(&clk_pxa3xx_ac97, NULL, "AC97CLK"),
-       INIT_CLKREG(&clk_pxa3xx_ffuart, "pxa2xx-uart.0", NULL),
-       INIT_CLKREG(&clk_pxa3xx_btuart, "pxa2xx-uart.1", NULL),
-       INIT_CLKREG(&clk_pxa3xx_stuart, "pxa2xx-uart.2", NULL),
-       INIT_CLKREG(&clk_pxa3xx_stuart, "pxa2xx-ir", "UARTCLK"),
-       INIT_CLKREG(&clk_pxa3xx_i2c, "pxa2xx-i2c.0", NULL),
-       INIT_CLKREG(&clk_pxa3xx_udc, "pxa27x-udc", NULL),
-       INIT_CLKREG(&clk_pxa3xx_usbh, "pxa27x-ohci", NULL),
-       INIT_CLKREG(&clk_pxa3xx_u2d, "pxa3xx-u2d", NULL),
-       INIT_CLKREG(&clk_pxa3xx_keypad, "pxa27x-keypad", NULL),
-       INIT_CLKREG(&clk_pxa3xx_ssp1, "pxa3xx-ssp.0", NULL),
-       INIT_CLKREG(&clk_pxa3xx_ssp2, "pxa3xx-ssp.1", NULL),
-       INIT_CLKREG(&clk_pxa3xx_ssp3, "pxa3xx-ssp.2", NULL),
-       INIT_CLKREG(&clk_pxa3xx_ssp4, "pxa3xx-ssp.3", NULL),
-       INIT_CLKREG(&clk_pxa3xx_pwm0, "pxa27x-pwm.0", NULL),
-       INIT_CLKREG(&clk_pxa3xx_pwm1, "pxa27x-pwm.1", NULL),
-       INIT_CLKREG(&clk_pxa3xx_mmc1, "pxa2xx-mci.0", NULL),
-       INIT_CLKREG(&clk_pxa3xx_mmc2, "pxa2xx-mci.1", NULL),
-       INIT_CLKREG(&clk_pxa3xx_smemc, "pxa2xx-pcmcia", NULL),
-       INIT_CLKREG(&clk_pxa3xx_gpio, "pxa3xx-gpio", NULL),
-       INIT_CLKREG(&clk_pxa3xx_gpio, "pxa93x-gpio", NULL),
-       INIT_CLKREG(&clk_dummy, "sa1100-rtc", NULL),
-};
-
 #ifdef CONFIG_PM
 
 #define ISRAM_START    0x5c000000
@@ -476,8 +420,6 @@ static int __init pxa3xx_init(void)
                 */
                ASCR &= ~(ASCR_RDH | ASCR_D1S | ASCR_D2S | ASCR_D3S);
 
-               clkdev_add_table(pxa3xx_clkregs, ARRAY_SIZE(pxa3xx_clkregs));
-
                if ((ret = pxa_init_dma(IRQ_DMA, 32)))
                        return ret;
 
@@ -485,7 +427,6 @@ static int __init pxa3xx_init(void)
 
                register_syscore_ops(&pxa_irq_syscore_ops);
                register_syscore_ops(&pxa3xx_mfp_syscore_ops);
-               register_syscore_ops(&pxa3xx_clock_syscore_ops);
 
                if (of_have_populated_dt())
                        return 0;
index 6dc4f02..88f70c3 100644 (file)
@@ -56,7 +56,6 @@
 
 #include "generic.h"
 #include "devices.h"
-#include "clock.h"
 
 /* common GPIO definitions */
 
index 7780d1f..93bf4ef 100644 (file)
@@ -58,7 +58,6 @@
 #include <asm/mach/sharpsl_param.h>
 
 #include "generic.h"
-#include "clock.h"
 #include "devices.h"
 
 static unsigned long tosa_pin_config[] = {
index 0fb4842..4500647 100644 (file)
@@ -139,7 +139,7 @@ config MACH_ARMADILLO800EVA
        select ARCH_REQUIRE_GPIOLIB
        select REGULATOR_FIXED_VOLTAGE if REGULATOR
        select SMSC_PHY if SH_ETH
-       select SND_SOC_WM8978 if SND_SIMPLE_CARD
+       select SND_SOC_WM8978 if SND_SIMPLE_CARD && I2C
        select USE_OF
 
 config MACH_BOCKW
@@ -148,7 +148,7 @@ config MACH_BOCKW
        select ARCH_REQUIRE_GPIOLIB
        select REGULATOR_FIXED_VOLTAGE if REGULATOR
        select SND_SOC_AK4554 if SND_SIMPLE_CARD
-       select SND_SOC_AK4642 if SND_SIMPLE_CARD
+       select SND_SOC_AK4642 if SND_SIMPLE_CARD && I2C
        select USE_OF
 
 config MACH_BOCKW_REFERENCE
index b5f8d75..90efdeb 100644 (file)
@@ -1,5 +1,6 @@
-config ARCH_SOCFPGA
+menuconfig ARCH_SOCFPGA
        bool "Altera SOCFPGA family" if ARCH_MULTI_V7
+       select ARCH_SUPPORTS_BIG_ENDIAN
        select ARM_AMBA
        select ARM_GIC
        select CACHE_L2X0
@@ -8,3 +9,11 @@ config ARCH_SOCFPGA
        select HAVE_ARM_SCU
        select HAVE_ARM_TWD if SMP
        select MFD_SYSCON
+
+if ARCH_SOCFPGA
+config SOCFPGA_SUSPEND
+       bool "Suspend to RAM on SOCFPGA"
+       help
+         Select this if you want to enable Suspend-to-RAM on SOCFPGA
+         platforms.
+endif
index 6dd7a93..b8f9e23 100644 (file)
@@ -4,3 +4,4 @@
 
 obj-y                                  := socfpga.o
 obj-$(CONFIG_SMP)      += headsmp.o platsmp.o
+obj-$(CONFIG_SOCFPGA_SUSPEND)  += pm.o self-refresh.o
index 767c09e..7259c37 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Copyright 2012 Pavel Machek <pavel@denx.de>
- * Copyright (C) 2012 Altera Corporation
+ * Copyright (C) 2012-2015 Altera Corporation
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
 #define SOCFPGA_RSTMGR_MODPERRST       0x14
 #define SOCFPGA_RSTMGR_BRGMODRST       0x1c
 
+#define SOCFPGA_A10_RSTMGR_MODMPURST   0x20
+
 /* System Manager bits */
 #define RSTMGR_CTRL_SWCOLDRSTREQ       0x1     /* Cold Reset */
 #define RSTMGR_CTRL_SWWARMRSTREQ       0x2     /* Warm Reset */
 
 #define RSTMGR_MPUMODRST_CPU1          0x2     /* CPU1 Reset */
 
-extern void __iomem *socfpga_scu_base_addr;
-
 extern void socfpga_init_clocks(void);
 extern void socfpga_sysmgr_init(void);
 
 extern void __iomem *sys_manager_base_addr;
 extern void __iomem *rst_manager_base_addr;
+extern void __iomem *sdr_ctl_base_addr;
+
+u32 socfpga_sdram_self_refresh(u32 sdr_base);
+extern unsigned int socfpga_sdram_self_refresh_sz;
 
-extern struct smp_operations socfpga_smp_ops;
 extern char secondary_trampoline, secondary_trampoline_end;
 
 extern unsigned long socfpga_cpu1start_addr;
index 5bb0164..5d94b7a 100644 (file)
@@ -10,6 +10,7 @@
 #include <linux/linkage.h>
 #include <linux/init.h>
 #include <asm/memory.h>
+#include <asm/assembler.h>
 
        .arch   armv7-a
 
@@ -18,12 +19,14 @@ ENTRY(secondary_trampoline)
         * Thus, we can just subtract the PAGE_OFFSET to get the physical
         * address of &cpu1start_addr. This would not work for platforms
         * where the physical memory does not start at 0x0.
-        */
+       */
+ARM_BE8(setend be)
        adr     r0, 1f
        ldmia   r0, {r1, r2}
        sub     r2, r2, #PAGE_OFFSET
        ldr     r3, [r2]
        ldr     r4, [r3]
+ARM_BE8(rev    r4, r4)
        bx      r4
 
        .align
index 79c5336..c6f1df8 100644 (file)
@@ -54,32 +54,43 @@ static int socfpga_boot_secondary(unsigned int cpu, struct task_struct *idle)
        return 0;
 }
 
-/*
- * Initialise the CPU possible map early - this describes the CPUs
- * which may be present or become present in the system.
- */
-static void __init socfpga_smp_init_cpus(void)
+static int socfpga_a10_boot_secondary(unsigned int cpu, struct task_struct *idle)
 {
-       unsigned int i, ncores;
+       int trampoline_size = &secondary_trampoline_end - &secondary_trampoline;
 
-       ncores = scu_get_core_count(socfpga_scu_base_addr);
+       if (socfpga_cpu1start_addr) {
+               writel(RSTMGR_MPUMODRST_CPU1, rst_manager_base_addr +
+                      SOCFPGA_A10_RSTMGR_MODMPURST);
+               memcpy(phys_to_virt(0), &secondary_trampoline, trampoline_size);
 
-       for (i = 0; i < ncores; i++)
-               set_cpu_possible(i, true);
+               writel(virt_to_phys(secondary_startup),
+                      sys_manager_base_addr + (socfpga_cpu1start_addr & 0x00000fff));
 
-       /* sanity check */
-       if (ncores > num_possible_cpus()) {
-               pr_warn("socfpga: no. of cores (%d) greater than configured"
-                       "maximum of %d - clipping\n", ncores, num_possible_cpus());
-               ncores = num_possible_cpus();
+               flush_cache_all();
+               smp_wmb();
+               outer_clean_range(0, trampoline_size);
+
+               /* This will release CPU #1 out of reset. */
+               writel(0, rst_manager_base_addr + SOCFPGA_A10_RSTMGR_MODMPURST);
        }
 
-       for (i = 0; i < ncores; i++)
-               set_cpu_possible(i, true);
+       return 0;
 }
 
 static void __init socfpga_smp_prepare_cpus(unsigned int max_cpus)
 {
+       struct device_node *np;
+       void __iomem *socfpga_scu_base_addr;
+
+       np = of_find_compatible_node(NULL, NULL, "arm,cortex-a9-scu");
+       if (!np) {
+               pr_err("%s: missing scu\n", __func__);
+               return;
+       }
+
+       socfpga_scu_base_addr = of_iomap(np, 0);
+       if (!socfpga_scu_base_addr)
+               return;
        scu_enable(socfpga_scu_base_addr);
 }
 
@@ -95,11 +106,21 @@ static void socfpga_cpu_die(unsigned int cpu)
                cpu_do_idle();
 }
 
-struct smp_operations socfpga_smp_ops __initdata = {
-       .smp_init_cpus          = socfpga_smp_init_cpus,
+static struct smp_operations socfpga_smp_ops __initdata = {
        .smp_prepare_cpus       = socfpga_smp_prepare_cpus,
        .smp_boot_secondary     = socfpga_boot_secondary,
 #ifdef CONFIG_HOTPLUG_CPU
        .cpu_die                = socfpga_cpu_die,
 #endif
 };
+
+static struct smp_operations socfpga_a10_smp_ops __initdata = {
+       .smp_prepare_cpus       = socfpga_smp_prepare_cpus,
+       .smp_boot_secondary     = socfpga_a10_boot_secondary,
+#ifdef CONFIG_HOTPLUG_CPU
+       .cpu_die                = socfpga_cpu_die,
+#endif
+};
+
+CPU_METHOD_OF_DECLARE(socfpga_smp, "altr,socfpga-smp", &socfpga_smp_ops);
+CPU_METHOD_OF_DECLARE(socfpga_a10_smp, "altr,socfpga-a10-smp", &socfpga_a10_smp_ops);
diff --git a/arch/arm/mach-socfpga/pm.c b/arch/arm/mach-socfpga/pm.c
new file mode 100644 (file)
index 0000000..1ed89fc
--- /dev/null
@@ -0,0 +1,149 @@
+/*
+ *  arch/arm/mach-socfpga/pm.c
+ *
+ * Copyright (C) 2014-2015 Altera Corporation. All rights reserved.
+ *
+ * with code from pm-imx6.c
+ * Copyright 2011-2014 Freescale Semiconductor, Inc.
+ * Copyright 2011 Linaro Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/bitops.h>
+#include <linux/genalloc.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/of_platform.h>
+#include <linux/suspend.h>
+#include <asm/suspend.h>
+#include <asm/fncpy.h>
+#include "core.h"
+
+/* Pointer to function copied to ocram */
+static u32 (*socfpga_sdram_self_refresh_in_ocram)(u32 sdr_base);
+
+static int socfpga_setup_ocram_self_refresh(void)
+{
+       struct platform_device *pdev;
+       phys_addr_t ocram_pbase;
+       struct device_node *np;
+       struct gen_pool *ocram_pool;
+       unsigned long ocram_base;
+       void __iomem *suspend_ocram_base;
+       int ret = 0;
+
+       np = of_find_compatible_node(NULL, NULL, "mmio-sram");
+       if (!np) {
+               pr_err("%s: Unable to find mmio-sram in dtb\n", __func__);
+               return -ENODEV;
+       }
+
+       pdev = of_find_device_by_node(np);
+       if (!pdev) {
+               pr_warn("%s: failed to find ocram device!\n", __func__);
+               ret = -ENODEV;
+               goto put_node;
+       }
+
+       ocram_pool = dev_get_gen_pool(&pdev->dev);
+       if (!ocram_pool) {
+               pr_warn("%s: ocram pool unavailable!\n", __func__);
+               ret = -ENODEV;
+               goto put_node;
+       }
+
+       ocram_base = gen_pool_alloc(ocram_pool, socfpga_sdram_self_refresh_sz);
+       if (!ocram_base) {
+               pr_warn("%s: unable to alloc ocram!\n", __func__);
+               ret = -ENOMEM;
+               goto put_node;
+       }
+
+       ocram_pbase = gen_pool_virt_to_phys(ocram_pool, ocram_base);
+
+       suspend_ocram_base = __arm_ioremap_exec(ocram_pbase,
+                                               socfpga_sdram_self_refresh_sz,
+                                               false);
+       if (!suspend_ocram_base) {
+               pr_warn("%s: __arm_ioremap_exec failed!\n", __func__);
+               ret = -ENOMEM;
+               goto put_node;
+       }
+
+       /* Copy the code that puts DDR in self refresh to ocram */
+       socfpga_sdram_self_refresh_in_ocram =
+               (void *)fncpy(suspend_ocram_base,
+                             &socfpga_sdram_self_refresh,
+                             socfpga_sdram_self_refresh_sz);
+
+       WARN(!socfpga_sdram_self_refresh_in_ocram,
+            "could not copy function to ocram");
+       if (!socfpga_sdram_self_refresh_in_ocram)
+               ret = -EFAULT;
+
+put_node:
+       of_node_put(np);
+
+       return ret;
+}
+
+static int socfpga_pm_suspend(unsigned long arg)
+{
+       u32 ret;
+
+       if (!sdr_ctl_base_addr)
+               return -EFAULT;
+
+       ret = socfpga_sdram_self_refresh_in_ocram((u32)sdr_ctl_base_addr);
+
+       pr_debug("%s self-refresh loops request=%d exit=%d\n", __func__,
+                ret & 0xffff, (ret >> 16) & 0xffff);
+
+       return 0;
+}
+
+static int socfpga_pm_enter(suspend_state_t state)
+{
+       switch (state) {
+       case PM_SUSPEND_STANDBY:
+       case PM_SUSPEND_MEM:
+               outer_disable();
+               cpu_suspend(0, socfpga_pm_suspend);
+               outer_resume();
+               break;
+       default:
+               return -EINVAL;
+       }
+       return 0;
+}
+
+static const struct platform_suspend_ops socfpga_pm_ops = {
+       .valid  = suspend_valid_only_mem,
+       .enter  = socfpga_pm_enter,
+};
+
+static int __init socfpga_pm_init(void)
+{
+       int ret;
+
+       ret = socfpga_setup_ocram_self_refresh();
+       if (ret)
+               return ret;
+
+       suspend_set_ops(&socfpga_pm_ops);
+       pr_info("SoCFPGA initialized for DDR self-refresh during suspend.\n");
+
+       return 0;
+}
+arch_initcall(socfpga_pm_init);
diff --git a/arch/arm/mach-socfpga/self-refresh.S b/arch/arm/mach-socfpga/self-refresh.S
new file mode 100644 (file)
index 0000000..f2d7f88
--- /dev/null
@@ -0,0 +1,136 @@
+/*
+ * Copyright (C) 2014-2015 Altera Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+
+#define MAX_LOOP_COUNT         1000
+
+/* Register offset */
+#define SDR_CTRLGRP_LOWPWREQ_ADDR       0x54
+#define SDR_CTRLGRP_LOWPWRACK_ADDR      0x58
+
+/* Bitfield positions */
+#define SELFRSHREQ_POS                  3
+#define SELFRSHREQ_MASK                 0x8
+
+#define SELFRFSHACK_POS                 1
+#define SELFRFSHACK_MASK                0x2
+
+       /*
+        * This code assumes that when the bootloader configured
+        * the sdram controller for the DDR on the board it
+        * configured the following fields depending on the DDR
+        * vendor/configuration:
+        *
+        * sdr.ctrlcfg.lowpwreq.selfrfshmask
+        * sdr.ctrlcfg.lowpwrtiming.clkdisablecycles
+        * sdr.ctrlcfg.dramtiming4.selfrfshexit
+        */
+
+       .arch   armv7-a
+       .text
+       .align 3
+
+       /*
+        * socfpga_sdram_self_refresh
+        *
+        *  r0 : sdr_ctl_base_addr
+        *  r1 : temp storage of return value
+        *  r2 : temp storage of register values
+        *  r3 : loop counter
+        *
+        *  return value: lower 16 bits: loop count going into self refresh
+        *                upper 16 bits: loop count exiting self refresh
+        */
+ENTRY(socfpga_sdram_self_refresh)
+       /* Enable dynamic clock gating in the Power Control Register. */
+       mrc     p15, 0, r2, c15, c0, 0
+       orr     r2, r2, #1
+       mcr     p15, 0, r2, c15, c0, 0
+
+       /* Enable self refresh: set sdr.ctrlgrp.lowpwreq.selfrshreq = 1 */
+       ldr     r2, [r0, #SDR_CTRLGRP_LOWPWREQ_ADDR]
+       orr     r2, r2, #SELFRSHREQ_MASK
+       str     r2, [r0, #SDR_CTRLGRP_LOWPWREQ_ADDR]
+
+       /* Poll until sdr.ctrlgrp.lowpwrack.selfrfshack == 1 or hit max loops */
+       mov     r3, #0
+while_ack_0:
+       ldr     r2, [r0, #SDR_CTRLGRP_LOWPWRACK_ADDR]
+       and     r2, r2, #SELFRFSHACK_MASK
+       cmp     r2, #SELFRFSHACK_MASK
+       beq     ack_1
+
+       add     r3, #1
+       cmp     r3, #MAX_LOOP_COUNT
+       bne     while_ack_0
+
+ack_1:
+       mov     r1, r3
+
+       /*
+        * Execute an ISB instruction to ensure that all of the
+        * CP15 register changes have been committed.
+        */
+       isb
+
+       /*
+        * Execute a barrier instruction to ensure that all cache,
+        * TLB and branch predictor maintenance operations issued
+        * by any CPU in the cluster have completed.
+        */
+       dsb
+       dmb
+
+       wfi
+
+       /* Disable self-refresh: set sdr.ctrlgrp.lowpwreq.selfrshreq = 0 */
+       ldr     r2, [r0, #SDR_CTRLGRP_LOWPWREQ_ADDR]
+       bic     r2, r2, #SELFRSHREQ_MASK
+       str     r2, [r0, #SDR_CTRLGRP_LOWPWREQ_ADDR]
+
+       /* Poll until sdr.ctrlgrp.lowpwrack.selfrfshack == 0 or hit max loops */
+       mov     r3, #0
+while_ack_1:
+       ldr     r2, [r0, #SDR_CTRLGRP_LOWPWRACK_ADDR]
+       and     r2, r2, #SELFRFSHACK_MASK
+       cmp     r2, #SELFRFSHACK_MASK
+       bne     ack_0
+
+       add     r3, #1
+       cmp     r3, #MAX_LOOP_COUNT
+       bne     while_ack_1
+
+ack_0:
+       /*
+        * Prepare return value:
+        * Shift loop count for exiting self refresh into upper 16 bits.
+        * Leave loop count for requesting self refresh in lower 16 bits.
+        */
+       mov     r3, r3, lsl #16
+       add     r1, r1, r3
+
+       /* Disable dynamic clock gating in the Power Control Register. */
+       mrc     p15, 0, r2, c15, c0, 0
+       bic     r2, r2, #1
+       mcr     p15, 0, r2, c15, c0, 0
+
+       mov     r0, r1                  @ return value
+       bx      lr                      @ return
+
+ENDPROC(socfpga_sdram_self_refresh)
+ENTRY(socfpga_sdram_self_refresh_sz)
+       .word   . - socfpga_sdram_self_refresh
index f5e597c..19643a7 100644 (file)
@@ -1,5 +1,5 @@
 /*
- *  Copyright (C) 2012 Altera Corporation
+ *  Copyright (C) 2012-2015 Altera Corporation
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
 
 #include "core.h"
 
-void __iomem *socfpga_scu_base_addr = ((void __iomem *)(SOCFPGA_SCU_VIRT_BASE));
 void __iomem *sys_manager_base_addr;
 void __iomem *rst_manager_base_addr;
+void __iomem *sdr_ctl_base_addr;
 unsigned long socfpga_cpu1start_addr;
 
-static struct map_desc scu_io_desc __initdata = {
-       .virtual        = SOCFPGA_SCU_VIRT_BASE,
-       .pfn            = 0, /* run-time */
-       .length         = SZ_8K,
-       .type           = MT_DEVICE,
-};
-
-static struct map_desc uart_io_desc __initdata = {
-       .virtual        = 0xfec02000,
-       .pfn            = __phys_to_pfn(0xffc02000),
-       .length         = SZ_8K,
-       .type           = MT_DEVICE,
-};
-
-static void __init socfpga_scu_map_io(void)
-{
-       unsigned long base;
-
-       /* Get SCU base */
-       asm("mrc p15, 4, %0, c15, c0, 0" : "=r" (base));
-
-       scu_io_desc.pfn = __phys_to_pfn(base);
-       iotable_init(&scu_io_desc, 1);
-}
-
-static void __init socfpga_map_io(void)
-{
-       socfpga_scu_map_io();
-       iotable_init(&uart_io_desc, 1);
-       early_printk("Early printk initialized\n");
-}
-
 void __init socfpga_sysmgr_init(void)
 {
        struct device_node *np;
@@ -82,6 +50,9 @@ void __init socfpga_sysmgr_init(void)
 
        np = of_find_compatible_node(NULL, NULL, "altr,rst-mgr");
        rst_manager_base_addr = of_iomap(np, 0);
+
+       np = of_find_compatible_node(NULL, NULL, "altr,sdr-ctl");
+       sdr_ctl_base_addr = of_iomap(np, 0);
 }
 
 static void __init socfpga_init_irq(void)
@@ -111,8 +82,6 @@ static const char *altera_dt_match[] = {
 DT_MACHINE_START(SOCFPGA, "Altera SOCFPGA")
        .l2c_aux_val    = 0,
        .l2c_aux_mask   = ~0,
-       .smp            = smp_ops(socfpga_smp_ops),
-       .map_io         = socfpga_map_io,
        .init_irq       = socfpga_init_irq,
        .restart        = socfpga_cyclone5_restart,
        .dt_compat      = altera_dt_match,
diff --git a/arch/arm/mach-stm32/Makefile b/arch/arm/mach-stm32/Makefile
new file mode 100644 (file)
index 0000000..bd0b7b5
--- /dev/null
@@ -0,0 +1 @@
+obj-y += board-dt.o
diff --git a/arch/arm/mach-stm32/Makefile.boot b/arch/arm/mach-stm32/Makefile.boot
new file mode 100644 (file)
index 0000000..eacfc3f
--- /dev/null
@@ -0,0 +1,3 @@
+# Empty file waiting for deletion once Makefile.boot isn't needed any more.
+# Patch waits for application at
+# http://www.arm.linux.org.uk/developer/patches/viewpatch.php?id=7889/1 .
diff --git a/arch/arm/mach-stm32/board-dt.c b/arch/arm/mach-stm32/board-dt.c
new file mode 100644 (file)
index 0000000..f2ad772
--- /dev/null
@@ -0,0 +1,19 @@
+/*
+ * Copyright (C) Maxime Coquelin 2015
+ * Author:  Maxime Coquelin <mcoquelin.stm32@gmail.com>
+ * License terms:  GNU General Public License (GPL), version 2
+ */
+
+#include <linux/kernel.h>
+#include <asm/v7m.h>
+#include <asm/mach/arch.h>
+
+static const char *const stm32_compat[] __initconst = {
+       "st,stm32f429",
+       NULL
+};
+
+DT_MACHINE_START(STM32DT, "STM32 (Device Tree Support)")
+       .dt_compat = stm32_compat,
+       .restart = armv7m_restart,
+MACHINE_END
index 587b046..e8483ec 100644 (file)
@@ -121,3 +121,72 @@ static struct smp_operations sun6i_smp_ops __initdata = {
        .smp_boot_secondary     = sun6i_smp_boot_secondary,
 };
 CPU_METHOD_OF_DECLARE(sun6i_a31_smp, "allwinner,sun6i-a31", &sun6i_smp_ops);
+
+static void __init sun8i_smp_prepare_cpus(unsigned int max_cpus)
+{
+       struct device_node *node;
+
+       node = of_find_compatible_node(NULL, NULL, "allwinner,sun8i-a23-prcm");
+       if (!node) {
+               pr_err("Missing A23 PRCM node in the device tree\n");
+               return;
+       }
+
+       prcm_membase = of_iomap(node, 0);
+       if (!prcm_membase) {
+               pr_err("Couldn't map A23 PRCM registers\n");
+               return;
+       }
+
+       node = of_find_compatible_node(NULL, NULL,
+                                      "allwinner,sun8i-a23-cpuconfig");
+       if (!node) {
+               pr_err("Missing A23 CPU config node in the device tree\n");
+               return;
+       }
+
+       cpucfg_membase = of_iomap(node, 0);
+       if (!cpucfg_membase)
+               pr_err("Couldn't map A23 CPU config registers\n");
+
+}
+
+static int sun8i_smp_boot_secondary(unsigned int cpu,
+                                   struct task_struct *idle)
+{
+       u32 reg;
+
+       if (!(prcm_membase && cpucfg_membase))
+               return -EFAULT;
+
+       spin_lock(&cpu_lock);
+
+       /* Set CPU boot address */
+       writel(virt_to_phys(secondary_startup),
+              cpucfg_membase + CPUCFG_PRIVATE0_REG);
+
+       /* Assert the CPU core in reset */
+       writel(0, cpucfg_membase + CPUCFG_CPU_RST_CTRL_REG(cpu));
+
+       /* Assert the L1 cache in reset */
+       reg = readl(cpucfg_membase + CPUCFG_GEN_CTRL_REG);
+       writel(reg & ~BIT(cpu), cpucfg_membase + CPUCFG_GEN_CTRL_REG);
+
+       /* Clear CPU power-off gating */
+       reg = readl(prcm_membase + PRCM_CPU_PWROFF_REG);
+       writel(reg & ~BIT(cpu), prcm_membase + PRCM_CPU_PWROFF_REG);
+       mdelay(1);
+
+       /* Deassert the CPU core reset */
+       writel(3, cpucfg_membase + CPUCFG_CPU_RST_CTRL_REG(cpu));
+
+       spin_unlock(&cpu_lock);
+
+       return 0;
+}
+
+struct smp_operations sun8i_smp_ops __initdata = {
+       .smp_prepare_cpus       = sun8i_smp_prepare_cpus,
+       .smp_boot_secondary     = sun8i_smp_boot_secondary,
+};
+CPU_METHOD_OF_DECLARE(sun8i_a23_smp, "allwinner,sun8i-a23", &sun8i_smp_ops);
index 88de2dc..7469347 100644 (file)
@@ -34,6 +34,7 @@
 #include "iomap.h"
 #include "irq.h"
 #include "pm.h"
+#include "reset.h"
 #include "sleep.h"
 
 #ifdef CONFIG_PM_SLEEP
@@ -70,15 +71,13 @@ static struct cpuidle_driver tegra_idle_driver = {
 
 #ifdef CONFIG_PM_SLEEP
 #ifdef CONFIG_SMP
-static void __iomem *pmc = IO_ADDRESS(TEGRA_PMC_BASE);
-
 static int tegra20_reset_sleeping_cpu_1(void)
 {
        int ret = 0;
 
        tegra_pen_lock();
 
-       if (readl(pmc + PMC_SCRATCH41) == CPU_RESETTABLE)
+       if (readb(tegra20_cpu1_resettable_status) == CPU_RESETTABLE)
                tegra20_cpu_shutdown(1);
        else
                ret = -EINVAL;
index 71be4af..e3070fd 100644 (file)
@@ -169,10 +169,10 @@ after_errata:
        cmp     r6, #TEGRA20
        bne     1f
        /* If not CPU0, don't let CPU0 reset CPU1 now that CPU1 is coming up. */
-       mov32   r5, TEGRA_PMC_BASE
-       mov     r0, #0
+       mov32   r5, TEGRA_IRAM_BASE + TEGRA_IRAM_RESET_HANDLER_OFFSET
+       mov     r0, #CPU_NOT_RESETTABLE
        cmp     r10, #0
-       strne   r0, [r5, #PMC_SCRATCH41]
+       strneb  r0, [r5, #__tegra20_cpu1_resettable_status_offset]
 1:
 #endif
 
@@ -281,6 +281,10 @@ __tegra_cpu_reset_handler_data:
        .rept   TEGRA_RESET_DATA_SIZE
        .long   0
        .endr
+       .globl  __tegra20_cpu1_resettable_status_offset
+       .equ    __tegra20_cpu1_resettable_status_offset, \
+                                       . - __tegra_cpu_reset_handler_start
+       .byte   0
        .align L1_CACHE_SHIFT
 
 ENTRY(__tegra_cpu_reset_handler_end)
index 0aee012..9c479c7 100644 (file)
@@ -35,6 +35,7 @@ extern unsigned long __tegra_cpu_reset_handler_data[TEGRA_RESET_DATA_SIZE];
 
 void __tegra_cpu_reset_handler_start(void);
 void __tegra_cpu_reset_handler(void);
+void __tegra20_cpu1_resettable_status_offset(void);
 void __tegra_cpu_reset_handler_end(void);
 
 #ifdef CONFIG_PM_SLEEP
@@ -46,6 +47,9 @@ void __tegra_cpu_reset_handler_end(void);
        (IO_ADDRESS(TEGRA_IRAM_BASE + TEGRA_IRAM_RESET_HANDLER_OFFSET + \
        ((u32)&__tegra_cpu_reset_handler_data[TEGRA_RESET_MASK_LP2] - \
         (u32)__tegra_cpu_reset_handler_start)))
+#define tegra20_cpu1_resettable_status \
+       (IO_ADDRESS(TEGRA_IRAM_BASE + TEGRA_IRAM_RESET_HANDLER_OFFSET + \
+        (u32)__tegra20_cpu1_resettable_status_offset))
 #endif
 
 #define tegra_cpu_reset_handler_offset \
index be4bc5f..e6b684e 100644 (file)
@@ -97,9 +97,10 @@ ENDPROC(tegra20_hotplug_shutdown)
 ENTRY(tegra20_cpu_shutdown)
        cmp     r0, #0
        reteq   lr                      @ must not be called for CPU 0
-       mov32   r1, TEGRA_PMC_VIRT + PMC_SCRATCH41
+       mov32   r1, TEGRA_IRAM_RESET_BASE_VIRT
+       ldr     r2, =__tegra20_cpu1_resettable_status_offset
        mov     r12, #CPU_RESETTABLE
-       str     r12, [r1]
+       strb    r12, [r1, r2]
 
        cpu_to_halt_reg r1, r0
        ldr     r3, =TEGRA_FLOW_CTRL_VIRT
@@ -182,38 +183,41 @@ ENDPROC(tegra_pen_unlock)
 /*
  * tegra20_cpu_clear_resettable(void)
  *
- * Called to clear the "resettable soon" flag in PMC_SCRATCH41 when
+ * Called to clear the "resettable soon" flag in IRAM variable when
  * it is expected that the secondary CPU will be idle soon.
  */
 ENTRY(tegra20_cpu_clear_resettable)
-       mov32   r1, TEGRA_PMC_VIRT + PMC_SCRATCH41
+       mov32   r1, TEGRA_IRAM_RESET_BASE_VIRT
+       ldr     r2, =__tegra20_cpu1_resettable_status_offset
        mov     r12, #CPU_NOT_RESETTABLE
-       str     r12, [r1]
+       strb    r12, [r1, r2]
        ret     lr
 ENDPROC(tegra20_cpu_clear_resettable)
 
 /*
  * tegra20_cpu_set_resettable_soon(void)
  *
- * Called to set the "resettable soon" flag in PMC_SCRATCH41 when
+ * Called to set the "resettable soon" flag in IRAM variable when
  * it is expected that the secondary CPU will be idle soon.
  */
 ENTRY(tegra20_cpu_set_resettable_soon)
-       mov32   r1, TEGRA_PMC_VIRT + PMC_SCRATCH41
+       mov32   r1, TEGRA_IRAM_RESET_BASE_VIRT
+       ldr     r2, =__tegra20_cpu1_resettable_status_offset
        mov     r12, #CPU_RESETTABLE_SOON
-       str     r12, [r1]
+       strb    r12, [r1, r2]
        ret     lr
 ENDPROC(tegra20_cpu_set_resettable_soon)
 
 /*
  * tegra20_cpu_is_resettable_soon(void)
  *
- * Returns true if the "resettable soon" flag in PMC_SCRATCH41 has been
+ * Returns true if the "resettable soon" flag in IRAM variable has been
  * set because it is expected that the secondary CPU will be idle soon.
  */
 ENTRY(tegra20_cpu_is_resettable_soon)
-       mov32   r1, TEGRA_PMC_VIRT + PMC_SCRATCH41
-       ldr     r12, [r1]
+       mov32   r1, TEGRA_IRAM_RESET_BASE_VIRT
+       ldr     r2, =__tegra20_cpu1_resettable_status_offset
+       ldrb    r12, [r1, r2]
        cmp     r12, #CPU_RESETTABLE_SOON
        moveq   r0, #1
        movne   r0, #0
@@ -256,9 +260,10 @@ ENTRY(tegra20_sleep_cpu_secondary_finish)
        mov     r0, #TEGRA_FLUSH_CACHE_LOUIS
        bl      tegra_disable_clean_inv_dcache
 
-       mov32   r0, TEGRA_PMC_VIRT + PMC_SCRATCH41
+       mov32   r0, TEGRA_IRAM_RESET_BASE_VIRT
+       ldr     r4, =__tegra20_cpu1_resettable_status_offset
        mov     r3, #CPU_RESETTABLE
-       str     r3, [r0]
+       strb    r3, [r0, r4]
 
        bl      tegra_cpu_do_idle
 
@@ -274,10 +279,10 @@ ENTRY(tegra20_sleep_cpu_secondary_finish)
 
        bl      tegra_pen_lock
 
-       mov32   r3, TEGRA_PMC_VIRT
-       add     r0, r3, #PMC_SCRATCH41
+       mov32   r0, TEGRA_IRAM_RESET_BASE_VIRT
+       ldr     r4, =__tegra20_cpu1_resettable_status_offset
        mov     r3, #CPU_NOT_RESETTABLE
-       str     r3, [r0]
+       strb    r3, [r0, r4]
 
        bl      tegra_pen_unlock
 
index 92d46ec..0d59360 100644 (file)
@@ -18,6 +18,7 @@
 #define __MACH_TEGRA_SLEEP_H
 
 #include "iomap.h"
+#include "irammap.h"
 
 #define TEGRA_ARM_PERIF_VIRT (TEGRA_ARM_PERIF_BASE - IO_CPU_PHYS \
                                        + IO_CPU_VIRT)
@@ -29,6 +30,9 @@
                                        + IO_APB_VIRT)
 #define TEGRA_PMC_VIRT (TEGRA_PMC_BASE - IO_APB_PHYS + IO_APB_VIRT)
 
+#define TEGRA_IRAM_RESET_BASE_VIRT (IO_IRAM_VIRT + \
+                               TEGRA_IRAM_RESET_HANDLER_OFFSET)
+
 /* PMC_SCRATCH37-39 and 41 are used for tegra_pen_lock and idle */
 #define PMC_SCRATCH37  0x130
 #define PMC_SCRATCH38  0x134
index 861d884..2378fa5 100644 (file)
@@ -163,6 +163,5 @@ DT_MACHINE_START(TEGRA_DT, "NVIDIA Tegra SoC (Flattened Device Tree)")
        .init_irq       = tegra_dt_init_irq,
        .init_machine   = tegra_dt_init,
        .init_late      = tegra_dt_init_late,
-       .restart        = tegra_pmc_restart,
        .dt_compat      = tegra_dt_board_compat,
 MACHINE_END
diff --git a/arch/arm/mach-uniphier/Kconfig b/arch/arm/mach-uniphier/Kconfig
new file mode 100644 (file)
index 0000000..b640458
--- /dev/null
@@ -0,0 +1,11 @@
+config ARCH_UNIPHIER
+       bool "Socionext UniPhier SoCs"
+       depends on ARCH_MULTI_V7
+       select ARM_AMBA
+       select ARM_GLOBAL_TIMER
+       select ARM_GIC
+       select HAVE_ARM_SCU
+       select HAVE_ARM_TWD if SMP
+       help
+         Support for UniPhier SoC family developed by Socionext Inc.
+         (formerly, System LSI Business Division of Panasonic Corporation)
diff --git a/arch/arm/mach-uniphier/Makefile b/arch/arm/mach-uniphier/Makefile
new file mode 100644 (file)
index 0000000..60bd226
--- /dev/null
@@ -0,0 +1,2 @@
+obj-y                  := uniphier.o
+obj-$(CONFIG_SMP)      += platsmp.o
diff --git a/arch/arm/mach-uniphier/platsmp.c b/arch/arm/mach-uniphier/platsmp.c
new file mode 100644 (file)
index 0000000..5943e1c
--- /dev/null
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2015 Masahiro Yamada <yamada.masahiro@socionext.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/sizes.h>
+#include <linux/compiler.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/regmap.h>
+#include <linux/mfd/syscon.h>
+#include <asm/smp.h>
+#include <asm/smp_scu.h>
+
+static struct regmap *sbcm_regmap;
+
+static void __init uniphier_smp_prepare_cpus(unsigned int max_cpus)
+{
+       static cpumask_t only_cpu_0 = { CPU_BITS_CPU0 };
+       unsigned long scu_base_phys = 0;
+       void __iomem *scu_base;
+
+       sbcm_regmap = syscon_regmap_lookup_by_compatible(
+                       "socionext,uniphier-system-bus-controller-misc");
+       if (IS_ERR(sbcm_regmap)) {
+               pr_err("failed to regmap system-bus-controller-misc\n");
+               goto err;
+       }
+
+       if (scu_a9_has_base())
+               scu_base_phys = scu_a9_get_base();
+
+       if (!scu_base_phys) {
+               pr_err("failed to get scu base\n");
+               goto err;
+       }
+
+       scu_base = ioremap(scu_base_phys, SZ_128);
+       if (!scu_base) {
+               pr_err("failed to remap scu base (0x%08lx)\n", scu_base_phys);
+               goto err;
+       }
+
+       scu_enable(scu_base);
+       iounmap(scu_base);
+
+       return;
+err:
+       pr_warn("disabling SMP\n");
+       init_cpu_present(&only_cpu_0);
+       sbcm_regmap = NULL;
+}
+
+static void __naked uniphier_secondary_startup(void)
+{
+       asm("bl         v7_invalidate_l1\n"
+           "b          secondary_startup\n");
+};
+
+static int uniphier_boot_secondary(unsigned int cpu,
+                                  struct task_struct *idle)
+{
+       int ret;
+
+       if (!sbcm_regmap)
+               return -ENODEV;
+
+       ret = regmap_write(sbcm_regmap, 0x1208,
+                          virt_to_phys(uniphier_secondary_startup));
+       if (!ret)
+               asm("sev"); /* wake up secondary CPU */
+
+       return ret;
+}
+
+struct smp_operations uniphier_smp_ops __initdata = {
+       .smp_prepare_cpus       = uniphier_smp_prepare_cpus,
+       .smp_boot_secondary     = uniphier_boot_secondary,
+};
+CPU_METHOD_OF_DECLARE(uniphier_smp, "socionext,uniphier-smp",
+                     &uniphier_smp_ops);
diff --git a/arch/arm/mach-uniphier/uniphier.c b/arch/arm/mach-uniphier/uniphier.c
new file mode 100644 (file)
index 0000000..9be10ef
--- /dev/null
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2015 Masahiro Yamada <yamada.masahiro@socionext.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <asm/mach/arch.h>
+
+static const char * const uniphier_dt_compat[] __initconst = {
+       "socionext,ph1-sld3",
+       "socionext,ph1-ld4",
+       "socionext,ph1-pro4",
+       "socionext,ph1-sld8",
+       "socionext,ph1-pro5",
+       "socionext,proxstream2",
+       "socionext,ph1-ld6b",
+       NULL,
+};
+
+DT_MACHINE_START(UNIPHIER, "Socionext UniPhier")
+       .dt_compat      = uniphier_dt_compat,
+MACHINE_END
diff --git a/arch/arm/mach-zx/Kconfig b/arch/arm/mach-zx/Kconfig
new file mode 100644 (file)
index 0000000..2a910dc
--- /dev/null
@@ -0,0 +1,18 @@
+menuconfig ARCH_ZX
+       bool "ZTE ZX family" if ARCH_MULTI_V7
+       help
+         Support for ZTE ZX-based family of processors. TV
+         set-top-box processor is supported. More will be
+         added soon.
+
+if ARCH_ZX
+
+config SOC_ZX296702
+       def_bool y
+       select ARM_GIC
+       select ARM_GLOBAL_TIMER
+       select HAVE_ARM_SCU if SMP
+       select HAVE_ARM_TWD if SMP
+       help
+         Support for ZTE ZX296702 SoC which is a dual core CortexA9MP
+endif
diff --git a/arch/arm/mach-zx/Makefile b/arch/arm/mach-zx/Makefile
new file mode 100644 (file)
index 0000000..7c2edf6
--- /dev/null
@@ -0,0 +1,2 @@
+obj-$(CONFIG_SOC_ZX296702) += zx296702.o
+obj-$(CONFIG_SMP) += headsmp.o platsmp.o
diff --git a/arch/arm/mach-zx/core.h b/arch/arm/mach-zx/core.h
new file mode 100644 (file)
index 0000000..3efe8e0
--- /dev/null
@@ -0,0 +1,19 @@
+/*
+ * Copyright 2014 Linaro Ltd.
+ * Copyright (C) 2014 ZTE Corporation.
+ *
+ * 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.
+ */
+
+#ifndef __MACH_ZX_CORE_H
+#define __MACH_ZX_CORE_H
+
+extern void zx_resume_jump(void);
+extern size_t zx_suspend_iram_sz;
+extern unsigned long zx_secondary_startup_pa;
+
+void zx_secondary_startup(void);
+
+#endif /* __MACH_ZX_CORE_H */
diff --git a/arch/arm/mach-zx/headsmp.S b/arch/arm/mach-zx/headsmp.S
new file mode 100644 (file)
index 0000000..a1aa402
--- /dev/null
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2014 Linaro Ltd.
+ * Copyright (C) 2014 ZTE Corporation.
+ *
+ * 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>
+
+       .align 3
+       .arm
+
+/* It runs from physical address */
+ENTRY(zx_resume_jump)
+       adr     r1, zx_secondary_startup_pa
+       ldr     r0, [r1]
+       bx      r0
+ENDPROC(zx_resume_jump)
+
+ENTRY(zx_secondary_startup_pa)
+       .word   zx_secondary_startup_pa
+
+ENTRY(zx_suspend_iram_sz)
+        .word  . - zx_resume_jump
+ENDPROC(zx_secondary_startup_pa)
+
+
+ENTRY(zx_secondary_startup)
+       bl      v7_invalidate_l1
+       b       secondary_startup
+ENDPROC(zx_secondary_startup)
diff --git a/arch/arm/mach-zx/platsmp.c b/arch/arm/mach-zx/platsmp.c
new file mode 100644 (file)
index 0000000..a369398
--- /dev/null
@@ -0,0 +1,189 @@
+/*
+ * Copyright 2014 Linaro Ltd.
+ * Copyright (C) 2014 ZTE Corporation.
+ *
+ * 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/delay.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/jiffies.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/smp.h>
+
+#include <asm/cacheflush.h>
+#include <asm/cp15.h>
+#include <asm/fncpy.h>
+#include <asm/proc-fns.h>
+#include <asm/smp_scu.h>
+#include <asm/smp_plat.h>
+
+#include "core.h"
+
+#define AON_SYS_CTRL_RESERVED1         0xa8
+
+#define BUS_MATRIX_REMAP_CONFIG                0x00
+
+#define PCU_CPU0_CTRL                  0x00
+#define PCU_CPU1_CTRL                  0x04
+#define PCU_CPU1_ST                    0x0c
+#define PCU_GLOBAL_CTRL                        0x14
+#define PCU_EXPEND_CONTROL             0x34
+
+#define ZX_IRAM_BASE                   0x00200000
+
+static void __iomem *pcu_base;
+static void __iomem *matrix_base;
+static void __iomem *scu_base;
+
+void __init zx_smp_prepare_cpus(unsigned int max_cpus)
+{
+       struct device_node *np;
+       unsigned long base = 0;
+       void __iomem *aonsysctrl_base;
+       void __iomem *sys_iram;
+
+       base = scu_a9_get_base();
+       scu_base = ioremap(base, SZ_256);
+       if (!scu_base) {
+               pr_err("%s: failed to map scu\n", __func__);
+               return;
+       }
+
+       scu_enable(scu_base);
+
+       np = of_find_compatible_node(NULL, NULL, "zte,sysctrl");
+       if (!np) {
+               pr_err("%s: failed to find sysctrl node\n", __func__);
+               return;
+       }
+
+       aonsysctrl_base = of_iomap(np, 0);
+       if (!aonsysctrl_base) {
+               pr_err("%s: failed to map aonsysctrl\n", __func__);
+               of_node_put(np);
+               return;
+       }
+
+       /*
+        * Write the address of secondary startup into the
+        * system-wide flags register. The BootMonitor waits
+        * until it receives a soft interrupt, and then the
+        * secondary CPU branches to this address.
+        */
+       __raw_writel(virt_to_phys(zx_secondary_startup),
+                    aonsysctrl_base + AON_SYS_CTRL_RESERVED1);
+
+       iounmap(aonsysctrl_base);
+       of_node_put(np);
+
+       np = of_find_compatible_node(NULL, NULL, "zte,zx296702-pcu");
+       pcu_base = of_iomap(np, 0);
+       of_node_put(np);
+       WARN_ON(!pcu_base);
+
+       np = of_find_compatible_node(NULL, NULL, "zte,zx-bus-matrix");
+       matrix_base = of_iomap(np, 0);
+       of_node_put(np);
+       WARN_ON(!matrix_base);
+
+       /* Map the first 4 KB IRAM for suspend usage */
+       sys_iram = __arm_ioremap_exec(ZX_IRAM_BASE, PAGE_SIZE, false);
+       zx_secondary_startup_pa = virt_to_phys(zx_secondary_startup);
+       fncpy(sys_iram, &zx_resume_jump, zx_suspend_iram_sz);
+}
+
+static int zx_boot_secondary(unsigned int cpu, struct task_struct *idle)
+{
+       static bool first_boot = true;
+
+       if (first_boot) {
+               arch_send_wakeup_ipi_mask(cpumask_of(cpu));
+               first_boot = false;
+               return 0;
+       }
+
+       /* Swap the base address mapping between IRAM and IROM */
+       writel_relaxed(0x1, matrix_base + BUS_MATRIX_REMAP_CONFIG);
+
+       /* Power on CPU1 */
+       writel_relaxed(0x0, pcu_base + PCU_CPU1_CTRL);
+
+       /* Wait for power on ack */
+       while (readl_relaxed(pcu_base + PCU_CPU1_ST) & 0x4)
+               cpu_relax();
+
+       /* Swap back the mapping of IRAM and IROM */
+       writel_relaxed(0x0, matrix_base + BUS_MATRIX_REMAP_CONFIG);
+
+       return 0;
+}
+
+#ifdef CONFIG_HOTPLUG_CPU
+static inline void cpu_enter_lowpower(void)
+{
+       unsigned int v;
+
+       asm volatile(
+               "mcr    p15, 0, %1, c7, c5, 0\n"
+       "       mcr     p15, 0, %1, c7, c10, 4\n"
+       /*
+        * Turn off coherency
+        */
+       "       mrc     p15, 0, %0, c1, c0, 1\n"
+       "       bic     %0, %0, %3\n"
+       "       mcr     p15, 0, %0, c1, c0, 1\n"
+       "       mrc     p15, 0, %0, c1, c0, 0\n"
+       "       bic     %0, %0, %2\n"
+       "       mcr     p15, 0, %0, c1, c0, 0\n"
+         : "=&r" (v)
+         : "r" (0), "Ir" (CR_C), "Ir" (0x40)
+         : "cc");
+}
+
+static int zx_cpu_kill(unsigned int cpu)
+{
+       unsigned long timeout = jiffies + msecs_to_jiffies(2000);
+
+       writel_relaxed(0x2, pcu_base + PCU_CPU1_CTRL);
+
+       while ((readl_relaxed(pcu_base + PCU_CPU1_ST) & 0x3) != 0x0) {
+               if (time_after(jiffies, timeout)) {
+                       pr_err("*** cpu1 poweroff timeout\n");
+                       break;
+               }
+       }
+       return 1;
+}
+
+static void zx_cpu_die(unsigned int cpu)
+{
+       scu_power_mode(scu_base, SCU_PM_POWEROFF);
+       cpu_enter_lowpower();
+
+       while (1)
+               cpu_do_idle();
+}
+#endif
+
+static void zx_secondary_init(unsigned int cpu)
+{
+       scu_power_mode(scu_base, SCU_PM_NORMAL);
+}
+
+struct smp_operations zx_smp_ops __initdata = {
+       .smp_prepare_cpus       = zx_smp_prepare_cpus,
+       .smp_secondary_init     = zx_secondary_init,
+       .smp_boot_secondary     = zx_boot_secondary,
+#ifdef CONFIG_HOTPLUG_CPU
+       .cpu_kill               = zx_cpu_kill,
+       .cpu_die                = zx_cpu_die,
+#endif
+};
+
+CPU_METHOD_OF_DECLARE(zx_smp, "zte,zx296702-smp", &zx_smp_ops);
diff --git a/arch/arm/mach-zx/zx296702.c b/arch/arm/mach-zx/zx296702.c
new file mode 100644 (file)
index 0000000..60bb1a8
--- /dev/null
@@ -0,0 +1,25 @@
+/*
+ * Copyright 2014 Linaro Ltd.
+ * Copyright (C) 2014 ZTE Corporation.
+ *
+ * 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 <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+#include <linux/of_address.h>
+#include <linux/of_platform.h>
+
+static const char *zx296702_dt_compat[] __initconst = {
+       "zte,zx296702",
+       NULL,
+};
+
+DT_MACHINE_START(ZX, "ZTE ZX296702 (Device Tree)")
+       .dt_compat      = zx296702_dt_compat,
+       .l2c_aux_val    = 0,
+       .l2c_aux_mask   = ~0,
+MACHINE_END
index 58ef2a7..616d584 100644 (file)
@@ -190,11 +190,6 @@ static void __init zynq_irq_init(void)
        irqchip_init();
 }
 
-static void zynq_system_reset(enum reboot_mode mode, const char *cmd)
-{
-       zynq_slcr_system_reset();
-}
-
 static const char * const zynq_dt_match[] = {
        "xlnx,zynq-7000",
        NULL
@@ -212,5 +207,4 @@ DT_MACHINE_START(XILINX_EP107, "Xilinx Zynq Platform")
        .init_time      = zynq_timer_init,
        .dt_compat      = zynq_dt_match,
        .reserve        = zynq_memory_init,
-       .restart        = zynq_system_reset,
 MACHINE_END
index 7038cae..79cda2e 100644 (file)
@@ -19,7 +19,6 @@
 
 extern int zynq_slcr_init(void);
 extern int zynq_early_slcr_init(void);
-extern void zynq_slcr_system_reset(void);
 extern void zynq_slcr_cpu_stop(int cpu);
 extern void zynq_slcr_cpu_start(int cpu);
 extern bool zynq_slcr_cpu_state_read(int cpu);
index c3c24fd..26320eb 100644 (file)
@@ -15,6 +15,7 @@
  */
 
 #include <linux/io.h>
+#include <linux/reboot.h>
 #include <linux/mfd/syscon.h>
 #include <linux/of_address.h>
 #include <linux/regmap.h>
@@ -92,20 +93,21 @@ u32 zynq_slcr_get_device_id(void)
 }
 
 /**
- * zynq_slcr_system_reset - Reset the entire system.
+ * zynq_slcr_system_restart - Restart the entire system.
+ *
+ * @nb:                Pointer to restart notifier block (unused)
+ * @action:    Reboot mode (unused)
+ * @data:      Restart handler private data (unused)
+ *
+ * Return:     0 always
  */
-void zynq_slcr_system_reset(void)
+static
+int zynq_slcr_system_restart(struct notifier_block *nb,
+                            unsigned long action, void *data)
 {
        u32 reboot;
 
        /*
-        * Unlock the SLCR then reset the system.
-        * Note that this seems to require raw i/o
-        * functions or there's a lockup?
-        */
-       zynq_slcr_unlock();
-
-       /*
         * Clear 0x0F000000 bits of reboot status register to workaround
         * the FSBL not loading the bitstream after soft-reboot
         * This is a temporary solution until we know more.
@@ -113,8 +115,14 @@ void zynq_slcr_system_reset(void)
        zynq_slcr_read(&reboot, SLCR_REBOOT_STATUS_OFFSET);
        zynq_slcr_write(reboot & 0xF0FFFFFF, SLCR_REBOOT_STATUS_OFFSET);
        zynq_slcr_write(1, SLCR_PS_RST_CTRL_OFFSET);
+       return 0;
 }
 
+static struct notifier_block zynq_slcr_restart_nb = {
+       .notifier_call  = zynq_slcr_system_restart,
+       .priority       = 192,
+};
+
 /**
  * zynq_slcr_cpu_start - Start cpu
  * @cpu:       cpu number
@@ -219,6 +227,8 @@ int __init zynq_early_slcr_init(void)
        /* unlock the SLCR so that registers can be changed */
        zynq_slcr_unlock();
 
+       register_restart_handler(&zynq_slcr_restart_nb);
+
        pr_info("%s mapped to %p\n", np->name, zynq_slcr_base);
 
        of_node_put(np);
index 6416e03..1e460b4 100644 (file)
 
 #include <linux/omap-dma.h>
 
+#ifdef CONFIG_ARCH_OMAP1
+#include <mach/soc.h>
+#endif
+
 /*
  * MAX_LOGICAL_DMA_CH_COUNT: the maximum number of logical DMA
  * channels that an instance of the SDMA IP block can support.  Used
index e2be70d..efa6e85 100644 (file)
@@ -389,7 +389,7 @@ static int s3c_adc_probe(struct platform_device *pdev)
        if (ret)
                return ret;
 
-       clk_enable(adc->clk);
+       clk_prepare_enable(adc->clk);
 
        tmp = adc->prescale | S3C2410_ADCCON_PRSCEN;
 
@@ -413,7 +413,7 @@ static int s3c_adc_remove(struct platform_device *pdev)
 {
        struct adc_device *adc = platform_get_drvdata(pdev);
 
-       clk_disable(adc->clk);
+       clk_disable_unprepare(adc->clk);
        regulator_disable(adc->vdd);
 
        return 0;
@@ -475,7 +475,7 @@ static int s3c_adc_resume(struct device *dev)
 #define s3c_adc_resume NULL
 #endif
 
-static struct platform_device_id s3c_adc_driver_ids[] = {
+static const struct platform_device_id s3c_adc_driver_ids[] = {
        {
                .name           = "s3c24xx-adc",
                .driver_data    = TYPE_ADCV1,
index f6e4d56..2a61e4b 100644 (file)
@@ -445,6 +445,19 @@ static void vfp_enable(void *unused)
        set_copro_access(access | CPACC_FULL(10) | CPACC_FULL(11));
 }
 
+/* Called by platforms on which we want to disable VFP because it may not be
+ * present on all CPUs within a SMP complex. Needs to be called prior to
+ * vfp_init().
+ */
+void vfp_disable(void)
+{
+       if (VFP_arch) {
+               pr_debug("%s: should be called prior to vfp_init\n", __func__);
+               return;
+       }
+       VFP_arch = 1;
+}
+
 #ifdef CONFIG_CPU_PM
 static int vfp_pm_suspend(void)
 {
index 7796af4..cb8fa34 100644 (file)
@@ -181,6 +181,11 @@ config ARCH_FSL_LS2085A
        help
          This enables support for Freescale LS2085A SOC.
 
+config ARCH_HISI
+       bool "Hisilicon SoC Family"
+       help
+         This enables support for Hisilicon ARMv8 SoC family
+
 config ARCH_MEDIATEK
        bool "Mediatek MT65xx & MT81xx ARMv8 SoC"
        select ARM_GIC
index 2ed7449..1d293ea 100644 (file)
@@ -33,6 +33,7 @@ CONFIG_MODULE_UNLOAD=y
 # CONFIG_IOSCHED_DEADLINE is not set
 CONFIG_ARCH_EXYNOS7=y
 CONFIG_ARCH_FSL_LS2085A=y
+CONFIG_ARCH_HISI=y
 CONFIG_ARCH_MEDIATEK=y
 CONFIG_ARCH_SEATTLE=y
 CONFIG_ARCH_TEGRA=y
index 738612c..f364fa4 100644 (file)
@@ -91,6 +91,7 @@ static const int gisb_offsets_bcm7445[] = {
 struct brcmstb_gisb_arb_device {
        void __iomem    *base;
        const int       *gisb_offsets;
+       bool            big_endian;
        struct mutex    lock;
        struct list_head next;
        u32 valid_mask;
@@ -108,7 +109,10 @@ static u32 gisb_read(struct brcmstb_gisb_arb_device *gdev, int reg)
        if (offset == -1)
                return 1;
 
-       return ioread32(gdev->base + offset);
+       if (gdev->big_endian)
+               return ioread32be(gdev->base + offset);
+       else
+               return ioread32(gdev->base + offset);
 }
 
 static void gisb_write(struct brcmstb_gisb_arb_device *gdev, u32 val, int reg)
@@ -117,7 +121,11 @@ static void gisb_write(struct brcmstb_gisb_arb_device *gdev, u32 val, int reg)
 
        if (offset == -1)
                return;
-       iowrite32(val, gdev->base + reg);
+
+       if (gdev->big_endian)
+               iowrite32be(val, gdev->base + reg);
+       else
+               iowrite32(val, gdev->base + reg);
 }
 
 static ssize_t gisb_arb_get_timeout(struct device *dev,
@@ -296,6 +304,7 @@ static int __init brcmstb_gisb_arb_probe(struct platform_device *pdev)
                return -EINVAL;
        }
        gdev->gisb_offsets = of_id->data;
+       gdev->big_endian = of_device_is_big_endian(dn);
 
        err = devm_request_irq(&pdev->dev, timeout_irq,
                                brcmstb_gisb_timeout_handler, 0, pdev->name,
index 3d00c25..4dcbdd3 100644 (file)
@@ -50,6 +50,7 @@ obj-$(CONFIG_ARCH_BERLIN)             += berlin/
 obj-$(CONFIG_ARCH_HI3xxx)              += hisilicon/
 obj-$(CONFIG_ARCH_HIP04)               += hisilicon/
 obj-$(CONFIG_ARCH_HIX5HD2)             += hisilicon/
+obj-$(CONFIG_ARCH_MXC)                 += imx/
 obj-$(CONFIG_COMMON_CLK_KEYSTONE)      += keystone/
 ifeq ($(CONFIG_COMMON_CLK), y)
 obj-$(CONFIG_ARCH_MMP)                 += mmp/
@@ -72,4 +73,5 @@ obj-$(CONFIG_ARCH_OMAP2PLUS)          += ti/
 obj-$(CONFIG_ARCH_U8500)               += ux500/
 obj-$(CONFIG_COMMON_CLK_VERSATILE)     += versatile/
 obj-$(CONFIG_X86)                      += x86/
+obj-$(CONFIG_ARCH_ZX)                  += zte/
 obj-$(CONFIG_ARCH_ZYNQ)                        += zynq/
diff --git a/drivers/clk/imx/Makefile b/drivers/clk/imx/Makefile
new file mode 100644 (file)
index 0000000..75fae16
--- /dev/null
@@ -0,0 +1,26 @@
+
+obj-y += \
+       clk.o \
+       clk-busy.o \
+       clk-cpu.o \
+       clk-fixup-div.o \
+       clk-fixup-mux.o \
+       clk-gate-exclusive.o \
+       clk-gate2.o \
+       clk-pllv1.o \
+       clk-pllv2.o \
+       clk-pllv3.o \
+       clk-pfd.o
+
+obj-$(CONFIG_SOC_IMX1)   += clk-imx1.o
+obj-$(CONFIG_SOC_IMX21)  += clk-imx21.o
+obj-$(CONFIG_SOC_IMX25)  += clk-imx25.o
+obj-$(CONFIG_SOC_IMX27)  += clk-imx27.o
+obj-$(CONFIG_SOC_IMX31)  += clk-imx31.o
+obj-$(CONFIG_SOC_IMX35)  += clk-imx35.o
+obj-$(CONFIG_SOC_IMX5)   += clk-imx51-imx53.o
+obj-$(CONFIG_SOC_IMX6Q)  += clk-imx6q.o
+obj-$(CONFIG_SOC_IMX6SL) += clk-imx6sl.o
+obj-$(CONFIG_SOC_IMX6SX) += clk-imx6sx.o
+obj-$(CONFIG_SOC_IMX7D)  += clk-imx7d.o
+obj-$(CONFIG_SOC_VF610)  += clk-vf610.o
similarity index 99%
rename from arch/arm/mach-imx/clk-cpu.c
rename to drivers/clk/imx/clk-cpu.c
index aa1c345..9d46eac 100644 (file)
@@ -12,6 +12,7 @@
 #include <linux/clk.h>
 #include <linux/clk-provider.h>
 #include <linux/slab.h>
+#include "clk.h"
 
 struct clk_cpu {
        struct clk_hw   hw;
similarity index 91%
rename from arch/arm/mach-imx/clk-imx1.c
rename to drivers/clk/imx/clk-imx1.c
index 37c307a..c2647fa 100644 (file)
 #include <linux/of.h>
 #include <linux/of_address.h>
 #include <dt-bindings/clock/imx1-clock.h>
+#include <soc/imx/timer.h>
+#include <asm/irq.h>
 
 #include "clk.h"
-#include "common.h"
-#include "hardware.h"
+
+#define MX1_CCM_BASE_ADDR      0x0021b000
+#define MX1_TIM1_BASE_ADDR     0x00220000
+#define MX1_TIM1_INT           (NR_IRQS_LEGACY + 59)
 
 static const char *prem_sel_clks[] = { "clk32_premult", "clk16m", };
 static const char *clko_sel_clks[] = { "per1", "hclk", "clk48m", "clk16m",
@@ -50,9 +54,9 @@ static void __init _mx1_clocks_init(unsigned long fref)
        clk[IMX1_CLK_CLK16M] = imx_clk_gate("clk16m", "clk16m_ext", CCM_CSCR, 17);
        clk[IMX1_CLK_CLK32_PREMULT] = imx_clk_fixed_factor("clk32_premult", "clk32", 512, 1);
        clk[IMX1_CLK_PREM] = imx_clk_mux("prem", CCM_CSCR, 16, 1, prem_sel_clks, ARRAY_SIZE(prem_sel_clks));
-       clk[IMX1_CLK_MPLL] = imx_clk_pllv1("mpll", "clk32_premult", CCM_MPCTL0);
+       clk[IMX1_CLK_MPLL] = imx_clk_pllv1(IMX_PLLV1_IMX1, "mpll", "clk32_premult", CCM_MPCTL0);
        clk[IMX1_CLK_MPLL_GATE] = imx_clk_gate("mpll_gate", "mpll", CCM_CSCR, 0);
-       clk[IMX1_CLK_SPLL] = imx_clk_pllv1("spll", "prem", CCM_SPCTL0);
+       clk[IMX1_CLK_SPLL] = imx_clk_pllv1(IMX_PLLV1_IMX1, "spll", "prem", CCM_SPCTL0);
        clk[IMX1_CLK_SPLL_GATE] = imx_clk_gate("spll_gate", "spll", CCM_CSCR, 1);
        clk[IMX1_CLK_MCU] = imx_clk_divider("mcu", "clk32_premult", CCM_CSCR, 15, 1);
        clk[IMX1_CLK_FCLK] = imx_clk_divider("fclk", "mpll_gate", CCM_CSCR, 15, 1);
@@ -75,7 +79,8 @@ static void __init _mx1_clocks_init(unsigned long fref)
 
 int __init mx1_clocks_init(unsigned long fref)
 {
-       ccm = MX1_IO_ADDRESS(MX1_CCM_BASE_ADDR);
+       ccm = ioremap(MX1_CCM_BASE_ADDR, SZ_4K);
+       BUG_ON(!ccm);
 
        _mx1_clocks_init(fref);
 
@@ -98,7 +103,7 @@ int __init mx1_clocks_init(unsigned long fref)
        clk_register_clkdev(clk[IMX1_CLK_DUMMY], "ipg", "imx1-fb.0");
        clk_register_clkdev(clk[IMX1_CLK_DUMMY], "ahb", "imx1-fb.0");
 
-       mxc_timer_init(MX1_IO_ADDRESS(MX1_TIM1_BASE_ADDR), MX1_TIM1_INT);
+       mxc_timer_init(MX1_TIM1_BASE_ADDR, MX1_TIM1_INT, GPT_TYPE_IMX1);
 
        return 0;
 }
similarity index 95%
rename from arch/arm/mach-imx/clk-imx21.c
rename to drivers/clk/imx/clk-imx21.c
index 4b4c753..dba987e 100644 (file)
 #include <linux/of.h>
 #include <linux/of_address.h>
 #include <dt-bindings/clock/imx21-clock.h>
+#include <soc/imx/timer.h>
+#include <asm/irq.h>
 
 #include "clk.h"
-#include "common.h"
-#include "hardware.h"
+
+#define MX21_CCM_BASE_ADDR     0x10027000
+#define MX21_GPT1_BASE_ADDR    0x10003000
+#define MX21_INT_GPT1          (NR_IRQS_LEGACY + 26)
 
 static void __iomem *ccm __initdata;
 
@@ -63,9 +67,9 @@ static void __init _mx21_clocks_init(unsigned long lref, unsigned long href)
        clk[IMX21_CLK_USB_DIV] = imx_clk_divider("usb_div", "spll_gate", CCM_CSCR, 26, 3);
        clk[IMX21_CLK_FCLK] = imx_clk_divider("fclk", "mpll_gate", CCM_CSCR, 29, 3);
 
-       clk[IMX21_CLK_MPLL] = imx_clk_pllv1("mpll", "mpll_sel", CCM_MPCTL0);
+       clk[IMX21_CLK_MPLL] = imx_clk_pllv1(IMX_PLLV1_IMX21, "mpll", "mpll_sel", CCM_MPCTL0);
 
-       clk[IMX21_CLK_SPLL] = imx_clk_pllv1("spll", "spll_sel", CCM_SPCTL0);
+       clk[IMX21_CLK_SPLL] = imx_clk_pllv1(IMX_PLLV1_IMX21, "spll", "spll_sel", CCM_SPCTL0);
 
        clk[IMX21_CLK_NFC_DIV] = imx_clk_divider("nfc_div", "fclk", CCM_PCDR0, 12, 4);
        clk[IMX21_CLK_SSI1_DIV] = imx_clk_divider("ssi1_div", "ssi1_sel", CCM_PCDR0, 16, 6);
@@ -153,7 +157,7 @@ int __init mx21_clocks_init(unsigned long lref, unsigned long href)
        clk_register_clkdev(clk[IMX21_CLK_I2C_GATE], NULL, "imx21-i2c.0");
        clk_register_clkdev(clk[IMX21_CLK_OWIRE_GATE], NULL, "mxc_w1.0");
 
-       mxc_timer_init(MX21_IO_ADDRESS(MX21_GPT1_BASE_ADDR), MX21_INT_GPT1);
+       mxc_timer_init(MX21_GPT1_BASE_ADDR, MX21_INT_GPT1, GPT_TYPE_IMX21);
 
        return 0;
 }
similarity index 98%
rename from arch/arm/mach-imx/clk-imx25.c
rename to drivers/clk/imx/clk-imx25.c
index 9c2633a..ec1a4c1 100644 (file)
@@ -28,8 +28,6 @@
 #include <linux/of_irq.h>
 
 #include "clk.h"
-#include "common.h"
-#include "hardware.h"
 
 #define CCM_MPCTL      0x00
 #define CCM_UPCTL      0x04
@@ -95,8 +93,8 @@ static int __init __mx25_clocks_init(unsigned long osc_rate,
 
        clk[dummy] = imx_clk_fixed("dummy", 0);
        clk[osc] = imx_clk_fixed("osc", osc_rate);
-       clk[mpll] = imx_clk_pllv1("mpll", "osc", ccm(CCM_MPCTL));
-       clk[upll] = imx_clk_pllv1("upll", "osc", ccm(CCM_UPCTL));
+       clk[mpll] = imx_clk_pllv1(IMX_PLLV1_IMX25, "mpll", "osc", ccm(CCM_MPCTL));
+       clk[upll] = imx_clk_pllv1(IMX_PLLV1_IMX25, "upll", "osc", ccm(CCM_UPCTL));
        clk[mpll_cpu_3_4] = imx_clk_fixed_factor("mpll_cpu_3_4", "mpll", 3, 4);
        clk[cpu_sel] = imx_clk_mux("cpu_sel", ccm(CCM_CCTL), 14, 1, cpu_sel_clks, ARRAY_SIZE(cpu_sel_clks));
        clk[cpu] = imx_clk_divider("cpu", "cpu_sel", ccm(CCM_CCTL), 30, 2);
similarity index 97%
rename from arch/arm/mach-imx/clk-imx27.c
rename to drivers/clk/imx/clk-imx27.c
index ab6349e..d9d50d5 100644 (file)
@@ -5,10 +5,15 @@
 #include <linux/of.h>
 #include <linux/of_address.h>
 #include <dt-bindings/clock/imx27-clock.h>
+#include <soc/imx/revision.h>
+#include <soc/imx/timer.h>
+#include <asm/irq.h>
 
 #include "clk.h"
-#include "common.h"
-#include "hardware.h"
+
+#define MX27_CCM_BASE_ADDR     0x10027000
+#define MX27_GPT1_BASE_ADDR    0x10003000
+#define MX27_INT_GPT1          (NR_IRQS_LEGACY + 26)
 
 static void __iomem *ccm __initdata;
 
@@ -54,8 +59,8 @@ static void __init _mx27_clocks_init(unsigned long fref)
        clk[IMX27_CLK_CKIH_GATE] = imx_clk_gate_dis("ckih_gate", "ckih", CCM_CSCR, 3);
        clk[IMX27_CLK_MPLL_OSC_SEL] = imx_clk_mux("mpll_osc_sel", CCM_CSCR, 4, 1, mpll_osc_sel_clks, ARRAY_SIZE(mpll_osc_sel_clks));
        clk[IMX27_CLK_MPLL_SEL] = imx_clk_mux("mpll_sel", CCM_CSCR, 16, 1, mpll_sel_clks, ARRAY_SIZE(mpll_sel_clks));
-       clk[IMX27_CLK_MPLL] = imx_clk_pllv1("mpll", "mpll_sel", CCM_MPCTL0);
-       clk[IMX27_CLK_SPLL] = imx_clk_pllv1("spll", "ckih_gate", CCM_SPCTL0);
+       clk[IMX27_CLK_MPLL] = imx_clk_pllv1(IMX_PLLV1_IMX27, "mpll", "mpll_sel", CCM_MPCTL0);
+       clk[IMX27_CLK_SPLL] = imx_clk_pllv1(IMX_PLLV1_IMX27, "spll", "ckih_gate", CCM_SPCTL0);
        clk[IMX27_CLK_SPLL_GATE] = imx_clk_gate("spll_gate", "spll", CCM_CSCR, 1);
        clk[IMX27_CLK_MPLL_MAIN2] = imx_clk_fixed_factor("mpll_main2", "mpll", 2, 3);
 
@@ -229,7 +234,7 @@ int __init mx27_clocks_init(unsigned long fref)
        clk_register_clkdev(clk[IMX27_CLK_EMMA_AHB_GATE], "ahb", "m2m-emmaprp.0");
        clk_register_clkdev(clk[IMX27_CLK_EMMA_IPG_GATE], "ipg", "m2m-emmaprp.0");
 
-       mxc_timer_init(MX27_IO_ADDRESS(MX27_GPT1_BASE_ADDR), MX27_INT_GPT1);
+       mxc_timer_init(MX27_GPT1_BASE_ADDR, MX27_INT_GPT1, GPT_TYPE_IMX21);
 
        return 0;
 }
similarity index 91%
rename from arch/arm/mach-imx/clk-imx31.c
rename to drivers/clk/imx/clk-imx31.c
index 286ef42..fe66c40 100644 (file)
 #include <linux/io.h>
 #include <linux/err.h>
 #include <linux/of.h>
+#include <soc/imx/revision.h>
+#include <soc/imx/timer.h>
+#include <asm/irq.h>
 
 #include "clk.h"
-#include "common.h"
-#include "crmregs-imx3.h"
-#include "hardware.h"
-#include "mx31.h"
+
+#define MX31_CCM_BASE_ADDR     0x53f80000
+#define MX31_GPT1_BASE_ADDR    0x53f90000
+#define MX31_INT_GPT           (NR_IRQS_LEGACY + 29)
+
+#define MXC_CCM_CCMR           0x00
+#define MXC_CCM_PDR0           0x04
+#define MXC_CCM_PDR1           0x08
+#define MXC_CCM_MPCTL          0x10
+#define MXC_CCM_UPCTL          0x14
+#define MXC_CCM_SRPCTL         0x18
+#define MXC_CCM_CGR0           0x20
+#define MXC_CCM_CGR1           0x24
+#define MXC_CCM_CGR2           0x28
+#define MXC_CCM_PMCR0          0x5c
 
 static const char *mcu_main_sel[] = { "spll", "mpll", };
 static const char *per_sel[] = { "per_div", "ipg", };
@@ -50,15 +64,18 @@ static struct clk_onecell_data clk_data;
 
 int __init mx31_clocks_init(unsigned long fref)
 {
-       void __iomem *base = MX31_IO_ADDRESS(MX31_CCM_BASE_ADDR);
+       void __iomem *base;
        struct device_node *np;
 
+       base = ioremap(MX31_CCM_BASE_ADDR, SZ_4K);
+       BUG_ON(!base);
+
        clk[dummy] = imx_clk_fixed("dummy", 0);
        clk[ckih] = imx_clk_fixed("ckih", fref);
        clk[ckil] = imx_clk_fixed("ckil", 32768);
-       clk[mpll] = imx_clk_pllv1("mpll", "ckih", base + MXC_CCM_MPCTL);
-       clk[spll] = imx_clk_pllv1("spll", "ckih", base + MXC_CCM_SRPCTL);
-       clk[upll] = imx_clk_pllv1("upll", "ckih", base + MXC_CCM_UPCTL);
+       clk[mpll] = imx_clk_pllv1(IMX_PLLV1_IMX31, "mpll", "ckih", base + MXC_CCM_MPCTL);
+       clk[spll] = imx_clk_pllv1(IMX_PLLV1_IMX31, "spll", "ckih", base + MXC_CCM_SRPCTL);
+       clk[upll] = imx_clk_pllv1(IMX_PLLV1_IMX31, "upll", "ckih", base + MXC_CCM_UPCTL);
        clk[mcu_main] = imx_clk_mux("mcu_main", base + MXC_CCM_PMCR0, 31, 1, mcu_main_sel, ARRAY_SIZE(mcu_main_sel));
        clk[hsp] = imx_clk_divider("hsp", "mcu_main", base + MXC_CCM_PDR0, 11, 3);
        clk[ahb] = imx_clk_divider("ahb", "mcu_main", base + MXC_CCM_PDR0, 3, 3);
@@ -182,7 +199,7 @@ int __init mx31_clocks_init(unsigned long fref)
        mx31_revision();
        clk_disable_unprepare(clk[iim_gate]);
 
-       mxc_timer_init(MX31_IO_ADDRESS(MX31_GPT1_BASE_ADDR), MX31_INT_GPT);
+       mxc_timer_init(MX31_GPT1_BASE_ADDR, MX31_INT_GPT, GPT_TYPE_IMX31);
 
        return 0;
 }
similarity index 94%
rename from arch/arm/mach-imx/clk-imx35.c
rename to drivers/clk/imx/clk-imx35.c
index a0d2b57..69138ba 100644 (file)
 #include <linux/clkdev.h>
 #include <linux/of.h>
 #include <linux/err.h>
+#include <soc/imx/revision.h>
+#include <soc/imx/timer.h>
+#include <asm/irq.h>
 
-#include "crmregs-imx3.h"
 #include "clk.h"
-#include "common.h"
-#include "hardware.h"
+
+#define MX35_CCM_BASE_ADDR     0x53f80000
+#define MX35_GPT1_BASE_ADDR    0x53f90000
+#define MX35_INT_GPT           (NR_IRQS_LEGACY + 29)
+
+#define MXC_CCM_PDR0           0x04
+#define MX35_CCM_PDR2          0x0c
+#define MX35_CCM_PDR3          0x10
+#define MX35_CCM_PDR4          0x14
+#define MX35_CCM_MPCTL         0x1c
+#define MX35_CCM_PPCTL         0x20
+#define MX35_CCM_CGR0          0x2c
+#define MX35_CCM_CGR1          0x30
+#define MX35_CCM_CGR2          0x34
+#define MX35_CCM_CGR3          0x38
 
 struct arm_ahb_div {
        unsigned char arm, ahb, sel;
@@ -71,11 +86,14 @@ static struct clk *clk[clk_max];
 
 int __init mx35_clocks_init(void)
 {
-       void __iomem *base = MX35_IO_ADDRESS(MX35_CCM_BASE_ADDR);
+       void __iomem *base;
        u32 pdr0, consumer_sel, hsp_sel;
        struct arm_ahb_div *aad;
        unsigned char *hsp_div;
 
+       base = ioremap(MX35_CCM_BASE_ADDR, SZ_4K);
+       BUG_ON(!base);
+
        pdr0 = __raw_readl(base + MXC_CCM_PDR0);
        consumer_sel = (pdr0 >> 16) & 0xf;
        aad = &clk_consumer[consumer_sel];
@@ -89,8 +107,8 @@ int __init mx35_clocks_init(void)
        }
 
        clk[ckih] = imx_clk_fixed("ckih", 24000000);
-       clk[mpll] = imx_clk_pllv1("mpll", "ckih", base + MX35_CCM_MPCTL);
-       clk[ppll] = imx_clk_pllv1("ppll", "ckih", base + MX35_CCM_PPCTL);
+       clk[mpll] = imx_clk_pllv1(IMX_PLLV1_IMX35, "mpll", "ckih", base + MX35_CCM_MPCTL);
+       clk[ppll] = imx_clk_pllv1(IMX_PLLV1_IMX35, "ppll", "ckih", base + MX35_CCM_PPCTL);
 
        clk[mpll] = imx_clk_fixed_factor("mpll_075", "mpll", 3, 4);
 
@@ -276,11 +294,7 @@ int __init mx35_clocks_init(void)
 
        imx_print_silicon_rev("i.MX35", mx35_revision());
 
-#ifdef CONFIG_MXC_USE_EPIT
-       epit_timer_init(MX35_IO_ADDRESS(MX35_EPIT1_BASE_ADDR), MX35_INT_EPIT1);
-#else
-       mxc_timer_init(MX35_IO_ADDRESS(MX35_GPT1_BASE_ADDR), MX35_INT_GPT);
-#endif
+       mxc_timer_init(MX35_GPT1_BASE_ADDR, MX35_INT_GPT, GPT_TYPE_IMX31);
 
        return 0;
 }
similarity index 99%
rename from arch/arm/mach-imx/clk-imx51-imx53.c
rename to drivers/clk/imx/clk-imx51-imx53.c
index 0f7e536..a7e4f39 100644 (file)
 #include <linux/of.h>
 #include <linux/of_address.h>
 #include <linux/of_irq.h>
+#include <soc/imx/revision.h>
 #include <dt-bindings/clock/imx5-clock.h>
 
 #include "clk.h"
-#include "common.h"
-#include "hardware.h"
 
 #define MX51_DPLL1_BASE                0x83f80000
 #define MX51_DPLL2_BASE                0x83f84000
@@ -133,8 +132,6 @@ static struct clk_onecell_data clk_data;
 
 static void __init mx5_clocks_common_init(void __iomem *ccm_base)
 {
-       imx5_pm_set_ccm_base(ccm_base);
-
        clk[IMX5_CLK_DUMMY]             = imx_clk_fixed("dummy", 0);
        clk[IMX5_CLK_CKIL]              = imx_obtain_fixed_clock("ckil", 0);
        clk[IMX5_CLK_OSC]               = imx_obtain_fixed_clock("osc", 0);
similarity index 98%
rename from arch/arm/mach-imx/clk-imx6q.c
rename to drivers/clk/imx/clk-imx6q.c
index 469a150..d046f8e 100644 (file)
 #include <linux/of.h>
 #include <linux/of_address.h>
 #include <linux/of_irq.h>
+#include <soc/imx/revision.h>
 #include <dt-bindings/clock/imx6qdl-clock.h>
 
 #include "clk.h"
-#include "common.h"
-#include "hardware.h"
 
 static const char *step_sels[] = { "osc", "pll2_pfd2_396m", };
 static const char *pll1_sw_sels[]      = { "pll1_sys", "step", };
@@ -121,6 +120,16 @@ static unsigned int share_count_ssi2;
 static unsigned int share_count_ssi3;
 static unsigned int share_count_mipi_core_cfg;
 
+static inline int clk_on_imx6q(void)
+{
+       return of_machine_is_compatible("fsl,imx6q");
+}
+
+static inline int clk_on_imx6dl(void)
+{
+       return of_machine_is_compatible("fsl,imx6dl");
+}
+
 static void __init imx6q_clocks_init(struct device_node *ccm_node)
 {
        struct device_node *np;
@@ -141,7 +150,7 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node)
        WARN_ON(!base);
 
        /* Audio/video PLL post dividers do not work on i.MX6q revision 1.0 */
-       if (cpu_is_imx6q() && imx_get_soc_revision() == IMX_CHIP_REVISION_1_0) {
+       if (clk_on_imx6q() && imx_get_soc_revision() == IMX_CHIP_REVISION_1_0) {
                post_div_table[1].div = 1;
                post_div_table[2].div = 1;
                video_div_table[1].div = 1;
@@ -248,7 +257,7 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node)
        clk[IMX6QDL_CLK_TWD]       = imx_clk_fixed_factor("twd",       "arm",            1, 2);
        clk[IMX6QDL_CLK_GPT_3M]    = imx_clk_fixed_factor("gpt_3m",    "osc",            1, 8);
        clk[IMX6QDL_CLK_VIDEO_27M] = imx_clk_fixed_factor("video_27m", "pll3_pfd1_540m", 1, 20);
-       if (cpu_is_imx6dl()) {
+       if (clk_on_imx6dl()) {
                clk[IMX6QDL_CLK_GPU2D_AXI] = imx_clk_fixed_factor("gpu2d_axi", "mmdc_ch0_axi_podf", 1, 1);
                clk[IMX6QDL_CLK_GPU3D_AXI] = imx_clk_fixed_factor("gpu3d_axi", "mmdc_ch0_axi_podf", 1, 1);
        }
@@ -262,8 +271,6 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node)
        base = of_iomap(np, 0);
        WARN_ON(!base);
 
-       imx6q_pm_set_ccm_base(base);
-
        /*                                              name                reg       shift width parent_names     num_parents */
        clk[IMX6QDL_CLK_STEP]             = imx_clk_mux("step",             base + 0xc,  8,  1, step_sels,         ARRAY_SIZE(step_sels));
        clk[IMX6QDL_CLK_PLL1_SW]          = imx_clk_mux("pll1_sw",          base + 0xc,  2,  1, pll1_sw_sels,      ARRAY_SIZE(pll1_sw_sels));
@@ -275,7 +282,7 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node)
        clk[IMX6QDL_CLK_ESAI_SEL]         = imx_clk_mux("esai_sel",         base + 0x20, 19, 2, audio_sels,        ARRAY_SIZE(audio_sels));
        clk[IMX6QDL_CLK_ASRC_SEL]         = imx_clk_mux("asrc_sel",         base + 0x30, 7,  2, audio_sels,        ARRAY_SIZE(audio_sels));
        clk[IMX6QDL_CLK_SPDIF_SEL]        = imx_clk_mux("spdif_sel",        base + 0x30, 20, 2, audio_sels,        ARRAY_SIZE(audio_sels));
-       if (cpu_is_imx6q()) {
+       if (clk_on_imx6q()) {
                clk[IMX6QDL_CLK_GPU2D_AXI]        = imx_clk_mux("gpu2d_axi",        base + 0x18, 0,  1, gpu_axi_sels,      ARRAY_SIZE(gpu_axi_sels));
                clk[IMX6QDL_CLK_GPU3D_AXI]        = imx_clk_mux("gpu3d_axi",        base + 0x18, 1,  1, gpu_axi_sels,      ARRAY_SIZE(gpu_axi_sels));
        }
@@ -382,7 +389,7 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node)
        clk[IMX6QDL_CLK_ECSPI2]       = imx_clk_gate2("ecspi2",        "ecspi_root",        base + 0x6c, 2);
        clk[IMX6QDL_CLK_ECSPI3]       = imx_clk_gate2("ecspi3",        "ecspi_root",        base + 0x6c, 4);
        clk[IMX6QDL_CLK_ECSPI4]       = imx_clk_gate2("ecspi4",        "ecspi_root",        base + 0x6c, 6);
-       if (cpu_is_imx6dl())
+       if (clk_on_imx6dl())
                clk[IMX6DL_CLK_I2C4]  = imx_clk_gate2("i2c4",          "ipg_per",           base + 0x6c, 8);
        else
                clk[IMX6Q_CLK_ECSPI5] = imx_clk_gate2("ecspi5",        "ecspi_root",        base + 0x6c, 8);
@@ -392,7 +399,7 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node)
        clk[IMX6QDL_CLK_ESAI_MEM]     = imx_clk_gate2_shared("esai_mem", "ahb",             base + 0x6c, 16, &share_count_esai);
        clk[IMX6QDL_CLK_GPT_IPG]      = imx_clk_gate2("gpt_ipg",       "ipg",               base + 0x6c, 20);
        clk[IMX6QDL_CLK_GPT_IPG_PER]  = imx_clk_gate2("gpt_ipg_per",   "ipg_per",           base + 0x6c, 22);
-       if (cpu_is_imx6dl())
+       if (clk_on_imx6dl())
                /*
                 * The multiplexer and divider of imx6q clock gpu3d_shader get
                 * redefined/reused as gpu2d_core_sel and gpu2d_core_podf on imx6dl.
@@ -420,7 +427,7 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node)
        clk[IMX6QDL_CLK_HSI_TX]       = imx_clk_gate2_shared("hsi_tx", "hsi_tx_podf",       base + 0x74, 16, &share_count_mipi_core_cfg);
        clk[IMX6QDL_CLK_MIPI_CORE_CFG] = imx_clk_gate2_shared("mipi_core_cfg", "video_27m", base + 0x74, 16, &share_count_mipi_core_cfg);
        clk[IMX6QDL_CLK_MIPI_IPG]     = imx_clk_gate2_shared("mipi_ipg", "ipg",             base + 0x74, 16, &share_count_mipi_core_cfg);
-       if (cpu_is_imx6dl())
+       if (clk_on_imx6dl())
                /*
                 * The multiplexer and divider of the imx6q clock gpu2d get
                 * redefined/reused as mlb_sys_sel and mlb_sys_clk_podf on imx6dl.
@@ -443,7 +450,7 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node)
        clk[IMX6QDL_CLK_GPMI_IO]      = imx_clk_gate2("gpmi_io",       "enfc",              base + 0x78, 28);
        clk[IMX6QDL_CLK_GPMI_APB]     = imx_clk_gate2("gpmi_apb",      "usdhc3",            base + 0x78, 30);
        clk[IMX6QDL_CLK_ROM]          = imx_clk_gate2("rom",           "ahb",               base + 0x7c, 0);
-       clk[IMX6QDL_CLK_SATA]         = imx_clk_gate2("sata",          "ipg",               base + 0x7c, 4);
+       clk[IMX6QDL_CLK_SATA]         = imx_clk_gate2("sata",          "ahb",               base + 0x7c, 4);
        clk[IMX6QDL_CLK_SDMA]         = imx_clk_gate2("sdma",          "ahb",               base + 0x7c, 6);
        clk[IMX6QDL_CLK_SPBA]         = imx_clk_gate2("spba",          "ipg",               base + 0x7c, 12);
        clk[IMX6QDL_CLK_SPDIF]        = imx_clk_gate2("spdif",         "spdif_podf",        base + 0x7c, 14);
@@ -470,7 +477,7 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node)
         * The gpt_3m clock is not available on i.MX6Q TO1.0.  Let's point it
         * to clock gpt_ipg_per to ease the gpt driver code.
         */
-       if (cpu_is_imx6q() && imx_get_soc_revision() == IMX_CHIP_REVISION_1_0)
+       if (clk_on_imx6q() && imx_get_soc_revision() == IMX_CHIP_REVISION_1_0)
                clk[IMX6QDL_CLK_GPT_3M] = clk[IMX6QDL_CLK_GPT_IPG_PER];
 
        imx_check_clocks(clk, ARRAY_SIZE(clk));
@@ -482,7 +489,7 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node)
        clk_register_clkdev(clk[IMX6QDL_CLK_ENET_REF], "enet_ref", NULL);
 
        if ((imx_get_soc_revision() != IMX_CHIP_REVISION_1_0) ||
-           cpu_is_imx6dl()) {
+           clk_on_imx6dl()) {
                clk_set_parent(clk[IMX6QDL_CLK_LDB_DI0_SEL], clk[IMX6QDL_CLK_PLL5_VIDEO_DIV]);
                clk_set_parent(clk[IMX6QDL_CLK_LDB_DI1_SEL], clk[IMX6QDL_CLK_PLL5_VIDEO_DIV]);
        }
@@ -527,8 +534,5 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node)
        /* All existing boards with PCIe use LVDS1 */
        if (IS_ENABLED(CONFIG_PCI_IMX6))
                clk_set_parent(clk[IMX6QDL_CLK_LVDS1_SEL], clk[IMX6QDL_CLK_SATA_REF_100M]);
-
-       /* Set initial power mode */
-       imx6q_set_lpm(WAIT_CLOCKED);
 }
 CLK_OF_DECLARE(imx6q, "fsl,imx6q-ccm", imx6q_clocks_init);
similarity index 99%
rename from arch/arm/mach-imx/clk-imx6sl.c
rename to drivers/clk/imx/clk-imx6sl.c
index e982ebe..a0d4cf2 100644 (file)
@@ -16,7 +16,6 @@
 #include <dt-bindings/clock/imx6sl-clock.h>
 
 #include "clk.h"
-#include "common.h"
 
 #define CCSR                   0xc
 #define BM_CCSR_PLL1_SW_CLK_SEL        (1 << 2)
@@ -288,9 +287,6 @@ static void __init imx6sl_clocks_init(struct device_node *ccm_node)
        WARN_ON(!base);
        ccm_base = base;
 
-       /* Reuse imx6q pm code */
-       imx6q_pm_set_ccm_base(base);
-
        /*                                              name                reg       shift width parent_names     num_parents */
        clks[IMX6SL_CLK_STEP]             = imx_clk_mux("step",             base + 0xc,  8,  1, step_sels,         ARRAY_SIZE(step_sels));
        clks[IMX6SL_CLK_PLL1_SW]          = imx_clk_mux("pll1_sw",          base + 0xc,  2,  1, pll1_sw_sels,      ARRAY_SIZE(pll1_sw_sels));
@@ -443,8 +439,5 @@ static void __init imx6sl_clocks_init(struct device_node *ccm_node)
 
        clk_set_parent(clks[IMX6SL_CLK_LCDIF_AXI_SEL],
                       clks[IMX6SL_CLK_PLL2_PFD2]);
-
-       /* Set initial power mode */
-       imx6q_set_lpm(WAIT_CLOCKED);
 }
 CLK_OF_DECLARE(imx6sl, "fsl,imx6sl-ccm", imx6sl_clocks_init);
similarity index 99%
rename from arch/arm/mach-imx/clk-imx6sx.c
rename to drivers/clk/imx/clk-imx6sx.c
index 87c5b09..5b95c2c 100644 (file)
@@ -21,7 +21,6 @@
 #include <linux/types.h>
 
 #include "clk.h"
-#include "common.h"
 
 #define CCDR    0x4
 #define BM_CCM_CCDR_MMDC_CH0_MASK       (0x2 << 16)
@@ -268,8 +267,6 @@ static void __init imx6sx_clocks_init(struct device_node *ccm_node)
        base = of_iomap(np, 0);
        WARN_ON(!base);
 
-       imx6q_pm_set_ccm_base(base);
-
        /*                                                name                reg           shift   width   parent_names       num_parents */
        clks[IMX6SX_CLK_STEP]               = imx_clk_mux("step",             base + 0xc,   8,      1,      step_sels,         ARRAY_SIZE(step_sels));
        clks[IMX6SX_CLK_PLL1_SW]            = imx_clk_mux("pll1_sw",          base + 0xc,   2,      1,      pll1_sw_sels,      ARRAY_SIZE(pll1_sw_sels));
@@ -560,8 +557,5 @@ static void __init imx6sx_clocks_init(struct device_node *ccm_node)
 
        clk_set_parent(clks[IMX6SX_CLK_QSPI1_SEL], clks[IMX6SX_CLK_PLL2_BUS]);
        clk_set_parent(clks[IMX6SX_CLK_QSPI2_SEL], clks[IMX6SX_CLK_PLL2_BUS]);
-
-       /* Set initial power mode */
-       imx6q_set_lpm(WAIT_CLOCKED);
 }
 CLK_OF_DECLARE(imx6sx, "fsl,imx6sx-ccm", imx6sx_clocks_init);
diff --git a/drivers/clk/imx/clk-imx7d.c b/drivers/clk/imx/clk-imx7d.c
new file mode 100644 (file)
index 0000000..71f3a94
--- /dev/null
@@ -0,0 +1,860 @@
+/*
+ * Copyright (C) 2014-2015 Freescale Semiconductor, Inc.
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include <dt-bindings/clock/imx7d-clock.h>
+#include <linux/clk.h>
+#include <linux/clkdev.h>
+#include <linux/err.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+#include <linux/types.h>
+
+#include "clk.h"
+
+static struct clk *clks[IMX7D_CLK_END];
+static const char *arm_a7_sel[] = { "osc", "pll_arm_main_clk",
+       "pll_enet_500m_clk", "pll_dram_main_clk",
+       "pll_sys_main_clk", "pll_sys_pfd0_392m_clk", "pll_audio_main_clk",
+       "pll_usb_main_clk", };
+
+static const char *arm_m4_sel[] = { "osc", "pll_sys_main_240m_clk",
+       "pll_enet_250m_clk", "pll_sys_pfd2_270m_clk",
+       "pll_dram_533m_clk", "pll_audio_main_clk", "pll_video_main_clk",
+       "pll_usb_main_clk", };
+
+static const char *arm_m0_sel[] = { "osc", "pll_sys_main_120m_clk",
+       "pll_enet_125m_clk", "pll_sys_pfd2_135m_clk",
+       "pll_dram_533m_clk", "pll_audio_main_clk", "pll_video_main_clk",
+       "pll_usb_main_clk", };
+
+static const char *axi_sel[] = { "osc", "pll_sys_pfd1_332m_clk",
+       "pll_dram_533m_clk", "pll_enet_250m_clk", "pll_sys_pfd5_clk",
+       "pll_audio_main_clk", "pll_video_main_clk", "pll_sys_pfd7_clk", };
+
+static const char *disp_axi_sel[] = { "osc", "pll_sys_pfd1_332m_clk",
+       "pll_dram_533m_clk", "pll_enet_250m_clk", "pll_sys_pfd6_clk",
+       "pll_sys_pfd7_clk", "pll_audio_main_clk", "pll_video_main_clk", };
+
+static const char *enet_axi_sel[] = { "osc", "pll_sys_pfd2_270m_clk",
+       "pll_dram_533m_clk", "pll_enet_250m_clk",
+       "pll_sys_main_240m_clk", "pll_audio_main_clk", "pll_video_main_clk",
+       "pll_sys_pfd4_clk", };
+
+static const char *nand_usdhc_bus_sel[] = { "osc", "pll_sys_pfd2_270m_clk",
+       "pll_dram_533m_clk", "pll_sys_main_240m_clk",
+       "pll_sys_pfd2_135m_clk", "pll_sys_pfd6_clk", "pll_enet_250m_clk",
+       "pll_audio_main_clk", };
+
+static const char *ahb_channel_sel[] = { "osc", "pll_sys_pfd2_135m_clk",
+       "pll_dram_533m_clk", "pll_sys_pfd0_392m_clk",
+       "pll_enet_125m_clk", "pll_usb_main_clk", "pll_audio_main_clk",
+       "pll_video_main_clk", };
+
+static const char *dram_phym_sel[] = { "pll_dram_main_clk",
+       "dram_phym_alt_clk", };
+
+static const char *dram_sel[] = { "pll_dram_main_clk",
+       "dram_alt_clk", };
+
+static const char *dram_phym_alt_sel[] = { "osc", "pll_dram_533m_clk",
+       "pll_sys_main_clk", "pll_enet_500m_clk",
+       "pll_usb_main_clk", "pll_sys_pfd7_clk", "pll_audio_main_clk",
+       "pll_video_main_clk", };
+
+static const char *dram_alt_sel[] = { "osc", "pll_dram_533m_clk",
+       "pll_sys_main_clk", "pll_enet_500m_clk",
+       "pll_enet_250m_clk", "pll_sys_pfd0_392m_clk",
+       "pll_audio_main_clk", "pll_sys_pfd2_270m_clk", };
+
+static const char *usb_hsic_sel[] = { "osc", "pll_sys_main_clk",
+       "pll_usb_main_clk", "pll_sys_pfd3_clk", "pll_sys_pfd4_clk",
+       "pll_sys_pfd5_clk", "pll_sys_pfd6_clk", "pll_sys_pfd7_clk", };
+
+static const char *pcie_ctrl_sel[] = { "osc", "pll_enet_250m_clk",
+       "pll_sys_main_240m_clk", "pll_sys_pfd2_270m_clk",
+       "pll_dram_533m_clk", "pll_enet_500m_clk",
+       "pll_sys_pfd1_332m_clk", "pll_sys_pfd6_clk", };
+
+static const char *pcie_phy_sel[] = { "osc", "pll_enet_100m_clk",
+       "pll_enet_500m_clk", "ext_clk_1", "ext_clk_2", "ext_clk_3",
+       "ext_clk_4", "pll_sys_pfd0_392m_clk", };
+
+static const char *epdc_pixel_sel[] = { "osc", "pll_sys_pfd1_332m_clk",
+       "pll_dram_533m_clk", "pll_sys_main_clk", "pll_sys_pfd5_clk",
+       "pll_sys_pfd6_clk", "pll_sys_pfd7_clk", "pll_video_main_clk", };
+
+static const char *lcdif_pixel_sel[] = { "osc", "pll_sys_pfd5_clk",
+       "pll_dram_533m_clk", "ext_clk_3", "pll_sys_pfd4_clk",
+       "pll_sys_pfd2_270m_clk", "pll_video_main_clk",
+       "pll_usb_main_clk", };
+
+static const char *mipi_dsi_sel[] = { "osc", "pll_sys_pfd5_clk",
+       "pll_sys_pfd3_clk", "pll_sys_main_clk", "pll_sys_pfd0_196m_clk",
+       "pll_dram_533m_clk", "pll_video_main_clk", "pll_audio_main_clk", };
+
+static const char *mipi_csi_sel[] = { "osc", "pll_sys_pfd4_clk",
+       "pll_sys_pfd3_clk", "pll_sys_main_clk", "pll_sys_pfd0_196m_clk",
+       "pll_dram_533m_clk", "pll_video_main_clk", "pll_audio_main_clk", };
+
+static const char *mipi_dphy_sel[] = { "osc", "pll_sys_main_120m_clk",
+       "pll_dram_533m_clk", "pll_sys_pfd5_clk", "ref_1m_clk", "ext_clk_2",
+       "pll_video_main_clk", "ext_clk_3", };
+
+static const char *sai1_sel[] = { "osc", "pll_sys_pfd2_135m_clk",
+       "pll_audio_main_clk", "pll_dram_533m_clk", "pll_video_main_clk",
+       "pll_sys_pfd4_clk", "pll_enet_125m_clk", "ext_clk_2", };
+
+static const char *sai2_sel[] = { "osc", "pll_sys_pfd2_135m_clk",
+       "pll_audio_main_clk", "pll_dram_533m_clk", "pll_video_main_clk",
+       "pll_sys_pfd4_clk", "pll_enet_125m_clk", "ext_clk_2", };
+
+static const char *sai3_sel[] = { "osc", "pll_sys_pfd2_135m_clk",
+       "pll_audio_main_clk", "pll_dram_533m_clk", "pll_video_main_clk",
+       "pll_sys_pfd4_clk", "pll_enet_125m_clk", "ext_clk_3", };
+
+static const char *spdif_sel[] = { "osc", "pll_sys_pfd2_135m_clk",
+       "pll_audio_main_clk", "pll_dram_533m_clk", "pll_video_main_clk",
+       "pll_sys_pfd4_clk", "pll_enet_125m_clk", "ext_3_clk", };
+
+static const char *enet1_ref_sel[] = { "osc", "pll_enet_125m_clk",
+       "pll_enet_50m_clk", "pll_enet_25m_clk",
+       "pll_sys_main_120m_clk", "pll_audio_main_clk", "pll_video_main_clk",
+       "ext_clk_4", };
+
+static const char *enet1_time_sel[] = { "osc", "pll_enet_100m_clk",
+       "pll_audio_main_clk", "ext_clk_1", "ext_clk_2", "ext_clk_3",
+       "ext_clk_4", "pll_video_main_clk", };
+
+static const char *enet2_ref_sel[] = { "osc", "pll_enet_125m_clk",
+       "pll_enet_50m_clk", "pll_enet_25m_clk",
+       "pll_sys_main_120m_clk", "pll_audio_main_clk", "pll_video_main_clk",
+       "ext_clk_4", };
+
+static const char *enet2_time_sel[] = { "osc", "pll_enet_100m_clk",
+       "pll_audio_main_clk", "ext_clk_1", "ext_clk_2", "ext_clk_3",
+       "ext_clk_4", "pll_video_main_clk", };
+
+static const char *enet_phy_ref_sel[] = { "osc", "pll_enet_25m_clk",
+       "pll_enet_50m_clk", "pll_enet_125m_clk",
+       "pll_dram_533m_clk", "pll_audio_main_clk", "pll_video_main_clk",
+       "pll_sys_pfd3_clk", };
+
+static const char *eim_sel[] = { "osc", "pll_sys_pfd2_135m_clk",
+       "pll_sys_main_120m_clk", "pll_dram_533m_clk",
+       "pll_sys_pfd2_270m_clk", "pll_sys_pfd3_clk", "pll_enet_125m_clk",
+       "pll_usb_main_clk", };
+
+static const char *nand_sel[] = { "osc", "pll_sys_main_clk",
+       "pll_dram_533m_clk", "pll_sys_pfd0_392m_clk", "pll_sys_pfd3_clk",
+       "pll_enet_500m_clk", "pll_enet_250m_clk",
+       "pll_video_main_clk", };
+
+static const char *qspi_sel[] = { "osc", "pll_sys_pfd4_clk",
+       "pll_dram_533m_clk", "pll_enet_500m_clk", "pll_sys_pfd3_clk",
+       "pll_sys_pfd2_270m_clk", "pll_sys_pfd6_clk", "pll_sys_pfd7_clk", };
+
+static const char *usdhc1_sel[] = { "osc", "pll_sys_pfd0_392m_clk",
+       "pll_dram_533m_clk", "pll_enet_500m_clk", "pll_sys_pfd4_clk",
+       "pll_sys_pfd2_270m_clk", "pll_sys_pfd6_clk", "pll_sys_pfd7_clk", };
+
+static const char *usdhc2_sel[] = { "osc", "pll_sys_pfd0_392m_clk",
+       "pll_dram_533m_clk", "pll_enet_500m_clk", "pll_sys_pfd4_clk",
+       "pll_sys_pfd2_270m_clk", "pll_sys_pfd6_clk", "pll_sys_pfd7_clk", };
+
+static const char *usdhc3_sel[] = { "osc", "pll_sys_pfd0_392m_clk",
+       "pll_dram_533m_clk", "pll_enet_500m_clk", "pll_sys_pfd4_clk",
+       "pll_sys_pfd2_270m_clk", "pll_sys_pfd6_clk", "pll_sys_pfd7_clk", };
+
+static const char *can1_sel[] = { "osc", "pll_sys_main_120m_clk",
+       "pll_dram_533m_clk", "pll_sys_main_clk",
+       "pll_enet_40m_clk", "pll_usb_main_clk", "ext_clk_1",
+       "ext_clk_4", };
+
+static const char *can2_sel[] = { "osc", "pll_sys_main_120m_clk",
+       "pll_dram_533m_clk", "pll_sys_main_clk",
+       "pll_enet_40m_clk", "pll_usb_main_clk", "ext_clk_1",
+       "ext_clk_3", };
+
+static const char *i2c1_sel[] = { "osc", "pll_sys_main_120m_clk",
+       "pll_enet_50m_clk", "pll_dram_533m_clk",
+       "pll_audio_main_clk", "pll_video_main_clk", "pll_usb_main_clk",
+       "pll_sys_pfd2_135m_clk", };
+
+static const char *i2c2_sel[] = { "osc", "pll_sys_main_120m_clk",
+       "pll_enet_50m_clk", "pll_dram_533m_clk",
+       "pll_audio_main_clk", "pll_video_main_clk", "pll_usb_main_clk",
+       "pll_sys_pfd2_135m_clk", };
+
+static const char *i2c3_sel[] = { "osc", "pll_sys_main_120m_clk",
+       "pll_enet_50m_clk", "pll_dram_533m_clk",
+       "pll_audio_main_clk", "pll_video_main_clk", "pll_usb_main_clk",
+       "pll_sys_pfd2_135m_clk", };
+
+static const char *i2c4_sel[] = { "osc", "pll_sys_main_120m_clk",
+       "pll_enet_50m_clk", "pll_dram_533m_clk",
+       "pll_audio_main_clk", "pll_video_main_clk", "pll_usb_main_clk",
+       "pll_sys_pfd2_135m_clk", };
+
+static const char *uart1_sel[] = { "osc", "pll_sys_main_240m_clk",
+       "pll_enet_40m_clk", "pll_enet_100m_clk",
+       "pll_sys_main_clk", "ext_clk_2", "ext_clk_4",
+       "pll_usb_main_clk", };
+
+static const char *uart2_sel[] = { "osc", "pll_sys_main_240m_clk",
+       "pll_enet_40m_clk", "pll_enet_100m_clk",
+       "pll_sys_main_clk", "ext_clk_2", "ext_clk_3",
+       "pll_usb_main_clk", };
+
+static const char *uart3_sel[] = { "osc", "pll_sys_main_240m_clk",
+       "pll_enet_40m_clk", "pll_enet_100m_clk",
+       "pll_sys_main_clk", "ext_clk_2", "ext_clk_4",
+       "pll_usb_main_clk", };
+
+static const char *uart4_sel[] = { "osc", "pll_sys_main_240m_clk",
+       "pll_enet_40m_clk", "pll_enet_100m_clk",
+       "pll_sys_main_clk", "ext_clk_2", "ext_clk_3",
+       "pll_usb_main_clk", };
+
+static const char *uart5_sel[] = { "osc", "pll_sys_main_240m_clk",
+       "pll_enet_40m_clk", "pll_enet_100m_clk",
+       "pll_sys_main_clk", "ext_clk_2", "ext_clk_4",
+       "pll_usb_main_clk", };
+
+static const char *uart6_sel[] = { "osc", "pll_sys_main_240m_clk",
+       "pll_enet_40m_clk", "pll_enet_100m_clk",
+       "pll_sys_main_clk", "ext_clk_2", "ext_clk_3",
+       "pll_usb_main_clk", };
+
+static const char *uart7_sel[] = { "osc", "pll_sys_main_240m_clk",
+       "pll_enet_40m_clk", "pll_enet_100m_clk",
+       "pll_sys_main_clk", "ext_clk_2", "ext_clk_4",
+       "pll_usb_main_clk", };
+
+static const char *ecspi1_sel[] = { "osc", "pll_sys_main_240m_clk",
+       "pll_enet_40m_clk", "pll_sys_main_120m_clk",
+       "pll_sys_main_clk", "pll_sys_pfd4_clk", "pll_enet_250m_clk",
+       "pll_usb_main_clk", };
+
+static const char *ecspi2_sel[] = { "osc", "pll_sys_main_240m_clk",
+       "pll_enet_40m_clk", "pll_sys_main_120m_clk",
+       "pll_sys_main_clk", "pll_sys_pfd4_clk", "pll_enet_250m_clk",
+       "pll_usb_main_clk", };
+
+static const char *ecspi3_sel[] = { "osc", "pll_sys_main_240m_clk",
+       "pll_enet_40m_clk", "pll_sys_main_120m_clk",
+       "pll_sys_main_clk", "pll_sys_pfd4_clk", "pll_enet_250m_clk",
+       "pll_usb_main_clk", };
+
+static const char *ecspi4_sel[] = { "osc", "pll_sys_main_240m_clk",
+       "pll_enet_40m_clk", "pll_sys_main_120m_clk",
+       "pll_sys_main_clk", "pll_sys_pfd4_clk", "pll_enet_250m_clk",
+       "pll_usb_main_clk", };
+
+static const char *pwm1_sel[] = { "osc", "pll_enet_100m_clk",
+       "pll_sys_main_120m_clk", "pll_enet_40m_clk", "pll_audio_main_clk",
+       "ext_clk_1", "ref_1m_clk", "pll_video_main_clk", };
+
+static const char *pwm2_sel[] = { "osc", "pll_enet_100m_clk",
+       "pll_sys_main_120m_clk", "pll_enet_40m_clk", "pll_audio_main_clk",
+       "ext_clk_1", "ref_1m_clk", "pll_video_main_clk", };
+
+static const char *pwm3_sel[] = { "osc", "pll_enet_100m_clk",
+       "pll_sys_main_120m_clk", "pll_enet_40m_clk", "pll_audio_main_clk",
+       "ext_clk_2", "ref_1m_clk", "pll_video_main_clk", };
+
+static const char *pwm4_sel[] = { "osc", "pll_enet_100m_clk",
+       "pll_sys_main_120m_clk", "pll_enet_40m_clk", "pll_audio_main_clk",
+       "ext_clk_2", "ref_1m_clk", "pll_video_main_clk", };
+
+static const char *flextimer1_sel[] = { "osc", "pll_enet_100m_clk",
+       "pll_sys_main_120m_clk", "pll_enet_40m_clk", "pll_audio_main_clk",
+       "ext_clk_3", "ref_1m_clk", "pll_video_main_clk", };
+
+static const char *flextimer2_sel[] = { "osc", "pll_enet_100m_clk",
+       "pll_sys_main_120m_clk", "pll_enet_40m_clk", "pll_audio_main_clk",
+       "ext_clk_3", "ref_1m_clk", "pll_video_main_clk", };
+
+static const char *sim1_sel[] = { "osc", "pll_sys_pfd2_135m_clk",
+       "pll_sys_main_120m_clk", "pll_dram_533m_clk",
+       "pll_usb_main_clk", "pll_audio_main_clk", "pll_enet_125m_clk",
+       "pll_sys_pfd7_clk", };
+
+static const char *sim2_sel[] = { "osc", "pll_sys_pfd2_135m_clk",
+       "pll_sys_main_120m_clk", "pll_dram_533m_clk",
+       "pll_usb_main_clk", "pll_video_main_clk", "pll_enet_125m_clk",
+       "pll_sys_pfd7_clk", };
+
+static const char *gpt1_sel[] = { "osc", "pll_enet_100m_clk",
+       "pll_sys_pfd0_392m_clk", "pll_enet_40m_clk", "pll_video_main_clk",
+       "ref_1m_clk", "pll_audio_main_clk", "ext_clk_1", };
+
+static const char *gpt2_sel[] = { "osc", "pll_enet_100m_clk",
+       "pll_sys_pfd0_392m_clk", "pll_enet_40m_clk", "pll_video_main_clk",
+       "ref_1m_clk", "pll_audio_main_clk", "ext_clk_2", };
+
+static const char *gpt3_sel[] = { "osc", "pll_enet_100m_clk",
+       "pll_sys_pfd0_392m_clk", "pll_enet_40m_clk", "pll_video_main_clk",
+       "ref_1m_clk", "pll_audio_main_clk", "ext_clk_3", };
+
+static const char *gpt4_sel[] = { "osc", "pll_enet_100m_clk",
+       "pll_sys_pfd0_392m_clk", "pll_enet_40m_clk", "pll_video_main_clk",
+       "ref_1m_clk", "pll_audio_main_clk", "ext_clk_4", };
+
+static const char *trace_sel[] = { "osc", "pll_sys_pfd2_135m_clk",
+       "pll_sys_main_120m_clk", "pll_dram_533m_clk",
+       "pll_enet_125m_clk", "pll_usb_main_clk", "ext_clk_2",
+       "ext_clk_3", };
+
+static const char *wdog_sel[] = { "osc", "pll_sys_pfd2_135m_clk",
+       "pll_sys_main_120m_clk", "pll_dram_533m_clk",
+       "pll_enet_125m_clk", "pll_usb_main_clk", "ref_1m_clk",
+       "pll_sys_pfd1_166m_clk", };
+
+static const char *csi_mclk_sel[] = { "osc", "pll_sys_pfd2_135m_clk",
+       "pll_sys_main_120m_clk", "pll_dram_533m_clk",
+       "pll_enet_125m_clk", "pll_audio_main_clk", "pll_video_main_clk",
+       "pll_usb_main_clk", };
+
+static const char *audio_mclk_sel[] = { "osc", "pll_sys_pfd2_135m_clk",
+       "pll_sys_main_120m_clk", "pll_dram_533m_clk",
+       "pll_enet_125m_clk", "pll_audio_main_clk", "pll_video_main_clk",
+       "pll_usb_main_clk", };
+
+static const char *wrclk_sel[] = { "osc", "pll_enet_40m_clk",
+       "pll_dram_533m_clk", "pll_usb_main_clk",
+       "pll_sys_main_240m_clk", "pll_sys_pfd2_270m_clk",
+       "pll_enet_500m_clk", "pll_sys_pfd7_clk", };
+
+static const char *clko1_sel[] = { "osc", "pll_sys_main_clk",
+       "pll_sys_main_240m_clk", "pll_sys_pfd0_196m_clk", "pll_sys_pfd3_clk",
+       "pll_enet_500m_clk", "pll_dram_533m_clk", "ref_1m_clk", };
+
+static const char *clko2_sel[] = { "osc", "pll_sys_main_240m_clk",
+       "pll_sys_pfd0_392m_clk", "pll_sys_pfd1_166m_clk", "pll_sys_pfd4_clk",
+       "pll_audio_main_clk", "pll_video_main_clk", "osc_32k_clk", };
+
+static const char *lvds1_sel[] = { "pll_arm_main_clk",
+       "pll_sys_main_clk", "pll_sys_pfd0_392m_clk", "pll_sys_pfd1_332m_clk",
+       "pll_sys_pfd2_270m_clk", "pll_sys_pfd3_clk", "pll_sys_pfd4_clk",
+       "pll_sys_pfd5_clk", "pll_sys_pfd6_clk", "pll_sys_pfd7_clk",
+       "pll_audio_main_clk", "pll_video_main_clk", "pll_enet_500m_clk",
+       "pll_enet_250m_clk", "pll_enet_125m_clk", "pll_enet_100m_clk",
+       "pll_enet_50m_clk", "pll_enet_40m_clk", "pll_enet_25m_clk",
+       "pll_dram_main_clk", };
+
+static const char *pll_bypass_src_sel[] = { "osc", "dummy", };
+static const char *pll_arm_bypass_sel[] = { "pll_arm_main", "pll_arm_main_src", };
+static const char *pll_dram_bypass_sel[] = { "pll_dram_main", "pll_dram_main_src", };
+static const char *pll_sys_bypass_sel[] = { "pll_sys_main", "pll_sys_main_src", };
+static const char *pll_enet_bypass_sel[] = { "pll_enet_main", "pll_enet_main_src", };
+static const char *pll_audio_bypass_sel[] = { "pll_audio_main", "pll_audio_main_src", };
+static const char *pll_video_bypass_sel[] = { "pll_video_main", "pll_video_main_src", };
+
+static struct clk_onecell_data clk_data;
+
+static void __init imx7d_clocks_init(struct device_node *ccm_node)
+{
+       struct device_node *np;
+       void __iomem *base;
+       int i;
+
+       clks[IMX7D_CLK_DUMMY] = imx_clk_fixed("dummy", 0);
+       clks[IMX7D_OSC_24M_CLK] = of_clk_get_by_name(ccm_node, "osc");
+
+       np = of_find_compatible_node(NULL, NULL, "fsl,imx7d-anatop");
+       base = of_iomap(np, 0);
+       WARN_ON(!base);
+
+       clks[IMX7D_PLL_ARM_MAIN_SRC]  = imx_clk_mux("pll_arm_main_src", base + 0x60, 14, 2, pll_bypass_src_sel, ARRAY_SIZE(pll_bypass_src_sel));
+       clks[IMX7D_PLL_DRAM_MAIN_SRC] = imx_clk_mux("pll_dram_main_src", base + 0x70, 14, 2, pll_bypass_src_sel, ARRAY_SIZE(pll_bypass_src_sel));
+       clks[IMX7D_PLL_SYS_MAIN_SRC]  = imx_clk_mux("pll_sys_main_src", base + 0xb0, 14, 2, pll_bypass_src_sel, ARRAY_SIZE(pll_bypass_src_sel));
+       clks[IMX7D_PLL_ENET_MAIN_SRC] = imx_clk_mux("pll_enet_main_src", base + 0xe0, 14, 2, pll_bypass_src_sel, ARRAY_SIZE(pll_bypass_src_sel));
+       clks[IMX7D_PLL_AUDIO_MAIN_SRC] = imx_clk_mux("pll_audio_main_src", base + 0xf0, 14, 2, pll_bypass_src_sel, ARRAY_SIZE(pll_bypass_src_sel));
+       clks[IMX7D_PLL_VIDEO_MAIN_SRC] = imx_clk_mux("pll_video_main_src", base + 0x130, 14, 2, pll_bypass_src_sel, ARRAY_SIZE(pll_bypass_src_sel));
+
+       clks[IMX7D_PLL_ARM_MAIN]  = imx_clk_pllv3(IMX_PLLV3_SYS, "pll_arm_main", "pll_arm_main_src", base + 0x60, 0x7f);
+       clks[IMX7D_PLL_DRAM_MAIN] = imx_clk_pllv3(IMX_PLLV3_SYS, "pll_dram_main", "pll_dram_main_src", base + 0x70, 0x7f);
+       clks[IMX7D_PLL_SYS_MAIN]  = imx_clk_pllv3(IMX_PLLV3_GENERIC, "pll_sys_main", "pll_sys_main_src", base + 0xb0, 0x1);
+       clks[IMX7D_PLL_ENET_MAIN] = imx_clk_pllv3(IMX_PLLV3_ENET_IMX7, "pll_enet_main", "pll_enet_main_src", base + 0xe0, 0x0);
+       clks[IMX7D_PLL_AUDIO_MAIN] = imx_clk_pllv3(IMX_PLLV3_AV, "pll_audio_main", "pll_audio_main_src", base + 0xf0, 0x7f);
+       clks[IMX7D_PLL_VIDEO_MAIN] = imx_clk_pllv3(IMX_PLLV3_AV, "pll_video_main", "pll_video_main_src", base + 0x130, 0x7f);
+
+       clks[IMX7D_PLL_ARM_MAIN_BYPASS]  = imx_clk_mux_flags("pll_arm_main_bypass", base + 0x60, 16, 1, pll_arm_bypass_sel, ARRAY_SIZE(pll_arm_bypass_sel), CLK_SET_RATE_PARENT);
+       clks[IMX7D_PLL_DRAM_MAIN_BYPASS] = imx_clk_mux_flags("pll_dram_main_bypass", base + 0x70, 16, 1, pll_dram_bypass_sel, ARRAY_SIZE(pll_dram_bypass_sel), CLK_SET_RATE_PARENT);
+       clks[IMX7D_PLL_SYS_MAIN_BYPASS]  = imx_clk_mux_flags("pll_sys_main_bypass", base + 0xb0, 16, 1, pll_sys_bypass_sel, ARRAY_SIZE(pll_sys_bypass_sel), CLK_SET_RATE_PARENT);
+       clks[IMX7D_PLL_ENET_MAIN_BYPASS] = imx_clk_mux_flags("pll_enet_main_bypass", base + 0xe0, 16, 1, pll_enet_bypass_sel, ARRAY_SIZE(pll_enet_bypass_sel), CLK_SET_RATE_PARENT);
+       clks[IMX7D_PLL_AUDIO_MAIN_BYPASS] = imx_clk_mux_flags("pll_audio_main_bypass", base + 0xf0, 16, 1, pll_audio_bypass_sel, ARRAY_SIZE(pll_audio_bypass_sel), CLK_SET_RATE_PARENT);
+       clks[IMX7D_PLL_VIDEO_MAIN_BYPASS] = imx_clk_mux_flags("pll_video_main_bypass", base + 0x130, 16, 1, pll_video_bypass_sel, ARRAY_SIZE(pll_video_bypass_sel), CLK_SET_RATE_PARENT);
+
+       clk_set_parent(clks[IMX7D_PLL_ARM_MAIN_BYPASS], clks[IMX7D_PLL_ARM_MAIN]);
+       clk_set_parent(clks[IMX7D_PLL_DRAM_MAIN_BYPASS], clks[IMX7D_PLL_DRAM_MAIN]);
+       clk_set_parent(clks[IMX7D_PLL_SYS_MAIN_BYPASS], clks[IMX7D_PLL_SYS_MAIN]);
+       clk_set_parent(clks[IMX7D_PLL_ENET_MAIN_BYPASS], clks[IMX7D_PLL_ENET_MAIN]);
+       clk_set_parent(clks[IMX7D_PLL_AUDIO_MAIN_BYPASS], clks[IMX7D_PLL_AUDIO_MAIN]);
+       clk_set_parent(clks[IMX7D_PLL_VIDEO_MAIN_BYPASS], clks[IMX7D_PLL_VIDEO_MAIN]);
+
+       clks[IMX7D_PLL_ARM_MAIN_CLK] = imx_clk_gate("pll_arm_main_clk", "pll_arm_main_bypass", base + 0x60, 13);
+       clks[IMX7D_PLL_DRAM_MAIN_CLK] = imx_clk_gate("pll_dram_main_clk", "pll_dram_main_bypass", base + 0x70, 13);
+       clks[IMX7D_PLL_SYS_MAIN_CLK] = imx_clk_gate("pll_sys_main_clk", "pll_sys_main_bypass", base + 0xb0, 13);
+       clks[IMX7D_PLL_AUDIO_MAIN_CLK] = imx_clk_gate("pll_audio_main_clk", "pll_audio_main_bypass", base + 0xf0, 13);
+       clks[IMX7D_PLL_VIDEO_MAIN_CLK] = imx_clk_gate("pll_video_main_clk", "pll_video_main_bypass", base + 0x130, 13);
+
+       clks[IMX7D_PLL_SYS_PFD0_392M_CLK] = imx_clk_pfd("pll_sys_pfd0_392m_clk", "pll_sys_main_clk", base + 0xc0, 0);
+       clks[IMX7D_PLL_SYS_PFD1_332M_CLK] = imx_clk_pfd("pll_sys_pfd1_332m_clk", "pll_sys_main_clk", base + 0xc0, 1);
+       clks[IMX7D_PLL_SYS_PFD2_270M_CLK] = imx_clk_pfd("pll_sys_pfd2_270m_clk", "pll_sys_main_clk", base + 0xc0, 2);
+
+       clks[IMX7D_PLL_SYS_PFD3_CLK] = imx_clk_pfd("pll_sys_pfd3_clk", "pll_sys_main_clk", base + 0xc0, 3);
+       clks[IMX7D_PLL_SYS_PFD4_CLK] = imx_clk_pfd("pll_sys_pfd4_clk", "pll_sys_main_clk", base + 0xd0, 0);
+       clks[IMX7D_PLL_SYS_PFD5_CLK] = imx_clk_pfd("pll_sys_pfd5_clk", "pll_sys_main_clk", base + 0xd0, 1);
+       clks[IMX7D_PLL_SYS_PFD6_CLK] = imx_clk_pfd("pll_sys_pfd6_clk", "pll_sys_main_clk", base + 0xd0, 2);
+       clks[IMX7D_PLL_SYS_PFD7_CLK] = imx_clk_pfd("pll_sys_pfd7_clk", "pll_sys_main_clk", base + 0xd0, 3);
+
+       clks[IMX7D_PLL_SYS_MAIN_480M] = imx_clk_fixed_factor("pll_sys_main_480m", "pll_sys_main_clk", 1, 1);
+       clks[IMX7D_PLL_SYS_MAIN_240M] = imx_clk_fixed_factor("pll_sys_main_240m", "pll_sys_main_clk", 1, 2);
+       clks[IMX7D_PLL_SYS_MAIN_120M] = imx_clk_fixed_factor("pll_sys_main_120m", "pll_sys_main_clk", 1, 4);
+       clks[IMX7D_PLL_DRAM_MAIN_533M] = imx_clk_fixed_factor("pll_dram_533m", "pll_dram_main_clk", 1, 2);
+
+       clks[IMX7D_PLL_SYS_MAIN_480M_CLK] = imx_clk_gate_dis("pll_sys_main_480m_clk", "pll_sys_main_480m", base + 0xb0, 4);
+       clks[IMX7D_PLL_SYS_MAIN_240M_CLK] = imx_clk_gate_dis("pll_sys_main_240m_clk", "pll_sys_main_240m", base + 0xb0, 5);
+       clks[IMX7D_PLL_SYS_MAIN_120M_CLK] = imx_clk_gate_dis("pll_sys_main_120m_clk", "pll_sys_main_120m", base + 0xb0, 6);
+       clks[IMX7D_PLL_DRAM_MAIN_533M_CLK] = imx_clk_gate("pll_dram_533m_clk", "pll_dram_533m", base + 0x70, 12);
+
+       clks[IMX7D_PLL_SYS_PFD0_196M] = imx_clk_fixed_factor("pll_sys_pfd0_196m", "pll_sys_pfd0_392m_clk", 1, 2);
+       clks[IMX7D_PLL_SYS_PFD1_166M] = imx_clk_fixed_factor("pll_sys_pfd1_166m", "pll_sys_pfd1_332m_clk", 1, 2);
+       clks[IMX7D_PLL_SYS_PFD2_135M] = imx_clk_fixed_factor("pll_sys_pfd2_135m", "pll_sys_pfd2_270m_clk", 1, 2);
+
+       clks[IMX7D_PLL_SYS_PFD0_196M_CLK] = imx_clk_gate_dis("pll_sys_pfd0_196m_clk", "pll_sys_pfd0_196m", base + 0xb0, 26);
+       clks[IMX7D_PLL_SYS_PFD1_166M_CLK] = imx_clk_gate_dis("pll_sys_pfd1_166m_clk", "pll_sys_pfd1_166m", base + 0xb0, 27);
+       clks[IMX7D_PLL_SYS_PFD2_135M_CLK] = imx_clk_gate_dis("pll_sys_pfd2_135m_clk", "pll_sys_pfd2_135m", base + 0xb0, 28);
+
+       clks[IMX7D_PLL_ENET_MAIN_CLK] = imx_clk_fixed_factor("pll_enet_main_clk", "pll_enet_main_bypass", 1, 1);
+       clks[IMX7D_PLL_ENET_MAIN_500M] = imx_clk_fixed_factor("pll_enet_500m", "pll_enet_main_clk", 1, 2);
+       clks[IMX7D_PLL_ENET_MAIN_250M] = imx_clk_fixed_factor("pll_enet_250m", "pll_enet_main_clk", 1, 4);
+       clks[IMX7D_PLL_ENET_MAIN_125M] = imx_clk_fixed_factor("pll_enet_125m", "pll_enet_main_clk", 1, 8);
+       clks[IMX7D_PLL_ENET_MAIN_100M] = imx_clk_fixed_factor("pll_enet_100m", "pll_enet_main_clk", 1, 10);
+       clks[IMX7D_PLL_ENET_MAIN_50M] = imx_clk_fixed_factor("pll_enet_50m", "pll_enet_main_clk", 1, 20);
+       clks[IMX7D_PLL_ENET_MAIN_40M] = imx_clk_fixed_factor("pll_enet_40m", "pll_enet_main_clk", 1, 25);
+       clks[IMX7D_PLL_ENET_MAIN_25M] = imx_clk_fixed_factor("pll_enet_25m", "pll_enet_main_clk", 1, 40);
+
+       clks[IMX7D_PLL_ENET_MAIN_500M_CLK] = imx_clk_gate("pll_enet_500m_clk", "pll_enet_500m", base + 0xe0, 12);
+       clks[IMX7D_PLL_ENET_MAIN_250M_CLK] = imx_clk_gate("pll_enet_250m_clk", "pll_enet_250m", base + 0xe0, 11);
+       clks[IMX7D_PLL_ENET_MAIN_125M_CLK] = imx_clk_gate("pll_enet_125m_clk", "pll_enet_125m", base + 0xe0, 10);
+       clks[IMX7D_PLL_ENET_MAIN_100M_CLK] = imx_clk_gate("pll_enet_100m_clk", "pll_enet_100m", base + 0xe0, 9);
+       clks[IMX7D_PLL_ENET_MAIN_50M_CLK]  = imx_clk_gate("pll_enet_50m_clk", "pll_enet_50m", base + 0xe0, 8);
+       clks[IMX7D_PLL_ENET_MAIN_40M_CLK]  = imx_clk_gate("pll_enet_40m_clk", "pll_enet_40m", base + 0xe0, 7);
+       clks[IMX7D_PLL_ENET_MAIN_25M_CLK]  = imx_clk_gate("pll_enet_25m_clk", "pll_enet_25m", base + 0xe0, 6);
+
+       clks[IMX7D_LVDS1_OUT_SEL] = imx_clk_mux("lvds1_sel", base + 0x170, 0, 5, lvds1_sel, ARRAY_SIZE(lvds1_sel));
+       clks[IMX7D_LVDS1_OUT_CLK] = imx_clk_gate_exclusive("lvds1_out", "lvds1_sel", base + 0x170, 5, BIT(6));
+
+       np = ccm_node;
+       base = of_iomap(np, 0);
+       WARN_ON(!base);
+
+       clks[IMX7D_ARM_A7_ROOT_SRC] = imx_clk_mux("arm_a7_src", base + 0x8000, 24, 3, arm_a7_sel, ARRAY_SIZE(arm_a7_sel));
+       clks[IMX7D_ARM_M4_ROOT_SRC] = imx_clk_mux("arm_m4_src", base + 0x8080, 24, 3, arm_m4_sel, ARRAY_SIZE(arm_m4_sel));
+       clks[IMX7D_ARM_M0_ROOT_SRC] = imx_clk_mux("arm_m0_src", base + 0x8100, 24, 3, arm_m0_sel, ARRAY_SIZE(arm_m0_sel));
+       clks[IMX7D_MAIN_AXI_ROOT_SRC] = imx_clk_mux("axi_src", base + 0x8800, 24, 3, axi_sel, ARRAY_SIZE(axi_sel));
+       clks[IMX7D_DISP_AXI_ROOT_SRC] = imx_clk_mux("disp_axi_src", base + 0x8880, 24, 3, disp_axi_sel, ARRAY_SIZE(disp_axi_sel));
+       clks[IMX7D_ENET_AXI_ROOT_SRC] = imx_clk_mux("enet_axi_src", base + 0x8900, 24, 3, enet_axi_sel, ARRAY_SIZE(enet_axi_sel));
+       clks[IMX7D_NAND_USDHC_BUS_ROOT_SRC] = imx_clk_mux("nand_usdhc_src", base + 0x8980, 24, 3, nand_usdhc_bus_sel, ARRAY_SIZE(nand_usdhc_bus_sel));
+       clks[IMX7D_AHB_CHANNEL_ROOT_SRC] = imx_clk_mux("ahb_src", base + 0x9000, 24, 3, ahb_channel_sel, ARRAY_SIZE(ahb_channel_sel));
+       clks[IMX7D_DRAM_PHYM_ROOT_SRC] = imx_clk_mux("dram_phym_src", base + 0x9800, 24, 1, dram_phym_sel, ARRAY_SIZE(dram_phym_sel));
+       clks[IMX7D_DRAM_ROOT_SRC] = imx_clk_mux("dram_src", base + 0x9880, 24, 1, dram_sel, ARRAY_SIZE(dram_sel));
+       clks[IMX7D_DRAM_PHYM_ALT_ROOT_SRC] = imx_clk_mux("dram_phym_alt_src", base + 0xa000, 24, 3, dram_phym_alt_sel, ARRAY_SIZE(dram_phym_alt_sel));
+       clks[IMX7D_DRAM_ALT_ROOT_SRC]  = imx_clk_mux("dram_alt_src", base + 0xa080, 24, 3, dram_alt_sel, ARRAY_SIZE(dram_alt_sel));
+       clks[IMX7D_USB_HSIC_ROOT_SRC] = imx_clk_mux("usb_hsic_src", base + 0xa100, 24, 3, usb_hsic_sel, ARRAY_SIZE(usb_hsic_sel));
+       clks[IMX7D_PCIE_CTRL_ROOT_SRC] = imx_clk_mux("pcie_ctrl_src", base + 0xa180, 24, 3, pcie_ctrl_sel, ARRAY_SIZE(pcie_ctrl_sel));
+       clks[IMX7D_PCIE_PHY_ROOT_SRC] = imx_clk_mux("pcie_phy_src", base + 0xa200, 24, 3, pcie_phy_sel, ARRAY_SIZE(pcie_phy_sel));
+       clks[IMX7D_EPDC_PIXEL_ROOT_SRC] = imx_clk_mux("epdc_pixel_src", base + 0xa280, 24, 3, epdc_pixel_sel, ARRAY_SIZE(epdc_pixel_sel));
+       clks[IMX7D_LCDIF_PIXEL_ROOT_SRC] = imx_clk_mux("lcdif_pixel_src", base + 0xa300, 24, 3, lcdif_pixel_sel, ARRAY_SIZE(lcdif_pixel_sel));
+       clks[IMX7D_MIPI_DSI_ROOT_SRC] = imx_clk_mux("mipi_dsi_src", base + 0xa380, 24, 3,  mipi_dsi_sel, ARRAY_SIZE(mipi_dsi_sel));
+       clks[IMX7D_MIPI_CSI_ROOT_SRC] = imx_clk_mux("mipi_csi_src", base + 0xa400, 24, 3, mipi_csi_sel, ARRAY_SIZE(mipi_csi_sel));
+       clks[IMX7D_MIPI_DPHY_ROOT_SRC] = imx_clk_mux("mipi_dphy_src", base + 0xa480, 24, 3, mipi_dphy_sel, ARRAY_SIZE(mipi_dphy_sel));
+       clks[IMX7D_SAI1_ROOT_SRC] = imx_clk_mux("sai1_src", base + 0xa500, 24, 3, sai1_sel, ARRAY_SIZE(sai1_sel));
+       clks[IMX7D_SAI2_ROOT_SRC] = imx_clk_mux("sai2_src", base + 0xa580, 24, 3, sai2_sel, ARRAY_SIZE(sai2_sel));
+       clks[IMX7D_SAI3_ROOT_SRC] = imx_clk_mux("sai3_src", base + 0xa600, 24, 3, sai3_sel, ARRAY_SIZE(sai3_sel));
+       clks[IMX7D_SPDIF_ROOT_SRC] = imx_clk_mux("spdif_src", base + 0xa680, 24, 3, spdif_sel, ARRAY_SIZE(spdif_sel));
+       clks[IMX7D_ENET1_REF_ROOT_SRC] = imx_clk_mux("enet1_ref_src", base + 0xa700, 24, 3, enet1_ref_sel, ARRAY_SIZE(enet1_ref_sel));
+       clks[IMX7D_ENET1_TIME_ROOT_SRC] = imx_clk_mux("enet1_time_src", base + 0xa780, 24, 3, enet1_time_sel, ARRAY_SIZE(enet1_time_sel));
+       clks[IMX7D_ENET2_REF_ROOT_SRC] = imx_clk_mux("enet2_ref_src", base + 0xa800, 24, 3, enet2_ref_sel, ARRAY_SIZE(enet2_ref_sel));
+       clks[IMX7D_ENET2_TIME_ROOT_SRC] = imx_clk_mux("enet2_time_src", base + 0xa880, 24, 3, enet2_time_sel, ARRAY_SIZE(enet2_time_sel));
+       clks[IMX7D_ENET_PHY_REF_ROOT_SRC] = imx_clk_mux("enet_phy_ref_src", base + 0xa900, 24, 3, enet_phy_ref_sel, ARRAY_SIZE(enet_phy_ref_sel));
+       clks[IMX7D_EIM_ROOT_SRC] = imx_clk_mux("eim_src", base + 0xa980, 24, 3, eim_sel, ARRAY_SIZE(eim_sel));
+       clks[IMX7D_NAND_ROOT_SRC] = imx_clk_mux("nand_src", base + 0xaa00, 24, 3, nand_sel, ARRAY_SIZE(nand_sel));
+       clks[IMX7D_QSPI_ROOT_SRC] = imx_clk_mux("qspi_src", base + 0xaa80, 24, 3, qspi_sel, ARRAY_SIZE(qspi_sel));
+       clks[IMX7D_USDHC1_ROOT_SRC] = imx_clk_mux("usdhc1_src", base + 0xab00, 24, 3, usdhc1_sel, ARRAY_SIZE(usdhc1_sel));
+       clks[IMX7D_USDHC2_ROOT_SRC] = imx_clk_mux("usdhc2_src", base + 0xab80, 24, 3, usdhc2_sel, ARRAY_SIZE(usdhc2_sel));
+       clks[IMX7D_USDHC3_ROOT_SRC] = imx_clk_mux("usdhc3_src", base + 0xac00, 24, 3, usdhc3_sel, ARRAY_SIZE(usdhc3_sel));
+       clks[IMX7D_CAN1_ROOT_SRC] = imx_clk_mux("can1_src", base + 0xac80, 24, 3, can1_sel, ARRAY_SIZE(can1_sel));
+       clks[IMX7D_CAN2_ROOT_SRC] = imx_clk_mux("can2_src", base + 0xad00, 24, 3, can2_sel, ARRAY_SIZE(can2_sel));
+       clks[IMX7D_I2C1_ROOT_SRC] = imx_clk_mux("i2c1_src", base + 0xad80, 24, 3, i2c1_sel, ARRAY_SIZE(i2c1_sel));
+       clks[IMX7D_I2C2_ROOT_SRC] = imx_clk_mux("i2c2_src", base + 0xae00, 24, 3, i2c2_sel, ARRAY_SIZE(i2c2_sel));
+       clks[IMX7D_I2C3_ROOT_SRC] = imx_clk_mux("i2c3_src", base + 0xae80, 24, 3, i2c3_sel, ARRAY_SIZE(i2c3_sel));
+       clks[IMX7D_I2C4_ROOT_SRC] = imx_clk_mux("i2c4_src", base + 0xaf00, 24, 3, i2c4_sel, ARRAY_SIZE(i2c4_sel));
+       clks[IMX7D_UART1_ROOT_SRC] = imx_clk_mux("uart1_src", base + 0xaf80, 24, 3, uart1_sel, ARRAY_SIZE(uart1_sel));
+       clks[IMX7D_UART2_ROOT_SRC] = imx_clk_mux("uart2_src", base + 0xb000, 24, 3, uart2_sel, ARRAY_SIZE(uart2_sel));
+       clks[IMX7D_UART3_ROOT_SRC] = imx_clk_mux("uart3_src", base + 0xb080, 24, 3, uart3_sel, ARRAY_SIZE(uart3_sel));
+       clks[IMX7D_UART4_ROOT_SRC] = imx_clk_mux("uart4_src", base + 0xb100, 24, 3, uart4_sel, ARRAY_SIZE(uart4_sel));
+       clks[IMX7D_UART5_ROOT_SRC] = imx_clk_mux("uart5_src", base + 0xb180, 24, 3, uart5_sel, ARRAY_SIZE(uart5_sel));
+       clks[IMX7D_UART6_ROOT_SRC] = imx_clk_mux("uart6_src", base + 0xb200, 24, 3, uart6_sel, ARRAY_SIZE(uart6_sel));
+       clks[IMX7D_UART7_ROOT_SRC] = imx_clk_mux("uart7_src", base + 0xb280, 24, 3, uart7_sel, ARRAY_SIZE(uart7_sel));
+       clks[IMX7D_ECSPI1_ROOT_SRC] = imx_clk_mux("ecspi1_src", base + 0xb300, 24, 3, ecspi1_sel, ARRAY_SIZE(ecspi1_sel));
+       clks[IMX7D_ECSPI2_ROOT_SRC] = imx_clk_mux("ecspi2_src", base + 0xb380, 24, 3, ecspi2_sel, ARRAY_SIZE(ecspi2_sel));
+       clks[IMX7D_ECSPI3_ROOT_SRC] = imx_clk_mux("ecspi3_src", base + 0xb400, 24, 3, ecspi3_sel, ARRAY_SIZE(ecspi3_sel));
+       clks[IMX7D_ECSPI4_ROOT_SRC] = imx_clk_mux("ecspi4_src", base + 0xb480, 24, 3, ecspi4_sel, ARRAY_SIZE(ecspi4_sel));
+       clks[IMX7D_PWM1_ROOT_SRC] = imx_clk_mux("pwm1_src", base + 0xb500, 24, 3, pwm1_sel, ARRAY_SIZE(pwm1_sel));
+       clks[IMX7D_PWM2_ROOT_SRC] = imx_clk_mux("pwm2_src", base + 0xb580, 24, 3, pwm2_sel, ARRAY_SIZE(pwm2_sel));
+       clks[IMX7D_PWM3_ROOT_SRC] = imx_clk_mux("pwm3_src", base + 0xb600, 24, 3, pwm3_sel, ARRAY_SIZE(pwm3_sel));
+       clks[IMX7D_PWM4_ROOT_SRC] = imx_clk_mux("pwm4_src", base + 0xb680, 24, 3, pwm4_sel, ARRAY_SIZE(pwm4_sel));
+       clks[IMX7D_FLEXTIMER1_ROOT_SRC] = imx_clk_mux("flextimer1_src", base + 0xb700, 24, 3, flextimer1_sel, ARRAY_SIZE(flextimer1_sel));
+       clks[IMX7D_FLEXTIMER2_ROOT_SRC] = imx_clk_mux("flextimer2_src", base + 0xb780, 24, 3, flextimer2_sel, ARRAY_SIZE(flextimer2_sel));
+       clks[IMX7D_SIM1_ROOT_SRC] = imx_clk_mux("sim1_src", base + 0xb800, 24, 3, sim1_sel, ARRAY_SIZE(sim1_sel));
+       clks[IMX7D_SIM2_ROOT_SRC] = imx_clk_mux("sim2_src", base + 0xb880, 24, 3, sim2_sel, ARRAY_SIZE(sim2_sel));
+       clks[IMX7D_GPT1_ROOT_SRC] = imx_clk_mux("gpt1_src", base + 0xb900, 24, 3, gpt1_sel, ARRAY_SIZE(gpt1_sel));
+       clks[IMX7D_GPT2_ROOT_SRC] = imx_clk_mux("gpt2_src", base + 0xb980, 24, 3, gpt2_sel, ARRAY_SIZE(gpt2_sel));
+       clks[IMX7D_GPT3_ROOT_SRC] = imx_clk_mux("gpt3_src", base + 0xba00, 24, 3, gpt3_sel, ARRAY_SIZE(gpt3_sel));
+       clks[IMX7D_GPT4_ROOT_SRC] = imx_clk_mux("gpt4_src", base + 0xba80, 24, 3, gpt4_sel, ARRAY_SIZE(gpt4_sel));
+       clks[IMX7D_TRACE_ROOT_SRC] = imx_clk_mux("trace_src", base + 0xbb00, 24, 3, trace_sel, ARRAY_SIZE(trace_sel));
+       clks[IMX7D_WDOG_ROOT_SRC] = imx_clk_mux("wdog_src", base + 0xbb80, 24, 3, wdog_sel, ARRAY_SIZE(wdog_sel));
+       clks[IMX7D_CSI_MCLK_ROOT_SRC] = imx_clk_mux("csi_mclk_src", base + 0xbc00, 24, 3, csi_mclk_sel, ARRAY_SIZE(csi_mclk_sel));
+       clks[IMX7D_AUDIO_MCLK_ROOT_SRC] = imx_clk_mux("audio_mclk_src", base + 0xbc80, 24, 3, audio_mclk_sel, ARRAY_SIZE(audio_mclk_sel));
+       clks[IMX7D_WRCLK_ROOT_SRC] = imx_clk_mux("wrclk_src", base + 0xbd00, 24, 3, wrclk_sel, ARRAY_SIZE(wrclk_sel));
+       clks[IMX7D_CLKO1_ROOT_SRC] = imx_clk_mux("clko1_src", base + 0xbd80, 24, 3, clko1_sel, ARRAY_SIZE(clko1_sel));
+       clks[IMX7D_CLKO2_ROOT_SRC] = imx_clk_mux("clko2_src", base + 0xbe00, 24, 3, clko2_sel, ARRAY_SIZE(clko2_sel));
+
+       clks[IMX7D_ARM_A7_ROOT_CG] = imx_clk_gate("arm_a7_cg", "arm_a7_src", base + 0x8000, 28);
+       clks[IMX7D_ARM_M4_ROOT_CG] = imx_clk_gate("arm_m4_cg", "arm_m4_src", base + 0x8080, 28);
+       clks[IMX7D_ARM_M0_ROOT_CG] = imx_clk_gate("arm_m0_cg", "arm_m0_src", base + 0x8100, 28);
+       clks[IMX7D_MAIN_AXI_ROOT_CG] = imx_clk_gate("axi_cg", "axi_src", base + 0x8800, 28);
+       clks[IMX7D_DISP_AXI_ROOT_CG] = imx_clk_gate("disp_axi_cg", "disp_axi_src", base + 0x8880, 28);
+       clks[IMX7D_ENET_AXI_ROOT_CG] = imx_clk_gate("enet_axi_cg", "enet_axi_src", base + 0x8900, 28);
+       clks[IMX7D_NAND_USDHC_BUS_ROOT_CG] = imx_clk_gate("nand_usdhc_cg", "nand_usdhc_src", base + 0x8980, 28);
+       clks[IMX7D_AHB_CHANNEL_ROOT_CG] = imx_clk_gate("ahb_cg", "ahb_src", base + 0x9000, 28);
+       clks[IMX7D_DRAM_PHYM_ROOT_CG] = imx_clk_gate("dram_phym_cg", "dram_phym_src", base + 0x9800, 28);
+       clks[IMX7D_DRAM_ROOT_CG] = imx_clk_gate("dram_cg", "dram_src", base + 0x9880, 28);
+       clks[IMX7D_DRAM_PHYM_ALT_ROOT_CG] = imx_clk_gate("dram_phym_alt_cg", "dram_phym_alt_src", base + 0xa000, 28);
+       clks[IMX7D_DRAM_ALT_ROOT_CG] = imx_clk_gate("dram_alt_cg", "dram_alt_src", base + 0xa080, 28);
+       clks[IMX7D_USB_HSIC_ROOT_CG] = imx_clk_gate("usb_hsic_cg", "usb_hsic_src", base + 0xa100, 28);
+       clks[IMX7D_PCIE_CTRL_ROOT_CG] = imx_clk_gate("pcie_ctrl_cg", "pcie_ctrl_src", base + 0xa180, 28);
+       clks[IMX7D_PCIE_PHY_ROOT_CG] = imx_clk_gate("pcie_phy_cg", "pcie_phy_src", base + 0xa200, 28);
+       clks[IMX7D_EPDC_PIXEL_ROOT_CG] = imx_clk_gate("epdc_pixel_cg", "epdc_pixel_src", base + 0xa280, 28);
+       clks[IMX7D_LCDIF_PIXEL_ROOT_CG] = imx_clk_gate("lcdif_pixel_cg", "lcdif_pixel_src", base + 0xa300, 28);
+       clks[IMX7D_MIPI_DSI_ROOT_CG] = imx_clk_gate("mipi_dsi_cg", "mipi_dsi_src", base + 0xa380, 28);
+       clks[IMX7D_MIPI_CSI_ROOT_CG] = imx_clk_gate("mipi_csi_cg", "mipi_csi_src", base + 0xa400, 28);
+       clks[IMX7D_MIPI_DPHY_ROOT_CG] = imx_clk_gate("mipi_dphy_cg", "mipi_dphy_src", base + 0xa480, 28);
+       clks[IMX7D_SAI1_ROOT_CG] = imx_clk_gate("sai1_cg", "sai1_src", base + 0xa500, 28);
+       clks[IMX7D_SAI2_ROOT_CG] = imx_clk_gate("sai2_cg", "sai2_src", base + 0xa580, 28);
+       clks[IMX7D_SAI3_ROOT_CG] = imx_clk_gate("sai3_cg", "sai3_src", base + 0xa600, 28);
+       clks[IMX7D_SPDIF_ROOT_CG] = imx_clk_gate("spdif_cg", "spdif_src", base + 0xa680, 28);
+       clks[IMX7D_ENET1_REF_ROOT_CG] = imx_clk_gate("enet1_ref_cg", "enet1_ref_src", base + 0xa700, 28);
+       clks[IMX7D_ENET1_TIME_ROOT_CG] = imx_clk_gate("enet1_time_cg", "enet1_time_src", base + 0xa780, 28);
+       clks[IMX7D_ENET2_REF_ROOT_CG] = imx_clk_gate("enet2_ref_cg", "enet2_ref_src", base + 0xa800, 28);
+       clks[IMX7D_ENET2_TIME_ROOT_CG] = imx_clk_gate("enet2_time_cg", "enet2_time_src", base + 0xa880, 28);
+       clks[IMX7D_ENET_PHY_REF_ROOT_CG] = imx_clk_gate("enet_phy_ref_cg", "enet_phy_ref_src", base + 0xa900, 28);
+       clks[IMX7D_EIM_ROOT_CG] = imx_clk_gate("eim_cg", "eim_src", base + 0xa980, 28);
+       clks[IMX7D_NAND_ROOT_CG] = imx_clk_gate("nand_cg", "nand_src", base + 0xaa00, 28);
+       clks[IMX7D_QSPI_ROOT_CG] = imx_clk_gate("qspi_cg", "qspi_src", base + 0xaa80, 28);
+       clks[IMX7D_USDHC1_ROOT_CG] = imx_clk_gate("usdhc1_cg", "usdhc1_src", base + 0xab00, 28);
+       clks[IMX7D_USDHC2_ROOT_CG] = imx_clk_gate("usdhc2_cg", "usdhc2_src", base + 0xab80, 28);
+       clks[IMX7D_USDHC3_ROOT_CG] = imx_clk_gate("usdhc3_cg", "usdhc3_src", base + 0xac00, 28);
+       clks[IMX7D_CAN1_ROOT_CG] = imx_clk_gate("can1_cg", "can1_src", base + 0xac80, 28);
+       clks[IMX7D_CAN2_ROOT_CG] = imx_clk_gate("can2_cg", "can2_src", base + 0xad00, 28);
+       clks[IMX7D_I2C1_ROOT_CG] = imx_clk_gate("i2c1_cg", "i2c1_src", base + 0xad80, 28);
+       clks[IMX7D_I2C2_ROOT_CG] = imx_clk_gate("i2c2_cg", "i2c2_src", base + 0xae00, 28);
+       clks[IMX7D_I2C3_ROOT_CG] = imx_clk_gate("i2c3_cg", "i2c3_src", base + 0xae80, 28);
+       clks[IMX7D_I2C4_ROOT_CG] = imx_clk_gate("i2c4_cg", "i2c4_src", base + 0xaf00, 28);
+       clks[IMX7D_UART1_ROOT_CG] = imx_clk_gate("uart1_cg", "uart1_src", base + 0xaf80, 28);
+       clks[IMX7D_UART2_ROOT_CG] = imx_clk_gate("uart2_cg", "uart2_src", base + 0xb000, 28);
+       clks[IMX7D_UART3_ROOT_CG] = imx_clk_gate("uart3_cg", "uart3_src", base + 0xb080, 28);
+       clks[IMX7D_UART4_ROOT_CG] = imx_clk_gate("uart4_cg", "uart4_src", base + 0xb100, 28);
+       clks[IMX7D_UART5_ROOT_CG] = imx_clk_gate("uart5_cg", "uart5_src", base + 0xb180, 28);
+       clks[IMX7D_UART6_ROOT_CG] = imx_clk_gate("uart6_cg", "uart6_src", base + 0xb200, 28);
+       clks[IMX7D_UART7_ROOT_CG] = imx_clk_gate("uart7_cg", "uart7_src", base + 0xb280, 28);
+       clks[IMX7D_ECSPI1_ROOT_CG] = imx_clk_gate("ecspi1_cg", "ecspi1_src", base + 0xb300, 28);
+       clks[IMX7D_ECSPI2_ROOT_CG] = imx_clk_gate("ecspi2_cg", "ecspi2_src", base + 0xb380, 28);
+       clks[IMX7D_ECSPI3_ROOT_CG] = imx_clk_gate("ecspi3_cg", "ecspi3_src", base + 0xb400, 28);
+       clks[IMX7D_ECSPI4_ROOT_CG] = imx_clk_gate("ecspi4_cg", "ecspi4_src", base + 0xb480, 28);
+       clks[IMX7D_PWM1_ROOT_CG] = imx_clk_gate("pwm1_cg", "pwm1_src", base + 0xb500, 28);
+       clks[IMX7D_PWM2_ROOT_CG] = imx_clk_gate("pwm2_cg", "pwm2_src", base + 0xb580, 28);
+       clks[IMX7D_PWM3_ROOT_CG] = imx_clk_gate("pwm3_cg", "pwm3_src", base + 0xb600, 28);
+       clks[IMX7D_PWM4_ROOT_CG] = imx_clk_gate("pwm4_cg", "pwm4_src", base + 0xb680, 28);
+       clks[IMX7D_FLEXTIMER1_ROOT_CG] = imx_clk_gate("flextimer1_cg", "flextimer1_src", base + 0xb700, 28);
+       clks[IMX7D_FLEXTIMER2_ROOT_CG] = imx_clk_gate("flextimer2_cg", "flextimer2_src", base + 0xb780, 28);
+       clks[IMX7D_SIM1_ROOT_CG] = imx_clk_gate("sim1_cg", "sim1_src", base + 0xb800, 28);
+       clks[IMX7D_SIM2_ROOT_CG] = imx_clk_gate("sim2_cg", "sim2_src", base + 0xb880, 28);
+       clks[IMX7D_GPT1_ROOT_CG] = imx_clk_gate("gpt1_cg", "gpt1_src", base + 0xb900, 28);
+       clks[IMX7D_GPT2_ROOT_CG] = imx_clk_gate("gpt2_cg", "gpt2_src", base + 0xb980, 28);
+       clks[IMX7D_GPT3_ROOT_CG] = imx_clk_gate("gpt3_cg", "gpt3_src", base + 0xbA00, 28);
+       clks[IMX7D_GPT4_ROOT_CG] = imx_clk_gate("gpt4_cg", "gpt4_src", base + 0xbA80, 28);
+       clks[IMX7D_TRACE_ROOT_CG] = imx_clk_gate("trace_cg", "trace_src", base + 0xbb00, 28);
+       clks[IMX7D_WDOG_ROOT_CG] = imx_clk_gate("wdog_cg", "wdog_src", base + 0xbb80, 28);
+       clks[IMX7D_CSI_MCLK_ROOT_CG] = imx_clk_gate("csi_mclk_cg", "csi_mclk_src", base + 0xbc00, 28);
+       clks[IMX7D_AUDIO_MCLK_ROOT_CG] = imx_clk_gate("audio_mclk_cg", "audio_mclk_src", base + 0xbc80, 28);
+       clks[IMX7D_WRCLK_ROOT_CG] = imx_clk_gate("wrclk_cg", "wrclk_src", base + 0xbd00, 28);
+       clks[IMX7D_CLKO1_ROOT_CG] = imx_clk_gate("clko1_cg", "clko1_src", base + 0xbd80, 28);
+       clks[IMX7D_CLKO2_ROOT_CG] = imx_clk_gate("clko2_cg", "clko2_src", base + 0xbe00, 28);
+
+       clks[IMX7D_MAIN_AXI_ROOT_PRE_DIV] = imx_clk_divider("axi_pre_div", "axi_cg", base + 0x8800, 16, 3);
+       clks[IMX7D_DISP_AXI_ROOT_PRE_DIV] = imx_clk_divider("disp_axi_pre_div", "disp_axi_cg", base + 0x8880, 16, 3);
+       clks[IMX7D_ENET_AXI_ROOT_PRE_DIV] = imx_clk_divider("enet_axi_pre_div", "enet_axi_cg", base + 0x8900, 16, 3);
+       clks[IMX7D_NAND_USDHC_BUS_ROOT_PRE_DIV] = imx_clk_divider("nand_usdhc_pre_div", "nand_usdhc_cg", base + 0x8980, 16, 3);
+       clks[IMX7D_AHB_CHANNEL_ROOT_PRE_DIV] = imx_clk_divider("ahb_pre_div", "ahb_cg", base + 0x9000, 16, 3);
+       clks[IMX7D_DRAM_PHYM_ALT_ROOT_PRE_DIV] = imx_clk_divider("dram_phym_alt_pre_div", "dram_phym_alt_cg", base + 0xa000, 16, 3);
+       clks[IMX7D_DRAM_ALT_ROOT_PRE_DIV] = imx_clk_divider("dram_alt_pre_div", "dram_alt_cg", base + 0xa080, 16, 3);
+       clks[IMX7D_USB_HSIC_ROOT_PRE_DIV] = imx_clk_divider("usb_hsic_pre_div", "usb_hsic_cg", base + 0xa100, 16, 3);
+       clks[IMX7D_PCIE_CTRL_ROOT_PRE_DIV] = imx_clk_divider("pcie_ctrl_pre_div", "pcie_ctrl_cg", base + 0xa180, 16, 3);
+       clks[IMX7D_PCIE_PHY_ROOT_PRE_DIV] = imx_clk_divider("pcie_phy_pre_div", "pcie_phy_cg", base + 0xa200, 16, 3);
+       clks[IMX7D_EPDC_PIXEL_ROOT_PRE_DIV] = imx_clk_divider("epdc_pixel_pre_div", "epdc_pixel_cg", base + 0xa280, 16, 3);
+       clks[IMX7D_LCDIF_PIXEL_ROOT_PRE_DIV] = imx_clk_divider("lcdif_pixel_pre_div", "lcdif_pixel_cg", base + 0xa300, 16, 3);
+       clks[IMX7D_MIPI_DSI_ROOT_PRE_DIV] = imx_clk_divider("mipi_dsi_pre_div", "mipi_dsi_cg", base + 0xa380, 16, 3);
+       clks[IMX7D_MIPI_CSI_ROOT_PRE_DIV] = imx_clk_divider("mipi_csi_pre_div", "mipi_csi_cg", base + 0xa400, 16, 3);
+       clks[IMX7D_MIPI_DPHY_ROOT_PRE_DIV] = imx_clk_divider("mipi_dphy_pre_div", "mipi_dphy_cg", base + 0xa480, 16, 3);
+       clks[IMX7D_SAI1_ROOT_PRE_DIV] = imx_clk_divider("sai1_pre_div", "sai1_cg", base + 0xa500, 16, 3);
+       clks[IMX7D_SAI2_ROOT_PRE_DIV] = imx_clk_divider("sai2_pre_div", "sai2_cg", base + 0xa580, 16, 3);
+       clks[IMX7D_SAI3_ROOT_PRE_DIV] = imx_clk_divider("sai3_pre_div", "sai3_cg", base + 0xa600, 16, 3);
+       clks[IMX7D_SPDIF_ROOT_PRE_DIV] = imx_clk_divider("spdif_pre_div", "spdif_cg", base + 0xa680, 16, 3);
+       clks[IMX7D_ENET1_REF_ROOT_PRE_DIV] = imx_clk_divider("enet1_ref_pre_div", "enet1_ref_cg", base + 0xa700, 16, 3);
+       clks[IMX7D_ENET1_TIME_ROOT_PRE_DIV] = imx_clk_divider("enet1_time_pre_div", "enet1_time_cg", base + 0xa780, 16, 3);
+       clks[IMX7D_ENET2_REF_ROOT_PRE_DIV] = imx_clk_divider("enet2_ref_pre_div", "enet2_ref_cg", base + 0xa800, 16, 3);
+       clks[IMX7D_ENET2_TIME_ROOT_PRE_DIV] = imx_clk_divider("enet2_time_pre_div", "enet2_time_cg", base + 0xa880, 16, 3);
+       clks[IMX7D_ENET_PHY_REF_ROOT_PRE_DIV] = imx_clk_divider("enet_phy_ref_pre_div", "enet_phy_ref_cg", base + 0xa900, 16, 3);
+       clks[IMX7D_EIM_ROOT_PRE_DIV] = imx_clk_divider("eim_pre_div", "eim_cg", base + 0xa980, 16, 3);
+       clks[IMX7D_NAND_ROOT_PRE_DIV] = imx_clk_divider("nand_pre_div", "nand_cg", base + 0xaa00, 16, 3);
+       clks[IMX7D_QSPI_ROOT_PRE_DIV] = imx_clk_divider("qspi_pre_div", "qspi_cg", base + 0xaa80, 16, 3);
+       clks[IMX7D_USDHC1_ROOT_PRE_DIV] = imx_clk_divider("usdhc1_pre_div", "usdhc1_cg", base + 0xab00, 16, 3);
+       clks[IMX7D_USDHC2_ROOT_PRE_DIV] = imx_clk_divider("usdhc2_pre_div", "usdhc2_cg", base + 0xab80, 16, 3);
+       clks[IMX7D_USDHC3_ROOT_PRE_DIV] = imx_clk_divider("usdhc3_pre_div", "usdhc3_cg", base + 0xac00, 16, 3);
+       clks[IMX7D_CAN1_ROOT_PRE_DIV] = imx_clk_divider("can1_pre_div", "can1_cg", base + 0xac80, 16, 3);
+       clks[IMX7D_CAN2_ROOT_PRE_DIV] = imx_clk_divider("can2_pre_div", "can2_cg", base + 0xad00, 16, 3);
+       clks[IMX7D_I2C1_ROOT_PRE_DIV] = imx_clk_divider("i2c1_pre_div", "i2c1_cg", base + 0xad80, 16, 3);
+       clks[IMX7D_I2C2_ROOT_PRE_DIV] = imx_clk_divider("i2c2_pre_div", "i2c2_cg", base + 0xae00, 16, 3);
+       clks[IMX7D_I2C3_ROOT_PRE_DIV] = imx_clk_divider("i2c3_pre_div", "i2c3_cg", base + 0xae80, 16, 3);
+       clks[IMX7D_I2C4_ROOT_PRE_DIV] = imx_clk_divider("i2c4_pre_div", "i2c4_cg", base + 0xaf00, 16, 3);
+       clks[IMX7D_UART1_ROOT_PRE_DIV] = imx_clk_divider("uart1_pre_div", "uart1_cg", base + 0xaf80, 16, 3);
+       clks[IMX7D_UART2_ROOT_PRE_DIV] = imx_clk_divider("uart2_pre_div", "uart2_cg", base + 0xb000, 16, 3);
+       clks[IMX7D_UART3_ROOT_PRE_DIV] = imx_clk_divider("uart3_pre_div", "uart3_cg", base + 0xb080, 16, 3);
+       clks[IMX7D_UART4_ROOT_PRE_DIV] = imx_clk_divider("uart4_pre_div", "uart4_cg", base + 0xb100, 16, 3);
+       clks[IMX7D_UART5_ROOT_PRE_DIV] = imx_clk_divider("uart5_pre_div", "uart5_cg", base + 0xb180, 16, 3);
+       clks[IMX7D_UART6_ROOT_PRE_DIV] = imx_clk_divider("uart6_pre_div", "uart6_cg", base + 0xb200, 16, 3);
+       clks[IMX7D_UART7_ROOT_PRE_DIV] = imx_clk_divider("uart7_pre_div", "uart7_cg", base + 0xb280, 16, 3);
+       clks[IMX7D_ECSPI1_ROOT_PRE_DIV] = imx_clk_divider("ecspi1_pre_div", "ecspi1_cg", base + 0xb300, 16, 3);
+       clks[IMX7D_ECSPI2_ROOT_PRE_DIV] = imx_clk_divider("ecspi2_pre_div", "ecspi2_cg", base + 0xb380, 16, 3);
+       clks[IMX7D_ECSPI3_ROOT_PRE_DIV] = imx_clk_divider("ecspi3_pre_div", "ecspi3_cg", base + 0xb400, 16, 3);
+       clks[IMX7D_ECSPI4_ROOT_PRE_DIV] = imx_clk_divider("ecspi4_pre_div", "ecspi4_cg", base + 0xb480, 16, 3);
+       clks[IMX7D_PWM1_ROOT_PRE_DIV] = imx_clk_divider("pwm1_pre_div", "pwm1_cg", base + 0xb500, 16, 3);
+       clks[IMX7D_PWM2_ROOT_PRE_DIV] = imx_clk_divider("pwm2_pre_div", "pwm2_cg", base + 0xb580, 16, 3);
+       clks[IMX7D_PWM3_ROOT_PRE_DIV] = imx_clk_divider("pwm3_pre_div", "pwm3_cg", base + 0xb600, 16, 3);
+       clks[IMX7D_PWM4_ROOT_PRE_DIV] = imx_clk_divider("pwm4_pre_div", "pwm4_cg", base + 0xb680, 16, 3);
+       clks[IMX7D_FLEXTIMER1_ROOT_PRE_DIV] = imx_clk_divider("flextimer1_pre_div", "flextimer1_cg", base + 0xb700, 16, 3);
+       clks[IMX7D_FLEXTIMER2_ROOT_PRE_DIV] = imx_clk_divider("flextimer2_pre_div", "flextimer2_cg", base + 0xb780, 16, 3);
+       clks[IMX7D_SIM1_ROOT_PRE_DIV] = imx_clk_divider("sim1_pre_div", "sim1_cg", base + 0xb800, 16, 3);
+       clks[IMX7D_SIM2_ROOT_PRE_DIV] = imx_clk_divider("sim2_pre_div", "sim2_cg", base + 0xb880, 16, 3);
+       clks[IMX7D_GPT1_ROOT_PRE_DIV] = imx_clk_divider("gpt1_pre_div", "gpt1_cg", base + 0xb900, 16, 3);
+       clks[IMX7D_GPT2_ROOT_PRE_DIV] = imx_clk_divider("gpt2_pre_div", "gpt2_cg", base + 0xb980, 16, 3);
+       clks[IMX7D_GPT3_ROOT_PRE_DIV] = imx_clk_divider("gpt3_pre_div", "gpt3_cg", base + 0xba00, 16, 3);
+       clks[IMX7D_GPT4_ROOT_PRE_DIV] = imx_clk_divider("gpt4_pre_div", "gpt4_cg", base + 0xba80, 16, 3);
+       clks[IMX7D_TRACE_ROOT_PRE_DIV] = imx_clk_divider("trace_pre_div", "trace_cg", base + 0xbb00, 16, 3);
+       clks[IMX7D_WDOG_ROOT_PRE_DIV] = imx_clk_divider("wdog_pre_div", "wdog_cg", base + 0xbb80, 16, 3);
+       clks[IMX7D_CSI_MCLK_ROOT_PRE_DIV] = imx_clk_divider("csi_mclk_pre_div", "csi_mclk_cg", base + 0xbc00, 16, 3);
+       clks[IMX7D_AUDIO_MCLK_ROOT_PRE_DIV] = imx_clk_divider("audio_mclk_pre_div", "audio_mclk_cg", base + 0xbc80, 16, 3);
+       clks[IMX7D_WRCLK_ROOT_PRE_DIV] = imx_clk_divider("wrclk_pre_div", "wrclk_cg", base + 0xbd00, 16, 3);
+       clks[IMX7D_CLKO1_ROOT_PRE_DIV] = imx_clk_divider("clko1_pre_div", "clko1_cg", base + 0xbd80, 16, 3);
+       clks[IMX7D_CLKO2_ROOT_PRE_DIV] = imx_clk_divider("clko2_pre_div", "clko2_cg", base + 0xbe00, 16, 3);
+
+       clks[IMX7D_ARM_A7_ROOT_DIV] = imx_clk_divider("arm_a7_div", "arm_a7_cg", base + 0x8000, 0, 3);
+       clks[IMX7D_ARM_M4_ROOT_DIV] = imx_clk_divider("arm_m4_div", "arm_m4_cg", base + 0x8080, 0, 3);
+       clks[IMX7D_ARM_M0_ROOT_DIV] = imx_clk_divider("arm_m0_div", "arm_m0_cg", base + 0x8100, 0, 3);
+       clks[IMX7D_MAIN_AXI_ROOT_DIV] = imx_clk_divider("axi_post_div", "axi_pre_div", base + 0x8800, 0, 6);
+       clks[IMX7D_DISP_AXI_ROOT_DIV] = imx_clk_divider("disp_axi_post_div", "disp_axi_pre_div", base + 0x8880, 0, 6);
+       clks[IMX7D_ENET_AXI_ROOT_DIV] = imx_clk_divider("enet_axi_post_div", "enet_axi_pre_div", base + 0x8900, 0, 6);
+       clks[IMX7D_NAND_USDHC_BUS_ROOT_DIV] = imx_clk_divider("nand_usdhc_post_div", "nand_usdhc_pre_div", base + 0x8980, 0, 6);
+       clks[IMX7D_AHB_CHANNEL_ROOT_DIV] = imx_clk_divider("ahb_post_div", "ahb_pre_div", base + 0x9000, 0, 6);
+       clks[IMX7D_DRAM_ROOT_DIV] = imx_clk_divider("dram_post_div", "dram_cg", base + 0x9880, 0, 3);
+       clks[IMX7D_DRAM_PHYM_ALT_ROOT_DIV] = imx_clk_divider("dram_phym_alt_post_div", "dram_phym_alt_pre_div", base + 0xa000, 0, 3);
+       clks[IMX7D_DRAM_ALT_ROOT_DIV] = imx_clk_divider("dram_alt_post_div", "dram_alt_pre_div", base + 0xa080, 0, 3);
+       clks[IMX7D_USB_HSIC_ROOT_DIV] = imx_clk_divider("usb_hsic_post_div", "usb_hsic_pre_div", base + 0xa100, 0, 6);
+       clks[IMX7D_PCIE_CTRL_ROOT_DIV] = imx_clk_divider("pcie_ctrl_post_div", "pcie_ctrl_pre_div", base + 0xa180, 0, 6);
+       clks[IMX7D_PCIE_PHY_ROOT_DIV] = imx_clk_divider("pcie_phy_post_div", "pcie_phy_pre_div", base + 0xa200, 0, 6);
+       clks[IMX7D_EPDC_PIXEL_ROOT_DIV] = imx_clk_divider("epdc_pixel_post_div", "epdc_pixel_pre_div", base + 0xa280, 0, 6);
+       clks[IMX7D_LCDIF_PIXEL_ROOT_DIV] = imx_clk_divider("lcdif_pixel_post_div", "lcdif_pixel_pre_div", base + 0xa300, 0, 6);
+       clks[IMX7D_MIPI_DSI_ROOT_DIV] = imx_clk_divider("mipi_dsi_post_div", "mipi_dsi_pre_div", base + 0xa380, 0, 6);
+       clks[IMX7D_MIPI_CSI_ROOT_DIV] = imx_clk_divider("mipi_csi_post_div", "mipi_csi_pre_div", base + 0xa400, 0, 6);
+       clks[IMX7D_MIPI_DPHY_ROOT_DIV] = imx_clk_divider("mipi_dphy_post_div", "mipi_csi_dphy_div", base + 0xa480, 0, 6);
+       clks[IMX7D_SAI1_ROOT_DIV] = imx_clk_divider("sai1_post_div", "sai1_pre_div", base + 0xa500, 0, 6);
+       clks[IMX7D_SAI2_ROOT_DIV] = imx_clk_divider("sai2_post_div", "sai2_pre_div", base + 0xa580, 0, 6);
+       clks[IMX7D_SAI3_ROOT_DIV] = imx_clk_divider("sai3_post_div", "sai3_pre_div", base + 0xa600, 0, 6);
+       clks[IMX7D_SPDIF_ROOT_DIV] = imx_clk_divider("spdif_post_div", "spdif_pre_div", base + 0xa680, 0, 6);
+       clks[IMX7D_ENET1_REF_ROOT_DIV] = imx_clk_divider("enet1_ref_post_div", "enet1_ref_pre_div", base + 0xa700, 0, 6);
+       clks[IMX7D_ENET1_TIME_ROOT_DIV] = imx_clk_divider("enet1_time_post_div", "enet1_time_pre_div", base + 0xa780, 0, 6);
+       clks[IMX7D_ENET2_REF_ROOT_DIV] = imx_clk_divider("enet2_ref_post_div", "enet2_ref_pre_div", base + 0xa800, 0, 6);
+       clks[IMX7D_ENET2_TIME_ROOT_DIV] = imx_clk_divider("enet2_time_post_div", "enet2_time_pre_div", base + 0xa880, 0, 6);
+       clks[IMX7D_ENET_PHY_REF_ROOT_DIV] = imx_clk_divider("enet_phy_ref_post_div", "enet_phy_ref_pre_div", base + 0xa900, 0, 6);
+       clks[IMX7D_EIM_ROOT_DIV] = imx_clk_divider("eim_post_div", "eim_pre_div", base + 0xa980, 0, 6);
+       clks[IMX7D_NAND_ROOT_DIV] = imx_clk_divider("nand_post_div", "nand_pre_div", base + 0xaa00, 0, 6);
+       clks[IMX7D_QSPI_ROOT_DIV] = imx_clk_divider("qspi_post_div", "qspi_pre_div", base + 0xaa80, 0, 6);
+       clks[IMX7D_USDHC1_ROOT_DIV] = imx_clk_divider("usdhc1_post_div", "usdhc1_pre_div", base + 0xab00, 0, 6);
+       clks[IMX7D_USDHC2_ROOT_DIV] = imx_clk_divider("usdhc2_post_div", "usdhc2_pre_div", base + 0xab80, 0, 6);
+       clks[IMX7D_USDHC3_ROOT_DIV] = imx_clk_divider("usdhc3_post_div", "usdhc3_pre_div", base + 0xac00, 0, 6);
+       clks[IMX7D_CAN1_ROOT_DIV] = imx_clk_divider("can1_post_div", "can1_pre_div", base + 0xac80, 0, 6);
+       clks[IMX7D_CAN2_ROOT_DIV] = imx_clk_divider("can2_post_div", "can2_pre_div", base + 0xad00, 0, 6);
+       clks[IMX7D_I2C1_ROOT_DIV] = imx_clk_divider("i2c1_post_div", "i2c1_pre_div", base + 0xad80, 0, 6);
+       clks[IMX7D_I2C2_ROOT_DIV] = imx_clk_divider("i2c2_post_div", "i2c2_pre_div", base + 0xae00, 0, 6);
+       clks[IMX7D_I2C3_ROOT_DIV] = imx_clk_divider("i2c3_post_div", "i2c3_pre_div", base + 0xae80, 0, 6);
+       clks[IMX7D_I2C4_ROOT_DIV] = imx_clk_divider("i2c4_post_div", "i2c4_pre_div", base + 0xaf00, 0, 6);
+       clks[IMX7D_UART1_ROOT_DIV] = imx_clk_divider("uart1_post_div", "uart1_pre_div", base + 0xaf80, 0, 6);
+       clks[IMX7D_UART2_ROOT_DIV] = imx_clk_divider("uart2_post_div", "uart2_pre_div", base + 0xb000, 0, 6);
+       clks[IMX7D_UART3_ROOT_DIV] = imx_clk_divider("uart3_post_div", "uart3_pre_div", base + 0xb080, 0, 6);
+       clks[IMX7D_UART4_ROOT_DIV] = imx_clk_divider("uart4_post_div", "uart4_pre_div", base + 0xb100, 0, 6);
+       clks[IMX7D_UART5_ROOT_DIV] = imx_clk_divider("uart5_post_div", "uart5_pre_div", base + 0xb180, 0, 6);
+       clks[IMX7D_UART6_ROOT_DIV] = imx_clk_divider("uart6_post_div", "uart6_pre_div", base + 0xb200, 0, 6);
+       clks[IMX7D_UART7_ROOT_DIV] = imx_clk_divider("uart7_post_div", "uart7_pre_div", base + 0xb280, 0, 6);
+       clks[IMX7D_ECSPI1_ROOT_DIV] = imx_clk_divider("ecspi1_post_div", "ecspi1_pre_div", base + 0xb300, 0, 6);
+       clks[IMX7D_ECSPI2_ROOT_DIV] = imx_clk_divider("ecspi2_post_div", "ecspi2_pre_div", base + 0xb380, 0, 6);
+       clks[IMX7D_ECSPI3_ROOT_DIV] = imx_clk_divider("ecspi3_post_div", "ecspi3_pre_div", base + 0xb400, 0, 6);
+       clks[IMX7D_ECSPI4_ROOT_DIV] = imx_clk_divider("ecspi4_post_div", "ecspi4_pre_div", base + 0xb480, 0, 6);
+       clks[IMX7D_PWM1_ROOT_DIV] = imx_clk_divider("pwm1_post_div", "pwm1_pre_div", base + 0xb500, 0, 6);
+       clks[IMX7D_PWM2_ROOT_DIV] = imx_clk_divider("pwm2_post_div", "pwm2_pre_div", base + 0xb580, 0, 6);
+       clks[IMX7D_PWM3_ROOT_DIV] = imx_clk_divider("pwm3_post_div", "pwm3_pre_div", base + 0xb600, 0, 6);
+       clks[IMX7D_PWM4_ROOT_DIV] = imx_clk_divider("pwm4_post_div", "pwm4_pre_div", base + 0xb680, 0, 6);
+       clks[IMX7D_FLEXTIMER1_ROOT_DIV] = imx_clk_divider("flextimer1_post_div", "flextimer1_pre_div", base + 0xb700, 0, 6);
+       clks[IMX7D_FLEXTIMER2_ROOT_DIV] = imx_clk_divider("flextimer2_post_div", "flextimer2_pre_div", base + 0xb780, 0, 6);
+       clks[IMX7D_SIM1_ROOT_DIV] = imx_clk_divider("sim1_post_div", "sim1_pre_div", base + 0xb800, 0, 6);
+       clks[IMX7D_SIM2_ROOT_DIV] = imx_clk_divider("sim2_post_div", "sim2_pre_div", base + 0xb880, 0, 6);
+       clks[IMX7D_GPT1_ROOT_DIV] = imx_clk_divider("gpt1_post_div", "gpt1_pre_div", base + 0xb900, 0, 6);
+       clks[IMX7D_GPT2_ROOT_DIV] = imx_clk_divider("gpt2_post_div", "gpt2_pre_div", base + 0xb980, 0, 6);
+       clks[IMX7D_GPT3_ROOT_DIV] = imx_clk_divider("gpt3_post_div", "gpt3_pre_div", base + 0xba00, 0, 6);
+       clks[IMX7D_GPT4_ROOT_DIV] = imx_clk_divider("gpt4_post_div", "gpt4_pre_div", base + 0xba80, 0, 6);
+       clks[IMX7D_TRACE_ROOT_DIV] = imx_clk_divider("trace_post_div", "trace_pre_div", base + 0xbb00, 0, 6);
+       clks[IMX7D_WDOG_ROOT_DIV] = imx_clk_divider("wdog_post_div", "wdog_pre_div", base + 0xbb80, 0, 6);
+       clks[IMX7D_CSI_MCLK_ROOT_DIV] = imx_clk_divider("csi_mclk_post_div", "csi_mclk_pre_div", base + 0xbc00, 0, 6);
+       clks[IMX7D_AUDIO_MCLK_ROOT_DIV] = imx_clk_divider("audio_mclk_post_div", "audio_mclk_pre_div", base + 0xbc80, 0, 6);
+       clks[IMX7D_WRCLK_ROOT_DIV] = imx_clk_divider("wrclk_post_div", "wrclk_pre_div", base + 0xbd00, 0, 6);
+       clks[IMX7D_CLKO1_ROOT_DIV] = imx_clk_divider("clko1_post_div", "clko1_pre_div", base + 0xbd80, 0, 6);
+       clks[IMX7D_CLKO2_ROOT_DIV] = imx_clk_divider("clko2_post_div", "clko2_pre_div", base + 0xbe00, 0, 6);
+
+       clks[IMX7D_ARM_A7_ROOT_CLK] = imx_clk_gate2("arm_a7_root_clk", "arm_a7_div", base + 0x4000, 0);
+       clks[IMX7D_ARM_M4_ROOT_CLK] = imx_clk_gate2("arm_m4_root_clk", "arm_m4_div", base + 0x4010, 0);
+       clks[IMX7D_ARM_M0_ROOT_CLK] = imx_clk_gate2("arm_m0_root_clk", "arm_m0_div", base + 0x4020, 0);
+       clks[IMX7D_MAIN_AXI_ROOT_CLK] = imx_clk_gate2("main_axi_root_clk", "axi_post_div", base + 0x4040, 0);
+       clks[IMX7D_DISP_AXI_ROOT_CLK] = imx_clk_gate2("disp_axi_root_clk", "disp_axi_post_div", base + 0x4050, 0);
+       clks[IMX7D_ENET_AXI_ROOT_CLK] = imx_clk_gate2("enet_axi_root_clk", "enet_axi_post_div", base + 0x4060, 0);
+       clks[IMX7D_OCRAM_CLK] = imx_clk_gate2("ocram_clk", "axi_post_div", base + 0x4110, 0);
+       clks[IMX7D_OCRAM_S_CLK] = imx_clk_gate2("ocram_s_clk", "ahb_post_div", base + 0x4120, 0);
+       clks[IMX7D_NAND_USDHC_BUS_ROOT_CLK] = imx_clk_gate2("nand_usdhc_root_clk", "nand_usdhc_post_div", base + 0x4130, 0);
+       clks[IMX7D_AHB_CHANNEL_ROOT_CLK] = imx_clk_gate2("ahb_root_clk", "ahb_post_div", base + 0x4200, 0);
+       clks[IMX7D_DRAM_ROOT_CLK] = imx_clk_gate2("dram_root_clk", "dram_post_div", base + 0x4130, 0);
+       clks[IMX7D_DRAM_PHYM_ROOT_CLK] = imx_clk_gate2("dram_phym_root_clk", "dram_phym_cg", base + 0x4130, 0);
+       clks[IMX7D_DRAM_PHYM_ALT_ROOT_CLK] = imx_clk_gate2("dram_phym_alt_root_clk", "dram_phym_alt_post_div", base + 0x4130, 0);
+       clks[IMX7D_DRAM_ALT_ROOT_CLK] = imx_clk_gate2("dram_alt_root_clk", "dram_alt_post_div", base + 0x4130, 0);
+       clks[IMX7D_USB_HSIC_ROOT_CLK] = imx_clk_gate2("usb_hsic_root_clk", "usb_hsic_post_div", base + 0x4420, 0);
+       clks[IMX7D_PCIE_CTRL_ROOT_CLK] = imx_clk_gate2("pcie_ctrl_root_clk", "pcie_ctrl_post_div", base + 0x4600, 0);
+       clks[IMX7D_PCIE_PHY_ROOT_CLK] = imx_clk_gate2("pcie_phy_root_clk", "pcie_phy_post_div", base + 0x4600, 0);
+       clks[IMX7D_EPDC_PIXEL_ROOT_CLK] = imx_clk_gate2("epdc_pixel_root_clk", "epdc_pixel_post_div", base + 0x44a0, 0);
+       clks[IMX7D_LCDIF_PIXEL_ROOT_CLK] = imx_clk_gate2("lcdif_pixel_root_clk", "lcdif_pixel_post_div", base + 0x44b0, 0);
+       clks[IMX7D_MIPI_DSI_ROOT_CLK] = imx_clk_gate2("mipi_dsi_root_clk", "mipi_dsi_post_div", base + 0x4650, 0);
+       clks[IMX7D_MIPI_CSI_ROOT_CLK] = imx_clk_gate2("mipi_csi_root_clk", "mipi_csi_post_div", base + 0x4640, 0);
+       clks[IMX7D_MIPI_DPHY_ROOT_CLK] = imx_clk_gate2("mipi_dphy_root_clk", "mipi_dphy_post_div", base + 0x4660, 0);
+       clks[IMX7D_SAI1_ROOT_CLK] = imx_clk_gate2("sai1_root_clk", "sai1_post_div", base + 0x48c0, 0);
+       clks[IMX7D_SAI2_ROOT_CLK] = imx_clk_gate2("sai2_root_clk", "sai2_post_div", base + 0x48d0, 0);
+       clks[IMX7D_SAI3_ROOT_CLK] = imx_clk_gate2("sai3_root_clk", "sai3_post_div", base + 0x48e0, 0);
+       clks[IMX7D_SPDIF_ROOT_CLK] = imx_clk_gate2("spdif_root_clk", "spdif_post_div", base + 0x44d0, 0);
+       clks[IMX7D_ENET1_REF_ROOT_CLK] = imx_clk_gate2("enet1_ref_root_clk", "enet1_ref_post_div", base + 0x44e0, 0);
+       clks[IMX7D_ENET1_TIME_ROOT_CLK] = imx_clk_gate2("enet1_time_root_clk", "enet1_time_post_div", base + 0x44f0, 0);
+       clks[IMX7D_ENET2_REF_ROOT_CLK] = imx_clk_gate2("enet2_ref_root_clk", "enet2_ref_post_div", base + 0x4500, 0);
+       clks[IMX7D_ENET2_TIME_ROOT_CLK] = imx_clk_gate2("enet2_time_root_clk", "enet2_time_post_div", base + 0x4510, 0);
+       clks[IMX7D_ENET_PHY_REF_ROOT_CLK] = imx_clk_gate2("enet_phy_ref_root_clk", "enet_phy_ref_post_div", base + 0x4520, 0);
+       clks[IMX7D_EIM_ROOT_CLK] = imx_clk_gate2("eim_root_clk", "eim_post_div", base + 0x4160, 0);
+       clks[IMX7D_NAND_ROOT_CLK] = imx_clk_gate2("nand_root_clk", "nand_post_div", base + 0x4140, 0);
+       clks[IMX7D_QSPI_ROOT_CLK] = imx_clk_gate2("qspi_root_clk", "qspi_post_div", base + 0x4150, 0);
+       clks[IMX7D_USDHC1_ROOT_CLK] = imx_clk_gate2("usdhc1_root_clk", "usdhc1_post_div", base + 0x46c0, 0);
+       clks[IMX7D_USDHC2_ROOT_CLK] = imx_clk_gate2("usdhc2_root_clk", "usdhc2_post_div", base + 0x46d0, 0);
+       clks[IMX7D_USDHC3_ROOT_CLK] = imx_clk_gate2("usdhc3_root_clk", "usdhc3_post_div", base + 0x46e0, 0);
+       clks[IMX7D_CAN1_ROOT_CLK] = imx_clk_gate2("can1_root_clk", "can1_post_div", base + 0x4740, 0);
+       clks[IMX7D_CAN2_ROOT_CLK] = imx_clk_gate2("can2_root_clk", "can2_post_div", base + 0x4750, 0);
+       clks[IMX7D_I2C1_ROOT_CLK] = imx_clk_gate2("i2c1_root_clk", "i2c1_post_div", base + 0x4880, 0);
+       clks[IMX7D_I2C2_ROOT_CLK] = imx_clk_gate2("i2c2_root_clk", "i2c2_post_div", base + 0x4890, 0);
+       clks[IMX7D_I2C3_ROOT_CLK] = imx_clk_gate2("i2c3_root_clk", "i2c3_post_div", base + 0x48a0, 0);
+       clks[IMX7D_I2C4_ROOT_CLK] = imx_clk_gate2("i2c4_root_clk", "i2c4_post_div", base + 0x48b0, 0);
+       clks[IMX7D_UART1_ROOT_CLK] = imx_clk_gate2("uart1_root_clk", "uart1_post_div", base + 0x4940, 0);
+       clks[IMX7D_UART2_ROOT_CLK] = imx_clk_gate2("uart2_root_clk", "uart2_post_div", base + 0x4950, 0);
+       clks[IMX7D_UART3_ROOT_CLK] = imx_clk_gate2("uart3_root_clk", "uart3_post_div", base + 0x4960, 0);
+       clks[IMX7D_UART4_ROOT_CLK] = imx_clk_gate2("uart4_root_clk", "uart4_post_div", base + 0x4970, 0);
+       clks[IMX7D_UART5_ROOT_CLK] = imx_clk_gate2("uart5_root_clk", "uart5_post_div", base + 0x4980, 0);
+       clks[IMX7D_UART6_ROOT_CLK] = imx_clk_gate2("uart6_root_clk", "uart6_post_div", base + 0x4990, 0);
+       clks[IMX7D_UART7_ROOT_CLK] = imx_clk_gate2("uart7_root_clk", "uart7_post_div", base + 0x49a0, 0);
+       clks[IMX7D_ECSPI1_ROOT_CLK] = imx_clk_gate2("ecspi1_root_clk", "ecspi1_post_div", base + 0x4780, 0);
+       clks[IMX7D_ECSPI2_ROOT_CLK] = imx_clk_gate2("ecspi2_root_clk", "ecspi2_post_div", base + 0x4790, 0);
+       clks[IMX7D_ECSPI3_ROOT_CLK] = imx_clk_gate2("ecspi3_root_clk", "ecspi3_post_div", base + 0x47a0, 0);
+       clks[IMX7D_ECSPI4_ROOT_CLK] = imx_clk_gate2("ecspi4_root_clk", "ecspi4_post_div", base + 0x47b0, 0);
+       clks[IMX7D_PWM1_ROOT_CLK] = imx_clk_gate2("pwm1_root_clk", "pwm1_post_div", base + 0x4840, 0);
+       clks[IMX7D_PWM2_ROOT_CLK] = imx_clk_gate2("pwm2_root_clk", "pwm2_post_div", base + 0x4850, 0);
+       clks[IMX7D_PWM3_ROOT_CLK] = imx_clk_gate2("pwm3_root_clk", "pwm3_post_div", base + 0x4860, 0);
+       clks[IMX7D_PWM4_ROOT_CLK] = imx_clk_gate2("pwm4_root_clk", "pwm4_post_div", base + 0x4870, 0);
+       clks[IMX7D_FLEXTIMER1_ROOT_CLK] = imx_clk_gate2("flextimer1_root_clk", "flextimer1_post_div", base + 0x4800, 0);
+       clks[IMX7D_FLEXTIMER2_ROOT_CLK] = imx_clk_gate2("flextimer2_root_clk", "flextimer2_post_div", base + 0x4810, 0);
+       clks[IMX7D_SIM1_ROOT_CLK] = imx_clk_gate2("sim1_root_clk", "sim1_post_div", base + 0x4900, 0);
+       clks[IMX7D_SIM2_ROOT_CLK] = imx_clk_gate2("sim2_root_clk", "sim2_post_div", base + 0x4910, 0);
+       clks[IMX7D_GPT1_ROOT_CLK] = imx_clk_gate2("gpt1_root_clk", "gpt1_post_div", base + 0x47c0, 0);
+       clks[IMX7D_GPT2_ROOT_CLK] = imx_clk_gate2("gpt2_root_clk", "gpt2_post_div", base + 0x47d0, 0);
+       clks[IMX7D_GPT3_ROOT_CLK] = imx_clk_gate2("gpt3_root_clk", "gpt3_post_div", base + 0x47e0, 0);
+       clks[IMX7D_GPT4_ROOT_CLK] = imx_clk_gate2("gpt4_root_clk", "gpt4_post_div", base + 0x47f0, 0);
+       clks[IMX7D_TRACE_ROOT_CLK] = imx_clk_gate2("trace_root_clk", "trace_post_div", base + 0x4300, 0);
+       clks[IMX7D_WDOG1_ROOT_CLK] = imx_clk_gate2("wdog1_root_clk", "wdog_post_div", base + 0x49c0, 0);
+       clks[IMX7D_WDOG2_ROOT_CLK] = imx_clk_gate2("wdog2_root_clk", "wdog_post_div", base + 0x49d0, 0);
+       clks[IMX7D_WDOG3_ROOT_CLK] = imx_clk_gate2("wdog3_root_clk", "wdog_post_div", base + 0x49e0, 0);
+       clks[IMX7D_WDOG4_ROOT_CLK] = imx_clk_gate2("wdog4_root_clk", "wdog_post_div", base + 0x49f0, 0);
+       clks[IMX7D_CSI_MCLK_ROOT_CLK] = imx_clk_gate2("csi_mclk_root_clk", "csi_mclk_post_div", base + 0x4490, 0);
+       clks[IMX7D_AUDIO_MCLK_ROOT_CLK] = imx_clk_gate2("audio_mclk_root_clk", "audio_mclk_post_div", base + 0x4790, 0);
+       clks[IMX7D_WRCLK_ROOT_CLK] = imx_clk_gate2("wrclk_root_clk", "wrclk_post_div", base + 0x47a0, 0);
+
+       clks[IMX7D_GPT_3M_CLK] = imx_clk_fixed_factor("gpt_3m", "osc", 1, 8);
+
+       for (i = 0; i < ARRAY_SIZE(clks); i++)
+               if (IS_ERR(clks[i]))
+                       pr_err("i.MX7D clk %d: register failed with %ld\n",
+                                       i, PTR_ERR(clks[i]));
+
+       clk_data.clks = clks;
+       clk_data.clk_num = ARRAY_SIZE(clks);
+       of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
+
+       /* TO BE FIXED LATER
+        * Enable all clock to bring up imx7, otherwise system will be halt and block
+        * the other part upstream Because imx7d clock design changed, clock framework
+        * need do a little modify.
+        * Dong Aisheng is working on this. After that, this part need be changed.
+        */
+       for (i = 0; i < IMX7D_CLK_END; i++)
+               clk_prepare_enable(clks[i]);
+
+       /* use old gpt clk setting, gpt1 root clk must be twice as gpt counter freq */
+       clk_set_parent(clks[IMX7D_GPT1_ROOT_SRC], clks[IMX7D_OSC_24M_CLK]);
+
+       /*
+        * init enet clock source:
+        *      AXI clock source is 250MHz
+        *      Phy refrence clock is 25MHz
+        *      1588 time clock source is 100MHz
+        */
+       clk_set_parent(clks[IMX7D_ENET_AXI_ROOT_SRC], clks[IMX7D_PLL_ENET_MAIN_250M_CLK]);
+       clk_set_parent(clks[IMX7D_ENET_PHY_REF_ROOT_SRC], clks[IMX7D_PLL_ENET_MAIN_25M_CLK]);
+       clk_set_parent(clks[IMX7D_ENET1_TIME_ROOT_SRC], clks[IMX7D_PLL_ENET_MAIN_100M_CLK]);
+       clk_set_parent(clks[IMX7D_ENET2_TIME_ROOT_SRC], clks[IMX7D_PLL_ENET_MAIN_100M_CLK]);
+
+       /* set uart module clock's parent clock source that must be great then 80MHz */
+       clk_set_parent(clks[IMX7D_UART1_ROOT_SRC], clks[IMX7D_OSC_24M_CLK]);
+
+}
+CLK_OF_DECLARE(imx7d, "fsl,imx7d-ccm", imx7d_clocks_init);
similarity index 75%
rename from arch/arm/mach-imx/clk-pllv1.c
rename to drivers/clk/imx/clk-pllv1.c
index d21d14c..c34ad8a 100644 (file)
@@ -6,8 +6,6 @@
 #include <linux/err.h>
 
 #include "clk.h"
-#include "common.h"
-#include "hardware.h"
 
 /**
  * pll v1
 struct clk_pllv1 {
        struct clk_hw   hw;
        void __iomem    *base;
+       enum imx_pllv1_type type;
 };
 
 #define to_clk_pllv1(clk) (container_of(clk, struct clk_pllv1, clk))
 
-static inline bool mfn_is_negative(unsigned int mfn)
+static inline bool is_imx1_pllv1(struct clk_pllv1 *pll)
 {
-       return !cpu_is_mx1() && !cpu_is_mx21() && (mfn & MFN_SIGN);
+       return pll->type == IMX_PLLV1_IMX1;
+}
+
+static inline bool is_imx21_pllv1(struct clk_pllv1 *pll)
+{
+       return pll->type == IMX_PLLV1_IMX21;
+}
+
+static inline bool is_imx27_pllv1(struct clk_pllv1 *pll)
+{
+       return pll->type == IMX_PLLV1_IMX27;
+}
+
+static inline bool mfn_is_negative(struct clk_pllv1 *pll, unsigned int mfn)
+{
+       return !is_imx1_pllv1(pll) && !is_imx21_pllv1(pll) && (mfn & MFN_SIGN);
 }
 
 static unsigned long clk_pllv1_recalc_rate(struct clk_hw *hw,
@@ -71,8 +85,8 @@ static unsigned long clk_pllv1_recalc_rate(struct clk_hw *hw,
         * 2's complements number.
         * On i.MX27 the bit 9 is the sign bit.
         */
-       if (mfn_is_negative(mfn)) {
-               if (cpu_is_mx27())
+       if (mfn_is_negative(pll, mfn)) {
+               if (is_imx27_pllv1(pll))
                        mfn_abs = mfn & MFN_MASK;
                else
                        mfn_abs = BIT(MFN_BITS) - mfn;
@@ -85,7 +99,7 @@ static unsigned long clk_pllv1_recalc_rate(struct clk_hw *hw,
 
        do_div(ll, mfd + 1);
 
-       if (mfn_is_negative(mfn))
+       if (mfn_is_negative(pll, mfn))
                ll = -ll;
 
        ll = (rate * mfi) + ll;
@@ -97,8 +111,8 @@ static struct clk_ops clk_pllv1_ops = {
        .recalc_rate = clk_pllv1_recalc_rate,
 };
 
-struct clk *imx_clk_pllv1(const char *name, const char *parent,
-               void __iomem *base)
+struct clk *imx_clk_pllv1(enum imx_pllv1_type type, const char *name,
+               const char *parent, void __iomem *base)
 {
        struct clk_pllv1 *pll;
        struct clk *clk;
@@ -109,6 +123,7 @@ struct clk *imx_clk_pllv1(const char *name, const char *parent,
                return ERR_PTR(-ENOMEM);
 
        pll->base = base;
+       pll->type = type;
 
        init.name = name;
        init.ops = &clk_pllv1_ops;
similarity index 96%
rename from arch/arm/mach-imx/clk-pllv3.c
rename to drivers/clk/imx/clk-pllv3.c
index 641ebc5..f0d15fb 100644 (file)
 
 #define BM_PLL_POWER           (0x1 << 12)
 #define BM_PLL_LOCK            (0x1 << 31)
+#define IMX7_ENET_PLL_POWER    (0x1 << 5)
 
 /**
  * struct clk_pllv3 - IMX PLL clock version 3
  * @clk_hw:     clock source
  * @base:       base address of PLL registers
  * @powerup_set: set POWER bit to power up the PLL
+ * @powerdown:   pll powerdown offset bit
  * @div_mask:   mask of divider bits
  * @div_shift:  shift of divider bits
  *
@@ -40,6 +42,7 @@ struct clk_pllv3 {
        struct clk_hw   hw;
        void __iomem    *base;
        bool            powerup_set;
+       u32             powerdown;
        u32             div_mask;
        u32             div_shift;
 };
@@ -49,7 +52,7 @@ struct clk_pllv3 {
 static int clk_pllv3_wait_lock(struct clk_pllv3 *pll)
 {
        unsigned long timeout = jiffies + msecs_to_jiffies(10);
-       u32 val = readl_relaxed(pll->base) & BM_PLL_POWER;
+       u32 val = readl_relaxed(pll->base) & pll->powerdown;
 
        /* No need to wait for lock when pll is not powered up */
        if ((pll->powerup_set && !val) || (!pll->powerup_set && val))
@@ -215,7 +218,7 @@ static long clk_pllv3_av_round_rate(struct clk_hw *hw, unsigned long rate,
        unsigned long max_rate = parent_rate * 54;
        u32 div;
        u32 mfn, mfd = 1000000;
-       s64 temp64;
+       u64 temp64;
 
        if (rate > max_rate)
                rate = max_rate;
@@ -239,7 +242,7 @@ static int clk_pllv3_av_set_rate(struct clk_hw *hw, unsigned long rate,
        unsigned long max_rate = parent_rate * 54;
        u32 val, div;
        u32 mfn, mfd = 1000000;
-       s64 temp64;
+       u64 temp64;
 
        if (rate < min_rate || rate > max_rate)
                return -EINVAL;
@@ -293,6 +296,8 @@ struct clk *imx_clk_pllv3(enum imx_pllv3_type type, const char *name,
        if (!pll)
                return ERR_PTR(-ENOMEM);
 
+       pll->powerdown = BM_PLL_POWER;
+
        switch (type) {
        case IMX_PLLV3_SYS:
                ops = &clk_pllv3_sys_ops;
@@ -306,6 +311,8 @@ struct clk *imx_clk_pllv3(enum imx_pllv3_type type, const char *name,
        case IMX_PLLV3_AV:
                ops = &clk_pllv3_av_ops;
                break;
+       case IMX_PLLV3_ENET_IMX7:
+               pll->powerdown = IMX7_ENET_PLL_POWER;
        case IMX_PLLV3_ENET:
                ops = &clk_pllv3_enet_ops;
                break;
similarity index 98%
rename from arch/arm/mach-imx/clk-vf610.c
rename to drivers/clk/imx/clk-vf610.c
index 61876ed..bff45ea 100644 (file)
@@ -118,6 +118,7 @@ static struct clk_onecell_data clk_data;
 static unsigned int const clks_init_on[] __initconst = {
        VF610_CLK_SYS_BUS,
        VF610_CLK_DDR_SEL,
+       VF610_CLK_DAP,
 };
 
 static struct clk * __init vf610_get_fixed_clock(
@@ -272,6 +273,8 @@ static void __init vf610_clocks_init(struct device_node *ccm_node)
 
        clk[VF610_CLK_I2C0] = imx_clk_gate2("i2c0", "ipg_bus", CCM_CCGR4, CCM_CCGRx_CGn(6));
        clk[VF610_CLK_I2C1] = imx_clk_gate2("i2c1", "ipg_bus", CCM_CCGR4, CCM_CCGRx_CGn(7));
+       clk[VF610_CLK_I2C2] = imx_clk_gate2("i2c2", "ipg_bus", CCM_CCGR10, CCM_CCGRx_CGn(6));
+       clk[VF610_CLK_I2C3] = imx_clk_gate2("i2c3", "ipg_bus", CCM_CCGR10, CCM_CCGRx_CGn(7));
 
        clk[VF610_CLK_DSPI0] = imx_clk_gate2("dspi0", "ipg_bus", CCM_CCGR0, CCM_CCGRx_CGn(12));
        clk[VF610_CLK_DSPI1] = imx_clk_gate2("dspi1", "ipg_bus", CCM_CCGR0, CCM_CCGRx_CGn(13));
@@ -383,6 +386,7 @@ static void __init vf610_clocks_init(struct device_node *ccm_node)
        clk[VF610_CLK_DMAMUX3] = imx_clk_gate2("dmamux3", "platform_bus", CCM_CCGR6, CCM_CCGRx_CGn(2));
 
        clk[VF610_CLK_SNVS] = imx_clk_gate2("snvs-rtc", "ipg_bus", CCM_CCGR6, CCM_CCGRx_CGn(7));
+       clk[VF610_CLK_DAP] = imx_clk_gate("dap", "platform_bus", CCM_CCSR, 24);
 
        imx_check_clocks(clk, ARRAY_SIZE(clk));
 
similarity index 94%
rename from arch/arm/mach-imx/clk.h
rename to drivers/clk/imx/clk.h
index 6a07903..1049b0c 100644 (file)
@@ -10,8 +10,17 @@ void imx_check_clocks(struct clk *clks[], unsigned int count);
 
 extern void imx_cscmr1_fixup(u32 *val);
 
-struct clk *imx_clk_pllv1(const char *name, const char *parent,
-               void __iomem *base);
+enum imx_pllv1_type {
+       IMX_PLLV1_IMX1,
+       IMX_PLLV1_IMX21,
+       IMX_PLLV1_IMX25,
+       IMX_PLLV1_IMX27,
+       IMX_PLLV1_IMX31,
+       IMX_PLLV1_IMX35,
+};
+
+struct clk *imx_clk_pllv1(enum imx_pllv1_type type, const char *name,
+               const char *parent, void __iomem *base);
 
 struct clk *imx_clk_pllv2(const char *name, const char *parent,
                void __iomem *base);
@@ -23,6 +32,7 @@ enum imx_pllv3_type {
        IMX_PLLV3_USB_VF610,
        IMX_PLLV3_AV,
        IMX_PLLV3_ENET,
+       IMX_PLLV3_ENET_IMX7,
 };
 
 struct clk *imx_clk_pllv3(enum imx_pllv3_type type, const char *name,
index 5f9b54b..9a31b77 100644 (file)
@@ -353,6 +353,34 @@ static u8 clk_pxa27x_memory_get_parent(struct clk_hw *hw)
 PARENTS(clk_pxa27x_memory) = { "osc_13mhz", "system_bus", "run" };
 MUX_RO_RATE_RO_OPS(clk_pxa27x_memory, "memory");
 
+#define DUMMY_CLK(_con_id, _dev_id, _parent) \
+       { .con_id = _con_id, .dev_id = _dev_id, .parent = _parent }
+struct dummy_clk {
+       const char *con_id;
+       const char *dev_id;
+       const char *parent;
+};
+static struct dummy_clk dummy_clks[] __initdata = {
+       DUMMY_CLK(NULL, "pxa27x-gpio", "osc_32_768khz"),
+       DUMMY_CLK(NULL, "sa1100-rtc", "osc_32_768khz"),
+       DUMMY_CLK("UARTCLK", "pxa2xx-ir", "STUART"),
+};
+
+static void __init pxa27x_dummy_clocks_init(void)
+{
+       struct clk *clk;
+       struct dummy_clk *d;
+       const char *name;
+       int i;
+
+       for (i = 0; i < ARRAY_SIZE(dummy_clks); i++) {
+               d = &dummy_clks[i];
+               name = d->dev_id ? d->dev_id : d->con_id;
+               clk = clk_register_fixed_factor(NULL, name, d->parent, 0, 1, 1);
+               clk_register_clkdev(clk, d->con_id, d->dev_id);
+       }
+}
+
 static void __init pxa27x_base_clocks_init(void)
 {
        pxa27x_register_plls();
@@ -362,12 +390,12 @@ static void __init pxa27x_base_clocks_init(void)
        clk_register_clk_pxa27x_lcd_base();
 }
 
-static int __init pxa27x_clocks_init(void)
+int __init pxa27x_clocks_init(void)
 {
        pxa27x_base_clocks_init();
+       pxa27x_dummy_clocks_init();
        return clk_pxa_cken_init(pxa27x_clocks, ARRAY_SIZE(pxa27x_clocks));
 }
-postcore_initcall(pxa27x_clocks_init);
 
 static void __init pxa27x_dt_clocks_init(struct device_node *np)
 {
diff --git a/drivers/clk/zte/Makefile b/drivers/clk/zte/Makefile
new file mode 100644 (file)
index 0000000..95b707c
--- /dev/null
@@ -0,0 +1,2 @@
+obj-y := clk-pll.o
+obj-$(CONFIG_SOC_ZX296702) += clk-zx296702.o
diff --git a/drivers/clk/zte/clk-pll.c b/drivers/clk/zte/clk-pll.c
new file mode 100644 (file)
index 0000000..c3b221a
--- /dev/null
@@ -0,0 +1,172 @@
+/*
+ * Copyright 2014 Linaro Ltd.
+ * Copyright (C) 2014 ZTE Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/iopoll.h>
+#include <linux/slab.h>
+#include <linux/spinlock.h>
+
+#include "clk.h"
+
+#define to_clk_zx_pll(_hw) container_of(_hw, struct clk_zx_pll, hw)
+
+#define CFG0_CFG1_OFFSET 4
+#define LOCK_FLAG BIT(30)
+#define POWER_DOWN BIT(31)
+
+static int rate_to_idx(struct clk_zx_pll *zx_pll, unsigned long rate)
+{
+       const struct zx_pll_config *config = zx_pll->lookup_table;
+       int i;
+
+       for (i = 0; i < zx_pll->count; i++) {
+               if (config[i].rate > rate)
+                       return i > 0 ? i - 1 : 0;
+
+               if (config[i].rate == rate)
+                       return i;
+       }
+
+       return i - 1;
+}
+
+static int hw_to_idx(struct clk_zx_pll *zx_pll)
+{
+       const struct zx_pll_config *config = zx_pll->lookup_table;
+       u32 hw_cfg0, hw_cfg1;
+       int i;
+
+       hw_cfg0 = readl_relaxed(zx_pll->reg_base);
+       hw_cfg1 = readl_relaxed(zx_pll->reg_base + CFG0_CFG1_OFFSET);
+
+       /* For matching the value in lookup table */
+       hw_cfg0 &= ~LOCK_FLAG;
+       hw_cfg0 |= POWER_DOWN;
+
+       for (i = 0; i < zx_pll->count; i++) {
+               if (hw_cfg0 == config[i].cfg0 && hw_cfg1 == config[i].cfg1)
+                       return i;
+       }
+
+       return -EINVAL;
+}
+
+static unsigned long zx_pll_recalc_rate(struct clk_hw *hw,
+                                       unsigned long parent_rate)
+{
+       struct clk_zx_pll *zx_pll = to_clk_zx_pll(hw);
+       int idx;
+
+       idx = hw_to_idx(zx_pll);
+       if (unlikely(idx == -EINVAL))
+               return 0;
+
+       return zx_pll->lookup_table[idx].rate;
+}
+
+static long zx_pll_round_rate(struct clk_hw *hw, unsigned long rate,
+                             unsigned long *prate)
+{
+       struct clk_zx_pll *zx_pll = to_clk_zx_pll(hw);
+       int idx;
+
+       idx = rate_to_idx(zx_pll, rate);
+
+       return zx_pll->lookup_table[idx].rate;
+}
+
+static int zx_pll_set_rate(struct clk_hw *hw, unsigned long rate,
+                          unsigned long parent_rate)
+{
+       /* Assume current cpu is not running on current PLL */
+       struct clk_zx_pll *zx_pll = to_clk_zx_pll(hw);
+       const struct zx_pll_config *config;
+       int idx;
+
+       idx = rate_to_idx(zx_pll, rate);
+       config = &zx_pll->lookup_table[idx];
+
+       writel_relaxed(config->cfg0, zx_pll->reg_base);
+       writel_relaxed(config->cfg1, zx_pll->reg_base + CFG0_CFG1_OFFSET);
+
+       return 0;
+}
+
+static int zx_pll_enable(struct clk_hw *hw)
+{
+       struct clk_zx_pll *zx_pll = to_clk_zx_pll(hw);
+       u32 reg;
+
+       reg = readl_relaxed(zx_pll->reg_base);
+       writel_relaxed(reg & ~POWER_DOWN, zx_pll->reg_base);
+
+       return readl_relaxed_poll_timeout(zx_pll->reg_base, reg,
+                                         reg & LOCK_FLAG, 0, 100);
+}
+
+static void zx_pll_disable(struct clk_hw *hw)
+{
+       struct clk_zx_pll *zx_pll = to_clk_zx_pll(hw);
+       u32 reg;
+
+       reg = readl_relaxed(zx_pll->reg_base);
+       writel_relaxed(reg | POWER_DOWN, zx_pll->reg_base);
+}
+
+static int zx_pll_is_enabled(struct clk_hw *hw)
+{
+       struct clk_zx_pll *zx_pll = to_clk_zx_pll(hw);
+       u32 reg;
+
+       reg = readl_relaxed(zx_pll->reg_base);
+
+       return !(reg & POWER_DOWN);
+}
+
+static const struct clk_ops zx_pll_ops = {
+       .recalc_rate = zx_pll_recalc_rate,
+       .round_rate = zx_pll_round_rate,
+       .set_rate = zx_pll_set_rate,
+       .enable = zx_pll_enable,
+       .disable = zx_pll_disable,
+       .is_enabled = zx_pll_is_enabled,
+};
+
+struct clk *clk_register_zx_pll(const char *name, const char *parent_name,
+       unsigned long flags, void __iomem *reg_base,
+       const struct zx_pll_config *lookup_table, int count, spinlock_t *lock)
+{
+       struct clk_zx_pll *zx_pll;
+       struct clk *clk;
+       struct clk_init_data init;
+
+       zx_pll = kzalloc(sizeof(*zx_pll), GFP_KERNEL);
+       if (!zx_pll)
+               return ERR_PTR(-ENOMEM);
+
+       init.name = name;
+       init.ops = &zx_pll_ops;
+       init.flags = flags;
+       init.parent_names = parent_name ? &parent_name : NULL;
+       init.num_parents = parent_name ? 1 : 0;
+
+       zx_pll->reg_base = reg_base;
+       zx_pll->lookup_table = lookup_table;
+       zx_pll->count = count;
+       zx_pll->lock = lock;
+       zx_pll->hw.init = &init;
+
+       clk = clk_register(NULL, &zx_pll->hw);
+       if (IS_ERR(clk))
+               kfree(zx_pll);
+
+       return clk;
+}
diff --git a/drivers/clk/zte/clk-zx296702.c b/drivers/clk/zte/clk-zx296702.c
new file mode 100644 (file)
index 0000000..929d033
--- /dev/null
@@ -0,0 +1,657 @@
+/*
+ * Copyright 2014 Linaro Ltd.
+ * Copyright (C) 2014 ZTE Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/of_address.h>
+#include <dt-bindings/clock/zx296702-clock.h>
+#include "clk.h"
+
+static DEFINE_SPINLOCK(reg_lock);
+
+static void __iomem *topcrm_base;
+static void __iomem *lsp0crpm_base;
+static void __iomem *lsp1crpm_base;
+
+static struct clk *topclk[ZX296702_TOPCLK_END];
+static struct clk *lsp0clk[ZX296702_LSP0CLK_END];
+static struct clk *lsp1clk[ZX296702_LSP1CLK_END];
+
+static struct clk_onecell_data topclk_data;
+static struct clk_onecell_data lsp0clk_data;
+static struct clk_onecell_data lsp1clk_data;
+
+#define CLK_MUX                        (topcrm_base + 0x04)
+#define CLK_DIV                        (topcrm_base + 0x08)
+#define CLK_EN0                        (topcrm_base + 0x0c)
+#define CLK_EN1                        (topcrm_base + 0x10)
+#define VOU_LOCAL_CLKEN                (topcrm_base + 0x68)
+#define VOU_LOCAL_CLKSEL       (topcrm_base + 0x70)
+#define VOU_LOCAL_DIV2_SET     (topcrm_base + 0x74)
+#define CLK_MUX1               (topcrm_base + 0x8c)
+
+#define CLK_SDMMC1             (lsp0crpm_base + 0x0c)
+
+#define CLK_UART0              (lsp1crpm_base + 0x20)
+#define CLK_UART1              (lsp1crpm_base + 0x24)
+#define CLK_SDMMC0             (lsp1crpm_base + 0x2c)
+
+static const struct zx_pll_config pll_a9_config[] = {
+       { .rate = 700000000, .cfg0 = 0x800405d1, .cfg1 = 0x04555555 },
+       { .rate = 800000000, .cfg0 = 0x80040691, .cfg1 = 0x04aaaaaa },
+       { .rate = 900000000, .cfg0 = 0x80040791, .cfg1 = 0x04000000 },
+       { .rate = 1000000000, .cfg0 = 0x80040851, .cfg1 = 0x04555555 },
+       { .rate = 1100000000, .cfg0 = 0x80040911, .cfg1 = 0x04aaaaaa },
+       { .rate = 1200000000, .cfg0 = 0x80040a11, .cfg1 = 0x04000000 },
+};
+
+static const struct clk_div_table main_hlk_div[] = {
+       { .val = 1, .div = 2, },
+       { .val = 3, .div = 4, },
+       { /* sentinel */ }
+};
+
+static const struct clk_div_table a9_as1_aclk_divider[] = {
+       { .val = 0, .div = 1, },
+       { .val = 1, .div = 2, },
+       { .val = 3, .div = 4, },
+       { /* sentinel */ }
+};
+
+static const struct clk_div_table sec_wclk_divider[] = {
+       { .val = 0, .div = 1, },
+       { .val = 1, .div = 2, },
+       { .val = 3, .div = 4, },
+       { .val = 5, .div = 6, },
+       { .val = 7, .div = 8, },
+       { /* sentinel */ }
+};
+
+static const char * matrix_aclk_sel[] = {
+       "pll_mm0_198M",
+       "osc",
+       "clk_148M5",
+       "pll_lsp_104M",
+};
+
+static const char * a9_wclk_sel[] = {
+       "pll_a9",
+       "osc",
+       "clk_500",
+       "clk_250",
+};
+
+static const char * a9_as1_aclk_sel[] = {
+       "clk_250",
+       "osc",
+       "pll_mm0_396M",
+       "pll_mac_333M",
+};
+
+static const char * a9_trace_clkin_sel[] = {
+       "clk_74M25",
+       "pll_mm1_108M",
+       "clk_125",
+       "clk_148M5",
+};
+
+static const char * decppu_aclk_sel[] = {
+       "clk_250",
+       "pll_mm0_198M",
+       "pll_lsp_104M",
+       "pll_audio_294M912",
+};
+
+static const char * vou_main_wclk_sel[] = {
+       "clk_148M5",
+       "clk_74M25",
+       "clk_27",
+       "pll_mm1_54M",
+};
+
+static const char * vou_scaler_wclk_sel[] = {
+       "clk_250",
+       "pll_mac_333M",
+       "pll_audio_294M912",
+       "pll_mm0_198M",
+};
+
+static const char * r2d_wclk_sel[] = {
+       "pll_audio_294M912",
+       "pll_mac_333M",
+       "pll_a9_350M",
+       "pll_mm0_396M",
+};
+
+static const char * ddr_wclk_sel[] = {
+       "pll_mac_333M",
+       "pll_ddr_266M",
+       "pll_audio_294M912",
+       "pll_mm0_198M",
+};
+
+static const char * nand_wclk_sel[] = {
+       "pll_lsp_104M",
+       "osc",
+};
+
+static const char * lsp_26_wclk_sel[] = {
+       "pll_lsp_26M",
+       "osc",
+};
+
+static const char * vl0_sel[] = {
+       "vou_main_channel_div",
+       "vou_aux_channel_div",
+};
+
+static const char * hdmi_sel[] = {
+       "vou_main_channel_wclk",
+       "vou_aux_channel_wclk",
+};
+
+static const char * sdmmc0_wclk_sel[] = {
+       "lsp1_104M_wclk",
+       "lsp1_26M_wclk",
+};
+
+static const char * sdmmc1_wclk_sel[] = {
+       "lsp0_104M_wclk",
+       "lsp0_26M_wclk",
+};
+
+static const char * uart_wclk_sel[] = {
+       "lsp1_104M_wclk",
+       "lsp1_26M_wclk",
+};
+
+static inline struct clk *zx_divtbl(const char *name, const char *parent,
+                                   void __iomem *reg, u8 shift, u8 width,
+                                   const struct clk_div_table *table)
+{
+       return clk_register_divider_table(NULL, name, parent, 0, reg, shift,
+                                         width, 0, table, &reg_lock);
+}
+
+static inline struct clk *zx_div(const char *name, const char *parent,
+                                void __iomem *reg, u8 shift, u8 width)
+{
+       return clk_register_divider(NULL, name, parent, 0,
+                                   reg, shift, width, 0, &reg_lock);
+}
+
+static inline struct clk *zx_mux(const char *name, const char **parents,
+               int num_parents, void __iomem *reg, u8 shift, u8 width)
+{
+       return clk_register_mux(NULL, name, parents, num_parents,
+                               0, reg, shift, width, 0, &reg_lock);
+}
+
+static inline struct clk *zx_gate(const char *name, const char *parent,
+                                 void __iomem *reg, u8 shift)
+{
+       return clk_register_gate(NULL, name, parent, CLK_IGNORE_UNUSED,
+                                reg, shift, 0, &reg_lock);
+}
+
+static void __init zx296702_top_clocks_init(struct device_node *np)
+{
+       struct clk **clk = topclk;
+       int i;
+
+       topcrm_base = of_iomap(np, 0);
+       WARN_ON(!topcrm_base);
+
+       clk[ZX296702_OSC] =
+               clk_register_fixed_rate(NULL, "osc", NULL, CLK_IS_ROOT,
+                               30000000);
+       clk[ZX296702_PLL_A9] =
+               clk_register_zx_pll("pll_a9", "osc", 0, topcrm_base
+                               + 0x01c, pll_a9_config,
+                               ARRAY_SIZE(pll_a9_config), &reg_lock);
+
+       /* TODO: pll_a9_350M look like changeble follow a9 pll */
+       clk[ZX296702_PLL_A9_350M] =
+               clk_register_fixed_rate(NULL, "pll_a9_350M", "osc", 0,
+                               350000000);
+       clk[ZX296702_PLL_MAC_1000M] =
+               clk_register_fixed_rate(NULL, "pll_mac_1000M", "osc", 0,
+                               1000000000);
+       clk[ZX296702_PLL_MAC_333M] =
+               clk_register_fixed_rate(NULL, "pll_mac_333M",    "osc", 0,
+                               333000000);
+       clk[ZX296702_PLL_MM0_1188M] =
+               clk_register_fixed_rate(NULL, "pll_mm0_1188M", "osc", 0,
+                               1188000000);
+       clk[ZX296702_PLL_MM0_396M] =
+               clk_register_fixed_rate(NULL, "pll_mm0_396M",  "osc", 0,
+                               396000000);
+       clk[ZX296702_PLL_MM0_198M] =
+               clk_register_fixed_rate(NULL, "pll_mm0_198M",  "osc", 0,
+                               198000000);
+       clk[ZX296702_PLL_MM1_108M] =
+               clk_register_fixed_rate(NULL, "pll_mm1_108M",  "osc", 0,
+                               108000000);
+       clk[ZX296702_PLL_MM1_72M] =
+               clk_register_fixed_rate(NULL, "pll_mm1_72M",     "osc", 0,
+                               72000000);
+       clk[ZX296702_PLL_MM1_54M] =
+               clk_register_fixed_rate(NULL, "pll_mm1_54M",     "osc", 0,
+                               54000000);
+       clk[ZX296702_PLL_LSP_104M] =
+               clk_register_fixed_rate(NULL, "pll_lsp_104M",  "osc", 0,
+                               104000000);
+       clk[ZX296702_PLL_LSP_26M] =
+               clk_register_fixed_rate(NULL, "pll_lsp_26M",     "osc", 0,
+                               26000000);
+       clk[ZX296702_PLL_DDR_266M] =
+               clk_register_fixed_rate(NULL, "pll_ddr_266M",    "osc", 0,
+                               266000000);
+       clk[ZX296702_PLL_AUDIO_294M912] =
+               clk_register_fixed_rate(NULL, "pll_audio_294M912", "osc", 0,
+                               294912000);
+
+       /* bus clock */
+       clk[ZX296702_MATRIX_ACLK] =
+               zx_mux("matrix_aclk", matrix_aclk_sel,
+                               ARRAY_SIZE(matrix_aclk_sel), CLK_MUX, 2, 2);
+       clk[ZX296702_MAIN_HCLK] =
+               zx_divtbl("main_hclk", "matrix_aclk", CLK_DIV, 0, 2,
+                               main_hlk_div);
+       clk[ZX296702_MAIN_PCLK] =
+               zx_divtbl("main_pclk", "matrix_aclk", CLK_DIV, 2, 2,
+                               main_hlk_div);
+
+       /* cpu clock */
+       clk[ZX296702_CLK_500] =
+               clk_register_fixed_factor(NULL, "clk_500", "pll_mac_1000M", 0,
+                               1, 2);
+       clk[ZX296702_CLK_250] =
+               clk_register_fixed_factor(NULL, "clk_250", "pll_mac_1000M", 0,
+                               1, 4);
+       clk[ZX296702_CLK_125] =
+               clk_register_fixed_factor(NULL, "clk_125", "clk_250", 0, 1, 2);
+       clk[ZX296702_CLK_148M5] =
+               clk_register_fixed_factor(NULL, "clk_148M5", "pll_mm0_1188M", 0,
+                               1, 8);
+       clk[ZX296702_CLK_74M25] =
+               clk_register_fixed_factor(NULL, "clk_74M25", "pll_mm0_1188M", 0,
+                               1, 16);
+       clk[ZX296702_A9_WCLK] =
+               zx_mux("a9_wclk", a9_wclk_sel, ARRAY_SIZE(a9_wclk_sel), CLK_MUX,
+                               0, 2);
+       clk[ZX296702_A9_AS1_ACLK_MUX] =
+               zx_mux("a9_as1_aclk_mux", a9_as1_aclk_sel,
+                               ARRAY_SIZE(a9_as1_aclk_sel), CLK_MUX, 4, 2);
+       clk[ZX296702_A9_TRACE_CLKIN_MUX] =
+               zx_mux("a9_trace_clkin_mux", a9_trace_clkin_sel,
+                               ARRAY_SIZE(a9_trace_clkin_sel), CLK_MUX1, 0, 2);
+       clk[ZX296702_A9_AS1_ACLK_DIV] =
+               zx_divtbl("a9_as1_aclk_div", "a9_as1_aclk_mux", CLK_DIV, 4, 2,
+                               a9_as1_aclk_divider);
+
+       /* multi-media clock */
+       clk[ZX296702_CLK_2] =
+               clk_register_fixed_factor(NULL, "clk_2", "pll_mm1_72M", 0,
+                               1, 36);
+       clk[ZX296702_CLK_27] =
+               clk_register_fixed_factor(NULL, "clk_27", "pll_mm1_54M", 0,
+                               1, 2);
+       clk[ZX296702_DECPPU_ACLK_MUX] =
+               zx_mux("decppu_aclk_mux", decppu_aclk_sel,
+                               ARRAY_SIZE(decppu_aclk_sel), CLK_MUX, 6, 2);
+       clk[ZX296702_PPU_ACLK_MUX] =
+               zx_mux("ppu_aclk_mux", decppu_aclk_sel,
+                               ARRAY_SIZE(decppu_aclk_sel), CLK_MUX, 8, 2);
+       clk[ZX296702_MALI400_ACLK_MUX] =
+               zx_mux("mali400_aclk_mux", decppu_aclk_sel,
+                               ARRAY_SIZE(decppu_aclk_sel), CLK_MUX, 12, 2);
+       clk[ZX296702_VOU_ACLK_MUX] =
+               zx_mux("vou_aclk_mux", decppu_aclk_sel,
+                               ARRAY_SIZE(decppu_aclk_sel), CLK_MUX, 10, 2);
+       clk[ZX296702_VOU_MAIN_WCLK_MUX] =
+               zx_mux("vou_main_wclk_mux", vou_main_wclk_sel,
+                               ARRAY_SIZE(vou_main_wclk_sel), CLK_MUX, 14, 2);
+       clk[ZX296702_VOU_AUX_WCLK_MUX] =
+               zx_mux("vou_aux_wclk_mux", vou_main_wclk_sel,
+                               ARRAY_SIZE(vou_main_wclk_sel), CLK_MUX, 16, 2);
+       clk[ZX296702_VOU_SCALER_WCLK_MUX] =
+               zx_mux("vou_scaler_wclk_mux", vou_scaler_wclk_sel,
+                               ARRAY_SIZE(vou_scaler_wclk_sel), CLK_MUX,
+                               18, 2);
+       clk[ZX296702_R2D_ACLK_MUX] =
+               zx_mux("r2d_aclk_mux", decppu_aclk_sel,
+                               ARRAY_SIZE(decppu_aclk_sel), CLK_MUX, 20, 2);
+       clk[ZX296702_R2D_WCLK_MUX] =
+               zx_mux("r2d_wclk_mux", r2d_wclk_sel,
+                               ARRAY_SIZE(r2d_wclk_sel), CLK_MUX, 22, 2);
+
+       /* other clock */
+       clk[ZX296702_CLK_50] =
+               clk_register_fixed_factor(NULL, "clk_50", "pll_mac_1000M",
+                               0, 1, 20);
+       clk[ZX296702_CLK_25] =
+               clk_register_fixed_factor(NULL, "clk_25", "pll_mac_1000M",
+                               0, 1, 40);
+       clk[ZX296702_CLK_12] =
+               clk_register_fixed_factor(NULL, "clk_12", "pll_mm1_72M",
+                               0, 1, 6);
+       clk[ZX296702_CLK_16M384] =
+               clk_register_fixed_factor(NULL, "clk_16M384",
+                               "pll_audio_294M912", 0, 1, 18);
+       clk[ZX296702_CLK_32K768] =
+               clk_register_fixed_factor(NULL, "clk_32K768", "clk_16M384",
+                               0, 1, 500);
+       clk[ZX296702_SEC_WCLK_DIV] =
+               zx_divtbl("sec_wclk_div", "pll_lsp_104M", CLK_DIV, 6, 3,
+                               sec_wclk_divider);
+       clk[ZX296702_DDR_WCLK_MUX] =
+               zx_mux("ddr_wclk_mux", ddr_wclk_sel,
+                               ARRAY_SIZE(ddr_wclk_sel), CLK_MUX, 24, 2);
+       clk[ZX296702_NAND_WCLK_MUX] =
+               zx_mux("nand_wclk_mux", nand_wclk_sel,
+                               ARRAY_SIZE(nand_wclk_sel), CLK_MUX, 24, 2);
+       clk[ZX296702_LSP_26_WCLK_MUX] =
+               zx_mux("lsp_26_wclk_mux", lsp_26_wclk_sel,
+                               ARRAY_SIZE(lsp_26_wclk_sel), CLK_MUX, 27, 1);
+
+       /* gates */
+       clk[ZX296702_A9_AS0_ACLK] =
+               zx_gate("a9_as0_aclk",  "matrix_aclk",          CLK_EN0, 0);
+       clk[ZX296702_A9_AS1_ACLK] =
+               zx_gate("a9_as1_aclk",  "a9_as1_aclk_div",      CLK_EN0, 1);
+       clk[ZX296702_A9_TRACE_CLKIN] =
+               zx_gate("a9_trace_clkin", "a9_trace_clkin_mux", CLK_EN0, 2);
+       clk[ZX296702_DECPPU_AXI_M_ACLK] =
+               zx_gate("decppu_axi_m_aclk", "decppu_aclk_mux", CLK_EN0, 3);
+       clk[ZX296702_DECPPU_AHB_S_HCLK] =
+               zx_gate("decppu_ahb_s_hclk",    "main_hclk",    CLK_EN0, 4);
+       clk[ZX296702_PPU_AXI_M_ACLK] =
+               zx_gate("ppu_axi_m_aclk",       "ppu_aclk_mux", CLK_EN0, 5);
+       clk[ZX296702_PPU_AHB_S_HCLK] =
+               zx_gate("ppu_ahb_s_hclk",       "main_hclk",    CLK_EN0, 6);
+       clk[ZX296702_VOU_AXI_M_ACLK] =
+               zx_gate("vou_axi_m_aclk",       "vou_aclk_mux", CLK_EN0, 7);
+       clk[ZX296702_VOU_APB_PCLK] =
+               zx_gate("vou_apb_pclk", "main_pclk",            CLK_EN0, 8);
+       clk[ZX296702_VOU_MAIN_CHANNEL_WCLK] =
+               zx_gate("vou_main_channel_wclk", "vou_main_wclk_mux",
+                               CLK_EN0, 9);
+       clk[ZX296702_VOU_AUX_CHANNEL_WCLK] =
+               zx_gate("vou_aux_channel_wclk", "vou_aux_wclk_mux",
+                               CLK_EN0, 10);
+       clk[ZX296702_VOU_HDMI_OSCLK_CEC] =
+               zx_gate("vou_hdmi_osclk_cec", "clk_2",          CLK_EN0, 11);
+       clk[ZX296702_VOU_SCALER_WCLK] =
+               zx_gate("vou_scaler_wclk", "vou_scaler_wclk_mux", CLK_EN0, 12);
+       clk[ZX296702_MALI400_AXI_M_ACLK] =
+               zx_gate("mali400_axi_m_aclk", "mali400_aclk_mux", CLK_EN0, 13);
+       clk[ZX296702_MALI400_APB_PCLK] =
+               zx_gate("mali400_apb_pclk",     "main_pclk",    CLK_EN0, 14);
+       clk[ZX296702_R2D_WCLK] =
+               zx_gate("r2d_wclk",             "r2d_wclk_mux", CLK_EN0, 15);
+       clk[ZX296702_R2D_AXI_M_ACLK] =
+               zx_gate("r2d_axi_m_aclk",       "r2d_aclk_mux", CLK_EN0, 16);
+       clk[ZX296702_R2D_AHB_HCLK] =
+               zx_gate("r2d_ahb_hclk",         "main_hclk",    CLK_EN0, 17);
+       clk[ZX296702_DDR3_AXI_S0_ACLK] =
+               zx_gate("ddr3_axi_s0_aclk",     "matrix_aclk",  CLK_EN0, 18);
+       clk[ZX296702_DDR3_APB_PCLK] =
+               zx_gate("ddr3_apb_pclk",        "main_pclk",    CLK_EN0, 19);
+       clk[ZX296702_DDR3_WCLK] =
+               zx_gate("ddr3_wclk",            "ddr_wclk_mux", CLK_EN0, 20);
+       clk[ZX296702_USB20_0_AHB_HCLK] =
+               zx_gate("usb20_0_ahb_hclk",     "main_hclk",    CLK_EN0, 21);
+       clk[ZX296702_USB20_0_EXTREFCLK] =
+               zx_gate("usb20_0_extrefclk",    "clk_12",       CLK_EN0, 22);
+       clk[ZX296702_USB20_1_AHB_HCLK] =
+               zx_gate("usb20_1_ahb_hclk",     "main_hclk",    CLK_EN0, 23);
+       clk[ZX296702_USB20_1_EXTREFCLK] =
+               zx_gate("usb20_1_extrefclk",    "clk_12",       CLK_EN0, 24);
+       clk[ZX296702_USB20_2_AHB_HCLK] =
+               zx_gate("usb20_2_ahb_hclk",     "main_hclk",    CLK_EN0, 25);
+       clk[ZX296702_USB20_2_EXTREFCLK] =
+               zx_gate("usb20_2_extrefclk",    "clk_12",       CLK_EN0, 26);
+       clk[ZX296702_GMAC_AXI_M_ACLK] =
+               zx_gate("gmac_axi_m_aclk",      "matrix_aclk",  CLK_EN0, 27);
+       clk[ZX296702_GMAC_APB_PCLK] =
+               zx_gate("gmac_apb_pclk",        "main_pclk",    CLK_EN0, 28);
+       clk[ZX296702_GMAC_125_CLKIN] =
+               zx_gate("gmac_125_clkin",       "clk_125",      CLK_EN0, 29);
+       clk[ZX296702_GMAC_RMII_CLKIN] =
+               zx_gate("gmac_rmii_clkin",      "clk_50",       CLK_EN0, 30);
+       clk[ZX296702_GMAC_25M_CLK] =
+               zx_gate("gmac_25M_clk",         "clk_25",       CLK_EN0, 31);
+       clk[ZX296702_NANDFLASH_AHB_HCLK] =
+               zx_gate("nandflash_ahb_hclk", "main_hclk",      CLK_EN1, 0);
+       clk[ZX296702_NANDFLASH_WCLK] =
+               zx_gate("nandflash_wclk",     "nand_wclk_mux",  CLK_EN1, 1);
+       clk[ZX296702_LSP0_APB_PCLK] =
+               zx_gate("lsp0_apb_pclk",        "main_pclk",    CLK_EN1, 2);
+       clk[ZX296702_LSP0_AHB_HCLK] =
+               zx_gate("lsp0_ahb_hclk",        "main_hclk",    CLK_EN1, 3);
+       clk[ZX296702_LSP0_26M_WCLK] =
+               zx_gate("lsp0_26M_wclk",   "lsp_26_wclk_mux",   CLK_EN1, 4);
+       clk[ZX296702_LSP0_104M_WCLK] =
+               zx_gate("lsp0_104M_wclk",       "pll_lsp_104M", CLK_EN1, 5);
+       clk[ZX296702_LSP0_16M384_WCLK] =
+               zx_gate("lsp0_16M384_wclk",     "clk_16M384",   CLK_EN1, 6);
+       clk[ZX296702_LSP1_APB_PCLK] =
+               zx_gate("lsp1_apb_pclk",        "main_pclk",    CLK_EN1, 7);
+       /* FIXME: wclk enable bit is bit8. We hack it as reserved 31 for
+        * UART does not work after parent clk is disabled/enabled */
+       clk[ZX296702_LSP1_26M_WCLK] =
+               zx_gate("lsp1_26M_wclk",     "lsp_26_wclk_mux", CLK_EN1, 31);
+       clk[ZX296702_LSP1_104M_WCLK] =
+               zx_gate("lsp1_104M_wclk",    "pll_lsp_104M",    CLK_EN1, 9);
+       clk[ZX296702_LSP1_32K_CLK] =
+               zx_gate("lsp1_32K_clk", "clk_32K768",           CLK_EN1, 10);
+       clk[ZX296702_AON_HCLK] =
+               zx_gate("aon_hclk",             "main_hclk",    CLK_EN1, 11);
+       clk[ZX296702_SYS_CTRL_PCLK] =
+               zx_gate("sys_ctrl_pclk",        "main_pclk",    CLK_EN1, 12);
+       clk[ZX296702_DMA_PCLK] =
+               zx_gate("dma_pclk",             "main_pclk",    CLK_EN1, 13);
+       clk[ZX296702_DMA_ACLK] =
+               zx_gate("dma_aclk",             "matrix_aclk",  CLK_EN1, 14);
+       clk[ZX296702_SEC_HCLK] =
+               zx_gate("sec_hclk",             "main_hclk",    CLK_EN1, 15);
+       clk[ZX296702_AES_WCLK] =
+               zx_gate("aes_wclk",             "sec_wclk_div", CLK_EN1, 16);
+       clk[ZX296702_DES_WCLK] =
+               zx_gate("des_wclk",             "sec_wclk_div", CLK_EN1, 17);
+       clk[ZX296702_IRAM_ACLK] =
+               zx_gate("iram_aclk",            "matrix_aclk",  CLK_EN1, 18);
+       clk[ZX296702_IROM_ACLK] =
+               zx_gate("irom_aclk",            "matrix_aclk",  CLK_EN1, 19);
+       clk[ZX296702_BOOT_CTRL_HCLK] =
+               zx_gate("boot_ctrl_hclk",       "main_hclk",    CLK_EN1, 20);
+       clk[ZX296702_EFUSE_CLK_30] =
+               zx_gate("efuse_clk_30", "osc",                  CLK_EN1, 21);
+
+       /* TODO: add VOU Local clocks */
+       clk[ZX296702_VOU_MAIN_CHANNEL_DIV] =
+               zx_div("vou_main_channel_div", "vou_main_channel_wclk",
+                               VOU_LOCAL_DIV2_SET, 1, 1);
+       clk[ZX296702_VOU_AUX_CHANNEL_DIV] =
+               zx_div("vou_aux_channel_div", "vou_aux_channel_wclk",
+                               VOU_LOCAL_DIV2_SET, 0, 1);
+       clk[ZX296702_VOU_TV_ENC_HD_DIV] =
+               zx_div("vou_tv_enc_hd_div", "vou_tv_enc_hd_mux",
+                               VOU_LOCAL_DIV2_SET, 3, 1);
+       clk[ZX296702_VOU_TV_ENC_SD_DIV] =
+               zx_div("vou_tv_enc_sd_div", "vou_tv_enc_sd_mux",
+                               VOU_LOCAL_DIV2_SET, 2, 1);
+       clk[ZX296702_VL0_MUX] =
+               zx_mux("vl0_mux", vl0_sel, ARRAY_SIZE(vl0_sel),
+                               VOU_LOCAL_CLKSEL, 8, 1);
+       clk[ZX296702_VL1_MUX] =
+               zx_mux("vl1_mux", vl0_sel, ARRAY_SIZE(vl0_sel),
+                               VOU_LOCAL_CLKSEL, 9, 1);
+       clk[ZX296702_VL2_MUX] =
+               zx_mux("vl2_mux", vl0_sel, ARRAY_SIZE(vl0_sel),
+                               VOU_LOCAL_CLKSEL, 10, 1);
+       clk[ZX296702_GL0_MUX] =
+               zx_mux("gl0_mux", vl0_sel, ARRAY_SIZE(vl0_sel),
+                               VOU_LOCAL_CLKSEL, 5, 1);
+       clk[ZX296702_GL1_MUX] =
+               zx_mux("gl1_mux", vl0_sel, ARRAY_SIZE(vl0_sel),
+                               VOU_LOCAL_CLKSEL, 6, 1);
+       clk[ZX296702_GL2_MUX] =
+               zx_mux("gl2_mux", vl0_sel, ARRAY_SIZE(vl0_sel),
+                               VOU_LOCAL_CLKSEL, 7, 1);
+       clk[ZX296702_WB_MUX] =
+               zx_mux("wb_mux",  vl0_sel, ARRAY_SIZE(vl0_sel),
+                               VOU_LOCAL_CLKSEL, 11, 1);
+       clk[ZX296702_HDMI_MUX] =
+               zx_mux("hdmi_mux", hdmi_sel, ARRAY_SIZE(hdmi_sel),
+                               VOU_LOCAL_CLKSEL, 4, 1);
+       clk[ZX296702_VOU_TV_ENC_HD_MUX] =
+               zx_mux("vou_tv_enc_hd_mux", hdmi_sel, ARRAY_SIZE(hdmi_sel),
+                               VOU_LOCAL_CLKSEL, 3, 1);
+       clk[ZX296702_VOU_TV_ENC_SD_MUX] =
+               zx_mux("vou_tv_enc_sd_mux", hdmi_sel, ARRAY_SIZE(hdmi_sel),
+                               VOU_LOCAL_CLKSEL, 2, 1);
+       clk[ZX296702_VL0_CLK] =
+               zx_gate("vl0_clk", "vl0_mux", VOU_LOCAL_CLKEN, 8);
+       clk[ZX296702_VL1_CLK] =
+               zx_gate("vl1_clk", "vl1_mux", VOU_LOCAL_CLKEN, 9);
+       clk[ZX296702_VL2_CLK] =
+               zx_gate("vl2_clk", "vl2_mux", VOU_LOCAL_CLKEN, 10);
+       clk[ZX296702_GL0_CLK] =
+               zx_gate("gl0_clk", "gl0_mux", VOU_LOCAL_CLKEN, 5);
+       clk[ZX296702_GL1_CLK] =
+               zx_gate("gl1_clk", "gl1_mux", VOU_LOCAL_CLKEN, 6);
+       clk[ZX296702_GL2_CLK] =
+               zx_gate("gl2_clk", "gl2_mux", VOU_LOCAL_CLKEN, 7);
+       clk[ZX296702_WB_CLK] =
+               zx_gate("wb_clk", "wb_mux", VOU_LOCAL_CLKEN, 11);
+       clk[ZX296702_CL_CLK] =
+               zx_gate("cl_clk", "vou_main_channel_div", VOU_LOCAL_CLKEN, 12);
+       clk[ZX296702_MAIN_MIX_CLK] =
+               zx_gate("main_mix_clk", "vou_main_channel_div",
+                               VOU_LOCAL_CLKEN, 4);
+       clk[ZX296702_AUX_MIX_CLK] =
+               zx_gate("aux_mix_clk", "vou_aux_channel_div",
+                               VOU_LOCAL_CLKEN, 3);
+       clk[ZX296702_HDMI_CLK] =
+               zx_gate("hdmi_clk", "hdmi_mux", VOU_LOCAL_CLKEN, 2);
+       clk[ZX296702_VOU_TV_ENC_HD_DAC_CLK] =
+               zx_gate("vou_tv_enc_hd_dac_clk", "vou_tv_enc_hd_div",
+                               VOU_LOCAL_CLKEN, 1);
+       clk[ZX296702_VOU_TV_ENC_SD_DAC_CLK] =
+               zx_gate("vou_tv_enc_sd_dac_clk", "vou_tv_enc_sd_div",
+                               VOU_LOCAL_CLKEN, 0);
+
+       /* CA9 PERIPHCLK = a9_wclk / 2 */
+       clk[ZX296702_A9_PERIPHCLK] =
+               clk_register_fixed_factor(NULL, "a9_periphclk", "a9_wclk",
+                               0, 1, 2);
+
+       for (i = 0; i < ARRAY_SIZE(topclk); i++) {
+               if (IS_ERR(clk[i])) {
+                       pr_err("zx296702 clk %d: register failed with %ld\n",
+                               i, PTR_ERR(clk[i]));
+                       return;
+               }
+       }
+
+       topclk_data.clks = topclk;
+       topclk_data.clk_num = ARRAY_SIZE(topclk);
+       of_clk_add_provider(np, of_clk_src_onecell_get, &topclk_data);
+}
+CLK_OF_DECLARE(zx296702_top_clk, "zte,zx296702-topcrm-clk",
+               zx296702_top_clocks_init);
+
+static void __init zx296702_lsp0_clocks_init(struct device_node *np)
+{
+       struct clk **clk = lsp0clk;
+       int i;
+
+       lsp0crpm_base = of_iomap(np, 0);
+       WARN_ON(!lsp0crpm_base);
+
+       /* SDMMC1 */
+       clk[ZX296702_SDMMC1_WCLK_MUX] =
+               zx_mux("sdmmc1_wclk_mux", sdmmc1_wclk_sel,
+                               ARRAY_SIZE(sdmmc1_wclk_sel), CLK_SDMMC1, 4, 1);
+       clk[ZX296702_SDMMC1_WCLK_DIV] =
+               zx_div("sdmmc1_wclk_div", "sdmmc1_wclk_mux", CLK_SDMMC1, 12, 4);
+       clk[ZX296702_SDMMC1_WCLK] =
+               zx_gate("sdmmc1_wclk", "sdmmc1_wclk_div", CLK_SDMMC1, 1);
+       clk[ZX296702_SDMMC1_PCLK] =
+               zx_gate("sdmmc1_pclk", "lsp1_apb_pclk", CLK_SDMMC1, 0);
+
+       for (i = 0; i < ARRAY_SIZE(lsp0clk); i++) {
+               if (IS_ERR(clk[i])) {
+                       pr_err("zx296702 clk %d: register failed with %ld\n",
+                               i, PTR_ERR(clk[i]));
+                       return;
+               }
+       }
+
+       lsp0clk_data.clks = lsp0clk;
+       lsp0clk_data.clk_num = ARRAY_SIZE(lsp0clk);
+       of_clk_add_provider(np, of_clk_src_onecell_get, &lsp0clk_data);
+}
+CLK_OF_DECLARE(zx296702_lsp0_clk, "zte,zx296702-lsp0crpm-clk",
+               zx296702_lsp0_clocks_init);
+
+static void __init zx296702_lsp1_clocks_init(struct device_node *np)
+{
+       struct clk **clk = lsp1clk;
+       int i;
+
+       lsp1crpm_base = of_iomap(np, 0);
+       WARN_ON(!lsp1crpm_base);
+
+       /* UART0 */
+       clk[ZX296702_UART0_WCLK_MUX] =
+               zx_mux("uart0_wclk_mux", uart_wclk_sel,
+                               ARRAY_SIZE(uart_wclk_sel), CLK_UART0, 4, 1);
+       /* FIXME: uart wclk enable bit is bit1 in. We hack it as reserved 31 for
+        * UART does not work after parent clk is disabled/enabled */
+       clk[ZX296702_UART0_WCLK] =
+               zx_gate("uart0_wclk", "uart0_wclk_mux", CLK_UART0, 31);
+       clk[ZX296702_UART0_PCLK] =
+               zx_gate("uart0_pclk", "lsp1_apb_pclk", CLK_UART0, 0);
+
+       /* UART1 */
+       clk[ZX296702_UART1_WCLK_MUX] =
+               zx_mux("uart1_wclk_mux", uart_wclk_sel,
+                               ARRAY_SIZE(uart_wclk_sel), CLK_UART1, 4, 1);
+       clk[ZX296702_UART1_WCLK] =
+               zx_gate("uart1_wclk", "uart1_wclk_mux", CLK_UART1, 1);
+       clk[ZX296702_UART1_PCLK] =
+               zx_gate("uart1_pclk", "lsp1_apb_pclk", CLK_UART1, 0);
+
+       /* SDMMC0 */
+       clk[ZX296702_SDMMC0_WCLK_MUX] =
+               zx_mux("sdmmc0_wclk_mux", sdmmc0_wclk_sel,
+                               ARRAY_SIZE(sdmmc0_wclk_sel), CLK_SDMMC0, 4, 1);
+       clk[ZX296702_SDMMC0_WCLK_DIV] =
+               zx_div("sdmmc0_wclk_div", "sdmmc0_wclk_mux", CLK_SDMMC0, 12, 4);
+       clk[ZX296702_SDMMC0_WCLK] =
+               zx_gate("sdmmc0_wclk", "sdmmc0_wclk_div", CLK_SDMMC0, 1);
+       clk[ZX296702_SDMMC0_PCLK] =
+               zx_gate("sdmmc0_pclk", "lsp1_apb_pclk", CLK_SDMMC0, 0);
+
+       for (i = 0; i < ARRAY_SIZE(lsp1clk); i++) {
+               if (IS_ERR(clk[i])) {
+                       pr_err("zx296702 clk %d: register failed with %ld\n",
+                               i, PTR_ERR(clk[i]));
+                       return;
+               }
+       }
+
+       lsp1clk_data.clks = lsp1clk;
+       lsp1clk_data.clk_num = ARRAY_SIZE(lsp1clk);
+       of_clk_add_provider(np, of_clk_src_onecell_get, &lsp1clk_data);
+}
+CLK_OF_DECLARE(zx296702_lsp1_clk, "zte,zx296702-lsp1crpm-clk",
+               zx296702_lsp1_clocks_init);
diff --git a/drivers/clk/zte/clk.h b/drivers/clk/zte/clk.h
new file mode 100644 (file)
index 0000000..0914a82
--- /dev/null
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2015 Linaro Ltd.
+ * Copyright (C) 2014 ZTE Corporation.
+ *
+ * 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.
+ */
+
+#ifndef __ZTE_CLK_H
+#define __ZTE_CLK_H
+#include <linux/clk-provider.h>
+#include <linux/spinlock.h>
+
+struct zx_pll_config {
+       unsigned long rate;
+       u32 cfg0;
+       u32 cfg1;
+};
+
+struct clk_zx_pll {
+       struct clk_hw hw;
+       void __iomem *reg_base;
+       const struct zx_pll_config *lookup_table; /* order by rate asc */
+       int count;
+       spinlock_t *lock;
+};
+
+struct clk *clk_register_zx_pll(const char *name, const char *parent_name,
+       unsigned long flags, void __iomem *reg_base,
+       const struct zx_pll_config *lookup_table, int count, spinlock_t *lock);
+#endif
index 51d7865..618102e 100644 (file)
@@ -258,4 +258,10 @@ config CLKSRC_PXA
        help
          This enables OST0 support available on PXA and SA-11x0
          platforms.
+
+config CLKSRC_IMX_GPT
+       bool "Clocksource using i.MX GPT" if COMPILE_TEST
+       depends on ARM && CLKDEV_LOOKUP
+       select CLKSRC_MMIO
+
 endmenu
index 5b85f6a..fce332c 100644 (file)
@@ -51,4 +51,5 @@ obj-$(CONFIG_ARCH_KEYSTONE)           += timer-keystone.o
 obj-$(CONFIG_ARCH_INTEGRATOR_AP)       += timer-integrator-ap.o
 obj-$(CONFIG_CLKSRC_VERSATILE)         += versatile.o
 obj-$(CONFIG_CLKSRC_MIPS_GIC)          += mips-gic-timer.o
+obj-$(CONFIG_CLKSRC_IMX_GPT)           += timer-imx-gpt.o
 obj-$(CONFIG_ASM9260_TIMER)            += asm9260_timer.o
diff --git a/drivers/clocksource/timer-imx-gpt.c b/drivers/clocksource/timer-imx-gpt.c
new file mode 100644 (file)
index 0000000..879c784
--- /dev/null
@@ -0,0 +1,540 @@
+/*
+ *  linux/arch/arm/plat-mxc/time.c
+ *
+ *  Copyright (C) 2000-2001 Deep Blue Solutions
+ *  Copyright (C) 2002 Shane Nay (shane@minirl.com)
+ *  Copyright (C) 2006-2007 Pavel Pisa (ppisa@pikron.com)
+ *  Copyright (C) 2008 Juergen Beisert (kernel@pengutronix.de)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * 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/interrupt.h>
+#include <linux/irq.h>
+#include <linux/clockchips.h>
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/sched_clock.h>
+#include <linux/slab.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+#include <soc/imx/timer.h>
+
+/*
+ * There are 4 versions of the timer hardware on Freescale MXC hardware.
+ *  - MX1/MXL
+ *  - MX21, MX27.
+ *  - MX25, MX31, MX35, MX37, MX51, MX6Q(rev1.0)
+ *  - MX6DL, MX6SX, MX6Q(rev1.1+)
+ */
+
+/* defines common for all i.MX */
+#define MXC_TCTL               0x00
+#define MXC_TCTL_TEN           (1 << 0) /* Enable module */
+#define MXC_TPRER              0x04
+
+/* MX1, MX21, MX27 */
+#define MX1_2_TCTL_CLK_PCLK1   (1 << 1)
+#define MX1_2_TCTL_IRQEN       (1 << 4)
+#define MX1_2_TCTL_FRR         (1 << 8)
+#define MX1_2_TCMP             0x08
+#define MX1_2_TCN              0x10
+#define MX1_2_TSTAT            0x14
+
+/* MX21, MX27 */
+#define MX2_TSTAT_CAPT         (1 << 1)
+#define MX2_TSTAT_COMP         (1 << 0)
+
+/* MX31, MX35, MX25, MX5, MX6 */
+#define V2_TCTL_WAITEN         (1 << 3) /* Wait enable mode */
+#define V2_TCTL_CLK_IPG                (1 << 6)
+#define V2_TCTL_CLK_PER                (2 << 6)
+#define V2_TCTL_CLK_OSC_DIV8   (5 << 6)
+#define V2_TCTL_FRR            (1 << 9)
+#define V2_TCTL_24MEN          (1 << 10)
+#define V2_TPRER_PRE24M                12
+#define V2_IR                  0x0c
+#define V2_TSTAT               0x08
+#define V2_TSTAT_OF1           (1 << 0)
+#define V2_TCN                 0x24
+#define V2_TCMP                        0x10
+
+#define V2_TIMER_RATE_OSC_DIV8 3000000
+
+struct imx_timer {
+       enum imx_gpt_type type;
+       void __iomem *base;
+       int irq;
+       struct clk *clk_per;
+       struct clk *clk_ipg;
+       const struct imx_gpt_data *gpt;
+       struct clock_event_device ced;
+       enum clock_event_mode cem;
+       struct irqaction act;
+};
+
+struct imx_gpt_data {
+       int reg_tstat;
+       int reg_tcn;
+       int reg_tcmp;
+       void (*gpt_setup_tctl)(struct imx_timer *imxtm);
+       void (*gpt_irq_enable)(struct imx_timer *imxtm);
+       void (*gpt_irq_disable)(struct imx_timer *imxtm);
+       void (*gpt_irq_acknowledge)(struct imx_timer *imxtm);
+       int (*set_next_event)(unsigned long evt,
+                             struct clock_event_device *ced);
+};
+
+static inline struct imx_timer *to_imx_timer(struct clock_event_device *ced)
+{
+       return container_of(ced, struct imx_timer, ced);
+}
+
+static void imx1_gpt_irq_disable(struct imx_timer *imxtm)
+{
+       unsigned int tmp;
+
+       tmp = readl_relaxed(imxtm->base + MXC_TCTL);
+       writel_relaxed(tmp & ~MX1_2_TCTL_IRQEN, imxtm->base + MXC_TCTL);
+}
+#define imx21_gpt_irq_disable imx1_gpt_irq_disable
+
+static void imx31_gpt_irq_disable(struct imx_timer *imxtm)
+{
+       writel_relaxed(0, imxtm->base + V2_IR);
+}
+#define imx6dl_gpt_irq_disable imx31_gpt_irq_disable
+
+static void imx1_gpt_irq_enable(struct imx_timer *imxtm)
+{
+       unsigned int tmp;
+
+       tmp = readl_relaxed(imxtm->base + MXC_TCTL);
+       writel_relaxed(tmp | MX1_2_TCTL_IRQEN, imxtm->base + MXC_TCTL);
+}
+#define imx21_gpt_irq_enable imx1_gpt_irq_enable
+
+static void imx31_gpt_irq_enable(struct imx_timer *imxtm)
+{
+       writel_relaxed(1<<0, imxtm->base + V2_IR);
+}
+#define imx6dl_gpt_irq_enable imx31_gpt_irq_enable
+
+static void imx1_gpt_irq_acknowledge(struct imx_timer *imxtm)
+{
+       writel_relaxed(0, imxtm->base + MX1_2_TSTAT);
+}
+
+static void imx21_gpt_irq_acknowledge(struct imx_timer *imxtm)
+{
+       writel_relaxed(MX2_TSTAT_CAPT | MX2_TSTAT_COMP,
+                               imxtm->base + MX1_2_TSTAT);
+}
+
+static void imx31_gpt_irq_acknowledge(struct imx_timer *imxtm)
+{
+       writel_relaxed(V2_TSTAT_OF1, imxtm->base + V2_TSTAT);
+}
+#define imx6dl_gpt_irq_acknowledge imx31_gpt_irq_acknowledge
+
+static void __iomem *sched_clock_reg;
+
+static u64 notrace mxc_read_sched_clock(void)
+{
+       return sched_clock_reg ? readl_relaxed(sched_clock_reg) : 0;
+}
+
+static struct delay_timer imx_delay_timer;
+
+static unsigned long imx_read_current_timer(void)
+{
+       return readl_relaxed(sched_clock_reg);
+}
+
+static int __init mxc_clocksource_init(struct imx_timer *imxtm)
+{
+       unsigned int c = clk_get_rate(imxtm->clk_per);
+       void __iomem *reg = imxtm->base + imxtm->gpt->reg_tcn;
+
+       imx_delay_timer.read_current_timer = &imx_read_current_timer;
+       imx_delay_timer.freq = c;
+       register_current_timer_delay(&imx_delay_timer);
+
+       sched_clock_reg = reg;
+
+       sched_clock_register(mxc_read_sched_clock, 32, c);
+       return clocksource_mmio_init(reg, "mxc_timer1", c, 200, 32,
+                       clocksource_mmio_readl_up);
+}
+
+/* clock event */
+
+static int mx1_2_set_next_event(unsigned long evt,
+                             struct clock_event_device *ced)
+{
+       struct imx_timer *imxtm = to_imx_timer(ced);
+       unsigned long tcmp;
+
+       tcmp = readl_relaxed(imxtm->base + MX1_2_TCN) + evt;
+
+       writel_relaxed(tcmp, imxtm->base + MX1_2_TCMP);
+
+       return (int)(tcmp - readl_relaxed(imxtm->base + MX1_2_TCN)) < 0 ?
+                               -ETIME : 0;
+}
+
+static int v2_set_next_event(unsigned long evt,
+                             struct clock_event_device *ced)
+{
+       struct imx_timer *imxtm = to_imx_timer(ced);
+       unsigned long tcmp;
+
+       tcmp = readl_relaxed(imxtm->base + V2_TCN) + evt;
+
+       writel_relaxed(tcmp, imxtm->base + V2_TCMP);
+
+       return evt < 0x7fffffff &&
+               (int)(tcmp - readl_relaxed(imxtm->base + V2_TCN)) < 0 ?
+                               -ETIME : 0;
+}
+
+#ifdef DEBUG
+static const char *clock_event_mode_label[] = {
+       [CLOCK_EVT_MODE_PERIODIC] = "CLOCK_EVT_MODE_PERIODIC",
+       [CLOCK_EVT_MODE_ONESHOT]  = "CLOCK_EVT_MODE_ONESHOT",
+       [CLOCK_EVT_MODE_SHUTDOWN] = "CLOCK_EVT_MODE_SHUTDOWN",
+       [CLOCK_EVT_MODE_UNUSED]   = "CLOCK_EVT_MODE_UNUSED",
+       [CLOCK_EVT_MODE_RESUME]   = "CLOCK_EVT_MODE_RESUME",
+};
+#endif /* DEBUG */
+
+static void mxc_set_mode(enum clock_event_mode mode,
+                               struct clock_event_device *ced)
+{
+       struct imx_timer *imxtm = to_imx_timer(ced);
+       unsigned long flags;
+
+       /*
+        * The timer interrupt generation is disabled at least
+        * for enough time to call mxc_set_next_event()
+        */
+       local_irq_save(flags);
+
+       /* Disable interrupt in GPT module */
+       imxtm->gpt->gpt_irq_disable(imxtm);
+
+       if (mode != imxtm->cem) {
+               u32 tcn = readl_relaxed(imxtm->base + imxtm->gpt->reg_tcn);
+               /* Set event time into far-far future */
+               writel_relaxed(tcn - 3, imxtm->base + imxtm->gpt->reg_tcmp);
+
+               /* Clear pending interrupt */
+               imxtm->gpt->gpt_irq_acknowledge(imxtm);
+       }
+
+#ifdef DEBUG
+       printk(KERN_INFO "mxc_set_mode: changing mode from %s to %s\n",
+               clock_event_mode_label[imxtm->cem],
+               clock_event_mode_label[mode]);
+#endif /* DEBUG */
+
+       /* Remember timer mode */
+       imxtm->cem = mode;
+       local_irq_restore(flags);
+
+       switch (mode) {
+       case CLOCK_EVT_MODE_PERIODIC:
+               printk(KERN_ERR"mxc_set_mode: Periodic mode is not "
+                               "supported for i.MX\n");
+               break;
+       case CLOCK_EVT_MODE_ONESHOT:
+       /*
+        * Do not put overhead of interrupt enable/disable into
+        * mxc_set_next_event(), the core has about 4 minutes
+        * to call mxc_set_next_event() or shutdown clock after
+        * mode switching
+        */
+               local_irq_save(flags);
+               imxtm->gpt->gpt_irq_enable(imxtm);
+               local_irq_restore(flags);
+               break;
+       case CLOCK_EVT_MODE_SHUTDOWN:
+       case CLOCK_EVT_MODE_UNUSED:
+       case CLOCK_EVT_MODE_RESUME:
+               /* Left event sources disabled, no more interrupts appear */
+               break;
+       }
+}
+
+/*
+ * IRQ handler for the timer
+ */
+static irqreturn_t mxc_timer_interrupt(int irq, void *dev_id)
+{
+       struct clock_event_device *ced = dev_id;
+       struct imx_timer *imxtm = to_imx_timer(ced);
+       uint32_t tstat;
+
+       tstat = readl_relaxed(imxtm->base + imxtm->gpt->reg_tstat);
+
+       imxtm->gpt->gpt_irq_acknowledge(imxtm);
+
+       ced->event_handler(ced);
+
+       return IRQ_HANDLED;
+}
+
+static int __init mxc_clockevent_init(struct imx_timer *imxtm)
+{
+       struct clock_event_device *ced = &imxtm->ced;
+       struct irqaction *act = &imxtm->act;
+
+       imxtm->cem = CLOCK_EVT_MODE_UNUSED;
+
+       ced->name = "mxc_timer1";
+       ced->features = CLOCK_EVT_FEAT_ONESHOT;
+       ced->set_mode = mxc_set_mode;
+       ced->set_next_event = imxtm->gpt->set_next_event;
+       ced->rating = 200;
+       ced->cpumask = cpumask_of(0);
+       clockevents_config_and_register(ced, clk_get_rate(imxtm->clk_per),
+                                       0xff, 0xfffffffe);
+
+       act->name = "i.MX Timer Tick";
+       act->flags = IRQF_TIMER | IRQF_IRQPOLL;
+       act->handler = mxc_timer_interrupt;
+       act->dev_id = ced;
+
+       return setup_irq(imxtm->irq, act);
+}
+
+static void imx1_gpt_setup_tctl(struct imx_timer *imxtm)
+{
+       u32 tctl_val;
+
+       tctl_val = MX1_2_TCTL_FRR | MX1_2_TCTL_CLK_PCLK1 | MXC_TCTL_TEN;
+       writel_relaxed(tctl_val, imxtm->base + MXC_TCTL);
+}
+#define imx21_gpt_setup_tctl imx1_gpt_setup_tctl
+
+static void imx31_gpt_setup_tctl(struct imx_timer *imxtm)
+{
+       u32 tctl_val;
+
+       tctl_val = V2_TCTL_FRR | V2_TCTL_WAITEN | MXC_TCTL_TEN;
+       if (clk_get_rate(imxtm->clk_per) == V2_TIMER_RATE_OSC_DIV8)
+               tctl_val |= V2_TCTL_CLK_OSC_DIV8;
+       else
+               tctl_val |= V2_TCTL_CLK_PER;
+
+       writel_relaxed(tctl_val, imxtm->base + MXC_TCTL);
+}
+
+static void imx6dl_gpt_setup_tctl(struct imx_timer *imxtm)
+{
+       u32 tctl_val;
+
+       tctl_val = V2_TCTL_FRR | V2_TCTL_WAITEN | MXC_TCTL_TEN;
+       if (clk_get_rate(imxtm->clk_per) == V2_TIMER_RATE_OSC_DIV8) {
+               tctl_val |= V2_TCTL_CLK_OSC_DIV8;
+               /* 24 / 8 = 3 MHz */
+               writel_relaxed(7 << V2_TPRER_PRE24M, imxtm->base + MXC_TPRER);
+               tctl_val |= V2_TCTL_24MEN;
+       } else {
+               tctl_val |= V2_TCTL_CLK_PER;
+       }
+
+       writel_relaxed(tctl_val, imxtm->base + MXC_TCTL);
+}
+
+static const struct imx_gpt_data imx1_gpt_data = {
+       .reg_tstat = MX1_2_TSTAT,
+       .reg_tcn = MX1_2_TCN,
+       .reg_tcmp = MX1_2_TCMP,
+       .gpt_irq_enable = imx1_gpt_irq_enable,
+       .gpt_irq_disable = imx1_gpt_irq_disable,
+       .gpt_irq_acknowledge = imx1_gpt_irq_acknowledge,
+       .gpt_setup_tctl = imx1_gpt_setup_tctl,
+       .set_next_event = mx1_2_set_next_event,
+};
+
+static const struct imx_gpt_data imx21_gpt_data = {
+       .reg_tstat = MX1_2_TSTAT,
+       .reg_tcn = MX1_2_TCN,
+       .reg_tcmp = MX1_2_TCMP,
+       .gpt_irq_enable = imx21_gpt_irq_enable,
+       .gpt_irq_disable = imx21_gpt_irq_disable,
+       .gpt_irq_acknowledge = imx21_gpt_irq_acknowledge,
+       .gpt_setup_tctl = imx21_gpt_setup_tctl,
+       .set_next_event = mx1_2_set_next_event,
+};
+
+static const struct imx_gpt_data imx31_gpt_data = {
+       .reg_tstat = V2_TSTAT,
+       .reg_tcn = V2_TCN,
+       .reg_tcmp = V2_TCMP,
+       .gpt_irq_enable = imx31_gpt_irq_enable,
+       .gpt_irq_disable = imx31_gpt_irq_disable,
+       .gpt_irq_acknowledge = imx31_gpt_irq_acknowledge,
+       .gpt_setup_tctl = imx31_gpt_setup_tctl,
+       .set_next_event = v2_set_next_event,
+};
+
+static const struct imx_gpt_data imx6dl_gpt_data = {
+       .reg_tstat = V2_TSTAT,
+       .reg_tcn = V2_TCN,
+       .reg_tcmp = V2_TCMP,
+       .gpt_irq_enable = imx6dl_gpt_irq_enable,
+       .gpt_irq_disable = imx6dl_gpt_irq_disable,
+       .gpt_irq_acknowledge = imx6dl_gpt_irq_acknowledge,
+       .gpt_setup_tctl = imx6dl_gpt_setup_tctl,
+       .set_next_event = v2_set_next_event,
+};
+
+static void __init _mxc_timer_init(struct imx_timer *imxtm)
+{
+       switch (imxtm->type) {
+       case GPT_TYPE_IMX1:
+               imxtm->gpt = &imx1_gpt_data;
+               break;
+       case GPT_TYPE_IMX21:
+               imxtm->gpt = &imx21_gpt_data;
+               break;
+       case GPT_TYPE_IMX31:
+               imxtm->gpt = &imx31_gpt_data;
+               break;
+       case GPT_TYPE_IMX6DL:
+               imxtm->gpt = &imx6dl_gpt_data;
+               break;
+       default:
+               BUG();
+       }
+
+       if (IS_ERR(imxtm->clk_per)) {
+               pr_err("i.MX timer: unable to get clk\n");
+               return;
+       }
+
+       if (!IS_ERR(imxtm->clk_ipg))
+               clk_prepare_enable(imxtm->clk_ipg);
+
+       clk_prepare_enable(imxtm->clk_per);
+
+       /*
+        * Initialise to a known state (all timers off, and timing reset)
+        */
+
+       writel_relaxed(0, imxtm->base + MXC_TCTL);
+       writel_relaxed(0, imxtm->base + MXC_TPRER); /* see datasheet note */
+
+       imxtm->gpt->gpt_setup_tctl(imxtm);
+
+       /* init and register the timer to the framework */
+       mxc_clocksource_init(imxtm);
+       mxc_clockevent_init(imxtm);
+}
+
+void __init mxc_timer_init(unsigned long pbase, int irq, enum imx_gpt_type type)
+{
+       struct imx_timer *imxtm;
+
+       imxtm = kzalloc(sizeof(*imxtm), GFP_KERNEL);
+       BUG_ON(!imxtm);
+
+       imxtm->clk_per = clk_get_sys("imx-gpt.0", "per");
+       imxtm->clk_ipg = clk_get_sys("imx-gpt.0", "ipg");
+
+       imxtm->base = ioremap(pbase, SZ_4K);
+       BUG_ON(!imxtm->base);
+
+       imxtm->type = type;
+
+       _mxc_timer_init(imxtm);
+}
+
+static void __init mxc_timer_init_dt(struct device_node *np,  enum imx_gpt_type type)
+{
+       struct imx_timer *imxtm;
+       static int initialized;
+
+       /* Support one instance only */
+       if (initialized)
+               return;
+
+       imxtm = kzalloc(sizeof(*imxtm), GFP_KERNEL);
+       BUG_ON(!imxtm);
+
+       imxtm->base = of_iomap(np, 0);
+       WARN_ON(!imxtm->base);
+       imxtm->irq = irq_of_parse_and_map(np, 0);
+
+       imxtm->clk_ipg = of_clk_get_by_name(np, "ipg");
+
+       /* Try osc_per first, and fall back to per otherwise */
+       imxtm->clk_per = of_clk_get_by_name(np, "osc_per");
+       if (IS_ERR(imxtm->clk_per))
+               imxtm->clk_per = of_clk_get_by_name(np, "per");
+
+       imxtm->type = type;
+
+       _mxc_timer_init(imxtm);
+
+       initialized = 1;
+}
+
+static void __init imx1_timer_init_dt(struct device_node *np)
+{
+       mxc_timer_init_dt(np, GPT_TYPE_IMX1);
+}
+
+static void __init imx21_timer_init_dt(struct device_node *np)
+{
+       mxc_timer_init_dt(np, GPT_TYPE_IMX21);
+}
+
+static void __init imx31_timer_init_dt(struct device_node *np)
+{
+       enum imx_gpt_type type = GPT_TYPE_IMX31;
+
+       /*
+        * We were using the same compatible string for i.MX6Q/D and i.MX6DL/S
+        * GPT device, while they actually have different programming model.
+        * This is a workaround to keep the existing i.MX6DL/S DTBs continue
+        * working with the new kernel.
+        */
+       if (of_machine_is_compatible("fsl,imx6dl"))
+               type = GPT_TYPE_IMX6DL;
+
+       mxc_timer_init_dt(np, type);
+}
+
+static void __init imx6dl_timer_init_dt(struct device_node *np)
+{
+       mxc_timer_init_dt(np, GPT_TYPE_IMX6DL);
+}
+
+CLOCKSOURCE_OF_DECLARE(imx1_timer, "fsl,imx1-gpt", imx1_timer_init_dt);
+CLOCKSOURCE_OF_DECLARE(imx21_timer, "fsl,imx21-gpt", imx21_timer_init_dt);
+CLOCKSOURCE_OF_DECLARE(imx31_timer, "fsl,imx31-gpt", imx31_timer_init_dt);
+CLOCKSOURCE_OF_DECLARE(imx25_timer, "fsl,imx25-gpt", imx31_timer_init_dt);
+CLOCKSOURCE_OF_DECLARE(imx50_timer, "fsl,imx50-gpt", imx31_timer_init_dt);
+CLOCKSOURCE_OF_DECLARE(imx51_timer, "fsl,imx51-gpt", imx31_timer_init_dt);
+CLOCKSOURCE_OF_DECLARE(imx53_timer, "fsl,imx53-gpt", imx31_timer_init_dt);
+CLOCKSOURCE_OF_DECLARE(imx6q_timer, "fsl,imx6q-gpt", imx31_timer_init_dt);
+CLOCKSOURCE_OF_DECLARE(imx6dl_timer, "fsl,imx6dl-gpt", imx6dl_timer_init_dt);
+CLOCKSOURCE_OF_DECLARE(imx6sl_timer, "fsl,imx6sl-gpt", imx6dl_timer_init_dt);
+CLOCKSOURCE_OF_DECLARE(imx6sx_timer, "fsl,imx6sx-gpt", imx6dl_timer_init_dt);
index 6de62a9..99b9a97 100644 (file)
@@ -30,6 +30,7 @@ config ARM_GIC_V3_ITS
 config ARM_NVIC
        bool
        select IRQ_DOMAIN
+       select IRQ_DOMAIN_HIERARCHY
        select GENERIC_IRQ_CHIP
 
 config ARM_VIC
index 4ff0805..5fac910 100644 (file)
@@ -49,6 +49,31 @@ nvic_handle_irq(irq_hw_number_t hwirq, struct pt_regs *regs)
        handle_IRQ(irq, regs);
 }
 
+static int nvic_irq_domain_alloc(struct irq_domain *domain, unsigned int virq,
+                               unsigned int nr_irqs, void *arg)
+{
+       int i, ret;
+       irq_hw_number_t hwirq;
+       unsigned int type = IRQ_TYPE_NONE;
+       struct of_phandle_args *irq_data = arg;
+
+       ret = irq_domain_xlate_onecell(domain, irq_data->np, irq_data->args,
+                                  irq_data->args_count, &hwirq, &type);
+       if (ret)
+               return ret;
+
+       for (i = 0; i < nr_irqs; i++)
+               irq_map_generic_chip(domain, virq + i, hwirq + i);
+
+       return 0;
+}
+
+static const struct irq_domain_ops nvic_irq_domain_ops = {
+       .xlate = irq_domain_xlate_onecell,
+       .alloc = nvic_irq_domain_alloc,
+       .free = irq_domain_free_irqs_top,
+};
+
 static int __init nvic_of_init(struct device_node *node,
                               struct device_node *parent)
 {
@@ -70,7 +95,8 @@ static int __init nvic_of_init(struct device_node *node,
                irqs = NVIC_MAX_IRQ;
 
        nvic_irq_domain =
-               irq_domain_add_linear(node, irqs, &irq_generic_chip_ops, NULL);
+               irq_domain_add_linear(node, irqs, &nvic_irq_domain_ops, NULL);
+
        if (!nvic_irq_domain) {
                pr_warn("Failed to allocate irq domain\n");
                return -ENOMEM;
index 9521057..b932ecb 100644 (file)
@@ -47,6 +47,7 @@ struct vf610_mscm_ir_chip_data {
        void __iomem *mscm_ir_base;
        u16 cpu_mask;
        u16 saved_irsprc[MSCM_IRSPRC_NUM];
+       bool is_nvic;
 };
 
 static struct vf610_mscm_ir_chip_data *mscm_ir_data;
@@ -101,7 +102,7 @@ static void vf610_mscm_ir_enable(struct irq_data *data)
        writew_relaxed(chip_data->cpu_mask,
                       chip_data->mscm_ir_base + MSCM_IRSPRC(hwirq));
 
-       irq_chip_unmask_parent(data);
+       irq_chip_enable_parent(data);
 }
 
 static void vf610_mscm_ir_disable(struct irq_data *data)
@@ -111,7 +112,7 @@ static void vf610_mscm_ir_disable(struct irq_data *data)
 
        writew_relaxed(0x0, chip_data->mscm_ir_base + MSCM_IRSPRC(hwirq));
 
-       irq_chip_mask_parent(data);
+       irq_chip_disable_parent(data);
 }
 
 static struct irq_chip vf610_mscm_ir_irq_chip = {
@@ -143,10 +144,17 @@ static int vf610_mscm_ir_domain_alloc(struct irq_domain *domain, unsigned int vi
                                              domain->host_data);
 
        gic_data.np = domain->parent->of_node;
-       gic_data.args_count = 3;
-       gic_data.args[0] = GIC_SPI;
-       gic_data.args[1] = irq_data->args[0];
-       gic_data.args[2] = irq_data->args[1];
+
+       if (mscm_ir_data->is_nvic) {
+               gic_data.args_count = 1;
+               gic_data.args[0] = irq_data->args[0];
+       } else {
+               gic_data.args_count = 3;
+               gic_data.args[0] = GIC_SPI;
+               gic_data.args[1] = irq_data->args[0];
+               gic_data.args[2] = irq_data->args[1];
+       }
+
        return irq_domain_alloc_irqs_parent(domain, virq, nr_irqs, &gic_data);
 }
 
@@ -199,6 +207,9 @@ static int __init vf610_mscm_ir_of_init(struct device_node *node,
                goto out_unmap;
        }
 
+       if (of_device_is_compatible(domain->parent->of_node, "arm,armv7m-nvic"))
+               mscm_ir_data->is_nvic = true;
+
        cpu_pm_register_notifier(&mscm_ir_notifier_block);
 
        return 0;
index 868036f..8406c66 100644 (file)
@@ -49,6 +49,14 @@ config OMAP_GPMC
          interfacing to a variety of asynchronous as well as synchronous
          memory drives like NOR, NAND, OneNAND, SRAM.
 
+config OMAP_GPMC_DEBUG
+       bool
+       depends on OMAP_GPMC
+       help
+         Enables verbose debugging mostly to decode the bootloader provided
+         timings. Enable this during development to configure devices
+         connected to the GPMC bus.
+
 config MVEBU_DEVBUS
        bool "Marvell EBU Device Bus Controller"
        default y
index c94ea0d..8911e51 100644 (file)
@@ -403,7 +403,7 @@ static void gpmc_cs_bool_timings(int cs, const struct gpmc_bool_timings *p)
                           p->cycle2cyclediffcsen);
 }
 
-#ifdef DEBUG
+#ifdef CONFIG_OMAP_GPMC_DEBUG
 /**
  * get_gpmc_timing_reg - read a timing parameter and print DTS settings for it.
  * @cs:      Chip Select Region
@@ -612,7 +612,7 @@ static int set_gpmc_timing_reg(int cs, int reg, int st_bit, int end_bit, int max
        }
 
        l = gpmc_cs_read_reg(cs, reg);
-#ifdef DEBUG
+#ifdef CONFIG_OMAP_GPMC_DEBUG
        pr_info(
                "GPMC CS%d: %-17s: %3d ticks, %3lu ns (was %3i ticks) %3d ns\n",
               cs, name, ticks, gpmc_get_clk_period(cs, cd) * ticks / 1000,
@@ -767,7 +767,7 @@ int gpmc_cs_set_timings(int cs, const struct gpmc_timings *t,
                            GPMC_CONFIG1_CLKACTIVATIONTIME_MAX,
                            clk_activation, GPMC_CD_FCLK);
 
-#ifdef DEBUG
+#ifdef CONFIG_OMAP_GPMC_DEBUG
        pr_info("GPMC CS%d CLK period is %lu ns (div %d)\n",
                        cs, (div * gpmc_get_fclk_period()) / 1000, div);
 #endif
index 5eff6f0..6acc2c4 100644 (file)
@@ -59,6 +59,7 @@ static u32 tegra20_fuse_readl(const unsigned int offset)
        int ret;
        u32 val = 0;
        struct dma_async_tx_descriptor *dma_desc;
+       unsigned long time_left;
 
        mutex_lock(&apb_dma_lock);
 
@@ -82,9 +83,10 @@ static u32 tegra20_fuse_readl(const unsigned int offset)
 
        dmaengine_submit(dma_desc);
        dma_async_issue_pending(apb_dma_chan);
-       ret = wait_for_completion_timeout(&apb_dma_wait, msecs_to_jiffies(50));
+       time_left = wait_for_completion_timeout(&apb_dma_wait,
+                                               msecs_to_jiffies(50));
 
-       if (WARN(ret == 0, "apb read dma timed out"))
+       if (WARN(time_left == 0, "apb read dma timed out"))
                dmaengine_terminate_all(apb_dma_chan);
        else
                val = *apb_buffer;
index c956395..cc119d1 100644 (file)
@@ -377,13 +377,10 @@ int tegra_pmc_cpu_remove_clamping(int cpuid)
 }
 #endif /* CONFIG_SMP */
 
-/**
- * tegra_pmc_restart() - reboot the system
- * @mode: which mode to reboot in
- * @cmd: reboot command
- */
-void tegra_pmc_restart(enum reboot_mode mode, const char *cmd)
+static int tegra_pmc_restart_notify(struct notifier_block *this,
+                                   unsigned long action, void *data)
 {
+       const char *cmd = data;
        u32 value;
 
        value = tegra_pmc_readl(PMC_SCRATCH0);
@@ -405,8 +402,15 @@ void tegra_pmc_restart(enum reboot_mode mode, const char *cmd)
        value = tegra_pmc_readl(0);
        value |= 0x10;
        tegra_pmc_writel(value, 0);
+
+       return NOTIFY_DONE;
 }
 
+static struct notifier_block tegra_pmc_restart_handler = {
+       .notifier_call = tegra_pmc_restart_notify,
+       .priority = 128,
+};
+
 static int powergate_show(struct seq_file *s, void *data)
 {
        unsigned int i;
@@ -837,6 +841,13 @@ static int tegra_pmc_probe(struct platform_device *pdev)
                        return err;
        }
 
+       err = register_restart_handler(&tegra_pmc_restart_handler);
+       if (err) {
+               dev_err(&pdev->dev, "unable to register restart handler, %d\n",
+                       err);
+               return err;
+       }
+
        return 0;
 }
 
index 2b5a9bb..7116968 100644 (file)
  * option) any later version.
  */
 
+#include <linux/delay.h>
+#include <linux/reboot.h>
 #include <linux/types.h>
 #include <linux/module.h>
 #include <linux/io.h>
 #include <linux/watchdog.h>
 #include <linux/platform_device.h>
 #include <linux/of_address.h>
+#include <linux/of_platform.h>
 
 #define PM_RSTC                                0x1c
+#define PM_RSTS                                0x20
 #define PM_WDOG                                0x24
 
 #define PM_PASSWORD                    0x5a000000
 
 #define PM_WDOG_TIME_SET               0x000fffff
 #define PM_RSTC_WRCFG_CLR              0xffffffcf
+#define PM_RSTS_HADWRH_SET             0x00000040
 #define PM_RSTC_WRCFG_SET              0x00000030
 #define PM_RSTC_WRCFG_FULL_RESET       0x00000020
 #define PM_RSTC_RESET                  0x00000102
@@ -37,6 +42,7 @@
 struct bcm2835_wdt {
        void __iomem            *base;
        spinlock_t              lock;
+       struct notifier_block   restart_handler;
 };
 
 static unsigned int heartbeat;
@@ -106,6 +112,53 @@ static struct watchdog_device bcm2835_wdt_wdd = {
        .timeout =      WDOG_TICKS_TO_SECS(PM_WDOG_TIME_SET),
 };
 
+static int
+bcm2835_restart(struct notifier_block *this, unsigned long mode, void *cmd)
+{
+       struct bcm2835_wdt *wdt = container_of(this, struct bcm2835_wdt,
+                                              restart_handler);
+       u32 val;
+
+       /* use a timeout of 10 ticks (~150us) */
+       writel_relaxed(10 | PM_PASSWORD, wdt->base + PM_WDOG);
+       val = readl_relaxed(wdt->base + PM_RSTC);
+       val &= PM_RSTC_WRCFG_CLR;
+       val |= PM_PASSWORD | PM_RSTC_WRCFG_FULL_RESET;
+       writel_relaxed(val, wdt->base + PM_RSTC);
+
+       /* No sleeping, possibly atomic. */
+       mdelay(1);
+
+       return 0;
+}
+
+/*
+ * We can't really power off, but if we do the normal reset scheme, and
+ * indicate to bootcode.bin not to reboot, then most of the chip will be
+ * powered off.
+ */
+static void bcm2835_power_off(void)
+{
+       struct device_node *np =
+               of_find_compatible_node(NULL, NULL, "brcm,bcm2835-pm-wdt");
+       struct platform_device *pdev = of_find_device_by_node(np);
+       struct bcm2835_wdt *wdt = platform_get_drvdata(pdev);
+       u32 val;
+
+       /*
+        * We set the watchdog hard reset bit here to distinguish this reset
+        * from the normal (full) reset. bootcode.bin will not reboot after a
+        * hard reset.
+        */
+       val = readl_relaxed(wdt->base + PM_RSTS);
+       val &= PM_RSTC_WRCFG_CLR;
+       val |= PM_PASSWORD | PM_RSTS_HADWRH_SET;
+       writel_relaxed(val, wdt->base + PM_RSTS);
+
+       /* Continue with normal reset mechanism */
+       bcm2835_restart(&wdt->restart_handler, REBOOT_HARD, NULL);
+}
+
 static int bcm2835_wdt_probe(struct platform_device *pdev)
 {
        struct device *dev = &pdev->dev;
@@ -136,6 +189,12 @@ static int bcm2835_wdt_probe(struct platform_device *pdev)
                return err;
        }
 
+       wdt->restart_handler.notifier_call = bcm2835_restart;
+       wdt->restart_handler.priority = 128;
+       register_restart_handler(&wdt->restart_handler);
+       if (pm_power_off == NULL)
+               pm_power_off = bcm2835_power_off;
+
        dev_info(dev, "Broadcom BCM2835 watchdog timer");
        return 0;
 }
@@ -144,6 +203,9 @@ static int bcm2835_wdt_remove(struct platform_device *pdev)
 {
        struct bcm2835_wdt *wdt = platform_get_drvdata(pdev);
 
+       unregister_restart_handler(&wdt->restart_handler);
+       if (pm_power_off == bcm2835_power_off)
+               pm_power_off = NULL;
        watchdog_unregister_device(&bcm2835_wdt_wdd);
        iounmap(wdt->base);
 
diff --git a/include/dt-bindings/clock/imx7d-clock.h b/include/dt-bindings/clock/imx7d-clock.h
new file mode 100644 (file)
index 0000000..728df28
--- /dev/null
@@ -0,0 +1,450 @@
+/*
+ * Copyright (C) 2014-2015 Freescale Semiconductor, Inc.
+ *
+ * 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.
+ *
+ */
+
+#ifndef __DT_BINDINGS_CLOCK_IMX7D_H
+#define __DT_BINDINGS_CLOCK_IMX7D_H
+
+#define IMX7D_OSC_24M_CLK              0
+#define IMX7D_PLL_ARM_MAIN             1
+#define IMX7D_PLL_ARM_MAIN_CLK         2
+#define IMX7D_PLL_ARM_MAIN_SRC         3
+#define IMX7D_PLL_ARM_MAIN_BYPASS      4
+#define IMX7D_PLL_SYS_MAIN             5
+#define IMX7D_PLL_SYS_MAIN_CLK         6
+#define IMX7D_PLL_SYS_MAIN_SRC         7
+#define IMX7D_PLL_SYS_MAIN_BYPASS      8
+#define IMX7D_PLL_SYS_MAIN_480M                9
+#define IMX7D_PLL_SYS_MAIN_240M                10
+#define IMX7D_PLL_SYS_MAIN_120M                11
+#define IMX7D_PLL_SYS_MAIN_480M_CLK    12
+#define IMX7D_PLL_SYS_MAIN_240M_CLK    13
+#define IMX7D_PLL_SYS_MAIN_120M_CLK    14
+#define IMX7D_PLL_SYS_PFD0_392M_CLK    15
+#define IMX7D_PLL_SYS_PFD0_196M                16
+#define IMX7D_PLL_SYS_PFD0_196M_CLK    17
+#define IMX7D_PLL_SYS_PFD1_332M_CLK    18
+#define IMX7D_PLL_SYS_PFD1_166M                19
+#define IMX7D_PLL_SYS_PFD1_166M_CLK    20
+#define IMX7D_PLL_SYS_PFD2_270M_CLK    21
+#define IMX7D_PLL_SYS_PFD2_135M                22
+#define IMX7D_PLL_SYS_PFD2_135M_CLK    23
+#define IMX7D_PLL_SYS_PFD3_CLK         24
+#define IMX7D_PLL_SYS_PFD4_CLK         25
+#define IMX7D_PLL_SYS_PFD5_CLK         26
+#define IMX7D_PLL_SYS_PFD6_CLK         27
+#define IMX7D_PLL_SYS_PFD7_CLK         28
+#define IMX7D_PLL_ENET_MAIN            29
+#define IMX7D_PLL_ENET_MAIN_CLK                30
+#define IMX7D_PLL_ENET_MAIN_SRC                31
+#define IMX7D_PLL_ENET_MAIN_BYPASS     32
+#define IMX7D_PLL_ENET_MAIN_500M       33
+#define IMX7D_PLL_ENET_MAIN_250M       34
+#define IMX7D_PLL_ENET_MAIN_125M       35
+#define IMX7D_PLL_ENET_MAIN_100M       36
+#define IMX7D_PLL_ENET_MAIN_50M                37
+#define IMX7D_PLL_ENET_MAIN_40M                38
+#define IMX7D_PLL_ENET_MAIN_25M                39
+#define IMX7D_PLL_ENET_MAIN_500M_CLK   40
+#define IMX7D_PLL_ENET_MAIN_250M_CLK   41
+#define IMX7D_PLL_ENET_MAIN_125M_CLK   42
+#define IMX7D_PLL_ENET_MAIN_100M_CLK   43
+#define IMX7D_PLL_ENET_MAIN_50M_CLK    44
+#define IMX7D_PLL_ENET_MAIN_40M_CLK    45
+#define IMX7D_PLL_ENET_MAIN_25M_CLK    46
+#define IMX7D_PLL_DRAM_MAIN            47
+#define IMX7D_PLL_DRAM_MAIN_CLK                48
+#define IMX7D_PLL_DRAM_MAIN_SRC                49
+#define IMX7D_PLL_DRAM_MAIN_BYPASS     50
+#define IMX7D_PLL_DRAM_MAIN_533M       51
+#define IMX7D_PLL_DRAM_MAIN_533M_CLK   52
+#define IMX7D_PLL_AUDIO_MAIN           53
+#define IMX7D_PLL_AUDIO_MAIN_CLK       54
+#define IMX7D_PLL_AUDIO_MAIN_SRC       55
+#define IMX7D_PLL_AUDIO_MAIN_BYPASS    56
+#define IMX7D_PLL_VIDEO_MAIN_CLK       57
+#define IMX7D_PLL_VIDEO_MAIN           58
+#define IMX7D_PLL_VIDEO_MAIN_SRC       59
+#define IMX7D_PLL_VIDEO_MAIN_BYPASS    60
+#define IMX7D_USB_MAIN_480M_CLK                61
+#define IMX7D_ARM_A7_ROOT_CLK          62
+#define IMX7D_ARM_A7_ROOT_SRC          63
+#define IMX7D_ARM_A7_ROOT_CG           64
+#define IMX7D_ARM_A7_ROOT_DIV          65
+#define IMX7D_ARM_M4_ROOT_CLK          66
+#define IMX7D_ARM_M4_ROOT_SRC          67
+#define IMX7D_ARM_M4_ROOT_CG           68
+#define IMX7D_ARM_M4_ROOT_DIV          69
+#define IMX7D_ARM_M0_ROOT_CLK          70
+#define IMX7D_ARM_M0_ROOT_SRC          71
+#define IMX7D_ARM_M0_ROOT_CG           72
+#define IMX7D_ARM_M0_ROOT_DIV          73
+#define IMX7D_MAIN_AXI_ROOT_CLK                74
+#define IMX7D_MAIN_AXI_ROOT_SRC                75
+#define IMX7D_MAIN_AXI_ROOT_CG         76
+#define IMX7D_MAIN_AXI_ROOT_DIV                77
+#define IMX7D_DISP_AXI_ROOT_CLK                78
+#define IMX7D_DISP_AXI_ROOT_SRC                79
+#define IMX7D_DISP_AXI_ROOT_CG         80
+#define IMX7D_DISP_AXI_ROOT_DIV                81
+#define IMX7D_ENET_AXI_ROOT_CLK                82
+#define IMX7D_ENET_AXI_ROOT_SRC                83
+#define IMX7D_ENET_AXI_ROOT_CG         84
+#define IMX7D_ENET_AXI_ROOT_DIV                85
+#define IMX7D_NAND_USDHC_BUS_ROOT_CLK  86
+#define IMX7D_NAND_USDHC_BUS_ROOT_SRC  87
+#define IMX7D_NAND_USDHC_BUS_ROOT_CG   88
+#define IMX7D_NAND_USDHC_BUS_ROOT_DIV  89
+#define IMX7D_AHB_CHANNEL_ROOT_CLK     90
+#define IMX7D_AHB_CHANNEL_ROOT_SRC     91
+#define IMX7D_AHB_CHANNEL_ROOT_CG      92
+#define IMX7D_AHB_CHANNEL_ROOT_DIV     93
+#define IMX7D_DRAM_PHYM_ROOT_CLK       94
+#define IMX7D_DRAM_PHYM_ROOT_SRC       95
+#define IMX7D_DRAM_PHYM_ROOT_CG                96
+#define IMX7D_DRAM_PHYM_ROOT_DIV       97
+#define IMX7D_DRAM_ROOT_CLK            98
+#define IMX7D_DRAM_ROOT_SRC            99
+#define IMX7D_DRAM_ROOT_CG             100
+#define IMX7D_DRAM_ROOT_DIV            101
+#define IMX7D_DRAM_PHYM_ALT_ROOT_CLK   102
+#define IMX7D_DRAM_PHYM_ALT_ROOT_SRC   103
+#define IMX7D_DRAM_PHYM_ALT_ROOT_CG    104
+#define IMX7D_DRAM_PHYM_ALT_ROOT_DIV   105
+#define IMX7D_DRAM_ALT_ROOT_CLK                106
+#define IMX7D_DRAM_ALT_ROOT_SRC                107
+#define IMX7D_DRAM_ALT_ROOT_CG         108
+#define IMX7D_DRAM_ALT_ROOT_DIV                109
+#define IMX7D_USB_HSIC_ROOT_CLK                110
+#define IMX7D_USB_HSIC_ROOT_SRC                111
+#define IMX7D_USB_HSIC_ROOT_CG         112
+#define IMX7D_USB_HSIC_ROOT_DIV                113
+#define IMX7D_PCIE_CTRL_ROOT_CLK       114
+#define IMX7D_PCIE_CTRL_ROOT_SRC       115
+#define IMX7D_PCIE_CTRL_ROOT_CG                116
+#define IMX7D_PCIE_CTRL_ROOT_DIV       117
+#define IMX7D_PCIE_PHY_ROOT_CLK                118
+#define IMX7D_PCIE_PHY_ROOT_SRC                119
+#define IMX7D_PCIE_PHY_ROOT_CG         120
+#define IMX7D_PCIE_PHY_ROOT_DIV                121
+#define IMX7D_EPDC_PIXEL_ROOT_CLK      122
+#define IMX7D_EPDC_PIXEL_ROOT_SRC      123
+#define IMX7D_EPDC_PIXEL_ROOT_CG       124
+#define IMX7D_EPDC_PIXEL_ROOT_DIV      125
+#define IMX7D_LCDIF_PIXEL_ROOT_CLK     126
+#define IMX7D_LCDIF_PIXEL_ROOT_SRC     127
+#define IMX7D_LCDIF_PIXEL_ROOT_CG      128
+#define IMX7D_LCDIF_PIXEL_ROOT_DIV     129
+#define IMX7D_MIPI_DSI_ROOT_CLK                130
+#define IMX7D_MIPI_DSI_ROOT_SRC                131
+#define IMX7D_MIPI_DSI_ROOT_CG         132
+#define IMX7D_MIPI_DSI_ROOT_DIV                133
+#define IMX7D_MIPI_CSI_ROOT_CLK                134
+#define IMX7D_MIPI_CSI_ROOT_SRC                135
+#define IMX7D_MIPI_CSI_ROOT_CG         136
+#define IMX7D_MIPI_CSI_ROOT_DIV                137
+#define IMX7D_MIPI_DPHY_ROOT_CLK       138
+#define IMX7D_MIPI_DPHY_ROOT_SRC       139
+#define IMX7D_MIPI_DPHY_ROOT_CG                140
+#define IMX7D_MIPI_DPHY_ROOT_DIV       141
+#define IMX7D_SAI1_ROOT_CLK            142
+#define IMX7D_SAI1_ROOT_SRC            143
+#define IMX7D_SAI1_ROOT_CG             144
+#define IMX7D_SAI1_ROOT_DIV            145
+#define IMX7D_SAI2_ROOT_CLK            146
+#define IMX7D_SAI2_ROOT_SRC            147
+#define IMX7D_SAI2_ROOT_CG             148
+#define IMX7D_SAI2_ROOT_DIV            149
+#define IMX7D_SAI3_ROOT_CLK            150
+#define IMX7D_SAI3_ROOT_SRC            151
+#define IMX7D_SAI3_ROOT_CG             152
+#define IMX7D_SAI3_ROOT_DIV            153
+#define IMX7D_SPDIF_ROOT_CLK           154
+#define IMX7D_SPDIF_ROOT_SRC           155
+#define IMX7D_SPDIF_ROOT_CG            156
+#define IMX7D_SPDIF_ROOT_DIV           157
+#define IMX7D_ENET1_REF_ROOT_CLK       158
+#define IMX7D_ENET1_REF_ROOT_SRC       159
+#define IMX7D_ENET1_REF_ROOT_CG                160
+#define IMX7D_ENET1_REF_ROOT_DIV       161
+#define IMX7D_ENET1_TIME_ROOT_CLK      162
+#define IMX7D_ENET1_TIME_ROOT_SRC      163
+#define IMX7D_ENET1_TIME_ROOT_CG       164
+#define IMX7D_ENET1_TIME_ROOT_DIV      165
+#define IMX7D_ENET2_REF_ROOT_CLK       166
+#define IMX7D_ENET2_REF_ROOT_SRC       167
+#define IMX7D_ENET2_REF_ROOT_CG                168
+#define IMX7D_ENET2_REF_ROOT_DIV       169
+#define IMX7D_ENET2_TIME_ROOT_CLK      170
+#define IMX7D_ENET2_TIME_ROOT_SRC      171
+#define IMX7D_ENET2_TIME_ROOT_CG       172
+#define IMX7D_ENET2_TIME_ROOT_DIV      173
+#define IMX7D_ENET_PHY_REF_ROOT_CLK    174
+#define IMX7D_ENET_PHY_REF_ROOT_SRC    175
+#define IMX7D_ENET_PHY_REF_ROOT_CG     176
+#define IMX7D_ENET_PHY_REF_ROOT_DIV    177
+#define IMX7D_EIM_ROOT_CLK             178
+#define IMX7D_EIM_ROOT_SRC             179
+#define IMX7D_EIM_ROOT_CG              180
+#define IMX7D_EIM_ROOT_DIV             181
+#define IMX7D_NAND_ROOT_CLK            182
+#define IMX7D_NAND_ROOT_SRC            183
+#define IMX7D_NAND_ROOT_CG             184
+#define IMX7D_NAND_ROOT_DIV            185
+#define IMX7D_QSPI_ROOT_CLK            186
+#define IMX7D_QSPI_ROOT_SRC            187
+#define IMX7D_QSPI_ROOT_CG             188
+#define IMX7D_QSPI_ROOT_DIV            189
+#define IMX7D_USDHC1_ROOT_CLK          190
+#define IMX7D_USDHC1_ROOT_SRC          191
+#define IMX7D_USDHC1_ROOT_CG           192
+#define IMX7D_USDHC1_ROOT_DIV          193
+#define IMX7D_USDHC2_ROOT_CLK          194
+#define IMX7D_USDHC2_ROOT_SRC          195
+#define IMX7D_USDHC2_ROOT_CG           196
+#define IMX7D_USDHC2_ROOT_DIV          197
+#define IMX7D_USDHC3_ROOT_CLK          198
+#define IMX7D_USDHC3_ROOT_SRC          199
+#define IMX7D_USDHC3_ROOT_CG           200
+#define IMX7D_USDHC3_ROOT_DIV          201
+#define IMX7D_CAN1_ROOT_CLK            202
+#define IMX7D_CAN1_ROOT_SRC            203
+#define IMX7D_CAN1_ROOT_CG             204
+#define IMX7D_CAN1_ROOT_DIV            205
+#define IMX7D_CAN2_ROOT_CLK            206
+#define IMX7D_CAN2_ROOT_SRC            207
+#define IMX7D_CAN2_ROOT_CG             208
+#define IMX7D_CAN2_ROOT_DIV            209
+#define IMX7D_I2C1_ROOT_CLK            210
+#define IMX7D_I2C1_ROOT_SRC            211
+#define IMX7D_I2C1_ROOT_CG             212
+#define IMX7D_I2C1_ROOT_DIV            213
+#define IMX7D_I2C2_ROOT_CLK            214
+#define IMX7D_I2C2_ROOT_SRC            215
+#define IMX7D_I2C2_ROOT_CG             216
+#define IMX7D_I2C2_ROOT_DIV            217
+#define IMX7D_I2C3_ROOT_CLK            218
+#define IMX7D_I2C3_ROOT_SRC            219
+#define IMX7D_I2C3_ROOT_CG             220
+#define IMX7D_I2C3_ROOT_DIV            221
+#define IMX7D_I2C4_ROOT_CLK            222
+#define IMX7D_I2C4_ROOT_SRC            223
+#define IMX7D_I2C4_ROOT_CG             224
+#define IMX7D_I2C4_ROOT_DIV            225
+#define IMX7D_UART1_ROOT_CLK           226
+#define IMX7D_UART1_ROOT_SRC           227
+#define IMX7D_UART1_ROOT_CG            228
+#define IMX7D_UART1_ROOT_DIV           229
+#define IMX7D_UART2_ROOT_CLK           230
+#define IMX7D_UART2_ROOT_SRC           231
+#define IMX7D_UART2_ROOT_CG            232
+#define IMX7D_UART2_ROOT_DIV           233
+#define IMX7D_UART3_ROOT_CLK           234
+#define IMX7D_UART3_ROOT_SRC           235
+#define IMX7D_UART3_ROOT_CG            236
+#define IMX7D_UART3_ROOT_DIV           237
+#define IMX7D_UART4_ROOT_CLK           238
+#define IMX7D_UART4_ROOT_SRC           239
+#define IMX7D_UART4_ROOT_CG            240
+#define IMX7D_UART4_ROOT_DIV           241
+#define IMX7D_UART5_ROOT_CLK           242
+#define IMX7D_UART5_ROOT_SRC           243
+#define IMX7D_UART5_ROOT_CG            244
+#define IMX7D_UART5_ROOT_DIV           245
+#define IMX7D_UART6_ROOT_CLK           246
+#define IMX7D_UART6_ROOT_SRC           247
+#define IMX7D_UART6_ROOT_CG            248
+#define IMX7D_UART6_ROOT_DIV           249
+#define IMX7D_UART7_ROOT_CLK           250
+#define IMX7D_UART7_ROOT_SRC           251
+#define IMX7D_UART7_ROOT_CG            252
+#define IMX7D_UART7_ROOT_DIV           253
+#define IMX7D_ECSPI1_ROOT_CLK          254
+#define IMX7D_ECSPI1_ROOT_SRC          255
+#define IMX7D_ECSPI1_ROOT_CG           256
+#define IMX7D_ECSPI1_ROOT_DIV          257
+#define IMX7D_ECSPI2_ROOT_CLK          258
+#define IMX7D_ECSPI2_ROOT_SRC          259
+#define IMX7D_ECSPI2_ROOT_CG           260
+#define IMX7D_ECSPI2_ROOT_DIV          261
+#define IMX7D_ECSPI3_ROOT_CLK          262
+#define IMX7D_ECSPI3_ROOT_SRC          263
+#define IMX7D_ECSPI3_ROOT_CG           264
+#define IMX7D_ECSPI3_ROOT_DIV          265
+#define IMX7D_ECSPI4_ROOT_CLK          266
+#define IMX7D_ECSPI4_ROOT_SRC          267
+#define IMX7D_ECSPI4_ROOT_CG           268
+#define IMX7D_ECSPI4_ROOT_DIV          269
+#define IMX7D_PWM1_ROOT_CLK            270
+#define IMX7D_PWM1_ROOT_SRC            271
+#define IMX7D_PWM1_ROOT_CG             272
+#define IMX7D_PWM1_ROOT_DIV            273
+#define IMX7D_PWM2_ROOT_CLK            274
+#define IMX7D_PWM2_ROOT_SRC            275
+#define IMX7D_PWM2_ROOT_CG             276
+#define IMX7D_PWM2_ROOT_DIV            277
+#define IMX7D_PWM3_ROOT_CLK            278
+#define IMX7D_PWM3_ROOT_SRC            279
+#define IMX7D_PWM3_ROOT_CG             280
+#define IMX7D_PWM3_ROOT_DIV            281
+#define IMX7D_PWM4_ROOT_CLK            282
+#define IMX7D_PWM4_ROOT_SRC            283
+#define IMX7D_PWM4_ROOT_CG             284
+#define IMX7D_PWM4_ROOT_DIV            285
+#define IMX7D_FLEXTIMER1_ROOT_CLK      286
+#define IMX7D_FLEXTIMER1_ROOT_SRC      287
+#define IMX7D_FLEXTIMER1_ROOT_CG       288
+#define IMX7D_FLEXTIMER1_ROOT_DIV      289
+#define IMX7D_FLEXTIMER2_ROOT_CLK      290
+#define IMX7D_FLEXTIMER2_ROOT_SRC      291
+#define IMX7D_FLEXTIMER2_ROOT_CG       292
+#define IMX7D_FLEXTIMER2_ROOT_DIV      293
+#define IMX7D_SIM1_ROOT_CLK            294
+#define IMX7D_SIM1_ROOT_SRC            295
+#define IMX7D_SIM1_ROOT_CG             296
+#define IMX7D_SIM1_ROOT_DIV            297
+#define IMX7D_SIM2_ROOT_CLK            298
+#define IMX7D_SIM2_ROOT_SRC            299
+#define IMX7D_SIM2_ROOT_CG             300
+#define IMX7D_SIM2_ROOT_DIV            301
+#define IMX7D_GPT1_ROOT_CLK            302
+#define IMX7D_GPT1_ROOT_SRC            303
+#define IMX7D_GPT1_ROOT_CG             304
+#define IMX7D_GPT1_ROOT_DIV            305
+#define IMX7D_GPT2_ROOT_CLK            306
+#define IMX7D_GPT2_ROOT_SRC            307
+#define IMX7D_GPT2_ROOT_CG             308
+#define IMX7D_GPT2_ROOT_DIV            309
+#define IMX7D_GPT3_ROOT_CLK            310
+#define IMX7D_GPT3_ROOT_SRC            311
+#define IMX7D_GPT3_ROOT_CG             312
+#define IMX7D_GPT3_ROOT_DIV            313
+#define IMX7D_GPT4_ROOT_CLK            314
+#define IMX7D_GPT4_ROOT_SRC            315
+#define IMX7D_GPT4_ROOT_CG             316
+#define IMX7D_GPT4_ROOT_DIV            317
+#define IMX7D_TRACE_ROOT_CLK           318
+#define IMX7D_TRACE_ROOT_SRC           319
+#define IMX7D_TRACE_ROOT_CG            320
+#define IMX7D_TRACE_ROOT_DIV           321
+#define IMX7D_WDOG1_ROOT_CLK           322
+#define IMX7D_WDOG_ROOT_SRC            323
+#define IMX7D_WDOG_ROOT_CG             324
+#define IMX7D_WDOG_ROOT_DIV            325
+#define IMX7D_CSI_MCLK_ROOT_CLK                326
+#define IMX7D_CSI_MCLK_ROOT_SRC                327
+#define IMX7D_CSI_MCLK_ROOT_CG         328
+#define IMX7D_CSI_MCLK_ROOT_DIV                329
+#define IMX7D_AUDIO_MCLK_ROOT_CLK      330
+#define IMX7D_AUDIO_MCLK_ROOT_SRC      331
+#define IMX7D_AUDIO_MCLK_ROOT_CG       332
+#define IMX7D_AUDIO_MCLK_ROOT_DIV      333
+#define IMX7D_WRCLK_ROOT_CLK           334
+#define IMX7D_WRCLK_ROOT_SRC           335
+#define IMX7D_WRCLK_ROOT_CG            336
+#define IMX7D_WRCLK_ROOT_DIV           337
+#define IMX7D_CLKO1_ROOT_SRC           338
+#define IMX7D_CLKO1_ROOT_CG            339
+#define IMX7D_CLKO1_ROOT_DIV           340
+#define IMX7D_CLKO2_ROOT_SRC           341
+#define IMX7D_CLKO2_ROOT_CG            342
+#define IMX7D_CLKO2_ROOT_DIV           343
+#define IMX7D_MAIN_AXI_ROOT_PRE_DIV    344
+#define IMX7D_DISP_AXI_ROOT_PRE_DIV    345
+#define IMX7D_ENET_AXI_ROOT_PRE_DIV    346
+#define IMX7D_NAND_USDHC_BUS_ROOT_PRE_DIV 347
+#define IMX7D_AHB_CHANNEL_ROOT_PRE_DIV 348
+#define IMX7D_USB_HSIC_ROOT_PRE_DIV    349
+#define IMX7D_PCIE_CTRL_ROOT_PRE_DIV   350
+#define IMX7D_PCIE_PHY_ROOT_PRE_DIV    351
+#define IMX7D_EPDC_PIXEL_ROOT_PRE_DIV  352
+#define IMX7D_LCDIF_PIXEL_ROOT_PRE_DIV 353
+#define IMX7D_MIPI_DSI_ROOT_PRE_DIV    354
+#define IMX7D_MIPI_CSI_ROOT_PRE_DIV    355
+#define IMX7D_MIPI_DPHY_ROOT_PRE_DIV   356
+#define IMX7D_SAI1_ROOT_PRE_DIV                357
+#define IMX7D_SAI2_ROOT_PRE_DIV                358
+#define IMX7D_SAI3_ROOT_PRE_DIV                359
+#define IMX7D_SPDIF_ROOT_PRE_DIV       360
+#define IMX7D_ENET1_REF_ROOT_PRE_DIV   361
+#define IMX7D_ENET1_TIME_ROOT_PRE_DIV  362
+#define IMX7D_ENET2_REF_ROOT_PRE_DIV   363
+#define IMX7D_ENET2_TIME_ROOT_PRE_DIV  364
+#define IMX7D_ENET_PHY_REF_ROOT_PRE_DIV 365
+#define IMX7D_EIM_ROOT_PRE_DIV         366
+#define IMX7D_NAND_ROOT_PRE_DIV                367
+#define IMX7D_QSPI_ROOT_PRE_DIV                368
+#define IMX7D_USDHC1_ROOT_PRE_DIV      369
+#define IMX7D_USDHC2_ROOT_PRE_DIV      370
+#define IMX7D_USDHC3_ROOT_PRE_DIV      371
+#define IMX7D_CAN1_ROOT_PRE_DIV                372
+#define IMX7D_CAN2_ROOT_PRE_DIV                373
+#define IMX7D_I2C1_ROOT_PRE_DIV                374
+#define IMX7D_I2C2_ROOT_PRE_DIV                375
+#define IMX7D_I2C3_ROOT_PRE_DIV                376
+#define IMX7D_I2C4_ROOT_PRE_DIV                377
+#define IMX7D_UART1_ROOT_PRE_DIV       378
+#define IMX7D_UART2_ROOT_PRE_DIV       379
+#define IMX7D_UART3_ROOT_PRE_DIV       380
+#define IMX7D_UART4_ROOT_PRE_DIV       381
+#define IMX7D_UART5_ROOT_PRE_DIV       382
+#define IMX7D_UART6_ROOT_PRE_DIV       383
+#define IMX7D_UART7_ROOT_PRE_DIV       384
+#define IMX7D_ECSPI1_ROOT_PRE_DIV      385
+#define IMX7D_ECSPI2_ROOT_PRE_DIV      386
+#define IMX7D_ECSPI3_ROOT_PRE_DIV      387
+#define IMX7D_ECSPI4_ROOT_PRE_DIV      388
+#define IMX7D_PWM1_ROOT_PRE_DIV                389
+#define IMX7D_PWM2_ROOT_PRE_DIV                390
+#define IMX7D_PWM3_ROOT_PRE_DIV                391
+#define IMX7D_PWM4_ROOT_PRE_DIV                392
+#define IMX7D_FLEXTIMER1_ROOT_PRE_DIV  393
+#define IMX7D_FLEXTIMER2_ROOT_PRE_DIV  394
+#define IMX7D_SIM1_ROOT_PRE_DIV                395
+#define IMX7D_SIM2_ROOT_PRE_DIV                396
+#define IMX7D_GPT1_ROOT_PRE_DIV                397
+#define IMX7D_GPT2_ROOT_PRE_DIV                398
+#define IMX7D_GPT3_ROOT_PRE_DIV                399
+#define IMX7D_GPT4_ROOT_PRE_DIV                400
+#define IMX7D_TRACE_ROOT_PRE_DIV       401
+#define IMX7D_WDOG_ROOT_PRE_DIV                402
+#define IMX7D_CSI_MCLK_ROOT_PRE_DIV    403
+#define IMX7D_AUDIO_MCLK_ROOT_PRE_DIV  404
+#define IMX7D_WRCLK_ROOT_PRE_DIV       405
+#define IMX7D_CLKO1_ROOT_PRE_DIV       406
+#define IMX7D_CLKO2_ROOT_PRE_DIV       407
+#define IMX7D_DRAM_PHYM_ALT_ROOT_PRE_DIV 408
+#define IMX7D_DRAM_ALT_ROOT_PRE_DIV    409
+#define IMX7D_LVDS1_IN_CLK             410
+#define IMX7D_LVDS1_OUT_SEL            411
+#define IMX7D_LVDS1_OUT_CLK            412
+#define IMX7D_CLK_DUMMY                        413
+#define IMX7D_GPT_3M_CLK               414
+#define IMX7D_OCRAM_CLK                        415
+#define IMX7D_OCRAM_S_CLK              416
+#define IMX7D_WDOG2_ROOT_CLK           417
+#define IMX7D_WDOG3_ROOT_CLK           418
+#define IMX7D_WDOG4_ROOT_CLK           419
+#define IMX7D_SDMA_CORE_CLK            420
+#define IMX7D_USB1_MAIN_480M_CLK       421
+#define IMX7D_USB_CTRL_CLK             422
+#define IMX7D_USB_PHY1_CLK             423
+#define IMX7D_USB_PHY2_CLK             424
+#define IMX7D_IPG_ROOT_CLK             425
+#define IMX7D_SAI1_IPG_CLK             426
+#define IMX7D_SAI2_IPG_CLK             427
+#define IMX7D_SAI3_IPG_CLK             428
+#define IMX7D_PLL_AUDIO_TEST_DIV       429
+#define IMX7D_PLL_AUDIO_POST_DIV       430
+#define IMX7D_PLL_VIDEO_TEST_DIV       431
+#define IMX7D_PLL_VIDEO_POST_DIV       432
+#define IMX7D_MU_ROOT_CLK              433
+#define IMX7D_SEMA4_HS_ROOT_CLK                434
+#define IMX7D_PLL_DRAM_TEST_DIV                435
+#define IMX7D_CLK_END                  436
+#endif /* __DT_BINDINGS_CLOCK_IMX7D_H */
index 979d24a..d197634 100644 (file)
 #define VF610_PLL6_BYPASS              180
 #define VF610_PLL7_BYPASS              181
 #define VF610_CLK_SNVS                 182
-#define VF610_CLK_END                  183
+#define VF610_CLK_DAP                  183
+#define VF610_CLK_END                  184
 
 #endif /* __DT_BINDINGS_CLOCK_VF610_H */
diff --git a/include/dt-bindings/clock/zx296702-clock.h b/include/dt-bindings/clock/zx296702-clock.h
new file mode 100644 (file)
index 0000000..e683dbb
--- /dev/null
@@ -0,0 +1,170 @@
+/*
+ * Copyright 2014 Linaro Ltd.
+ * Copyright (C) 2014 ZTE Corporation.
+ *
+ * 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.
+ */
+
+#ifndef __DT_BINDINGS_CLOCK_ZX296702_H
+#define __DT_BINDINGS_CLOCK_ZX296702_H
+
+#define ZX296702_OSC                           0
+#define ZX296702_PLL_A9                                1
+#define ZX296702_PLL_A9_350M                   2
+#define ZX296702_PLL_MAC_1000M                 3
+#define ZX296702_PLL_MAC_333M                  4
+#define ZX296702_PLL_MM0_1188M                 5
+#define ZX296702_PLL_MM0_396M                  6
+#define ZX296702_PLL_MM0_198M                  7
+#define ZX296702_PLL_MM1_108M                  8
+#define ZX296702_PLL_MM1_72M                   9
+#define ZX296702_PLL_MM1_54M                   10
+#define ZX296702_PLL_LSP_104M                  11
+#define ZX296702_PLL_LSP_26M                   12
+#define ZX296702_PLL_AUDIO_294M912             13
+#define ZX296702_PLL_DDR_266M                  14
+#define ZX296702_CLK_148M5                     15
+#define ZX296702_MATRIX_ACLK                   16
+#define ZX296702_MAIN_HCLK                     17
+#define ZX296702_MAIN_PCLK                     18
+#define ZX296702_CLK_500                       19
+#define ZX296702_CLK_250                       20
+#define ZX296702_CLK_125                       21
+#define ZX296702_CLK_74M25                     22
+#define ZX296702_A9_WCLK                       23
+#define ZX296702_A9_AS1_ACLK_MUX               24
+#define ZX296702_A9_TRACE_CLKIN_MUX            25
+#define ZX296702_A9_AS1_ACLK_DIV               26
+#define ZX296702_CLK_2                         27
+#define ZX296702_CLK_27                                28
+#define ZX296702_DECPPU_ACLK_MUX               29
+#define ZX296702_PPU_ACLK_MUX                  30
+#define ZX296702_MALI400_ACLK_MUX              31
+#define ZX296702_VOU_ACLK_MUX                  32
+#define ZX296702_VOU_MAIN_WCLK_MUX             33
+#define ZX296702_VOU_AUX_WCLK_MUX              34
+#define ZX296702_VOU_SCALER_WCLK_MUX           35
+#define ZX296702_R2D_ACLK_MUX                  36
+#define ZX296702_R2D_WCLK_MUX                  37
+#define ZX296702_CLK_50                                38
+#define ZX296702_CLK_25                                39
+#define ZX296702_CLK_12                                40
+#define ZX296702_CLK_16M384                    41
+#define ZX296702_CLK_32K768                    42
+#define ZX296702_SEC_WCLK_DIV                  43
+#define ZX296702_DDR_WCLK_MUX                  44
+#define ZX296702_NAND_WCLK_MUX                 45
+#define ZX296702_LSP_26_WCLK_MUX               46
+#define ZX296702_A9_AS0_ACLK                   47
+#define ZX296702_A9_AS1_ACLK                   48
+#define ZX296702_A9_TRACE_CLKIN                        49
+#define ZX296702_DECPPU_AXI_M_ACLK             50
+#define ZX296702_DECPPU_AHB_S_HCLK             51
+#define ZX296702_PPU_AXI_M_ACLK                        52
+#define ZX296702_PPU_AHB_S_HCLK                        53
+#define ZX296702_VOU_AXI_M_ACLK                        54
+#define ZX296702_VOU_APB_PCLK                  55
+#define ZX296702_VOU_MAIN_CHANNEL_WCLK         56
+#define ZX296702_VOU_AUX_CHANNEL_WCLK          57
+#define ZX296702_VOU_HDMI_OSCLK_CEC            58
+#define ZX296702_VOU_SCALER_WCLK               59
+#define ZX296702_MALI400_AXI_M_ACLK            60
+#define ZX296702_MALI400_APB_PCLK              61
+#define ZX296702_R2D_WCLK                      62
+#define ZX296702_R2D_AXI_M_ACLK                        63
+#define ZX296702_R2D_AHB_HCLK                  64
+#define ZX296702_DDR3_AXI_S0_ACLK              65
+#define ZX296702_DDR3_APB_PCLK                 66
+#define ZX296702_DDR3_WCLK                     67
+#define ZX296702_USB20_0_AHB_HCLK              68
+#define ZX296702_USB20_0_EXTREFCLK             69
+#define ZX296702_USB20_1_AHB_HCLK              70
+#define ZX296702_USB20_1_EXTREFCLK             71
+#define ZX296702_USB20_2_AHB_HCLK              72
+#define ZX296702_USB20_2_EXTREFCLK             73
+#define ZX296702_GMAC_AXI_M_ACLK               74
+#define ZX296702_GMAC_APB_PCLK                 75
+#define ZX296702_GMAC_125_CLKIN                        76
+#define ZX296702_GMAC_RMII_CLKIN               77
+#define ZX296702_GMAC_25M_CLK                  78
+#define ZX296702_NANDFLASH_AHB_HCLK            79
+#define ZX296702_NANDFLASH_WCLK                        80
+#define ZX296702_LSP0_APB_PCLK                 81
+#define ZX296702_LSP0_AHB_HCLK                 82
+#define ZX296702_LSP0_26M_WCLK                 83
+#define ZX296702_LSP0_104M_WCLK                        84
+#define ZX296702_LSP0_16M384_WCLK              85
+#define ZX296702_LSP1_APB_PCLK                 86
+#define ZX296702_LSP1_26M_WCLK                 87
+#define ZX296702_LSP1_104M_WCLK                        88
+#define ZX296702_LSP1_32K_CLK                  89
+#define ZX296702_AON_HCLK                      90
+#define ZX296702_SYS_CTRL_PCLK                 91
+#define ZX296702_DMA_PCLK                      92
+#define ZX296702_DMA_ACLK                      93
+#define ZX296702_SEC_HCLK                      94
+#define ZX296702_AES_WCLK                      95
+#define ZX296702_DES_WCLK                      96
+#define ZX296702_IRAM_ACLK                     97
+#define ZX296702_IROM_ACLK                     98
+#define ZX296702_BOOT_CTRL_HCLK                        99
+#define ZX296702_EFUSE_CLK_30                  100
+#define ZX296702_VOU_MAIN_CHANNEL_DIV          101
+#define ZX296702_VOU_AUX_CHANNEL_DIV           102
+#define ZX296702_VOU_TV_ENC_HD_DIV             103
+#define ZX296702_VOU_TV_ENC_SD_DIV             104
+#define ZX296702_VL0_MUX                       105
+#define ZX296702_VL1_MUX                       106
+#define ZX296702_VL2_MUX                       107
+#define ZX296702_GL0_MUX                       108
+#define ZX296702_GL1_MUX                       109
+#define ZX296702_GL2_MUX                       110
+#define ZX296702_WB_MUX                                111
+#define ZX296702_HDMI_MUX                      112
+#define ZX296702_VOU_TV_ENC_HD_MUX             113
+#define ZX296702_VOU_TV_ENC_SD_MUX             114
+#define ZX296702_VL0_CLK                       115
+#define ZX296702_VL1_CLK                       116
+#define ZX296702_VL2_CLK                       117
+#define ZX296702_GL0_CLK                       118
+#define ZX296702_GL1_CLK                       119
+#define ZX296702_GL2_CLK                       120
+#define ZX296702_WB_CLK                                121
+#define ZX296702_CL_CLK                                122
+#define ZX296702_MAIN_MIX_CLK                  123
+#define ZX296702_AUX_MIX_CLK                   124
+#define ZX296702_HDMI_CLK                      125
+#define ZX296702_VOU_TV_ENC_HD_DAC_CLK         126
+#define ZX296702_VOU_TV_ENC_SD_DAC_CLK         127
+#define ZX296702_A9_PERIPHCLK                  128
+#define ZX296702_TOPCLK_END                    129
+
+#define ZX296702_SDMMC1_WCLK_MUX               0
+#define ZX296702_SDMMC1_WCLK_DIV               1
+#define ZX296702_SDMMC1_WCLK                   2
+#define ZX296702_SDMMC1_PCLK                   3
+#define ZX296702_SPDIF0_WCLK_MUX               4
+#define ZX296702_SPDIF0_WCLK                   5
+#define ZX296702_SPDIF0_PCLK                   6
+#define ZX296702_SPDIF0_DIV                    7
+#define ZX296702_I2S0_WCLK_MUX                 8
+#define ZX296702_I2S0_WCLK                     9
+#define ZX296702_I2S0_PCLK                     10
+#define ZX296702_I2S0_DIV                      11
+#define ZX296702_LSP0CLK_END                   12
+
+#define ZX296702_UART0_WCLK_MUX                        0
+#define ZX296702_UART0_WCLK                    1
+#define ZX296702_UART0_PCLK                    2
+#define ZX296702_UART1_WCLK_MUX                        3
+#define ZX296702_UART1_WCLK                    4
+#define ZX296702_UART1_PCLK                    5
+#define ZX296702_SDMMC0_WCLK_MUX               6
+#define ZX296702_SDMMC0_WCLK_DIV               7
+#define ZX296702_SDMMC0_WCLK                   8
+#define ZX296702_SDMMC0_PCLK                   9
+#define ZX296702_LSP1CLK_END                   10
+
+#endif /* __DT_BINDINGS_CLOCK_ZX296702_H */
index 62c6901..2633061 100644 (file)
@@ -458,6 +458,8 @@ extern void handle_nested_irq(unsigned int irq);
 
 extern int irq_chip_compose_msi_msg(struct irq_data *data, struct msi_msg *msg);
 #ifdef CONFIG_IRQ_DOMAIN_HIERARCHY
+extern void irq_chip_enable_parent(struct irq_data *data);
+extern void irq_chip_disable_parent(struct irq_data *data);
 extern void irq_chip_ack_parent(struct irq_data *data);
 extern int irq_chip_retrigger_hierarchy(struct irq_data *data);
 extern void irq_chip_mask_parent(struct irq_data *data);
index 676d730..744ac0e 100644 (file)
@@ -258,6 +258,10 @@ int irq_domain_xlate_onetwocell(struct irq_domain *d, struct device_node *ctrlr,
 /* V2 interfaces to support hierarchy IRQ domains. */
 extern struct irq_data *irq_domain_get_irq_data(struct irq_domain *domain,
                                                unsigned int virq);
+extern void irq_domain_set_info(struct irq_domain *domain, unsigned int virq,
+                               irq_hw_number_t hwirq, struct irq_chip *chip,
+                               void *chip_data, irq_flow_handler_t handler,
+                               void *handler_data, const char *handler_name);
 #ifdef CONFIG_IRQ_DOMAIN_HIERARCHY
 extern struct irq_domain *irq_domain_add_hierarchy(struct irq_domain *parent,
                        unsigned int flags, unsigned int size,
@@ -281,10 +285,6 @@ extern int irq_domain_set_hwirq_and_chip(struct irq_domain *domain,
                                         irq_hw_number_t hwirq,
                                         struct irq_chip *chip,
                                         void *chip_data);
-extern void irq_domain_set_info(struct irq_domain *domain, unsigned int virq,
-                               irq_hw_number_t hwirq, struct irq_chip *chip,
-                               void *chip_data, irq_flow_handler_t handler,
-                               void *handler_data, const char *handler_name);
 extern void irq_domain_reset_irq_data(struct irq_data *irq_data);
 extern void irq_domain_free_irqs_common(struct irq_domain *domain,
                                        unsigned int virq,
diff --git a/include/linux/reset/bcm63xx_pmb.h b/include/linux/reset/bcm63xx_pmb.h
new file mode 100644 (file)
index 0000000..bb4af7b
--- /dev/null
@@ -0,0 +1,88 @@
+/*
+ * Broadcom BCM63xx Processor Monitor Bus shared routines (SMP and reset)
+ *
+ * Copyright (C) 2015, Broadcom Corporation
+ * Author: Florian Fainelli <f.fainelli@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation version 2.
+ *
+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any
+ * kind, whether express or implied; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+#ifndef __BCM63XX_PMB_H
+#define __BCM63XX_PMB_H
+
+#include <linux/io.h>
+#include <linux/types.h>
+#include <linux/delay.h>
+#include <linux/err.h>
+
+/* PMB Master controller register */
+#define PMB_CTRL               0x00
+#define  PMC_PMBM_START                (1 << 31)
+#define  PMC_PMBM_TIMEOUT      (1 << 30)
+#define  PMC_PMBM_SLAVE_ERR    (1 << 29)
+#define  PMC_PMBM_BUSY         (1 << 28)
+#define  PMC_PMBM_READ         (0 << 20)
+#define  PMC_PMBM_WRITE                (1 << 20)
+#define PMB_WR_DATA            0x04
+#define PMB_TIMEOUT            0x08
+#define PMB_RD_DATA            0x0C
+
+#define PMB_BUS_ID_SHIFT       8
+
+/* Perform the low-level PMB master operation, shared between reads and
+ * writes.
+ */
+static inline int __bpcm_do_op(void __iomem *master, unsigned int addr,
+                              u32 off, u32 op)
+{
+       unsigned int timeout = 1000;
+       u32 cmd;
+
+       cmd = (PMC_PMBM_START | op | (addr & 0xff) << 12 | off);
+       writel(cmd, master + PMB_CTRL);
+       do {
+               cmd = readl(master + PMB_CTRL);
+               if (!(cmd & PMC_PMBM_START))
+                       return 0;
+
+               if (cmd & PMC_PMBM_SLAVE_ERR)
+                       return -EIO;
+
+               if (cmd & PMC_PMBM_TIMEOUT)
+                       return -ETIMEDOUT;
+
+               udelay(1);
+       } while (timeout-- > 0);
+
+       return -ETIMEDOUT;
+}
+
+static inline int bpcm_rd(void __iomem *master, unsigned int addr,
+                         u32 off, u32 *val)
+{
+       int ret = 0;
+
+       ret = __bpcm_do_op(master, addr, off >> 2, PMC_PMBM_READ);
+       *val = readl(master + PMB_RD_DATA);
+
+       return ret;
+}
+
+static inline int bpcm_wr(void __iomem *master, unsigned int addr,
+                         u32 off, u32 val)
+{
+       int ret = 0;
+
+       writel(val, master + PMB_WR_DATA);
+       ret = __bpcm_do_op(master, addr, off >> 2, PMC_PMBM_WRITE);
+
+       return ret;
+}
+
+#endif /* __BCM63XX_PMB_H */
diff --git a/include/soc/imx/revision.h b/include/soc/imx/revision.h
new file mode 100644 (file)
index 0000000..9ea3469
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ * Copyright 2015 Linaro Ltd.
+ *
+ * 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.
+ */
+
+#ifndef __SOC_IMX_REVISION_H__
+#define __SOC_IMX_REVISION_H__
+
+#define IMX_CHIP_REVISION_1_0          0x10
+#define IMX_CHIP_REVISION_1_1          0x11
+#define IMX_CHIP_REVISION_1_2          0x12
+#define IMX_CHIP_REVISION_1_3          0x13
+#define IMX_CHIP_REVISION_1_4          0x14
+#define IMX_CHIP_REVISION_1_5          0x15
+#define IMX_CHIP_REVISION_2_0          0x20
+#define IMX_CHIP_REVISION_2_1          0x21
+#define IMX_CHIP_REVISION_2_2          0x22
+#define IMX_CHIP_REVISION_2_3          0x23
+#define IMX_CHIP_REVISION_3_0          0x30
+#define IMX_CHIP_REVISION_3_1          0x31
+#define IMX_CHIP_REVISION_3_2          0x32
+#define IMX_CHIP_REVISION_3_3          0x33
+#define IMX_CHIP_REVISION_UNKNOWN      0xff
+
+int mx27_revision(void);
+int mx31_revision(void);
+int mx35_revision(void);
+int mx51_revision(void);
+int mx53_revision(void);
+
+unsigned int imx_get_soc_revision(void);
+void imx_print_silicon_rev(const char *cpu, int srev);
+
+#endif /* __SOC_IMX_REVISION_H__ */
diff --git a/include/soc/imx/timer.h b/include/soc/imx/timer.h
new file mode 100644 (file)
index 0000000..bbbafd6
--- /dev/null
@@ -0,0 +1,26 @@
+/*
+ * Copyright 2015 Linaro Ltd.
+ *
+ * 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.
+ */
+
+#ifndef __SOC_IMX_TIMER_H__
+#define __SOC_IMX_TIMER_H__
+
+enum imx_gpt_type {
+       GPT_TYPE_IMX1,          /* i.MX1 */
+       GPT_TYPE_IMX21,         /* i.MX21/27 */
+       GPT_TYPE_IMX31,         /* i.MX31/35/25/37/51/6Q */
+       GPT_TYPE_IMX6DL,        /* i.MX6DL/SX/SL */
+};
+
+/*
+ * This is a stop-gap solution for clock drivers like imx1/imx21 which call
+ * mxc_timer_init() to initialize timer for non-DT boot.  It can be removed
+ * when these legacy non-DT support is converted or dropped.
+ */
+void mxc_timer_init(unsigned long pbase, int irq, enum imx_gpt_type type);
+
+#endif  /* __SOC_IMX_TIMER_H__ */
index 65a9327..f5c0de4 100644 (file)
@@ -26,8 +26,6 @@
 struct clk;
 struct reset_control;
 
-void tegra_pmc_restart(enum reboot_mode mode, const char *cmd);
-
 #ifdef CONFIG_PM_SLEEP
 enum tegra_suspend_mode tegra_pmc_get_suspend_mode(void);
 void tegra_pmc_set_suspend_mode(enum tegra_suspend_mode mode);
index e9b4cb0..1e5ac4e 100644 (file)
  * Extra serial register definitions for the internal UARTs
  * in TI OMAP processors.
  */
+#define OMAP1_UART1_BASE       0xfffb0000
+#define OMAP1_UART2_BASE       0xfffb0800
+#define OMAP1_UART3_BASE       0xfffb9800
 #define UART_OMAP_MDR1         0x08    /* Mode definition register */
 #define UART_OMAP_MDR2         0x09    /* Mode definition register 2 */
 #define UART_OMAP_SCR          0x10    /* Supplementary control register */
index eb9a4ea..2456fe8 100644 (file)
@@ -876,6 +876,34 @@ void irq_cpu_offline(void)
 
 #ifdef CONFIG_IRQ_DOMAIN_HIERARCHY
 /**
+ * irq_chip_enable_parent - Enable the parent interrupt (defaults to unmask if
+ * NULL)
+ * @data:      Pointer to interrupt specific data
+ */
+void irq_chip_enable_parent(struct irq_data *data)
+{
+       data = data->parent_data;
+       if (data->chip->irq_enable)
+               data->chip->irq_enable(data);
+       else
+               data->chip->irq_unmask(data);
+}
+
+/**
+ * irq_chip_disable_parent - Disable the parent interrupt (defaults to mask if
+ * NULL)
+ * @data:      Pointer to interrupt specific data
+ */
+void irq_chip_disable_parent(struct irq_data *data)
+{
+       data = data->parent_data;
+       if (data->chip->irq_disable)
+               data->chip->irq_disable(data);
+       else
+               data->chip->irq_mask(data);
+}
+
+/**
  * irq_chip_ack_parent - Acknowledge the parent interrupt
  * @data:      Pointer to interrupt specific data
  */
index 61024e8..15b370d 100644 (file)
@@ -360,7 +360,7 @@ static struct lock_class_key irq_nested_lock_class;
 int irq_map_generic_chip(struct irq_domain *d, unsigned int virq,
                         irq_hw_number_t hw_irq)
 {
-       struct irq_data *data = irq_get_irq_data(virq);
+       struct irq_data *data = irq_domain_get_irq_data(d, virq);
        struct irq_domain_chip_generic *dgc = d->gc;
        struct irq_chip_generic *gc;
        struct irq_chip_type *ct;
@@ -405,8 +405,7 @@ int irq_map_generic_chip(struct irq_domain *d, unsigned int virq,
        else
                data->mask = 1 << idx;
 
-       irq_set_chip_and_handler(virq, chip, ct->handler);
-       irq_set_chip_data(virq, gc);
+       irq_domain_set_info(d, virq, hw_irq, chip, gc, ct->handler, NULL, NULL);
        irq_modify_status(virq, dgc->irq_flags_to_clear, dgc->irq_flags_to_set);
        return 0;
 }
index 7fac311..41bf6dc 100644 (file)
@@ -1232,6 +1232,27 @@ struct irq_data *irq_domain_get_irq_data(struct irq_domain *domain,
        return (irq_data && irq_data->domain == domain) ? irq_data : NULL;
 }
 
+/**
+ * irq_domain_set_info - Set the complete data for a @virq in @domain
+ * @domain:            Interrupt domain to match
+ * @virq:              IRQ number
+ * @hwirq:             The hardware interrupt number
+ * @chip:              The associated interrupt chip
+ * @chip_data:         The associated interrupt chip data
+ * @handler:           The interrupt flow handler
+ * @handler_data:      The interrupt flow handler data
+ * @handler_name:      The interrupt handler name
+ */
+void irq_domain_set_info(struct irq_domain *domain, unsigned int virq,
+                        irq_hw_number_t hwirq, struct irq_chip *chip,
+                        void *chip_data, irq_flow_handler_t handler,
+                        void *handler_data, const char *handler_name)
+{
+       irq_set_chip_and_handler_name(virq, chip, handler, handler_name);
+       irq_set_chip_data(virq, chip_data);
+       irq_set_handler_data(virq, handler_data);
+}
+
 static void irq_domain_check_hierarchy(struct irq_domain *domain)
 {
 }