Merge tag 'armsoc-soc' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc
authorLinus Torvalds <torvalds@linux-foundation.org>
Tue, 1 Sep 2015 19:18:40 +0000 (12:18 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Tue, 1 Sep 2015 19:18:40 +0000 (12:18 -0700)
Pull ARM SoC platform updates from Olof Johansson:
 "New or improved SoC support:

   - add support for Atmel's SAMA5D2 SoC
   - add support for Freescale i.MX6UL
   - improved support for TI's DM814x platform
   - misc fixes and improvements for RockChip platforms
   - Marvell MVEBU suspend/resume support

  A few driver changes that ideally would belong in the drivers branch
  are also here (acked by appropriate maintainers):

   - power key input driver for Freescale platforms (svns)
   - RTC driver updates for Freescale platforms (svns/mxc)
   - clk fixes for TI DM814/816X

  + a bunch of other changes for various platforms"

* tag 'armsoc-soc' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc: (83 commits)
  ARM: rockchip: pm: Fix PTR_ERR() argument
  ARM: imx: mach-imx6ul: Fix allmodconfig build
  clk: ti: fix for definition movement
  ARM: uniphier: drop v7_invalidate_l1 call at secondary entry
  memory: kill off set_irq_flags usage
  rtc: snvs: select option REGMAP_MMIO
  ARM: brcmstb: select ARCH_DMA_ADDR_T_64BIT for LPAE
  ARM: BCM: Enable ARM erratum 798181 for BRCMSTB
  ARM: OMAP2+: Fix power domain operations regression caused by 81xx
  ARM: rockchip: enable PMU_GPIOINT_WAKEUP_EN when entering shallow suspend
  ARM: rockchip: set correct stabilization thresholds in suspend
  ARM: rockchip: rename osc_switch_to_32k variable
  ARM: imx6ul: add fec MAC refrence clock and phy fixup init
  ARM: imx6ul: add fec bits to GPR syscon definition
  rtc: mxc: add support of device tree
  dt-binding: document the binding for mxc rtc
  rtc: mxc: use a second rtc clock
  ARM: davinci: cp_intc: use IRQCHIP_SKIP_SET_WAKE instead of irq_set_wake callback
  soc: mediatek: Fix SCPSYS compilation
  ARM: at91/soc: add basic support for new sama5d2 SoC
  ...

100 files changed:
Documentation/arm/Atmel/README
Documentation/devicetree/bindings/arm/atmel-at91.txt
Documentation/devicetree/bindings/crypto/fsl-sec4.txt
Documentation/devicetree/bindings/input/snvs-pwrkey.txt [new file with mode: 0644]
Documentation/devicetree/bindings/rtc/rtc-mxc.txt [new file with mode: 0644]
Documentation/devicetree/bindings/soc/mediatek/scpsys.txt [new file with mode: 0644]
MAINTAINERS
arch/arm/Kconfig.debug
arch/arm/boot/dts/am4372.dtsi
arch/arm/include/debug/at91.S
arch/arm/include/debug/imx-uart.h
arch/arm/include/debug/zynq.S
arch/arm/mach-at91/Kconfig
arch/arm/mach-at91/sama5.c
arch/arm/mach-at91/soc.h
arch/arm/mach-bcm/Kconfig
arch/arm/mach-davinci/cp_intc.c
arch/arm/mach-imx/Kconfig
arch/arm/mach-imx/Makefile
arch/arm/mach-imx/cpu.c
arch/arm/mach-imx/mach-imx6ul.c [new file with mode: 0644]
arch/arm/mach-imx/mxc.h
arch/arm/mach-mediatek/Kconfig
arch/arm/mach-mvebu/coherency.c
arch/arm/mach-mvebu/common.h
arch/arm/mach-mvebu/pm-board.c
arch/arm/mach-mvebu/pm.c
arch/arm/mach-omap2/Makefile
arch/arm/mach-omap2/board-generic.c
arch/arm/mach-omap2/clockdomain.h
arch/arm/mach-omap2/clockdomains7xx_data.c
arch/arm/mach-omap2/clockdomains81xx_data.c
arch/arm/mach-omap2/common.h
arch/arm/mach-omap2/control.c
arch/arm/mach-omap2/io.c
arch/arm/mach-omap2/iomap.h
arch/arm/mach-omap2/omap-iommu.c
arch/arm/mach-omap2/omap-mpuss-lowpower.c
arch/arm/mach-omap2/omap3-restart.c
arch/arm/mach-omap2/omap4-restart.c
arch/arm/mach-omap2/omap54xx.h
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_43xx_data.c
arch/arm/mach-omap2/omap_hwmod_81xx_data.c
arch/arm/mach-omap2/pdata-quirks.c
arch/arm/mach-omap2/powerdomains3xxx_data.c
arch/arm/mach-omap2/prcm-common.h
arch/arm/mach-omap2/prcm43xx.h
arch/arm/mach-omap2/prm44xx.c
arch/arm/mach-omap2/prm_common.c
arch/arm/mach-omap2/timer.c
arch/arm/mach-pxa/devices.c
arch/arm/mach-pxa/pxa25x.c
arch/arm/mach-pxa/pxa27x.c
arch/arm/mach-pxa/pxa3xx.c
arch/arm/mach-pxa/sharpsl_pm.c
arch/arm/mach-pxa/tosa-bt.c
arch/arm/mach-rockchip/platsmp.c
arch/arm/mach-rockchip/pm.c
arch/arm/mach-rockchip/pm.h
arch/arm/mach-shmobile/Kconfig
arch/arm/mach-shmobile/Makefile
arch/arm/mach-shmobile/regulator-quirk-rcar-gen2.c
arch/arm/mach-shmobile/setup-r8a7793.c [new file with mode: 0644]
arch/arm/mach-socfpga/core.h
arch/arm/mach-socfpga/platsmp.c
arch/arm/mach-socfpga/socfpga.c
arch/arm/mach-sti/headsmp.S
arch/arm/mach-sti/platsmp.c
arch/arm/mach-sti/smp.h
arch/arm/mach-uniphier/platsmp.c
arch/arm/mach-zx/Kconfig
arch/arm/mach-zx/Makefile
arch/arm/mach-zx/zx296702-pm-domain.c [new file with mode: 0644]
arch/arm/mach-zynq/common.c
arch/arm/mach-zynq/headsmp.S
arch/arm/plat-pxa/dma.c
arch/arm/plat-pxa/include/plat/dma.h
drivers/clk/ti/Makefile
drivers/clk/ti/clk-814x.c [new file with mode: 0644]
drivers/clk/ti/clk-816x.c
drivers/clk/zynq/Makefile
drivers/input/keyboard/Kconfig
drivers/input/keyboard/Makefile
drivers/input/keyboard/snvs_pwrkey.c [new file with mode: 0644]
drivers/memory/omap-gpmc.c
drivers/rtc/Kconfig
drivers/rtc/rtc-mxc.c
drivers/rtc/rtc-snvs.c
drivers/soc/mediatek/Kconfig
drivers/soc/mediatek/Makefile
drivers/soc/mediatek/mtk-infracfg.c [new file with mode: 0644]
drivers/soc/mediatek/mtk-pmic-wrap.c
drivers/soc/mediatek/mtk-scpsys.c [new file with mode: 0644]
include/dt-bindings/power/mt8173-power.h [new file with mode: 0644]
include/linux/clk/ti.h
include/linux/mfd/syscon/imx6q-iomuxc-gpr.h
include/linux/soc/mediatek/infracfg.h [new file with mode: 0644]

index c53a19b..0931cf7 100644 (file)
@@ -90,6 +90,11 @@ the Atmel website: http://www.atmel.com.
         + Datasheet
           http://www.atmel.com/Images/Atmel-11238-32-bit-Cortex-A5-Microcontroller-SAMA5D4_Datasheet.pdf
 
+      - sama5d2 family
+        - sama5d27
+        + Datasheet
+          Coming soon
+
 
 Linux kernel information
 ------------------------
index dd998b9..23c0978 100644 (file)
@@ -27,6 +27,8 @@ compatible: must be one of:
     o "atmel,at91sam9xe"
  * "atmel,sama5" for SoCs using a Cortex-A5, shall be extended with the specific
    SoC family:
+    o "atmel,sama5d2" shall be extended with the specific SoC compatible:
+       - "atmel,sama5d27"
     o "atmel,sama5d3" shall be extended with the specific SoC compatible:
        - "atmel,sama5d31"
        - "atmel,sama5d33"
index 1003073..6831d02 100644 (file)
@@ -305,12 +305,13 @@ Secure Non-Volatile Storage (SNVS) Node
     Node defines address range and the associated
     interrupt for the SNVS function.  This function
     monitors security state information & reports
-    security violations.
+    security violations. This also included rtc,
+    system power off and ON/OFF key.
 
   - compatible
       Usage: required
       Value type: <string>
-      Definition: Must include "fsl,sec-v4.0-mon".
+      Definition: Must include "fsl,sec-v4.0-mon" and "syscon".
 
   - reg
       Usage: required
@@ -341,7 +342,7 @@ Secure Non-Volatile Storage (SNVS) Node
            the child address, parent address, & length.
 
    - interrupts
-      Usage: required
+      Usage: optional
       Value type: <prop_encoded-array>
       Definition:  Specifies the interrupts generated by this
            device.  The value of the interrupts property
@@ -358,7 +359,7 @@ Secure Non-Volatile Storage (SNVS) Node
 
 EXAMPLE
        sec_mon@314000 {
-               compatible = "fsl,sec-v4.0-mon";
+               compatible = "fsl,sec-v4.0-mon", "syscon";
                reg = <0x314000 0x1000>;
                ranges = <0 0x314000 0x1000>;
                interrupt-parent = <&mpic>;
@@ -375,16 +376,72 @@ Secure Non-Volatile Storage (SNVS) Low Power (LP) RTC Node
       Value type: <string>
       Definition: Must include "fsl,sec-v4.0-mon-rtc-lp".
 
-  - reg
+  - interrupts
       Usage: required
-      Value type: <prop-encoded-array>
-      Definition: A standard property.  Specifies the physical
-          address and length of the SNVS LP configuration registers.
+      Value type: <prop_encoded-array>
+      Definition: Specifies the interrupts generated by this
+          device.  The value of the interrupts property
+          consists of one interrupt specifier. The format
+          of the specifier is defined by the binding document
+          describing the node's interrupt parent.
+
+ - regmap
+       Usage: required
+       Value type: <phandle>
+       Definition: this is phandle to the register map node.
+
+ - offset
+       Usage: option
+       value type: <u32>
+       Definition: LP register offset. default it is 0x34.
 
 EXAMPLE
-       sec_mon_rtc_lp@314000 {
+       sec_mon_rtc_lp@1 {
                compatible = "fsl,sec-v4.0-mon-rtc-lp";
-               reg = <0x34 0x58>;
+               interrupts = <93 2>;
+               regmap = <&snvs>;
+               offset = <0x34>;
+       };
+
+=====================================================================
+System ON/OFF key driver
+
+  The snvs-pwrkey is designed to enable POWER key function which controlled
+  by SNVS ONOFF, the driver can report the status of POWER key and wakeup
+  system if pressed after system suspend.
+
+  - compatible:
+      Usage: required
+      Value type: <string>
+      Definition: Mush include "fsl,sec-v4.0-pwrkey".
+
+  - interrupts:
+      Usage: required
+      Value type: <prop_encoded-array>
+      Definition: The SNVS ON/OFF interrupt number to the CPU(s).
+
+  - linux,keycode:
+      Usage: option
+      Value type: <int>
+      Definition: Keycode to emit, KEY_POWER by default.
+
+  - wakeup-source:
+      Usage: option
+      Value type: <boo>
+      Definition: Button can wake-up the system.
+
+ - regmap:
+      Usage: required:
+      Value type: <phandle>
+      Definition: this is phandle to the register map node.
+
+EXAMPLE:
+       snvs-pwrkey@0x020cc000 {
+               compatible = "fsl,sec-v4.0-pwrkey";
+               regmap = <&snvs>;
+               interrupts = <0 4 0x4>
+               linux,keycode = <116>; /* KEY_POWER */
+               wakeup;
        };
 
 =====================================================================
@@ -460,12 +517,20 @@ FULL EXAMPLE
                compatible = "fsl,sec-v4.0-mon";
                reg = <0x314000 0x1000>;
                ranges = <0 0x314000 0x1000>;
-               interrupt-parent = <&mpic>;
-               interrupts = <93 2>;
 
                sec_mon_rtc_lp@34 {
                        compatible = "fsl,sec-v4.0-mon-rtc-lp";
-                       reg = <0x34 0x58>;
+                       regmap = <&sec_mon>;
+                       offset = <0x34>;
+                       interrupts = <93 2>;
+               };
+
+               snvs-pwrkey@0x020cc000 {
+                       compatible = "fsl,sec-v4.0-pwrkey";
+                       regmap = <&sec_mon>;
+                       interrupts = <0 4 0x4>;
+                       linux,keycode = <116>; /* KEY_POWER */
+                       wakeup;
                };
        };
 
diff --git a/Documentation/devicetree/bindings/input/snvs-pwrkey.txt b/Documentation/devicetree/bindings/input/snvs-pwrkey.txt
new file mode 100644 (file)
index 0000000..70c1425
--- /dev/null
@@ -0,0 +1 @@
+See Documentation/devicetree/bindings/crypto/fsl-sec4.txt
diff --git a/Documentation/devicetree/bindings/rtc/rtc-mxc.txt b/Documentation/devicetree/bindings/rtc/rtc-mxc.txt
new file mode 100644 (file)
index 0000000..5bcd31d
--- /dev/null
@@ -0,0 +1,26 @@
+* Real Time Clock of the i.MX SoCs
+
+RTC controller for the i.MX SoCs
+
+Required properties:
+- compatible: Should be "fsl,imx1-rtc" or "fsl,imx21-rtc".
+- reg: physical base address of the controller and length of memory mapped
+  region.
+- interrupts: IRQ line for the RTC.
+- clocks: should contain two entries:
+  * one for the input reference
+  * one for the the SoC RTC
+- clock-names: should contain:
+  * "ref" for the input reference clock
+  * "ipg" for the SoC RTC clock
+
+Example:
+
+rtc@10007000 {
+       compatible = "fsl,imx21-rtc";
+       reg = <0x10007000 0x1000>;
+       interrupts = <22>;
+       clocks = <&clks IMX27_CLK_CKIL>,
+                <&clks IMX27_CLK_RTC_IPG_GATE>;
+       clock-names = "ref", "ipg";
+};
diff --git a/Documentation/devicetree/bindings/soc/mediatek/scpsys.txt b/Documentation/devicetree/bindings/soc/mediatek/scpsys.txt
new file mode 100644 (file)
index 0000000..c051114
--- /dev/null
@@ -0,0 +1,41 @@
+MediaTek SCPSYS
+===============
+
+The System Control Processor System (SCPSYS) has several power management
+related tasks in the system. The tasks include thermal measurement, dynamic
+voltage frequency scaling (DVFS), interrupt filter and lowlevel sleep control.
+The System Power Manager (SPM) inside the SCPSYS is for the MTCMOS power
+domain control.
+
+The driver implements the Generic PM domain bindings described in
+power/power_domain.txt. It provides the power domains defined in
+include/dt-bindings/power/mt8173-power.h.
+
+Required properties:
+- compatible: Must be "mediatek,mt8173-scpsys"
+- #power-domain-cells: Must be 1
+- reg: Address range of the SCPSYS unit
+- infracfg: must contain a phandle to the infracfg controller
+- clock, clock-names: clocks according to the common clock binding.
+                      The clocks needed "mm" and "mfg". These are the
+                     clocks which hardware needs to be enabled before
+                     enabling certain power domains.
+
+Example:
+
+       scpsys: scpsys@10006000 {
+               #power-domain-cells = <1>;
+               compatible = "mediatek,mt8173-scpsys";
+               reg = <0 0x10006000 0 0x1000>;
+               infracfg = <&infracfg>;
+               clocks = <&clk26m>,
+                        <&topckgen CLK_TOP_MM_SEL>;
+               clock-names = "mfg", "mm";
+       };
+
+Example consumer:
+
+       afe: mt8173-afe-pcm@11220000 {
+               compatible = "mediatek,mt8173-afe-pcm";
+               power-domains = <&scpsys MT8173_POWER_DOMAIN_AUDIO>;
+       };
index 671a8f8..b772b85 100644 (file)
@@ -1583,7 +1583,10 @@ 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/boot/dts/uniphier*
 F:     arch/arm/mach-uniphier/
+F:     drivers/pinctrl/uniphier/
+F:     drivers/tty/serial/8250/8250_uniphier.c
 N:     uniphier
 
 ARM/Ux500 ARM ARCHITECTURE
@@ -1678,7 +1681,7 @@ M:        Michal Simek <michal.simek@xilinx.com>
 R:     Sören Brinkmann <soren.brinkmann@xilinx.com>
 L:     linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
 W:     http://wiki.xilinx.com
-T:     git git://git.xilinx.com/linux-xlnx.git
+T:     git https://github.com/Xilinx/linux-xlnx.git
 S:     Supported
 F:     arch/arm/mach-zynq/
 F:     drivers/cpuidle/cpuidle-zynq.c
index a2e16f9..0cfd7f9 100644 (file)
@@ -141,6 +141,12 @@ choice
                depends on ARCH_AT91
                depends on SOC_SAMA5
 
+       config AT91_DEBUG_LL_DBGU3
+               bool "Kernel low-level debugging on sama5d2"
+               select DEBUG_AT91_UART
+               depends on ARCH_AT91
+               depends on SOC_SAMA5
+
        config DEBUG_BCM2835
                bool "Kernel low-level debugging on BCM2835 PL011 UART"
                depends on ARCH_BCM2835
@@ -411,6 +417,13 @@ choice
                  Say Y here if you want kernel low-level debugging support
                  on i.MX6SX.
 
+       config DEBUG_IMX6UL_UART
+               bool "i.MX6UL Debug UART"
+               depends on SOC_IMX6UL
+               help
+                 Say Y here if you want kernel low-level debugging support
+                 on i.MX6UL.
+
        config DEBUG_IMX7D_UART
                bool "i.MX7D Debug UART"
                depends on SOC_IMX7D
@@ -1269,6 +1282,7 @@ config DEBUG_IMX_UART_PORT
                                                DEBUG_IMX6Q_UART || \
                                                DEBUG_IMX6SL_UART || \
                                                DEBUG_IMX6SX_UART || \
+                                               DEBUG_IMX6UL_UART || \
                                                DEBUG_IMX7D_UART
        default 1
        depends on ARCH_MXC
@@ -1320,6 +1334,7 @@ config DEBUG_LL_INCLUDE
                                 DEBUG_IMX6Q_UART || \
                                 DEBUG_IMX6SL_UART || \
                                 DEBUG_IMX6SX_UART || \
+                                DEBUG_IMX6UL_UART || \
                                 DEBUG_IMX7D_UART
        default "debug/ks8695.S" if DEBUG_KS8695_UART
        default "debug/msm.S" if DEBUG_QCOM_UARTDM
index ade28c7..359a3b6 100644 (file)
@@ -86,6 +86,7 @@
                        prcm: prcm@1f0000 {
                                compatible = "ti,am4-prcm";
                                reg = <0x1f0000 0x11000>;
+                               interrupts = <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>;
 
                                prcm_clocks: clocks {
                                        #address-cells = <1>;
index c3c45e6..2556a88 100644 (file)
 #define AT91_DBGU 0xfffff200 /* AT91_BASE_DBGU0 */
 #elif defined(CONFIG_AT91_DEBUG_LL_DBGU1)
 #define AT91_DBGU 0xffffee00 /* AT91_BASE_DBGU1 */
-#else
+#elif defined(CONFIG_AT91_DEBUG_LL_DBGU2)
 /* On sama5d4, use USART3 as low level serial console */
 #define AT91_DBGU 0xfc00c000 /* SAMA5D4_BASE_USART3 */
+#else
+/* On sama5d2, use UART1 as low level serial console */
+#define AT91_DBGU 0xf8020000
 #endif
 
 #ifdef CONFIG_MMU
index 66f736f..bce58e9 100644 (file)
 #define IMX6SX_UART_BASE_ADDR(n) IMX6SX_UART##n##_BASE_ADDR
 #define IMX6SX_UART_BASE(n)    IMX6SX_UART_BASE_ADDR(n)
 
+#define IMX6UL_UART1_BASE_ADDR 0x02020000
+#define IMX6UL_UART2_BASE_ADDR 0x021e8000
+#define IMX6UL_UART3_BASE_ADDR 0x021ec000
+#define IMX6UL_UART4_BASE_ADDR 0x021f0000
+#define IMX6UL_UART5_BASE_ADDR 0x021f4000
+#define IMX6UL_UART6_BASE_ADDR 0x021fc000
+#define IMX6UL_UART7_BASE_ADDR 0x02018000
+#define IMX6UL_UART8_BASE_ADDR 0x02024000
+#define IMX6UL_UART_BASE_ADDR(n) IMX6UL_UART##n##_BASE_ADDR
+#define IMX6UL_UART_BASE(n)    IMX6UL_UART_BASE_ADDR(n)
+
 #define IMX7D_UART1_BASE_ADDR  0x30860000
 #define IMX7D_UART2_BASE_ADDR  0x30890000
 #define IMX7D_UART3_BASE_ADDR  0x30880000
 #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_IMX6UL_UART)
+#define UART_PADDR     IMX_DEBUG_UART_BASE(IMX6UL)
 #elif defined(CONFIG_DEBUG_IMX7D_UART)
 #define UART_PADDR     IMX_DEBUG_UART_BASE(IMX7D)
 
index bd13ded..de86b92 100644 (file)
@@ -38,7 +38,7 @@
                .endm
 
                .macro  senduart,rd,rx
-               str     \rd, [\rx, #UART_FIFO_OFFSET]   @ TXDATA
+               strb    \rd, [\rx, #UART_FIFO_OFFSET]   @ TXDATA
                .endm
 
                .macro  waituart,rd,rx
index fd95f34..89a755b 100644 (file)
@@ -8,6 +8,18 @@ menuconfig ARCH_AT91
        select SOC_BUS
 
 if ARCH_AT91
+config SOC_SAMA5D2
+       bool "SAMA5D2 family" if ARCH_MULTI_V7
+       select SOC_SAMA5
+       select CACHE_L2X0
+       select HAVE_FB_ATMEL
+       select HAVE_AT91_UTMI
+       select HAVE_AT91_USB_CLK
+       select HAVE_AT91_H32MX
+       select HAVE_AT91_GENERATED_CLK
+       help
+         Select this if ou are using one of Atmel's SAMA5D2 family SoC.
+
 config SOC_SAMA5D3
        bool "SAMA5D3 family" if ARCH_MULTI_V7
        select SOC_SAMA5
index 8fc4763..d9cf679 100644 (file)
@@ -18,6 +18,8 @@
 #include "soc.h"
 
 static const struct at91_soc sama5_socs[] = {
+       AT91_SOC(SAMA5D2_CIDR_MATCH, SAMA5D27_EXID_MATCH,
+                "sama5d27", "sama5d2"),
        AT91_SOC(SAMA5D3_CIDR_MATCH, SAMA5D31_EXID_MATCH,
                 "sama5d31", "sama5d3"),
        AT91_SOC(SAMA5D3_CIDR_MATCH, SAMA5D33_EXID_MATCH,
@@ -64,6 +66,7 @@ DT_MACHINE_START(sama5_dt, "Atmel SAMA5")
 MACHINE_END
 
 static const char *const sama5_alt_dt_board_compat[] __initconst = {
+       "atmel,sama5d2",
        "atmel,sama5d4",
        NULL
 };
index be23c40..8ede0ef 100644 (file)
@@ -62,6 +62,9 @@ at91_soc_init(const struct at91_soc *socs);
 #define AT91SAM9XE256_CIDR_MATCH       0x329a93a0
 #define AT91SAM9XE512_CIDR_MATCH       0x329aa3a0
 
+#define SAMA5D2_CIDR_MATCH             0x0a5c08c0
+#define SAMA5D27_EXID_MATCH            0x00000021
+
 #define SAMA5D3_CIDR_MATCH             0x0a5c07c0
 #define SAMA5D31_EXID_MATCH            0x00444300
 #define SAMA5D33_EXID_MATCH            0x00414300
index 0ac9e4b..1319c3c 100644 (file)
@@ -140,10 +140,12 @@ config ARCH_BCM_63XX
 config ARCH_BRCMSTB
        bool "Broadcom BCM7XXX based boards" if ARCH_MULTI_V7
        select ARM_GIC
+       select ARM_ERRATA_798181 if SMP
        select HAVE_ARM_ARCH_TIMER
        select BRCMSTB_GISB_ARB
        select BRCMSTB_L2_IRQ
        select BCM7120_L2_IRQ
+       select ARCH_DMA_ADDR_T_64BIT if ARM_LPAE
        select ARCH_WANT_OPTIONAL_GPIOLIB
        help
          Say Y if you intend to run the kernel on a Broadcom ARM-based STB
index bf12ce6..507aad4 100644 (file)
@@ -85,23 +85,13 @@ static int cp_intc_set_irq_type(struct irq_data *d, unsigned int flow_type)
        return 0;
 }
 
-/*
- * Faking this allows us to to work with suspend functions of
- * generic drivers which call {enable|disable}_irq_wake for
- * wake up interrupt sources (eg RTC on DA850).
- */
-static int cp_intc_set_wake(struct irq_data *d, unsigned int on)
-{
-       return 0;
-}
-
 static struct irq_chip cp_intc_irq_chip = {
        .name           = "cp_intc",
        .irq_ack        = cp_intc_ack_irq,
        .irq_mask       = cp_intc_mask_irq,
        .irq_unmask     = cp_intc_unmask_irq,
        .irq_set_type   = cp_intc_set_irq_type,
-       .irq_set_wake   = cp_intc_set_wake,
+       .flags          = IRQCHIP_SKIP_SET_WAKE,
 };
 
 static struct irq_domain *cp_intc_domain;
index 573536f..8ceda28 100644 (file)
@@ -548,6 +548,14 @@ config SOC_IMX6SX
        help
          This enables support for Freescale i.MX6 SoloX processor.
 
+config SOC_IMX6UL
+       bool "i.MX6 UltraLite support"
+       select PINCTRL_IMX6UL
+       select SOC_IMX6
+
+       help
+         This enables support for Freescale i.MX6 UltraLite processor.
+
 config SOC_IMX7D
        bool "i.MX7 Dual support"
        select PINCTRL_IMX7D
index 37c502a..fb689d8 100644 (file)
@@ -83,6 +83,7 @@ endif
 obj-$(CONFIG_SOC_IMX6Q) += mach-imx6q.o
 obj-$(CONFIG_SOC_IMX6SL) += mach-imx6sl.o
 obj-$(CONFIG_SOC_IMX6SX) += mach-imx6sx.o
+obj-$(CONFIG_SOC_IMX6UL) += mach-imx6ul.o
 obj-$(CONFIG_SOC_IMX7D) += mach-imx7d.o
 
 ifeq ($(CONFIG_SUSPEND),y)
index a7fa92a..5b0f752 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_IMX6UL:
+               soc_id = "i.MX6UL";
+               break;
        case MXC_CPU_IMX7D:
                soc_id = "i.MX7D";
                break;
diff --git a/arch/arm/mach-imx/mach-imx6ul.c b/arch/arm/mach-imx/mach-imx6ul.c
new file mode 100644 (file)
index 0000000..1b97fe1
--- /dev/null
@@ -0,0 +1,88 @@
+/*
+ * 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/mfd/syscon.h>
+#include <linux/mfd/syscon/imx6q-iomuxc-gpr.h>
+#include <linux/micrel_phy.h>
+#include <linux/of_platform.h>
+#include <linux/phy.h>
+#include <linux/regmap.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+#include "common.h"
+
+static void __init imx6ul_enet_clk_init(void)
+{
+       struct regmap *gpr;
+
+       gpr = syscon_regmap_lookup_by_compatible("fsl,imx6ul-iomuxc-gpr");
+       if (!IS_ERR(gpr))
+               regmap_update_bits(gpr, IOMUXC_GPR1, IMX6UL_GPR1_ENET_CLK_DIR,
+                                  IMX6UL_GPR1_ENET_CLK_OUTPUT);
+       else
+               pr_err("failed to find fsl,imx6ul-iomux-gpr regmap\n");
+
+}
+
+static int ksz8081_phy_fixup(struct phy_device *dev)
+{
+       if (dev && dev->interface == PHY_INTERFACE_MODE_MII) {
+               phy_write(dev, 0x1f, 0x8110);
+               phy_write(dev, 0x16, 0x201);
+       } else if (dev && dev->interface == PHY_INTERFACE_MODE_RMII) {
+               phy_write(dev, 0x1f, 0x8190);
+               phy_write(dev, 0x16, 0x202);
+       }
+
+       return 0;
+}
+
+static void __init imx6ul_enet_phy_init(void)
+{
+       if (IS_BUILTIN(CONFIG_PHYLIB))
+               phy_register_fixup_for_uid(PHY_ID_KSZ8081, 0xffffffff,
+                                          ksz8081_phy_fixup);
+}
+
+static inline void imx6ul_enet_init(void)
+{
+       imx6ul_enet_clk_init();
+       imx6ul_enet_phy_init();
+}
+
+static void __init imx6ul_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);
+       imx6ul_enet_init();
+       imx_anatop_init();
+}
+
+static void __init imx6ul_init_irq(void)
+{
+       imx_init_revision_from_anatop();
+       imx_src_init();
+       irqchip_init();
+}
+
+static const char *imx6ul_dt_compat[] __initconst = {
+       "fsl,imx6ul",
+       NULL,
+};
+
+DT_MACHINE_START(IMX6UL, "Freescale i.MX6 Ultralite (Device Tree)")
+       .init_irq       = imx6ul_init_irq,
+       .init_machine   = imx6ul_init_machine,
+       .dt_compat      = imx6ul_dt_compat,
+MACHINE_END
index c4436d4..a5b1af6 100644 (file)
@@ -38,6 +38,7 @@
 #define MXC_CPU_IMX6DL         0x61
 #define MXC_CPU_IMX6SX         0x62
 #define MXC_CPU_IMX6Q          0x63
+#define MXC_CPU_IMX6UL         0x64
 #define MXC_CPU_IMX7D          0x72
 
 #define IMX_DDR_TYPE_LPDDR2            1
@@ -165,6 +166,11 @@ static inline bool cpu_is_imx6sx(void)
        return __mxc_cpu_type == MXC_CPU_IMX6SX;
 }
 
+static inline bool cpu_is_imx6ul(void)
+{
+       return __mxc_cpu_type == MXC_CPU_IMX6UL;
+}
+
 static inline bool cpu_is_imx6q(void)
 {
        return __mxc_cpu_type == MXC_CPU_IMX6Q;
index 9f59e58..aeece17 100644 (file)
@@ -3,6 +3,7 @@ menuconfig ARCH_MEDIATEK
        select ARM_GIC
        select PINCTRL
        select MTK_TIMER
+       select MFD_SYSCON
        help
          Support for Mediatek MT65xx & MT81xx SoCs
 
index e46e9ea..44eedf3 100644 (file)
@@ -65,18 +65,6 @@ static const struct of_device_id of_coherency_table[] = {
 int ll_enable_coherency(void);
 void ll_add_cpu_to_smp_group(void);
 
-int set_cpu_coherent(void)
-{
-       if (!coherency_base) {
-               pr_warn("Can't make current CPU cache coherent.\n");
-               pr_warn("Coherency fabric is not initialized\n");
-               return 1;
-       }
-
-       ll_add_cpu_to_smp_group();
-       return ll_enable_coherency();
-}
-
 static int mvebu_hwcc_notifier(struct notifier_block *nb,
                               unsigned long event, void *__dev)
 {
@@ -206,6 +194,23 @@ static int coherency_type(void)
        return type;
 }
 
+int set_cpu_coherent(void)
+{
+       int type = coherency_type();
+
+       if (type == COHERENCY_FABRIC_TYPE_ARMADA_370_XP) {
+               if (!coherency_base) {
+                       pr_warn("Can't make current CPU cache coherent.\n");
+                       pr_warn("Coherency fabric is not initialized\n");
+                       return 1;
+               }
+               ll_add_cpu_to_smp_group();
+               return ll_enable_coherency();
+       }
+
+       return 0;
+}
+
 int coherency_available(void)
 {
        return coherency_type() != COHERENCY_FABRIC_TYPE_NONE;
index 3e0aca1..6b77549 100644 (file)
@@ -25,6 +25,6 @@ int mvebu_system_controller_get_soc_id(u32 *dev, u32 *rev);
 
 void __iomem *mvebu_get_scu_base(void);
 
-int mvebu_pm_init(void (*board_pm_enter)(void __iomem *sdram_reg, u32 srcmd));
-
+int mvebu_pm_suspend_init(void (*board_pm_enter)(void __iomem *sdram_reg,
+                                                       u32 srcmd));
 #endif
index 301ab38..db17121 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Board-level suspend/resume support.
  *
- * Copyright (C) 2014 Marvell
+ * Copyright (C) 2014-2015 Marvell
  *
  * Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
  *
 #include <linux/slab.h>
 #include "common.h"
 
-#define ARMADA_XP_GP_PIC_NR_GPIOS 3
+#define ARMADA_PIC_NR_GPIOS 3
 
 static void __iomem *gpio_ctrl;
-static int pic_gpios[ARMADA_XP_GP_PIC_NR_GPIOS];
-static int pic_raw_gpios[ARMADA_XP_GP_PIC_NR_GPIOS];
+static int pic_gpios[ARMADA_PIC_NR_GPIOS];
+static int pic_raw_gpios[ARMADA_PIC_NR_GPIOS];
 
-static void mvebu_armada_xp_gp_pm_enter(void __iomem *sdram_reg, u32 srcmd)
+static void mvebu_armada_pm_enter(void __iomem *sdram_reg, u32 srcmd)
 {
        u32 reg, ackcmd;
        int i;
 
        /* Put 001 as value on the GPIOs */
        reg = readl(gpio_ctrl);
-       for (i = 0; i < ARMADA_XP_GP_PIC_NR_GPIOS; i++)
+       for (i = 0; i < ARMADA_PIC_NR_GPIOS; i++)
                reg &= ~BIT(pic_raw_gpios[i]);
        reg |= BIT(pic_raw_gpios[0]);
        writel(reg, gpio_ctrl);
 
        /* Prepare writing 111 to the GPIOs */
        ackcmd = readl(gpio_ctrl);
-       for (i = 0; i < ARMADA_XP_GP_PIC_NR_GPIOS; i++)
+       for (i = 0; i < ARMADA_PIC_NR_GPIOS; i++)
                ackcmd |= BIT(pic_raw_gpios[i]);
 
        srcmd = cpu_to_le32(srcmd);
@@ -76,7 +76,7 @@ static void mvebu_armada_xp_gp_pm_enter(void __iomem *sdram_reg, u32 srcmd)
                  [ackcmd] "r" (ackcmd), [gpio_ctrl] "r" (gpio_ctrl) : "r1");
 }
 
-static int mvebu_armada_xp_gp_pm_init(void)
+static int __init mvebu_armada_pm_init(void)
 {
        struct device_node *np;
        struct device_node *gpio_ctrl_np;
@@ -89,7 +89,7 @@ static int mvebu_armada_xp_gp_pm_init(void)
        if (!np)
                return -ENODEV;
 
-       for (i = 0; i < ARMADA_XP_GP_PIC_NR_GPIOS; i++) {
+       for (i = 0; i < ARMADA_PIC_NR_GPIOS; i++) {
                char *name;
                struct of_phandle_args args;
 
@@ -134,11 +134,19 @@ static int mvebu_armada_xp_gp_pm_init(void)
        if (!gpio_ctrl)
                return -ENOMEM;
 
-       mvebu_pm_init(mvebu_armada_xp_gp_pm_enter);
+       mvebu_pm_suspend_init(mvebu_armada_pm_enter);
 
 out:
        of_node_put(np);
        return ret;
 }
 
-late_initcall(mvebu_armada_xp_gp_pm_init);
+/*
+ * Registering the mvebu_board_pm_enter callback must be done before
+ * the platform_suspend_ops will be registered. In the same time we
+ * also need to have the gpio devices registered. That's why we use a
+ * device_initcall_sync which is called after all the device_initcall
+ * (used by the gpio device) but before the late_initcall (used to
+ * register the platform_suspend_ops)
+ */
+device_initcall_sync(mvebu_armada_pm_init);
index 6573a8f..8d32bf7 100644 (file)
@@ -105,12 +105,10 @@ static phys_addr_t mvebu_internal_reg_base(void)
        return of_translate_address(np, in_addr);
 }
 
-static void mvebu_pm_store_bootinfo(void)
+static void mvebu_pm_store_armadaxp_bootinfo(u32 *store_addr)
 {
-       u32 *store_addr;
        phys_addr_t resume_pc;
 
-       store_addr = phys_to_virt(BOOT_INFO_ADDR);
        resume_pc = virt_to_phys(armada_370_xp_cpu_resume);
 
        /*
@@ -151,14 +149,30 @@ static void mvebu_pm_store_bootinfo(void)
        writel(BOOT_MAGIC_LIST_END, store_addr);
 }
 
-static int mvebu_pm_enter(suspend_state_t state)
+static int mvebu_pm_store_bootinfo(void)
 {
-       if (state != PM_SUSPEND_MEM)
-               return -EINVAL;
+       u32 *store_addr;
+
+       store_addr = phys_to_virt(BOOT_INFO_ADDR);
+
+       if (of_machine_is_compatible("marvell,armadaxp"))
+               mvebu_pm_store_armadaxp_bootinfo(store_addr);
+       else
+               return -ENODEV;
+
+       return 0;
+}
+
+static int mvebu_enter_suspend(void)
+{
+       int ret;
+
+       ret = mvebu_pm_store_bootinfo();
+       if (ret)
+               return ret;
 
        cpu_pm_enter();
 
-       mvebu_pm_store_bootinfo();
        cpu_suspend(0, mvebu_pm_powerdown);
 
        outer_resume();
@@ -168,23 +182,62 @@ static int mvebu_pm_enter(suspend_state_t state)
        set_cpu_coherent();
 
        cpu_pm_exit();
+       return 0;
+}
+
+static int mvebu_pm_enter(suspend_state_t state)
+{
+       switch (state) {
+       case PM_SUSPEND_STANDBY:
+               cpu_do_idle();
+               break;
+       case PM_SUSPEND_MEM:
+               pr_warn("Entering suspend to RAM. Only special wake-up sources will resume the system\n");
+               return mvebu_enter_suspend();
+       default:
+               return -EINVAL;
+       }
+       return 0;
+}
+
+static int mvebu_pm_valid(suspend_state_t state)
+{
+       if (state == PM_SUSPEND_STANDBY)
+               return 1;
+
+       if (state == PM_SUSPEND_MEM && mvebu_board_pm_enter != NULL)
+               return 1;
 
        return 0;
 }
 
 static const struct platform_suspend_ops mvebu_pm_ops = {
        .enter = mvebu_pm_enter,
-       .valid = suspend_valid_only_mem,
+       .valid = mvebu_pm_valid,
 };
 
-int mvebu_pm_init(void (*board_pm_enter)(void __iomem *sdram_reg, u32 srcmd))
+static int __init mvebu_pm_init(void)
+{
+       if (!of_machine_is_compatible("marvell,armadaxp") &&
+           !of_machine_is_compatible("marvell,armada370") &&
+           !of_machine_is_compatible("marvell,armada380") &&
+           !of_machine_is_compatible("marvell,armada390"))
+               return -ENODEV;
+
+       suspend_set_ops(&mvebu_pm_ops);
+
+       return 0;
+}
+
+
+late_initcall(mvebu_pm_init);
+
+int __init mvebu_pm_suspend_init(void (*board_pm_enter)(void __iomem *sdram_reg,
+                                                       u32 srcmd))
 {
        struct device_node *np;
        struct resource res;
 
-       if (!of_machine_is_compatible("marvell,armadaxp"))
-               return -ENODEV;
-
        np = of_find_compatible_node(NULL, NULL,
                                     "marvell,armada-xp-sdram-controller");
        if (!np)
@@ -212,7 +265,5 @@ int mvebu_pm_init(void (*board_pm_enter)(void __iomem *sdram_reg, u32 srcmd))
 
        mvebu_board_pm_enter = board_pm_enter;
 
-       suspend_set_ops(&mvebu_pm_ops);
-
        return 0;
 }
index 8a7a606..9358696 100644 (file)
@@ -226,8 +226,7 @@ obj-$(CONFIG_SOC_DRA7XX)            += omap_hwmod_7xx_data.o
 # EMU peripherals
 obj-$(CONFIG_HW_PERF_EVENTS)           += pmu.o
 
-iommu-$(CONFIG_OMAP_IOMMU)             := omap-iommu.o
-obj-y                                  += $(iommu-m) $(iommu-y)
+obj-$(CONFIG_OMAP_IOMMU)               += omap-iommu.o
 
 # OMAP2420 MSDI controller integration support ("MMC")
 obj-$(CONFIG_SOC_OMAP2420)             += msdi.o
index 34ff14b..24c9afc 100644 (file)
@@ -169,7 +169,7 @@ static const char *const ti814x_boards_compat[] __initconst = {
        NULL,
 };
 
-DT_MACHINE_START(TI81XX_DT, "Generic ti814x (Flattened Device Tree)")
+DT_MACHINE_START(TI814X_DT, "Generic ti814x (Flattened Device Tree)")
        .reserve        = omap_reserve,
        .map_io         = ti81xx_map_io,
        .init_early     = ti814x_init_early,
@@ -297,7 +297,7 @@ static const char *const dra74x_boards_compat[] __initconst = {
 DT_MACHINE_START(DRA74X_DT, "Generic DRA74X (Flattened Device Tree)")
        .reserve        = omap_reserve,
        .smp            = smp_ops(omap4_smp_ops),
-       .map_io         = omap5_map_io,
+       .map_io         = dra7xx_map_io,
        .init_early     = dra7xx_init_early,
        .init_late      = dra7xx_init_late,
        .init_irq       = omap_gic_of_init,
@@ -316,7 +316,7 @@ static const char *const dra72x_boards_compat[] __initconst = {
 
 DT_MACHINE_START(DRA72X_DT, "Generic DRA72X (Flattened Device Tree)")
        .reserve        = omap_reserve,
-       .map_io         = omap5_map_io,
+       .map_io         = dra7xx_map_io,
        .init_early     = dra7xx_init_early,
        .init_late      = dra7xx_init_late,
        .init_irq       = omap_gic_of_init,
index 77bab5f..2c398ce 100644 (file)
@@ -216,7 +216,8 @@ extern void __init omap242x_clockdomains_init(void);
 extern void __init omap243x_clockdomains_init(void);
 extern void __init omap3xxx_clockdomains_init(void);
 extern void __init am33xx_clockdomains_init(void);
-extern void __init ti81xx_clockdomains_init(void);
+extern void __init ti814x_clockdomains_init(void);
+extern void __init ti816x_clockdomains_init(void);
 extern void __init omap44xx_clockdomains_init(void);
 extern void __init omap54xx_clockdomains_init(void);
 extern void __init dra7xx_clockdomains_init(void);
index 57d5df0..7581e03 100644 (file)
@@ -331,7 +331,7 @@ static struct clockdomain l4per2_7xx_clkdm = {
        .dep_bit          = DRA7XX_L4PER2_STATDEP_SHIFT,
        .wkdep_srcs       = l4per2_wkup_sleep_deps,
        .sleepdep_srcs    = l4per2_wkup_sleep_deps,
-       .flags            = CLKDM_CAN_HWSUP_SWSUP,
+       .flags            = CLKDM_CAN_SWSUP,
 };
 
 static struct clockdomain mpu0_7xx_clkdm = {
index ce2a820..53442c8 100644 (file)
@@ -165,7 +165,24 @@ static struct clockdomain default_l3_slow_816x_clkdm = {
        .flags          = CLKDM_CAN_SWSUP,
 };
 
-static struct clockdomain *clockdomains_ti81xx[] __initdata = {
+static struct clockdomain *clockdomains_ti814x[] __initdata = {
+       &alwon_l3_slow_81xx_clkdm,
+       &alwon_l3_med_81xx_clkdm,
+       &alwon_l3_fast_81xx_clkdm,
+       &alwon_ethernet_81xx_clkdm,
+       &mmu_81xx_clkdm,
+       &mmu_cfg_81xx_clkdm,
+       NULL,
+};
+
+void __init ti814x_clockdomains_init(void)
+{
+       clkdm_register_platform_funcs(&am33xx_clkdm_operations);
+       clkdm_register_clkdms(clockdomains_ti814x);
+       clkdm_complete_init();
+}
+
+static struct clockdomain *clockdomains_ti816x[] __initdata = {
        &alwon_mpu_816x_clkdm,
        &alwon_l3_slow_81xx_clkdm,
        &alwon_l3_med_81xx_clkdm,
@@ -185,10 +202,10 @@ static struct clockdomain *clockdomains_ti81xx[] __initdata = {
        NULL,
 };
 
-void __init ti81xx_clockdomains_init(void)
+void __init ti816x_clockdomains_init(void)
 {
        clkdm_register_platform_funcs(&am33xx_clkdm_operations);
-       clkdm_register_clkdms(clockdomains_ti81xx);
+       clkdm_register_clkdms(clockdomains_ti816x);
        clkdm_complete_init();
 }
 #endif
index cf3cf22..749d50b 100644 (file)
@@ -198,6 +198,7 @@ void __init omap3_map_io(void);
 void __init am33xx_map_io(void);
 void __init omap4_map_io(void);
 void __init omap5_map_io(void);
+void __init dra7xx_map_io(void);
 void __init ti81xx_map_io(void);
 
 /**
index f008930..cf58551 100644 (file)
@@ -652,6 +652,7 @@ static const struct of_device_id omap_scrm_dt_match_table[] = {
        { .compatible = "ti,am4-scm", .data = &ctrl_data },
        { .compatible = "ti,omap2-scm", .data = &omap2_ctrl_data },
        { .compatible = "ti,omap3-scm", .data = &omap2_ctrl_data },
+       { .compatible = "ti,dm814-scm", .data = &ctrl_data },
        { .compatible = "ti,dm816-scrm", .data = &ctrl_data },
        { .compatible = "ti,omap4-scm-core", .data = &ctrl_data },
        { .compatible = "ti,omap5-scm-core", .data = &ctrl_data },
index a253aaf..6a4822d 100644 (file)
@@ -235,7 +235,7 @@ static struct map_desc omap44xx_io_desc[] __initdata = {
 };
 #endif
 
-#if defined(CONFIG_SOC_OMAP5) || defined(CONFIG_SOC_DRA7XX)
+#ifdef CONFIG_SOC_OMAP5
 static struct map_desc omap54xx_io_desc[] __initdata = {
        {
                .virtual        = L3_54XX_VIRT,
@@ -264,6 +264,53 @@ static struct map_desc omap54xx_io_desc[] __initdata = {
 };
 #endif
 
+#ifdef CONFIG_SOC_DRA7XX
+static struct map_desc dra7xx_io_desc[] __initdata = {
+       {
+               .virtual        = L4_CFG_MPU_DRA7XX_VIRT,
+               .pfn            = __phys_to_pfn(L4_CFG_MPU_DRA7XX_PHYS),
+               .length         = L4_CFG_MPU_DRA7XX_SIZE,
+               .type           = MT_DEVICE,
+       },
+       {
+               .virtual        = L3_MAIN_SN_DRA7XX_VIRT,
+               .pfn            = __phys_to_pfn(L3_MAIN_SN_DRA7XX_PHYS),
+               .length         = L3_MAIN_SN_DRA7XX_SIZE,
+               .type           = MT_DEVICE,
+       },
+       {
+               .virtual        = L4_PER1_DRA7XX_VIRT,
+               .pfn            = __phys_to_pfn(L4_PER1_DRA7XX_PHYS),
+               .length         = L4_PER1_DRA7XX_SIZE,
+               .type           = MT_DEVICE,
+       },
+       {
+               .virtual        = L4_PER2_DRA7XX_VIRT,
+               .pfn            = __phys_to_pfn(L4_PER2_DRA7XX_PHYS),
+               .length         = L4_PER2_DRA7XX_SIZE,
+               .type           = MT_DEVICE,
+       },
+       {
+               .virtual        = L4_PER3_DRA7XX_VIRT,
+               .pfn            = __phys_to_pfn(L4_PER3_DRA7XX_PHYS),
+               .length         = L4_PER3_DRA7XX_SIZE,
+               .type           = MT_DEVICE,
+       },
+       {
+               .virtual        = L4_CFG_DRA7XX_VIRT,
+               .pfn            = __phys_to_pfn(L4_CFG_DRA7XX_PHYS),
+               .length         = L4_CFG_DRA7XX_SIZE,
+               .type           = MT_DEVICE,
+       },
+       {
+               .virtual        = L4_WKUP_DRA7XX_VIRT,
+               .pfn            = __phys_to_pfn(L4_WKUP_DRA7XX_PHYS),
+               .length         = L4_WKUP_DRA7XX_SIZE,
+               .type           = MT_DEVICE,
+       },
+};
+#endif
+
 #ifdef CONFIG_SOC_OMAP2420
 void __init omap242x_map_io(void)
 {
@@ -308,12 +355,19 @@ void __init omap4_map_io(void)
 }
 #endif
 
-#if defined(CONFIG_SOC_OMAP5) ||  defined(CONFIG_SOC_DRA7XX)
+#ifdef CONFIG_SOC_OMAP5
 void __init omap5_map_io(void)
 {
        iotable_init(omap54xx_io_desc, ARRAY_SIZE(omap54xx_io_desc));
 }
 #endif
+
+#ifdef CONFIG_SOC_DRA7XX
+void __init dra7xx_map_io(void)
+{
+       iotable_init(dra7xx_io_desc, ARRAY_SIZE(dra7xx_io_desc));
+}
+#endif
 /*
  * omap2_init_reprogram_sdrc - reprogram SDRC timing parameters
  *
@@ -553,11 +607,11 @@ void __init ti814x_init_early(void)
        omap2_prcm_base_init();
        omap3xxx_voltagedomains_init();
        omap3xxx_powerdomains_init();
-       ti81xx_clockdomains_init();
-       ti81xx_hwmod_init();
+       ti814x_clockdomains_init();
+       dm814x_hwmod_init();
        omap_hwmod_init_postsetup();
        if (of_have_populated_dt())
-               omap_clk_soc_init = ti81xx_dt_clk_init;
+               omap_clk_soc_init = dm814x_dt_clk_init;
 }
 
 void __init ti816x_init_early(void)
@@ -570,11 +624,11 @@ void __init ti816x_init_early(void)
        omap2_prcm_base_init();
        omap3xxx_voltagedomains_init();
        omap3xxx_powerdomains_init();
-       ti81xx_clockdomains_init();
-       ti81xx_hwmod_init();
+       ti816x_clockdomains_init();
+       dm816x_hwmod_init();
        omap_hwmod_init_postsetup();
        if (of_have_populated_dt())
-               omap_clk_soc_init = ti81xx_dt_clk_init;
+               omap_clk_soc_init = dm816x_dt_clk_init;
 }
 #endif
 
index cce2b65..6191d24 100644 (file)
 #define L4_PER_54XX_PHYS       L4_PER_54XX_BASE /* 0x48000000 --> 0xfa000000 */
 #define L4_PER_54XX_VIRT       (L4_PER_54XX_PHYS + OMAP2_L4_IO_OFFSET)
 #define L4_PER_54XX_SIZE       SZ_4M
+
+/*
+ * ----------------------------------------------------------------------------
+ * DRA7xx specific IO mapping
+ * ----------------------------------------------------------------------------
+ */
+/*
+ * L3_MAIN_SN_DRA7XX_PHYS 0x44000000 --> 0xf8000000
+ * The overall space is 24MiB (0x4400_0000<->0x457F_FFFF), but mapping
+ * everything is just inefficient, since, there are too many address holes.
+ */
+#define L3_MAIN_SN_DRA7XX_PHYS         L3_MAIN_SN_DRA7XX_BASE
+#define L3_MAIN_SN_DRA7XX_VIRT         (L3_MAIN_SN_DRA7XX_PHYS + OMAP4_L3_IO_OFFSET)
+#define L3_MAIN_SN_DRA7XX_SIZE         SZ_1M
+
+/*
+ * L4_PER1_DRA7XX_PHYS (0x4800_000<>0x480D_2FFF) -> 0.82MiB (alloc 1MiB)
+ *     (0x48000000<->0x48100000) <=> (0xFA000000<->0xFA100000)
+ */
+#define L4_PER1_DRA7XX_PHYS            L4_PER1_DRA7XX_BASE
+#define L4_PER1_DRA7XX_VIRT            (L4_PER1_DRA7XX_PHYS + OMAP2_L4_IO_OFFSET)
+#define L4_PER1_DRA7XX_SIZE            SZ_1M
+
+/*
+ * L4_CFG_MPU_DRA7XX_PHYS      (0x48210000<>0x482A_F2FF) -> 0.62MiB (alloc 1MiB)
+ *     (0x48210000<->0x48310000) <=> (0xFA210000<->0xFA310000)
+ * NOTE: This is a bit of an orphan memory map sitting isolated in TRM
+ */
+#define L4_CFG_MPU_DRA7XX_PHYS         L4_CFG_MPU_DRA7XX_BASE
+#define L4_CFG_MPU_DRA7XX_VIRT         (L4_CFG_MPU_DRA7XX_PHYS + OMAP2_L4_IO_OFFSET)
+#define L4_CFG_MPU_DRA7XX_SIZE         SZ_1M
+
+/*
+ * L4_PER2_DRA7XX_PHYS (0x4840_0000<>0x4848_8FFF) -> .53MiB (alloc 1MiB)
+ *     (0x48400000<->0x48500000) <=> (0xFA400000<->0xFA500000)
+ */
+#define L4_PER2_DRA7XX_PHYS            L4_PER2_DRA7XX_BASE
+#define L4_PER2_DRA7XX_VIRT            (L4_PER2_DRA7XX_PHYS + OMAP2_L4_IO_OFFSET)
+#define L4_PER2_DRA7XX_SIZE            SZ_1M
+
+/*
+ * L4_PER3_DRA7XX_PHYS (0x4880_0000<>0x489E_0FFF) -> 1.87MiB (alloc 2MiB)
+ *     (0x48800000<->0x48A00000) <=> (0xFA800000<->0xFAA00000)
+ */
+#define L4_PER3_DRA7XX_PHYS            L4_PER3_DRA7XX_BASE
+#define L4_PER3_DRA7XX_VIRT            (L4_PER3_DRA7XX_PHYS + OMAP2_L4_IO_OFFSET)
+#define L4_PER3_DRA7XX_SIZE            SZ_2M
+
+/*
+ * L4_CFG_DRA7XX_PHYS  (0x4A00_0000<>0x4A22_BFFF) ->2.17MiB (alloc 3MiB)?
+ *     (0x4A000000<->0x4A300000) <=> (0xFC000000<->0xFC300000)
+ */
+#define L4_CFG_DRA7XX_PHYS             L4_CFG_DRA7XX_BASE
+#define L4_CFG_DRA7XX_VIRT             (L4_CFG_DRA7XX_PHYS + OMAP2_L4_IO_OFFSET)
+#define L4_CFG_DRA7XX_SIZE             (SZ_1M + SZ_2M)
+
+/*
+ * L4_WKUP_DRA7XX_PHYS (0x4AE0_0000<>0x4AE3_EFFF) -> .24 mb (alloc 1MiB)?
+ *     (0x4AE00000<->4AF00000) <=> (0xFCE00000<->0xFCF00000)
+ */
+#define L4_WKUP_DRA7XX_PHYS            L4_WKUP_DRA7XX_BASE
+#define L4_WKUP_DRA7XX_VIRT            (L4_WKUP_DRA7XX_PHYS + OMAP2_L4_IO_OFFSET)
+#define L4_WKUP_DRA7XX_SIZE            SZ_1M
index 4068350..8867eb4 100644 (file)
@@ -11,7 +11,6 @@
  */
 
 #include <linux/of.h>
-#include <linux/module.h>
 #include <linux/platform_device.h>
 #include <linux/err.h>
 #include <linux/slab.h>
@@ -63,15 +62,5 @@ static int __init omap_iommu_init(void)
 
        return omap_hwmod_for_each_by_class("mmu", omap_iommu_dev_init, NULL);
 }
-/* must be ready before omap3isp is probed */
 omap_subsys_initcall(omap_iommu_init);
-
-static void __exit omap_iommu_exit(void)
-{
-       /* Do nothing */
-}
-module_exit(omap_iommu_exit);
-
-MODULE_AUTHOR("Hiroshi DOYU");
-MODULE_DESCRIPTION("omap iommu: omap device registration");
-MODULE_LICENSE("GPL v2");
+/* must be ready before omap3isp is probed */
index 79f49d9..65024af 100644 (file)
@@ -105,7 +105,7 @@ static void dummy_cpu_resume(void)
 static void dummy_scu_prepare(unsigned int cpu_id, unsigned int cpu_state)
 {}
 
-struct cpu_pm_ops omap_pm_ops = {
+static struct cpu_pm_ops omap_pm_ops = {
        .finish_suspend         = default_finish_suspend,
        .resume                 = dummy_cpu_resume,
        .scu_prepare            = dummy_scu_prepare,
index 103a49f..4bdd22e 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/init.h>
 #include <linux/reboot.h>
 
+#include "common.h"
 #include "control.h"
 #include "prm.h"
 
index a99e7f7..e17136a 100644 (file)
@@ -9,6 +9,7 @@
 
 #include <linux/types.h>
 #include <linux/reboot.h>
+#include "common.h"
 #include "prm.h"
 
 /**
index 2d35c57..0ca8e93 100644 (file)
 #define OMAP54XX_CTRL_BASE             0x4a002800
 #define OMAP54XX_SAR_RAM_BASE          0x4ae26000
 
+/* DRA7 specific base addresses */
+#define L3_MAIN_SN_DRA7XX_BASE         0x44000000
+#define L4_PER1_DRA7XX_BASE            0x48000000
+#define L4_CFG_MPU_DRA7XX_BASE         0x48210000
+#define L4_PER2_DRA7XX_BASE            0x48400000
+#define L4_PER3_DRA7XX_BASE            0x48800000
+#define L4_CFG_DRA7XX_BASE             0x4A000000
+#define L4_WKUP_DRA7XX_BASE            0x4ae00000
 #define DRA7XX_CM_CORE_AON_BASE                0x4a005000
 #define DRA7XX_CTRL_BASE               0x4a003400
 #define DRA7XX_TAP_BASE                        0x4ae0c000
index 6ef9e63..cc8a987 100644 (file)
@@ -300,7 +300,20 @@ static void _write_sysconfig(u32 v, struct omap_hwmod *oh)
 
        /* Module might have lost context, always update cache and register */
        oh->_sysc_cache = v;
+
+       /*
+        * Some IP blocks (such as RTC) require unlocking of IP before
+        * accessing its registers. If a function pointer is present
+        * to unlock, then call it before accessing sysconfig and
+        * call lock after writing sysconfig.
+        */
+       if (oh->class->unlock)
+               oh->class->unlock(oh);
+
        omap_hwmod_write(v, oh, oh->class->sysc->sysc_offs);
+
+       if (oh->class->lock)
+               oh->class->lock(oh);
 }
 
 /**
@@ -3887,7 +3900,8 @@ void __init omap_hwmod_init(void)
                soc_ops.init_clkdm = _init_clkdm;
                soc_ops.update_context_lost = _omap4_update_context_lost;
                soc_ops.get_context_lost = _omap4_get_context_lost;
-       } else if (cpu_is_ti816x() || soc_is_am33xx() || soc_is_am43xx()) {
+       } else if (cpu_is_ti814x() || cpu_is_ti816x() || soc_is_am33xx() ||
+                  soc_is_am43xx()) {
                soc_ops.enable_module = _omap4_enable_module;
                soc_ops.disable_module = _omap4_disable_module;
                soc_ops.wait_target_ready = _omap4_wait_target_ready;
index b5d27ec..ca6df1a 100644 (file)
@@ -576,6 +576,8 @@ struct omap_hwmod_omap4_prcm {
  * @pre_shutdown: ptr to fn to be executed immediately prior to device shutdown
  * @reset: ptr to fn to be executed in place of the standard hwmod reset fn
  * @enable_preprogram:  ptr to fn to be executed during device enable
+ * @lock: ptr to fn to be executed to lock IP registers
+ * @unlock: ptr to fn to be executed to unlock IP registers
  *
  * Represent the class of a OMAP hardware "modules" (e.g. timer,
  * smartreflex, gpio, uart...)
@@ -600,6 +602,8 @@ struct omap_hwmod_class {
        int                                     (*pre_shutdown)(struct omap_hwmod *oh);
        int                                     (*reset)(struct omap_hwmod *oh);
        int                                     (*enable_preprogram)(struct omap_hwmod *oh);
+       void                                    (*lock)(struct omap_hwmod *oh);
+       void                                    (*unlock)(struct omap_hwmod *oh);
 };
 
 /**
@@ -755,7 +759,8 @@ extern int omap3xxx_hwmod_init(void);
 extern int omap44xx_hwmod_init(void);
 extern int omap54xx_hwmod_init(void);
 extern int am33xx_hwmod_init(void);
-extern int ti81xx_hwmod_init(void);
+extern int dm814x_hwmod_init(void);
+extern int dm816x_hwmod_init(void);
 extern int dra7xx_hwmod_init(void);
 int am43xx_hwmod_init(void);
 
index 6dcfd03..36bcd2e 100644 (file)
@@ -20,7 +20,7 @@
 #include "prm-regbits-24xx.h"
 #include "wd_timer.h"
 
-struct omap_hwmod_dma_info omap2xxx_dss_sdma_chs[] = {
+static struct omap_hwmod_dma_info omap2xxx_dss_sdma_chs[] = {
        { .name = "dispc", .dma_req = 5 },
        { .dma_req = -1, },
 };
index 215d5ef..e97a894 100644 (file)
@@ -480,7 +480,7 @@ static struct omap_hwmod am43xx_dss_core_hwmod = {
 
 /* dispc */
 
-struct omap_dss_dispc_dev_attr am43xx_dss_dispc_dev_attr = {
+static struct omap_dss_dispc_dev_attr am43xx_dss_dispc_dev_attr = {
        .manager_count          = 1,
        .has_framedonetv_irq    = 0
 };
index c924137..b1288f5 100644 (file)
  */
 
 /*
- * The alwon .clkctrl_offs field is offset from the CM_ALWON, that's
- * TRM 18.7.17 CM_ALWON device register values minus 0x1400.
+ * Common alwon .clkctrl_offs from dm814x TRM "Table 2-278. CM_ALWON REGISTERS"
+ * also dm816x TRM 18.7.17 CM_ALWON device register values minus 0x1400.
  */
+#define DM81XX_CM_ALWON_MCASP0_CLKCTRL         0x140
+#define DM81XX_CM_ALWON_MCASP1_CLKCTRL         0x144
+#define DM81XX_CM_ALWON_MCASP2_CLKCTRL         0x148
+#define DM81XX_CM_ALWON_MCBSP_CLKCTRL          0x14c
+#define DM81XX_CM_ALWON_UART_0_CLKCTRL         0x150
+#define DM81XX_CM_ALWON_UART_1_CLKCTRL         0x154
+#define DM81XX_CM_ALWON_UART_2_CLKCTRL         0x158
+#define DM81XX_CM_ALWON_GPIO_0_CLKCTRL         0x15c
+#define DM81XX_CM_ALWON_GPIO_1_CLKCTRL         0x160
+#define DM81XX_CM_ALWON_I2C_0_CLKCTRL          0x164
+#define DM81XX_CM_ALWON_I2C_1_CLKCTRL          0x168
+#define DM81XX_CM_ALWON_WDTIMER_CLKCTRL                0x18c
+#define DM81XX_CM_ALWON_SPI_CLKCTRL            0x190
+#define DM81XX_CM_ALWON_MAILBOX_CLKCTRL                0x194
+#define DM81XX_CM_ALWON_SPINBOX_CLKCTRL                0x198
+#define DM81XX_CM_ALWON_MMUDATA_CLKCTRL                0x19c
+#define DM81XX_CM_ALWON_MMUCFG_CLKCTRL         0x1a8
+#define DM81XX_CM_ALWON_CONTROL_CLKCTRL                0x1c4
+#define DM81XX_CM_ALWON_GPMC_CLKCTRL           0x1d0
+#define DM81XX_CM_ALWON_ETHERNET_0_CLKCTRL     0x1d4
+#define DM81XX_CM_ALWON_L3_CLKCTRL             0x1e4
+#define DM81XX_CM_ALWON_L4HS_CLKCTRL           0x1e8
+#define DM81XX_CM_ALWON_L4LS_CLKCTRL           0x1ec
+#define DM81XX_CM_ALWON_RTC_CLKCTRL            0x1f0
+#define DM81XX_CM_ALWON_TPCC_CLKCTRL           0x1f4
+#define DM81XX_CM_ALWON_TPTC0_CLKCTRL          0x1f8
+#define DM81XX_CM_ALWON_TPTC1_CLKCTRL          0x1fc
+#define DM81XX_CM_ALWON_TPTC2_CLKCTRL          0x200
+#define DM81XX_CM_ALWON_TPTC3_CLKCTRL          0x204
+
+/* Registers specific to dm814x */
+#define DM814X_CM_ALWON_MCASP_3_4_5_CLKCTRL    0x16c
+#define DM814X_CM_ALWON_ATL_CLKCTRL            0x170
+#define DM814X_CM_ALWON_MLB_CLKCTRL            0x174
+#define DM814X_CM_ALWON_PATA_CLKCTRL           0x178
+#define DM814X_CM_ALWON_UART_3_CLKCTRL         0x180
+#define DM814X_CM_ALWON_UART_4_CLKCTRL         0x184
+#define DM814X_CM_ALWON_UART_5_CLKCTRL         0x188
+#define DM814X_CM_ALWON_OCM_0_CLKCTRL          0x1b4
+#define DM814X_CM_ALWON_VCP_CLKCTRL            0x1b8
+#define DM814X_CM_ALWON_MPU_CLKCTRL            0x1dc
+#define DM814X_CM_ALWON_DEBUGSS_CLKCTRL                0x1e0
+#define DM814X_CM_ALWON_DCAN_0_1_CLKCTRL       0x218
+#define DM814X_CM_ALWON_MMCHS_0_CLKCTRL                0x21c
+#define DM814X_CM_ALWON_MMCHS_1_CLKCTRL                0x220
+#define DM814X_CM_ALWON_MMCHS_2_CLKCTRL                0x224
+#define DM814X_CM_ALWON_CUST_EFUSE_CLKCTRL     0x228
+
+/* Registers specific to dm816x */
 #define DM816X_DM_ALWON_BASE           0x1400
-#define DM816X_CM_ALWON_MCASP0_CLKCTRL (0x1540 - DM816X_DM_ALWON_BASE)
-#define DM816X_CM_ALWON_MCASP1_CLKCTRL (0x1544 - DM816X_DM_ALWON_BASE)
-#define DM816X_CM_ALWON_MCASP2_CLKCTRL (0x1548 - DM816X_DM_ALWON_BASE)
-#define DM816X_CM_ALWON_MCBSP_CLKCTRL  (0x154c - DM816X_DM_ALWON_BASE)
-#define DM816X_CM_ALWON_UART_0_CLKCTRL (0x1550 - DM816X_DM_ALWON_BASE)
-#define DM816X_CM_ALWON_UART_1_CLKCTRL (0x1554 - DM816X_DM_ALWON_BASE)
-#define DM816X_CM_ALWON_UART_2_CLKCTRL (0x1558 - DM816X_DM_ALWON_BASE)
-#define DM816X_CM_ALWON_GPIO_0_CLKCTRL (0x155c - DM816X_DM_ALWON_BASE)
-#define DM816X_CM_ALWON_GPIO_1_CLKCTRL (0x1560 - DM816X_DM_ALWON_BASE)
-#define DM816X_CM_ALWON_I2C_0_CLKCTRL  (0x1564 - DM816X_DM_ALWON_BASE)
-#define DM816X_CM_ALWON_I2C_1_CLKCTRL  (0x1568 - DM816X_DM_ALWON_BASE)
 #define DM816X_CM_ALWON_TIMER_1_CLKCTRL        (0x1570 - DM816X_DM_ALWON_BASE)
 #define DM816X_CM_ALWON_TIMER_2_CLKCTRL        (0x1574 - DM816X_DM_ALWON_BASE)
 #define DM816X_CM_ALWON_TIMER_3_CLKCTRL        (0x1578 - DM816X_DM_ALWON_BASE)
 #define DM816X_CM_ALWON_TIMER_5_CLKCTRL        (0x1580 - DM816X_DM_ALWON_BASE)
 #define DM816X_CM_ALWON_TIMER_6_CLKCTRL        (0x1584 - DM816X_DM_ALWON_BASE)
 #define DM816X_CM_ALWON_TIMER_7_CLKCTRL        (0x1588 - DM816X_DM_ALWON_BASE)
-#define DM816X_CM_ALWON_WDTIMER_CLKCTRL        (0x158c - DM816X_DM_ALWON_BASE)
-#define DM816X_CM_ALWON_SPI_CLKCTRL    (0x1590 - DM816X_DM_ALWON_BASE)
-#define DM816X_CM_ALWON_MAILBOX_CLKCTRL        (0x1594 - DM816X_DM_ALWON_BASE)
-#define DM816X_CM_ALWON_SPINBOX_CLKCTRL        (0x1598 - DM816X_DM_ALWON_BASE)
-#define DM816X_CM_ALWON_MMUDATA_CLKCTRL        (0x159c - DM816X_DM_ALWON_BASE)
-#define DM816X_CM_ALWON_MMUCFG_CLKCTRL (0x15a8 - DM816X_DM_ALWON_BASE)
 #define DM816X_CM_ALWON_SDIO_CLKCTRL   (0x15b0 - DM816X_DM_ALWON_BASE)
 #define DM816X_CM_ALWON_OCMC_0_CLKCTRL (0x15b4 - DM816X_DM_ALWON_BASE)
 #define DM816X_CM_ALWON_OCMC_1_CLKCTRL (0x15b8 - DM816X_DM_ALWON_BASE)
-#define DM816X_CM_ALWON_CONTRL_CLKCTRL (0x15c4 - DM816X_DM_ALWON_BASE)
-#define DM816X_CM_ALWON_GPMC_CLKCTRL   (0x15d0 - DM816X_DM_ALWON_BASE)
-#define DM816X_CM_ALWON_ETHERNET_0_CLKCTRL (0x15d4 - DM816X_DM_ALWON_BASE)
 #define DM816X_CM_ALWON_ETHERNET_1_CLKCTRL (0x15d8 - DM816X_DM_ALWON_BASE)
 #define DM816X_CM_ALWON_MPU_CLKCTRL    (0x15dc - DM816X_DM_ALWON_BASE)
-#define DM816X_CM_ALWON_L3_CLKCTRL     (0x15e4 - DM816X_DM_ALWON_BASE)
-#define DM816X_CM_ALWON_L4HS_CLKCTRL   (0x15e8 - DM816X_DM_ALWON_BASE)
-#define DM816X_CM_ALWON_L4LS_CLKCTRL   (0x15ec - DM816X_DM_ALWON_BASE)
-#define DM816X_CM_ALWON_RTC_CLKCTRL    (0x15f0 - DM816X_DM_ALWON_BASE)
-#define DM816X_CM_ALWON_TPCC_CLKCTRL   (0x15f4 - DM816X_DM_ALWON_BASE)
-#define DM816X_CM_ALWON_TPTC0_CLKCTRL  (0x15f8 - DM816X_DM_ALWON_BASE)
-#define DM816X_CM_ALWON_TPTC1_CLKCTRL  (0x15fc - DM816X_DM_ALWON_BASE)
-#define DM816X_CM_ALWON_TPTC2_CLKCTRL  (0x1600 - DM816X_DM_ALWON_BASE)
-#define DM816X_CM_ALWON_TPTC3_CLKCTRL  (0x1604 - DM816X_DM_ALWON_BASE)
 #define DM816X_CM_ALWON_SR_0_CLKCTRL   (0x1608 - DM816X_DM_ALWON_BASE)
 #define DM816X_CM_ALWON_SR_1_CLKCTRL   (0x160c - DM816X_DM_ALWON_BASE)
 
 #define DM816X_CM_DEFAULT_USB_CLKCTRL  (0x558 - DM816X_CM_DEFAULT_OFFSET)
 
 /* L3 Interconnect entries clocked at 125, 250 and 500MHz */
-static struct omap_hwmod dm816x_alwon_l3_slow_hwmod = {
+static struct omap_hwmod dm81xx_alwon_l3_slow_hwmod = {
        .name           = "alwon_l3_slow",
        .clkdm_name     = "alwon_l3s_clkdm",
        .class          = &l3_hwmod_class,
        .flags          = HWMOD_NO_IDLEST,
 };
 
-static struct omap_hwmod dm816x_default_l3_slow_hwmod = {
+static struct omap_hwmod dm81xx_default_l3_slow_hwmod = {
        .name           = "default_l3_slow",
        .clkdm_name     = "default_l3_slow_clkdm",
        .class          = &l3_hwmod_class,
        .flags          = HWMOD_NO_IDLEST,
 };
 
-static struct omap_hwmod dm816x_alwon_l3_med_hwmod = {
+static struct omap_hwmod dm81xx_alwon_l3_med_hwmod = {
        .name           = "l3_med",
        .clkdm_name     = "alwon_l3_med_clkdm",
        .class          = &l3_hwmod_class,
        .flags          = HWMOD_NO_IDLEST,
 };
 
-static struct omap_hwmod dm816x_alwon_l3_fast_hwmod = {
+static struct omap_hwmod dm81xx_alwon_l3_fast_hwmod = {
        .name           = "l3_fast",
        .clkdm_name     = "alwon_l3_fast_clkdm",
        .class          = &l3_hwmod_class,
@@ -120,7 +140,7 @@ static struct omap_hwmod dm816x_alwon_l3_fast_hwmod = {
  * L4 standard peripherals, see TRM table 1-12 for devices using this.
  * See TRM table 1-73 for devices using the 125MHz SYSCLK6 clock.
  */
-static struct omap_hwmod dm816x_l4_ls_hwmod = {
+static struct omap_hwmod dm81xx_l4_ls_hwmod = {
        .name           = "l4_ls",
        .clkdm_name     = "alwon_l3s_clkdm",
        .class          = &l4_hwmod_class,
@@ -131,27 +151,54 @@ static struct omap_hwmod dm816x_l4_ls_hwmod = {
  * table 1-13. On dm816x, only EMAC, MDIO and SATA use this. See also TRM
  * table 1-73 for devices using 250MHz SYSCLK5 clock.
  */
-static struct omap_hwmod dm816x_l4_hs_hwmod = {
+static struct omap_hwmod dm81xx_l4_hs_hwmod = {
        .name           = "l4_hs",
        .clkdm_name     = "alwon_l3_med_clkdm",
        .class          = &l4_hwmod_class,
 };
 
 /* L3 slow -> L4 ls peripheral interface running at 125MHz */
-static struct omap_hwmod_ocp_if dm816x_alwon_l3_slow__l4_ls = {
-       .master = &dm816x_alwon_l3_slow_hwmod,
-       .slave  = &dm816x_l4_ls_hwmod,
+static struct omap_hwmod_ocp_if dm81xx_alwon_l3_slow__l4_ls = {
+       .master = &dm81xx_alwon_l3_slow_hwmod,
+       .slave  = &dm81xx_l4_ls_hwmod,
        .user   = OCP_USER_MPU,
 };
 
 /* L3 med -> L4 fast peripheral interface running at 250MHz */
-static struct omap_hwmod_ocp_if dm816x_alwon_l3_slow__l4_hs = {
-       .master = &dm816x_alwon_l3_med_hwmod,
-       .slave  = &dm816x_l4_hs_hwmod,
+static struct omap_hwmod_ocp_if dm81xx_alwon_l3_slow__l4_hs = {
+       .master = &dm81xx_alwon_l3_med_hwmod,
+       .slave  = &dm81xx_l4_hs_hwmod,
        .user   = OCP_USER_MPU,
 };
 
 /* MPU */
+static struct omap_hwmod dm814x_mpu_hwmod = {
+       .name           = "mpu",
+       .clkdm_name     = "alwon_l3s_clkdm",
+       .class          = &mpu_hwmod_class,
+       .flags          = HWMOD_INIT_NO_IDLE,
+       .main_clk       = "mpu_ck",
+       .prcm           = {
+               .omap4 = {
+                       .clkctrl_offs = DM814X_CM_ALWON_MPU_CLKCTRL,
+                       .modulemode = MODULEMODE_SWCTRL,
+               },
+       },
+};
+
+static struct omap_hwmod_ocp_if dm814x_mpu__alwon_l3_slow = {
+       .master         = &dm814x_mpu_hwmod,
+       .slave          = &dm81xx_alwon_l3_slow_hwmod,
+       .user           = OCP_USER_MPU,
+};
+
+/* L3 med peripheral interface running at 200MHz */
+static struct omap_hwmod_ocp_if dm814x_mpu__alwon_l3_med = {
+       .master = &dm814x_mpu_hwmod,
+       .slave  = &dm81xx_alwon_l3_med_hwmod,
+       .user   = OCP_USER_MPU,
+};
+
 static struct omap_hwmod dm816x_mpu_hwmod = {
        .name           = "mpu",
        .clkdm_name     = "alwon_mpu_clkdm",
@@ -168,14 +215,14 @@ static struct omap_hwmod dm816x_mpu_hwmod = {
 
 static struct omap_hwmod_ocp_if dm816x_mpu__alwon_l3_slow = {
        .master         = &dm816x_mpu_hwmod,
-       .slave          = &dm816x_alwon_l3_slow_hwmod,
+       .slave          = &dm81xx_alwon_l3_slow_hwmod,
        .user           = OCP_USER_MPU,
 };
 
 /* L3 med peripheral interface running at 250MHz */
 static struct omap_hwmod_ocp_if dm816x_mpu__alwon_l3_med = {
        .master = &dm816x_mpu_hwmod,
-       .slave  = &dm816x_alwon_l3_med_hwmod,
+       .slave  = &dm81xx_alwon_l3_med_hwmod,
        .user   = OCP_USER_MPU,
 };
 
@@ -197,13 +244,13 @@ static struct omap_hwmod_class uart_class = {
        .sysc = &uart_sysc,
 };
 
-static struct omap_hwmod dm816x_uart1_hwmod = {
+static struct omap_hwmod dm81xx_uart1_hwmod = {
        .name           = "uart1",
        .clkdm_name     = "alwon_l3s_clkdm",
        .main_clk       = "sysclk10_ck",
        .prcm           = {
                .omap4 = {
-                       .clkctrl_offs = DM816X_CM_ALWON_UART_0_CLKCTRL,
+                       .clkctrl_offs = DM81XX_CM_ALWON_UART_0_CLKCTRL,
                        .modulemode = MODULEMODE_SWCTRL,
                },
        },
@@ -211,20 +258,20 @@ static struct omap_hwmod dm816x_uart1_hwmod = {
        .flags          = DEBUG_TI81XXUART1_FLAGS,
 };
 
-static struct omap_hwmod_ocp_if dm816x_l4_ls__uart1 = {
-       .master         = &dm816x_l4_ls_hwmod,
-       .slave          = &dm816x_uart1_hwmod,
+static struct omap_hwmod_ocp_if dm81xx_l4_ls__uart1 = {
+       .master         = &dm81xx_l4_ls_hwmod,
+       .slave          = &dm81xx_uart1_hwmod,
        .clk            = "sysclk6_ck",
        .user           = OCP_USER_MPU,
 };
 
-static struct omap_hwmod dm816x_uart2_hwmod = {
+static struct omap_hwmod dm81xx_uart2_hwmod = {
        .name           = "uart2",
        .clkdm_name     = "alwon_l3s_clkdm",
        .main_clk       = "sysclk10_ck",
        .prcm           = {
                .omap4 = {
-                       .clkctrl_offs = DM816X_CM_ALWON_UART_1_CLKCTRL,
+                       .clkctrl_offs = DM81XX_CM_ALWON_UART_1_CLKCTRL,
                        .modulemode = MODULEMODE_SWCTRL,
                },
        },
@@ -232,20 +279,20 @@ static struct omap_hwmod dm816x_uart2_hwmod = {
        .flags          = DEBUG_TI81XXUART2_FLAGS,
 };
 
-static struct omap_hwmod_ocp_if dm816x_l4_ls__uart2 = {
-       .master         = &dm816x_l4_ls_hwmod,
-       .slave          = &dm816x_uart2_hwmod,
+static struct omap_hwmod_ocp_if dm81xx_l4_ls__uart2 = {
+       .master         = &dm81xx_l4_ls_hwmod,
+       .slave          = &dm81xx_uart2_hwmod,
        .clk            = "sysclk6_ck",
        .user           = OCP_USER_MPU,
 };
 
-static struct omap_hwmod dm816x_uart3_hwmod = {
+static struct omap_hwmod dm81xx_uart3_hwmod = {
        .name           = "uart3",
        .clkdm_name     = "alwon_l3s_clkdm",
        .main_clk       = "sysclk10_ck",
        .prcm           = {
                .omap4 = {
-                       .clkctrl_offs = DM816X_CM_ALWON_UART_2_CLKCTRL,
+                       .clkctrl_offs = DM81XX_CM_ALWON_UART_2_CLKCTRL,
                        .modulemode = MODULEMODE_SWCTRL,
                },
        },
@@ -253,9 +300,9 @@ static struct omap_hwmod dm816x_uart3_hwmod = {
        .flags          = DEBUG_TI81XXUART3_FLAGS,
 };
 
-static struct omap_hwmod_ocp_if dm816x_l4_ls__uart3 = {
-       .master         = &dm816x_l4_ls_hwmod,
-       .slave          = &dm816x_uart3_hwmod,
+static struct omap_hwmod_ocp_if dm81xx_l4_ls__uart3 = {
+       .master         = &dm81xx_l4_ls_hwmod,
+       .slave          = &dm81xx_uart3_hwmod,
        .clk            = "sysclk6_ck",
        .user           = OCP_USER_MPU,
 };
@@ -276,23 +323,23 @@ static struct omap_hwmod_class wd_timer_class = {
        .reset          = &omap2_wd_timer_reset,
 };
 
-static struct omap_hwmod dm816x_wd_timer_hwmod = {
+static struct omap_hwmod dm81xx_wd_timer_hwmod = {
        .name           = "wd_timer",
        .clkdm_name     = "alwon_l3s_clkdm",
        .main_clk       = "sysclk18_ck",
        .flags          = HWMOD_NO_IDLEST,
        .prcm           = {
                .omap4 = {
-                       .clkctrl_offs = DM816X_CM_ALWON_WDTIMER_CLKCTRL,
+                       .clkctrl_offs = DM81XX_CM_ALWON_WDTIMER_CLKCTRL,
                        .modulemode = MODULEMODE_SWCTRL,
                },
        },
        .class          = &wd_timer_class,
 };
 
-static struct omap_hwmod_ocp_if dm816x_l4_ls__wd_timer1 = {
-       .master         = &dm816x_l4_ls_hwmod,
-       .slave          = &dm816x_wd_timer_hwmod,
+static struct omap_hwmod_ocp_if dm81xx_l4_ls__wd_timer1 = {
+       .master         = &dm81xx_l4_ls_hwmod,
+       .slave          = &dm81xx_wd_timer_hwmod,
        .clk            = "sysclk6_ck",
        .user           = OCP_USER_MPU,
 };
@@ -320,27 +367,27 @@ static struct omap_hwmod dm81xx_i2c1_hwmod = {
        .main_clk       = "sysclk10_ck",
        .prcm           = {
                .omap4 = {
-                       .clkctrl_offs = DM816X_CM_ALWON_I2C_0_CLKCTRL,
+                       .clkctrl_offs = DM81XX_CM_ALWON_I2C_0_CLKCTRL,
                        .modulemode = MODULEMODE_SWCTRL,
                },
        },
        .class          = &i2c_class,
 };
 
-static struct omap_hwmod_ocp_if dm816x_l4_ls__i2c1 = {
-       .master         = &dm816x_l4_ls_hwmod,
+static struct omap_hwmod_ocp_if dm81xx_l4_ls__i2c1 = {
+       .master         = &dm81xx_l4_ls_hwmod,
        .slave          = &dm81xx_i2c1_hwmod,
        .clk            = "sysclk6_ck",
        .user           = OCP_USER_MPU,
 };
 
-static struct omap_hwmod dm816x_i2c2_hwmod = {
+static struct omap_hwmod dm81xx_i2c2_hwmod = {
        .name           = "i2c2",
        .clkdm_name     = "alwon_l3s_clkdm",
        .main_clk       = "sysclk10_ck",
        .prcm           = {
                .omap4 = {
-                       .clkctrl_offs = DM816X_CM_ALWON_I2C_1_CLKCTRL,
+                       .clkctrl_offs = DM81XX_CM_ALWON_I2C_1_CLKCTRL,
                        .modulemode = MODULEMODE_SWCTRL,
                },
        },
@@ -358,9 +405,9 @@ static struct omap_hwmod_class_sysconfig dm81xx_elm_sysc = {
        .sysc_fields    = &omap_hwmod_sysc_type1,
 };
 
-static struct omap_hwmod_ocp_if dm816x_l4_ls__i2c2 = {
-       .master         = &dm816x_l4_ls_hwmod,
-       .slave          = &dm816x_i2c2_hwmod,
+static struct omap_hwmod_ocp_if dm81xx_l4_ls__i2c2 = {
+       .master         = &dm81xx_l4_ls_hwmod,
+       .slave          = &dm81xx_i2c2_hwmod,
        .clk            = "sysclk6_ck",
        .user           = OCP_USER_MPU,
 };
@@ -378,7 +425,7 @@ static struct omap_hwmod dm81xx_elm_hwmod = {
 };
 
 static struct omap_hwmod_ocp_if dm81xx_l4_ls__elm = {
-       .master         = &dm816x_l4_ls_hwmod,
+       .master         = &dm81xx_l4_ls_hwmod,
        .slave          = &dm81xx_elm_hwmod,
        .user           = OCP_USER_MPU,
 };
@@ -417,7 +464,7 @@ static struct omap_hwmod dm81xx_gpio1_hwmod = {
        .main_clk       = "sysclk6_ck",
        .prcm = {
                .omap4 = {
-                       .clkctrl_offs = DM816X_CM_ALWON_GPIO_0_CLKCTRL,
+                       .clkctrl_offs = DM81XX_CM_ALWON_GPIO_0_CLKCTRL,
                        .modulemode = MODULEMODE_SWCTRL,
                },
        },
@@ -427,7 +474,7 @@ static struct omap_hwmod dm81xx_gpio1_hwmod = {
 };
 
 static struct omap_hwmod_ocp_if dm81xx_l4_ls__gpio1 = {
-       .master         = &dm816x_l4_ls_hwmod,
+       .master         = &dm81xx_l4_ls_hwmod,
        .slave          = &dm81xx_gpio1_hwmod,
        .user           = OCP_USER_MPU,
 };
@@ -443,7 +490,7 @@ static struct omap_hwmod dm81xx_gpio2_hwmod = {
        .main_clk       = "sysclk6_ck",
        .prcm = {
                .omap4 = {
-                       .clkctrl_offs = DM816X_CM_ALWON_GPIO_1_CLKCTRL,
+                       .clkctrl_offs = DM81XX_CM_ALWON_GPIO_1_CLKCTRL,
                        .modulemode = MODULEMODE_SWCTRL,
                },
        },
@@ -453,7 +500,7 @@ static struct omap_hwmod dm81xx_gpio2_hwmod = {
 };
 
 static struct omap_hwmod_ocp_if dm81xx_l4_ls__gpio2 = {
-       .master         = &dm816x_l4_ls_hwmod,
+       .master         = &dm81xx_l4_ls_hwmod,
        .slave          = &dm81xx_gpio2_hwmod,
        .user           = OCP_USER_MPU,
 };
@@ -482,14 +529,14 @@ static struct omap_hwmod dm81xx_gpmc_hwmod = {
        .flags          = DEBUG_OMAP_GPMC_HWMOD_FLAGS,
        .prcm = {
                .omap4 = {
-                       .clkctrl_offs = DM816X_CM_ALWON_GPMC_CLKCTRL,
+                       .clkctrl_offs = DM81XX_CM_ALWON_GPMC_CLKCTRL,
                        .modulemode = MODULEMODE_SWCTRL,
                },
        },
 };
 
-struct omap_hwmod_ocp_if dm81xx_alwon_l3_slow__gpmc = {
-       .master         = &dm816x_alwon_l3_slow_hwmod,
+static struct omap_hwmod_ocp_if dm81xx_alwon_l3_slow__gpmc = {
+       .master         = &dm81xx_alwon_l3_slow_hwmod,
        .slave          = &dm81xx_gpmc_hwmod,
        .user           = OCP_USER_MPU,
 };
@@ -522,7 +569,7 @@ static struct omap_hwmod dm81xx_usbss_hwmod = {
 };
 
 static struct omap_hwmod_ocp_if dm81xx_default_l3_slow__usbss = {
-       .master         = &dm816x_default_l3_slow_hwmod,
+       .master         = &dm81xx_default_l3_slow_hwmod,
        .slave          = &dm81xx_usbss_hwmod,
        .clk            = "sysclk6_ck",
        .user           = OCP_USER_MPU,
@@ -547,6 +594,22 @@ static struct omap_timer_capability_dev_attr capability_alwon_dev_attr = {
        .timer_capability       = OMAP_TIMER_ALWON,
 };
 
+static struct omap_hwmod dm814x_timer1_hwmod = {
+       .name           = "timer1",
+       .clkdm_name     = "alwon_l3s_clkdm",
+       .main_clk       = "timer_sys_ck",
+       .dev_attr       = &capability_alwon_dev_attr,
+       .class          = &dm816x_timer_hwmod_class,
+       .flags          = HWMOD_NO_IDLEST,
+};
+
+static struct omap_hwmod_ocp_if dm814x_l4_ls__timer1 = {
+       .master         = &dm81xx_l4_ls_hwmod,
+       .slave          = &dm814x_timer1_hwmod,
+       .clk            = "timer_sys_ck",
+       .user           = OCP_USER_MPU,
+};
+
 static struct omap_hwmod dm816x_timer1_hwmod = {
        .name           = "timer1",
        .clkdm_name     = "alwon_l3s_clkdm",
@@ -562,12 +625,28 @@ static struct omap_hwmod dm816x_timer1_hwmod = {
 };
 
 static struct omap_hwmod_ocp_if dm816x_l4_ls__timer1 = {
-       .master         = &dm816x_l4_ls_hwmod,
+       .master         = &dm81xx_l4_ls_hwmod,
        .slave          = &dm816x_timer1_hwmod,
        .clk            = "sysclk6_ck",
        .user           = OCP_USER_MPU,
 };
 
+static struct omap_hwmod dm814x_timer2_hwmod = {
+       .name           = "timer2",
+       .clkdm_name     = "alwon_l3s_clkdm",
+       .main_clk       = "timer_sys_ck",
+       .dev_attr       = &capability_alwon_dev_attr,
+       .class          = &dm816x_timer_hwmod_class,
+       .flags          = HWMOD_NO_IDLEST,
+};
+
+static struct omap_hwmod_ocp_if dm814x_l4_ls__timer2 = {
+       .master         = &dm81xx_l4_ls_hwmod,
+       .slave          = &dm814x_timer2_hwmod,
+       .clk            = "timer_sys_ck",
+       .user           = OCP_USER_MPU,
+};
+
 static struct omap_hwmod dm816x_timer2_hwmod = {
        .name           = "timer2",
        .clkdm_name     = "alwon_l3s_clkdm",
@@ -583,7 +662,7 @@ static struct omap_hwmod dm816x_timer2_hwmod = {
 };
 
 static struct omap_hwmod_ocp_if dm816x_l4_ls__timer2 = {
-       .master         = &dm816x_l4_ls_hwmod,
+       .master         = &dm81xx_l4_ls_hwmod,
        .slave          = &dm816x_timer2_hwmod,
        .clk            = "sysclk6_ck",
        .user           = OCP_USER_MPU,
@@ -604,7 +683,7 @@ static struct omap_hwmod dm816x_timer3_hwmod = {
 };
 
 static struct omap_hwmod_ocp_if dm816x_l4_ls__timer3 = {
-       .master         = &dm816x_l4_ls_hwmod,
+       .master         = &dm81xx_l4_ls_hwmod,
        .slave          = &dm816x_timer3_hwmod,
        .clk            = "sysclk6_ck",
        .user           = OCP_USER_MPU,
@@ -625,7 +704,7 @@ static struct omap_hwmod dm816x_timer4_hwmod = {
 };
 
 static struct omap_hwmod_ocp_if dm816x_l4_ls__timer4 = {
-       .master         = &dm816x_l4_ls_hwmod,
+       .master         = &dm81xx_l4_ls_hwmod,
        .slave          = &dm816x_timer4_hwmod,
        .clk            = "sysclk6_ck",
        .user           = OCP_USER_MPU,
@@ -646,7 +725,7 @@ static struct omap_hwmod dm816x_timer5_hwmod = {
 };
 
 static struct omap_hwmod_ocp_if dm816x_l4_ls__timer5 = {
-       .master         = &dm816x_l4_ls_hwmod,
+       .master         = &dm81xx_l4_ls_hwmod,
        .slave          = &dm816x_timer5_hwmod,
        .clk            = "sysclk6_ck",
        .user           = OCP_USER_MPU,
@@ -667,7 +746,7 @@ static struct omap_hwmod dm816x_timer6_hwmod = {
 };
 
 static struct omap_hwmod_ocp_if dm816x_l4_ls__timer6 = {
-       .master         = &dm816x_l4_ls_hwmod,
+       .master         = &dm81xx_l4_ls_hwmod,
        .slave          = &dm816x_timer6_hwmod,
        .clk            = "sysclk6_ck",
        .user           = OCP_USER_MPU,
@@ -688,12 +767,68 @@ static struct omap_hwmod dm816x_timer7_hwmod = {
 };
 
 static struct omap_hwmod_ocp_if dm816x_l4_ls__timer7 = {
-       .master         = &dm816x_l4_ls_hwmod,
+       .master         = &dm81xx_l4_ls_hwmod,
        .slave          = &dm816x_timer7_hwmod,
        .clk            = "sysclk6_ck",
        .user           = OCP_USER_MPU,
 };
 
+/* CPSW on dm814x */
+static struct omap_hwmod_class_sysconfig dm814x_cpgmac_sysc = {
+       .rev_offs       = 0x0,
+       .sysc_offs      = 0x8,
+       .syss_offs      = 0x4,
+       .sysc_flags     = SYSC_HAS_SIDLEMODE | SYSC_HAS_MIDLEMODE |
+                         SYSS_HAS_RESET_STATUS,
+       .idlemodes      = SIDLE_FORCE | SIDLE_NO | MSTANDBY_FORCE |
+                         MSTANDBY_NO,
+       .sysc_fields    = &omap_hwmod_sysc_type3,
+};
+
+static struct omap_hwmod_class dm814x_cpgmac0_hwmod_class = {
+       .name           = "cpgmac0",
+       .sysc           = &dm814x_cpgmac_sysc,
+};
+
+static struct omap_hwmod dm814x_cpgmac0_hwmod = {
+       .name           = "cpgmac0",
+       .class          = &dm814x_cpgmac0_hwmod_class,
+       .clkdm_name     = "alwon_ethernet_clkdm",
+       .flags          = HWMOD_SWSUP_SIDLE | HWMOD_SWSUP_MSTANDBY,
+       .main_clk       = "cpsw_125mhz_gclk",
+       .prcm           = {
+               .omap4  = {
+                       .clkctrl_offs = DM81XX_CM_ALWON_ETHERNET_0_CLKCTRL,
+                       .modulemode = MODULEMODE_SWCTRL,
+               },
+       },
+};
+
+static struct omap_hwmod_class dm814x_mdio_hwmod_class = {
+       .name           = "davinci_mdio",
+};
+
+static struct omap_hwmod dm814x_mdio_hwmod = {
+       .name           = "davinci_mdio",
+       .class          = &dm814x_mdio_hwmod_class,
+       .clkdm_name     = "alwon_ethernet_clkdm",
+       .main_clk       = "cpsw_125mhz_gclk",
+};
+
+static struct omap_hwmod_ocp_if dm814x_l4_hs__cpgmac0 = {
+       .master         = &dm81xx_l4_hs_hwmod,
+       .slave          = &dm814x_cpgmac0_hwmod,
+       .clk            = "cpsw_125mhz_gclk",
+       .user           = OCP_USER_MPU,
+};
+
+static struct omap_hwmod_ocp_if dm814x_cpgmac0__mdio = {
+       .master         = &dm814x_cpgmac0_hwmod,
+       .slave          = &dm814x_mdio_hwmod,
+       .user           = OCP_USER_MPU,
+       .flags          = HWMOD_NO_IDLEST,
+};
+
 /* EMAC Ethernet */
 static struct omap_hwmod_class_sysconfig dm816x_emac_sysc = {
        .rev_offs       = 0x0,
@@ -717,21 +852,21 @@ static struct omap_hwmod dm816x_emac0_hwmod = {
        .class          = &dm816x_emac_hwmod_class,
 };
 
-static struct omap_hwmod_ocp_if dm816x_l4_hs__emac0 = {
-       .master         = &dm816x_l4_hs_hwmod,
+static struct omap_hwmod_ocp_if dm81xx_l4_hs__emac0 = {
+       .master         = &dm81xx_l4_hs_hwmod,
        .slave          = &dm816x_emac0_hwmod,
        .clk            = "sysclk5_ck",
        .user           = OCP_USER_MPU,
 };
 
-static struct omap_hwmod_class dm816x_mdio_hwmod_class = {
+static struct omap_hwmod_class dm81xx_mdio_hwmod_class = {
        .name           = "davinci_mdio",
        .sysc           = &dm816x_emac_sysc,
 };
 
-struct omap_hwmod dm816x_emac0_mdio_hwmod = {
+static struct omap_hwmod dm81xx_emac0_mdio_hwmod = {
        .name           = "davinci_mdio",
-       .class          = &dm816x_mdio_hwmod_class,
+       .class          = &dm81xx_mdio_hwmod_class,
        .clkdm_name     = "alwon_ethernet_clkdm",
        .main_clk       = "sysclk24_ck",
        .flags          = HWMOD_NO_IDLEST,
@@ -741,15 +876,15 @@ struct omap_hwmod dm816x_emac0_mdio_hwmod = {
         */
        .prcm           = {
                .omap4 = {
-                       .clkctrl_offs = DM816X_CM_ALWON_ETHERNET_0_CLKCTRL,
+                       .clkctrl_offs = DM81XX_CM_ALWON_ETHERNET_0_CLKCTRL,
                        .modulemode = MODULEMODE_SWCTRL,
                },
        },
 };
 
-struct omap_hwmod_ocp_if dm816x_emac0__mdio = {
-       .master         = &dm816x_l4_hs_hwmod,
-       .slave          = &dm816x_emac0_mdio_hwmod,
+static struct omap_hwmod_ocp_if dm81xx_emac0__mdio = {
+       .master         = &dm81xx_l4_hs_hwmod,
+       .slave          = &dm81xx_emac0_mdio_hwmod,
        .user           = OCP_USER_MPU,
 };
 
@@ -768,7 +903,7 @@ static struct omap_hwmod dm816x_emac1_hwmod = {
 };
 
 static struct omap_hwmod_ocp_if dm816x_l4_hs__emac1 = {
-       .master         = &dm816x_l4_hs_hwmod,
+       .master         = &dm81xx_l4_hs_hwmod,
        .slave          = &dm816x_emac1_hwmod,
        .clk            = "sysclk5_ck",
        .user           = OCP_USER_MPU,
@@ -815,7 +950,7 @@ static struct omap_hwmod dm816x_mmc1_hwmod = {
 };
 
 static struct omap_hwmod_ocp_if dm816x_l4_ls__mmc1 = {
-       .master         = &dm816x_l4_ls_hwmod,
+       .master         = &dm81xx_l4_ls_hwmod,
        .slave          = &dm816x_mmc1_hwmod,
        .clk            = "sysclk6_ck",
        .user           = OCP_USER_MPU,
@@ -843,13 +978,13 @@ static struct omap2_mcspi_dev_attr dm816x_mcspi1_dev_attr = {
        .num_chipselect = 4,
 };
 
-static struct omap_hwmod dm816x_mcspi1_hwmod = {
+static struct omap_hwmod dm81xx_mcspi1_hwmod = {
        .name           = "mcspi1",
        .clkdm_name     = "alwon_l3s_clkdm",
        .main_clk       = "sysclk10_ck",
        .prcm           = {
                .omap4 = {
-                       .clkctrl_offs = DM816X_CM_ALWON_SPI_CLKCTRL,
+                       .clkctrl_offs = DM81XX_CM_ALWON_SPI_CLKCTRL,
                        .modulemode = MODULEMODE_SWCTRL,
                },
        },
@@ -857,14 +992,14 @@ static struct omap_hwmod dm816x_mcspi1_hwmod = {
        .dev_attr       = &dm816x_mcspi1_dev_attr,
 };
 
-static struct omap_hwmod_ocp_if dm816x_l4_ls__mcspi1 = {
-       .master         = &dm816x_l4_ls_hwmod,
-       .slave          = &dm816x_mcspi1_hwmod,
+static struct omap_hwmod_ocp_if dm81xx_l4_ls__mcspi1 = {
+       .master         = &dm81xx_l4_ls_hwmod,
+       .slave          = &dm81xx_mcspi1_hwmod,
        .clk            = "sysclk6_ck",
        .user           = OCP_USER_MPU,
 };
 
-static struct omap_hwmod_class_sysconfig dm816x_mailbox_sysc = {
+static struct omap_hwmod_class_sysconfig dm81xx_mailbox_sysc = {
        .rev_offs       = 0x000,
        .sysc_offs      = 0x010,
        .syss_offs      = 0x014,
@@ -874,55 +1009,55 @@ static struct omap_hwmod_class_sysconfig dm816x_mailbox_sysc = {
        .sysc_fields    = &omap_hwmod_sysc_type1,
 };
 
-static struct omap_hwmod_class dm816x_mailbox_hwmod_class = {
+static struct omap_hwmod_class dm81xx_mailbox_hwmod_class = {
        .name = "mailbox",
-       .sysc = &dm816x_mailbox_sysc,
+       .sysc = &dm81xx_mailbox_sysc,
 };
 
-static struct omap_hwmod dm816x_mailbox_hwmod = {
+static struct omap_hwmod dm81xx_mailbox_hwmod = {
        .name           = "mailbox",
        .clkdm_name     = "alwon_l3s_clkdm",
-       .class          = &dm816x_mailbox_hwmod_class,
+       .class          = &dm81xx_mailbox_hwmod_class,
        .main_clk       = "sysclk6_ck",
        .prcm           = {
                .omap4 = {
-                       .clkctrl_offs = DM816X_CM_ALWON_MAILBOX_CLKCTRL,
+                       .clkctrl_offs = DM81XX_CM_ALWON_MAILBOX_CLKCTRL,
                        .modulemode = MODULEMODE_SWCTRL,
                },
        },
 };
 
-static struct omap_hwmod_ocp_if dm816x_l4_ls__mailbox = {
-       .master         = &dm816x_l4_ls_hwmod,
-       .slave          = &dm816x_mailbox_hwmod,
+static struct omap_hwmod_ocp_if dm81xx_l4_ls__mailbox = {
+       .master         = &dm81xx_l4_ls_hwmod,
+       .slave          = &dm81xx_mailbox_hwmod,
        .user           = OCP_USER_MPU,
 };
 
-static struct omap_hwmod_class dm816x_tpcc_hwmod_class = {
+static struct omap_hwmod_class dm81xx_tpcc_hwmod_class = {
        .name           = "tpcc",
 };
 
-struct omap_hwmod dm816x_tpcc_hwmod = {
+static struct omap_hwmod dm81xx_tpcc_hwmod = {
        .name           = "tpcc",
-       .class          = &dm816x_tpcc_hwmod_class,
+       .class          = &dm81xx_tpcc_hwmod_class,
        .clkdm_name     = "alwon_l3s_clkdm",
        .main_clk       = "sysclk4_ck",
        .prcm           = {
                .omap4  = {
-                       .clkctrl_offs   = DM816X_CM_ALWON_TPCC_CLKCTRL,
+                       .clkctrl_offs   = DM81XX_CM_ALWON_TPCC_CLKCTRL,
                        .modulemode     = MODULEMODE_SWCTRL,
                },
        },
 };
 
-struct omap_hwmod_ocp_if dm816x_alwon_l3_fast__tpcc = {
-       .master         = &dm816x_alwon_l3_fast_hwmod,
-       .slave          = &dm816x_tpcc_hwmod,
+static struct omap_hwmod_ocp_if dm81xx_alwon_l3_fast__tpcc = {
+       .master         = &dm81xx_alwon_l3_fast_hwmod,
+       .slave          = &dm81xx_tpcc_hwmod,
        .clk            = "sysclk4_ck",
        .user           = OCP_USER_MPU,
 };
 
-static struct omap_hwmod_addr_space dm816x_tptc0_addr_space[] = {
+static struct omap_hwmod_addr_space dm81xx_tptc0_addr_space[] = {
        {
                .pa_start       = 0x49800000,
                .pa_end         = 0x49800000 + SZ_8K - 1,
@@ -931,40 +1066,40 @@ static struct omap_hwmod_addr_space dm816x_tptc0_addr_space[] = {
        { },
 };
 
-static struct omap_hwmod_class dm816x_tptc0_hwmod_class = {
+static struct omap_hwmod_class dm81xx_tptc0_hwmod_class = {
        .name           = "tptc0",
 };
 
-struct omap_hwmod dm816x_tptc0_hwmod = {
+static struct omap_hwmod dm81xx_tptc0_hwmod = {
        .name           = "tptc0",
-       .class          = &dm816x_tptc0_hwmod_class,
+       .class          = &dm81xx_tptc0_hwmod_class,
        .clkdm_name     = "alwon_l3s_clkdm",
        .main_clk       = "sysclk4_ck",
        .prcm           = {
                .omap4  = {
-                       .clkctrl_offs   = DM816X_CM_ALWON_TPTC0_CLKCTRL,
+                       .clkctrl_offs   = DM81XX_CM_ALWON_TPTC0_CLKCTRL,
                        .modulemode     = MODULEMODE_SWCTRL,
                },
        },
 };
 
-struct omap_hwmod_ocp_if dm816x_alwon_l3_fast__tptc0 = {
-       .master         = &dm816x_alwon_l3_fast_hwmod,
-       .slave          = &dm816x_tptc0_hwmod,
+static struct omap_hwmod_ocp_if dm81xx_alwon_l3_fast__tptc0 = {
+       .master         = &dm81xx_alwon_l3_fast_hwmod,
+       .slave          = &dm81xx_tptc0_hwmod,
        .clk            = "sysclk4_ck",
-       .addr           = dm816x_tptc0_addr_space,
+       .addr           = dm81xx_tptc0_addr_space,
        .user           = OCP_USER_MPU,
 };
 
-struct omap_hwmod_ocp_if dm816x_tptc0__alwon_l3_fast = {
-       .master         = &dm816x_tptc0_hwmod,
-       .slave          = &dm816x_alwon_l3_fast_hwmod,
+static struct omap_hwmod_ocp_if dm81xx_tptc0__alwon_l3_fast = {
+       .master         = &dm81xx_tptc0_hwmod,
+       .slave          = &dm81xx_alwon_l3_fast_hwmod,
        .clk            = "sysclk4_ck",
-       .addr           = dm816x_tptc0_addr_space,
+       .addr           = dm81xx_tptc0_addr_space,
        .user           = OCP_USER_MPU,
 };
 
-static struct omap_hwmod_addr_space dm816x_tptc1_addr_space[] = {
+static struct omap_hwmod_addr_space dm81xx_tptc1_addr_space[] = {
        {
                .pa_start       = 0x49900000,
                .pa_end         = 0x49900000 + SZ_8K - 1,
@@ -973,40 +1108,40 @@ static struct omap_hwmod_addr_space dm816x_tptc1_addr_space[] = {
        { },
 };
 
-static struct omap_hwmod_class dm816x_tptc1_hwmod_class = {
+static struct omap_hwmod_class dm81xx_tptc1_hwmod_class = {
        .name           = "tptc1",
 };
 
-struct omap_hwmod dm816x_tptc1_hwmod = {
+static struct omap_hwmod dm81xx_tptc1_hwmod = {
        .name           = "tptc1",
-       .class          = &dm816x_tptc1_hwmod_class,
+       .class          = &dm81xx_tptc1_hwmod_class,
        .clkdm_name     = "alwon_l3s_clkdm",
        .main_clk       = "sysclk4_ck",
        .prcm           = {
                .omap4  = {
-                       .clkctrl_offs   = DM816X_CM_ALWON_TPTC1_CLKCTRL,
+                       .clkctrl_offs   = DM81XX_CM_ALWON_TPTC1_CLKCTRL,
                        .modulemode     = MODULEMODE_SWCTRL,
                },
        },
 };
 
-struct omap_hwmod_ocp_if dm816x_alwon_l3_fast__tptc1 = {
-       .master         = &dm816x_alwon_l3_fast_hwmod,
-       .slave          = &dm816x_tptc1_hwmod,
+static struct omap_hwmod_ocp_if dm81xx_alwon_l3_fast__tptc1 = {
+       .master         = &dm81xx_alwon_l3_fast_hwmod,
+       .slave          = &dm81xx_tptc1_hwmod,
        .clk            = "sysclk4_ck",
-       .addr           = dm816x_tptc1_addr_space,
+       .addr           = dm81xx_tptc1_addr_space,
        .user           = OCP_USER_MPU,
 };
 
-struct omap_hwmod_ocp_if dm816x_tptc1__alwon_l3_fast = {
-       .master         = &dm816x_tptc1_hwmod,
-       .slave          = &dm816x_alwon_l3_fast_hwmod,
+static struct omap_hwmod_ocp_if dm81xx_tptc1__alwon_l3_fast = {
+       .master         = &dm81xx_tptc1_hwmod,
+       .slave          = &dm81xx_alwon_l3_fast_hwmod,
        .clk            = "sysclk4_ck",
-       .addr           = dm816x_tptc1_addr_space,
+       .addr           = dm81xx_tptc1_addr_space,
        .user           = OCP_USER_MPU,
 };
 
-static struct omap_hwmod_addr_space dm816x_tptc2_addr_space[] = {
+static struct omap_hwmod_addr_space dm81xx_tptc2_addr_space[] = {
        {
                .pa_start       = 0x49a00000,
                .pa_end         = 0x49a00000 + SZ_8K - 1,
@@ -1015,40 +1150,40 @@ static struct omap_hwmod_addr_space dm816x_tptc2_addr_space[] = {
        { },
 };
 
-static struct omap_hwmod_class dm816x_tptc2_hwmod_class = {
+static struct omap_hwmod_class dm81xx_tptc2_hwmod_class = {
        .name           = "tptc2",
 };
 
-struct omap_hwmod dm816x_tptc2_hwmod = {
+static struct omap_hwmod dm81xx_tptc2_hwmod = {
        .name           = "tptc2",
-       .class          = &dm816x_tptc2_hwmod_class,
+       .class          = &dm81xx_tptc2_hwmod_class,
        .clkdm_name     = "alwon_l3s_clkdm",
        .main_clk       = "sysclk4_ck",
        .prcm           = {
                .omap4  = {
-                       .clkctrl_offs   = DM816X_CM_ALWON_TPTC2_CLKCTRL,
+                       .clkctrl_offs   = DM81XX_CM_ALWON_TPTC2_CLKCTRL,
                        .modulemode     = MODULEMODE_SWCTRL,
                },
        },
 };
 
-struct omap_hwmod_ocp_if dm816x_alwon_l3_fast__tptc2 = {
-       .master         = &dm816x_alwon_l3_fast_hwmod,
-       .slave          = &dm816x_tptc2_hwmod,
+static struct omap_hwmod_ocp_if dm81xx_alwon_l3_fast__tptc2 = {
+       .master         = &dm81xx_alwon_l3_fast_hwmod,
+       .slave          = &dm81xx_tptc2_hwmod,
        .clk            = "sysclk4_ck",
-       .addr           = dm816x_tptc2_addr_space,
+       .addr           = dm81xx_tptc2_addr_space,
        .user           = OCP_USER_MPU,
 };
 
-struct omap_hwmod_ocp_if dm816x_tptc2__alwon_l3_fast = {
-       .master         = &dm816x_tptc2_hwmod,
-       .slave          = &dm816x_alwon_l3_fast_hwmod,
+static struct omap_hwmod_ocp_if dm81xx_tptc2__alwon_l3_fast = {
+       .master         = &dm81xx_tptc2_hwmod,
+       .slave          = &dm81xx_alwon_l3_fast_hwmod,
        .clk            = "sysclk4_ck",
-       .addr           = dm816x_tptc2_addr_space,
+       .addr           = dm81xx_tptc2_addr_space,
        .user           = OCP_USER_MPU,
 };
 
-static struct omap_hwmod_addr_space dm816x_tptc3_addr_space[] = {
+static struct omap_hwmod_addr_space dm81xx_tptc3_addr_space[] = {
        {
                .pa_start       = 0x49b00000,
                .pa_end         = 0x49b00000 + SZ_8K - 1,
@@ -1057,50 +1192,96 @@ static struct omap_hwmod_addr_space dm816x_tptc3_addr_space[] = {
        { },
 };
 
-static struct omap_hwmod_class dm816x_tptc3_hwmod_class = {
+static struct omap_hwmod_class dm81xx_tptc3_hwmod_class = {
        .name           = "tptc3",
 };
 
-struct omap_hwmod dm816x_tptc3_hwmod = {
+static struct omap_hwmod dm81xx_tptc3_hwmod = {
        .name           = "tptc3",
-       .class          = &dm816x_tptc3_hwmod_class,
+       .class          = &dm81xx_tptc3_hwmod_class,
        .clkdm_name     = "alwon_l3s_clkdm",
        .main_clk       = "sysclk4_ck",
        .prcm           = {
                .omap4  = {
-                       .clkctrl_offs   = DM816X_CM_ALWON_TPTC3_CLKCTRL,
+                       .clkctrl_offs   = DM81XX_CM_ALWON_TPTC3_CLKCTRL,
                        .modulemode     = MODULEMODE_SWCTRL,
                },
        },
 };
 
-struct omap_hwmod_ocp_if dm816x_alwon_l3_fast__tptc3 = {
-       .master         = &dm816x_alwon_l3_fast_hwmod,
-       .slave          = &dm816x_tptc3_hwmod,
+static struct omap_hwmod_ocp_if dm81xx_alwon_l3_fast__tptc3 = {
+       .master         = &dm81xx_alwon_l3_fast_hwmod,
+       .slave          = &dm81xx_tptc3_hwmod,
        .clk            = "sysclk4_ck",
-       .addr           = dm816x_tptc3_addr_space,
+       .addr           = dm81xx_tptc3_addr_space,
        .user           = OCP_USER_MPU,
 };
 
-struct omap_hwmod_ocp_if dm816x_tptc3__alwon_l3_fast = {
-       .master         = &dm816x_tptc3_hwmod,
-       .slave          = &dm816x_alwon_l3_fast_hwmod,
+static struct omap_hwmod_ocp_if dm81xx_tptc3__alwon_l3_fast = {
+       .master         = &dm81xx_tptc3_hwmod,
+       .slave          = &dm81xx_alwon_l3_fast_hwmod,
        .clk            = "sysclk4_ck",
-       .addr           = dm816x_tptc3_addr_space,
+       .addr           = dm81xx_tptc3_addr_space,
        .user           = OCP_USER_MPU,
 };
 
+/*
+ * REVISIT: Test and enable the following once clocks work:
+ * dm81xx_l4_ls__gpio1
+ * dm81xx_l4_ls__gpio2
+ * dm81xx_l4_ls__mailbox
+ * dm81xx_alwon_l3_slow__gpmc
+ * dm81xx_default_l3_slow__usbss
+ *
+ * Also note that some devices share a single clkctrl_offs..
+ * For example, i2c1 and 3 share one, and i2c2 and 4 share one.
+ */
+static struct omap_hwmod_ocp_if *dm814x_hwmod_ocp_ifs[] __initdata = {
+       &dm814x_mpu__alwon_l3_slow,
+       &dm814x_mpu__alwon_l3_med,
+       &dm81xx_alwon_l3_slow__l4_ls,
+       &dm81xx_alwon_l3_slow__l4_hs,
+       &dm81xx_l4_ls__uart1,
+       &dm81xx_l4_ls__uart2,
+       &dm81xx_l4_ls__uart3,
+       &dm81xx_l4_ls__wd_timer1,
+       &dm81xx_l4_ls__i2c1,
+       &dm81xx_l4_ls__i2c2,
+       &dm81xx_l4_ls__elm,
+       &dm81xx_l4_ls__mcspi1,
+       &dm81xx_alwon_l3_fast__tpcc,
+       &dm81xx_alwon_l3_fast__tptc0,
+       &dm81xx_alwon_l3_fast__tptc1,
+       &dm81xx_alwon_l3_fast__tptc2,
+       &dm81xx_alwon_l3_fast__tptc3,
+       &dm81xx_tptc0__alwon_l3_fast,
+       &dm81xx_tptc1__alwon_l3_fast,
+       &dm81xx_tptc2__alwon_l3_fast,
+       &dm81xx_tptc3__alwon_l3_fast,
+       &dm814x_l4_ls__timer1,
+       &dm814x_l4_ls__timer2,
+       &dm814x_l4_hs__cpgmac0,
+       &dm814x_cpgmac0__mdio,
+       NULL,
+};
+
+int __init dm814x_hwmod_init(void)
+{
+       omap_hwmod_init();
+       return omap_hwmod_register_links(dm814x_hwmod_ocp_ifs);
+}
+
 static struct omap_hwmod_ocp_if *dm816x_hwmod_ocp_ifs[] __initdata = {
        &dm816x_mpu__alwon_l3_slow,
        &dm816x_mpu__alwon_l3_med,
-       &dm816x_alwon_l3_slow__l4_ls,
-       &dm816x_alwon_l3_slow__l4_hs,
-       &dm816x_l4_ls__uart1,
-       &dm816x_l4_ls__uart2,
-       &dm816x_l4_ls__uart3,
-       &dm816x_l4_ls__wd_timer1,
-       &dm816x_l4_ls__i2c1,
-       &dm816x_l4_ls__i2c2,
+       &dm81xx_alwon_l3_slow__l4_ls,
+       &dm81xx_alwon_l3_slow__l4_hs,
+       &dm81xx_l4_ls__uart1,
+       &dm81xx_l4_ls__uart2,
+       &dm81xx_l4_ls__uart3,
+       &dm81xx_l4_ls__wd_timer1,
+       &dm81xx_l4_ls__i2c1,
+       &dm81xx_l4_ls__i2c2,
        &dm81xx_l4_ls__gpio1,
        &dm81xx_l4_ls__gpio2,
        &dm81xx_l4_ls__elm,
@@ -1112,26 +1293,26 @@ static struct omap_hwmod_ocp_if *dm816x_hwmod_ocp_ifs[] __initdata = {
        &dm816x_l4_ls__timer5,
        &dm816x_l4_ls__timer6,
        &dm816x_l4_ls__timer7,
-       &dm816x_l4_ls__mcspi1,
-       &dm816x_l4_ls__mailbox,
-       &dm816x_l4_hs__emac0,
-       &dm816x_emac0__mdio,
+       &dm81xx_l4_ls__mcspi1,
+       &dm81xx_l4_ls__mailbox,
+       &dm81xx_l4_hs__emac0,
+       &dm81xx_emac0__mdio,
        &dm816x_l4_hs__emac1,
-       &dm816x_alwon_l3_fast__tpcc,
-       &dm816x_alwon_l3_fast__tptc0,
-       &dm816x_alwon_l3_fast__tptc1,
-       &dm816x_alwon_l3_fast__tptc2,
-       &dm816x_alwon_l3_fast__tptc3,
-       &dm816x_tptc0__alwon_l3_fast,
-       &dm816x_tptc1__alwon_l3_fast,
-       &dm816x_tptc2__alwon_l3_fast,
-       &dm816x_tptc3__alwon_l3_fast,
+       &dm81xx_alwon_l3_fast__tpcc,
+       &dm81xx_alwon_l3_fast__tptc0,
+       &dm81xx_alwon_l3_fast__tptc1,
+       &dm81xx_alwon_l3_fast__tptc2,
+       &dm81xx_alwon_l3_fast__tptc3,
+       &dm81xx_tptc0__alwon_l3_fast,
+       &dm81xx_tptc1__alwon_l3_fast,
+       &dm81xx_tptc2__alwon_l3_fast,
+       &dm81xx_tptc3__alwon_l3_fast,
        &dm81xx_alwon_l3_slow__gpmc,
        &dm81xx_default_l3_slow__usbss,
        NULL,
 };
 
-int __init ti81xx_hwmod_init(void)
+int __init dm816x_hwmod_init(void)
 {
        omap_hwmod_init();
        return omap_hwmod_register_links(dm816x_hwmod_ocp_ifs);
index 821171c..1a352f5 100644 (file)
@@ -31,7 +31,7 @@ struct pdata_init {
        void (*fn)(void);
 };
 
-struct of_dev_auxdata omap_auxdata_lookup[];
+static struct of_dev_auxdata omap_auxdata_lookup[];
 static struct twl4030_gpio_platform_data twl_gpio_auxdata;
 
 #ifdef CONFIG_MACH_NOKIA_N8X0
@@ -128,7 +128,7 @@ static void __init omap3_sbc_t3530_legacy_init(void)
        omap3_sbc_t3x_usb_hub_init(167, "sb-t35 usb hub");
 }
 
-struct ti_st_plat_data wilink_pdata = {
+static struct ti_st_plat_data wilink_pdata = {
        .nshutdown_gpio = 137,
        .dev_name = "/dev/ttyO1",
        .flow_cntrl = 1,
@@ -323,7 +323,7 @@ static struct pdata_init auxdata_quirks[] __initdata = {
        { /* sentinel */ },
 };
 
-struct of_dev_auxdata omap_auxdata_lookup[] __initdata = {
+static struct of_dev_auxdata omap_auxdata_lookup[] __initdata = {
 #ifdef CONFIG_MACH_NOKIA_N8X0
        OF_DEV_AUXDATA("ti,omap2420-mmc", 0x4809c000, "mmci-omap.0", NULL),
        OF_DEV_AUXDATA("menelaus", 0x72, "1-0072", &n8x0_menelaus_platform_data),
index 70bc706..d31c495 100644 (file)
@@ -349,6 +349,41 @@ static struct powerdomain device_81xx_pwrdm = {
        .voltdm           = { .name = "core" },
 };
 
+static struct powerdomain gem_814x_pwrdm = {
+       .name           = "gem_pwrdm",
+       .prcm_offs      = TI814X_PRM_DSP_MOD,
+       .pwrsts         = PWRSTS_OFF_ON,
+       .voltdm         = { .name = "dsp" },
+};
+
+static struct powerdomain ivahd_814x_pwrdm = {
+       .name           = "ivahd_pwrdm",
+       .prcm_offs      = TI814X_PRM_HDVICP_MOD,
+       .pwrsts         = PWRSTS_OFF_ON,
+       .voltdm         = { .name = "iva" },
+};
+
+static struct powerdomain hdvpss_814x_pwrdm = {
+       .name           = "hdvpss_pwrdm",
+       .prcm_offs      = TI814X_PRM_HDVPSS_MOD,
+       .pwrsts         = PWRSTS_OFF_ON,
+       .voltdm         = { .name = "dsp" },
+};
+
+static struct powerdomain sgx_814x_pwrdm = {
+       .name           = "sgx_pwrdm",
+       .prcm_offs      = TI814X_PRM_GFX_MOD,
+       .pwrsts         = PWRSTS_OFF_ON,
+       .voltdm         = { .name = "core" },
+};
+
+static struct powerdomain isp_814x_pwrdm = {
+       .name           = "isp_pwrdm",
+       .prcm_offs      = TI814X_PRM_ISP_MOD,
+       .pwrsts         = PWRSTS_OFF_ON,
+       .voltdm         = { .name = "core" },
+};
+
 static struct powerdomain active_816x_pwrdm = {
        .name             = "active_pwrdm",
        .prcm_offs        = TI816X_PRM_ACTIVE_MOD,
@@ -448,7 +483,18 @@ static struct powerdomain *powerdomains_am35x[] __initdata = {
        NULL
 };
 
-static struct powerdomain *powerdomains_ti81xx[] __initdata = {
+static struct powerdomain *powerdomains_ti814x[] __initdata = {
+       &alwon_81xx_pwrdm,
+       &device_81xx_pwrdm,
+       &gem_814x_pwrdm,
+       &ivahd_814x_pwrdm,
+       &hdvpss_814x_pwrdm,
+       &sgx_814x_pwrdm,
+       &isp_814x_pwrdm,
+       NULL
+};
+
+static struct powerdomain *powerdomains_ti816x[] __initdata = {
        &alwon_81xx_pwrdm,
        &device_81xx_pwrdm,
        &active_816x_pwrdm,
@@ -460,6 +506,73 @@ static struct powerdomain *powerdomains_ti81xx[] __initdata = {
        NULL
 };
 
+/* TI81XX specific ops */
+#define TI81XX_PM_PWSTCTRL                             0x0000
+#define TI81XX_RM_RSTCTRL                              0x0010
+#define TI81XX_PM_PWSTST                               0x0004
+
+static int ti81xx_pwrdm_set_next_pwrst(struct powerdomain *pwrdm, u8 pwrst)
+{
+       omap2_prm_rmw_mod_reg_bits(OMAP_POWERSTATE_MASK,
+                                  (pwrst << OMAP_POWERSTATE_SHIFT),
+                                  pwrdm->prcm_offs, TI81XX_PM_PWSTCTRL);
+       return 0;
+}
+
+static int ti81xx_pwrdm_read_next_pwrst(struct powerdomain *pwrdm)
+{
+       return omap2_prm_read_mod_bits_shift(pwrdm->prcm_offs,
+                                            TI81XX_PM_PWSTCTRL,
+                                            OMAP_POWERSTATE_MASK);
+}
+
+static int ti81xx_pwrdm_read_pwrst(struct powerdomain *pwrdm)
+{
+       return omap2_prm_read_mod_bits_shift(pwrdm->prcm_offs,
+               (pwrdm->prcm_offs == TI814X_PRM_GFX_MOD) ? TI81XX_RM_RSTCTRL :
+                                            TI81XX_PM_PWSTST,
+                                            OMAP_POWERSTATEST_MASK);
+}
+
+static int ti81xx_pwrdm_read_logic_pwrst(struct powerdomain *pwrdm)
+{
+       return omap2_prm_read_mod_bits_shift(pwrdm->prcm_offs,
+               (pwrdm->prcm_offs == TI814X_PRM_GFX_MOD) ? TI81XX_RM_RSTCTRL :
+                                            TI81XX_PM_PWSTST,
+                                            OMAP3430_LOGICSTATEST_MASK);
+}
+
+static int ti81xx_pwrdm_wait_transition(struct powerdomain *pwrdm)
+{
+       u32 c = 0;
+
+       while ((omap2_prm_read_mod_reg(pwrdm->prcm_offs,
+               (pwrdm->prcm_offs == TI814X_PRM_GFX_MOD) ? TI81XX_RM_RSTCTRL :
+                                      TI81XX_PM_PWSTST) &
+               OMAP_INTRANSITION_MASK) &&
+               (c++ < PWRDM_TRANSITION_BAILOUT))
+                       udelay(1);
+
+       if (c > PWRDM_TRANSITION_BAILOUT) {
+               pr_err("powerdomain: %s timeout waiting for transition\n",
+                      pwrdm->name);
+               return -EAGAIN;
+       }
+
+       pr_debug("powerdomain: completed transition in %d loops\n", c);
+
+       return 0;
+}
+
+/* For dm814x we need to fix up fix GFX pwstst and rstctrl reg offsets */
+static struct pwrdm_ops ti81xx_pwrdm_operations = {
+       .pwrdm_set_next_pwrst   = ti81xx_pwrdm_set_next_pwrst,
+       .pwrdm_read_next_pwrst  = ti81xx_pwrdm_read_next_pwrst,
+       .pwrdm_read_pwrst       = ti81xx_pwrdm_read_pwrst,
+       .pwrdm_read_logic_pwrst = ti81xx_pwrdm_read_logic_pwrst,
+       .pwrdm_wait_transition  = ti81xx_pwrdm_wait_transition,
+};
+
 void __init omap3xxx_powerdomains_init(void)
 {
        unsigned int rev;
@@ -467,15 +580,22 @@ void __init omap3xxx_powerdomains_init(void)
        if (!cpu_is_omap34xx() && !cpu_is_ti81xx())
                return;
 
-       pwrdm_register_platform_funcs(&omap3_pwrdm_operations);
+       /* Only 81xx needs custom pwrdm_operations */
+       if (!cpu_is_ti81xx())
+               pwrdm_register_platform_funcs(&omap3_pwrdm_operations);;
 
        rev = omap_rev();
 
        if (rev == AM35XX_REV_ES1_0 || rev == AM35XX_REV_ES1_1) {
                pwrdm_register_pwrdms(powerdomains_am35x);
+       } else if (rev == TI8148_REV_ES1_0 || rev == TI8148_REV_ES2_0 ||
+                  rev == TI8148_REV_ES2_1) {
+               pwrdm_register_platform_funcs(&ti81xx_pwrdm_operations);
+               pwrdm_register_pwrdms(powerdomains_ti814x);
        } else if (rev == TI8168_REV_ES1_0 || rev == TI8168_REV_ES1_1
                        || rev == TI8168_REV_ES2_0 || rev == TI8168_REV_ES2_1) {
-               pwrdm_register_pwrdms(powerdomains_ti81xx);
+               pwrdm_register_platform_funcs(&ti81xx_pwrdm_operations);
+               pwrdm_register_pwrdms(powerdomains_ti816x);
        } else {
                pwrdm_register_pwrdms(powerdomains_omap3430_common);
 
index 6ae0b3a..c8f590b 100644 (file)
 /*
  * TI81XX PRM module offsets
  */
+#define TI814X_PRM_DSP_MOD                             0x0a00
+#define TI814X_PRM_HDVICP_MOD                          0x0c00
+#define TI814X_PRM_ISP_MOD                             0x0d00
+#define TI814X_PRM_HDVPSS_MOD                          0x0e00
+#define TI814X_PRM_GFX_MOD                             0x0f00
+
 #define TI81XX_PRM_DEVICE_MOD                  0x0000
 #define TI816X_PRM_ACTIVE_MOD                  0x0a00
 #define TI81XX_PRM_DEFAULT_MOD                 0x0b00
@@ -472,6 +478,7 @@ struct omap_prcm_irq {
  * struct omap_prcm_irq_setup - PRCM interrupt controller details
  * @ack: PRM register offset for the first PRM_IRQSTATUS_MPU register
  * @mask: PRM register offset for the first PRM_IRQENABLE_MPU register
+ * @pm_ctrl: PRM register offset for the PRM_IO_PMCTRL register
  * @nr_regs: number of PRM_IRQ{STATUS,ENABLE}_MPU* registers
  * @nr_irqs: number of entries in the @irqs array
  * @irqs: ptr to an array of PRCM interrupt bits (see @nr_irqs)
@@ -494,6 +501,7 @@ struct omap_prcm_irq {
 struct omap_prcm_irq_setup {
        u16 ack;
        u16 mask;
+       u16 pm_ctrl;
        u8 nr_regs;
        u8 nr_irqs;
        const struct omap_prcm_irq *irqs;
index 7eebc27..7c34c44 100644 (file)
 #define AM43XX_PRM_WKUP_INST                           0x2000
 #define AM43XX_PRM_DEVICE_INST                         0x4000
 
+/* PRM_IRQ offsets */
+#define AM43XX_PRM_IRQSTATUS_MPU_OFFSET                        0x0004
+#define AM43XX_PRM_IRQENABLE_MPU_OFFSET                        0x0008
+
+/* Other PRM offsets */
+#define AM43XX_PRM_IO_PMCTRL_OFFSET                    0x0024
+
 /* RM RSTCTRL offsets */
 #define AM43XX_RM_PER_RSTCTRL_OFFSET                   0x0010
 #define AM43XX_RM_GFX_RSTCTRL_OFFSET                   0x0010
index 4541700..3076800 100644 (file)
 #include <linux/err.h>
 #include <linux/io.h>
 #include <linux/of_irq.h>
-
+#include <linux/of.h>
 
 #include "soc.h"
 #include "iomap.h"
 #include "common.h"
 #include "vp.h"
 #include "prm44xx.h"
+#include "prcm43xx.h"
 #include "prm-regbits-44xx.h"
 #include "prcm44xx.h"
 #include "prminst44xx.h"
@@ -45,6 +46,7 @@ static const struct omap_prcm_irq omap4_prcm_irqs[] = {
 static struct omap_prcm_irq_setup omap4_prcm_irq_setup = {
        .ack                    = OMAP4_PRM_IRQSTATUS_MPU_OFFSET,
        .mask                   = OMAP4_PRM_IRQENABLE_MPU_OFFSET,
+       .pm_ctrl                = OMAP4_PRM_IO_PMCTRL_OFFSET,
        .nr_regs                = 2,
        .irqs                   = omap4_prcm_irqs,
        .nr_irqs                = ARRAY_SIZE(omap4_prcm_irqs),
@@ -216,11 +218,11 @@ static inline u32 _read_pending_irq_reg(u16 irqen_offs, u16 irqst_offs)
  */
 static void omap44xx_prm_read_pending_irqs(unsigned long *events)
 {
-       events[0] = _read_pending_irq_reg(OMAP4_PRM_IRQENABLE_MPU_OFFSET,
-                                         OMAP4_PRM_IRQSTATUS_MPU_OFFSET);
+       int i;
 
-       events[1] = _read_pending_irq_reg(OMAP4_PRM_IRQENABLE_MPU_2_OFFSET,
-                                         OMAP4_PRM_IRQSTATUS_MPU_2_OFFSET);
+       for (i = 0; i < omap4_prcm_irq_setup.nr_regs; i++)
+               events[i] = _read_pending_irq_reg(omap4_prcm_irq_setup.mask +
+                               i * 4, omap4_prcm_irq_setup.ack + i * 4);
 }
 
 /**
@@ -250,17 +252,17 @@ static void omap44xx_prm_ocp_barrier(void)
  */
 static void omap44xx_prm_save_and_clear_irqen(u32 *saved_mask)
 {
-       saved_mask[0] =
-               omap4_prm_read_inst_reg(OMAP4430_PRM_OCP_SOCKET_INST,
-                                       OMAP4_PRM_IRQENABLE_MPU_OFFSET);
-       saved_mask[1] =
-               omap4_prm_read_inst_reg(OMAP4430_PRM_OCP_SOCKET_INST,
-                                       OMAP4_PRM_IRQENABLE_MPU_2_OFFSET);
+       int i;
+       u16 reg;
+
+       for (i = 0; i < omap4_prcm_irq_setup.nr_regs; i++) {
+               reg = omap4_prcm_irq_setup.mask + i * 4;
 
-       omap4_prm_write_inst_reg(0, OMAP4430_PRM_OCP_SOCKET_INST,
-                                OMAP4_PRM_IRQENABLE_MPU_OFFSET);
-       omap4_prm_write_inst_reg(0, OMAP4430_PRM_OCP_SOCKET_INST,
-                                OMAP4_PRM_IRQENABLE_MPU_2_OFFSET);
+               saved_mask[i] =
+                       omap4_prm_read_inst_reg(OMAP4430_PRM_OCP_SOCKET_INST,
+                                               reg);
+               omap4_prm_write_inst_reg(0, OMAP4430_PRM_OCP_SOCKET_INST, reg);
+       }
 
        /* OCP barrier */
        omap4_prm_read_inst_reg(OMAP4430_PRM_OCP_SOCKET_INST,
@@ -279,10 +281,12 @@ static void omap44xx_prm_save_and_clear_irqen(u32 *saved_mask)
  */
 static void omap44xx_prm_restore_irqen(u32 *saved_mask)
 {
-       omap4_prm_write_inst_reg(saved_mask[0], OMAP4430_PRM_OCP_SOCKET_INST,
-                                OMAP4_PRM_IRQENABLE_MPU_OFFSET);
-       omap4_prm_write_inst_reg(saved_mask[1], OMAP4430_PRM_OCP_SOCKET_INST,
-                                OMAP4_PRM_IRQENABLE_MPU_2_OFFSET);
+       int i;
+
+       for (i = 0; i < omap4_prcm_irq_setup.nr_regs; i++)
+               omap4_prm_write_inst_reg(saved_mask[i],
+                                        OMAP4430_PRM_OCP_SOCKET_INST,
+                                        omap4_prcm_irq_setup.mask + i * 4);
 }
 
 /**
@@ -306,10 +310,10 @@ static void omap44xx_prm_reconfigure_io_chain(void)
        omap4_prm_rmw_inst_reg_bits(OMAP4430_WUCLK_CTRL_MASK,
                                    OMAP4430_WUCLK_CTRL_MASK,
                                    inst,
-                                   OMAP4_PRM_IO_PMCTRL_OFFSET);
+                                   omap4_prcm_irq_setup.pm_ctrl);
        omap_test_timeout(
                (((omap4_prm_read_inst_reg(inst,
-                                          OMAP4_PRM_IO_PMCTRL_OFFSET) &
+                                          omap4_prcm_irq_setup.pm_ctrl) &
                   OMAP4430_WUCLK_STATUS_MASK) >>
                  OMAP4430_WUCLK_STATUS_SHIFT) == 1),
                MAX_IOPAD_LATCH_TIME, i);
@@ -319,10 +323,10 @@ static void omap44xx_prm_reconfigure_io_chain(void)
        /* Trigger WUCLKIN disable */
        omap4_prm_rmw_inst_reg_bits(OMAP4430_WUCLK_CTRL_MASK, 0x0,
                                    inst,
-                                   OMAP4_PRM_IO_PMCTRL_OFFSET);
+                                   omap4_prcm_irq_setup.pm_ctrl);
        omap_test_timeout(
                (((omap4_prm_read_inst_reg(inst,
-                                          OMAP4_PRM_IO_PMCTRL_OFFSET) &
+                                          omap4_prcm_irq_setup.pm_ctrl) &
                   OMAP4430_WUCLK_STATUS_MASK) >>
                  OMAP4430_WUCLK_STATUS_SHIFT) == 0),
                MAX_IOPAD_LATCH_TIME, i);
@@ -350,7 +354,7 @@ static void __init omap44xx_prm_enable_io_wakeup(void)
        omap4_prm_rmw_inst_reg_bits(OMAP4430_GLOBAL_WUEN_MASK,
                                    OMAP4430_GLOBAL_WUEN_MASK,
                                    inst,
-                                   OMAP4_PRM_IO_PMCTRL_OFFSET);
+                                   omap4_prcm_irq_setup.pm_ctrl);
 }
 
 /**
@@ -719,6 +723,15 @@ int __init omap44xx_prm_init(const struct omap_prcm_init_data *data)
 
        omap4_prminst_set_prm_dev_inst(data->device_inst_offset);
 
+       /* Add AM437X specific differences */
+       if (of_device_is_compatible(data->np, "ti,am4-prcm")) {
+               omap4_prcm_irq_setup.nr_irqs = 1;
+               omap4_prcm_irq_setup.nr_regs = 1;
+               omap4_prcm_irq_setup.pm_ctrl = AM43XX_PRM_IO_PMCTRL_OFFSET;
+               omap4_prcm_irq_setup.ack = AM43XX_PRM_IRQSTATUS_MPU_OFFSET;
+               omap4_prcm_irq_setup.mask = AM43XX_PRM_IRQENABLE_MPU_OFFSET;
+       }
+
        return prm_register(&omap44xx_prm_ll_data);
 }
 
index f62f832..257e98c 100644 (file)
@@ -696,6 +696,7 @@ static struct omap_prcm_init_data am4_prm_data __initdata = {
        .index = TI_CLKM_PRM,
        .init = omap44xx_prm_init,
        .device_inst_offset = AM43XX_PRM_DEVICE_INST,
+       .flags = PRM_HAS_IO_WAKEUP,
 };
 #endif
 
index 16b37e7..e4d8701 100644 (file)
@@ -208,8 +208,7 @@ static void __init omap_dmtimer_init(void)
        /* If we are a secure device, remove any secure timer nodes */
        if ((omap_type() != OMAP2_DEVICE_TYPE_GP)) {
                np = omap_get_timer_dt(omap_timer_match, "ti,timer-secure");
-               if (np)
-                       of_node_put(np);
+               of_node_put(np);
        }
 }
 
@@ -649,23 +648,10 @@ static OMAP_SYS_32K_TIMER_INIT(4, 1, "timer_32k_ck", "ti,timer-alwon",
 
 #ifdef CONFIG_ARCH_OMAP4
 #ifdef CONFIG_HAVE_ARM_TWD
-static DEFINE_TWD_LOCAL_TIMER(twd_local_timer, OMAP44XX_LOCAL_TWD_BASE, 29);
 void __init omap4_local_timer_init(void)
 {
        omap4_sync32k_timer_init();
-       /* Local timers are not supprted on OMAP4430 ES1.0 */
-       if (omap_rev() != OMAP4430_REV_ES1_0) {
-               int err;
-
-               if (of_have_populated_dt()) {
-                       clocksource_of_init();
-                       return;
-               }
-
-               err = twd_local_timer_register(&twd_local_timer);
-               if (err)
-                       pr_err("twd_local_timer_register failed %d\n", err);
-       }
+       clocksource_of_init();
 }
 #else
 void __init omap4_local_timer_init(void)
index 3543466..e6ce669 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/platform_data/camera-pxa.h>
 #include <mach/audio.h>
 #include <mach/hardware.h>
+#include <linux/platform_data/mmp_dma.h>
 #include <linux/platform_data/mtd-nand-pxa3xx.h>
 
 #include "devices.h"
@@ -1193,3 +1194,39 @@ void __init pxa2xx_set_spi_info(unsigned id, struct pxa2xx_spi_master *info)
        pd->dev.platform_data = info;
        platform_device_add(pd);
 }
+
+static struct mmp_dma_platdata pxa_dma_pdata = {
+       .dma_channels   = 0,
+};
+
+static struct resource pxa_dma_resource[] = {
+       [0] = {
+               .start  = 0x40000000,
+               .end    = 0x4000ffff,
+               .flags  = IORESOURCE_MEM,
+       },
+       [1] = {
+               .start  = IRQ_DMA,
+               .end    = IRQ_DMA,
+               .flags  = IORESOURCE_IRQ,
+       },
+};
+
+static u64 pxadma_dmamask = 0xffffffffUL;
+
+static struct platform_device pxa2xx_pxa_dma = {
+       .name           = "pxa-dma",
+       .id             = 0,
+       .dev            = {
+               .dma_mask = &pxadma_dmamask,
+               .coherent_dma_mask = 0xffffffff,
+       },
+       .num_resources  = ARRAY_SIZE(pxa_dma_resource),
+       .resource       = pxa_dma_resource,
+};
+
+void __init pxa2xx_set_dmac_info(int nb_channels)
+{
+       pxa_dma_pdata.dma_channels = nb_channels;
+       pxa_register_device(&pxa2xx_pxa_dma, &pxa_dma_pdata);
+}
index 23a90c6..1dc85ff 100644 (file)
@@ -206,6 +206,7 @@ static int __init pxa25x_init(void)
                register_syscore_ops(&pxa_irq_syscore_ops);
                register_syscore_ops(&pxa2xx_mfp_syscore_ops);
 
+               pxa2xx_set_dmac_info(16);
                pxa_register_device(&pxa25x_device_gpio, &pxa25x_gpio_info);
                ret = platform_add_devices(pxa25x_devices,
                                           ARRAY_SIZE(pxa25x_devices));
index b5abdeb..e6aae9e 100644 (file)
@@ -310,6 +310,7 @@ static int __init pxa27x_init(void)
                if (!of_have_populated_dt()) {
                        pxa_register_device(&pxa27x_device_gpio,
                                            &pxa27x_gpio_info);
+                       pxa2xx_set_dmac_info(32);
                        ret = platform_add_devices(devices,
                                                   ARRAY_SIZE(devices));
                }
index e1362c0..1656384 100644 (file)
@@ -431,6 +431,7 @@ static int __init pxa3xx_init(void)
                if (of_have_populated_dt())
                        return 0;
 
+               pxa2xx_set_dmac_info(32);
                ret = platform_add_devices(devices, ARRAY_SIZE(devices));
                if (ret)
                        return ret;
index 051a655..bdc0c41 100644 (file)
@@ -841,11 +841,9 @@ static int sharpsl_pm_probe(struct platform_device *pdev)
        sharpsl_pm.charge_mode = CHRG_OFF;
        sharpsl_pm.flags = 0;
 
-       init_timer(&sharpsl_pm.ac_timer);
-       sharpsl_pm.ac_timer.function = sharpsl_ac_timer;
+       setup_timer(&sharpsl_pm.ac_timer, sharpsl_ac_timer, 0UL);
 
-       init_timer(&sharpsl_pm.chrg_full_timer);
-       sharpsl_pm.chrg_full_timer.function = sharpsl_chrg_full_timer;
+       setup_timer(&sharpsl_pm.chrg_full_timer, sharpsl_chrg_full_timer, 0UL);
 
        led_trigger_register_simple("sharpsl-charge", &sharpsl_charge_led_trigger);
 
index 685deff..e0a5320 100644 (file)
@@ -131,17 +131,4 @@ static struct platform_driver tosa_bt_driver = {
                .name = "tosa-bt",
        },
 };
-
-
-static int __init tosa_bt_init(void)
-{
-       return platform_driver_register(&tosa_bt_driver);
-}
-
-static void __exit tosa_bt_exit(void)
-{
-       platform_driver_unregister(&tosa_bt_driver);
-}
-
-module_init(tosa_bt_init);
-module_exit(tosa_bt_exit);
+module_platform_driver(tosa_bt_driver);
index 8fcec1c..3e7a4b7 100644 (file)
@@ -72,29 +72,22 @@ static struct reset_control *rockchip_get_core_reset(int cpu)
 static int pmu_set_power_domain(int pd, bool on)
 {
        u32 val = (on) ? 0 : BIT(pd);
+       struct reset_control *rstc = rockchip_get_core_reset(pd);
        int ret;
 
+       if (IS_ERR(rstc) && read_cpuid_part() != ARM_CPU_PART_CORTEX_A9) {
+               pr_err("%s: could not get reset control for core %d\n",
+                      __func__, pd);
+               return PTR_ERR(rstc);
+       }
+
        /*
         * We need to soft reset the cpu when we turn off the cpu power domain,
         * or else the active processors might be stalled when the individual
         * processor is powered down.
         */
-       if (read_cpuid_part() != ARM_CPU_PART_CORTEX_A9) {
-               struct reset_control *rstc = rockchip_get_core_reset(pd);
-
-               if (IS_ERR(rstc)) {
-                       pr_err("%s: could not get reset control for core %d\n",
-                              __func__, pd);
-                       return PTR_ERR(rstc);
-               }
-
-               if (on)
-                       reset_control_deassert(rstc);
-               else
-                       reset_control_assert(rstc);
-
-               reset_control_put(rstc);
-       }
+       if (!IS_ERR(rstc) && !on)
+               reset_control_assert(rstc);
 
        ret = regmap_update_bits(pmu, PMU_PWRDN_CON, BIT(pd), val);
        if (ret < 0) {
@@ -107,11 +100,17 @@ static int pmu_set_power_domain(int pd, bool on)
                ret = pmu_power_domain_is_on(pd);
                if (ret < 0) {
                        pr_err("%s: could not read power domain state\n",
-                                __func__);
+                              __func__);
                        return ret;
                }
        }
 
+       if (!IS_ERR(rstc)) {
+               if (on)
+                       reset_control_deassert(rstc);
+               reset_control_put(rstc);
+       }
+
        return 0;
 }
 
@@ -130,7 +129,7 @@ static int rockchip_boot_secondary(unsigned int cpu, struct task_struct *idle)
 
        if (cpu >= ncores) {
                pr_err("%s: cpu %d outside maximum number of cpus %d\n",
-                                                       __func__, cpu, ncores);
+                      __func__, cpu, ncores);
                return -ENXIO;
        }
 
@@ -140,14 +139,19 @@ static int rockchip_boot_secondary(unsigned int cpu, struct task_struct *idle)
                return ret;
 
        if (read_cpuid_part() != ARM_CPU_PART_CORTEX_A9) {
-               /* We communicate with the bootrom to active the cpus other
+               /*
+                * We communicate with the bootrom to active the cpus other
                 * than cpu0, after a blob of initialize code, they will
                 * stay at wfe state, once they are actived, they will check
                 * the mailbox:
                 * sram_base_addr + 4: 0xdeadbeaf
                 * sram_base_addr + 8: start address for pc
-                * */
-               udelay(10);
+                * The cpu0 need to wait the other cpus other than cpu0 entering
+                * the wfe state.The wait time is affected by many aspects.
+                * (e.g: cpu frequency, bootrom frequency, sram frequency, ...)
+                */
+               mdelay(1); /* ensure the cpus other than cpu0 to startup */
+
                writel(virt_to_phys(secondary_startup), sram_base_addr + 8);
                writel(0xDEADBEAF, sram_base_addr + 4);
                dsb_sev();
@@ -317,6 +321,13 @@ static void __init rockchip_smp_prepare_cpus(unsigned int max_cpus)
 #ifdef CONFIG_HOTPLUG_CPU
 static int rockchip_cpu_kill(unsigned int cpu)
 {
+       /*
+        * We need a delay here to ensure that the dying CPU can finish
+        * executing v7_coherency_exit() and reach the WFI/WFE state
+        * prior to having the power domain disabled.
+        */
+       mdelay(1);
+
        pmu_set_power_domain(0 + cpu, false);
        return 1;
 }
@@ -324,7 +335,7 @@ static int rockchip_cpu_kill(unsigned int cpu)
 static void rockchip_cpu_die(unsigned int cpu)
 {
        v7_exit_coherency_flush(louis);
-       while(1)
+       while (1)
                cpu_do_idle();
 }
 #endif
@@ -337,4 +348,5 @@ static struct smp_operations rockchip_smp_ops __initdata = {
        .cpu_die                = rockchip_cpu_die,
 #endif
 };
+
 CPU_METHOD_OF_DECLARE(rk3066_smp, "rockchip,rk3066-smp", &rockchip_smp_ops);
index b0dcbe2..bee8c80 100644 (file)
@@ -45,9 +45,11 @@ static phys_addr_t rk3288_bootram_phy;
 
 static struct regmap *pmu_regmap;
 static struct regmap *sgrf_regmap;
+static struct regmap *grf_regmap;
 
 static u32 rk3288_pmu_pwr_mode_con;
 static u32 rk3288_sgrf_soc_con0;
+static u32 rk3288_sgrf_cpu_con0;
 
 static inline u32 rk3288_l2_config(void)
 {
@@ -66,10 +68,37 @@ static void rk3288_config_bootdata(void)
        rkpm_bootdata_l2ctlr = rk3288_l2_config();
 }
 
+#define GRF_UOC0_CON0                  0x320
+#define GRF_UOC1_CON0                  0x334
+#define GRF_UOC2_CON0                  0x348
+#define GRF_SIDDQ                      BIT(13)
+
+static bool rk3288_slp_disable_osc(void)
+{
+       static const u32 reg_offset[] = { GRF_UOC0_CON0, GRF_UOC1_CON0,
+                                         GRF_UOC2_CON0 };
+       u32 reg, i;
+
+       /*
+        * if any usb phy is still on(GRF_SIDDQ==0), that means we need the
+        * function of usb wakeup, so do not switch to 32khz, since the usb phy
+        * clk does not connect to 32khz osc
+        */
+       for (i = 0; i < ARRAY_SIZE(reg_offset); i++) {
+               regmap_read(grf_regmap, reg_offset[i], &reg);
+               if (!(reg & GRF_SIDDQ))
+                       return false;
+       }
+
+       return true;
+}
+
 static void rk3288_slp_mode_set(int level)
 {
        u32 mode_set, mode_set1;
+       bool osc_disable = rk3288_slp_disable_osc();
 
+       regmap_read(sgrf_regmap, RK3288_SGRF_CPU_CON0, &rk3288_sgrf_cpu_con0);
        regmap_read(sgrf_regmap, RK3288_SGRF_SOC_CON0, &rk3288_sgrf_soc_con0);
 
        regmap_read(pmu_regmap, RK3288_PMU_PWRMODE_CON,
@@ -94,9 +123,6 @@ static void rk3288_slp_mode_set(int level)
        regmap_write(sgrf_regmap, RK3288_SGRF_FAST_BOOT_ADDR,
                     rk3288_bootram_phy);
 
-       regmap_write(pmu_regmap, RK3288_PMU_WAKEUP_CFG1,
-                    PMU_ARMINT_WAKEUP_EN);
-
        mode_set = BIT(PMU_GLOBAL_INT_DISABLE) | BIT(PMU_L2FLUSH_EN) |
                   BIT(PMU_SREF0_ENTER_EN) | BIT(PMU_SREF1_ENTER_EN) |
                   BIT(PMU_DDR0_GATING_EN) | BIT(PMU_DDR1_GATING_EN) |
@@ -107,13 +133,31 @@ static void rk3288_slp_mode_set(int level)
 
        if (level == ROCKCHIP_ARM_OFF_LOGIC_DEEP) {
                /* arm off, logic deep sleep */
-               mode_set |= BIT(PMU_BUS_PD_EN) |
+               mode_set |= BIT(PMU_BUS_PD_EN) | BIT(PMU_PMU_USE_LF) |
                            BIT(PMU_DDR1IO_RET_EN) | BIT(PMU_DDR0IO_RET_EN) |
-                           BIT(PMU_OSC_24M_DIS) | BIT(PMU_PMU_USE_LF) |
                            BIT(PMU_ALIVE_USE_LF) | BIT(PMU_PLL_PD_EN);
 
+               if (osc_disable)
+                       mode_set |= BIT(PMU_OSC_24M_DIS);
+
                mode_set1 |= BIT(PMU_CLR_ALIVE) | BIT(PMU_CLR_BUS) |
                             BIT(PMU_CLR_PERI) | BIT(PMU_CLR_DMA);
+
+               regmap_write(pmu_regmap, RK3288_PMU_WAKEUP_CFG1,
+                            PMU_ARMINT_WAKEUP_EN);
+
+               /*
+                * In deep suspend we use PMU_PMU_USE_LF to let the rk3288
+                * switch its main clock supply to the alternative 32kHz
+                * source. Therefore set 30ms on a 32kHz clock for pmic
+                * stabilization. Similar 30ms on 24MHz for the other
+                * mode below.
+                */
+               regmap_write(pmu_regmap, RK3288_PMU_STABL_CNT, 32 * 30);
+
+               /* only wait for stabilization, if we turned the osc off */
+               regmap_write(pmu_regmap, RK3288_PMU_OSC_CNT,
+                                        osc_disable ? 32 * 30 : 0);
        } else {
                /*
                 * arm off, logic normal
@@ -121,6 +165,15 @@ static void rk3288_slp_mode_set(int level)
                 * wakeup will be error
                 */
                mode_set |= BIT(PMU_CLK_CORE_SRC_GATE_EN);
+
+               regmap_write(pmu_regmap, RK3288_PMU_WAKEUP_CFG1,
+                            PMU_ARMINT_WAKEUP_EN | PMU_GPIOINT_WAKEUP_EN);
+
+               /* 30ms on a 24MHz clock for pmic stabilization */
+               regmap_write(pmu_regmap, RK3288_PMU_STABL_CNT, 24000 * 30);
+
+               /* oscillator is still running, so no need to wait */
+               regmap_write(pmu_regmap, RK3288_PMU_OSC_CNT, 0);
        }
 
        regmap_write(pmu_regmap, RK3288_PMU_PWRMODE_CON, mode_set);
@@ -129,6 +182,9 @@ static void rk3288_slp_mode_set(int level)
 
 static void rk3288_slp_mode_set_resume(void)
 {
+       regmap_write(sgrf_regmap, RK3288_SGRF_CPU_CON0,
+                    rk3288_sgrf_cpu_con0 | SGRF_DAPDEVICEEN_WRITE);
+
        regmap_write(pmu_regmap, RK3288_PMU_PWRMODE_CON,
                     rk3288_pmu_pwr_mode_con);
 
@@ -190,7 +246,14 @@ static int rk3288_suspend_init(struct device_node *np)
                                "rockchip,rk3288-sgrf");
        if (IS_ERR(sgrf_regmap)) {
                pr_err("%s: could not find sgrf regmap\n", __func__);
-               return PTR_ERR(pmu_regmap);
+               return PTR_ERR(sgrf_regmap);
+       }
+
+       grf_regmap = syscon_regmap_lookup_by_compatible(
+                               "rockchip,rk3288-grf");
+       if (IS_ERR(grf_regmap)) {
+               pr_err("%s: could not find grf regmap\n", __func__);
+               return PTR_ERR(grf_regmap);
        }
 
        sram_np = of_find_compatible_node(NULL, NULL,
@@ -221,9 +284,6 @@ static int rk3288_suspend_init(struct device_node *np)
        memcpy(rk3288_bootram_base, rockchip_slp_cpu_resume,
               rk3288_bootram_sz);
 
-       regmap_write(pmu_regmap, RK3288_PMU_OSC_CNT, OSC_STABL_CNT_THRESH);
-       regmap_write(pmu_regmap, RK3288_PMU_STABL_CNT, PMU_STABL_CNT_THRESH);
-
        return 0;
 }
 
index 3e8d39c..b5af26f 100644 (file)
@@ -59,19 +59,9 @@ static inline void rockchip_suspend_init(void)
 #define SGRF_DAPDEVICEEN               BIT(0)
 #define SGRF_DAPDEVICEEN_WRITE         BIT(16)
 
-#define RK3288_CRU_MODE_CON            0x50
-#define RK3288_CRU_SEL0_CON            0x60
-#define RK3288_CRU_SEL1_CON            0x64
-#define RK3288_CRU_SEL10_CON           0x88
-#define RK3288_CRU_SEL33_CON           0xe4
-#define RK3288_CRU_SEL37_CON           0xf4
-
 /* PMU_WAKEUP_CFG1 bits */
 #define PMU_ARMINT_WAKEUP_EN           BIT(0)
-
-/* wait 30ms for OSC stable and 30ms for pmic stable */
-#define OSC_STABL_CNT_THRESH   (32 * 30)
-#define PMU_STABL_CNT_THRESH   (32 * 30)
+#define PMU_GPIOINT_WAKEUP_EN          BIT(3)
 
 enum rk3288_pwr_mode_con {
        PMU_PWR_MODE_EN = 0,
index 26505d4..aa38a43 100644 (file)
@@ -80,6 +80,11 @@ config ARCH_R8A7791
        select ARCH_RCAR_GEN2
        select I2C
 
+config ARCH_R8A7793
+       bool "R-Car M2-N (R8A7793)"
+       select ARCH_RCAR_GEN2
+       select I2C
+
 config ARCH_R8A7794
        bool "R-Car E2 (R8A77940)"
        select ARCH_RCAR_GEN2
index 9fd0fac..476de30 100644 (file)
@@ -13,6 +13,7 @@ obj-$(CONFIG_ARCH_R8A7778)    += setup-r8a7778.o
 obj-$(CONFIG_ARCH_R8A7779)     += setup-r8a7779.o pm-r8a7779.o
 obj-$(CONFIG_ARCH_R8A7790)     += setup-r8a7790.o
 obj-$(CONFIG_ARCH_R8A7791)     += setup-r8a7791.o
+obj-$(CONFIG_ARCH_R8A7793)     += setup-r8a7793.o
 obj-$(CONFIG_ARCH_R8A7794)     += setup-r8a7794.o
 obj-$(CONFIG_ARCH_EMEV2)       += setup-emev2.o
 obj-$(CONFIG_ARCH_R7S72100)    += setup-r7s72100.o
@@ -31,6 +32,7 @@ obj-$(CONFIG_ARCH_RCAR_GEN2)  += setup-rcar-gen2.o platsmp-apmu.o $(cpu-y)
 CFLAGS_setup-rcar-gen2.o       += -march=armv7-a
 obj-$(CONFIG_ARCH_R8A7790)     += regulator-quirk-rcar-gen2.o
 obj-$(CONFIG_ARCH_R8A7791)     += regulator-quirk-rcar-gen2.o
+obj-$(CONFIG_ARCH_R8A7793)     += regulator-quirk-rcar-gen2.o
 
 # SMP objects
 smp-y                          := $(cpu-y)
index 384e6e9..62437b5 100644 (file)
@@ -123,7 +123,8 @@ static int __init rcar_gen2_regulator_quirk(void)
        u32 mon;
 
        if (!of_machine_is_compatible("renesas,koelsch") &&
-           !of_machine_is_compatible("renesas,lager"))
+           !of_machine_is_compatible("renesas,lager") &&
+           !of_machine_is_compatible("renesas,gose"))
                return -ENODEV;
 
        irqc = ioremap(IRQC_BASE, PAGE_SIZE);
diff --git a/arch/arm/mach-shmobile/setup-r8a7793.c b/arch/arm/mach-shmobile/setup-r8a7793.c
new file mode 100644 (file)
index 0000000..1d2825c
--- /dev/null
@@ -0,0 +1,33 @@
+/*
+ * r8a7793 processor support
+ *
+ * Copyright (C) 2015  Ulrich Hecht
+ *
+ * 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 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/init.h>
+#include <asm/mach/arch.h>
+
+#include "common.h"
+#include "rcar-gen2.h"
+
+static const char *r8a7793_boards_compat_dt[] __initconst = {
+       "renesas,r8a7793",
+       NULL,
+};
+
+DT_MACHINE_START(R8A7793_DT, "Generic R8A7793 (Flattened Device Tree)")
+       .init_early     = shmobile_init_delay,
+       .init_time      = rcar_gen2_timer_init,
+       .init_late      = shmobile_init_late,
+       .reserve        = rcar_gen2_reserve,
+       .dt_compat      = r8a7793_boards_compat_dt,
+MACHINE_END
index 7259c37..5bc6ea8 100644 (file)
@@ -25,6 +25,7 @@
 #define SOCFPGA_RSTMGR_MODPERRST       0x14
 #define SOCFPGA_RSTMGR_BRGMODRST       0x1c
 
+#define SOCFPGA_A10_RSTMGR_CTRL                0xC
 #define SOCFPGA_A10_RSTMGR_MODMPURST   0x20
 
 /* System Manager bits */
index c6f1df8..15c8ce8 100644 (file)
@@ -106,11 +106,23 @@ static void socfpga_cpu_die(unsigned int cpu)
                cpu_do_idle();
 }
 
+/*
+ * We need a dummy function so that platform_can_cpu_hotplug() knows
+ * we support CPU hotplug. However, the function does not need to do
+ * anything, because CPUs going offline just do WFI. We could reset
+ * the CPUs but it would increase power consumption.
+ */
+static int socfpga_cpu_kill(unsigned int cpu)
+{
+       return 1;
+}
+
 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,
+       .cpu_kill               = socfpga_cpu_kill,
 #endif
 };
 
@@ -119,6 +131,7 @@ static struct smp_operations socfpga_a10_smp_ops __initdata = {
        .smp_boot_secondary     = socfpga_a10_boot_secondary,
 #ifdef CONFIG_HOTPLUG_CPU
        .cpu_die                = socfpga_cpu_die,
+       .cpu_kill               = socfpga_cpu_kill,
 #endif
 };
 
index 19643a7..a1c0efa 100644 (file)
@@ -74,6 +74,19 @@ static void socfpga_cyclone5_restart(enum reboot_mode mode, const char *cmd)
        writel(temp, rst_manager_base_addr + SOCFPGA_RSTMGR_CTRL);
 }
 
+static void socfpga_arria10_restart(enum reboot_mode mode, const char *cmd)
+{
+       u32 temp;
+
+       temp = readl(rst_manager_base_addr + SOCFPGA_A10_RSTMGR_CTRL);
+
+       if (mode == REBOOT_HARD)
+               temp |= RSTMGR_CTRL_SWCOLDRSTREQ;
+       else
+               temp |= RSTMGR_CTRL_SWWARMRSTREQ;
+       writel(temp, rst_manager_base_addr + SOCFPGA_A10_RSTMGR_CTRL);
+}
+
 static const char *altera_dt_match[] = {
        "altr,socfpga",
        NULL
@@ -86,3 +99,16 @@ DT_MACHINE_START(SOCFPGA, "Altera SOCFPGA")
        .restart        = socfpga_cyclone5_restart,
        .dt_compat      = altera_dt_match,
 MACHINE_END
+
+static const char *altera_a10_dt_match[] = {
+       "altr,socfpga-arria10",
+       NULL
+};
+
+DT_MACHINE_START(SOCFPGA_A10, "Altera SOCFPGA Arria10")
+       .l2c_aux_val    = 0,
+       .l2c_aux_mask   = ~0,
+       .init_irq       = socfpga_init_irq,
+       .restart        = socfpga_arria10_restart,
+       .dt_compat      = altera_a10_dt_match,
+MACHINE_END
index 4c09bae..e0ad451 100644 (file)
@@ -37,6 +37,7 @@ pen:  ldr     r7, [r6]
         * should now contain the SVC stack for this core
         */
        b       secondary_startup
+ENDPROC(sti_secondary_startup)
 
 1:     .long   .
        .long   pen_release
index d4b624f..c4ad6ea 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/io.h>
 #include <linux/of.h>
 #include <linux/of_address.h>
+#include <linux/memblock.h>
 
 #include <asm/cacheflush.h>
 #include <asm/smp_plat.h>
@@ -38,8 +39,6 @@ static DEFINE_SPINLOCK(boot_lock);
 
 static void sti_secondary_init(unsigned int cpu)
 {
-       trace_hardirqs_off();
-
        /*
         * let the primary processor know we're out of the
         * pen, then head off into the C entry point
@@ -99,14 +98,62 @@ static int sti_boot_secondary(unsigned int cpu, struct task_struct *idle)
 
 static void __init sti_smp_prepare_cpus(unsigned int max_cpus)
 {
-       void __iomem *scu_base = NULL;
-       struct device_node *np = of_find_compatible_node(
-                                       NULL, NULL, "arm,cortex-a9-scu");
+       struct device_node *np;
+       void __iomem *scu_base;
+       u32 __iomem *cpu_strt_ptr;
+       u32 release_phys;
+       int cpu;
+       unsigned long entry_pa = virt_to_phys(sti_secondary_startup);
+
+       np = of_find_compatible_node(NULL, NULL, "arm,cortex-a9-scu");
+
        if (np) {
                scu_base = of_iomap(np, 0);
                scu_enable(scu_base);
                of_node_put(np);
        }
+
+       if (max_cpus <= 1)
+               return;
+
+       for_each_possible_cpu(cpu) {
+
+               np = of_get_cpu_node(cpu, NULL);
+
+               if (!np)
+                       continue;
+
+               if (of_property_read_u32(np, "cpu-release-addr",
+                                               &release_phys)) {
+                       pr_err("CPU %d: missing or invalid cpu-release-addr "
+                               "property\n", cpu);
+                       continue;
+               }
+
+               /*
+                * holding pen is usually configured in SBC DMEM but can also be
+                * in RAM.
+                */
+
+               if (!memblock_is_memory(release_phys))
+                       cpu_strt_ptr =
+                               ioremap(release_phys, sizeof(release_phys));
+               else
+                       cpu_strt_ptr =
+                               (u32 __iomem *)phys_to_virt(release_phys);
+
+               __raw_writel(entry_pa, cpu_strt_ptr);
+
+               /*
+                * wmb so that data is actually written
+                * before cache flush is done
+                */
+               smp_wmb();
+               sync_cache_w(cpu_strt_ptr);
+
+               if (!memblock_is_memory(release_phys))
+                       iounmap(cpu_strt_ptr);
+       }
 }
 
 struct smp_operations __initdata sti_smp_ops = {
index 1871b72..ae22707 100644 (file)
@@ -14,4 +14,6 @@
 
 extern struct smp_operations   sti_smp_ops;
 
+void sti_secondary_startup(void);
+
 #endif
index 5943e1c..4b784f7 100644 (file)
@@ -60,12 +60,6 @@ err:
        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)
 {
@@ -75,7 +69,7 @@ static int uniphier_boot_secondary(unsigned int cpu,
                return -ENODEV;
 
        ret = regmap_write(sbcm_regmap, 0x1208,
-                          virt_to_phys(uniphier_secondary_startup));
+                          virt_to_phys(secondary_startup));
        if (!ret)
                asm("sev"); /* wake up secondary CPU */
 
index 2a910dc..7fdc5bf 100644 (file)
@@ -13,6 +13,7 @@ config SOC_ZX296702
        select ARM_GLOBAL_TIMER
        select HAVE_ARM_SCU if SMP
        select HAVE_ARM_TWD if SMP
+       select PM_GENERIC_DOMAINS
        help
          Support for ZTE ZX296702 SoC which is a dual core CortexA9MP
 endif
index 7c2edf6..a4b4864 100644 (file)
@@ -1,2 +1,2 @@
-obj-$(CONFIG_SOC_ZX296702) += zx296702.o
+obj-$(CONFIG_SOC_ZX296702) += zx296702.o zx296702-pm-domain.o
 obj-$(CONFIG_SMP) += headsmp.o platsmp.o
diff --git a/arch/arm/mach-zx/zx296702-pm-domain.c b/arch/arm/mach-zx/zx296702-pm-domain.c
new file mode 100644 (file)
index 0000000..e08574d
--- /dev/null
@@ -0,0 +1,202 @@
+/*
+ * Copyright (C) 2015 Linaro Ltd.
+ *
+ * Author: Jun Nie <jun.nie@linaro.org>
+ * License terms: GNU General Public License (GPL) version 2
+ */
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/pm_domain.h>
+#include <linux/slab.h>
+
+#define PCU_DM_CLKEN        0x18
+#define PCU_DM_RSTEN        0x1C
+#define PCU_DM_ISOEN        0x20
+#define PCU_DM_PWRDN        0x24
+#define PCU_DM_ACK_SYNC     0x28
+
+enum {
+       PCU_DM_NEON0 = 0,
+       PCU_DM_NEON1,
+       PCU_DM_GPU,
+       PCU_DM_DECPPU,
+       PCU_DM_VOU,
+       PCU_DM_R2D,
+       PCU_DM_TOP,
+};
+
+static void __iomem *pcubase;
+
+struct zx_pm_domain {
+       struct generic_pm_domain dm;
+       unsigned int bit;
+};
+
+static int normal_power_off(struct generic_pm_domain *domain)
+{
+       struct zx_pm_domain *zpd = (struct zx_pm_domain *)domain;
+       unsigned long loop = 1000;
+       u32 tmp;
+
+       tmp = readl_relaxed(pcubase + PCU_DM_CLKEN);
+       tmp &= ~BIT(zpd->bit);
+       writel_relaxed(tmp, pcubase + PCU_DM_CLKEN);
+       udelay(5);
+
+       tmp = readl_relaxed(pcubase + PCU_DM_ISOEN);
+       tmp &= ~BIT(zpd->bit);
+       writel_relaxed(tmp | BIT(zpd->bit), pcubase + PCU_DM_ISOEN);
+       udelay(5);
+
+       tmp = readl_relaxed(pcubase + PCU_DM_RSTEN);
+       tmp &= ~BIT(zpd->bit);
+       writel_relaxed(tmp, pcubase + PCU_DM_RSTEN);
+       udelay(5);
+
+       tmp = readl_relaxed(pcubase + PCU_DM_PWRDN);
+       tmp &= ~BIT(zpd->bit);
+       writel_relaxed(tmp | BIT(zpd->bit), pcubase + PCU_DM_PWRDN);
+       do {
+               tmp = readl_relaxed(pcubase + PCU_DM_ACK_SYNC) & BIT(zpd->bit);
+       } while (--loop && !tmp);
+
+       if (!loop) {
+               pr_err("Error: %s %s fail\n", __func__, domain->name);
+               return -EIO;
+       }
+
+       return 0;
+}
+
+static int normal_power_on(struct generic_pm_domain *domain)
+{
+       struct zx_pm_domain *zpd = (struct zx_pm_domain *)domain;
+       unsigned long loop = 10000;
+       u32 tmp;
+
+       tmp = readl_relaxed(pcubase + PCU_DM_PWRDN);
+       tmp &= ~BIT(zpd->bit);
+       writel_relaxed(tmp, pcubase + PCU_DM_PWRDN);
+       do {
+               tmp = readl_relaxed(pcubase + PCU_DM_ACK_SYNC) & BIT(zpd->bit);
+       } while (--loop && tmp);
+
+       if (!loop) {
+               pr_err("Error: %s %s fail\n", __func__, domain->name);
+               return -EIO;
+       }
+
+       tmp = readl_relaxed(pcubase + PCU_DM_RSTEN);
+       tmp &= ~BIT(zpd->bit);
+       writel_relaxed(tmp | BIT(zpd->bit), pcubase + PCU_DM_RSTEN);
+       udelay(5);
+
+       tmp = readl_relaxed(pcubase + PCU_DM_ISOEN);
+       tmp &= ~BIT(zpd->bit);
+       writel_relaxed(tmp, pcubase + PCU_DM_ISOEN);
+       udelay(5);
+
+       tmp = readl_relaxed(pcubase + PCU_DM_CLKEN);
+       tmp &= ~BIT(zpd->bit);
+       writel_relaxed(tmp | BIT(zpd->bit), pcubase + PCU_DM_CLKEN);
+       udelay(5);
+       return 0;
+}
+
+static struct zx_pm_domain gpu_domain = {
+       .dm = {
+               .name           = "gpu_domain",
+               .power_off      = normal_power_off,
+               .power_on       = normal_power_on,
+       },
+       .bit = PCU_DM_GPU,
+};
+
+static struct zx_pm_domain decppu_domain = {
+       .dm = {
+               .name           = "decppu_domain",
+               .power_off      = normal_power_off,
+               .power_on       = normal_power_on,
+       },
+       .bit = PCU_DM_DECPPU,
+};
+
+static struct zx_pm_domain vou_domain = {
+       .dm = {
+               .name           = "vou_domain",
+               .power_off      = normal_power_off,
+               .power_on       = normal_power_on,
+       },
+       .bit = PCU_DM_VOU,
+};
+
+static struct zx_pm_domain r2d_domain = {
+       .dm = {
+               .name           = "r2d_domain",
+               .power_off      = normal_power_off,
+               .power_on       = normal_power_on,
+       },
+       .bit = PCU_DM_R2D,
+};
+
+static struct generic_pm_domain *zx296702_pm_domains[] = {
+       &vou_domain.dm,
+       &gpu_domain.dm,
+       &decppu_domain.dm,
+       &r2d_domain.dm,
+};
+
+static int zx296702_pd_probe(struct platform_device *pdev)
+{
+       struct genpd_onecell_data *genpd_data;
+       struct resource *res;
+       int i;
+
+       genpd_data = devm_kzalloc(&pdev->dev, sizeof(*genpd_data), GFP_KERNEL);
+       if (!genpd_data)
+               return -ENOMEM;
+
+       genpd_data->domains = zx296702_pm_domains;
+       genpd_data->num_domains = ARRAY_SIZE(zx296702_pm_domains);
+
+       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       if (!res) {
+               dev_err(&pdev->dev, "no memory resource defined\n");
+               return -ENODEV;
+       }
+
+       pcubase = devm_ioremap_resource(&pdev->dev, res);
+       if (!pcubase) {
+               dev_err(&pdev->dev, "ioremap fail.\n");
+               return -EIO;
+       }
+
+       for (i = 0; i < ARRAY_SIZE(zx296702_pm_domains); ++i)
+               pm_genpd_init(zx296702_pm_domains[i], NULL, false);
+
+       of_genpd_add_provider_onecell(pdev->dev.of_node, genpd_data);
+       return 0;
+}
+
+static const struct of_device_id zx296702_pm_domain_matches[] __initconst = {
+       { .compatible = "zte,zx296702-pcu", },
+       { },
+};
+
+static struct platform_driver zx296702_pd_driver __initdata = {
+       .driver = {
+               .name = "zx-powerdomain",
+               .owner = THIS_MODULE,
+               .of_match_table = zx296702_pm_domain_matches,
+       },
+       .probe = zx296702_pd_probe,
+};
+
+static int __init zx296702_pd_init(void)
+{
+       return platform_driver_register(&zx296702_pd_driver);
+}
+subsys_initcall(zx296702_pd_init);
index 616d584..6bd4a43 100644 (file)
@@ -197,8 +197,8 @@ static const char * const zynq_dt_match[] = {
 
 DT_MACHINE_START(XILINX_EP107, "Xilinx Zynq Platform")
        /* 64KB way size, 8-way associativity, parity disabled */
-       .l2c_aux_val    = 0x00000000,
-       .l2c_aux_mask   = 0xffffffff,
+       .l2c_aux_val    = 0x00400000,
+       .l2c_aux_mask   = 0xffbfffff,
        .smp            = smp_ops(zynq_smp_ops),
        .map_io         = zynq_map_io,
        .init_irq       = zynq_irq_init,
index 045c727..f6d5de0 100644 (file)
@@ -18,7 +18,7 @@ ARM_BE8(rev   r0, r0)
 .globl zynq_secondary_trampoline_jump
 zynq_secondary_trampoline_jump:
        /* Space for jumping address */
-       .word   /* cpu 1 */
+       .word   0       /* cpu 1 */
 .globl zynq_secondary_trampoline_end
 zynq_secondary_trampoline_end:
 ENDPROC(zynq_secondary_trampoline)
index d92f07f..de2b061 100644 (file)
@@ -289,7 +289,8 @@ int pxa_request_dma (char *name, pxa_dma_prio prio,
                /* try grabbing a DMA channel with the requested priority */
                for (i = 0; i < num_dma_channels; i++) {
                        if ((dma_channels[i].prio == prio) &&
-                           !dma_channels[i].name) {
+                           !dma_channels[i].name &&
+                           !pxad_toggle_reserved_channel(i)) {
                                found = 1;
                                break;
                        }
@@ -326,13 +327,14 @@ void pxa_free_dma (int dma_ch)
        local_irq_save(flags);
        DCSR(dma_ch) = DCSR_STARTINTR|DCSR_ENDINTR|DCSR_BUSERR;
        dma_channels[dma_ch].name = NULL;
+       pxad_toggle_reserved_channel(dma_ch);
        local_irq_restore(flags);
 }
 EXPORT_SYMBOL(pxa_free_dma);
 
 static irqreturn_t dma_irq_handler(int irq, void *dev_id)
 {
-       int i, dint = DINT;
+       int i, dint = DINT, done = 0;
        struct dma_channel *channel;
 
        while (dint) {
@@ -341,16 +343,13 @@ static irqreturn_t dma_irq_handler(int irq, void *dev_id)
                channel = &dma_channels[i];
                if (channel->name && channel->irq_handler) {
                        channel->irq_handler(i, channel->data);
-               } else {
-                       /*
-                        * IRQ for an unregistered DMA channel:
-                        * let's clear the interrupts and disable it.
-                        */
-                       printk (KERN_WARNING "spurious IRQ for DMA channel %d\n", i);
-                       DCSR(i) = DCSR_STARTINTR|DCSR_ENDINTR|DCSR_BUSERR;
+                       done++;
                }
        }
-       return IRQ_HANDLED;
+       if (done)
+               return IRQ_HANDLED;
+       else
+               return IRQ_NONE;
 }
 
 int __init pxa_init_dma(int irq, int num_ch)
@@ -372,7 +371,8 @@ int __init pxa_init_dma(int irq, int num_ch)
                spin_lock_init(&dma_channels[i].lock);
        }
 
-       ret = request_irq(irq, dma_irq_handler, 0, "DMA", NULL);
+       ret = request_irq(irq, dma_irq_handler, IRQF_SHARED, "DMA",
+                         dma_channels);
        if (ret) {
                printk (KERN_CRIT "Wow!  Can't register IRQ for DMA\n");
                kfree(dma_channels);
index a7b91dc..28848b3 100644 (file)
@@ -82,4 +82,19 @@ int pxa_request_dma (char *name,
 
 void pxa_free_dma (int dma_ch);
 
+/*
+ * Cooperation with pxa_dma + dmaengine while there remains at least one pxa
+ * driver not converted to dmaengine.
+ */
+#if defined(CONFIG_PXA_DMA)
+extern int pxad_toggle_reserved_channel(int legacy_channel);
+#else
+static inline int pxad_toggle_reserved_channel(int legacy_channel)
+{
+       return 0;
+}
+#endif
+
+extern void __init pxa2xx_set_dmac_info(int nb_channels);
+
 #endif /* __PLAT_DMA_H */
index 9b93e69..d4ac960 100644 (file)
@@ -3,7 +3,7 @@ clk-common                              = dpll.o composite.o divider.o gate.o \
                                          fixed-factor.o mux.o apll.o \
                                          clkt_dpll.o clkt_iclk.o clkt_dflt.o
 obj-$(CONFIG_SOC_AM33XX)               += $(clk-common) clk-33xx.o dpll3xxx.o
-obj-$(CONFIG_SOC_TI81XX)               += $(clk-common) fapll.o clk-816x.o
+obj-$(CONFIG_SOC_TI81XX)               += $(clk-common) fapll.o clk-814x.o clk-816x.o
 obj-$(CONFIG_ARCH_OMAP2)               += $(clk-common) interface.o clk-2xxx.o
 obj-$(CONFIG_ARCH_OMAP3)               += $(clk-common) interface.o \
                                           clk-3xxx.o dpll3xxx.o
diff --git a/drivers/clk/ti/clk-814x.c b/drivers/clk/ti/clk-814x.c
new file mode 100644 (file)
index 0000000..e172920
--- /dev/null
@@ -0,0 +1,33 @@
+/*
+ * 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.
+ */
+
+#include <linux/kernel.h>
+#include <linux/clk-provider.h>
+#include <linux/clk/ti.h>
+
+#include "clock.h"
+
+static struct ti_dt_clk dm814_clks[] = {
+       DT_CLK(NULL, "devosc_ck", "devosc_ck"),
+       DT_CLK(NULL, "mpu_ck", "mpu_ck"),
+       DT_CLK(NULL, "sysclk4_ck", "sysclk4_ck"),
+       DT_CLK(NULL, "sysclk6_ck", "sysclk6_ck"),
+       DT_CLK(NULL, "sysclk10_ck", "sysclk10_ck"),
+       DT_CLK(NULL, "sysclk18_ck", "sysclk18_ck"),
+       DT_CLK(NULL, "timer_sys_ck", "devosc_ck"),
+       DT_CLK(NULL, "cpsw_125mhz_gclk", "cpsw_125mhz_gclk"),
+       DT_CLK(NULL, "cpsw_cpts_rft_clk", "cpsw_cpts_rft_clk"),
+       { .node_name = NULL },
+};
+
+int __init dm814x_dt_clk_init(void)
+{
+       ti_dt_clocks_register(dm814_clks);
+       omap2_clk_disable_autoidle_all();
+       omap2_clk_enable_init_clocks(NULL, 0);
+
+       return 0;
+}
index c69352b..1dfad0c 100644 (file)
@@ -44,7 +44,7 @@ static const char *enable_init_clks[] = {
        "ddr_pll_clk3",
 };
 
-int __init ti81xx_dt_clk_init(void)
+int __init dm816x_dt_clk_init(void)
 {
        ti_dt_clocks_register(dm816x_clks);
        omap2_clk_disable_autoidle_all();
index 156d923..0afc2e7 100644 (file)
@@ -1,3 +1,3 @@
 # Zynq clock specific Makefile
 
-obj-$(CONFIG_ARCH_ZYNQ)        += clkc.o pll.o
+obj-y  += clkc.o pll.o
index 4cd94fd..82a8fb5 100644 (file)
@@ -401,6 +401,17 @@ config KEYBOARD_MPR121
          To compile this driver as a module, choose M here: the
          module will be called mpr121_touchkey.
 
+config KEYBOARD_SNVS_PWRKEY
+       tristate "IMX SNVS Power Key Driver"
+       depends on SOC_IMX6SX
+       depends on OF
+       help
+         This is the snvs powerkey driver for the Freescale i.MX application
+         processors that are newer than i.MX6 SX.
+
+         To compile this driver as a module, choose M here; the
+         module will be called snvs_pwrkey.
+
 config KEYBOARD_IMX
        tristate "IMX keypad support"
        depends on ARCH_MXC
index df28d55..1d416dd 100644 (file)
@@ -51,6 +51,7 @@ obj-$(CONFIG_KEYBOARD_QT1070)           += qt1070.o
 obj-$(CONFIG_KEYBOARD_QT2160)          += qt2160.o
 obj-$(CONFIG_KEYBOARD_SAMSUNG)         += samsung-keypad.o
 obj-$(CONFIG_KEYBOARD_SH_KEYSC)                += sh_keysc.o
+obj-$(CONFIG_KEYBOARD_SNVS_PWRKEY)     += snvs_pwrkey.o
 obj-$(CONFIG_KEYBOARD_SPEAR)           += spear-keyboard.o
 obj-$(CONFIG_KEYBOARD_STMPE)           += stmpe-keypad.o
 obj-$(CONFIG_KEYBOARD_STOWAWAY)                += stowaway.o
diff --git a/drivers/input/keyboard/snvs_pwrkey.c b/drivers/input/keyboard/snvs_pwrkey.c
new file mode 100644 (file)
index 0000000..78fd24c
--- /dev/null
@@ -0,0 +1,227 @@
+/*
+ * Driver for the IMX SNVS ON/OFF Power Key
+ * Copyright (C) 2015 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * 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/device.h>
+#include <linux/err.h>
+#include <linux/init.h>
+#include <linux/input.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/jiffies.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/platform_device.h>
+#include <linux/mfd/syscon.h>
+#include <linux/regmap.h>
+
+#define SNVS_LPSR_REG  0x4C    /* LP Status Register */
+#define SNVS_LPCR_REG  0x38    /* LP Control Register */
+#define SNVS_HPSR_REG  0x14
+#define SNVS_HPSR_BTN  BIT(6)
+#define SNVS_LPSR_SPO  BIT(18)
+#define SNVS_LPCR_DEP_EN BIT(5)
+
+#define DEBOUNCE_TIME 30
+#define REPEAT_INTERVAL 60
+
+struct pwrkey_drv_data {
+       struct regmap *snvs;
+       int irq;
+       int keycode;
+       int keystate;  /* 1:pressed */
+       int wakeup;
+       struct timer_list check_timer;
+       struct input_dev *input;
+};
+
+static void imx_imx_snvs_check_for_events(unsigned long data)
+{
+       struct pwrkey_drv_data *pdata = (struct pwrkey_drv_data *) data;
+       struct input_dev *input = pdata->input;
+       u32 state;
+
+       regmap_read(pdata->snvs, SNVS_HPSR_REG, &state);
+       state = state & SNVS_HPSR_BTN ? 1 : 0;
+
+       /* only report new event if status changed */
+       if (state ^ pdata->keystate) {
+               pdata->keystate = state;
+               input_event(input, EV_KEY, pdata->keycode, state);
+               input_sync(input);
+               pm_relax(pdata->input->dev.parent);
+       }
+
+       /* repeat check if pressed long */
+       if (state) {
+               mod_timer(&pdata->check_timer,
+                         jiffies + msecs_to_jiffies(REPEAT_INTERVAL));
+       }
+}
+
+static irqreturn_t imx_snvs_pwrkey_interrupt(int irq, void *dev_id)
+{
+       struct platform_device *pdev = dev_id;
+       struct pwrkey_drv_data *pdata = platform_get_drvdata(pdev);
+       u32 lp_status;
+
+       pm_wakeup_event(pdata->input->dev.parent, 0);
+
+       regmap_read(pdata->snvs, SNVS_LPSR_REG, &lp_status);
+       if (lp_status & SNVS_LPSR_SPO)
+               mod_timer(&pdata->check_timer, jiffies + msecs_to_jiffies(DEBOUNCE_TIME));
+
+       /* clear SPO status */
+       regmap_write(pdata->snvs, SNVS_LPSR_REG, SNVS_LPSR_SPO);
+
+       return IRQ_HANDLED;
+}
+
+static void imx_snvs_pwrkey_act(void *pdata)
+{
+       struct pwrkey_drv_data *pd = pdata;
+
+       del_timer_sync(&pd->check_timer);
+}
+
+static int imx_snvs_pwrkey_probe(struct platform_device *pdev)
+{
+       struct pwrkey_drv_data *pdata = NULL;
+       struct input_dev *input = NULL;
+       struct device_node *np;
+       int error;
+
+       /* Get SNVS register Page */
+       np = pdev->dev.of_node;
+       if (!np)
+               return -ENODEV;
+
+       pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
+       if (!pdata)
+               return -ENOMEM;
+
+       pdata->snvs = syscon_regmap_lookup_by_phandle(np, "regmap");;
+
+       if (!pdata->snvs) {
+               dev_err(&pdev->dev, "Can't get snvs syscon\n");
+               return -ENODEV;
+       }
+
+       if (of_property_read_u32(np, "linux,keycode", &pdata->keycode)) {
+               pdata->keycode = KEY_POWER;
+               dev_warn(&pdev->dev, "KEY_POWER without setting in dts\n");
+       }
+
+       pdata->wakeup = of_property_read_bool(np, "wakeup-source");
+
+       pdata->irq = platform_get_irq(pdev, 0);
+       if (pdata->irq < 0) {
+               dev_err(&pdev->dev, "no irq defined in platform data\n");
+               return -EINVAL;
+       }
+
+       regmap_update_bits(pdata->snvs, SNVS_LPCR_REG, SNVS_LPCR_DEP_EN, SNVS_LPCR_DEP_EN);
+
+       /* clear the unexpected interrupt before driver ready */
+       regmap_write(pdata->snvs, SNVS_LPSR_REG, SNVS_LPSR_SPO);
+
+       setup_timer(&pdata->check_timer,
+                   imx_imx_snvs_check_for_events, (unsigned long) pdata);
+
+       input = devm_input_allocate_device(&pdev->dev);
+       if (!input) {
+               dev_err(&pdev->dev, "failed to allocate the input device\n");
+               return -ENOMEM;
+       }
+
+       input->name = pdev->name;
+       input->phys = "snvs-pwrkey/input0";
+       input->id.bustype = BUS_HOST;
+
+       input_set_capability(input, EV_KEY, pdata->keycode);
+
+       /* input customer action to cancel release timer */
+       error = devm_add_action(&pdev->dev, imx_snvs_pwrkey_act, pdata);
+       if (error) {
+               dev_err(&pdev->dev, "failed to register remove action\n");
+               return error;
+       }
+
+       error = devm_request_irq(&pdev->dev, pdata->irq,
+                              imx_snvs_pwrkey_interrupt,
+                              0, pdev->name, pdev);
+
+       if (error) {
+               dev_err(&pdev->dev, "interrupt not available.\n");
+               return error;
+       }
+
+       error = input_register_device(input);
+       if (error < 0) {
+               dev_err(&pdev->dev, "failed to register input device\n");
+               input_free_device(input);
+               return error;
+       }
+
+       pdata->input = input;
+       platform_set_drvdata(pdev, pdata);
+
+       device_init_wakeup(&pdev->dev, pdata->wakeup);
+
+       return 0;
+}
+
+static int imx_snvs_pwrkey_suspend(struct device *dev)
+{
+       struct platform_device *pdev = to_platform_device(dev);
+       struct pwrkey_drv_data *pdata = platform_get_drvdata(pdev);
+
+       if (device_may_wakeup(&pdev->dev))
+               enable_irq_wake(pdata->irq);
+
+       return 0;
+}
+
+static int imx_snvs_pwrkey_resume(struct device *dev)
+{
+       struct platform_device *pdev = to_platform_device(dev);
+       struct pwrkey_drv_data *pdata = platform_get_drvdata(pdev);
+
+       if (device_may_wakeup(&pdev->dev))
+               disable_irq_wake(pdata->irq);
+
+       return 0;
+}
+
+static const struct of_device_id imx_snvs_pwrkey_ids[] = {
+       { .compatible = "fsl,sec-v4.0-pwrkey" },
+       { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, imx_snvs_pwrkey_ids);
+
+static SIMPLE_DEV_PM_OPS(imx_snvs_pwrkey_pm_ops, imx_snvs_pwrkey_suspend,
+                               imx_snvs_pwrkey_resume);
+
+static struct platform_driver imx_snvs_pwrkey_driver = {
+       .driver = {
+               .name = "snvs_pwrkey",
+               .pm     = &imx_snvs_pwrkey_pm_ops,
+               .of_match_table = imx_snvs_pwrkey_ids,
+       },
+       .probe = imx_snvs_pwrkey_probe,
+};
+module_platform_driver(imx_snvs_pwrkey_driver);
+
+MODULE_AUTHOR("Freescale Semiconductor");
+MODULE_DESCRIPTION("i.MX snvs power key Driver");
+MODULE_LICENSE("GPL");
index 9426276..32ac049 100644 (file)
@@ -1176,8 +1176,8 @@ static int gpmc_setup_irq(void)
                gpmc_client_irq[i].irq = gpmc_irq_start + i;
                irq_set_chip_and_handler(gpmc_client_irq[i].irq,
                                        &gpmc_irq_chip, handle_simple_irq);
-               set_irq_flags(gpmc_client_irq[i].irq,
-                               IRQF_VALID | IRQF_NOAUTOEN);
+               irq_modify_status(gpmc_client_irq[i].irq, IRQ_NOREQUEST,
+                                 IRQ_NOAUTOEN);
        }
 
        /* Disable interrupts */
@@ -1200,7 +1200,6 @@ static int gpmc_free_irq(void)
        for (i = 0; i < GPMC_NR_IRQ; i++) {
                irq_set_handler(gpmc_client_irq[i].irq, NULL);
                irq_set_chip(gpmc_client_irq[i].irq, &no_irq_chip);
-               irq_modify_status(gpmc_client_irq[i].irq, 0, 0);
        }
 
        irq_free_descs(gpmc_irq_start, GPMC_NR_IRQ);
index 83b4b89..533bfa3 100644 (file)
@@ -1523,6 +1523,7 @@ config RTC_DRV_MXC
 
 config RTC_DRV_SNVS
        tristate "Freescale SNVS RTC support"
+       select REGMAP_MMIO
        depends on HAS_IOMEM
        depends on OF
        help
index 5fc292c..7bd89d9 100644 (file)
@@ -16,6 +16,8 @@
 #include <linux/interrupt.h>
 #include <linux/platform_device.h>
 #include <linux/clk.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
 
 #define RTC_INPUT_CLK_32768HZ  (0x00 << 5)
 #define RTC_INPUT_CLK_32000HZ  (0x01 << 5)
@@ -79,7 +81,8 @@ struct rtc_plat_data {
        struct rtc_device *rtc;
        void __iomem *ioaddr;
        int irq;
-       struct clk *clk;
+       struct clk *clk_ref;
+       struct clk *clk_ipg;
        struct rtc_time g_rtc_alarm;
        enum imx_rtc_type devtype;
 };
@@ -97,6 +100,15 @@ static const struct platform_device_id imx_rtc_devtype[] = {
 };
 MODULE_DEVICE_TABLE(platform, imx_rtc_devtype);
 
+#ifdef CONFIG_OF
+static const struct of_device_id imx_rtc_dt_ids[] = {
+       { .compatible = "fsl,imx1-rtc", .data = (const void *)IMX1_RTC },
+       { .compatible = "fsl,imx21-rtc", .data = (const void *)IMX21_RTC },
+       {}
+};
+MODULE_DEVICE_TABLE(of, imx_rtc_dt_ids);
+#endif
+
 static inline int is_imx1_rtc(struct rtc_plat_data *data)
 {
        return data->devtype == IMX1_RTC;
@@ -361,29 +373,45 @@ static int mxc_rtc_probe(struct platform_device *pdev)
        u32 reg;
        unsigned long rate;
        int ret;
+       const struct of_device_id *of_id;
 
        pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
        if (!pdata)
                return -ENOMEM;
 
-       pdata->devtype = pdev->id_entry->driver_data;
+       of_id = of_match_device(imx_rtc_dt_ids, &pdev->dev);
+       if (of_id)
+               pdata->devtype = (enum imx_rtc_type)of_id->data;
+       else
+               pdata->devtype = pdev->id_entry->driver_data;
 
        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
        pdata->ioaddr = devm_ioremap_resource(&pdev->dev, res);
        if (IS_ERR(pdata->ioaddr))
                return PTR_ERR(pdata->ioaddr);
 
-       pdata->clk = devm_clk_get(&pdev->dev, NULL);
-       if (IS_ERR(pdata->clk)) {
-               dev_err(&pdev->dev, "unable to get clock!\n");
-               return PTR_ERR(pdata->clk);
+       pdata->clk_ipg = devm_clk_get(&pdev->dev, "ipg");
+       if (IS_ERR(pdata->clk_ipg)) {
+               dev_err(&pdev->dev, "unable to get ipg clock!\n");
+               return PTR_ERR(pdata->clk_ipg);
        }
 
-       ret = clk_prepare_enable(pdata->clk);
+       ret = clk_prepare_enable(pdata->clk_ipg);
        if (ret)
                return ret;
 
-       rate = clk_get_rate(pdata->clk);
+       pdata->clk_ref = devm_clk_get(&pdev->dev, "ref");
+       if (IS_ERR(pdata->clk_ref)) {
+               dev_err(&pdev->dev, "unable to get ref clock!\n");
+               ret = PTR_ERR(pdata->clk_ref);
+               goto exit_put_clk_ipg;
+       }
+
+       ret = clk_prepare_enable(pdata->clk_ref);
+       if (ret)
+               goto exit_put_clk_ipg;
+
+       rate = clk_get_rate(pdata->clk_ref);
 
        if (rate == 32768)
                reg = RTC_INPUT_CLK_32768HZ;
@@ -394,7 +422,7 @@ static int mxc_rtc_probe(struct platform_device *pdev)
        else {
                dev_err(&pdev->dev, "rtc clock is not valid (%lu)\n", rate);
                ret = -EINVAL;
-               goto exit_put_clk;
+               goto exit_put_clk_ref;
        }
 
        reg |= RTC_ENABLE_BIT;
@@ -402,7 +430,7 @@ static int mxc_rtc_probe(struct platform_device *pdev)
        if (((readw(pdata->ioaddr + RTC_RTCCTL)) & RTC_ENABLE_BIT) == 0) {
                dev_err(&pdev->dev, "hardware module can't be enabled!\n");
                ret = -EIO;
-               goto exit_put_clk;
+               goto exit_put_clk_ref;
        }
 
        platform_set_drvdata(pdev, pdata);
@@ -424,15 +452,17 @@ static int mxc_rtc_probe(struct platform_device *pdev)
                                  THIS_MODULE);
        if (IS_ERR(rtc)) {
                ret = PTR_ERR(rtc);
-               goto exit_put_clk;
+               goto exit_put_clk_ref;
        }
 
        pdata->rtc = rtc;
 
        return 0;
 
-exit_put_clk:
-       clk_disable_unprepare(pdata->clk);
+exit_put_clk_ref:
+       clk_disable_unprepare(pdata->clk_ref);
+exit_put_clk_ipg:
+       clk_disable_unprepare(pdata->clk_ipg);
 
        return ret;
 }
@@ -441,7 +471,8 @@ static int mxc_rtc_remove(struct platform_device *pdev)
 {
        struct rtc_plat_data *pdata = platform_get_drvdata(pdev);
 
-       clk_disable_unprepare(pdata->clk);
+       clk_disable_unprepare(pdata->clk_ref);
+       clk_disable_unprepare(pdata->clk_ipg);
 
        return 0;
 }
@@ -473,6 +504,7 @@ static SIMPLE_DEV_PM_OPS(mxc_rtc_pm_ops, mxc_rtc_suspend, mxc_rtc_resume);
 static struct platform_driver mxc_rtc_driver = {
        .driver = {
                   .name        = "mxc_rtc",
+                  .of_match_table = of_match_ptr(imx_rtc_dt_ids),
                   .pm          = &mxc_rtc_pm_ops,
        },
        .id_table = imx_rtc_devtype,
index d87a85c..950c5d0 100644 (file)
 #include <linux/platform_device.h>
 #include <linux/rtc.h>
 #include <linux/clk.h>
+#include <linux/mfd/syscon.h>
+#include <linux/regmap.h>
+
+#define SNVS_LPREGISTER_OFFSET 0x34
 
 /* These register offsets are relative to LP (Low Power) range */
 #define SNVS_LPCR              0x04
 
 struct snvs_rtc_data {
        struct rtc_device *rtc;
-       void __iomem *ioaddr;
+       struct regmap *regmap;
+       int offset;
        int irq;
-       spinlock_t lock;
        struct clk *clk;
 };
 
-static u32 rtc_read_lp_counter(void __iomem *ioaddr)
+static u32 rtc_read_lp_counter(struct snvs_rtc_data *data)
 {
        u64 read1, read2;
+       u32 val;
 
        do {
-               read1 = readl(ioaddr + SNVS_LPSRTCMR);
+               regmap_read(data->regmap, data->offset + SNVS_LPSRTCMR, &val);
+               read1 = val;
                read1 <<= 32;
-               read1 |= readl(ioaddr + SNVS_LPSRTCLR);
+               regmap_read(data->regmap, data->offset + SNVS_LPSRTCLR, &val);
+               read1 |= val;
 
-               read2 = readl(ioaddr + SNVS_LPSRTCMR);
+               regmap_read(data->regmap, data->offset + SNVS_LPSRTCMR, &val);
+               read2 = val;
                read2 <<= 32;
-               read2 |= readl(ioaddr + SNVS_LPSRTCLR);
+               regmap_read(data->regmap, data->offset + SNVS_LPSRTCLR, &val);
+               read2 |= val;
        } while (read1 != read2);
 
        /* Convert 47-bit counter to 32-bit raw second count */
        return (u32) (read1 >> CNTR_TO_SECS_SH);
 }
 
-static void rtc_write_sync_lp(void __iomem *ioaddr)
+static void rtc_write_sync_lp(struct snvs_rtc_data *data)
 {
        u32 count1, count2, count3;
        int i;
@@ -69,15 +78,15 @@ static void rtc_write_sync_lp(void __iomem *ioaddr)
        /* Wait for 3 CKIL cycles */
        for (i = 0; i < 3; i++) {
                do {
-                       count1 = readl(ioaddr + SNVS_LPSRTCLR);
-                       count2 = readl(ioaddr + SNVS_LPSRTCLR);
+                       regmap_read(data->regmap, data->offset + SNVS_LPSRTCLR, &count1);
+                       regmap_read(data->regmap, data->offset + SNVS_LPSRTCLR, &count2);
                } while (count1 != count2);
 
                /* Now wait until counter value changes */
                do {
                        do {
-                               count2 = readl(ioaddr + SNVS_LPSRTCLR);
-                               count3 = readl(ioaddr + SNVS_LPSRTCLR);
+                               regmap_read(data->regmap, data->offset + SNVS_LPSRTCLR, &count2);
+                               regmap_read(data->regmap, data->offset + SNVS_LPSRTCLR, &count3);
                        } while (count2 != count3);
                } while (count3 == count1);
        }
@@ -85,23 +94,14 @@ static void rtc_write_sync_lp(void __iomem *ioaddr)
 
 static int snvs_rtc_enable(struct snvs_rtc_data *data, bool enable)
 {
-       unsigned long flags;
        int timeout = 1000;
        u32 lpcr;
 
-       spin_lock_irqsave(&data->lock, flags);
-
-       lpcr = readl(data->ioaddr + SNVS_LPCR);
-       if (enable)
-               lpcr |= SNVS_LPCR_SRTC_ENV;
-       else
-               lpcr &= ~SNVS_LPCR_SRTC_ENV;
-       writel(lpcr, data->ioaddr + SNVS_LPCR);
-
-       spin_unlock_irqrestore(&data->lock, flags);
+       regmap_update_bits(data->regmap, data->offset + SNVS_LPCR, SNVS_LPCR_SRTC_ENV,
+                          enable ? SNVS_LPCR_SRTC_ENV : 0);
 
        while (--timeout) {
-               lpcr = readl(data->ioaddr + SNVS_LPCR);
+               regmap_read(data->regmap, data->offset + SNVS_LPCR, &lpcr);
 
                if (enable) {
                        if (lpcr & SNVS_LPCR_SRTC_ENV)
@@ -121,7 +121,7 @@ static int snvs_rtc_enable(struct snvs_rtc_data *data, bool enable)
 static int snvs_rtc_read_time(struct device *dev, struct rtc_time *tm)
 {
        struct snvs_rtc_data *data = dev_get_drvdata(dev);
-       unsigned long time = rtc_read_lp_counter(data->ioaddr);
+       unsigned long time = rtc_read_lp_counter(data);
 
        rtc_time_to_tm(time, tm);
 
@@ -139,8 +139,8 @@ static int snvs_rtc_set_time(struct device *dev, struct rtc_time *tm)
        snvs_rtc_enable(data, false);
 
        /* Write 32-bit time to 47-bit timer, leaving 15 LSBs blank */
-       writel(time << CNTR_TO_SECS_SH, data->ioaddr + SNVS_LPSRTCLR);
-       writel(time >> (32 - CNTR_TO_SECS_SH), data->ioaddr + SNVS_LPSRTCMR);
+       regmap_write(data->regmap, data->offset + SNVS_LPSRTCLR, time << CNTR_TO_SECS_SH);
+       regmap_write(data->regmap, data->offset + SNVS_LPSRTCMR, time >> (32 - CNTR_TO_SECS_SH));
 
        /* Enable RTC again */
        snvs_rtc_enable(data, true);
@@ -153,10 +153,10 @@ static int snvs_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
        struct snvs_rtc_data *data = dev_get_drvdata(dev);
        u32 lptar, lpsr;
 
-       lptar = readl(data->ioaddr + SNVS_LPTAR);
+       regmap_read(data->regmap, data->offset + SNVS_LPTAR, &lptar);
        rtc_time_to_tm(lptar, &alrm->time);
 
-       lpsr = readl(data->ioaddr + SNVS_LPSR);
+       regmap_read(data->regmap, data->offset + SNVS_LPSR, &lpsr);
        alrm->pending = (lpsr & SNVS_LPSR_LPTA) ? 1 : 0;
 
        return 0;
@@ -165,21 +165,12 @@ static int snvs_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
 static int snvs_rtc_alarm_irq_enable(struct device *dev, unsigned int enable)
 {
        struct snvs_rtc_data *data = dev_get_drvdata(dev);
-       u32 lpcr;
-       unsigned long flags;
-
-       spin_lock_irqsave(&data->lock, flags);
 
-       lpcr = readl(data->ioaddr + SNVS_LPCR);
-       if (enable)
-               lpcr |= (SNVS_LPCR_LPTA_EN | SNVS_LPCR_LPWUI_EN);
-       else
-               lpcr &= ~(SNVS_LPCR_LPTA_EN | SNVS_LPCR_LPWUI_EN);
-       writel(lpcr, data->ioaddr + SNVS_LPCR);
+       regmap_update_bits(data->regmap, data->offset + SNVS_LPCR,
+                          (SNVS_LPCR_LPTA_EN | SNVS_LPCR_LPWUI_EN),
+                          enable ? (SNVS_LPCR_LPTA_EN | SNVS_LPCR_LPWUI_EN) : 0);
 
-       spin_unlock_irqrestore(&data->lock, flags);
-
-       rtc_write_sync_lp(data->ioaddr);
+       rtc_write_sync_lp(data);
 
        return 0;
 }
@@ -189,24 +180,14 @@ static int snvs_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
        struct snvs_rtc_data *data = dev_get_drvdata(dev);
        struct rtc_time *alrm_tm = &alrm->time;
        unsigned long time;
-       unsigned long flags;
-       u32 lpcr;
 
        rtc_tm_to_time(alrm_tm, &time);
 
-       spin_lock_irqsave(&data->lock, flags);
-
-       /* Have to clear LPTA_EN before programming new alarm time in LPTAR */
-       lpcr = readl(data->ioaddr + SNVS_LPCR);
-       lpcr &= ~SNVS_LPCR_LPTA_EN;
-       writel(lpcr, data->ioaddr + SNVS_LPCR);
-
-       spin_unlock_irqrestore(&data->lock, flags);
-
-       writel(time, data->ioaddr + SNVS_LPTAR);
+       regmap_update_bits(data->regmap, data->offset + SNVS_LPCR, SNVS_LPCR_LPTA_EN, 0);
+       regmap_write(data->regmap, data->offset + SNVS_LPTAR, time);
 
        /* Clear alarm interrupt status bit */
-       writel(SNVS_LPSR_LPTA, data->ioaddr + SNVS_LPSR);
+       regmap_write(data->regmap, data->offset + SNVS_LPSR, SNVS_LPSR_LPTA);
 
        return snvs_rtc_alarm_irq_enable(dev, alrm->enabled);
 }
@@ -226,7 +207,7 @@ static irqreturn_t snvs_rtc_irq_handler(int irq, void *dev_id)
        u32 lpsr;
        u32 events = 0;
 
-       lpsr = readl(data->ioaddr + SNVS_LPSR);
+       regmap_read(data->regmap, data->offset + SNVS_LPSR, &lpsr);
 
        if (lpsr & SNVS_LPSR_LPTA) {
                events |= (RTC_AF | RTC_IRQF);
@@ -238,25 +219,48 @@ static irqreturn_t snvs_rtc_irq_handler(int irq, void *dev_id)
        }
 
        /* clear interrupt status */
-       writel(lpsr, data->ioaddr + SNVS_LPSR);
+       regmap_write(data->regmap, data->offset + SNVS_LPSR, lpsr);
 
        return events ? IRQ_HANDLED : IRQ_NONE;
 }
 
+static const struct regmap_config snvs_rtc_config = {
+       .reg_bits = 32,
+       .val_bits = 32,
+       .reg_stride = 4,
+};
+
 static int snvs_rtc_probe(struct platform_device *pdev)
 {
        struct snvs_rtc_data *data;
        struct resource *res;
        int ret;
+       void __iomem *mmio;
 
        data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
        if (!data)
                return -ENOMEM;
 
-       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       data->ioaddr = devm_ioremap_resource(&pdev->dev, res);
-       if (IS_ERR(data->ioaddr))
-               return PTR_ERR(data->ioaddr);
+       data->regmap = syscon_regmap_lookup_by_phandle(pdev->dev.of_node, "regmap");
+
+       if (IS_ERR(data->regmap)) {
+               dev_warn(&pdev->dev, "snvs rtc: you use old dts file, please update it\n");
+               res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+
+               mmio = devm_ioremap_resource(&pdev->dev, res);
+               if (IS_ERR(mmio))
+                       return PTR_ERR(mmio);
+
+               data->regmap = devm_regmap_init_mmio(&pdev->dev, mmio, &snvs_rtc_config);
+       } else {
+               data->offset = SNVS_LPREGISTER_OFFSET;
+               of_property_read_u32(pdev->dev.of_node, "offset", &data->offset);
+       }
+
+       if (!data->regmap) {
+               dev_err(&pdev->dev, "Can't find snvs syscon\n");
+               return -ENODEV;
+       }
 
        data->irq = platform_get_irq(pdev, 0);
        if (data->irq < 0)
@@ -276,13 +280,11 @@ static int snvs_rtc_probe(struct platform_device *pdev)
 
        platform_set_drvdata(pdev, data);
 
-       spin_lock_init(&data->lock);
-
        /* Initialize glitch detect */
-       writel(SNVS_LPPGDR_INIT, data->ioaddr + SNVS_LPPGDR);
+       regmap_write(data->regmap, data->offset + SNVS_LPPGDR, SNVS_LPPGDR_INIT);
 
        /* Clear interrupt status */
-       writel(0xffffffff, data->ioaddr + SNVS_LPSR);
+       regmap_write(data->regmap, data->offset + SNVS_LPSR, 0xffffffff);
 
        /* Enable RTC */
        snvs_rtc_enable(data, true);
index 3c18503..9d50682 100644 (file)
@@ -1,6 +1,15 @@
 #
 # MediaTek SoC drivers
 #
+config MTK_INFRACFG
+       bool "MediaTek INFRACFG Support"
+       depends on ARCH_MEDIATEK || COMPILE_TEST
+       select REGMAP
+       help
+         Say yes here to add support for the MediaTek INFRACFG controller. The
+         INFRACFG controller contains various infrastructure registers not
+         directly associated to any device.
+
 config MTK_PMIC_WRAP
        tristate "MediaTek PMIC Wrapper Support"
        depends on ARCH_MEDIATEK
@@ -10,3 +19,13 @@ config MTK_PMIC_WRAP
          Say yes here to add support for MediaTek PMIC Wrapper found
          on different MediaTek SoCs. The PMIC wrapper is a proprietary
          hardware to connect the PMIC.
+
+config MTK_SCPSYS
+       bool "MediaTek SCPSYS Support"
+       depends on ARCH_MEDIATEK || COMPILE_TEST
+       select REGMAP
+       select MTK_INFRACFG
+       select PM_GENERIC_DOMAINS if PM
+       help
+         Say yes here to add support for the MediaTek SCPSYS power domain
+         driver.
index ecaf4de..12998b0 100644 (file)
@@ -1 +1,3 @@
+obj-$(CONFIG_MTK_INFRACFG) += mtk-infracfg.o
 obj-$(CONFIG_MTK_PMIC_WRAP) += mtk-pmic-wrap.o
+obj-$(CONFIG_MTK_SCPSYS) += mtk-scpsys.o
diff --git a/drivers/soc/mediatek/mtk-infracfg.c b/drivers/soc/mediatek/mtk-infracfg.c
new file mode 100644 (file)
index 0000000..dba3055
--- /dev/null
@@ -0,0 +1,91 @@
+/*
+ * Copyright (c) 2015 Pengutronix, Sascha Hauer <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 version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/export.h>
+#include <linux/jiffies.h>
+#include <linux/regmap.h>
+#include <linux/soc/mediatek/infracfg.h>
+#include <asm/processor.h>
+
+#define INFRA_TOPAXI_PROTECTEN         0x0220
+#define INFRA_TOPAXI_PROTECTSTA1       0x0228
+
+/**
+ * mtk_infracfg_set_bus_protection - enable bus protection
+ * @regmap: The infracfg regmap
+ * @mask: The mask containing the protection bits to be enabled.
+ *
+ * This function enables the bus protection bits for disabled power
+ * domains so that the system does not hang when some unit accesses the
+ * bus while in power down.
+ */
+int mtk_infracfg_set_bus_protection(struct regmap *infracfg, u32 mask)
+{
+       unsigned long expired;
+       u32 val;
+       int ret;
+
+       regmap_update_bits(infracfg, INFRA_TOPAXI_PROTECTEN, mask, mask);
+
+       expired = jiffies + HZ;
+
+       while (1) {
+               ret = regmap_read(infracfg, INFRA_TOPAXI_PROTECTSTA1, &val);
+               if (ret)
+                       return ret;
+
+               if ((val & mask) == mask)
+                       break;
+
+               cpu_relax();
+               if (time_after(jiffies, expired))
+                       return -EIO;
+       }
+
+       return 0;
+}
+
+/**
+ * mtk_infracfg_clear_bus_protection - disable bus protection
+ * @regmap: The infracfg regmap
+ * @mask: The mask containing the protection bits to be disabled.
+ *
+ * This function disables the bus protection bits previously enabled with
+ * mtk_infracfg_set_bus_protection.
+ */
+int mtk_infracfg_clear_bus_protection(struct regmap *infracfg, u32 mask)
+{
+       unsigned long expired;
+       int ret;
+
+       regmap_update_bits(infracfg, INFRA_TOPAXI_PROTECTEN, mask, 0);
+
+       expired = jiffies + HZ;
+
+       while (1) {
+               u32 val;
+
+               ret = regmap_read(infracfg, INFRA_TOPAXI_PROTECTSTA1, &val);
+               if (ret)
+                       return ret;
+
+               if (!(val & mask))
+                       break;
+
+               cpu_relax();
+               if (time_after(jiffies, expired))
+                       return -EIO;
+       }
+
+       return 0;
+}
index f432291..8bc7b41 100644 (file)
@@ -926,7 +926,6 @@ err_out1:
 static struct platform_driver pwrap_drv = {
        .driver = {
                .name = "mt-pmic-pwrap",
-               .owner = THIS_MODULE,
                .of_match_table = of_match_ptr(of_pwrap_match_tbl),
        },
        .probe = pwrap_probe,
diff --git a/drivers/soc/mediatek/mtk-scpsys.c b/drivers/soc/mediatek/mtk-scpsys.c
new file mode 100644 (file)
index 0000000..164a7d8
--- /dev/null
@@ -0,0 +1,488 @@
+/*
+ * Copyright (c) 2015 Pengutronix, Sascha Hauer <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 version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/mfd/syscon.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/pm_domain.h>
+#include <linux/regmap.h>
+#include <linux/soc/mediatek/infracfg.h>
+#include <dt-bindings/power/mt8173-power.h>
+
+#define SPM_VDE_PWR_CON                        0x0210
+#define SPM_MFG_PWR_CON                        0x0214
+#define SPM_VEN_PWR_CON                        0x0230
+#define SPM_ISP_PWR_CON                        0x0238
+#define SPM_DIS_PWR_CON                        0x023c
+#define SPM_VEN2_PWR_CON               0x0298
+#define SPM_AUDIO_PWR_CON              0x029c
+#define SPM_MFG_2D_PWR_CON             0x02c0
+#define SPM_MFG_ASYNC_PWR_CON          0x02c4
+#define SPM_USB_PWR_CON                        0x02cc
+#define SPM_PWR_STATUS                 0x060c
+#define SPM_PWR_STATUS_2ND             0x0610
+
+#define PWR_RST_B_BIT                  BIT(0)
+#define PWR_ISO_BIT                    BIT(1)
+#define PWR_ON_BIT                     BIT(2)
+#define PWR_ON_2ND_BIT                 BIT(3)
+#define PWR_CLK_DIS_BIT                        BIT(4)
+
+#define PWR_STATUS_DISP                        BIT(3)
+#define PWR_STATUS_MFG                 BIT(4)
+#define PWR_STATUS_ISP                 BIT(5)
+#define PWR_STATUS_VDEC                        BIT(7)
+#define PWR_STATUS_VENC_LT             BIT(20)
+#define PWR_STATUS_VENC                        BIT(21)
+#define PWR_STATUS_MFG_2D              BIT(22)
+#define PWR_STATUS_MFG_ASYNC           BIT(23)
+#define PWR_STATUS_AUDIO               BIT(24)
+#define PWR_STATUS_USB                 BIT(25)
+
+enum clk_id {
+       MT8173_CLK_MM,
+       MT8173_CLK_MFG,
+       MT8173_CLK_NONE,
+       MT8173_CLK_MAX = MT8173_CLK_NONE,
+};
+
+struct scp_domain_data {
+       const char *name;
+       u32 sta_mask;
+       int ctl_offs;
+       u32 sram_pdn_bits;
+       u32 sram_pdn_ack_bits;
+       u32 bus_prot_mask;
+       enum clk_id clk_id;
+};
+
+static const struct scp_domain_data scp_domain_data[] __initconst = {
+       [MT8173_POWER_DOMAIN_VDEC] = {
+               .name = "vdec",
+               .sta_mask = PWR_STATUS_VDEC,
+               .ctl_offs = SPM_VDE_PWR_CON,
+               .sram_pdn_bits = GENMASK(11, 8),
+               .sram_pdn_ack_bits = GENMASK(12, 12),
+               .clk_id = MT8173_CLK_MM,
+       },
+       [MT8173_POWER_DOMAIN_VENC] = {
+               .name = "venc",
+               .sta_mask = PWR_STATUS_VENC,
+               .ctl_offs = SPM_VEN_PWR_CON,
+               .sram_pdn_bits = GENMASK(11, 8),
+               .sram_pdn_ack_bits = GENMASK(15, 12),
+               .clk_id = MT8173_CLK_MM,
+       },
+       [MT8173_POWER_DOMAIN_ISP] = {
+               .name = "isp",
+               .sta_mask = PWR_STATUS_ISP,
+               .ctl_offs = SPM_ISP_PWR_CON,
+               .sram_pdn_bits = GENMASK(11, 8),
+               .sram_pdn_ack_bits = GENMASK(13, 12),
+               .clk_id = MT8173_CLK_MM,
+       },
+       [MT8173_POWER_DOMAIN_MM] = {
+               .name = "mm",
+               .sta_mask = PWR_STATUS_DISP,
+               .ctl_offs = SPM_DIS_PWR_CON,
+               .sram_pdn_bits = GENMASK(11, 8),
+               .sram_pdn_ack_bits = GENMASK(12, 12),
+               .clk_id = MT8173_CLK_MM,
+               .bus_prot_mask = MT8173_TOP_AXI_PROT_EN_MM_M0 |
+                       MT8173_TOP_AXI_PROT_EN_MM_M1,
+       },
+       [MT8173_POWER_DOMAIN_VENC_LT] = {
+               .name = "venc_lt",
+               .sta_mask = PWR_STATUS_VENC_LT,
+               .ctl_offs = SPM_VEN2_PWR_CON,
+               .sram_pdn_bits = GENMASK(11, 8),
+               .sram_pdn_ack_bits = GENMASK(15, 12),
+               .clk_id = MT8173_CLK_MM,
+       },
+       [MT8173_POWER_DOMAIN_AUDIO] = {
+               .name = "audio",
+               .sta_mask = PWR_STATUS_AUDIO,
+               .ctl_offs = SPM_AUDIO_PWR_CON,
+               .sram_pdn_bits = GENMASK(11, 8),
+               .sram_pdn_ack_bits = GENMASK(15, 12),
+               .clk_id = MT8173_CLK_NONE,
+       },
+       [MT8173_POWER_DOMAIN_USB] = {
+               .name = "usb",
+               .sta_mask = PWR_STATUS_USB,
+               .ctl_offs = SPM_USB_PWR_CON,
+               .sram_pdn_bits = GENMASK(11, 8),
+               .sram_pdn_ack_bits = GENMASK(15, 12),
+               .clk_id = MT8173_CLK_NONE,
+       },
+       [MT8173_POWER_DOMAIN_MFG_ASYNC] = {
+               .name = "mfg_async",
+               .sta_mask = PWR_STATUS_MFG_ASYNC,
+               .ctl_offs = SPM_MFG_ASYNC_PWR_CON,
+               .sram_pdn_bits = GENMASK(11, 8),
+               .sram_pdn_ack_bits = 0,
+               .clk_id = MT8173_CLK_MFG,
+       },
+       [MT8173_POWER_DOMAIN_MFG_2D] = {
+               .name = "mfg_2d",
+               .sta_mask = PWR_STATUS_MFG_2D,
+               .ctl_offs = SPM_MFG_2D_PWR_CON,
+               .sram_pdn_bits = GENMASK(11, 8),
+               .sram_pdn_ack_bits = GENMASK(13, 12),
+               .clk_id = MT8173_CLK_NONE,
+       },
+       [MT8173_POWER_DOMAIN_MFG] = {
+               .name = "mfg",
+               .sta_mask = PWR_STATUS_MFG,
+               .ctl_offs = SPM_MFG_PWR_CON,
+               .sram_pdn_bits = GENMASK(13, 8),
+               .sram_pdn_ack_bits = GENMASK(21, 16),
+               .clk_id = MT8173_CLK_NONE,
+               .bus_prot_mask = MT8173_TOP_AXI_PROT_EN_MFG_S |
+                       MT8173_TOP_AXI_PROT_EN_MFG_M0 |
+                       MT8173_TOP_AXI_PROT_EN_MFG_M1 |
+                       MT8173_TOP_AXI_PROT_EN_MFG_SNOOP_OUT,
+       },
+};
+
+#define NUM_DOMAINS    ARRAY_SIZE(scp_domain_data)
+
+struct scp;
+
+struct scp_domain {
+       struct generic_pm_domain genpd;
+       struct scp *scp;
+       struct clk *clk;
+       u32 sta_mask;
+       void __iomem *ctl_addr;
+       u32 sram_pdn_bits;
+       u32 sram_pdn_ack_bits;
+       u32 bus_prot_mask;
+};
+
+struct scp {
+       struct scp_domain domains[NUM_DOMAINS];
+       struct genpd_onecell_data pd_data;
+       struct device *dev;
+       void __iomem *base;
+       struct regmap *infracfg;
+};
+
+static int scpsys_domain_is_on(struct scp_domain *scpd)
+{
+       struct scp *scp = scpd->scp;
+
+       u32 status = readl(scp->base + SPM_PWR_STATUS) & scpd->sta_mask;
+       u32 status2 = readl(scp->base + SPM_PWR_STATUS_2ND) & scpd->sta_mask;
+
+       /*
+        * A domain is on when both status bits are set. If only one is set
+        * return an error. This happens while powering up a domain
+        */
+
+       if (status && status2)
+               return true;
+       if (!status && !status2)
+               return false;
+
+       return -EINVAL;
+}
+
+static int scpsys_power_on(struct generic_pm_domain *genpd)
+{
+       struct scp_domain *scpd = container_of(genpd, struct scp_domain, genpd);
+       struct scp *scp = scpd->scp;
+       unsigned long timeout;
+       bool expired;
+       void __iomem *ctl_addr = scpd->ctl_addr;
+       u32 sram_pdn_ack = scpd->sram_pdn_ack_bits;
+       u32 val;
+       int ret;
+
+       if (scpd->clk) {
+               ret = clk_prepare_enable(scpd->clk);
+               if (ret)
+                       goto err_clk;
+       }
+
+       val = readl(ctl_addr);
+       val |= PWR_ON_BIT;
+       writel(val, ctl_addr);
+       val |= PWR_ON_2ND_BIT;
+       writel(val, ctl_addr);
+
+       /* wait until PWR_ACK = 1 */
+       timeout = jiffies + HZ;
+       expired = false;
+       while (1) {
+               ret = scpsys_domain_is_on(scpd);
+               if (ret > 0)
+                       break;
+
+               if (expired) {
+                       ret = -ETIMEDOUT;
+                       goto err_pwr_ack;
+               }
+
+               cpu_relax();
+
+               if (time_after(jiffies, timeout))
+                       expired = true;
+       }
+
+       val &= ~PWR_CLK_DIS_BIT;
+       writel(val, ctl_addr);
+
+       val &= ~PWR_ISO_BIT;
+       writel(val, ctl_addr);
+
+       val |= PWR_RST_B_BIT;
+       writel(val, ctl_addr);
+
+       val &= ~scpd->sram_pdn_bits;
+       writel(val, ctl_addr);
+
+       /* wait until SRAM_PDN_ACK all 0 */
+       timeout = jiffies + HZ;
+       expired = false;
+       while (sram_pdn_ack && (readl(ctl_addr) & sram_pdn_ack)) {
+
+               if (expired) {
+                       ret = -ETIMEDOUT;
+                       goto err_pwr_ack;
+               }
+
+               cpu_relax();
+
+               if (time_after(jiffies, timeout))
+                       expired = true;
+       }
+
+       if (scpd->bus_prot_mask) {
+               ret = mtk_infracfg_clear_bus_protection(scp->infracfg,
+                               scpd->bus_prot_mask);
+               if (ret)
+                       goto err_pwr_ack;
+       }
+
+       return 0;
+
+err_pwr_ack:
+       clk_disable_unprepare(scpd->clk);
+err_clk:
+       dev_err(scp->dev, "Failed to power on domain %s\n", genpd->name);
+
+       return ret;
+}
+
+static int scpsys_power_off(struct generic_pm_domain *genpd)
+{
+       struct scp_domain *scpd = container_of(genpd, struct scp_domain, genpd);
+       struct scp *scp = scpd->scp;
+       unsigned long timeout;
+       bool expired;
+       void __iomem *ctl_addr = scpd->ctl_addr;
+       u32 pdn_ack = scpd->sram_pdn_ack_bits;
+       u32 val;
+       int ret;
+
+       if (scpd->bus_prot_mask) {
+               ret = mtk_infracfg_set_bus_protection(scp->infracfg,
+                               scpd->bus_prot_mask);
+               if (ret)
+                       goto out;
+       }
+
+       val = readl(ctl_addr);
+       val |= scpd->sram_pdn_bits;
+       writel(val, ctl_addr);
+
+       /* wait until SRAM_PDN_ACK all 1 */
+       timeout = jiffies + HZ;
+       expired = false;
+       while (pdn_ack && (readl(ctl_addr) & pdn_ack) != pdn_ack) {
+               if (expired) {
+                       ret = -ETIMEDOUT;
+                       goto out;
+               }
+
+               cpu_relax();
+
+               if (time_after(jiffies, timeout))
+                       expired = true;
+       }
+
+       val |= PWR_ISO_BIT;
+       writel(val, ctl_addr);
+
+       val &= ~PWR_RST_B_BIT;
+       writel(val, ctl_addr);
+
+       val |= PWR_CLK_DIS_BIT;
+       writel(val, ctl_addr);
+
+       val &= ~PWR_ON_BIT;
+       writel(val, ctl_addr);
+
+       val &= ~PWR_ON_2ND_BIT;
+       writel(val, ctl_addr);
+
+       /* wait until PWR_ACK = 0 */
+       timeout = jiffies + HZ;
+       expired = false;
+       while (1) {
+               ret = scpsys_domain_is_on(scpd);
+               if (ret == 0)
+                       break;
+
+               if (expired) {
+                       ret = -ETIMEDOUT;
+                       goto out;
+               }
+
+               cpu_relax();
+
+               if (time_after(jiffies, timeout))
+                       expired = true;
+       }
+
+       if (scpd->clk)
+               clk_disable_unprepare(scpd->clk);
+
+       return 0;
+
+out:
+       dev_err(scp->dev, "Failed to power off domain %s\n", genpd->name);
+
+       return ret;
+}
+
+static int __init scpsys_probe(struct platform_device *pdev)
+{
+       struct genpd_onecell_data *pd_data;
+       struct resource *res;
+       int i, ret;
+       struct scp *scp;
+       struct clk *clk[MT8173_CLK_MAX];
+
+       scp = devm_kzalloc(&pdev->dev, sizeof(*scp), GFP_KERNEL);
+       if (!scp)
+               return -ENOMEM;
+
+       scp->dev = &pdev->dev;
+
+       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       scp->base = devm_ioremap_resource(&pdev->dev, res);
+       if (IS_ERR(scp->base))
+               return PTR_ERR(scp->base);
+
+       pd_data = &scp->pd_data;
+
+       pd_data->domains = devm_kzalloc(&pdev->dev,
+                       sizeof(*pd_data->domains) * NUM_DOMAINS, GFP_KERNEL);
+       if (!pd_data->domains)
+               return -ENOMEM;
+
+       clk[MT8173_CLK_MM] = devm_clk_get(&pdev->dev, "mm");
+       if (IS_ERR(clk[MT8173_CLK_MM]))
+               return PTR_ERR(clk[MT8173_CLK_MM]);
+
+       clk[MT8173_CLK_MFG] = devm_clk_get(&pdev->dev, "mfg");
+       if (IS_ERR(clk[MT8173_CLK_MFG]))
+               return PTR_ERR(clk[MT8173_CLK_MFG]);
+
+       scp->infracfg = syscon_regmap_lookup_by_phandle(pdev->dev.of_node,
+                       "infracfg");
+       if (IS_ERR(scp->infracfg)) {
+               dev_err(&pdev->dev, "Cannot find infracfg controller: %ld\n",
+                               PTR_ERR(scp->infracfg));
+               return PTR_ERR(scp->infracfg);
+       }
+
+       pd_data->num_domains = NUM_DOMAINS;
+
+       for (i = 0; i < NUM_DOMAINS; i++) {
+               struct scp_domain *scpd = &scp->domains[i];
+               struct generic_pm_domain *genpd = &scpd->genpd;
+               const struct scp_domain_data *data = &scp_domain_data[i];
+
+               pd_data->domains[i] = genpd;
+               scpd->scp = scp;
+
+               scpd->sta_mask = data->sta_mask;
+               scpd->ctl_addr = scp->base + data->ctl_offs;
+               scpd->sram_pdn_bits = data->sram_pdn_bits;
+               scpd->sram_pdn_ack_bits = data->sram_pdn_ack_bits;
+               scpd->bus_prot_mask = data->bus_prot_mask;
+               if (data->clk_id != MT8173_CLK_NONE)
+                       scpd->clk = clk[data->clk_id];
+
+               genpd->name = data->name;
+               genpd->power_off = scpsys_power_off;
+               genpd->power_on = scpsys_power_on;
+
+               /*
+                * Initially turn on all domains to make the domains usable
+                * with !CONFIG_PM and to get the hardware in sync with the
+                * software.  The unused domains will be switched off during
+                * late_init time.
+                */
+               genpd->power_on(genpd);
+
+               pm_genpd_init(genpd, NULL, false);
+       }
+
+       /*
+        * We are not allowed to fail here since there is no way to unregister
+        * a power domain. Once registered above we have to keep the domains
+        * valid.
+        */
+
+       ret = pm_genpd_add_subdomain(pd_data->domains[MT8173_POWER_DOMAIN_MFG_ASYNC],
+               pd_data->domains[MT8173_POWER_DOMAIN_MFG_2D]);
+       if (ret && IS_ENABLED(CONFIG_PM))
+               dev_err(&pdev->dev, "Failed to add subdomain: %d\n", ret);
+
+       ret = pm_genpd_add_subdomain(pd_data->domains[MT8173_POWER_DOMAIN_MFG_2D],
+               pd_data->domains[MT8173_POWER_DOMAIN_MFG]);
+       if (ret && IS_ENABLED(CONFIG_PM))
+               dev_err(&pdev->dev, "Failed to add subdomain: %d\n", ret);
+
+       ret = of_genpd_add_provider_onecell(pdev->dev.of_node, pd_data);
+       if (ret)
+               dev_err(&pdev->dev, "Failed to add OF provider: %d\n", ret);
+
+       return 0;
+}
+
+static const struct of_device_id of_scpsys_match_tbl[] = {
+       {
+               .compatible = "mediatek,mt8173-scpsys",
+       }, {
+               /* sentinel */
+       }
+};
+
+static struct platform_driver scpsys_drv = {
+       .driver = {
+               .name = "mtk-scpsys",
+               .owner = THIS_MODULE,
+               .of_match_table = of_match_ptr(of_scpsys_match_tbl),
+       },
+};
+
+module_platform_driver_probe(scpsys_drv, scpsys_probe);
diff --git a/include/dt-bindings/power/mt8173-power.h b/include/dt-bindings/power/mt8173-power.h
new file mode 100644 (file)
index 0000000..b34cee9
--- /dev/null
@@ -0,0 +1,15 @@
+#ifndef _DT_BINDINGS_POWER_MT8183_POWER_H
+#define _DT_BINDINGS_POWER_MT8183_POWER_H
+
+#define MT8173_POWER_DOMAIN_VDEC       0
+#define MT8173_POWER_DOMAIN_VENC       1
+#define MT8173_POWER_DOMAIN_ISP                2
+#define MT8173_POWER_DOMAIN_MM         3
+#define MT8173_POWER_DOMAIN_VENC_LT    4
+#define MT8173_POWER_DOMAIN_AUDIO      5
+#define MT8173_POWER_DOMAIN_USB                6
+#define MT8173_POWER_DOMAIN_MFG_ASYNC  7
+#define MT8173_POWER_DOMAIN_MFG_2D     8
+#define MT8173_POWER_DOMAIN_MFG                9
+
+#endif /* _DT_BINDINGS_POWER_MT8183_POWER_H */
index 9299222..223be69 100644 (file)
@@ -263,7 +263,8 @@ void omap2_clk_legacy_provider_init(int index, void __iomem *mem);
 int omap3430_dt_clk_init(void);
 int omap3630_dt_clk_init(void);
 int am35xx_dt_clk_init(void);
-int ti81xx_dt_clk_init(void);
+int dm814x_dt_clk_init(void);
+int dm816x_dt_clk_init(void);
 int omap4xxx_dt_clk_init(void);
 int omap5xxx_dt_clk_init(void);
 int dra7xx_dt_clk_init(void);
index d16f4c8..558a485 100644 (file)
 #define IMX6SX_GPR5_DISP_MUX_DCIC1_LVDS                        (0x1 << 1)
 #define IMX6SX_GPR5_DISP_MUX_DCIC1_MASK                        (0x1 << 1)
 
+/* For imx6ul iomux gpr register field define */
+#define IMX6UL_GPR1_ENET1_CLK_DIR              (0x1 << 17)
+#define IMX6UL_GPR1_ENET2_CLK_DIR              (0x1 << 18)
+#define IMX6UL_GPR1_ENET1_CLK_OUTPUT           (0x1 << 17)
+#define IMX6UL_GPR1_ENET2_CLK_OUTPUT           (0x1 << 18)
+#define IMX6UL_GPR1_ENET_CLK_DIR               (0x3 << 17)
+#define IMX6UL_GPR1_ENET_CLK_OUTPUT            (0x3 << 17)
+
 #endif /* __LINUX_IMX6Q_IOMUXC_GPR_H */
diff --git a/include/linux/soc/mediatek/infracfg.h b/include/linux/soc/mediatek/infracfg.h
new file mode 100644 (file)
index 0000000..a5714e9
--- /dev/null
@@ -0,0 +1,26 @@
+#ifndef __SOC_MEDIATEK_INFRACFG_H
+#define __SOC_MEDIATEK_INFRACFG_H
+
+#define MT8173_TOP_AXI_PROT_EN_MCI_M2          BIT(0)
+#define MT8173_TOP_AXI_PROT_EN_MM_M0           BIT(1)
+#define MT8173_TOP_AXI_PROT_EN_MM_M1           BIT(2)
+#define MT8173_TOP_AXI_PROT_EN_MMAPB_S         BIT(6)
+#define MT8173_TOP_AXI_PROT_EN_L2C_M2          BIT(9)
+#define MT8173_TOP_AXI_PROT_EN_L2SS_SMI                BIT(11)
+#define MT8173_TOP_AXI_PROT_EN_L2SS_ADD                BIT(12)
+#define MT8173_TOP_AXI_PROT_EN_CCI_M2          BIT(13)
+#define MT8173_TOP_AXI_PROT_EN_MFG_S           BIT(14)
+#define MT8173_TOP_AXI_PROT_EN_PERI_M0         BIT(15)
+#define MT8173_TOP_AXI_PROT_EN_PERI_M1         BIT(16)
+#define MT8173_TOP_AXI_PROT_EN_DEBUGSYS                BIT(17)
+#define MT8173_TOP_AXI_PROT_EN_CQ_DMA          BIT(18)
+#define MT8173_TOP_AXI_PROT_EN_GCPU            BIT(19)
+#define MT8173_TOP_AXI_PROT_EN_IOMMU           BIT(20)
+#define MT8173_TOP_AXI_PROT_EN_MFG_M0          BIT(21)
+#define MT8173_TOP_AXI_PROT_EN_MFG_M1          BIT(22)
+#define MT8173_TOP_AXI_PROT_EN_MFG_SNOOP_OUT   BIT(23)
+
+int mtk_infracfg_set_bus_protection(struct regmap *infracfg, u32 mask);
+int mtk_infracfg_clear_bus_protection(struct regmap *infracfg, u32 mask);
+
+#endif /* __SOC_MEDIATEK_INFRACFG_H */