aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2014-12-09 17:38:28 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2014-12-09 17:38:28 -0500
commit6cd94d5e57ab97ddd672b707ab4bb639672c1727 (patch)
treeb1b301b16433d4deab6bd52e81d04a7b58c239d3
parent6c9e92476bc924ede6d6d2f0bfed2c06ae148d29 (diff)
parent842f7d2c4d392c0571cf72e3eaca26742bebbd1e (diff)
Merge tag 'soc-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc
Pull ARM SoC platform changes from Arnd Bergmann: "New and updated SoC support, notable changes include: - bcm: brcmstb SMP support initial iproc/cygnus support - exynos: Exynos4415 SoC support PMU and suspend support for Exynos5420 PMU support for Exynos3250 pm related maintenance - imx: new LS1021A SoC support vybrid 610 global timer support - integrator: convert to using multiplatform configuration - mediatek: earlyprintk support for mt8127/mt8135 - meson: meson8 soc and l2 cache controller support - mvebu: Armada 38x CPU hotplug support drop support for prerelease Armada 375 Z1 stepping extended suspend support, now works on Armada 370/XP - omap: hwmod related maintenance prcm cleanup - pxa: initial pxa27x DT handling - rockchip: SMP support for rk3288 add cpu frequency scaling support - shmobile: r8a7740 power domain support various small restart, timer, pci apmu changes - sunxi: Allwinner A80 (sun9i) earlyprintk support - ux500: power domain support Overall, a significant chunk of changes, coming mostly from the usual suspects: omap, shmobile, samsung and mvebu, all of which already contain a lot of platform specific code in arch/arm" * tag 'soc-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc: (187 commits) ARM: mvebu: use the cpufreq-dt platform_data for independent clocks soc: integrator: Add terminating entry for integrator_cm_match ARM: mvebu: add SDRAM controller description for Armada XP ARM: mvebu: adjust mbus controller description on Armada 370/XP ARM: mvebu: add suspend/resume DT information for Armada XP GP ARM: mvebu: synchronize secondary CPU clocks on resume ARM: mvebu: make sure MMU is disabled in armada_370_xp_cpu_resume ARM: mvebu: Armada XP GP specific suspend/resume code ARM: mvebu: reserve the first 10 KB of each memory bank for suspend/resume ARM: mvebu: implement suspend/resume support for Armada XP clk: mvebu: add suspend/resume for gatable clocks bus: mvebu-mbus: provide a mechanism to save SDRAM window configuration bus: mvebu-mbus: suspend/resume support clocksource: time-armada-370-xp: add suspend/resume support irqchip: armada-370-xp: Add suspend/resume support ARM: add lolevel debug support for asm9260 ARM: add mach-asm9260 ARM: EXYNOS: use u8 for val[] in struct exynos_pmu_conf power: reset: imx-snvs-poweroff: add power off driver for i.mx6 ARM: imx: temporarily remove CONFIG_SOC_FSL from LS1021A ...
-rw-r--r--Documentation/arm/firmware.txt28
-rw-r--r--Documentation/arm/sunxi/README16
-rw-r--r--Documentation/devicetree/bindings/arm/amlogic.txt8
-rw-r--r--Documentation/devicetree/bindings/arm/cpus.txt9
-rw-r--r--Documentation/devicetree/bindings/arm/sunxi.txt12
-rw-r--r--Documentation/devicetree/bindings/arm/ux500/power_domain.txt35
-rw-r--r--Documentation/devicetree/bindings/bus/mvebu-mbus.txt17
-rw-r--r--Documentation/devicetree/bindings/memory-controllers/mvebu-sdram-controller.txt21
-rw-r--r--Documentation/devicetree/bindings/power_supply/imx-snvs-poweroff.txt23
-rw-r--r--Documentation/devicetree/bindings/vendor-prefixes.txt1
-rw-r--r--MAINTAINERS1
-rw-r--r--arch/arm/Kconfig20
-rw-r--r--arch/arm/Kconfig.debug167
-rw-r--r--arch/arm/boot/dts/armada-370-xp.dtsi3
-rw-r--r--arch/arm/boot/dts/armada-xp-gp.dts19
-rw-r--r--arch/arm/boot/dts/armada-xp.dtsi5
-rw-r--r--arch/arm/boot/dts/integrator.dtsi48
-rw-r--r--arch/arm/boot/dts/omap3-cm-t3x30.dtsi17
-rw-r--r--arch/arm/boot/dts/omap4.dtsi2
-rw-r--r--arch/arm/boot/dts/omap44xx-clocks.dtsi8
-rw-r--r--arch/arm/boot/dts/ste-dbx5x0.dtsi22
-rw-r--r--arch/arm/configs/bcm_defconfig3
-rw-r--r--arch/arm/configs/integrator_defconfig3
-rw-r--r--arch/arm/include/asm/firmware.h10
-rw-r--r--arch/arm/include/debug/asm9260.S29
-rw-r--r--arch/arm/include/debug/renesas-scif.S52
-rw-r--r--arch/arm/include/debug/sa1100.S (renamed from arch/arm/mach-sa1100/include/mach/debug-macro.S)10
-rw-r--r--arch/arm/mach-asm9260/Kconfig6
-rw-r--r--arch/arm/mach-bcm/Kconfig96
-rw-r--r--arch/arm/mach-bcm/Makefile5
-rw-r--r--arch/arm/mach-bcm/bcm_cygnus.c25
-rw-r--r--arch/arm/mach-bcm/brcmstb.h19
-rw-r--r--arch/arm/mach-bcm/headsmp-brcmstb.S33
-rw-r--r--arch/arm/mach-bcm/platsmp-brcmstb.c329
-rw-r--r--arch/arm/mach-berlin/Kconfig3
-rw-r--r--arch/arm/mach-exynos/Kconfig11
-rw-r--r--arch/arm/mach-exynos/Makefile4
-rw-r--r--arch/arm/mach-exynos/common.h31
-rw-r--r--arch/arm/mach-exynos/exynos-pmu.h24
-rw-r--r--arch/arm/mach-exynos/exynos.c30
-rw-r--r--arch/arm/mach-exynos/firmware.c67
-rw-r--r--arch/arm/mach-exynos/mcpm-exynos.c32
-rw-r--r--arch/arm/mach-exynos/platsmp.c35
-rw-r--r--arch/arm/mach-exynos/pm.c311
-rw-r--r--arch/arm/mach-exynos/pmu.c669
-rw-r--r--arch/arm/mach-exynos/regs-pmu.h358
-rw-r--r--arch/arm/mach-exynos/sleep.S28
-rw-r--r--arch/arm/mach-exynos/smc.h4
-rw-r--r--arch/arm/mach-exynos/suspend.c566
-rw-r--r--arch/arm/mach-imx/Kconfig31
-rw-r--r--arch/arm/mach-imx/Makefile6
-rw-r--r--arch/arm/mach-imx/anatop.c34
-rw-r--r--arch/arm/mach-imx/clk-cpu.c107
-rw-r--r--arch/arm/mach-imx/clk-imx51-imx53.c14
-rw-r--r--arch/arm/mach-imx/clk-vf610.c21
-rw-r--r--arch/arm/mach-imx/clk.h4
-rw-r--r--arch/arm/mach-imx/common.h2
-rw-r--r--arch/arm/mach-imx/mach-imx53.c2
-rw-r--r--arch/arm/mach-imx/mach-imx6sx.c51
-rw-r--r--arch/arm/mach-imx/mach-ls1021a.c22
-rw-r--r--arch/arm/mach-imx/mmdc.c17
-rw-r--r--arch/arm/mach-imx/mxc.h2
-rw-r--r--arch/arm/mach-imx/platsmp.c33
-rw-r--r--arch/arm/mach-imx/pm-imx6.c10
-rw-r--r--arch/arm/mach-imx/suspend-imx6.S14
-rw-r--r--arch/arm/mach-integrator/Kconfig23
-rw-r--r--arch/arm/mach-integrator/Makefile2
-rw-r--r--arch/arm/mach-integrator/cm.h1
-rw-r--r--arch/arm/mach-integrator/common.h2
-rw-r--r--arch/arm/mach-integrator/core.c103
-rw-r--r--arch/arm/mach-integrator/include/mach/uncompress.h48
-rw-r--r--arch/arm/mach-integrator/integrator_ap.c218
-rw-r--r--arch/arm/mach-integrator/integrator_cp.c28
-rw-r--r--arch/arm/mach-integrator/leds.c124
-rw-r--r--arch/arm/mach-mediatek/Kconfig4
-rw-r--r--arch/arm/mach-meson/Kconfig6
-rw-r--r--arch/arm/mach-meson/meson.c10
-rw-r--r--arch/arm/mach-mvebu/Makefile2
-rw-r--r--arch/arm/mach-mvebu/armada-370-xp.h6
-rw-r--r--arch/arm/mach-mvebu/board-v7.c122
-rw-r--r--arch/arm/mach-mvebu/coherency.c221
-rw-r--r--arch/arm/mach-mvebu/coherency_ll.S21
-rw-r--r--arch/arm/mach-mvebu/common.h2
-rw-r--r--arch/arm/mach-mvebu/cpu-reset.c1
-rw-r--r--arch/arm/mach-mvebu/headsmp-a9.S1
-rw-r--r--arch/arm/mach-mvebu/platsmp-a9.c53
-rw-r--r--arch/arm/mach-mvebu/platsmp.c33
-rw-r--r--arch/arm/mach-mvebu/pm-board.c141
-rw-r--r--arch/arm/mach-mvebu/pm.c218
-rw-r--r--arch/arm/mach-mvebu/pmsu.c11
-rw-r--r--arch/arm/mach-mvebu/pmsu.h3
-rw-r--r--arch/arm/mach-mvebu/pmsu_ll.S28
-rw-r--r--arch/arm/mach-omap2/Makefile2
-rw-r--r--arch/arm/mach-omap2/am33xx-restart.c12
-rw-r--r--arch/arm/mach-omap2/cclock3xxx_data.c6
-rw-r--r--arch/arm/mach-omap2/clock.c7
-rw-r--r--arch/arm/mach-omap2/clock.h1
-rw-r--r--arch/arm/mach-omap2/clock3xxx.c38
-rw-r--r--arch/arm/mach-omap2/cm.h18
-rw-r--r--arch/arm/mach-omap2/cm1_44xx.h2
-rw-r--r--arch/arm/mach-omap2/cm1_54xx.h2
-rw-r--r--arch/arm/mach-omap2/cm1_7xx.h2
-rw-r--r--arch/arm/mach-omap2/cm2_44xx.h2
-rw-r--r--arch/arm/mach-omap2/cm2_54xx.h2
-rw-r--r--arch/arm/mach-omap2/cm2_7xx.h2
-rw-r--r--arch/arm/mach-omap2/cm2xxx.c17
-rw-r--r--arch/arm/mach-omap2/cm2xxx.h10
-rw-r--r--arch/arm/mach-omap2/cm33xx.c61
-rw-r--r--arch/arm/mach-omap2/cm33xx.h37
-rw-r--r--arch/arm/mach-omap2/cm3xxx.c19
-rw-r--r--arch/arm/mach-omap2/cm3xxx.h12
-rw-r--r--arch/arm/mach-omap2/cm44xx.c49
-rw-r--r--arch/arm/mach-omap2/cm44xx.h3
-rw-r--r--arch/arm/mach-omap2/cm_44xx_54xx.h36
-rw-r--r--arch/arm/mach-omap2/cm_common.c82
-rw-r--r--arch/arm/mach-omap2/cminst44xx.c80
-rw-r--r--arch/arm/mach-omap2/cminst44xx.h43
-rw-r--r--arch/arm/mach-omap2/dpll3xxx.c179
-rw-r--r--arch/arm/mach-omap2/dpll44xx.c41
-rw-r--r--arch/arm/mach-omap2/io.c11
-rw-r--r--arch/arm/mach-omap2/omap-mpuss-lowpower.c4
-rw-r--r--arch/arm/mach-omap2/omap2-restart.c5
-rw-r--r--arch/arm/mach-omap2/omap3-restart.c7
-rw-r--r--arch/arm/mach-omap2/omap4-restart.c6
-rw-r--r--arch/arm/mach-omap2/omap_hwmod.c272
-rw-r--r--arch/arm/mach-omap2/omap_hwmod.h8
-rw-r--r--arch/arm/mach-omap2/omap_hwmod_43xx_data.c39
-rw-r--r--arch/arm/mach-omap2/omap_hwmod_44xx_data.c25
-rw-r--r--arch/arm/mach-omap2/omap_hwmod_54xx_data.c5
-rw-r--r--arch/arm/mach-omap2/omap_hwmod_7xx_data.c100
-rw-r--r--arch/arm/mach-omap2/pm44xx.c146
-rw-r--r--arch/arm/mach-omap2/prm.h16
-rw-r--r--arch/arm/mach-omap2/prm2xxx.c6
-rw-r--r--arch/arm/mach-omap2/prm2xxx.h1
-rw-r--r--arch/arm/mach-omap2/prm2xxx_3xxx.c19
-rw-r--r--arch/arm/mach-omap2/prm2xxx_3xxx.h9
-rw-r--r--arch/arm/mach-omap2/prm33xx.c64
-rw-r--r--arch/arm/mach-omap2/prm33xx.h11
-rw-r--r--arch/arm/mach-omap2/prm3xxx.c32
-rw-r--r--arch/arm/mach-omap2/prm3xxx.h16
-rw-r--r--arch/arm/mach-omap2/prm44xx.c36
-rw-r--r--arch/arm/mach-omap2/prm44xx_54xx.h19
-rw-r--r--arch/arm/mach-omap2/prm_common.c99
-rw-r--r--arch/arm/mach-omap2/prminst44xx.c10
-rw-r--r--arch/arm/mach-omap2/prminst44xx.h5
-rw-r--r--arch/arm/mach-pxa/Kconfig11
-rw-r--r--arch/arm/mach-pxa/Makefile1
-rw-r--r--arch/arm/mach-pxa/em-x270.c4
-rw-r--r--arch/arm/mach-pxa/generic.h65
-rw-r--r--arch/arm/mach-pxa/gumstix.c3
-rw-r--r--arch/arm/mach-pxa/include/mach/pxa25x.h8
-rw-r--r--arch/arm/mach-pxa/include/mach/pxa27x.h4
-rw-r--r--arch/arm/mach-pxa/include/mach/pxa3xx.h5
-rw-r--r--arch/arm/mach-pxa/mfp-pxa2xx.c12
-rw-r--r--arch/arm/mach-pxa/poodle.c2
-rw-r--r--arch/arm/mach-pxa/pxa-dt.c18
-rw-r--r--arch/arm/mach-pxa/pxa27x.c6
-rw-r--r--arch/arm/mach-pxa/pxa3xx-ulpi.c6
-rw-r--r--arch/arm/mach-pxa/raumfeld.c26
-rw-r--r--arch/arm/mach-pxa/tosa.c41
-rw-r--r--arch/arm/mach-rockchip/headsmp.S5
-rw-r--r--arch/arm/mach-rockchip/platsmp.c223
-rw-r--r--arch/arm/mach-rockchip/rockchip.c7
-rw-r--r--arch/arm/mach-shmobile/Kconfig2
-rw-r--r--arch/arm/mach-shmobile/Makefile1
-rw-r--r--arch/arm/mach-shmobile/board-armadillo800eva.c12
-rw-r--r--arch/arm/mach-shmobile/board-kzm9g-reference.c8
-rw-r--r--arch/arm/mach-shmobile/common.h5
-rw-r--r--arch/arm/mach-shmobile/platsmp-apmu.c27
-rw-r--r--arch/arm/mach-shmobile/platsmp-apmu.h32
-rw-r--r--arch/arm/mach-shmobile/pm-r8a7740.c44
-rw-r--r--arch/arm/mach-shmobile/setup-r8a7740.c12
-rw-r--r--arch/arm/mach-shmobile/setup-r8a7779.c1
-rw-r--r--arch/arm/mach-shmobile/setup-rcar-gen2.c72
-rw-r--r--arch/arm/mach-shmobile/setup-sh7372.c2
-rw-r--r--arch/arm/mach-shmobile/setup-sh73a0.c9
-rw-r--r--arch/arm/mach-shmobile/smp-r8a7790.c16
-rw-r--r--arch/arm/mach-shmobile/smp-r8a7791.c12
-rw-r--r--arch/arm/mach-shmobile/timer.c23
-rw-r--r--arch/arm/mach-socfpga/core.h3
-rw-r--r--arch/arm/mach-socfpga/platsmp.c19
-rw-r--r--arch/arm/mach-sunxi/Kconfig7
-rw-r--r--arch/arm/mach-sunxi/platsmp.c2
-rw-r--r--arch/arm/mach-sunxi/sunxi.c9
-rw-r--r--arch/arm/mach-tegra/cpuidle-tegra114.c2
-rw-r--r--arch/arm/mach-u300/dummyspichip.c65
-rw-r--r--arch/arm/mach-ux500/Kconfig1
-rw-r--r--arch/arm/mach-ux500/Makefile1
-rw-r--r--arch/arm/mach-ux500/pm.c4
-rw-r--r--arch/arm/mach-ux500/pm_domains.c79
-rw-r--r--arch/arm/mach-ux500/pm_domains.h17
-rw-r--r--arch/arm/mm/Kconfig28
-rw-r--r--arch/arm/plat-samsung/Makefile1
-rw-r--r--drivers/bus/brcmstb_gisb.c45
-rw-r--r--drivers/bus/mvebu-mbus.c180
-rw-r--r--drivers/clk/mvebu/common.c32
-rw-r--r--drivers/clk/samsung/clk-exynos5440.c29
-rw-r--r--drivers/clk/ti/dpll.c15
-rw-r--r--drivers/clocksource/Kconfig1
-rw-r--r--drivers/clocksource/Makefile1
-rw-r--r--drivers/clocksource/time-armada-370-xp.c25
-rw-r--r--drivers/clocksource/timer-integrator-ap.c210
-rw-r--r--drivers/irqchip/irq-armada-370-xp.c52
-rw-r--r--drivers/power/reset/Kconfig9
-rw-r--r--drivers/power/reset/Makefile1
-rw-r--r--drivers/power/reset/imx-snvs-poweroff.c66
-rw-r--r--drivers/soc/versatile/Kconfig9
-rw-r--r--drivers/soc/versatile/Makefile1
-rw-r--r--drivers/soc/versatile/soc-integrator.c155
-rw-r--r--include/dt-bindings/arm/ux500_pm_domains.h15
-rw-r--r--include/dt-bindings/clock/imx5-clock.h5
-rw-r--r--include/linux/clk/ti.h15
-rw-r--r--include/linux/mbus.h1
-rw-r--r--include/linux/mfd/syscon/imx6q-iomuxc-gpr.h39
214 files changed, 6329 insertions, 2353 deletions
diff --git a/Documentation/arm/firmware.txt b/Documentation/arm/firmware.txt
index c2e468fe7b0b..da6713adac8a 100644
--- a/Documentation/arm/firmware.txt
+++ b/Documentation/arm/firmware.txt
@@ -7,32 +7,14 @@ world, which changes the way some things have to be initialized. This makes
7a need to provide an interface for such platforms to specify available firmware 7a need to provide an interface for such platforms to specify available firmware
8operations and call them when needed. 8operations and call them when needed.
9 9
10Firmware operations can be specified using struct firmware_ops 10Firmware operations can be specified by filling in a struct firmware_ops
11 11with appropriate callbacks and then registering it with register_firmware_ops()
12 struct firmware_ops { 12function.
13 /*
14 * Enters CPU idle mode
15 */
16 int (*do_idle)(void);
17 /*
18 * Sets boot address of specified physical CPU
19 */
20 int (*set_cpu_boot_addr)(int cpu, unsigned long boot_addr);
21 /*
22 * Boots specified physical CPU
23 */
24 int (*cpu_boot)(int cpu);
25 /*
26 * Initializes L2 cache
27 */
28 int (*l2x0_init)(void);
29 };
30
31and then registered with register_firmware_ops function
32 13
33 void register_firmware_ops(const struct firmware_ops *ops) 14 void register_firmware_ops(const struct firmware_ops *ops)
34 15
35the ops pointer must be non-NULL. 16The ops pointer must be non-NULL. More information about struct firmware_ops
17and its members can be found in arch/arm/include/asm/firmware.h header.
36 18
37There is a default, empty set of operations provided, so there is no need to 19There is a default, empty set of operations provided, so there is no need to
38set anything if platform does not require firmware operations. 20set anything if platform does not require firmware operations.
diff --git a/Documentation/arm/sunxi/README b/Documentation/arm/sunxi/README
index 7945238453ed..e68d163df33d 100644
--- a/Documentation/arm/sunxi/README
+++ b/Documentation/arm/sunxi/README
@@ -37,16 +37,26 @@ SunXi family
37 http://dl.linux-sunxi.org/A20/A20%20User%20Manual%202013-03-22.pdf 37 http://dl.linux-sunxi.org/A20/A20%20User%20Manual%202013-03-22.pdf
38 38
39 - Allwinner A23 39 - Allwinner A23
40 + Not Supported 40 + Datasheet
41 http://dl.linux-sunxi.org/A23/A23%20Datasheet%20V1.0%2020130830.pdf
42 + User Manual
43 http://dl.linux-sunxi.org/A23/A23%20User%20Manual%20V1.0%2020130830.pdf
41 44
42 * Quad ARM Cortex-A7 based SoCs 45 * Quad ARM Cortex-A7 based SoCs
43 - Allwinner A31 (sun6i) 46 - Allwinner A31 (sun6i)
44 + Datasheet 47 + Datasheet
45 http://dl.linux-sunxi.org/A31/A31%20Datasheet%20-%20v1.00%20(2012-12-24).pdf 48 http://dl.linux-sunxi.org/A31/A3x_release_document/A31/IC/A31%20datasheet%20V1.3%2020131106.pdf
49 + User Manual
50 http://dl.linux-sunxi.org/A31/A3x_release_document/A31/IC/A31%20user%20manual%20V1.1%2020130630.pdf
46 51
47 - Allwinner A31s (sun6i) 52 - Allwinner A31s (sun6i)
48 + Not Supported 53 + Not Supported
54 + Datasheet
55 http://dl.linux-sunxi.org/A31/A3x_release_document/A31s/IC/A31s%20datasheet%20V1.3%2020131106.pdf
56 + User Manual
57 http://dl.linux-sunxi.org/A31/A3x_release_document/A31s/IC/A31s%20User%20Manual%20%20V1.0%2020130322.pdf
49 58
50 * Quad ARM Cortex-A15, Quad ARM Cortex-A7 based SoCs 59 * Quad ARM Cortex-A15, Quad ARM Cortex-A7 based SoCs
51 - Allwinner A80 60 - Allwinner A80
52 + Not Supported \ No newline at end of file 61 + Datasheet
62 http://dl.linux-sunxi.org/A80/A80_Datasheet_Revision_1.0_0404.pdf
diff --git a/Documentation/devicetree/bindings/arm/amlogic.txt b/Documentation/devicetree/bindings/arm/amlogic.txt
index 7eece72b1a35..8fe815046140 100644
--- a/Documentation/devicetree/bindings/arm/amlogic.txt
+++ b/Documentation/devicetree/bindings/arm/amlogic.txt
@@ -2,7 +2,9 @@ Amlogic MesonX device tree bindings
2------------------------------------------- 2-------------------------------------------
3 3
4Boards with the Amlogic Meson6 SoC shall have the following properties: 4Boards with the Amlogic Meson6 SoC shall have the following properties:
5 Required root node property:
6 compatible: "amlogic,meson6"
5 7
6Required root node property: 8Boards with the Amlogic Meson8 SoC shall have the following properties:
7 9 Required root node property:
8compatible = "amlogic,meson6"; 10 compatible: "amlogic,meson8";
diff --git a/Documentation/devicetree/bindings/arm/cpus.txt b/Documentation/devicetree/bindings/arm/cpus.txt
index fc446347ab6d..b2aacbe16ed9 100644
--- a/Documentation/devicetree/bindings/arm/cpus.txt
+++ b/Documentation/devicetree/bindings/arm/cpus.txt
@@ -227,6 +227,15 @@ nodes to be present and contain the properties described below.
227 # List of phandles to idle state nodes supported 227 # List of phandles to idle state nodes supported
228 by this cpu [3]. 228 by this cpu [3].
229 229
230 - rockchip,pmu
231 Usage: optional for systems that have an "enable-method"
232 property value of "rockchip,rk3066-smp"
233 While optional, it is the preferred way to get access to
234 the cpu-core power-domains.
235 Value type: <phandle>
236 Definition: Specifies the syscon node controlling the cpu core
237 power domains.
238
230Example 1 (dual-cluster big.LITTLE system 32-bit): 239Example 1 (dual-cluster big.LITTLE system 32-bit):
231 240
232 cpus { 241 cpus {
diff --git a/Documentation/devicetree/bindings/arm/sunxi.txt b/Documentation/devicetree/bindings/arm/sunxi.txt
new file mode 100644
index 000000000000..42941fdefb11
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/sunxi.txt
@@ -0,0 +1,12 @@
1Allwinner sunXi Platforms Device Tree Bindings
2
3Each device tree must specify which Allwinner SoC it uses,
4using one of the following compatible strings:
5
6 allwinner,sun4i-a10
7 allwinner,sun5i-a10s
8 allwinner,sun5i-a13
9 allwinner,sun6i-a31
10 allwinner,sun7i-a20
11 allwinner,sun8i-a23
12 allwinner,sun9i-a80
diff --git a/Documentation/devicetree/bindings/arm/ux500/power_domain.txt b/Documentation/devicetree/bindings/arm/ux500/power_domain.txt
new file mode 100644
index 000000000000..5679d1742d3e
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/ux500/power_domain.txt
@@ -0,0 +1,35 @@
1* ST-Ericsson UX500 PM Domains
2
3UX500 supports multiple PM domains which are used to gate power to one or
4more peripherals on the SOC.
5
6The implementation of PM domains for UX500 are based upon the generic PM domain
7and use the corresponding DT bindings.
8
9==PM domain providers==
10
11Required properties:
12 - compatible: Must be "stericsson,ux500-pm-domains".
13 - #power-domain-cells : Number of cells in a power domain specifier, must be 1.
14
15Example:
16 pm_domains: pm_domains0 {
17 compatible = "stericsson,ux500-pm-domains";
18 #power-domain-cells = <1>;
19 };
20
21==PM domain consumers==
22
23Required properties:
24 - power-domains: A phandle and PM domain specifier. Below are the list of
25 valid specifiers:
26
27 Index Specifier
28 ----- ---------
29 0 DOMAIN_VAPE
30
31Example:
32 sdi0_per1@80126000 {
33 compatible = "arm,pl18x", "arm,primecell";
34 power-domains = <&pm_domains DOMAIN_VAPE>
35 };
diff --git a/Documentation/devicetree/bindings/bus/mvebu-mbus.txt b/Documentation/devicetree/bindings/bus/mvebu-mbus.txt
index 5fa44f52a0b8..5e16c3ccb061 100644
--- a/Documentation/devicetree/bindings/bus/mvebu-mbus.txt
+++ b/Documentation/devicetree/bindings/bus/mvebu-mbus.txt
@@ -48,9 +48,12 @@ Required properties:
48- compatible: Should be set to "marvell,mbus-controller". 48- compatible: Should be set to "marvell,mbus-controller".
49 49
50- reg: Device's register space. 50- reg: Device's register space.
51 Two entries are expected (see the examples below): 51 Two or three entries are expected (see the examples below):
52 the first one controls the devices decoding window and 52 the first one controls the devices decoding window,
53 the second one controls the SDRAM decoding window. 53 the second one controls the SDRAM decoding window and
54 the third controls the MBus bridge (only with the
55 marvell,armada370-mbus and marvell,armadaxp-mbus
56 compatible strings)
54 57
55Example: 58Example:
56 59
@@ -67,7 +70,7 @@ Example:
67 70
68 mbusc: mbus-controller@20000 { 71 mbusc: mbus-controller@20000 {
69 compatible = "marvell,mbus-controller"; 72 compatible = "marvell,mbus-controller";
70 reg = <0x20000 0x100>, <0x20180 0x20>; 73 reg = <0x20000 0x100>, <0x20180 0x20>, <0x20250 0x8>;
71 }; 74 };
72 75
73 /* more children ...*/ 76 /* more children ...*/
@@ -126,7 +129,7 @@ are skipped.
126 129
127 mbusc: mbus-controller@20000 { 130 mbusc: mbus-controller@20000 {
128 compatible = "marvell,mbus-controller"; 131 compatible = "marvell,mbus-controller";
129 reg = <0x20000 0x100>, <0x20180 0x20>; 132 reg = <0x20000 0x100>, <0x20180 0x20>, <0x20250 0x8>;
130 }; 133 };
131 134
132 /* more children ...*/ 135 /* more children ...*/
@@ -170,7 +173,7 @@ Using this macro, the above example would be:
170 173
171 mbusc: mbus-controller@20000 { 174 mbusc: mbus-controller@20000 {
172 compatible = "marvell,mbus-controller"; 175 compatible = "marvell,mbus-controller";
173 reg = <0x20000 0x100>, <0x20180 0x20>; 176 reg = <0x20000 0x100>, <0x20180 0x20>, <0x20250 0x8>;
174 }; 177 };
175 178
176 /* other children */ 179 /* other children */
@@ -266,7 +269,7 @@ See the example below, where a more complete device tree is shown:
266 ranges = <0 MBUS_ID(0xf0, 0x01) 0 0x100000>; 269 ranges = <0 MBUS_ID(0xf0, 0x01) 0 0x100000>;
267 270
268 mbusc: mbus-controller@20000 { 271 mbusc: mbus-controller@20000 {
269 reg = <0x20000 0x100>, <0x20180 0x20>; 272 reg = <0x20000 0x100>, <0x20180 0x20>, <0x20250 0x8>;
270 }; 273 };
271 274
272 interrupt-controller@20000 { 275 interrupt-controller@20000 {
diff --git a/Documentation/devicetree/bindings/memory-controllers/mvebu-sdram-controller.txt b/Documentation/devicetree/bindings/memory-controllers/mvebu-sdram-controller.txt
new file mode 100644
index 000000000000..89657d1d4cd4
--- /dev/null
+++ b/Documentation/devicetree/bindings/memory-controllers/mvebu-sdram-controller.txt
@@ -0,0 +1,21 @@
1Device Tree bindings for MVEBU SDRAM controllers
2
3The Marvell EBU SoCs all have a SDRAM controller. The SDRAM controller
4differs from one SoC variant to another, but they also share a number
5of commonalities.
6
7For now, this Device Tree binding documentation only documents the
8Armada XP SDRAM controller.
9
10Required properties:
11
12 - compatible: for Armada XP, "marvell,armada-xp-sdram-controller"
13 - reg: a resource specifier for the register space, which should
14 include all SDRAM controller registers as per the datasheet.
15
16Example:
17
18sdramc@1400 {
19 compatible = "marvell,armada-xp-sdram-controller";
20 reg = <0x1400 0x500>;
21};
diff --git a/Documentation/devicetree/bindings/power_supply/imx-snvs-poweroff.txt b/Documentation/devicetree/bindings/power_supply/imx-snvs-poweroff.txt
new file mode 100644
index 000000000000..dc7c9bad63ea
--- /dev/null
+++ b/Documentation/devicetree/bindings/power_supply/imx-snvs-poweroff.txt
@@ -0,0 +1,23 @@
1i.mx6 Poweroff Driver
2
3SNVS_LPCR in SNVS module can power off the whole system by pull
4PMIC_ON_REQ low if PMIC_ON_REQ is connected with external PMIC.
5If you don't want to use PMIC_ON_REQ as power on/off control,
6please set status='disabled' to disable this driver.
7
8Required Properties:
9-compatible: "fsl,sec-v4.0-poweroff"
10-reg: Specifies the physical address of the SNVS_LPCR register
11
12Example:
13 snvs@020cc000 {
14 compatible = "fsl,sec-v4.0-mon", "simple-bus";
15 #address-cells = <1>;
16 #size-cells = <1>;
17 ranges = <0 0x020cc000 0x4000>;
18 .....
19 snvs_poweroff: snvs-poweroff@38 {
20 compatible = "fsl,sec-v4.0-poweroff";
21 reg = <0x38 0x4>;
22 };
23 }
diff --git a/Documentation/devicetree/bindings/vendor-prefixes.txt b/Documentation/devicetree/bindings/vendor-prefixes.txt
index a344ec2713a5..ecaf2035c2fe 100644
--- a/Documentation/devicetree/bindings/vendor-prefixes.txt
+++ b/Documentation/devicetree/bindings/vendor-prefixes.txt
@@ -91,6 +91,7 @@ lltc Linear Technology Corporation
91marvell Marvell Technology Group Ltd. 91marvell Marvell Technology Group Ltd.
92maxim Maxim Integrated Products 92maxim Maxim Integrated Products
93mediatek MediaTek Inc. 93mediatek MediaTek Inc.
94merrii Merrii Technology Co., Ltd.
94micrel Micrel Inc. 95micrel Micrel Inc.
95microchip Microchip Technology Inc. 96microchip Microchip Technology Inc.
96micron Micron Technology Inc. 97micron Micron Technology Inc.
diff --git a/MAINTAINERS b/MAINTAINERS
index 79ccbdf57723..e3a96e42193c 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1379,6 +1379,7 @@ F: arch/arm/configs/lager_defconfig
1379F: arch/arm/configs/mackerel_defconfig 1379F: arch/arm/configs/mackerel_defconfig
1380F: arch/arm/configs/marzen_defconfig 1380F: arch/arm/configs/marzen_defconfig
1381F: arch/arm/configs/shmobile_defconfig 1381F: arch/arm/configs/shmobile_defconfig
1382F: arch/arm/include/debug/renesas-scif.S
1382F: arch/arm/mach-shmobile/ 1383F: arch/arm/mach-shmobile/
1383F: drivers/sh/ 1384F: drivers/sh/
1384 1385
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index fd4515ca8358..8db9dc07f8ac 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -320,24 +320,6 @@ config ARCH_MULTIPLATFORM
320 select SPARSE_IRQ 320 select SPARSE_IRQ
321 select USE_OF 321 select USE_OF
322 322
323config ARCH_INTEGRATOR
324 bool "ARM Ltd. Integrator family"
325 select ARM_AMBA
326 select ARM_PATCH_PHYS_VIRT if MMU
327 select AUTO_ZRELADDR
328 select COMMON_CLK
329 select COMMON_CLK_VERSATILE
330 select GENERIC_CLOCKEVENTS
331 select HAVE_TCM
332 select ICST
333 select MULTI_IRQ_HANDLER
334 select PLAT_VERSATILE
335 select SPARSE_IRQ
336 select USE_OF
337 select VERSATILE_FPGA_IRQ
338 help
339 Support for ARM's Integrator platform.
340
341config ARCH_REALVIEW 323config ARCH_REALVIEW
342 bool "ARM Ltd. RealView family" 324 bool "ARM Ltd. RealView family"
343 select ARCH_WANT_OPTIONAL_GPIOLIB 325 select ARCH_WANT_OPTIONAL_GPIOLIB
@@ -857,6 +839,8 @@ config ARCH_VIRT
857# 839#
858source "arch/arm/mach-mvebu/Kconfig" 840source "arch/arm/mach-mvebu/Kconfig"
859 841
842source "arch/arm/mach-asm9260/Kconfig"
843
860source "arch/arm/mach-at91/Kconfig" 844source "arch/arm/mach-at91/Kconfig"
861 845
862source "arch/arm/mach-axxia/Kconfig" 846source "arch/arm/mach-axxia/Kconfig"
diff --git a/arch/arm/Kconfig.debug b/arch/arm/Kconfig.debug
index d8f6a2ec3d4e..f9295a4e1036 100644
--- a/arch/arm/Kconfig.debug
+++ b/arch/arm/Kconfig.debug
@@ -93,6 +93,27 @@ choice
93 prompt "Kernel low-level debugging port" 93 prompt "Kernel low-level debugging port"
94 depends on DEBUG_LL 94 depends on DEBUG_LL
95 95
96 config DEBUG_ASM9260_UART
97 bool "Kernel low-level debugging via asm9260 UART"
98 depends on MACH_ASM9260
99 help
100 Say Y here if you want the debug print routines to direct
101 their output to an UART or USART port on asm9260 based
102 machines.
103
104 DEBUG_UART_PHYS | DEBUG_UART_VIRT
105
106 0x80000000 | 0xf0000000 | UART0
107 0x80004000 | 0xf0004000 | UART1
108 0x80008000 | 0xf0008000 | UART2
109 0x8000c000 | 0xf000c000 | UART3
110 0x80010000 | 0xf0010000 | UART4
111 0x80014000 | 0xf0014000 | UART5
112 0x80018000 | 0xf0018000 | UART6
113 0x8001c000 | 0xf001c000 | UART7
114 0x80020000 | 0xf0020000 | UART8
115 0x80024000 | 0xf0024000 | UART9
116
96 config AT91_DEBUG_LL_DBGU0 117 config AT91_DEBUG_LL_DBGU0
97 bool "Kernel low-level debugging on rm9200, 9260/9g20, 9261/9g10 and 9rl" 118 bool "Kernel low-level debugging on rm9200, 9260/9g20, 9261/9g10 and 9rl"
98 depends on HAVE_AT91_DBGU0 119 depends on HAVE_AT91_DBGU0
@@ -113,7 +134,7 @@ choice
113 config DEBUG_BCM_5301X 134 config DEBUG_BCM_5301X
114 bool "Kernel low-level debugging on BCM5301X UART1" 135 bool "Kernel low-level debugging on BCM5301X UART1"
115 depends on ARCH_BCM_5301X 136 depends on ARCH_BCM_5301X
116 select DEBUG_UART_PL01X 137 select DEBUG_UART_8250
117 138
118 config DEBUG_BCM_KONA_UART 139 config DEBUG_BCM_KONA_UART
119 bool "Kernel low-level debugging messages via BCM KONA UART" 140 bool "Kernel low-level debugging messages via BCM KONA UART"
@@ -139,6 +160,17 @@ choice
139 Say Y here if you want kernel low-level debugging support 160 Say Y here if you want kernel low-level debugging support
140 on Marvell Berlin SoC based platforms. 161 on Marvell Berlin SoC based platforms.
141 162
163 config DEBUG_BRCMSTB_UART
164 bool "Use BRCMSTB UART for low-level debug"
165 depends on ARCH_BRCMSTB
166 select DEBUG_UART_8250
167 help
168 Say Y here if you want the debug print routines to direct
169 their output to the first serial port on these devices.
170
171 If you have a Broadcom STB chip and would like early print
172 messages to appear over the UART, select this option.
173
142 config DEBUG_CLPS711X_UART1 174 config DEBUG_CLPS711X_UART1
143 bool "Kernel low-level debugging messages via UART1" 175 bool "Kernel low-level debugging messages via UART1"
144 depends on ARCH_CLPS711X 176 depends on ARCH_CLPS711X
@@ -653,6 +685,64 @@ choice
653 Say Y here if you want kernel low-level debugging support 685 Say Y here if you want kernel low-level debugging support
654 on Rockchip RK32xx based platforms. 686 on Rockchip RK32xx based platforms.
655 687
688 config DEBUG_R7S72100_SCIF2
689 bool "Kernel low-level debugging messages via SCIF2 on R7S72100"
690 depends on ARCH_R7S72100
691 help
692 Say Y here if you want kernel low-level debugging support
693 via SCIF2 on Renesas RZ/A1H (R7S72100).
694
695 config DEBUG_RCAR_GEN1_SCIF0
696 bool "Kernel low-level debugging messages via SCIF0 on R8A7778"
697 depends on ARCH_R8A7778
698 help
699 Say Y here if you want kernel low-level debugging support
700 via SCIF0 on Renesas R-Car M1A (R8A7778).
701
702 config DEBUG_RCAR_GEN1_SCIF2
703 bool "Kernel low-level debugging messages via SCIF2 on R8A7779"
704 depends on ARCH_R8A7779
705 help
706 Say Y here if you want kernel low-level debugging support
707 via SCIF2 on Renesas R-Car H1 (R8A7779).
708
709 config DEBUG_RCAR_GEN2_SCIF0
710 bool "Kernel low-level debugging messages via SCIF0 on R8A7790/R8A7791/R8A7793)"
711 depends on ARCH_R8A7790 || ARCH_R8A7791 || ARCH_R8A7793
712 help
713 Say Y here if you want kernel low-level debugging support
714 via SCIF0 on Renesas R-Car H2 (R8A7790), M2-W (R8A7791), or
715 M2-N (R8A7793).
716
717 config DEBUG_RCAR_GEN2_SCIF2
718 bool "Kernel low-level debugging messages via SCIF2 on R8A7794"
719 depends on ARCH_R8A7794
720 help
721 Say Y here if you want kernel low-level debugging support
722 via SCIF2 on Renesas R-Car E2 (R8A7794).
723
724 config DEBUG_RMOBILE_SCIFA0
725 bool "Kernel low-level debugging messages via SCIFA0 on R8A73A4/SH7372"
726 depends on ARCH_R8A73A4 || ARCH_SH7372
727 help
728 Say Y here if you want kernel low-level debugging support
729 via SCIFA0 on Renesas R-Mobile APE6 (R8A73A4) or SH-Mobile
730 AP4 (SH7372).
731
732 config DEBUG_RMOBILE_SCIFA1
733 bool "Kernel low-level debugging messages via SCIFA1 on R8A7740"
734 depends on ARCH_R8A7740
735 help
736 Say Y here if you want kernel low-level debugging support
737 via SCIFA1 on Renesas R-Mobile A1 (R8A7740).
738
739 config DEBUG_RMOBILE_SCIFA4
740 bool "Kernel low-level debugging messages via SCIFA4 on SH73A0"
741 depends on ARCH_SH73A0
742 help
743 Say Y here if you want kernel low-level debugging support
744 via SCIFA4 on Renesas SH-Mobile AG5 (SH73A0).
745
656 config DEBUG_S3C_UART0 746 config DEBUG_S3C_UART0
657 depends on PLAT_SAMSUNG 747 depends on PLAT_SAMSUNG
658 select DEBUG_EXYNOS_UART if ARCH_EXYNOS 748 select DEBUG_EXYNOS_UART if ARCH_EXYNOS
@@ -723,6 +813,14 @@ choice
723 their output to UART 2. The port must have been initialised 813 their output to UART 2. The port must have been initialised
724 by the boot-loader before use. 814 by the boot-loader before use.
725 815
816 config DEBUG_SA1100
817 depends on ARCH_SA1100
818 bool "Use SA1100 UARTs for low-level debug"
819 help
820 Say Y here if you want kernel low-level debugging support
821 on SA-11x0 UART ports. The kernel will check for the first
822 enabled UART in a sequence 3-1-2.
823
726 config DEBUG_SOCFPGA_UART 824 config DEBUG_SOCFPGA_UART
727 depends on ARCH_SOCFPGA 825 depends on ARCH_SOCFPGA
728 bool "Use SOCFPGA UART for low-level debug" 826 bool "Use SOCFPGA UART for low-level debug"
@@ -731,6 +829,14 @@ choice
731 Say Y here if you want kernel low-level debugging support 829 Say Y here if you want kernel low-level debugging support
732 on SOCFPGA based platforms. 830 on SOCFPGA based platforms.
733 831
832 config DEBUG_SUN9I_UART0
833 bool "Kernel low-level debugging messages via sun9i UART0"
834 depends on MACH_SUN9I
835 select DEBUG_UART_8250
836 help
837 Say Y here if you want kernel low-level debugging support
838 on Allwinner A80 based platforms on the UART0.
839
734 config DEBUG_SUNXI_UART0 840 config DEBUG_SUNXI_UART0
735 bool "Kernel low-level debugging messages via sunXi UART0" 841 bool "Kernel low-level debugging messages via sunXi UART0"
736 depends on ARCH_SUNXI 842 depends on ARCH_SUNXI
@@ -866,6 +972,22 @@ choice
866 Say Y here if you want kernel low-level debugging support 972 Say Y here if you want kernel low-level debugging support
867 for Mediatek mt6589 based platforms on UART0. 973 for Mediatek mt6589 based platforms on UART0.
868 974
975 config DEBUG_MT8127_UART0
976 bool "Mediatek mt8127 UART0"
977 depends on ARCH_MEDIATEK
978 select DEBUG_UART_8250
979 help
980 Say Y here if you want kernel low-level debugging support
981 for Mediatek mt8127 based platforms on UART0.
982
983 config DEBUG_MT8135_UART3
984 bool "Mediatek mt8135 UART3"
985 depends on ARCH_MEDIATEK
986 select DEBUG_UART_8250
987 help
988 Say Y here if you want kernel low-level debugging support
989 for Mediatek mt8135 based platforms on UART3.
990
869 config DEBUG_VEXPRESS_UART0_DETECT 991 config DEBUG_VEXPRESS_UART0_DETECT
870 bool "Autodetect UART0 on Versatile Express Cortex-A core tiles" 992 bool "Autodetect UART0 on Versatile Express Cortex-A core tiles"
871 depends on ARCH_VEXPRESS && CPU_CP15_MMU 993 depends on ARCH_VEXPRESS && CPU_CP15_MMU
@@ -1041,7 +1163,9 @@ config DEBUG_STI_UART
1041 1163
1042config DEBUG_LL_INCLUDE 1164config DEBUG_LL_INCLUDE
1043 string 1165 string
1166 default "debug/sa1100.S" if DEBUG_SA1100
1044 default "debug/8250.S" if DEBUG_LL_UART_8250 || DEBUG_UART_8250 1167 default "debug/8250.S" if DEBUG_LL_UART_8250 || DEBUG_UART_8250
1168 default "debug/asm9260.S" if DEBUG_ASM9260_UART
1045 default "debug/clps711x.S" if DEBUG_CLPS711X_UART1 || DEBUG_CLPS711X_UART2 1169 default "debug/clps711x.S" if DEBUG_CLPS711X_UART1 || DEBUG_CLPS711X_UART2
1046 default "debug/meson.S" if DEBUG_MESON_UARTAO 1170 default "debug/meson.S" if DEBUG_MESON_UARTAO
1047 default "debug/pl01x.S" if DEBUG_LL_UART_PL01X || DEBUG_UART_PL01X 1171 default "debug/pl01x.S" if DEBUG_LL_UART_PL01X || DEBUG_UART_PL01X
@@ -1061,6 +1185,14 @@ config DEBUG_LL_INCLUDE
1061 DEBUG_IMX6SX_UART 1185 DEBUG_IMX6SX_UART
1062 default "debug/msm.S" if DEBUG_MSM_UART || DEBUG_QCOM_UARTDM 1186 default "debug/msm.S" if DEBUG_MSM_UART || DEBUG_QCOM_UARTDM
1063 default "debug/omap2plus.S" if DEBUG_OMAP2PLUS_UART 1187 default "debug/omap2plus.S" if DEBUG_OMAP2PLUS_UART
1188 default "debug/renesas-scif.S" if DEBUG_R7S72100_SCIF2
1189 default "debug/renesas-scif.S" if DEBUG_RCAR_GEN1_SCIF0
1190 default "debug/renesas-scif.S" if DEBUG_RCAR_GEN1_SCIF2
1191 default "debug/renesas-scif.S" if DEBUG_RCAR_GEN2_SCIF0
1192 default "debug/renesas-scif.S" if DEBUG_RCAR_GEN2_SCIF2
1193 default "debug/renesas-scif.S" if DEBUG_RMOBILE_SCIFA0
1194 default "debug/renesas-scif.S" if DEBUG_RMOBILE_SCIFA1
1195 default "debug/renesas-scif.S" if DEBUG_RMOBILE_SCIFA4
1064 default "debug/s3c24xx.S" if DEBUG_S3C24XX_UART 1196 default "debug/s3c24xx.S" if DEBUG_S3C24XX_UART
1065 default "debug/s5pv210.S" if DEBUG_S5PV210_UART 1197 default "debug/s5pv210.S" if DEBUG_S5PV210_UART
1066 default "debug/sirf.S" if DEBUG_SIRFPRIMA2_UART1 || DEBUG_SIRFMARCO_UART1 1198 default "debug/sirf.S" if DEBUG_SIRFPRIMA2_UART1 || DEBUG_SIRFMARCO_UART1
@@ -1106,6 +1238,7 @@ config DEBUG_UART_PHYS
1106 default 0x02530c00 if DEBUG_KEYSTONE_UART0 1238 default 0x02530c00 if DEBUG_KEYSTONE_UART0
1107 default 0x02531000 if DEBUG_KEYSTONE_UART1 1239 default 0x02531000 if DEBUG_KEYSTONE_UART1
1108 default 0x03010fe0 if ARCH_RPC 1240 default 0x03010fe0 if ARCH_RPC
1241 default 0x07000000 if DEBUG_SUN9I_UART0
1109 default 0x10009000 if DEBUG_REALVIEW_STD_PORT || \ 1242 default 0x10009000 if DEBUG_REALVIEW_STD_PORT || \
1110 DEBUG_VEXPRESS_UART0_CA9 1243 DEBUG_VEXPRESS_UART0_CA9
1111 default 0x1010c000 if DEBUG_REALVIEW_PB1176_PORT 1244 default 0x1010c000 if DEBUG_REALVIEW_PB1176_PORT
@@ -1113,7 +1246,9 @@ config DEBUG_UART_PHYS
1113 default 0x10126000 if DEBUG_RK3X_UART1 1246 default 0x10126000 if DEBUG_RK3X_UART1
1114 default 0x101f1000 if ARCH_VERSATILE 1247 default 0x101f1000 if ARCH_VERSATILE
1115 default 0x101fb000 if DEBUG_NOMADIK_UART 1248 default 0x101fb000 if DEBUG_NOMADIK_UART
1249 default 0x11002000 if DEBUG_MT8127_UART0
1116 default 0x11006000 if DEBUG_MT6589_UART0 1250 default 0x11006000 if DEBUG_MT6589_UART0
1251 default 0x11009000 if DEBUG_MT8135_UART3
1117 default 0x16000000 if ARCH_INTEGRATOR 1252 default 0x16000000 if ARCH_INTEGRATOR
1118 default 0x18000300 if DEBUG_BCM_5301X 1253 default 0x18000300 if DEBUG_BCM_5301X
1119 default 0x1c090000 if DEBUG_VEXPRESS_UART0_RS1 1254 default 0x1c090000 if DEBUG_VEXPRESS_UART0_RS1
@@ -1135,6 +1270,7 @@ config DEBUG_UART_PHYS
1135 default 0x78000000 if DEBUG_CNS3XXX 1270 default 0x78000000 if DEBUG_CNS3XXX
1136 default 0x7c0003f8 if FOOTBRIDGE 1271 default 0x7c0003f8 if FOOTBRIDGE
1137 default 0x78000000 if DEBUG_CNS3XXX 1272 default 0x78000000 if DEBUG_CNS3XXX
1273 default 0x80010000 if DEBUG_ASM9260_UART
1138 default 0x80070000 if DEBUG_IMX23_UART 1274 default 0x80070000 if DEBUG_IMX23_UART
1139 default 0x80074000 if DEBUG_IMX28_UART 1275 default 0x80074000 if DEBUG_IMX28_UART
1140 default 0x80230000 if DEBUG_PICOXCELL_UART 1276 default 0x80230000 if DEBUG_PICOXCELL_UART
@@ -1152,7 +1288,14 @@ config DEBUG_UART_PHYS
1152 default 0xd4018000 if DEBUG_MMP_UART3 1288 default 0xd4018000 if DEBUG_MMP_UART3
1153 default 0xe0000000 if ARCH_SPEAR13XX 1289 default 0xe0000000 if ARCH_SPEAR13XX
1154 default 0xe4007000 if DEBUG_HIP04_UART 1290 default 0xe4007000 if DEBUG_HIP04_UART
1291 default 0xe6c40000 if DEBUG_RMOBILE_SCIFA0
1292 default 0xe6c50000 if DEBUG_RMOBILE_SCIFA1
1293 default 0xe6c80000 if DEBUG_RMOBILE_SCIFA4
1294 default 0xe6e58000 if DEBUG_RCAR_GEN2_SCIF2
1295 default 0xe6e60000 if DEBUG_RCAR_GEN2_SCIF0
1296 default 0xe8008000 if DEBUG_R7S72100_SCIF2
1155 default 0xf0000be0 if ARCH_EBSA110 1297 default 0xf0000be0 if ARCH_EBSA110
1298 default 0xf040ab00 if DEBUG_BRCMSTB_UART
1156 default 0xf1012000 if DEBUG_MVEBU_UART_ALTERNATE 1299 default 0xf1012000 if DEBUG_MVEBU_UART_ALTERNATE
1157 default 0xf1012000 if ARCH_DOVE || ARCH_MV78XX0 || \ 1300 default 0xf1012000 if ARCH_DOVE || ARCH_MV78XX0 || \
1158 ARCH_ORION5X 1301 ARCH_ORION5X
@@ -1164,24 +1307,33 @@ config DEBUG_UART_PHYS
1164 default 0xff690000 if DEBUG_RK32_UART2 1307 default 0xff690000 if DEBUG_RK32_UART2
1165 default 0xffc02000 if DEBUG_SOCFPGA_UART 1308 default 0xffc02000 if DEBUG_SOCFPGA_UART
1166 default 0xffd82340 if ARCH_IOP13XX 1309 default 0xffd82340 if ARCH_IOP13XX
1310 default 0xffe40000 if DEBUG_RCAR_GEN1_SCIF0
1311 default 0xffe42000 if DEBUG_RCAR_GEN1_SCIF2
1167 default 0xfff36000 if DEBUG_HIGHBANK_UART 1312 default 0xfff36000 if DEBUG_HIGHBANK_UART
1168 default 0xfffe8600 if DEBUG_UART_BCM63XX 1313 default 0xfffe8600 if DEBUG_UART_BCM63XX
1169 default 0xfffff700 if ARCH_IOP33X 1314 default 0xfffff700 if ARCH_IOP33X
1170 depends on DEBUG_LL_UART_8250 || DEBUG_LL_UART_PL01X || \ 1315 depends on DEBUG_LL_UART_8250 || DEBUG_LL_UART_PL01X || \
1171 DEBUG_LL_UART_EFM32 || \ 1316 DEBUG_LL_UART_EFM32 || \
1172 DEBUG_UART_8250 || DEBUG_UART_PL01X || DEBUG_MESON_UARTAO || \ 1317 DEBUG_UART_8250 || DEBUG_UART_PL01X || DEBUG_MESON_UARTAO || \
1173 DEBUG_MSM_UART || DEBUG_QCOM_UARTDM || DEBUG_S3C24XX_UART || \ 1318 DEBUG_MSM_UART || DEBUG_QCOM_UARTDM || DEBUG_R7S72100_SCIF2 || \
1174 DEBUG_UART_BCM63XX 1319 DEBUG_RCAR_GEN1_SCIF0 || DEBUG_RCAR_GEN1_SCIF2 || \
1320 DEBUG_RCAR_GEN2_SCIF0 || DEBUG_RCAR_GEN2_SCIF2 || \
1321 DEBUG_RMOBILE_SCIFA0 || DEBUG_RMOBILE_SCIFA1 || \
1322 DEBUG_RMOBILE_SCIFA4 || DEBUG_S3C24XX_UART || \
1323 DEBUG_UART_BCM63XX || DEBUG_ASM9260_UART
1175 1324
1176config DEBUG_UART_VIRT 1325config DEBUG_UART_VIRT
1177 hex "Virtual base address of debug UART" 1326 hex "Virtual base address of debug UART"
1178 default 0xe0010fe0 if ARCH_RPC 1327 default 0xe0010fe0 if ARCH_RPC
1179 default 0xe1000000 if DEBUG_MSM_UART 1328 default 0xe1000000 if DEBUG_MSM_UART
1180 default 0xf0000be0 if ARCH_EBSA110 1329 default 0xf0000be0 if ARCH_EBSA110
1330 default 0xf0010000 if DEBUG_ASM9260_UART
1181 default 0xf01fb000 if DEBUG_NOMADIK_UART 1331 default 0xf01fb000 if DEBUG_NOMADIK_UART
1182 default 0xf0201000 if DEBUG_BCM2835 1332 default 0xf0201000 if DEBUG_BCM2835
1183 default 0xf1000300 if DEBUG_BCM_5301X 1333 default 0xf1000300 if DEBUG_BCM_5301X
1334 default 0xf1002000 if DEBUG_MT8127_UART0
1184 default 0xf1006000 if DEBUG_MT6589_UART0 1335 default 0xf1006000 if DEBUG_MT6589_UART0
1336 default 0xf1009000 if DEBUG_MT8135_UART3
1185 default 0xf11f1000 if ARCH_VERSATILE 1337 default 0xf11f1000 if ARCH_VERSATILE
1186 default 0xf1600000 if ARCH_INTEGRATOR 1338 default 0xf1600000 if ARCH_INTEGRATOR
1187 default 0xf1c28000 if DEBUG_SUNXI_UART0 1339 default 0xf1c28000 if DEBUG_SUNXI_UART0
@@ -1190,6 +1342,7 @@ config DEBUG_UART_VIRT
1190 default 0xf6200000 if DEBUG_PXA_UART1 1342 default 0xf6200000 if DEBUG_PXA_UART1
1191 default 0xf4090000 if ARCH_LPC32XX 1343 default 0xf4090000 if ARCH_LPC32XX
1192 default 0xf4200000 if ARCH_GEMINI 1344 default 0xf4200000 if ARCH_GEMINI
1345 default 0xf7000000 if DEBUG_SUN9I_UART0
1193 default 0xf7000000 if DEBUG_S3C24XX_UART && (DEBUG_S3C_UART0 || \ 1346 default 0xf7000000 if DEBUG_S3C24XX_UART && (DEBUG_S3C_UART0 || \
1194 DEBUG_S3C2410_UART0) 1347 DEBUG_S3C2410_UART0)
1195 default 0xf7004000 if DEBUG_S3C24XX_UART && (DEBUG_S3C_UART1 || \ 1348 default 0xf7004000 if DEBUG_S3C24XX_UART && (DEBUG_S3C_UART1 || \
@@ -1204,6 +1357,7 @@ config DEBUG_UART_VIRT
1204 default 0xfb002000 if DEBUG_CNS3XXX 1357 default 0xfb002000 if DEBUG_CNS3XXX
1205 default 0xfb009000 if DEBUG_REALVIEW_STD_PORT 1358 default 0xfb009000 if DEBUG_REALVIEW_STD_PORT
1206 default 0xfb10c000 if DEBUG_REALVIEW_PB1176_PORT 1359 default 0xfb10c000 if DEBUG_REALVIEW_PB1176_PORT
1360 default 0xfc40ab00 if DEBUG_BRCMSTB_UART
1207 default 0xfcfe8600 if DEBUG_UART_BCM63XX 1361 default 0xfcfe8600 if DEBUG_UART_BCM63XX
1208 default 0xfd000000 if ARCH_SPEAR3XX || ARCH_SPEAR6XX 1362 default 0xfd000000 if ARCH_SPEAR3XX || ARCH_SPEAR6XX
1209 default 0xfd000000 if ARCH_SPEAR13XX 1363 default 0xfd000000 if ARCH_SPEAR13XX
@@ -1244,12 +1398,12 @@ config DEBUG_UART_VIRT
1244 depends on DEBUG_LL_UART_8250 || DEBUG_LL_UART_PL01X || \ 1398 depends on DEBUG_LL_UART_8250 || DEBUG_LL_UART_PL01X || \
1245 DEBUG_UART_8250 || DEBUG_UART_PL01X || DEBUG_MESON_UARTAO || \ 1399 DEBUG_UART_8250 || DEBUG_UART_PL01X || DEBUG_MESON_UARTAO || \
1246 DEBUG_MSM_UART || DEBUG_QCOM_UARTDM || DEBUG_S3C24XX_UART || \ 1400 DEBUG_MSM_UART || DEBUG_QCOM_UARTDM || DEBUG_S3C24XX_UART || \
1247 DEBUG_UART_BCM63XX 1401 DEBUG_UART_BCM63XX || DEBUG_ASM9260_UART
1248 1402
1249config DEBUG_UART_8250_SHIFT 1403config DEBUG_UART_8250_SHIFT
1250 int "Register offset shift for the 8250 debug UART" 1404 int "Register offset shift for the 8250 debug UART"
1251 depends on DEBUG_LL_UART_8250 || DEBUG_UART_8250 1405 depends on DEBUG_LL_UART_8250 || DEBUG_UART_8250
1252 default 0 if FOOTBRIDGE || ARCH_IOP32X 1406 default 0 if FOOTBRIDGE || ARCH_IOP32X || DEBUG_BCM_5301X
1253 default 2 1407 default 2
1254 1408
1255config DEBUG_UART_8250_WORD 1409config DEBUG_UART_8250_WORD
@@ -1260,7 +1414,8 @@ config DEBUG_UART_8250_WORD
1260 ARCH_KEYSTONE || \ 1414 ARCH_KEYSTONE || \
1261 DEBUG_DAVINCI_DMx_UART0 || DEBUG_DAVINCI_DA8XX_UART1 || \ 1415 DEBUG_DAVINCI_DMx_UART0 || DEBUG_DAVINCI_DA8XX_UART1 || \
1262 DEBUG_DAVINCI_DA8XX_UART2 || \ 1416 DEBUG_DAVINCI_DA8XX_UART2 || \
1263 DEBUG_BCM_KONA_UART || DEBUG_RK32_UART2 1417 DEBUG_BCM_KONA_UART || DEBUG_RK32_UART2 || \
1418 DEBUG_BRCMSTB_UART
1264 1419
1265config DEBUG_UART_8250_FLOW_CONTROL 1420config DEBUG_UART_8250_FLOW_CONTROL
1266 bool "Enable flow control for 8250 UART" 1421 bool "Enable flow control for 8250 UART"
diff --git a/arch/arm/boot/dts/armada-370-xp.dtsi b/arch/arm/boot/dts/armada-370-xp.dtsi
index 83286ec9702c..90dba78554c8 100644
--- a/arch/arm/boot/dts/armada-370-xp.dtsi
+++ b/arch/arm/boot/dts/armada-370-xp.dtsi
@@ -180,7 +180,8 @@
180 180
181 mbusc: mbus-controller@20000 { 181 mbusc: mbus-controller@20000 {
182 compatible = "marvell,mbus-controller"; 182 compatible = "marvell,mbus-controller";
183 reg = <0x20000 0x100>, <0x20180 0x20>; 183 reg = <0x20000 0x100>, <0x20180 0x20>,
184 <0x20250 0x8>;
184 }; 185 };
185 186
186 mpic: interrupt-controller@20000 { 187 mpic: interrupt-controller@20000 {
diff --git a/arch/arm/boot/dts/armada-xp-gp.dts b/arch/arm/boot/dts/armada-xp-gp.dts
index 0478c55ca656..ea8673647494 100644
--- a/arch/arm/boot/dts/armada-xp-gp.dts
+++ b/arch/arm/boot/dts/armada-xp-gp.dts
@@ -23,6 +23,7 @@
23 */ 23 */
24 24
25/dts-v1/; 25/dts-v1/;
26#include <dt-bindings/gpio/gpio.h>
26#include "armada-xp-mv78460.dtsi" 27#include "armada-xp-mv78460.dtsi"
27 28
28/ { 29/ {
@@ -48,6 +49,14 @@
48 <0x00000001 0x00000000 0x00000001 0x00000000>; 49 <0x00000001 0x00000000 0x00000001 0x00000000>;
49 }; 50 };
50 51
52 cpus {
53 pm_pic {
54 ctrl-gpios = <&gpio0 16 GPIO_ACTIVE_LOW>,
55 <&gpio0 17 GPIO_ACTIVE_LOW>,
56 <&gpio0 18 GPIO_ACTIVE_LOW>;
57 };
58 };
59
51 soc { 60 soc {
52 ranges = <MBUS_ID(0xf0, 0x01) 0 0 0xf1000000 0x100000 61 ranges = <MBUS_ID(0xf0, 0x01) 0 0 0xf1000000 0x100000
53 MBUS_ID(0x01, 0x1d) 0 0 0xfff00000 0x100000 62 MBUS_ID(0x01, 0x1d) 0 0 0xfff00000 0x100000
@@ -115,7 +124,15 @@
115 serial@12300 { 124 serial@12300 {
116 status = "okay"; 125 status = "okay";
117 }; 126 };
118 127 pinctrl {
128 pinctrl-0 = <&pic_pins>;
129 pinctrl-names = "default";
130 pic_pins: pic-pins-0 {
131 marvell,pins = "mpp16", "mpp17",
132 "mpp18";
133 marvell,function = "gpio";
134 };
135 };
119 sata@a0000 { 136 sata@a0000 {
120 nr-ports = <2>; 137 nr-ports = <2>;
121 status = "okay"; 138 status = "okay";
diff --git a/arch/arm/boot/dts/armada-xp.dtsi b/arch/arm/boot/dts/armada-xp.dtsi
index bff9f6c18db1..2be244a96edf 100644
--- a/arch/arm/boot/dts/armada-xp.dtsi
+++ b/arch/arm/boot/dts/armada-xp.dtsi
@@ -35,6 +35,11 @@
35 }; 35 };
36 36
37 internal-regs { 37 internal-regs {
38 sdramc@1400 {
39 compatible = "marvell,armada-xp-sdram-controller";
40 reg = <0x1400 0x500>;
41 };
42
38 L2: l2-cache { 43 L2: l2-cache {
39 compatible = "marvell,aurora-system-cache"; 44 compatible = "marvell,aurora-system-cache";
40 reg = <0x08000 0x1000>; 45 reg = <0x08000 0x1000>;
diff --git a/arch/arm/boot/dts/integrator.dtsi b/arch/arm/boot/dts/integrator.dtsi
index 88e3d477bf16..28e38f8c6b0f 100644
--- a/arch/arm/boot/dts/integrator.dtsi
+++ b/arch/arm/boot/dts/integrator.dtsi
@@ -6,8 +6,18 @@
6 6
7/ { 7/ {
8 core-module@10000000 { 8 core-module@10000000 {
9 compatible = "arm,core-module-integrator"; 9 compatible = "arm,core-module-integrator", "syscon";
10 reg = <0x10000000 0x200>; 10 reg = <0x10000000 0x200>;
11
12 /* Use core module LED to indicate CPU load */
13 led@0c.0 {
14 compatible = "register-bit-led";
15 offset = <0x0c>;
16 mask = <0x01>;
17 label = "integrator:core_module";
18 linux,default-trigger = "cpu0";
19 default-state = "on";
20 };
11 }; 21 };
12 22
13 ebi@12000000 { 23 ebi@12000000 {
@@ -82,5 +92,41 @@
82 reg = <0x19000000 0x1000>; 92 reg = <0x19000000 0x1000>;
83 interrupts = <4>; 93 interrupts = <4>;
84 }; 94 };
95
96 syscon {
97 /* Debug registers mapped as syscon */
98 compatible = "syscon";
99 reg = <0x1a000000 0x10>;
100
101 led@04.0 {
102 compatible = "register-bit-led";
103 offset = <0x04>;
104 mask = <0x01>;
105 label = "integrator:green0";
106 linux,default-trigger = "heartbeat";
107 default-state = "on";
108 };
109 led@04.1 {
110 compatible = "register-bit-led";
111 offset = <0x04>;
112 mask = <0x02>;
113 label = "integrator:yellow";
114 default-state = "off";
115 };
116 led@04.2 {
117 compatible = "register-bit-led";
118 offset = <0x04>;
119 mask = <0x04>;
120 label = "integrator:red";
121 default-state = "off";
122 };
123 led@04.3 {
124 compatible = "register-bit-led";
125 offset = <0x04>;
126 mask = <0x08>;
127 label = "integrator:green1";
128 default-state = "off";
129 };
130 };
85 }; 131 };
86}; 132};
diff --git a/arch/arm/boot/dts/omap3-cm-t3x30.dtsi b/arch/arm/boot/dts/omap3-cm-t3x30.dtsi
index 25ba08331d88..3cbaf98c1372 100644
--- a/arch/arm/boot/dts/omap3-cm-t3x30.dtsi
+++ b/arch/arm/boot/dts/omap3-cm-t3x30.dtsi
@@ -64,6 +64,7 @@
64 64
65#include "twl4030.dtsi" 65#include "twl4030.dtsi"
66#include "twl4030_omap3.dtsi" 66#include "twl4030_omap3.dtsi"
67#include <dt-bindings/input/input.h>
67 68
68&mmc1 { 69&mmc1 {
69 vmmc-supply = <&vmmc1>; 70 vmmc-supply = <&vmmc1>;
@@ -75,6 +76,22 @@
75 ti,pullups = <0x000001>; 76 ti,pullups = <0x000001>;
76}; 77};
77 78
79&twl_keypad {
80 linux,keymap = <
81 MATRIX_KEY(0x00, 0x01, KEY_A)
82 MATRIX_KEY(0x00, 0x02, KEY_B)
83 MATRIX_KEY(0x00, 0x03, KEY_LEFT)
84
85 MATRIX_KEY(0x01, 0x01, KEY_UP)
86 MATRIX_KEY(0x01, 0x02, KEY_ENTER)
87 MATRIX_KEY(0x01, 0x03, KEY_DOWN)
88
89 MATRIX_KEY(0x02, 0x01, KEY_RIGHT)
90 MATRIX_KEY(0x02, 0x02, KEY_C)
91 MATRIX_KEY(0x02, 0x03, KEY_D)
92 >;
93};
94
78&hsusb1_phy { 95&hsusb1_phy {
79 reset-gpios = <&twl_gpio 6 GPIO_ACTIVE_LOW>; 96 reset-gpios = <&twl_gpio 6 GPIO_ACTIVE_LOW>;
80}; 97};
diff --git a/arch/arm/boot/dts/omap4.dtsi b/arch/arm/boot/dts/omap4.dtsi
index 878c979203d0..84045a5c3ce8 100644
--- a/arch/arm/boot/dts/omap4.dtsi
+++ b/arch/arm/boot/dts/omap4.dtsi
@@ -895,7 +895,7 @@
895 reg = <0x58002000 0x1000>; 895 reg = <0x58002000 0x1000>;
896 status = "disabled"; 896 status = "disabled";
897 ti,hwmods = "dss_rfbi"; 897 ti,hwmods = "dss_rfbi";
898 clocks = <&dss_dss_clk>, <&dss_fck>; 898 clocks = <&dss_dss_clk>, <&l3_div_ck>;
899 clock-names = "fck", "ick"; 899 clock-names = "fck", "ick";
900 }; 900 };
901 901
diff --git a/arch/arm/boot/dts/omap44xx-clocks.dtsi b/arch/arm/boot/dts/omap44xx-clocks.dtsi
index c821ff5e9b8d..f2c48f09824e 100644
--- a/arch/arm/boot/dts/omap44xx-clocks.dtsi
+++ b/arch/arm/boot/dts/omap44xx-clocks.dtsi
@@ -1018,14 +1018,6 @@
1018 reg = <0x1120>; 1018 reg = <0x1120>;
1019 }; 1019 };
1020 1020
1021 dss_fck: dss_fck {
1022 #clock-cells = <0>;
1023 compatible = "ti,gate-clock";
1024 clocks = <&l3_div_ck>;
1025 ti,bit-shift = <1>;
1026 reg = <0x1120>;
1027 };
1028
1029 fdif_fck: fdif_fck { 1021 fdif_fck: fdif_fck {
1030 #clock-cells = <0>; 1022 #clock-cells = <0>;
1031 compatible = "ti,divider-clock"; 1023 compatible = "ti,divider-clock";
diff --git a/arch/arm/boot/dts/ste-dbx5x0.dtsi b/arch/arm/boot/dts/ste-dbx5x0.dtsi
index 9d2323020d34..bfd3f1c734b8 100644
--- a/arch/arm/boot/dts/ste-dbx5x0.dtsi
+++ b/arch/arm/boot/dts/ste-dbx5x0.dtsi
@@ -11,6 +11,7 @@
11 11
12#include <dt-bindings/interrupt-controller/irq.h> 12#include <dt-bindings/interrupt-controller/irq.h>
13#include <dt-bindings/mfd/dbx500-prcmu.h> 13#include <dt-bindings/mfd/dbx500-prcmu.h>
14#include <dt-bindings/arm/ux500_pm_domains.h>
14#include "skeleton.dtsi" 15#include "skeleton.dtsi"
15 16
16/ { 17/ {
@@ -43,6 +44,10 @@
43 interrupts = <0 7 IRQ_TYPE_LEVEL_HIGH>; 44 interrupts = <0 7 IRQ_TYPE_LEVEL_HIGH>;
44 }; 45 };
45 46
47 pm_domains: pm_domains0 {
48 compatible = "stericsson,ux500-pm-domains";
49 #power-domain-cells = <1>;
50 };
46 51
47 clocks { 52 clocks {
48 compatible = "stericsson,u8500-clks"; 53 compatible = "stericsson,u8500-clks";
@@ -636,6 +641,7 @@
636 clock-frequency = <400000>; 641 clock-frequency = <400000>;
637 clocks = <&prcc_kclk 3 3>, <&prcc_pclk 3 3>; 642 clocks = <&prcc_kclk 3 3>, <&prcc_pclk 3 3>;
638 clock-names = "i2cclk", "apb_pclk"; 643 clock-names = "i2cclk", "apb_pclk";
644 power-domains = <&pm_domains DOMAIN_VAPE>;
639 }; 645 };
640 646
641 i2c@80122000 { 647 i2c@80122000 {
@@ -651,6 +657,7 @@
651 657
652 clocks = <&prcc_kclk 1 2>, <&prcc_pclk 1 2>; 658 clocks = <&prcc_kclk 1 2>, <&prcc_pclk 1 2>;
653 clock-names = "i2cclk", "apb_pclk"; 659 clock-names = "i2cclk", "apb_pclk";
660 power-domains = <&pm_domains DOMAIN_VAPE>;
654 }; 661 };
655 662
656 i2c@80128000 { 663 i2c@80128000 {
@@ -666,6 +673,7 @@
666 673
667 clocks = <&prcc_kclk 1 6>, <&prcc_pclk 1 6>; 674 clocks = <&prcc_kclk 1 6>, <&prcc_pclk 1 6>;
668 clock-names = "i2cclk", "apb_pclk"; 675 clock-names = "i2cclk", "apb_pclk";
676 power-domains = <&pm_domains DOMAIN_VAPE>;
669 }; 677 };
670 678
671 i2c@80110000 { 679 i2c@80110000 {
@@ -681,6 +689,7 @@
681 689
682 clocks = <&prcc_kclk 2 0>, <&prcc_pclk 2 0>; 690 clocks = <&prcc_kclk 2 0>, <&prcc_pclk 2 0>;
683 clock-names = "i2cclk", "apb_pclk"; 691 clock-names = "i2cclk", "apb_pclk";
692 power-domains = <&pm_domains DOMAIN_VAPE>;
684 }; 693 };
685 694
686 i2c@8012a000 { 695 i2c@8012a000 {
@@ -696,6 +705,7 @@
696 705
697 clocks = <&prcc_kclk 1 9>, <&prcc_pclk 1 10>; 706 clocks = <&prcc_kclk 1 9>, <&prcc_pclk 1 10>;
698 clock-names = "i2cclk", "apb_pclk"; 707 clock-names = "i2cclk", "apb_pclk";
708 power-domains = <&pm_domains DOMAIN_VAPE>;
699 }; 709 };
700 710
701 ssp@80002000 { 711 ssp@80002000 {
@@ -709,6 +719,7 @@
709 dmas = <&dma 8 0 0x2>, /* Logical - DevToMem */ 719 dmas = <&dma 8 0 0x2>, /* Logical - DevToMem */
710 <&dma 8 0 0x0>; /* Logical - MemToDev */ 720 <&dma 8 0 0x0>; /* Logical - MemToDev */
711 dma-names = "rx", "tx"; 721 dma-names = "rx", "tx";
722 power-domains = <&pm_domains DOMAIN_VAPE>;
712 }; 723 };
713 724
714 ssp@80003000 { 725 ssp@80003000 {
@@ -722,6 +733,7 @@
722 dmas = <&dma 9 0 0x2>, /* Logical - DevToMem */ 733 dmas = <&dma 9 0 0x2>, /* Logical - DevToMem */
723 <&dma 9 0 0x0>; /* Logical - MemToDev */ 734 <&dma 9 0 0x0>; /* Logical - MemToDev */
724 dma-names = "rx", "tx"; 735 dma-names = "rx", "tx";
736 power-domains = <&pm_domains DOMAIN_VAPE>;
725 }; 737 };
726 738
727 spi@8011a000 { 739 spi@8011a000 {
@@ -736,6 +748,7 @@
736 dmas = <&dma 0 0 0x2>, /* Logical - DevToMem */ 748 dmas = <&dma 0 0 0x2>, /* Logical - DevToMem */
737 <&dma 0 0 0x0>; /* Logical - MemToDev */ 749 <&dma 0 0 0x0>; /* Logical - MemToDev */
738 dma-names = "rx", "tx"; 750 dma-names = "rx", "tx";
751 power-domains = <&pm_domains DOMAIN_VAPE>;
739 }; 752 };
740 753
741 spi@80112000 { 754 spi@80112000 {
@@ -750,6 +763,7 @@
750 dmas = <&dma 35 0 0x2>, /* Logical - DevToMem */ 763 dmas = <&dma 35 0 0x2>, /* Logical - DevToMem */
751 <&dma 35 0 0x0>; /* Logical - MemToDev */ 764 <&dma 35 0 0x0>; /* Logical - MemToDev */
752 dma-names = "rx", "tx"; 765 dma-names = "rx", "tx";
766 power-domains = <&pm_domains DOMAIN_VAPE>;
753 }; 767 };
754 768
755 spi@80111000 { 769 spi@80111000 {
@@ -764,6 +778,7 @@
764 dmas = <&dma 33 0 0x2>, /* Logical - DevToMem */ 778 dmas = <&dma 33 0 0x2>, /* Logical - DevToMem */
765 <&dma 33 0 0x0>; /* Logical - MemToDev */ 779 <&dma 33 0 0x0>; /* Logical - MemToDev */
766 dma-names = "rx", "tx"; 780 dma-names = "rx", "tx";
781 power-domains = <&pm_domains DOMAIN_VAPE>;
767 }; 782 };
768 783
769 spi@80129000 { 784 spi@80129000 {
@@ -778,6 +793,7 @@
778 dmas = <&dma 40 0 0x2>, /* Logical - DevToMem */ 793 dmas = <&dma 40 0 0x2>, /* Logical - DevToMem */
779 <&dma 40 0 0x0>; /* Logical - MemToDev */ 794 <&dma 40 0 0x0>; /* Logical - MemToDev */
780 dma-names = "rx", "tx"; 795 dma-names = "rx", "tx";
796 power-domains = <&pm_domains DOMAIN_VAPE>;
781 }; 797 };
782 798
783 uart@80120000 { 799 uart@80120000 {
@@ -836,6 +852,7 @@
836 852
837 clocks = <&prcc_kclk 1 5>, <&prcc_pclk 1 5>; 853 clocks = <&prcc_kclk 1 5>, <&prcc_pclk 1 5>;
838 clock-names = "sdi", "apb_pclk"; 854 clock-names = "sdi", "apb_pclk";
855 power-domains = <&pm_domains DOMAIN_VAPE>;
839 856
840 status = "disabled"; 857 status = "disabled";
841 }; 858 };
@@ -851,6 +868,7 @@
851 868
852 clocks = <&prcc_kclk 2 4>, <&prcc_pclk 2 6>; 869 clocks = <&prcc_kclk 2 4>, <&prcc_pclk 2 6>;
853 clock-names = "sdi", "apb_pclk"; 870 clock-names = "sdi", "apb_pclk";
871 power-domains = <&pm_domains DOMAIN_VAPE>;
854 872
855 status = "disabled"; 873 status = "disabled";
856 }; 874 };
@@ -866,6 +884,7 @@
866 884
867 clocks = <&prcc_kclk 3 4>, <&prcc_pclk 3 4>; 885 clocks = <&prcc_kclk 3 4>, <&prcc_pclk 3 4>;
868 clock-names = "sdi", "apb_pclk"; 886 clock-names = "sdi", "apb_pclk";
887 power-domains = <&pm_domains DOMAIN_VAPE>;
869 888
870 status = "disabled"; 889 status = "disabled";
871 }; 890 };
@@ -881,6 +900,7 @@
881 900
882 clocks = <&prcc_kclk 2 5>, <&prcc_pclk 2 7>; 901 clocks = <&prcc_kclk 2 5>, <&prcc_pclk 2 7>;
883 clock-names = "sdi", "apb_pclk"; 902 clock-names = "sdi", "apb_pclk";
903 power-domains = <&pm_domains DOMAIN_VAPE>;
884 904
885 status = "disabled"; 905 status = "disabled";
886 }; 906 };
@@ -896,6 +916,7 @@
896 916
897 clocks = <&prcc_kclk 2 2>, <&prcc_pclk 2 4>; 917 clocks = <&prcc_kclk 2 2>, <&prcc_pclk 2 4>;
898 clock-names = "sdi", "apb_pclk"; 918 clock-names = "sdi", "apb_pclk";
919 power-domains = <&pm_domains DOMAIN_VAPE>;
899 920
900 status = "disabled"; 921 status = "disabled";
901 }; 922 };
@@ -911,6 +932,7 @@
911 932
912 clocks = <&prcc_kclk 3 7>, <&prcc_pclk 3 7>; 933 clocks = <&prcc_kclk 3 7>, <&prcc_pclk 3 7>;
913 clock-names = "sdi", "apb_pclk"; 934 clock-names = "sdi", "apb_pclk";
935 power-domains = <&pm_domains DOMAIN_VAPE>;
914 936
915 status = "disabled"; 937 status = "disabled";
916 }; 938 };
diff --git a/arch/arm/configs/bcm_defconfig b/arch/arm/configs/bcm_defconfig
index bc614f44b33d..83a87e48901c 100644
--- a/arch/arm/configs/bcm_defconfig
+++ b/arch/arm/configs/bcm_defconfig
@@ -25,7 +25,8 @@ CONFIG_MODULE_UNLOAD=y
25# CONFIG_BLK_DEV_BSG is not set 25# CONFIG_BLK_DEV_BSG is not set
26CONFIG_PARTITION_ADVANCED=y 26CONFIG_PARTITION_ADVANCED=y
27CONFIG_ARCH_BCM=y 27CONFIG_ARCH_BCM=y
28CONFIG_ARCH_BCM_MOBILE=y 28CONFIG_ARCH_BCM_21664=y
29CONFIG_ARCH_BCM_281XX=y
29CONFIG_ARM_THUMBEE=y 30CONFIG_ARM_THUMBEE=y
30CONFIG_SMP=y 31CONFIG_SMP=y
31CONFIG_PREEMPT=y 32CONFIG_PREEMPT=y
diff --git a/arch/arm/configs/integrator_defconfig b/arch/arm/configs/integrator_defconfig
index c1f5adc5493e..71f14675d009 100644
--- a/arch/arm/configs/integrator_defconfig
+++ b/arch/arm/configs/integrator_defconfig
@@ -8,6 +8,9 @@ CONFIG_BLK_DEV_INITRD=y
8CONFIG_MODULES=y 8CONFIG_MODULES=y
9CONFIG_MODULE_UNLOAD=y 9CONFIG_MODULE_UNLOAD=y
10CONFIG_PARTITION_ADVANCED=y 10CONFIG_PARTITION_ADVANCED=y
11CONFIG_ARCH_MULTI_V4T=y
12CONFIG_ARCH_MULTI_V5=y
13# CONFIG_ARCH_MULTI_V7 is not set
11CONFIG_ARCH_INTEGRATOR=y 14CONFIG_ARCH_INTEGRATOR=y
12CONFIG_ARCH_INTEGRATOR_AP=y 15CONFIG_ARCH_INTEGRATOR_AP=y
13CONFIG_ARCH_INTEGRATOR_CP=y 16CONFIG_ARCH_INTEGRATOR_CP=y
diff --git a/arch/arm/include/asm/firmware.h b/arch/arm/include/asm/firmware.h
index 2c9f10df7568..89aefe10d66b 100644
--- a/arch/arm/include/asm/firmware.h
+++ b/arch/arm/include/asm/firmware.h
@@ -28,7 +28,7 @@ struct firmware_ops {
28 /* 28 /*
29 * Enters CPU idle mode 29 * Enters CPU idle mode
30 */ 30 */
31 int (*do_idle)(void); 31 int (*do_idle)(unsigned long mode);
32 /* 32 /*
33 * Sets boot address of specified physical CPU 33 * Sets boot address of specified physical CPU
34 */ 34 */
@@ -41,6 +41,14 @@ struct firmware_ops {
41 * Initializes L2 cache 41 * Initializes L2 cache
42 */ 42 */
43 int (*l2x0_init)(void); 43 int (*l2x0_init)(void);
44 /*
45 * Enter system-wide suspend.
46 */
47 int (*suspend)(void);
48 /*
49 * Restore state of privileged hardware after system-wide suspend.
50 */
51 int (*resume)(void);
44}; 52};
45 53
46/* Global pointer for current firmware_ops structure, can't be NULL. */ 54/* Global pointer for current firmware_ops structure, can't be NULL. */
diff --git a/arch/arm/include/debug/asm9260.S b/arch/arm/include/debug/asm9260.S
new file mode 100644
index 000000000000..292f85b49fca
--- /dev/null
+++ b/arch/arm/include/debug/asm9260.S
@@ -0,0 +1,29 @@
1/* Debugging macro include header
2 *
3 * Copyright (C) 1994-1999 Russell King
4 * Moved from linux/arch/arm/kernel/debug.S by Ben Dooks
5 * Modified for ASM9260 by Oleksij Remepl <linux@rempel-privat.de>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 *
11 */
12
13 .macro addruart, rp, rv, tmp
14 ldr \rp, = CONFIG_DEBUG_UART_PHYS
15 ldr \rv, = CONFIG_DEBUG_UART_VIRT
16 .endm
17
18 .macro waituart,rd,rx
19 .endm
20
21 .macro senduart,rd,rx
22 str \rd, [\rx, #0x50] @ TXDATA
23 .endm
24
25 .macro busyuart,rd,rx
261002: ldr \rd, [\rx, #0x60] @ STAT
27 tst \rd, #1 << 27 @ TXEMPTY
28 beq 1002b @ wait until transmit done
29 .endm
diff --git a/arch/arm/include/debug/renesas-scif.S b/arch/arm/include/debug/renesas-scif.S
new file mode 100644
index 000000000000..97820a8df51a
--- /dev/null
+++ b/arch/arm/include/debug/renesas-scif.S
@@ -0,0 +1,52 @@
1/*
2 * Renesas SCIF(A) debugging macro include header
3 *
4 * Based on r8a7790.S
5 *
6 * Copyright (C) 2012-2013 Renesas Electronics Corporation
7 * Copyright (C) 1994-1999 Russell King
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12 */
13
14#define SCIF_PHYS CONFIG_DEBUG_UART_PHYS
15#define SCIF_VIRT ((SCIF_PHYS & 0x00ffffff) | 0xfd000000)
16
17#if CONFIG_DEBUG_UART_PHYS < 0xe6e00000
18/* SCIFA */
19#define FTDR 0x20
20#define FSR 0x14
21#else
22/* SCIF */
23#define FTDR 0x0c
24#define FSR 0x10
25#endif
26
27#define TDFE (1 << 5)
28#define TEND (1 << 6)
29
30 .macro addruart, rp, rv, tmp
31 ldr \rp, =SCIF_PHYS
32 ldr \rv, =SCIF_VIRT
33 .endm
34
35 .macro waituart, rd, rx
361001: ldrh \rd, [\rx, #FSR]
37 tst \rd, #TDFE
38 beq 1001b
39 .endm
40
41 .macro senduart, rd, rx
42 strb \rd, [\rx, #FTDR]
43 ldrh \rd, [\rx, #FSR]
44 bic \rd, \rd, #TEND
45 strh \rd, [\rx, #FSR]
46 .endm
47
48 .macro busyuart, rd, rx
491001: ldrh \rd, [\rx, #FSR]
50 tst \rd, #TEND
51 beq 1001b
52 .endm
diff --git a/arch/arm/mach-sa1100/include/mach/debug-macro.S b/arch/arm/include/debug/sa1100.S
index 530772d937ad..a0ae4f4cd924 100644
--- a/arch/arm/mach-sa1100/include/mach/debug-macro.S
+++ b/arch/arm/include/debug/sa1100.S
@@ -1,4 +1,4 @@
1/* arch/arm/mach-sa1100/include/mach/debug-macro.S 1/* arch/arm/include/debug/sa1100.S
2 * 2 *
3 * Debugging macro include header 3 * Debugging macro include header
4 * 4 *
@@ -10,7 +10,13 @@
10 * published by the Free Software Foundation. 10 * published by the Free Software Foundation.
11 * 11 *
12*/ 12*/
13#include <mach/hardware.h> 13
14#define UTCR3 0x0c
15#define UTDR 0x14
16#define UTSR1 0x20
17#define UTCR3_TXE 0x00000002 /* Transmit Enable */
18#define UTSR1_TBY 0x00000001 /* Transmitter BusY (read) */
19#define UTSR1_TNF 0x00000004 /* Transmit FIFO Not Full (read) */
14 20
15 .macro addruart, rp, rv, tmp 21 .macro addruart, rp, rv, tmp
16 mrc p15, 0, \rp, c1, c0 22 mrc p15, 0, \rp, c1, c0
diff --git a/arch/arm/mach-asm9260/Kconfig b/arch/arm/mach-asm9260/Kconfig
new file mode 100644
index 000000000000..8423be76080e
--- /dev/null
+++ b/arch/arm/mach-asm9260/Kconfig
@@ -0,0 +1,6 @@
1config MACH_ASM9260
2 bool "Alphascale ASM9260"
3 depends on ARCH_MULTI_V5
4 select CPU_ARM926T
5 help
6 Support for Alphascale ASM9260 based platform.
diff --git a/arch/arm/mach-bcm/Kconfig b/arch/arm/mach-bcm/Kconfig
index 2abad742516d..1bd39b45d08b 100644
--- a/arch/arm/mach-bcm/Kconfig
+++ b/arch/arm/mach-bcm/Kconfig
@@ -5,8 +5,56 @@ menuconfig ARCH_BCM
5 5
6if ARCH_BCM 6if ARCH_BCM
7 7
8comment "IPROC architected SoCs"
9
10config ARCH_BCM_IPROC
11 bool
12 select ARM_GIC
13 select CACHE_L2X0
14 select HAVE_ARM_SCU if SMP
15 select HAVE_ARM_TWD if SMP
16 select ARM_GLOBAL_TIMER
17
18 select CLKSRC_MMIO
19 select ARCH_REQUIRE_GPIOLIB
20 select ARM_AMBA
21 select PINCTRL
22 help
23 This enables support for systems based on Broadcom IPROC architected SoCs.
24 The IPROC complex contains one or more ARM CPUs along with common
25 core periperals. Application specific SoCs are created by adding a
26 uArchitecture containing peripherals outside of the IPROC complex.
27 Currently supported SoCs are Cygnus.
28
29config ARCH_BCM_CYGNUS
30 bool "Broadcom Cygnus Support" if ARCH_MULTI_V7
31 select ARCH_BCM_IPROC
32 help
33 Enable support for the Cygnus family,
34 which includes the following variants:
35 BCM11300, BCM11320, BCM11350, BCM11360,
36 BCM58300, BCM58302, BCM58303, BCM58305.
37
38config ARCH_BCM_5301X
39 bool "Broadcom BCM470X / BCM5301X ARM SoC" if ARCH_MULTI_V7
40 select ARCH_BCM_IPROC
41 help
42 Support for Broadcom BCM470X and BCM5301X SoCs with ARM CPU cores.
43
44 This is a network SoC line mostly used in home routers and
45 wifi access points, it's internal name is Northstar.
46 This inclused the following SoC: BCM53010, BCM53011, BCM53012,
47 BCM53014, BCM53015, BCM53016, BCM53017, BCM53018, BCM4707,
48 BCM4708 and BCM4709.
49
50 Do not confuse this with the BCM4760 which is a totally
51 different SoC or with the older BCM47XX and BCM53XX based
52 network SoC using a MIPS CPU, they are supported by arch/mips/bcm47xx
53
54comment "KONA architected SoCs"
55
8config ARCH_BCM_MOBILE 56config ARCH_BCM_MOBILE
9 bool "Broadcom Mobile SoC Support" if ARCH_MULTI_V7 57 bool
10 select ARCH_REQUIRE_GPIOLIB 58 select ARCH_REQUIRE_GPIOLIB
11 select ARM_ERRATA_754322 59 select ARM_ERRATA_754322
12 select ARM_ERRATA_775420 60 select ARM_ERRATA_775420
@@ -15,16 +63,13 @@ config ARCH_BCM_MOBILE
15 select TICK_ONESHOT 63 select TICK_ONESHOT
16 select HAVE_ARM_ARCH_TIMER 64 select HAVE_ARM_ARCH_TIMER
17 select PINCTRL 65 select PINCTRL
66 select ARCH_BCM_MOBILE_SMP if SMP
18 help 67 help
19 This enables support for systems based on Broadcom mobile SoCs. 68 This enables support for systems based on Broadcom mobile SoCs.
20 69
21if ARCH_BCM_MOBILE
22
23menu "Broadcom Mobile SoC Selection"
24
25config ARCH_BCM_281XX 70config ARCH_BCM_281XX
26 bool "Broadcom BCM281XX SoC family" 71 bool "Broadcom BCM281XX SoC family"
27 default y 72 select ARCH_BCM_MOBILE
28 select HAVE_SMP 73 select HAVE_SMP
29 help 74 help
30 Enable support for the BCM281XX family, which includes 75 Enable support for the BCM281XX family, which includes
@@ -33,7 +78,7 @@ config ARCH_BCM_281XX
33 78
34config ARCH_BCM_21664 79config ARCH_BCM_21664
35 bool "Broadcom BCM21664 SoC family" 80 bool "Broadcom BCM21664 SoC family"
36 default y 81 select ARCH_BCM_MOBILE
37 select HAVE_SMP 82 select HAVE_SMP
38 help 83 help
39 Enable support for the BCM21664 family, which includes 84 Enable support for the BCM21664 family, which includes
@@ -41,19 +86,18 @@ config ARCH_BCM_21664
41 86
42config ARCH_BCM_MOBILE_L2_CACHE 87config ARCH_BCM_MOBILE_L2_CACHE
43 bool "Broadcom mobile SoC level 2 cache support" 88 bool "Broadcom mobile SoC level 2 cache support"
44 depends on (ARCH_BCM_281XX || ARCH_BCM_21664) 89 depends on ARCH_BCM_MOBILE
45 default y 90 default y
46 select CACHE_L2X0 91 select CACHE_L2X0
47 select ARCH_BCM_MOBILE_SMC 92 select ARCH_BCM_MOBILE_SMC
48 93
49config ARCH_BCM_MOBILE_SMC 94config ARCH_BCM_MOBILE_SMC
50 bool 95 bool
51 depends on ARCH_BCM_281XX || ARCH_BCM_21664 96 depends on ARCH_BCM_MOBILE
52 97
53config ARCH_BCM_MOBILE_SMP 98config ARCH_BCM_MOBILE_SMP
54 bool "Broadcom mobile SoC SMP support" 99 bool
55 depends on (ARCH_BCM_281XX || ARCH_BCM_21664) && SMP 100 depends on ARCH_BCM_MOBILE
56 default y
57 select HAVE_ARM_SCU 101 select HAVE_ARM_SCU
58 select ARM_ERRATA_764369 102 select ARM_ERRATA_764369
59 help 103 help
@@ -61,9 +105,7 @@ config ARCH_BCM_MOBILE_SMP
61 Provided as an option so SMP support for SoCs of this type 105 Provided as an option so SMP support for SoCs of this type
62 can be disabled for an SMP-enabled kernel. 106 can be disabled for an SMP-enabled kernel.
63 107
64endmenu 108comment "Other Architectures"
65
66endif
67 109
68config ARCH_BCM2835 110config ARCH_BCM2835
69 bool "Broadcom BCM2835 family" if ARCH_MULTI_V6 111 bool "Broadcom BCM2835 family" if ARCH_MULTI_V6
@@ -78,27 +120,6 @@ config ARCH_BCM2835
78 This enables support for the Broadcom BCM2835 SoC. This SoC is 120 This enables support for the Broadcom BCM2835 SoC. This SoC is
79 used in the Raspberry Pi and Roku 2 devices. 121 used in the Raspberry Pi and Roku 2 devices.
80 122
81config ARCH_BCM_5301X
82 bool "Broadcom BCM470X / BCM5301X ARM SoC" if ARCH_MULTI_V7
83 select ARM_GIC
84 select CACHE_L2X0
85 select HAVE_ARM_SCU if SMP
86 select HAVE_ARM_TWD if SMP
87 select ARM_GLOBAL_TIMER
88 select CLKSRC_ARM_GLOBAL_TIMER_SCHED_CLOCK
89 help
90 Support for Broadcom BCM470X and BCM5301X SoCs with ARM CPU cores.
91
92 This is a network SoC line mostly used in home routers and
93 wifi access points, it's internal name is Northstar.
94 This inclused the following SoC: BCM53010, BCM53011, BCM53012,
95 BCM53014, BCM53015, BCM53016, BCM53017, BCM53018, BCM4707,
96 BCM4708 and BCM4709.
97
98 Do not confuse this with the BCM4760 which is a totally
99 different SoC or with the older BCM47XX and BCM53XX based
100 network SoC using a MIPS CPU, they are supported by arch/mips/bcm47xx
101
102config ARCH_BCM_63XX 123config ARCH_BCM_63XX
103 bool "Broadcom BCM63xx DSL SoC" if ARCH_MULTI_V7 124 bool "Broadcom BCM63xx DSL SoC" if ARCH_MULTI_V7
104 depends on MMU 125 depends on MMU
@@ -118,10 +139,7 @@ config ARCH_BCM_63XX
118 139
119config ARCH_BRCMSTB 140config ARCH_BRCMSTB
120 bool "Broadcom BCM7XXX based boards" if ARCH_MULTI_V7 141 bool "Broadcom BCM7XXX based boards" if ARCH_MULTI_V7
121 depends on MMU
122 select ARM_GIC 142 select ARM_GIC
123 select MIGHT_HAVE_PCI
124 select HAVE_SMP
125 select HAVE_ARM_ARCH_TIMER 143 select HAVE_ARM_ARCH_TIMER
126 select BRCMSTB_GISB_ARB 144 select BRCMSTB_GISB_ARB
127 select BRCMSTB_L2_IRQ 145 select BRCMSTB_L2_IRQ
diff --git a/arch/arm/mach-bcm/Makefile b/arch/arm/mach-bcm/Makefile
index 300ae4b79ae6..4c38674c73ec 100644
--- a/arch/arm/mach-bcm/Makefile
+++ b/arch/arm/mach-bcm/Makefile
@@ -10,6 +10,9 @@
10# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11# GNU General Public License for more details. 11# GNU General Public License for more details.
12 12
13# Cygnus
14obj-$(CONFIG_ARCH_BCM_CYGNUS) += bcm_cygnus.o
15
13# BCM281XX 16# BCM281XX
14obj-$(CONFIG_ARCH_BCM_281XX) += board_bcm281xx.o 17obj-$(CONFIG_ARCH_BCM_281XX) += board_bcm281xx.o
15 18
@@ -38,5 +41,7 @@ obj-$(CONFIG_ARCH_BCM_5301X) += bcm_5301x.o
38obj-$(CONFIG_ARCH_BCM_63XX) := bcm63xx.o 41obj-$(CONFIG_ARCH_BCM_63XX) := bcm63xx.o
39 42
40ifeq ($(CONFIG_ARCH_BRCMSTB),y) 43ifeq ($(CONFIG_ARCH_BRCMSTB),y)
44CFLAGS_platsmp-brcmstb.o += -march=armv7-a
41obj-y += brcmstb.o 45obj-y += brcmstb.o
46obj-$(CONFIG_SMP) += headsmp-brcmstb.o platsmp-brcmstb.o
42endif 47endif
diff --git a/arch/arm/mach-bcm/bcm_cygnus.c b/arch/arm/mach-bcm/bcm_cygnus.c
new file mode 100644
index 000000000000..30dc58be51b8
--- /dev/null
+++ b/arch/arm/mach-bcm/bcm_cygnus.c
@@ -0,0 +1,25 @@
1/*
2 * Copyright (C) 2014 Broadcom Corporation
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License as
6 * published by the Free Software Foundation version 2.
7 *
8 * This program is distributed "as is" WITHOUT ANY WARRANTY of any
9 * kind, whether express or implied; without even the implied warranty
10 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 */
13
14#include <asm/mach/arch.h>
15
16static const char const *bcm_cygnus_dt_compat[] = {
17 "brcm,cygnus",
18 NULL,
19};
20
21DT_MACHINE_START(BCM_CYGNUS_DT, "Broadcom Cygnus SoC")
22 .l2c_aux_val = 0,
23 .l2c_aux_mask = ~0,
24 .dt_compat = bcm_cygnus_dt_compat,
25MACHINE_END
diff --git a/arch/arm/mach-bcm/brcmstb.h b/arch/arm/mach-bcm/brcmstb.h
new file mode 100644
index 000000000000..ec0c3d112b36
--- /dev/null
+++ b/arch/arm/mach-bcm/brcmstb.h
@@ -0,0 +1,19 @@
1/*
2 * Copyright (C) 2013-2014 Broadcom Corporation
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License as
6 * published by the Free Software Foundation version 2.
7 *
8 * This program is distributed "as is" WITHOUT ANY WARRANTY of any
9 * kind, whether express or implied; without even the implied warranty
10 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 */
13
14#ifndef __BRCMSTB_H__
15#define __BRCMSTB_H__
16
17void brcmstb_secondary_startup(void);
18
19#endif /* __BRCMSTB_H__ */
diff --git a/arch/arm/mach-bcm/headsmp-brcmstb.S b/arch/arm/mach-bcm/headsmp-brcmstb.S
new file mode 100644
index 000000000000..199c1ea58248
--- /dev/null
+++ b/arch/arm/mach-bcm/headsmp-brcmstb.S
@@ -0,0 +1,33 @@
1/*
2 * SMP boot code for secondary CPUs
3 * Based on arch/arm/mach-tegra/headsmp.S
4 *
5 * Copyright (C) 2010 NVIDIA, Inc.
6 * Copyright (C) 2013-2014 Broadcom Corporation
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License as
10 * published by the Free Software Foundation version 2.
11 *
12 * This program is distributed "as is" WITHOUT ANY WARRANTY of any
13 * kind, whether express or implied; without even the implied warranty
14 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 */
17
18#include <asm/assembler.h>
19#include <linux/linkage.h>
20#include <linux/init.h>
21
22 .section ".text.head", "ax"
23
24ENTRY(brcmstb_secondary_startup)
25 /*
26 * Ensure CPU is in a sane state by disabling all IRQs and switching
27 * into SVC mode.
28 */
29 setmode PSR_I_BIT | PSR_F_BIT | SVC_MODE, r0
30
31 bl v7_invalidate_l1
32 b secondary_startup
33ENDPROC(brcmstb_secondary_startup)
diff --git a/arch/arm/mach-bcm/platsmp-brcmstb.c b/arch/arm/mach-bcm/platsmp-brcmstb.c
new file mode 100644
index 000000000000..31c87a284a34
--- /dev/null
+++ b/arch/arm/mach-bcm/platsmp-brcmstb.c
@@ -0,0 +1,329 @@
1/*
2 * Broadcom STB CPU SMP and hotplug support for ARM
3 *
4 * Copyright (C) 2013-2014 Broadcom Corporation
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as
8 * published by the Free Software Foundation version 2.
9 *
10 * This program is distributed "as is" WITHOUT ANY WARRANTY of any
11 * kind, whether express or implied; without even the implied warranty
12 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 */
15
16#include <linux/delay.h>
17#include <linux/errno.h>
18#include <linux/init.h>
19#include <linux/io.h>
20#include <linux/of_address.h>
21#include <linux/of_platform.h>
22#include <linux/printk.h>
23#include <linux/regmap.h>
24#include <linux/smp.h>
25#include <linux/mfd/syscon.h>
26
27#include <asm/cacheflush.h>
28#include <asm/cp15.h>
29#include <asm/mach-types.h>
30#include <asm/smp_plat.h>
31
32#include "brcmstb.h"
33
34enum {
35 ZONE_MAN_CLKEN_MASK = BIT(0),
36 ZONE_MAN_RESET_CNTL_MASK = BIT(1),
37 ZONE_MAN_MEM_PWR_MASK = BIT(4),
38 ZONE_RESERVED_1_MASK = BIT(5),
39 ZONE_MAN_ISO_CNTL_MASK = BIT(6),
40 ZONE_MANUAL_CONTROL_MASK = BIT(7),
41 ZONE_PWR_DN_REQ_MASK = BIT(9),
42 ZONE_PWR_UP_REQ_MASK = BIT(10),
43 ZONE_BLK_RST_ASSERT_MASK = BIT(12),
44 ZONE_PWR_OFF_STATE_MASK = BIT(25),
45 ZONE_PWR_ON_STATE_MASK = BIT(26),
46 ZONE_DPG_PWR_STATE_MASK = BIT(28),
47 ZONE_MEM_PWR_STATE_MASK = BIT(29),
48 ZONE_RESET_STATE_MASK = BIT(31),
49 CPU0_PWR_ZONE_CTRL_REG = 1,
50 CPU_RESET_CONFIG_REG = 2,
51};
52
53static void __iomem *cpubiuctrl_block;
54static void __iomem *hif_cont_block;
55static u32 cpu0_pwr_zone_ctrl_reg;
56static u32 cpu_rst_cfg_reg;
57static u32 hif_cont_reg;
58
59#ifdef CONFIG_HOTPLUG_CPU
60/*
61 * We must quiesce a dying CPU before it can be killed by the boot CPU. Because
62 * one or more cache may be disabled, we must flush to ensure coherency. We
63 * cannot use traditionl completion structures or spinlocks as they rely on
64 * coherency.
65 */
66static DEFINE_PER_CPU_ALIGNED(int, per_cpu_sw_state);
67
68static int per_cpu_sw_state_rd(u32 cpu)
69{
70 sync_cache_r(SHIFT_PERCPU_PTR(&per_cpu_sw_state, per_cpu_offset(cpu)));
71 return per_cpu(per_cpu_sw_state, cpu);
72}
73
74static void per_cpu_sw_state_wr(u32 cpu, int val)
75{
76 dmb();
77 per_cpu(per_cpu_sw_state, cpu) = val;
78 sync_cache_w(SHIFT_PERCPU_PTR(&per_cpu_sw_state, per_cpu_offset(cpu)));
79}
80#else
81static inline void per_cpu_sw_state_wr(u32 cpu, int val) { }
82#endif
83
84static void __iomem *pwr_ctrl_get_base(u32 cpu)
85{
86 void __iomem *base = cpubiuctrl_block + cpu0_pwr_zone_ctrl_reg;
87 base += (cpu_logical_map(cpu) * 4);
88 return base;
89}
90
91static u32 pwr_ctrl_rd(u32 cpu)
92{
93 void __iomem *base = pwr_ctrl_get_base(cpu);
94 return readl_relaxed(base);
95}
96
97static void pwr_ctrl_wr(u32 cpu, u32 val)
98{
99 void __iomem *base = pwr_ctrl_get_base(cpu);
100 writel(val, base);
101}
102
103static void cpu_rst_cfg_set(u32 cpu, int set)
104{
105 u32 val;
106 val = readl_relaxed(cpubiuctrl_block + cpu_rst_cfg_reg);
107 if (set)
108 val |= BIT(cpu_logical_map(cpu));
109 else
110 val &= ~BIT(cpu_logical_map(cpu));
111 writel_relaxed(val, cpubiuctrl_block + cpu_rst_cfg_reg);
112}
113
114static void cpu_set_boot_addr(u32 cpu, unsigned long boot_addr)
115{
116 const int reg_ofs = cpu_logical_map(cpu) * 8;
117 writel_relaxed(0, hif_cont_block + hif_cont_reg + reg_ofs);
118 writel_relaxed(boot_addr, hif_cont_block + hif_cont_reg + 4 + reg_ofs);
119}
120
121static void brcmstb_cpu_boot(u32 cpu)
122{
123 /* Mark this CPU as "up" */
124 per_cpu_sw_state_wr(cpu, 1);
125
126 /*
127 * Set the reset vector to point to the secondary_startup
128 * routine
129 */
130 cpu_set_boot_addr(cpu, virt_to_phys(brcmstb_secondary_startup));
131
132 /* Unhalt the cpu */
133 cpu_rst_cfg_set(cpu, 0);
134}
135
136static void brcmstb_cpu_power_on(u32 cpu)
137{
138 /*
139 * The secondary cores power was cut, so we must go through
140 * power-on initialization.
141 */
142 u32 tmp;
143
144 /* Request zone power up */
145 pwr_ctrl_wr(cpu, ZONE_PWR_UP_REQ_MASK);
146
147 /* Wait for the power up FSM to complete */
148 do {
149 tmp = pwr_ctrl_rd(cpu);
150 } while (!(tmp & ZONE_PWR_ON_STATE_MASK));
151}
152
153static int brcmstb_cpu_get_power_state(u32 cpu)
154{
155 int tmp = pwr_ctrl_rd(cpu);
156 return (tmp & ZONE_RESET_STATE_MASK) ? 0 : 1;
157}
158
159#ifdef CONFIG_HOTPLUG_CPU
160
161static void brcmstb_cpu_die(u32 cpu)
162{
163 v7_exit_coherency_flush(all);
164
165 per_cpu_sw_state_wr(cpu, 0);
166
167 /* Sit and wait to die */
168 wfi();
169
170 /* We should never get here... */
171 while (1)
172 ;
173}
174
175static int brcmstb_cpu_kill(u32 cpu)
176{
177 u32 tmp;
178
179 while (per_cpu_sw_state_rd(cpu))
180 ;
181
182 /* Program zone reset */
183 pwr_ctrl_wr(cpu, ZONE_RESET_STATE_MASK | ZONE_BLK_RST_ASSERT_MASK |
184 ZONE_PWR_DN_REQ_MASK);
185
186 /* Verify zone reset */
187 tmp = pwr_ctrl_rd(cpu);
188 if (!(tmp & ZONE_RESET_STATE_MASK))
189 pr_err("%s: Zone reset bit for CPU %d not asserted!\n",
190 __func__, cpu);
191
192 /* Wait for power down */
193 do {
194 tmp = pwr_ctrl_rd(cpu);
195 } while (!(tmp & ZONE_PWR_OFF_STATE_MASK));
196
197 /* Flush pipeline before resetting CPU */
198 mb();
199
200 /* Assert reset on the CPU */
201 cpu_rst_cfg_set(cpu, 1);
202
203 return 1;
204}
205
206#endif /* CONFIG_HOTPLUG_CPU */
207
208static int __init setup_hifcpubiuctrl_regs(struct device_node *np)
209{
210 int rc = 0;
211 char *name;
212 struct device_node *syscon_np = NULL;
213
214 name = "syscon-cpu";
215
216 syscon_np = of_parse_phandle(np, name, 0);
217 if (!syscon_np) {
218 pr_err("can't find phandle %s\n", name);
219 rc = -EINVAL;
220 goto cleanup;
221 }
222
223 cpubiuctrl_block = of_iomap(syscon_np, 0);
224 if (!cpubiuctrl_block) {
225 pr_err("iomap failed for cpubiuctrl_block\n");
226 rc = -EINVAL;
227 goto cleanup;
228 }
229
230 rc = of_property_read_u32_index(np, name, CPU0_PWR_ZONE_CTRL_REG,
231 &cpu0_pwr_zone_ctrl_reg);
232 if (rc) {
233 pr_err("failed to read 1st entry from %s property (%d)\n", name,
234 rc);
235 rc = -EINVAL;
236 goto cleanup;
237 }
238
239 rc = of_property_read_u32_index(np, name, CPU_RESET_CONFIG_REG,
240 &cpu_rst_cfg_reg);
241 if (rc) {
242 pr_err("failed to read 2nd entry from %s property (%d)\n", name,
243 rc);
244 rc = -EINVAL;
245 goto cleanup;
246 }
247
248cleanup:
249 of_node_put(syscon_np);
250 return rc;
251}
252
253static int __init setup_hifcont_regs(struct device_node *np)
254{
255 int rc = 0;
256 char *name;
257 struct device_node *syscon_np = NULL;
258
259 name = "syscon-cont";
260
261 syscon_np = of_parse_phandle(np, name, 0);
262 if (!syscon_np) {
263 pr_err("can't find phandle %s\n", name);
264 rc = -EINVAL;
265 goto cleanup;
266 }
267
268 hif_cont_block = of_iomap(syscon_np, 0);
269 if (!hif_cont_block) {
270 pr_err("iomap failed for hif_cont_block\n");
271 rc = -EINVAL;
272 goto cleanup;
273 }
274
275 /* Offset is at top of hif_cont_block */
276 hif_cont_reg = 0;
277
278cleanup:
279 of_node_put(syscon_np);
280 return rc;
281}
282
283static void __init brcmstb_cpu_ctrl_setup(unsigned int max_cpus)
284{
285 int rc;
286 struct device_node *np;
287 char *name;
288
289 name = "brcm,brcmstb-smpboot";
290 np = of_find_compatible_node(NULL, NULL, name);
291 if (!np) {
292 pr_err("can't find compatible node %s\n", name);
293 return;
294 }
295
296 rc = setup_hifcpubiuctrl_regs(np);
297 if (rc)
298 return;
299
300 rc = setup_hifcont_regs(np);
301 if (rc)
302 return;
303}
304
305static int brcmstb_boot_secondary(unsigned int cpu, struct task_struct *idle)
306{
307 /* Missing the brcm,brcmstb-smpboot DT node? */
308 if (!cpubiuctrl_block || !hif_cont_block)
309 return -ENODEV;
310
311 /* Bring up power to the core if necessary */
312 if (brcmstb_cpu_get_power_state(cpu) == 0)
313 brcmstb_cpu_power_on(cpu);
314
315 brcmstb_cpu_boot(cpu);
316
317 return 0;
318}
319
320static struct smp_operations brcmstb_smp_ops __initdata = {
321 .smp_prepare_cpus = brcmstb_cpu_ctrl_setup,
322 .smp_boot_secondary = brcmstb_boot_secondary,
323#ifdef CONFIG_HOTPLUG_CPU
324 .cpu_kill = brcmstb_cpu_kill,
325 .cpu_die = brcmstb_cpu_die,
326#endif
327};
328
329CPU_METHOD_OF_DECLARE(brcmstb_smp, "brcm,brahma-b15", &brcmstb_smp_ops);
diff --git a/arch/arm/mach-berlin/Kconfig b/arch/arm/mach-berlin/Kconfig
index 24f85be71671..3e40a947f3ea 100644
--- a/arch/arm/mach-berlin/Kconfig
+++ b/arch/arm/mach-berlin/Kconfig
@@ -1,10 +1,11 @@
1menuconfig ARCH_BERLIN 1menuconfig ARCH_BERLIN
2 bool "Marvell Berlin SoCs" if ARCH_MULTI_V7 2 bool "Marvell Berlin SoCs" if ARCH_MULTI_V7
3 select ARCH_HAS_RESET_CONTROLLER
3 select ARCH_REQUIRE_GPIOLIB 4 select ARCH_REQUIRE_GPIOLIB
4 select ARM_GIC 5 select ARM_GIC
5 select GENERIC_IRQ_CHIP
6 select DW_APB_ICTL 6 select DW_APB_ICTL
7 select DW_APB_TIMER_OF 7 select DW_APB_TIMER_OF
8 select GENERIC_IRQ_CHIP
8 select PINCTRL 9 select PINCTRL
9 10
10if ARCH_BERLIN 11if ARCH_BERLIN
diff --git a/arch/arm/mach-exynos/Kconfig b/arch/arm/mach-exynos/Kconfig
index 2d0240f241b8..b9e3f1c61baf 100644
--- a/arch/arm/mach-exynos/Kconfig
+++ b/arch/arm/mach-exynos/Kconfig
@@ -24,6 +24,7 @@ menuconfig ARCH_EXYNOS
24 select PM_GENERIC_DOMAINS if PM_RUNTIME 24 select PM_GENERIC_DOMAINS if PM_RUNTIME
25 select S5P_DEV_MFC 25 select S5P_DEV_MFC
26 select SRAM 26 select SRAM
27 select MFD_SYSCON
27 help 28 help
28 Support for SAMSUNG EXYNOS SoCs (EXYNOS4/5) 29 Support for SAMSUNG EXYNOS SoCs (EXYNOS4/5)
29 30
@@ -75,6 +76,11 @@ config SOC_EXYNOS4412
75 default y 76 default y
76 depends on ARCH_EXYNOS4 77 depends on ARCH_EXYNOS4
77 78
79config SOC_EXYNOS4415
80 bool "SAMSUNG EXYNOS4415"
81 default y
82 depends on ARCH_EXYNOS4
83
78config SOC_EXYNOS5250 84config SOC_EXYNOS5250
79 bool "SAMSUNG EXYNOS5250" 85 bool "SAMSUNG EXYNOS5250"
80 default y 86 default y
@@ -123,4 +129,9 @@ config EXYNOS5420_MCPM
123 This is needed to provide CPU and cluster power management 129 This is needed to provide CPU and cluster power management
124 on Exynos5420 implementing big.LITTLE. 130 on Exynos5420 implementing big.LITTLE.
125 131
132config EXYNOS_CPU_SUSPEND
133 bool
134 select ARM_CPU_SUSPEND
135 default PM_SLEEP || ARM_EXYNOS_CPUIDLE
136
126endif 137endif
diff --git a/arch/arm/mach-exynos/Makefile b/arch/arm/mach-exynos/Makefile
index d634de588d96..bcefb5473ee4 100644
--- a/arch/arm/mach-exynos/Makefile
+++ b/arch/arm/mach-exynos/Makefile
@@ -11,13 +11,15 @@ ccflags-$(CONFIG_ARCH_MULTIPLATFORM) += -I$(srctree)/$(src)/include -I$(srctree)
11 11
12obj-$(CONFIG_ARCH_EXYNOS) += exynos.o pmu.o exynos-smc.o firmware.o 12obj-$(CONFIG_ARCH_EXYNOS) += exynos.o pmu.o exynos-smc.o firmware.o
13 13
14obj-$(CONFIG_PM_SLEEP) += pm.o sleep.o 14obj-$(CONFIG_EXYNOS_CPU_SUSPEND) += pm.o sleep.o
15obj-$(CONFIG_PM_SLEEP) += suspend.o
15obj-$(CONFIG_PM_GENERIC_DOMAINS) += pm_domains.o 16obj-$(CONFIG_PM_GENERIC_DOMAINS) += pm_domains.o
16 17
17obj-$(CONFIG_SMP) += platsmp.o headsmp.o 18obj-$(CONFIG_SMP) += platsmp.o headsmp.o
18 19
19plus_sec := $(call as-instr,.arch_extension sec,+sec) 20plus_sec := $(call as-instr,.arch_extension sec,+sec)
20AFLAGS_exynos-smc.o :=-Wa,-march=armv7-a$(plus_sec) 21AFLAGS_exynos-smc.o :=-Wa,-march=armv7-a$(plus_sec)
22AFLAGS_sleep.o :=-Wa,-march=armv7-a$(plus_sec)
21 23
22obj-$(CONFIG_EXYNOS5420_MCPM) += mcpm-exynos.o 24obj-$(CONFIG_EXYNOS5420_MCPM) += mcpm-exynos.o
23CFLAGS_mcpm-exynos.o += -march=armv7-a 25CFLAGS_mcpm-exynos.o += -march=armv7-a
diff --git a/arch/arm/mach-exynos/common.h b/arch/arm/mach-exynos/common.h
index 3d3e6af9d015..865f878063cc 100644
--- a/arch/arm/mach-exynos/common.h
+++ b/arch/arm/mach-exynos/common.h
@@ -12,7 +12,6 @@
12#ifndef __ARCH_ARM_MACH_EXYNOS_COMMON_H 12#ifndef __ARCH_ARM_MACH_EXYNOS_COMMON_H
13#define __ARCH_ARM_MACH_EXYNOS_COMMON_H 13#define __ARCH_ARM_MACH_EXYNOS_COMMON_H
14 14
15#include <linux/reboot.h>
16#include <linux/of.h> 15#include <linux/of.h>
17 16
18#define EXYNOS3250_SOC_ID 0xE3472000 17#define EXYNOS3250_SOC_ID 0xE3472000
@@ -111,11 +110,19 @@ IS_SAMSUNG_CPU(exynos5800, EXYNOS5800_SOC_ID, EXYNOS5_SOC_MASK)
111#define soc_is_exynos5() (soc_is_exynos5250() || soc_is_exynos5410() || \ 110#define soc_is_exynos5() (soc_is_exynos5250() || soc_is_exynos5410() || \
112 soc_is_exynos5420() || soc_is_exynos5800()) 111 soc_is_exynos5420() || soc_is_exynos5800())
113 112
113extern u32 cp15_save_diag;
114extern u32 cp15_save_power;
115
114extern void __iomem *sysram_ns_base_addr; 116extern void __iomem *sysram_ns_base_addr;
115extern void __iomem *sysram_base_addr; 117extern void __iomem *sysram_base_addr;
116extern void __iomem *pmu_base_addr; 118extern void __iomem *pmu_base_addr;
117void exynos_sysram_init(void); 119void exynos_sysram_init(void);
118 120
121enum {
122 FW_DO_IDLE_SLEEP,
123 FW_DO_IDLE_AFTR,
124};
125
119void exynos_firmware_init(void); 126void exynos_firmware_init(void);
120 127
121extern u32 exynos_get_eint_wake_mask(void); 128extern u32 exynos_get_eint_wake_mask(void);
@@ -127,32 +134,20 @@ static inline void exynos_pm_init(void) {}
127#endif 134#endif
128 135
129extern void exynos_cpu_resume(void); 136extern void exynos_cpu_resume(void);
137extern void exynos_cpu_resume_ns(void);
130 138
131extern struct smp_operations exynos_smp_ops; 139extern struct smp_operations exynos_smp_ops;
132 140
133/* PMU(Power Management Unit) support */
134
135#define PMU_TABLE_END (-1U)
136
137enum sys_powerdown {
138 SYS_AFTR,
139 SYS_LPA,
140 SYS_SLEEP,
141 NUM_SYS_POWERDOWN,
142};
143
144struct exynos_pmu_conf {
145 unsigned int offset;
146 unsigned int val[NUM_SYS_POWERDOWN];
147};
148
149extern void exynos_sys_powerdown_conf(enum sys_powerdown mode);
150extern void exynos_cpu_power_down(int cpu); 141extern void exynos_cpu_power_down(int cpu);
151extern void exynos_cpu_power_up(int cpu); 142extern void exynos_cpu_power_up(int cpu);
152extern int exynos_cpu_power_state(int cpu); 143extern int exynos_cpu_power_state(int cpu);
153extern void exynos_cluster_power_down(int cluster); 144extern void exynos_cluster_power_down(int cluster);
154extern void exynos_cluster_power_up(int cluster); 145extern void exynos_cluster_power_up(int cluster);
155extern int exynos_cluster_power_state(int cluster); 146extern int exynos_cluster_power_state(int cluster);
147extern void exynos_cpu_save_register(void);
148extern void exynos_cpu_restore_register(void);
149extern void exynos_pm_central_suspend(void);
150extern int exynos_pm_central_resume(void);
156extern void exynos_enter_aftr(void); 151extern void exynos_enter_aftr(void);
157 152
158extern void s5p_init_cpu(void __iomem *cpuid_addr); 153extern void s5p_init_cpu(void __iomem *cpuid_addr);
diff --git a/arch/arm/mach-exynos/exynos-pmu.h b/arch/arm/mach-exynos/exynos-pmu.h
new file mode 100644
index 000000000000..a2ab0d52b230
--- /dev/null
+++ b/arch/arm/mach-exynos/exynos-pmu.h
@@ -0,0 +1,24 @@
1/*
2 * Copyright (c) 2014 Samsung Electronics Co., Ltd.
3 * http://www.samsung.com
4 *
5 * Header for EXYNOS PMU Driver support
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11
12#ifndef __EXYNOS_PMU_H
13#define __EXYNOS_PMU_H
14
15enum sys_powerdown {
16 SYS_AFTR,
17 SYS_LPA,
18 SYS_SLEEP,
19 NUM_SYS_POWERDOWN,
20};
21
22extern void exynos_sys_powerdown_conf(enum sys_powerdown mode);
23
24#endif /* __EXYNOS_PMU_H */
diff --git a/arch/arm/mach-exynos/exynos.c b/arch/arm/mach-exynos/exynos.c
index 6de7cf5ef2b2..c13d0837fa8c 100644
--- a/arch/arm/mach-exynos/exynos.c
+++ b/arch/arm/mach-exynos/exynos.c
@@ -87,28 +87,6 @@ static struct map_desc exynos5_iodesc[] __initdata = {
87 }, 87 },
88}; 88};
89 89
90static void exynos_restart(enum reboot_mode mode, const char *cmd)
91{
92 struct device_node *np;
93 u32 val = 0x1;
94 void __iomem *addr = pmu_base_addr + EXYNOS_SWRESET;
95
96 if (of_machine_is_compatible("samsung,exynos5440")) {
97 u32 status;
98 np = of_find_compatible_node(NULL, NULL, "samsung,exynos5440-clock");
99
100 addr = of_iomap(np, 0) + 0xbc;
101 status = __raw_readl(addr);
102
103 addr = of_iomap(np, 0) + 0xcc;
104 val = __raw_readl(addr);
105
106 val = (val & 0xffff0000) | (status & 0xffff);
107 }
108
109 __raw_writel(val, addr);
110}
111
112static struct platform_device exynos_cpuidle = { 90static struct platform_device exynos_cpuidle = {
113 .name = "exynos_cpuidle", 91 .name = "exynos_cpuidle",
114#ifdef CONFIG_ARM_EXYNOS_CPUIDLE 92#ifdef CONFIG_ARM_EXYNOS_CPUIDLE
@@ -202,6 +180,7 @@ static const struct of_device_id exynos_dt_pmu_match[] = {
202 { .compatible = "samsung,exynos4210-pmu" }, 180 { .compatible = "samsung,exynos4210-pmu" },
203 { .compatible = "samsung,exynos4212-pmu" }, 181 { .compatible = "samsung,exynos4212-pmu" },
204 { .compatible = "samsung,exynos4412-pmu" }, 182 { .compatible = "samsung,exynos4412-pmu" },
183 { .compatible = "samsung,exynos4415-pmu" },
205 { .compatible = "samsung,exynos5250-pmu" }, 184 { .compatible = "samsung,exynos5250-pmu" },
206 { .compatible = "samsung,exynos5260-pmu" }, 185 { .compatible = "samsung,exynos5260-pmu" },
207 { .compatible = "samsung,exynos5410-pmu" }, 186 { .compatible = "samsung,exynos5410-pmu" },
@@ -268,7 +247,10 @@ static void __init exynos_dt_machine_init(void)
268 exynos_sysram_init(); 247 exynos_sysram_init();
269 248
270 if (of_machine_is_compatible("samsung,exynos4210") || 249 if (of_machine_is_compatible("samsung,exynos4210") ||
271 of_machine_is_compatible("samsung,exynos5250")) 250 of_machine_is_compatible("samsung,exynos4212") ||
251 (of_machine_is_compatible("samsung,exynos4412") &&
252 of_machine_is_compatible("samsung,trats2")) ||
253 of_machine_is_compatible("samsung,exynos5250"))
272 platform_device_register(&exynos_cpuidle); 254 platform_device_register(&exynos_cpuidle);
273 255
274 platform_device_register_simple("exynos-cpufreq", -1, NULL, 0); 256 platform_device_register_simple("exynos-cpufreq", -1, NULL, 0);
@@ -283,6 +265,7 @@ static char const *exynos_dt_compat[] __initconst = {
283 "samsung,exynos4210", 265 "samsung,exynos4210",
284 "samsung,exynos4212", 266 "samsung,exynos4212",
285 "samsung,exynos4412", 267 "samsung,exynos4412",
268 "samsung,exynos4415",
286 "samsung,exynos5", 269 "samsung,exynos5",
287 "samsung,exynos5250", 270 "samsung,exynos5250",
288 "samsung,exynos5260", 271 "samsung,exynos5260",
@@ -328,7 +311,6 @@ DT_MACHINE_START(EXYNOS_DT, "SAMSUNG EXYNOS (Flattened Device Tree)")
328 .init_machine = exynos_dt_machine_init, 311 .init_machine = exynos_dt_machine_init,
329 .init_late = exynos_init_late, 312 .init_late = exynos_init_late,
330 .dt_compat = exynos_dt_compat, 313 .dt_compat = exynos_dt_compat,
331 .restart = exynos_restart,
332 .reserve = exynos_reserve, 314 .reserve = exynos_reserve,
333 .dt_fixup = exynos_dt_fixup, 315 .dt_fixup = exynos_dt_fixup,
334MACHINE_END 316MACHINE_END
diff --git a/arch/arm/mach-exynos/firmware.c b/arch/arm/mach-exynos/firmware.c
index e8797bb78871..766f57d2f029 100644
--- a/arch/arm/mach-exynos/firmware.c
+++ b/arch/arm/mach-exynos/firmware.c
@@ -14,16 +14,44 @@
14#include <linux/of.h> 14#include <linux/of.h>
15#include <linux/of_address.h> 15#include <linux/of_address.h>
16 16
17#include <asm/cacheflush.h>
18#include <asm/cputype.h>
17#include <asm/firmware.h> 19#include <asm/firmware.h>
20#include <asm/suspend.h>
18 21
19#include <mach/map.h> 22#include <mach/map.h>
20 23
21#include "common.h" 24#include "common.h"
22#include "smc.h" 25#include "smc.h"
23 26
24static int exynos_do_idle(void) 27#define EXYNOS_SLEEP_MAGIC 0x00000bad
28#define EXYNOS_AFTR_MAGIC 0xfcba0d10
29#define EXYNOS_BOOT_ADDR 0x8
30#define EXYNOS_BOOT_FLAG 0xc
31
32static void exynos_save_cp15(void)
25{ 33{
26 exynos_smc(SMC_CMD_SLEEP, 0, 0, 0); 34 /* Save Power control and Diagnostic registers */
35 asm ("mrc p15, 0, %0, c15, c0, 0\n"
36 "mrc p15, 0, %1, c15, c0, 1\n"
37 : "=r" (cp15_save_power), "=r" (cp15_save_diag)
38 : : "cc");
39}
40
41static int exynos_do_idle(unsigned long mode)
42{
43 switch (mode) {
44 case FW_DO_IDLE_AFTR:
45 if (read_cpuid_part() == ARM_CPU_PART_CORTEX_A9)
46 exynos_save_cp15();
47 __raw_writel(virt_to_phys(exynos_cpu_resume_ns),
48 sysram_ns_base_addr + 0x24);
49 __raw_writel(EXYNOS_AFTR_MAGIC, sysram_ns_base_addr + 0x20);
50 exynos_smc(SMC_CMD_CPU0AFTR, 0, 0, 0);
51 break;
52 case FW_DO_IDLE_SLEEP:
53 exynos_smc(SMC_CMD_SLEEP, 0, 0, 0);
54 }
27 return 0; 55 return 0;
28} 56}
29 57
@@ -69,10 +97,43 @@ static int exynos_set_cpu_boot_addr(int cpu, unsigned long boot_addr)
69 return 0; 97 return 0;
70} 98}
71 99
100static int exynos_cpu_suspend(unsigned long arg)
101{
102 flush_cache_all();
103 outer_flush_all();
104
105 exynos_smc(SMC_CMD_SLEEP, 0, 0, 0);
106
107 pr_info("Failed to suspend the system\n");
108 writel(0, sysram_ns_base_addr + EXYNOS_BOOT_FLAG);
109 return 1;
110}
111
112static int exynos_suspend(void)
113{
114 if (read_cpuid_part() == ARM_CPU_PART_CORTEX_A9)
115 exynos_save_cp15();
116
117 writel(EXYNOS_SLEEP_MAGIC, sysram_ns_base_addr + EXYNOS_BOOT_FLAG);
118 writel(virt_to_phys(exynos_cpu_resume_ns),
119 sysram_ns_base_addr + EXYNOS_BOOT_ADDR);
120
121 return cpu_suspend(0, exynos_cpu_suspend);
122}
123
124static int exynos_resume(void)
125{
126 writel(0, sysram_ns_base_addr + EXYNOS_BOOT_FLAG);
127
128 return 0;
129}
130
72static const struct firmware_ops exynos_firmware_ops = { 131static const struct firmware_ops exynos_firmware_ops = {
73 .do_idle = exynos_do_idle, 132 .do_idle = IS_ENABLED(CONFIG_EXYNOS_CPU_SUSPEND) ? exynos_do_idle : NULL,
74 .set_cpu_boot_addr = exynos_set_cpu_boot_addr, 133 .set_cpu_boot_addr = exynos_set_cpu_boot_addr,
75 .cpu_boot = exynos_cpu_boot, 134 .cpu_boot = exynos_cpu_boot,
135 .suspend = IS_ENABLED(CONFIG_PM_SLEEP) ? exynos_suspend : NULL,
136 .resume = IS_ENABLED(CONFIG_EXYNOS_CPU_SUSPEND) ? exynos_resume : NULL,
76}; 137};
77 138
78void __init exynos_firmware_init(void) 139void __init exynos_firmware_init(void)
diff --git a/arch/arm/mach-exynos/mcpm-exynos.c b/arch/arm/mach-exynos/mcpm-exynos.c
index dc9a764a7c37..b0d3c2e876fb 100644
--- a/arch/arm/mach-exynos/mcpm-exynos.c
+++ b/arch/arm/mach-exynos/mcpm-exynos.c
@@ -15,6 +15,7 @@
15#include <linux/delay.h> 15#include <linux/delay.h>
16#include <linux/io.h> 16#include <linux/io.h>
17#include <linux/of_address.h> 17#include <linux/of_address.h>
18#include <linux/syscore_ops.h>
18 19
19#include <asm/cputype.h> 20#include <asm/cputype.h>
20#include <asm/cp15.h> 21#include <asm/cp15.h>
@@ -30,6 +31,8 @@
30#define EXYNOS5420_USE_ARM_CORE_DOWN_STATE BIT(29) 31#define EXYNOS5420_USE_ARM_CORE_DOWN_STATE BIT(29)
31#define EXYNOS5420_USE_L2_COMMON_UP_STATE BIT(30) 32#define EXYNOS5420_USE_L2_COMMON_UP_STATE BIT(30)
32 33
34static void __iomem *ns_sram_base_addr;
35
33/* 36/*
34 * The common v7_exit_coherency_flush API could not be used because of the 37 * The common v7_exit_coherency_flush API could not be used because of the
35 * Erratum 799270 workaround. This macro is the same as the common one (in 38 * Erratum 799270 workaround. This macro is the same as the common one (in
@@ -318,10 +321,26 @@ static const struct of_device_id exynos_dt_mcpm_match[] = {
318 {}, 321 {},
319}; 322};
320 323
324static void exynos_mcpm_setup_entry_point(void)
325{
326 /*
327 * U-Boot SPL is hardcoded to jump to the start of ns_sram_base_addr
328 * as part of secondary_cpu_start(). Let's redirect it to the
329 * mcpm_entry_point(). This is done during both secondary boot-up as
330 * well as system resume.
331 */
332 __raw_writel(0xe59f0000, ns_sram_base_addr); /* ldr r0, [pc, #0] */
333 __raw_writel(0xe12fff10, ns_sram_base_addr + 4); /* bx r0 */
334 __raw_writel(virt_to_phys(mcpm_entry_point), ns_sram_base_addr + 8);
335}
336
337static struct syscore_ops exynos_mcpm_syscore_ops = {
338 .resume = exynos_mcpm_setup_entry_point,
339};
340
321static int __init exynos_mcpm_init(void) 341static int __init exynos_mcpm_init(void)
322{ 342{
323 struct device_node *node; 343 struct device_node *node;
324 void __iomem *ns_sram_base_addr;
325 unsigned int value, i; 344 unsigned int value, i;
326 int ret; 345 int ret;
327 346
@@ -387,16 +406,9 @@ static int __init exynos_mcpm_init(void)
387 pmu_raw_writel(value, EXYNOS_COMMON_OPTION(i)); 406 pmu_raw_writel(value, EXYNOS_COMMON_OPTION(i));
388 } 407 }
389 408
390 /* 409 exynos_mcpm_setup_entry_point();
391 * U-Boot SPL is hardcoded to jump to the start of ns_sram_base_addr
392 * as part of secondary_cpu_start(). Let's redirect it to the
393 * mcpm_entry_point().
394 */
395 __raw_writel(0xe59f0000, ns_sram_base_addr); /* ldr r0, [pc, #0] */
396 __raw_writel(0xe12fff10, ns_sram_base_addr + 4); /* bx r0 */
397 __raw_writel(virt_to_phys(mcpm_entry_point), ns_sram_base_addr + 8);
398 410
399 iounmap(ns_sram_base_addr); 411 register_syscore_ops(&exynos_mcpm_syscore_ops);
400 412
401 return ret; 413 return ret;
402} 414}
diff --git a/arch/arm/mach-exynos/platsmp.c b/arch/arm/mach-exynos/platsmp.c
index 9c6dd1451136..7a1ebfeeeeb8 100644
--- a/arch/arm/mach-exynos/platsmp.c
+++ b/arch/arm/mach-exynos/platsmp.c
@@ -126,6 +126,18 @@ static inline void platform_do_lowpower(unsigned int cpu, int *spurious)
126 */ 126 */
127void exynos_cpu_power_down(int cpu) 127void exynos_cpu_power_down(int cpu)
128{ 128{
129 if (cpu == 0 && (of_machine_is_compatible("samsung,exynos5420") ||
130 of_machine_is_compatible("samsung,exynos5800"))) {
131 /*
132 * Bypass power down for CPU0 during suspend. Check for
133 * the SYS_PWR_REG value to decide if we are suspending
134 * the system.
135 */
136 int val = pmu_raw_readl(EXYNOS5_ARM_CORE0_SYS_PWR_REG);
137
138 if (!(val & S5P_CORE_LOCAL_PWR_EN))
139 return;
140 }
129 pmu_raw_writel(0, EXYNOS_ARM_CORE_CONFIGURATION(cpu)); 141 pmu_raw_writel(0, EXYNOS_ARM_CORE_CONFIGURATION(cpu));
130} 142}
131 143
@@ -204,6 +216,26 @@ static inline void __iomem *cpu_boot_reg(int cpu)
204} 216}
205 217
206/* 218/*
219 * Set wake up by local power mode and execute software reset for given core.
220 *
221 * Currently this is needed only when booting secondary CPU on Exynos3250.
222 */
223static void exynos_core_restart(u32 core_id)
224{
225 u32 val;
226
227 if (!of_machine_is_compatible("samsung,exynos3250"))
228 return;
229
230 val = pmu_raw_readl(EXYNOS_ARM_CORE_STATUS(core_id));
231 val |= S5P_CORE_WAKEUP_FROM_LOCAL_CFG;
232 pmu_raw_writel(val, EXYNOS_ARM_CORE_STATUS(core_id));
233
234 pr_info("CPU%u: Software reset\n", core_id);
235 pmu_raw_writel(EXYNOS_CORE_PO_RESET(core_id), EXYNOS_SWRESET);
236}
237
238/*
207 * Write pen_release in a way that is guaranteed to be visible to all 239 * Write pen_release in a way that is guaranteed to be visible to all
208 * observers, irrespective of whether they're taking part in coherency 240 * observers, irrespective of whether they're taking part in coherency
209 * or not. This is necessary for the hotplug code to work reliably. 241 * or not. This is necessary for the hotplug code to work reliably.
@@ -279,6 +311,9 @@ static int exynos_boot_secondary(unsigned int cpu, struct task_struct *idle)
279 return -ETIMEDOUT; 311 return -ETIMEDOUT;
280 } 312 }
281 } 313 }
314
315 exynos_core_restart(core_id);
316
282 /* 317 /*
283 * Send the secondary CPU a soft interrupt, thereby causing 318 * Send the secondary CPU a soft interrupt, thereby causing
284 * the boot monitor to read the system wide flags register, 319 * the boot monitor to read the system wide flags register,
diff --git a/arch/arm/mach-exynos/pm.c b/arch/arm/mach-exynos/pm.c
index abefacb45976..86f3ecd88f78 100644
--- a/arch/arm/mach-exynos/pm.c
+++ b/arch/arm/mach-exynos/pm.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2011-2012 Samsung Electronics Co., Ltd. 2 * Copyright (c) 2011-2014 Samsung Electronics Co., Ltd.
3 * http://www.samsung.com 3 * http://www.samsung.com
4 * 4 *
5 * EXYNOS - Power Management support 5 * EXYNOS - Power Management support
@@ -15,109 +15,45 @@
15 15
16#include <linux/init.h> 16#include <linux/init.h>
17#include <linux/suspend.h> 17#include <linux/suspend.h>
18#include <linux/syscore_ops.h>
19#include <linux/cpu_pm.h> 18#include <linux/cpu_pm.h>
20#include <linux/io.h> 19#include <linux/io.h>
21#include <linux/irqchip/arm-gic.h>
22#include <linux/err.h> 20#include <linux/err.h>
23#include <linux/clk.h>
24 21
25#include <asm/cacheflush.h> 22#include <asm/firmware.h>
26#include <asm/hardware/cache-l2x0.h>
27#include <asm/smp_scu.h> 23#include <asm/smp_scu.h>
28#include <asm/suspend.h> 24#include <asm/suspend.h>
29 25
30#include <plat/pm-common.h> 26#include <plat/pm-common.h>
31#include <plat/regs-srom.h>
32
33#include <mach/map.h>
34 27
35#include "common.h" 28#include "common.h"
29#include "exynos-pmu.h"
36#include "regs-pmu.h" 30#include "regs-pmu.h"
37#include "regs-sys.h" 31#include "regs-sys.h"
38 32
39/** 33static inline void __iomem *exynos_boot_vector_addr(void)
40 * struct exynos_wkup_irq - Exynos GIC to PMU IRQ mapping
41 * @hwirq: Hardware IRQ signal of the GIC
42 * @mask: Mask in PMU wake-up mask register
43 */
44struct exynos_wkup_irq {
45 unsigned int hwirq;
46 u32 mask;
47};
48
49static struct sleep_save exynos5_sys_save[] = {
50 SAVE_ITEM(EXYNOS5_SYS_I2C_CFG),
51};
52
53static struct sleep_save exynos_core_save[] = {
54 /* SROM side */
55 SAVE_ITEM(S5P_SROM_BW),
56 SAVE_ITEM(S5P_SROM_BC0),
57 SAVE_ITEM(S5P_SROM_BC1),
58 SAVE_ITEM(S5P_SROM_BC2),
59 SAVE_ITEM(S5P_SROM_BC3),
60};
61
62/*
63 * GIC wake-up support
64 */
65
66static u32 exynos_irqwake_intmask = 0xffffffff;
67
68static const struct exynos_wkup_irq exynos4_wkup_irq[] = {
69 { 76, BIT(1) }, /* RTC alarm */
70 { 77, BIT(2) }, /* RTC tick */
71 { /* sentinel */ },
72};
73
74static const struct exynos_wkup_irq exynos5250_wkup_irq[] = {
75 { 75, BIT(1) }, /* RTC alarm */
76 { 76, BIT(2) }, /* RTC tick */
77 { /* sentinel */ },
78};
79
80static int exynos_irq_set_wake(struct irq_data *data, unsigned int state)
81{ 34{
82 const struct exynos_wkup_irq *wkup_irq; 35 if (samsung_rev() == EXYNOS4210_REV_1_1)
83 36 return pmu_base_addr + S5P_INFORM7;
84 if (soc_is_exynos5250()) 37 else if (samsung_rev() == EXYNOS4210_REV_1_0)
85 wkup_irq = exynos5250_wkup_irq; 38 return sysram_base_addr + 0x24;
86 else 39 return pmu_base_addr + S5P_INFORM0;
87 wkup_irq = exynos4_wkup_irq;
88
89 while (wkup_irq->mask) {
90 if (wkup_irq->hwirq == data->hwirq) {
91 if (!state)
92 exynos_irqwake_intmask |= wkup_irq->mask;
93 else
94 exynos_irqwake_intmask &= ~wkup_irq->mask;
95 return 0;
96 }
97 ++wkup_irq;
98 }
99
100 return -ENOENT;
101} 40}
102 41
103#define EXYNOS_BOOT_VECTOR_ADDR (samsung_rev() == EXYNOS4210_REV_1_1 ? \ 42static inline void __iomem *exynos_boot_vector_flag(void)
104 pmu_base_addr + S5P_INFORM7 : \ 43{
105 (samsung_rev() == EXYNOS4210_REV_1_0 ? \ 44 if (samsung_rev() == EXYNOS4210_REV_1_1)
106 (sysram_base_addr + 0x24) : \ 45 return pmu_base_addr + S5P_INFORM6;
107 pmu_base_addr + S5P_INFORM0)) 46 else if (samsung_rev() == EXYNOS4210_REV_1_0)
108#define EXYNOS_BOOT_VECTOR_FLAG (samsung_rev() == EXYNOS4210_REV_1_1 ? \ 47 return sysram_base_addr + 0x20;
109 pmu_base_addr + S5P_INFORM6 : \ 48 return pmu_base_addr + S5P_INFORM1;
110 (samsung_rev() == EXYNOS4210_REV_1_0 ? \ 49}
111 (sysram_base_addr + 0x20) : \
112 pmu_base_addr + S5P_INFORM1))
113 50
114#define S5P_CHECK_AFTR 0xFCBA0D10 51#define S5P_CHECK_AFTR 0xFCBA0D10
115#define S5P_CHECK_SLEEP 0x00000BAD
116 52
117/* For Cortex-A9 Diagnostic and Power control register */ 53/* For Cortex-A9 Diagnostic and Power control register */
118static unsigned int save_arm_register[2]; 54static unsigned int save_arm_register[2];
119 55
120static void exynos_cpu_save_register(void) 56void exynos_cpu_save_register(void)
121{ 57{
122 unsigned long tmp; 58 unsigned long tmp;
123 59
@@ -134,7 +70,7 @@ static void exynos_cpu_save_register(void)
134 save_arm_register[1] = tmp; 70 save_arm_register[1] = tmp;
135} 71}
136 72
137static void exynos_cpu_restore_register(void) 73void exynos_cpu_restore_register(void)
138{ 74{
139 unsigned long tmp; 75 unsigned long tmp;
140 76
@@ -153,7 +89,7 @@ static void exynos_cpu_restore_register(void)
153 : "cc"); 89 : "cc");
154} 90}
155 91
156static void exynos_pm_central_suspend(void) 92void exynos_pm_central_suspend(void)
157{ 93{
158 unsigned long tmp; 94 unsigned long tmp;
159 95
@@ -161,9 +97,13 @@ static void exynos_pm_central_suspend(void)
161 tmp = pmu_raw_readl(S5P_CENTRAL_SEQ_CONFIGURATION); 97 tmp = pmu_raw_readl(S5P_CENTRAL_SEQ_CONFIGURATION);
162 tmp &= ~S5P_CENTRAL_LOWPWR_CFG; 98 tmp &= ~S5P_CENTRAL_LOWPWR_CFG;
163 pmu_raw_writel(tmp, S5P_CENTRAL_SEQ_CONFIGURATION); 99 pmu_raw_writel(tmp, S5P_CENTRAL_SEQ_CONFIGURATION);
100
101 /* Setting SEQ_OPTION register */
102 pmu_raw_writel(S5P_USE_STANDBY_WFI0 | S5P_USE_STANDBY_WFE0,
103 S5P_CENTRAL_SEQ_OPTION);
164} 104}
165 105
166static int exynos_pm_central_resume(void) 106int exynos_pm_central_resume(void)
167{ 107{
168 unsigned long tmp; 108 unsigned long tmp;
169 109
@@ -194,17 +134,26 @@ static void exynos_set_wakeupmask(long mask)
194 134
195static void exynos_cpu_set_boot_vector(long flags) 135static void exynos_cpu_set_boot_vector(long flags)
196{ 136{
197 __raw_writel(virt_to_phys(exynos_cpu_resume), EXYNOS_BOOT_VECTOR_ADDR); 137 __raw_writel(virt_to_phys(exynos_cpu_resume),
198 __raw_writel(flags, EXYNOS_BOOT_VECTOR_FLAG); 138 exynos_boot_vector_addr());
139 __raw_writel(flags, exynos_boot_vector_flag());
199} 140}
200 141
201static int exynos_aftr_finisher(unsigned long flags) 142static int exynos_aftr_finisher(unsigned long flags)
202{ 143{
144 int ret;
145
203 exynos_set_wakeupmask(0x0000ff3e); 146 exynos_set_wakeupmask(0x0000ff3e);
204 exynos_cpu_set_boot_vector(S5P_CHECK_AFTR);
205 /* Set value of power down register for aftr mode */ 147 /* Set value of power down register for aftr mode */
206 exynos_sys_powerdown_conf(SYS_AFTR); 148 exynos_sys_powerdown_conf(SYS_AFTR);
207 cpu_do_idle(); 149
150 ret = call_firmware_op(do_idle, FW_DO_IDLE_AFTR);
151 if (ret == -ENOSYS) {
152 if (read_cpuid_part() == ARM_CPU_PART_CORTEX_A9)
153 exynos_cpu_save_register();
154 exynos_cpu_set_boot_vector(S5P_CHECK_AFTR);
155 cpu_do_idle();
156 }
208 157
209 return 1; 158 return 1;
210} 159}
@@ -214,196 +163,16 @@ void exynos_enter_aftr(void)
214 cpu_pm_enter(); 163 cpu_pm_enter();
215 164
216 exynos_pm_central_suspend(); 165 exynos_pm_central_suspend();
217 if (read_cpuid_part() == ARM_CPU_PART_CORTEX_A9)
218 exynos_cpu_save_register();
219 166
220 cpu_suspend(0, exynos_aftr_finisher); 167 cpu_suspend(0, exynos_aftr_finisher);
221 168
222 if (read_cpuid_part() == ARM_CPU_PART_CORTEX_A9) { 169 if (read_cpuid_part() == ARM_CPU_PART_CORTEX_A9) {
223 scu_enable(S5P_VA_SCU); 170 scu_enable(S5P_VA_SCU);
224 exynos_cpu_restore_register(); 171 if (call_firmware_op(resume) == -ENOSYS)
172 exynos_cpu_restore_register();
225 } 173 }
226 174
227 exynos_pm_central_resume(); 175 exynos_pm_central_resume();
228 176
229 cpu_pm_exit(); 177 cpu_pm_exit();
230} 178}
231
232static int exynos_cpu_suspend(unsigned long arg)
233{
234#ifdef CONFIG_CACHE_L2X0
235 outer_flush_all();
236#endif
237
238 if (soc_is_exynos5250())
239 flush_cache_all();
240
241 /* issue the standby signal into the pm unit. */
242 cpu_do_idle();
243
244 pr_info("Failed to suspend the system\n");
245 return 1; /* Aborting suspend */
246}
247
248static void exynos_pm_prepare(void)
249{
250 unsigned int tmp;
251
252 /* Set wake-up mask registers */
253 pmu_raw_writel(exynos_get_eint_wake_mask(), S5P_EINT_WAKEUP_MASK);
254 pmu_raw_writel(exynos_irqwake_intmask & ~(1 << 31), S5P_WAKEUP_MASK);
255
256 s3c_pm_do_save(exynos_core_save, ARRAY_SIZE(exynos_core_save));
257
258 if (soc_is_exynos5250()) {
259 s3c_pm_do_save(exynos5_sys_save, ARRAY_SIZE(exynos5_sys_save));
260 /* Disable USE_RETENTION of JPEG_MEM_OPTION */
261 tmp = pmu_raw_readl(EXYNOS5_JPEG_MEM_OPTION);
262 tmp &= ~EXYNOS5_OPTION_USE_RETENTION;
263 pmu_raw_writel(tmp, EXYNOS5_JPEG_MEM_OPTION);
264 }
265
266 /* Set value of power down register for sleep mode */
267
268 exynos_sys_powerdown_conf(SYS_SLEEP);
269 pmu_raw_writel(S5P_CHECK_SLEEP, S5P_INFORM1);
270
271 /* ensure at least INFORM0 has the resume address */
272
273 pmu_raw_writel(virt_to_phys(exynos_cpu_resume), S5P_INFORM0);
274}
275
276static int exynos_pm_suspend(void)
277{
278 unsigned long tmp;
279
280 exynos_pm_central_suspend();
281
282 /* Setting SEQ_OPTION register */
283
284 tmp = (S5P_USE_STANDBY_WFI0 | S5P_USE_STANDBY_WFE0);
285 pmu_raw_writel(tmp, S5P_CENTRAL_SEQ_OPTION);
286
287 if (read_cpuid_part() == ARM_CPU_PART_CORTEX_A9)
288 exynos_cpu_save_register();
289
290 return 0;
291}
292
293static void exynos_pm_resume(void)
294{
295 if (exynos_pm_central_resume())
296 goto early_wakeup;
297
298 if (read_cpuid_part() == ARM_CPU_PART_CORTEX_A9)
299 exynos_cpu_restore_register();
300
301 /* For release retention */
302
303 pmu_raw_writel((1 << 28), S5P_PAD_RET_MAUDIO_OPTION);
304 pmu_raw_writel((1 << 28), S5P_PAD_RET_GPIO_OPTION);
305 pmu_raw_writel((1 << 28), S5P_PAD_RET_UART_OPTION);
306 pmu_raw_writel((1 << 28), S5P_PAD_RET_MMCA_OPTION);
307 pmu_raw_writel((1 << 28), S5P_PAD_RET_MMCB_OPTION);
308 pmu_raw_writel((1 << 28), S5P_PAD_RET_EBIA_OPTION);
309 pmu_raw_writel((1 << 28), S5P_PAD_RET_EBIB_OPTION);
310
311 if (soc_is_exynos5250())
312 s3c_pm_do_restore(exynos5_sys_save,
313 ARRAY_SIZE(exynos5_sys_save));
314
315 s3c_pm_do_restore_core(exynos_core_save, ARRAY_SIZE(exynos_core_save));
316
317 if (read_cpuid_part() == ARM_CPU_PART_CORTEX_A9)
318 scu_enable(S5P_VA_SCU);
319
320early_wakeup:
321
322 /* Clear SLEEP mode set in INFORM1 */
323 pmu_raw_writel(0x0, S5P_INFORM1);
324
325 return;
326}
327
328static struct syscore_ops exynos_pm_syscore_ops = {
329 .suspend = exynos_pm_suspend,
330 .resume = exynos_pm_resume,
331};
332
333/*
334 * Suspend Ops
335 */
336
337static int exynos_suspend_enter(suspend_state_t state)
338{
339 int ret;
340
341 s3c_pm_debug_init();
342
343 S3C_PMDBG("%s: suspending the system...\n", __func__);
344
345 S3C_PMDBG("%s: wakeup masks: %08x,%08x\n", __func__,
346 exynos_irqwake_intmask, exynos_get_eint_wake_mask());
347
348 if (exynos_irqwake_intmask == -1U
349 && exynos_get_eint_wake_mask() == -1U) {
350 pr_err("%s: No wake-up sources!\n", __func__);
351 pr_err("%s: Aborting sleep\n", __func__);
352 return -EINVAL;
353 }
354
355 s3c_pm_save_uarts();
356 exynos_pm_prepare();
357 flush_cache_all();
358 s3c_pm_check_store();
359
360 ret = cpu_suspend(0, exynos_cpu_suspend);
361 if (ret)
362 return ret;
363
364 s3c_pm_restore_uarts();
365
366 S3C_PMDBG("%s: wakeup stat: %08x\n", __func__,
367 pmu_raw_readl(S5P_WAKEUP_STAT));
368
369 s3c_pm_check_restore();
370
371 S3C_PMDBG("%s: resuming the system...\n", __func__);
372
373 return 0;
374}
375
376static int exynos_suspend_prepare(void)
377{
378 s3c_pm_check_prepare();
379
380 return 0;
381}
382
383static void exynos_suspend_finish(void)
384{
385 s3c_pm_check_cleanup();
386}
387
388static const struct platform_suspend_ops exynos_suspend_ops = {
389 .enter = exynos_suspend_enter,
390 .prepare = exynos_suspend_prepare,
391 .finish = exynos_suspend_finish,
392 .valid = suspend_valid_only_mem,
393};
394
395void __init exynos_pm_init(void)
396{
397 u32 tmp;
398
399 /* Platform-specific GIC callback */
400 gic_arch_extn.irq_set_wake = exynos_irq_set_wake;
401
402 /* All wakeup disable */
403 tmp = pmu_raw_readl(S5P_WAKEUP_MASK);
404 tmp |= ((0xFF << 8) | (0x1F << 1));
405 pmu_raw_writel(tmp, S5P_WAKEUP_MASK);
406
407 register_syscore_ops(&exynos_pm_syscore_ops);
408 suspend_set_ops(&exynos_suspend_ops);
409}
diff --git a/arch/arm/mach-exynos/pmu.c b/arch/arm/mach-exynos/pmu.c
index d8fa0337db73..c15761ca2f18 100644
--- a/arch/arm/mach-exynos/pmu.c
+++ b/arch/arm/mach-exynos/pmu.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2011-2012 Samsung Electronics Co., Ltd. 2 * Copyright (c) 2011-2014 Samsung Electronics Co., Ltd.
3 * http://www.samsung.com/ 3 * http://www.samsung.com/
4 * 4 *
5 * EXYNOS - CPU PMU(Power Management Unit) support 5 * EXYNOS - CPU PMU(Power Management Unit) support
@@ -10,12 +10,136 @@
10 */ 10 */
11 11
12#include <linux/io.h> 12#include <linux/io.h>
13#include <linux/kernel.h> 13#include <linux/of.h>
14#include <linux/of_address.h>
15#include <linux/platform_device.h>
16#include <linux/delay.h>
17#include <linux/notifier.h>
18#include <linux/reboot.h>
14 19
15#include "common.h" 20
21#include "exynos-pmu.h"
16#include "regs-pmu.h" 22#include "regs-pmu.h"
17 23
18static const struct exynos_pmu_conf *exynos_pmu_config; 24#define PMU_TABLE_END (-1U)
25
26struct exynos_pmu_conf {
27 unsigned int offset;
28 u8 val[NUM_SYS_POWERDOWN];
29};
30
31struct exynos_pmu_data {
32 const struct exynos_pmu_conf *pmu_config;
33 const struct exynos_pmu_conf *pmu_config_extra;
34
35 void (*pmu_init)(void);
36 void (*powerdown_conf)(enum sys_powerdown);
37 void (*powerdown_conf_extra)(enum sys_powerdown);
38};
39
40struct exynos_pmu_context {
41 struct device *dev;
42 const struct exynos_pmu_data *pmu_data;
43};
44
45static void __iomem *pmu_base_addr;
46static struct exynos_pmu_context *pmu_context;
47
48static inline void pmu_raw_writel(u32 val, u32 offset)
49{
50 writel_relaxed(val, pmu_base_addr + offset);
51}
52
53static inline u32 pmu_raw_readl(u32 offset)
54{
55 return readl_relaxed(pmu_base_addr + offset);
56}
57
58static struct exynos_pmu_conf exynos3250_pmu_config[] = {
59 /* { .offset = offset, .val = { AFTR, W-AFTR, SLEEP } */
60 { EXYNOS3_ARM_CORE0_SYS_PWR_REG, { 0x0, 0x0, 0x2} },
61 { EXYNOS3_DIS_IRQ_ARM_CORE0_LOCAL_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
62 { EXYNOS3_DIS_IRQ_ARM_CORE0_CENTRAL_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
63 { EXYNOS3_ARM_CORE1_SYS_PWR_REG, { 0x0, 0x0, 0x2} },
64 { EXYNOS3_DIS_IRQ_ARM_CORE1_LOCAL_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
65 { EXYNOS3_DIS_IRQ_ARM_CORE1_CENTRAL_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
66 { EXYNOS3_ISP_ARM_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
67 { EXYNOS3_DIS_IRQ_ISP_ARM_LOCAL_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
68 { EXYNOS3_DIS_IRQ_ISP_ARM_CENTRAL_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
69 { EXYNOS3_ARM_COMMON_SYS_PWR_REG, { 0x0, 0x0, 0x2} },
70 { EXYNOS3_ARM_L2_SYS_PWR_REG, { 0x0, 0x0, 0x3} },
71 { EXYNOS3_CMU_ACLKSTOP_SYS_PWR_REG, { 0x1, 0x1, 0x0} },
72 { EXYNOS3_CMU_SCLKSTOP_SYS_PWR_REG, { 0x1, 0x1, 0x0} },
73 { EXYNOS3_CMU_RESET_SYS_PWR_REG, { 0x1, 0x1, 0x0} },
74 { EXYNOS3_DRAM_FREQ_DOWN_SYS_PWR_REG, { 0x1, 0x1, 0x1} },
75 { EXYNOS3_DDRPHY_DLLOFF_SYS_PWR_REG, { 0x1, 0x1, 0x1} },
76 { EXYNOS3_LPDDR_PHY_DLL_LOCK_SYS_PWR_REG, { 0x1, 0x1, 0x1} },
77 { EXYNOS3_CMU_ACLKSTOP_COREBLK_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
78 { EXYNOS3_CMU_SCLKSTOP_COREBLK_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
79 { EXYNOS3_CMU_RESET_COREBLK_SYS_PWR_REG, { 0x1, 0x1, 0x0} },
80 { EXYNOS3_APLL_SYSCLK_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
81 { EXYNOS3_MPLL_SYSCLK_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
82 { EXYNOS3_BPLL_SYSCLK_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
83 { EXYNOS3_VPLL_SYSCLK_SYS_PWR_REG, { 0x1, 0x1, 0x0} },
84 { EXYNOS3_EPLL_SYSCLK_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
85 { EXYNOS3_UPLL_SYSCLK_SYS_PWR_REG, { 0x1, 0x1, 0x1} },
86 { EXYNOS3_EPLLUSER_SYSCLK_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
87 { EXYNOS3_MPLLUSER_SYSCLK_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
88 { EXYNOS3_BPLLUSER_SYSCLK_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
89 { EXYNOS3_CMU_CLKSTOP_CAM_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
90 { EXYNOS3_CMU_CLKSTOP_MFC_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
91 { EXYNOS3_CMU_CLKSTOP_G3D_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
92 { EXYNOS3_CMU_CLKSTOP_LCD0_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
93 { EXYNOS3_CMU_CLKSTOP_ISP_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
94 { EXYNOS3_CMU_CLKSTOP_MAUDIO_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
95 { EXYNOS3_CMU_RESET_CAM_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
96 { EXYNOS3_CMU_RESET_MFC_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
97 { EXYNOS3_CMU_RESET_G3D_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
98 { EXYNOS3_CMU_RESET_LCD0_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
99 { EXYNOS3_CMU_RESET_ISP_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
100 { EXYNOS3_CMU_RESET_MAUDIO_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
101 { EXYNOS3_TOP_BUS_SYS_PWR_REG, { 0x3, 0x0, 0x0} },
102 { EXYNOS3_TOP_RETENTION_SYS_PWR_REG, { 0x1, 0x1, 0x1} },
103 { EXYNOS3_TOP_PWR_SYS_PWR_REG, { 0x3, 0x3, 0x3} },
104 { EXYNOS3_TOP_BUS_COREBLK_SYS_PWR_REG, { 0x3, 0x0, 0x0} },
105 { EXYNOS3_TOP_RETENTION_COREBLK_SYS_PWR_REG, { 0x1, 0x1, 0x1} },
106 { EXYNOS3_TOP_PWR_COREBLK_SYS_PWR_REG, { 0x3, 0x3, 0x3} },
107 { EXYNOS3_LOGIC_RESET_SYS_PWR_REG, { 0x1, 0x1, 0x0} },
108 { EXYNOS3_OSCCLK_GATE_SYS_PWR_REG, { 0x1, 0x1, 0x1} },
109 { EXYNOS3_LOGIC_RESET_COREBLK_SYS_PWR_REG, { 0x1, 0x1, 0x0} },
110 { EXYNOS3_OSCCLK_GATE_COREBLK_SYS_PWR_REG, { 0x1, 0x0, 0x1} },
111 { EXYNOS3_PAD_RETENTION_DRAM_SYS_PWR_REG, { 0x1, 0x1, 0x0} },
112 { EXYNOS3_PAD_RETENTION_MAUDIO_SYS_PWR_REG, { 0x1, 0x1, 0x0} },
113 { EXYNOS3_PAD_RETENTION_GPIO_SYS_PWR_REG, { 0x1, 0x1, 0x0} },
114 { EXYNOS3_PAD_RETENTION_UART_SYS_PWR_REG, { 0x1, 0x1, 0x0} },
115 { EXYNOS3_PAD_RETENTION_MMC0_SYS_PWR_REG, { 0x1, 0x1, 0x0} },
116 { EXYNOS3_PAD_RETENTION_MMC1_SYS_PWR_REG, { 0x1, 0x1, 0x0} },
117 { EXYNOS3_PAD_RETENTION_MMC2_SYS_PWR_REG, { 0x1, 0x1, 0x0} },
118 { EXYNOS3_PAD_RETENTION_SPI_SYS_PWR_REG, { 0x1, 0x1, 0x0} },
119 { EXYNOS3_PAD_RETENTION_EBIA_SYS_PWR_REG, { 0x1, 0x1, 0x0} },
120 { EXYNOS3_PAD_RETENTION_EBIB_SYS_PWR_REG, { 0x1, 0x1, 0x0} },
121 { EXYNOS3_PAD_RETENTION_JTAG_SYS_PWR_REG, { 0x1, 0x1, 0x0} },
122 { EXYNOS3_PAD_ISOLATION_SYS_PWR_REG, { 0x1, 0x1, 0x0} },
123 { EXYNOS3_PAD_ALV_SEL_SYS_PWR_REG, { 0x1, 0x1, 0x0} },
124 { EXYNOS3_XUSBXTI_SYS_PWR_REG, { 0x1, 0x1, 0x0} },
125 { EXYNOS3_XXTI_SYS_PWR_REG, { 0x1, 0x1, 0x0} },
126 { EXYNOS3_EXT_REGULATOR_SYS_PWR_REG, { 0x1, 0x1, 0x0} },
127 { EXYNOS3_EXT_REGULATOR_COREBLK_SYS_PWR_REG, { 0x1, 0x1, 0x0} },
128 { EXYNOS3_GPIO_MODE_SYS_PWR_REG, { 0x1, 0x1, 0x0} },
129 { EXYNOS3_GPIO_MODE_MAUDIO_SYS_PWR_REG, { 0x1, 0x1, 0x0} },
130 { EXYNOS3_TOP_ASB_RESET_SYS_PWR_REG, { 0x1, 0x1, 0x0} },
131 { EXYNOS3_TOP_ASB_ISOLATION_SYS_PWR_REG, { 0x1, 0x1, 0x0} },
132 { EXYNOS3_TOP_ASB_RESET_COREBLK_SYS_PWR_REG, { 0x1, 0x1, 0x0} },
133 { EXYNOS3_TOP_ASB_ISOLATION_COREBLK_SYS_PWR_REG, { 0x1, 0x1, 0x0} },
134 { EXYNOS3_CAM_SYS_PWR_REG, { 0x7, 0x0, 0x0} },
135 { EXYNOS3_MFC_SYS_PWR_REG, { 0x7, 0x0, 0x0} },
136 { EXYNOS3_G3D_SYS_PWR_REG, { 0x7, 0x0, 0x0} },
137 { EXYNOS3_LCD0_SYS_PWR_REG, { 0x7, 0x0, 0x0} },
138 { EXYNOS3_ISP_SYS_PWR_REG, { 0x7, 0x0, 0x0} },
139 { EXYNOS3_MAUDIO_SYS_PWR_REG, { 0x7, 0x0, 0x0} },
140 { EXYNOS3_CMU_SYSCLK_ISP_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
141 { PMU_TABLE_END,},
142};
19 143
20static const struct exynos_pmu_conf exynos4210_pmu_config[] = { 144static const struct exynos_pmu_conf exynos4210_pmu_config[] = {
21 /* { .offset = offset, .val = { AFTR, LPA, SLEEP } */ 145 /* { .offset = offset, .val = { AFTR, LPA, SLEEP } */
@@ -264,6 +388,7 @@ static const struct exynos_pmu_conf exynos5250_pmu_config[] = {
264 { EXYNOS5_INTRAM_MEM_SYS_PWR_REG, { 0x3, 0x0, 0x0} }, 388 { EXYNOS5_INTRAM_MEM_SYS_PWR_REG, { 0x3, 0x0, 0x0} },
265 { EXYNOS5_INTROM_MEM_SYS_PWR_REG, { 0x3, 0x0, 0x0} }, 389 { EXYNOS5_INTROM_MEM_SYS_PWR_REG, { 0x3, 0x0, 0x0} },
266 { EXYNOS5_JPEG_MEM_SYS_PWR_REG, { 0x3, 0x0, 0x0} }, 390 { EXYNOS5_JPEG_MEM_SYS_PWR_REG, { 0x3, 0x0, 0x0} },
391 { EXYNOS5_JPEG_MEM_OPTION, { 0x10, 0x10, 0x0} },
267 { EXYNOS5_HSI_MEM_SYS_PWR_REG, { 0x3, 0x0, 0x0} }, 392 { EXYNOS5_HSI_MEM_SYS_PWR_REG, { 0x3, 0x0, 0x0} },
268 { EXYNOS5_MCUIOP_MEM_SYS_PWR_REG, { 0x3, 0x0, 0x0} }, 393 { EXYNOS5_MCUIOP_MEM_SYS_PWR_REG, { 0x3, 0x0, 0x0} },
269 { EXYNOS5_SATA_MEM_SYS_PWR_REG, { 0x3, 0x0, 0x0} }, 394 { EXYNOS5_SATA_MEM_SYS_PWR_REG, { 0x3, 0x0, 0x0} },
@@ -315,6 +440,189 @@ static const struct exynos_pmu_conf exynos5250_pmu_config[] = {
315 { PMU_TABLE_END,}, 440 { PMU_TABLE_END,},
316}; 441};
317 442
443static struct exynos_pmu_conf exynos5420_pmu_config[] = {
444 /* { .offset = offset, .val = { AFTR, LPA, SLEEP } */
445 { EXYNOS5_ARM_CORE0_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
446 { EXYNOS5_DIS_IRQ_ARM_CORE0_LOCAL_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
447 { EXYNOS5_DIS_IRQ_ARM_CORE0_CENTRAL_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
448 { EXYNOS5_ARM_CORE1_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
449 { EXYNOS5_DIS_IRQ_ARM_CORE1_LOCAL_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
450 { EXYNOS5_DIS_IRQ_ARM_CORE1_CENTRAL_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
451 { EXYNOS5420_ARM_CORE2_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
452 { EXYNOS5420_DIS_IRQ_ARM_CORE2_LOCAL_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
453 { EXYNOS5420_DIS_IRQ_ARM_CORE2_CENTRAL_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
454 { EXYNOS5420_ARM_CORE3_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
455 { EXYNOS5420_DIS_IRQ_ARM_CORE3_LOCAL_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
456 { EXYNOS5420_DIS_IRQ_ARM_CORE3_CENTRAL_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
457 { EXYNOS5420_KFC_CORE0_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
458 { EXYNOS5420_DIS_IRQ_KFC_CORE0_LOCAL_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
459 { EXYNOS5420_DIS_IRQ_KFC_CORE0_CENTRAL_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
460 { EXYNOS5420_KFC_CORE1_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
461 { EXYNOS5420_DIS_IRQ_KFC_CORE1_LOCAL_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
462 { EXYNOS5420_DIS_IRQ_KFC_CORE1_CENTRAL_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
463 { EXYNOS5420_KFC_CORE2_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
464 { EXYNOS5420_DIS_IRQ_KFC_CORE2_LOCAL_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
465 { EXYNOS5420_DIS_IRQ_KFC_CORE2_CENTRAL_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
466 { EXYNOS5420_KFC_CORE3_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
467 { EXYNOS5420_DIS_IRQ_KFC_CORE3_LOCAL_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
468 { EXYNOS5420_DIS_IRQ_KFC_CORE3_CENTRAL_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
469 { EXYNOS5_ISP_ARM_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
470 { EXYNOS5_DIS_IRQ_ISP_ARM_LOCAL_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
471 { EXYNOS5_DIS_IRQ_ISP_ARM_CENTRAL_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
472 { EXYNOS5420_ARM_COMMON_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
473 { EXYNOS5420_KFC_COMMON_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
474 { EXYNOS5_ARM_L2_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
475 { EXYNOS5420_KFC_L2_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
476 { EXYNOS5_CMU_ACLKSTOP_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
477 { EXYNOS5_CMU_SCLKSTOP_SYS_PWR_REG, { 0x1, 0x0, 0x1} },
478 { EXYNOS5_CMU_RESET_SYS_PWR_REG, { 0x1, 0x1, 0x0} },
479 { EXYNOS5_CMU_ACLKSTOP_SYSMEM_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
480 { EXYNOS5_CMU_SCLKSTOP_SYSMEM_SYS_PWR_REG, { 0x1, 0x0, 0x1} },
481 { EXYNOS5_CMU_RESET_SYSMEM_SYS_PWR_REG, { 0x1, 0x1, 0x0} },
482 { EXYNOS5_DRAM_FREQ_DOWN_SYS_PWR_REG, { 0x1, 0x0, 0x1} },
483 { EXYNOS5_DDRPHY_DLLOFF_SYS_PWR_REG, { 0x1, 0x1, 0x1} },
484 { EXYNOS5_DDRPHY_DLLLOCK_SYS_PWR_REG, { 0x1, 0x0, 0x1} },
485 { EXYNOS5_APLL_SYSCLK_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
486 { EXYNOS5_MPLL_SYSCLK_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
487 { EXYNOS5_VPLL_SYSCLK_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
488 { EXYNOS5_EPLL_SYSCLK_SYS_PWR_REG, { 0x1, 0x1, 0x0} },
489 { EXYNOS5_BPLL_SYSCLK_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
490 { EXYNOS5_CPLL_SYSCLK_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
491 { EXYNOS5420_DPLL_SYSCLK_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
492 { EXYNOS5420_IPLL_SYSCLK_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
493 { EXYNOS5420_KPLL_SYSCLK_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
494 { EXYNOS5_MPLLUSER_SYSCLK_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
495 { EXYNOS5_BPLLUSER_SYSCLK_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
496 { EXYNOS5420_RPLL_SYSCLK_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
497 { EXYNOS5420_SPLL_SYSCLK_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
498 { EXYNOS5_TOP_BUS_SYS_PWR_REG, { 0x3, 0x0, 0x0} },
499 { EXYNOS5_TOP_RETENTION_SYS_PWR_REG, { 0x1, 0x1, 0x1} },
500 { EXYNOS5_TOP_PWR_SYS_PWR_REG, { 0x3, 0x3, 0x0} },
501 { EXYNOS5_TOP_BUS_SYSMEM_SYS_PWR_REG, { 0x3, 0x0, 0x0} },
502 { EXYNOS5_TOP_RETENTION_SYSMEM_SYS_PWR_REG, { 0x1, 0x0, 0x1} },
503 { EXYNOS5_TOP_PWR_SYSMEM_SYS_PWR_REG, { 0x3, 0x0, 0x0} },
504 { EXYNOS5_LOGIC_RESET_SYS_PWR_REG, { 0x1, 0x1, 0x0} },
505 { EXYNOS5_OSCCLK_GATE_SYS_PWR_REG, { 0x1, 0x0, 0x1} },
506 { EXYNOS5_LOGIC_RESET_SYSMEM_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
507 { EXYNOS5_OSCCLK_GATE_SYSMEM_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
508 { EXYNOS5420_INTRAM_MEM_SYS_PWR_REG, { 0x3, 0x0, 0x3} },
509 { EXYNOS5420_INTROM_MEM_SYS_PWR_REG, { 0x3, 0x0, 0x3} },
510 { EXYNOS5_PAD_RETENTION_DRAM_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
511 { EXYNOS5_PAD_RETENTION_MAU_SYS_PWR_REG, { 0x1, 0x1, 0x0} },
512 { EXYNOS5420_PAD_RETENTION_JTAG_SYS_PWR_REG, { 0x1, 0x1, 0x0} },
513 { EXYNOS5420_PAD_RETENTION_DRAM_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
514 { EXYNOS5420_PAD_RETENTION_UART_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
515 { EXYNOS5420_PAD_RETENTION_MMC0_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
516 { EXYNOS5420_PAD_RETENTION_MMC1_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
517 { EXYNOS5420_PAD_RETENTION_MMC2_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
518 { EXYNOS5420_PAD_RETENTION_HSI_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
519 { EXYNOS5420_PAD_RETENTION_EBIA_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
520 { EXYNOS5420_PAD_RETENTION_EBIB_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
521 { EXYNOS5420_PAD_RETENTION_SPI_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
522 { EXYNOS5420_PAD_RETENTION_DRAM_COREBLK_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
523 { EXYNOS5_PAD_ISOLATION_SYS_PWR_REG, { 0x1, 0x1, 0x0} },
524 { EXYNOS5_PAD_ISOLATION_SYSMEM_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
525 { EXYNOS5_PAD_ALV_SEL_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
526 { EXYNOS5_XUSBXTI_SYS_PWR_REG, { 0x1, 0x1, 0x0} },
527 { EXYNOS5_XXTI_SYS_PWR_REG, { 0x1, 0x1, 0x0} },
528 { EXYNOS5_EXT_REGULATOR_SYS_PWR_REG, { 0x1, 0x1, 0x0} },
529 { EXYNOS5_GPIO_MODE_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
530 { EXYNOS5_GPIO_MODE_SYSMEM_SYS_PWR_REG, { 0x1, 0x1, 0x0} },
531 { EXYNOS5_GPIO_MODE_MAU_SYS_PWR_REG, { 0x1, 0x1, 0x0} },
532 { EXYNOS5_TOP_ASB_RESET_SYS_PWR_REG, { 0x1, 0x1, 0x0} },
533 { EXYNOS5_TOP_ASB_ISOLATION_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
534 { EXYNOS5_GSCL_SYS_PWR_REG, { 0x7, 0x0, 0x0} },
535 { EXYNOS5_ISP_SYS_PWR_REG, { 0x7, 0x0, 0x0} },
536 { EXYNOS5_MFC_SYS_PWR_REG, { 0x7, 0x0, 0x0} },
537 { EXYNOS5_G3D_SYS_PWR_REG, { 0x7, 0x0, 0x0} },
538 { EXYNOS5420_DISP1_SYS_PWR_REG, { 0x7, 0x0, 0x0} },
539 { EXYNOS5420_MAU_SYS_PWR_REG, { 0x7, 0x7, 0x0} },
540 { EXYNOS5420_G2D_SYS_PWR_REG, { 0x7, 0x0, 0x0} },
541 { EXYNOS5420_MSC_SYS_PWR_REG, { 0x7, 0x0, 0x0} },
542 { EXYNOS5420_FSYS_SYS_PWR_REG, { 0x7, 0x0, 0x0} },
543 { EXYNOS5420_FSYS2_SYS_PWR_REG, { 0x7, 0x0, 0x0} },
544 { EXYNOS5420_PSGEN_SYS_PWR_REG, { 0x7, 0x0, 0x0} },
545 { EXYNOS5420_PERIC_SYS_PWR_REG, { 0x7, 0x0, 0x0} },
546 { EXYNOS5420_WCORE_SYS_PWR_REG, { 0x7, 0x0, 0x0} },
547 { EXYNOS5_CMU_CLKSTOP_GSCL_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
548 { EXYNOS5_CMU_CLKSTOP_ISP_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
549 { EXYNOS5_CMU_CLKSTOP_MFC_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
550 { EXYNOS5_CMU_CLKSTOP_G3D_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
551 { EXYNOS5420_CMU_CLKSTOP_DISP1_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
552 { EXYNOS5420_CMU_CLKSTOP_MAU_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
553 { EXYNOS5420_CMU_CLKSTOP_G2D_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
554 { EXYNOS5420_CMU_CLKSTOP_MSC_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
555 { EXYNOS5420_CMU_CLKSTOP_FSYS_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
556 { EXYNOS5420_CMU_CLKSTOP_PSGEN_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
557 { EXYNOS5420_CMU_CLKSTOP_PERIC_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
558 { EXYNOS5420_CMU_CLKSTOP_WCORE_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
559 { EXYNOS5_CMU_SYSCLK_GSCL_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
560 { EXYNOS5_CMU_SYSCLK_ISP_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
561 { EXYNOS5_CMU_SYSCLK_MFC_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
562 { EXYNOS5_CMU_SYSCLK_G3D_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
563 { EXYNOS5420_CMU_SYSCLK_DISP1_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
564 { EXYNOS5420_CMU_SYSCLK_MAU_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
565 { EXYNOS5420_CMU_SYSCLK_G2D_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
566 { EXYNOS5420_CMU_SYSCLK_MSC_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
567 { EXYNOS5420_CMU_SYSCLK_FSYS_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
568 { EXYNOS5420_CMU_SYSCLK_FSYS2_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
569 { EXYNOS5420_CMU_SYSCLK_PSGEN_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
570 { EXYNOS5420_CMU_SYSCLK_PERIC_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
571 { EXYNOS5420_CMU_SYSCLK_WCORE_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
572 { EXYNOS5420_CMU_RESET_FSYS2_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
573 { EXYNOS5420_CMU_RESET_PSGEN_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
574 { EXYNOS5420_CMU_RESET_PERIC_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
575 { EXYNOS5420_CMU_RESET_WCORE_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
576 { EXYNOS5_CMU_RESET_GSCL_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
577 { EXYNOS5_CMU_RESET_ISP_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
578 { EXYNOS5_CMU_RESET_MFC_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
579 { EXYNOS5_CMU_RESET_G3D_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
580 { EXYNOS5420_CMU_RESET_DISP1_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
581 { EXYNOS5420_CMU_RESET_MAU_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
582 { EXYNOS5420_CMU_RESET_G2D_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
583 { EXYNOS5420_CMU_RESET_MSC_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
584 { EXYNOS5420_CMU_RESET_FSYS_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
585 { PMU_TABLE_END,},
586};
587
588static unsigned int const exynos3250_list_feed[] = {
589 EXYNOS3_ARM_CORE_OPTION(0),
590 EXYNOS3_ARM_CORE_OPTION(1),
591 EXYNOS3_ARM_CORE_OPTION(2),
592 EXYNOS3_ARM_CORE_OPTION(3),
593 EXYNOS3_ARM_COMMON_OPTION,
594 EXYNOS3_TOP_PWR_OPTION,
595 EXYNOS3_CORE_TOP_PWR_OPTION,
596 S5P_CAM_OPTION,
597 S5P_MFC_OPTION,
598 S5P_G3D_OPTION,
599 S5P_LCD0_OPTION,
600 S5P_ISP_OPTION,
601};
602
603static void exynos3250_powerdown_conf_extra(enum sys_powerdown mode)
604{
605 unsigned int i;
606 unsigned int tmp;
607
608 /* Enable only SC_FEEDBACK */
609 for (i = 0; i < ARRAY_SIZE(exynos3250_list_feed); i++) {
610 tmp = pmu_raw_readl(exynos3250_list_feed[i]);
611 tmp &= ~(EXYNOS3_OPTION_USE_SC_COUNTER);
612 tmp |= EXYNOS3_OPTION_USE_SC_FEEDBACK;
613 pmu_raw_writel(tmp, exynos3250_list_feed[i]);
614 }
615
616 if (mode != SYS_SLEEP)
617 return;
618
619 pmu_raw_writel(XUSBXTI_DURATION, EXYNOS3_XUSBXTI_DURATION);
620 pmu_raw_writel(XXTI_DURATION, EXYNOS3_XXTI_DURATION);
621 pmu_raw_writel(EXT_REGULATOR_DURATION, EXYNOS3_EXT_REGULATOR_DURATION);
622 pmu_raw_writel(EXT_REGULATOR_COREBLK_DURATION,
623 EXYNOS3_EXT_REGULATOR_COREBLK_DURATION);
624}
625
318static unsigned int const exynos5_list_both_cnt_feed[] = { 626static unsigned int const exynos5_list_both_cnt_feed[] = {
319 EXYNOS5_ARM_CORE0_OPTION, 627 EXYNOS5_ARM_CORE0_OPTION,
320 EXYNOS5_ARM_CORE1_OPTION, 628 EXYNOS5_ARM_CORE1_OPTION,
@@ -335,7 +643,76 @@ static unsigned int const exynos5_list_disable_wfi_wfe[] = {
335 EXYNOS5_ISP_ARM_OPTION, 643 EXYNOS5_ISP_ARM_OPTION,
336}; 644};
337 645
338static void exynos5_init_pmu(void) 646static unsigned int const exynos5420_list_disable_pmu_reg[] = {
647 EXYNOS5_CMU_CLKSTOP_GSCL_SYS_PWR_REG,
648 EXYNOS5_CMU_CLKSTOP_ISP_SYS_PWR_REG,
649 EXYNOS5_CMU_CLKSTOP_G3D_SYS_PWR_REG,
650 EXYNOS5420_CMU_CLKSTOP_DISP1_SYS_PWR_REG,
651 EXYNOS5420_CMU_CLKSTOP_MAU_SYS_PWR_REG,
652 EXYNOS5420_CMU_CLKSTOP_G2D_SYS_PWR_REG,
653 EXYNOS5420_CMU_CLKSTOP_MSC_SYS_PWR_REG,
654 EXYNOS5420_CMU_CLKSTOP_FSYS_SYS_PWR_REG,
655 EXYNOS5420_CMU_CLKSTOP_PSGEN_SYS_PWR_REG,
656 EXYNOS5420_CMU_CLKSTOP_PERIC_SYS_PWR_REG,
657 EXYNOS5420_CMU_CLKSTOP_WCORE_SYS_PWR_REG,
658 EXYNOS5_CMU_SYSCLK_GSCL_SYS_PWR_REG,
659 EXYNOS5_CMU_SYSCLK_ISP_SYS_PWR_REG,
660 EXYNOS5_CMU_SYSCLK_G3D_SYS_PWR_REG,
661 EXYNOS5420_CMU_SYSCLK_DISP1_SYS_PWR_REG,
662 EXYNOS5420_CMU_SYSCLK_MAU_SYS_PWR_REG,
663 EXYNOS5420_CMU_SYSCLK_G2D_SYS_PWR_REG,
664 EXYNOS5420_CMU_SYSCLK_MSC_SYS_PWR_REG,
665 EXYNOS5420_CMU_SYSCLK_FSYS_SYS_PWR_REG,
666 EXYNOS5420_CMU_SYSCLK_FSYS2_SYS_PWR_REG,
667 EXYNOS5420_CMU_SYSCLK_PSGEN_SYS_PWR_REG,
668 EXYNOS5420_CMU_SYSCLK_PERIC_SYS_PWR_REG,
669 EXYNOS5420_CMU_SYSCLK_WCORE_SYS_PWR_REG,
670 EXYNOS5420_CMU_RESET_FSYS2_SYS_PWR_REG,
671 EXYNOS5420_CMU_RESET_PSGEN_SYS_PWR_REG,
672 EXYNOS5420_CMU_RESET_PERIC_SYS_PWR_REG,
673 EXYNOS5420_CMU_RESET_WCORE_SYS_PWR_REG,
674 EXYNOS5_CMU_RESET_GSCL_SYS_PWR_REG,
675 EXYNOS5_CMU_RESET_ISP_SYS_PWR_REG,
676 EXYNOS5_CMU_RESET_G3D_SYS_PWR_REG,
677 EXYNOS5420_CMU_RESET_DISP1_SYS_PWR_REG,
678 EXYNOS5420_CMU_RESET_MAU_SYS_PWR_REG,
679 EXYNOS5420_CMU_RESET_G2D_SYS_PWR_REG,
680 EXYNOS5420_CMU_RESET_MSC_SYS_PWR_REG,
681 EXYNOS5420_CMU_RESET_FSYS_SYS_PWR_REG,
682};
683
684static void exynos5_power_off(void)
685{
686 unsigned int tmp;
687
688 pr_info("Power down.\n");
689 tmp = pmu_raw_readl(EXYNOS_PS_HOLD_CONTROL);
690 tmp ^= (1 << 8);
691 pmu_raw_writel(tmp, EXYNOS_PS_HOLD_CONTROL);
692
693 /* Wait a little so we don't give a false warning below */
694 mdelay(100);
695
696 pr_err("Power down failed, please power off system manually.\n");
697 while (1)
698 ;
699}
700
701void exynos5420_powerdown_conf(enum sys_powerdown mode)
702{
703 u32 this_cluster;
704
705 this_cluster = MPIDR_AFFINITY_LEVEL(read_cpuid_mpidr(), 1);
706
707 /*
708 * set the cluster id to IROM register to ensure that we wake
709 * up with the current cluster.
710 */
711 pmu_raw_writel(this_cluster, EXYNOS_IROM_DATA2);
712}
713
714
715static void exynos5_powerdown_conf(enum sys_powerdown mode)
339{ 716{
340 unsigned int i; 717 unsigned int i;
341 unsigned int tmp; 718 unsigned int tmp;
@@ -343,7 +720,7 @@ static void exynos5_init_pmu(void)
343 /* 720 /*
344 * Enable both SC_FEEDBACK and SC_COUNTER 721 * Enable both SC_FEEDBACK and SC_COUNTER
345 */ 722 */
346 for (i = 0 ; i < ARRAY_SIZE(exynos5_list_both_cnt_feed) ; i++) { 723 for (i = 0; i < ARRAY_SIZE(exynos5_list_both_cnt_feed); i++) {
347 tmp = pmu_raw_readl(exynos5_list_both_cnt_feed[i]); 724 tmp = pmu_raw_readl(exynos5_list_both_cnt_feed[i]);
348 tmp |= (EXYNOS5_USE_SC_FEEDBACK | 725 tmp |= (EXYNOS5_USE_SC_FEEDBACK |
349 EXYNOS5_USE_SC_COUNTER); 726 EXYNOS5_USE_SC_COUNTER);
@@ -360,7 +737,7 @@ static void exynos5_init_pmu(void)
360 /* 737 /*
361 * Disable WFI/WFE on XXX_OPTION 738 * Disable WFI/WFE on XXX_OPTION
362 */ 739 */
363 for (i = 0 ; i < ARRAY_SIZE(exynos5_list_disable_wfi_wfe) ; i++) { 740 for (i = 0; i < ARRAY_SIZE(exynos5_list_disable_wfi_wfe); i++) {
364 tmp = pmu_raw_readl(exynos5_list_disable_wfi_wfe[i]); 741 tmp = pmu_raw_readl(exynos5_list_disable_wfi_wfe[i]);
365 tmp &= ~(EXYNOS5_OPTION_USE_STANDBYWFE | 742 tmp &= ~(EXYNOS5_OPTION_USE_STANDBYWFE |
366 EXYNOS5_OPTION_USE_STANDBYWFI); 743 EXYNOS5_OPTION_USE_STANDBYWFI);
@@ -372,51 +749,257 @@ void exynos_sys_powerdown_conf(enum sys_powerdown mode)
372{ 749{
373 unsigned int i; 750 unsigned int i;
374 751
375 if (soc_is_exynos5250()) 752 const struct exynos_pmu_data *pmu_data = pmu_context->pmu_data;
376 exynos5_init_pmu(); 753
754 if (pmu_data->powerdown_conf)
755 pmu_data->powerdown_conf(mode);
756
757 if (pmu_data->pmu_config) {
758 for (i = 0; (pmu_data->pmu_config[i].offset != PMU_TABLE_END); i++)
759 pmu_raw_writel(pmu_data->pmu_config[i].val[mode],
760 pmu_data->pmu_config[i].offset);
761 }
377 762
378 for (i = 0; (exynos_pmu_config[i].offset != PMU_TABLE_END) ; i++) 763 if (pmu_data->powerdown_conf_extra)
379 pmu_raw_writel(exynos_pmu_config[i].val[mode], 764 pmu_data->powerdown_conf_extra(mode);
380 exynos_pmu_config[i].offset);
381 765
382 if (soc_is_exynos4412()) { 766 if (pmu_data->pmu_config_extra) {
383 for (i = 0; exynos4412_pmu_config[i].offset != PMU_TABLE_END ; i++) 767 for (i = 0; pmu_data->pmu_config_extra[i].offset != PMU_TABLE_END; i++)
384 pmu_raw_writel(exynos4412_pmu_config[i].val[mode], 768 pmu_raw_writel(pmu_data->pmu_config_extra[i].val[mode],
385 exynos4412_pmu_config[i].offset); 769 pmu_data->pmu_config_extra[i].offset);
386 } 770 }
387} 771}
388 772
389static int __init exynos_pmu_init(void) 773static void exynos3250_pmu_init(void)
774{
775 unsigned int value;
776
777 /*
778 * To prevent from issuing new bus request form L2 memory system
779 * If core status is power down, should be set '1' to L2 power down
780 */
781 value = pmu_raw_readl(EXYNOS3_ARM_COMMON_OPTION);
782 value |= EXYNOS3_OPTION_SKIP_DEACTIVATE_ACEACP_IN_PWDN;
783 pmu_raw_writel(value, EXYNOS3_ARM_COMMON_OPTION);
784
785 /* Enable USE_STANDBY_WFI for all CORE */
786 pmu_raw_writel(S5P_USE_STANDBY_WFI_ALL, S5P_CENTRAL_SEQ_OPTION);
787
788 /*
789 * Set PSHOLD port for output high
790 */
791 value = pmu_raw_readl(S5P_PS_HOLD_CONTROL);
792 value |= S5P_PS_HOLD_OUTPUT_HIGH;
793 pmu_raw_writel(value, S5P_PS_HOLD_CONTROL);
794
795 /*
796 * Enable signal for PSHOLD port
797 */
798 value = pmu_raw_readl(S5P_PS_HOLD_CONTROL);
799 value |= S5P_PS_HOLD_EN;
800 pmu_raw_writel(value, S5P_PS_HOLD_CONTROL);
801}
802
803static void exynos5250_pmu_init(void)
390{ 804{
391 unsigned int value; 805 unsigned int value;
806 /*
807 * When SYS_WDTRESET is set, watchdog timer reset request
808 * is ignored by power management unit.
809 */
810 value = pmu_raw_readl(EXYNOS5_AUTO_WDTRESET_DISABLE);
811 value &= ~EXYNOS5_SYS_WDTRESET;
812 pmu_raw_writel(value, EXYNOS5_AUTO_WDTRESET_DISABLE);
813
814 value = pmu_raw_readl(EXYNOS5_MASK_WDTRESET_REQUEST);
815 value &= ~EXYNOS5_SYS_WDTRESET;
816 pmu_raw_writel(value, EXYNOS5_MASK_WDTRESET_REQUEST);
817}
818
819static void exynos5420_pmu_init(void)
820{
821 unsigned int value;
822 int i;
823
824 /*
825 * Set the CMU_RESET, CMU_SYSCLK and CMU_CLKSTOP registers
826 * for local power blocks to Low initially as per Table 8-4:
827 * "System-Level Power-Down Configuration Registers".
828 */
829 for (i = 0; i < ARRAY_SIZE(exynos5420_list_disable_pmu_reg); i++)
830 pmu_raw_writel(0, exynos5420_list_disable_pmu_reg[i]);
831
832 /* Enable USE_STANDBY_WFI for all CORE */
833 pmu_raw_writel(EXYNOS5420_USE_STANDBY_WFI_ALL, S5P_CENTRAL_SEQ_OPTION);
834
835 value = pmu_raw_readl(EXYNOS_L2_OPTION(0));
836 value &= ~EXYNOS5_USE_RETENTION;
837 pmu_raw_writel(value, EXYNOS_L2_OPTION(0));
838
839 value = pmu_raw_readl(EXYNOS_L2_OPTION(1));
840 value &= ~EXYNOS5_USE_RETENTION;
841 pmu_raw_writel(value, EXYNOS_L2_OPTION(1));
842
843 /*
844 * If L2_COMMON is turned off, clocks related to ATB async
845 * bridge are gated. Thus, when ISP power is gated, LPI
846 * may get stuck.
847 */
848 value = pmu_raw_readl(EXYNOS5420_LPI_MASK);
849 value |= EXYNOS5420_ATB_ISP_ARM;
850 pmu_raw_writel(value, EXYNOS5420_LPI_MASK);
851
852 value = pmu_raw_readl(EXYNOS5420_LPI_MASK1);
853 value |= EXYNOS5420_ATB_KFC;
854 pmu_raw_writel(value, EXYNOS5420_LPI_MASK1);
855
856 /* Prevent issue of new bus request from L2 memory */
857 value = pmu_raw_readl(EXYNOS5420_ARM_COMMON_OPTION);
858 value |= EXYNOS5_SKIP_DEACTIVATE_ACEACP_IN_PWDN;
859 pmu_raw_writel(value, EXYNOS5420_ARM_COMMON_OPTION);
860
861 value = pmu_raw_readl(EXYNOS5420_KFC_COMMON_OPTION);
862 value |= EXYNOS5_SKIP_DEACTIVATE_ACEACP_IN_PWDN;
863 pmu_raw_writel(value, EXYNOS5420_KFC_COMMON_OPTION);
864
865 /* This setting is to reduce suspend/resume time */
866 pmu_raw_writel(DUR_WAIT_RESET, EXYNOS5420_LOGIC_RESET_DURATION3);
867
868 /* Serialized CPU wakeup of Eagle */
869 pmu_raw_writel(SPREAD_ENABLE, EXYNOS5420_ARM_INTR_SPREAD_ENABLE);
870
871 pmu_raw_writel(SPREAD_USE_STANDWFI,
872 EXYNOS5420_ARM_INTR_SPREAD_USE_STANDBYWFI);
873
874 pmu_raw_writel(0x1, EXYNOS5420_UP_SCHEDULER);
875
876 pm_power_off = exynos5_power_off;
877 pr_info("EXYNOS5420 PMU initialized\n");
878}
879
880static int pmu_restart_notify(struct notifier_block *this,
881 unsigned long code, void *unused)
882{
883 pmu_raw_writel(0x1, EXYNOS_SWRESET);
884
885 return NOTIFY_DONE;
886}
887
888static const struct exynos_pmu_data exynos3250_pmu_data = {
889 .pmu_config = exynos3250_pmu_config,
890 .pmu_init = exynos3250_pmu_init,
891 .powerdown_conf_extra = exynos3250_powerdown_conf_extra,
892};
392 893
393 exynos_pmu_config = exynos4210_pmu_config; 894static const struct exynos_pmu_data exynos4210_pmu_data = {
394 895 .pmu_config = exynos4210_pmu_config,
395 if (soc_is_exynos4210()) { 896};
396 exynos_pmu_config = exynos4210_pmu_config; 897
397 pr_info("EXYNOS4210 PMU Initialize\n"); 898static const struct exynos_pmu_data exynos4212_pmu_data = {
398 } else if (soc_is_exynos4212() || soc_is_exynos4412()) { 899 .pmu_config = exynos4x12_pmu_config,
399 exynos_pmu_config = exynos4x12_pmu_config; 900};
400 pr_info("EXYNOS4x12 PMU Initialize\n"); 901
401 } else if (soc_is_exynos5250()) { 902static const struct exynos_pmu_data exynos4412_pmu_data = {
402 /* 903 .pmu_config = exynos4x12_pmu_config,
403 * When SYS_WDTRESET is set, watchdog timer reset request 904 .pmu_config_extra = exynos4412_pmu_config,
404 * is ignored by power management unit. 905};
405 */ 906
406 value = pmu_raw_readl(EXYNOS5_AUTO_WDTRESET_DISABLE); 907static const struct exynos_pmu_data exynos5250_pmu_data = {
407 value &= ~EXYNOS5_SYS_WDTRESET; 908 .pmu_config = exynos5250_pmu_config,
408 pmu_raw_writel(value, EXYNOS5_AUTO_WDTRESET_DISABLE); 909 .pmu_init = exynos5250_pmu_init,
409 910 .powerdown_conf = exynos5_powerdown_conf,
410 value = pmu_raw_readl(EXYNOS5_MASK_WDTRESET_REQUEST); 911};
411 value &= ~EXYNOS5_SYS_WDTRESET; 912
412 pmu_raw_writel(value, EXYNOS5_MASK_WDTRESET_REQUEST); 913static struct exynos_pmu_data exynos5420_pmu_data = {
413 914 .pmu_config = exynos5420_pmu_config,
414 exynos_pmu_config = exynos5250_pmu_config; 915 .pmu_init = exynos5420_pmu_init,
415 pr_info("EXYNOS5250 PMU Initialize\n"); 916 .powerdown_conf = exynos5420_powerdown_conf,
416 } else { 917};
417 pr_info("EXYNOS: PMU not supported\n"); 918
919/*
920 * PMU platform driver and devicetree bindings.
921 */
922static const struct of_device_id exynos_pmu_of_device_ids[] = {
923 {
924 .compatible = "samsung,exynos3250-pmu",
925 .data = &exynos3250_pmu_data,
926 }, {
927 .compatible = "samsung,exynos4210-pmu",
928 .data = &exynos4210_pmu_data,
929 }, {
930 .compatible = "samsung,exynos4212-pmu",
931 .data = &exynos4212_pmu_data,
932 }, {
933 .compatible = "samsung,exynos4412-pmu",
934 .data = &exynos4412_pmu_data,
935 }, {
936 .compatible = "samsung,exynos5250-pmu",
937 .data = &exynos5250_pmu_data,
938 }, {
939 .compatible = "samsung,exynos5420-pmu",
940 .data = &exynos5420_pmu_data,
941 },
942 { /*sentinel*/ },
943};
944
945/*
946 * Exynos PMU restart notifier, handles restart functionality
947 */
948static struct notifier_block pmu_restart_handler = {
949 .notifier_call = pmu_restart_notify,
950 .priority = 128,
951};
952
953static int exynos_pmu_probe(struct platform_device *pdev)
954{
955 const struct of_device_id *match;
956 struct device *dev = &pdev->dev;
957 struct resource *res;
958 int ret;
959
960 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
961 pmu_base_addr = devm_ioremap_resource(dev, res);
962 if (IS_ERR(pmu_base_addr))
963 return PTR_ERR(pmu_base_addr);
964
965 pmu_context = devm_kzalloc(&pdev->dev,
966 sizeof(struct exynos_pmu_context),
967 GFP_KERNEL);
968 if (!pmu_context) {
969 dev_err(dev, "Cannot allocate memory.\n");
970 return -ENOMEM;
418 } 971 }
972 pmu_context->dev = dev;
973
974 match = of_match_node(exynos_pmu_of_device_ids, dev->of_node);
975
976 pmu_context->pmu_data = match->data;
977
978 if (pmu_context->pmu_data->pmu_init)
979 pmu_context->pmu_data->pmu_init();
980
981 platform_set_drvdata(pdev, pmu_context);
419 982
983 ret = register_restart_handler(&pmu_restart_handler);
984 if (ret)
985 dev_warn(dev, "can't register restart handler err=%d\n", ret);
986
987 dev_dbg(dev, "Exynos PMU Driver probe done\n");
420 return 0; 988 return 0;
421} 989}
422arch_initcall(exynos_pmu_init); 990
991static struct platform_driver exynos_pmu_driver = {
992 .driver = {
993 .name = "exynos-pmu",
994 .owner = THIS_MODULE,
995 .of_match_table = exynos_pmu_of_device_ids,
996 },
997 .probe = exynos_pmu_probe,
998};
999
1000static int __init exynos_pmu_init(void)
1001{
1002 return platform_driver_register(&exynos_pmu_driver);
1003
1004}
1005postcore_initcall(exynos_pmu_init);
diff --git a/arch/arm/mach-exynos/regs-pmu.h b/arch/arm/mach-exynos/regs-pmu.h
index 4e9b4440e2bd..b5f4406fc1b5 100644
--- a/arch/arm/mach-exynos/regs-pmu.h
+++ b/arch/arm/mach-exynos/regs-pmu.h
@@ -19,9 +19,24 @@
19#define S5P_CENTRAL_SEQ_OPTION 0x0208 19#define S5P_CENTRAL_SEQ_OPTION 0x0208
20 20
21#define S5P_USE_STANDBY_WFI0 (1 << 16) 21#define S5P_USE_STANDBY_WFI0 (1 << 16)
22#define S5P_USE_STANDBY_WFI1 (1 << 17)
23#define S5P_USE_STANDBY_WFI2 (1 << 19)
24#define S5P_USE_STANDBY_WFI3 (1 << 20)
22#define S5P_USE_STANDBY_WFE0 (1 << 24) 25#define S5P_USE_STANDBY_WFE0 (1 << 24)
26#define S5P_USE_STANDBY_WFE1 (1 << 25)
27#define S5P_USE_STANDBY_WFE2 (1 << 27)
28#define S5P_USE_STANDBY_WFE3 (1 << 28)
29
30#define S5P_USE_STANDBY_WFI_ALL \
31 (S5P_USE_STANDBY_WFI0 | S5P_USE_STANDBY_WFI1 | \
32 S5P_USE_STANDBY_WFI2 | S5P_USE_STANDBY_WFI3 | \
33 S5P_USE_STANDBY_WFE0 | S5P_USE_STANDBY_WFE1 | \
34 S5P_USE_STANDBY_WFE2 | S5P_USE_STANDBY_WFE3)
35
23#define S5P_USE_DELAYED_RESET_ASSERTION BIT(12) 36#define S5P_USE_DELAYED_RESET_ASSERTION BIT(12)
24 37
38#define EXYNOS_CORE_PO_RESET(n) ((1 << 4) << n)
39#define EXYNOS_WAKEUP_FROM_LOWPWR (1 << 28)
25#define EXYNOS_SWRESET 0x0400 40#define EXYNOS_SWRESET 0x0400
26#define EXYNOS5440_SWRESET 0x00C4 41#define EXYNOS5440_SWRESET 0x00C4
27 42
@@ -36,6 +51,7 @@
36#define S5P_INFORM7 0x081C 51#define S5P_INFORM7 0x081C
37#define S5P_PMU_SPARE3 0x090C 52#define S5P_PMU_SPARE3 0x090C
38 53
54#define EXYNOS_IROM_DATA2 0x0988
39#define S5P_ARM_CORE0_LOWPWR 0x1000 55#define S5P_ARM_CORE0_LOWPWR 0x1000
40#define S5P_DIS_IRQ_CORE0 0x1004 56#define S5P_DIS_IRQ_CORE0 0x1004
41#define S5P_DIS_IRQ_CENTRAL0 0x1008 57#define S5P_DIS_IRQ_CENTRAL0 0x1008
@@ -118,6 +134,31 @@
118#define EXYNOS_COMMON_OPTION(_nr) \ 134#define EXYNOS_COMMON_OPTION(_nr) \
119 (EXYNOS_COMMON_CONFIGURATION(_nr) + 0x8) 135 (EXYNOS_COMMON_CONFIGURATION(_nr) + 0x8)
120 136
137#define EXYNOS_CORE_LOCAL_PWR_EN 0x3
138
139#define EXYNOS_ARM_COMMON_STATUS 0x2504
140#define EXYNOS_COMMON_OPTION(_nr) \
141 (EXYNOS_COMMON_CONFIGURATION(_nr) + 0x8)
142
143#define EXYNOS_ARM_L2_CONFIGURATION 0x2600
144#define EXYNOS_L2_CONFIGURATION(_nr) \
145 (EXYNOS_ARM_L2_CONFIGURATION + ((_nr) * 0x80))
146#define EXYNOS_L2_STATUS(_nr) \
147 (EXYNOS_L2_CONFIGURATION(_nr) + 0x4)
148#define EXYNOS_L2_OPTION(_nr) \
149 (EXYNOS_L2_CONFIGURATION(_nr) + 0x8)
150#define EXYNOS_L2_COMMON_PWR_EN 0x3
151
152#define EXYNOS_ARM_CORE_X_STATUS_OFFSET 0x4
153
154#define EXYNOS5_APLL_SYSCLK_CONFIGURATION 0x2A00
155#define EXYNOS5_APLL_SYSCLK_STATUS 0x2A04
156
157#define EXYNOS5_ARM_L2_OPTION 0x2608
158#define EXYNOS5_USE_RETENTION BIT(4)
159
160#define EXYNOS5_L2RSTDISABLE_VALUE BIT(3)
161
121#define S5P_PAD_RET_MAUDIO_OPTION 0x3028 162#define S5P_PAD_RET_MAUDIO_OPTION 0x3028
122#define S5P_PAD_RET_GPIO_OPTION 0x3108 163#define S5P_PAD_RET_GPIO_OPTION 0x3108
123#define S5P_PAD_RET_UART_OPTION 0x3128 164#define S5P_PAD_RET_UART_OPTION 0x3128
@@ -126,7 +167,19 @@
126#define S5P_PAD_RET_EBIA_OPTION 0x3188 167#define S5P_PAD_RET_EBIA_OPTION 0x3188
127#define S5P_PAD_RET_EBIB_OPTION 0x31A8 168#define S5P_PAD_RET_EBIB_OPTION 0x31A8
128 169
170#define S5P_PS_HOLD_CONTROL 0x330C
171#define S5P_PS_HOLD_EN (1 << 31)
172#define S5P_PS_HOLD_OUTPUT_HIGH (3 << 8)
173
174#define S5P_CAM_OPTION 0x3C08
175#define S5P_MFC_OPTION 0x3C48
176#define S5P_G3D_OPTION 0x3C68
177#define S5P_LCD0_OPTION 0x3C88
178#define S5P_LCD1_OPTION 0x3CA8
179#define S5P_ISP_OPTION S5P_LCD1_OPTION
180
129#define S5P_CORE_LOCAL_PWR_EN 0x3 181#define S5P_CORE_LOCAL_PWR_EN 0x3
182#define S5P_CORE_WAKEUP_FROM_LOCAL_CFG (0x3 << 8)
130 183
131/* Only for EXYNOS4210 */ 184/* Only for EXYNOS4210 */
132#define S5P_CMU_CLKSTOP_LCD1_LOWPWR 0x1154 185#define S5P_CMU_CLKSTOP_LCD1_LOWPWR 0x1154
@@ -185,11 +238,116 @@
185#define S5P_DIS_IRQ_CORE3 0x1034 238#define S5P_DIS_IRQ_CORE3 0x1034
186#define S5P_DIS_IRQ_CENTRAL3 0x1038 239#define S5P_DIS_IRQ_CENTRAL3 0x1038
187 240
241/* Only for EXYNOS3XXX */
242#define EXYNOS3_ARM_CORE0_SYS_PWR_REG 0x1000
243#define EXYNOS3_DIS_IRQ_ARM_CORE0_LOCAL_SYS_PWR_REG 0x1004
244#define EXYNOS3_DIS_IRQ_ARM_CORE0_CENTRAL_SYS_PWR_REG 0x1008
245#define EXYNOS3_ARM_CORE1_SYS_PWR_REG 0x1010
246#define EXYNOS3_DIS_IRQ_ARM_CORE1_LOCAL_SYS_PWR_REG 0x1014
247#define EXYNOS3_DIS_IRQ_ARM_CORE1_CENTRAL_SYS_PWR_REG 0x1018
248#define EXYNOS3_ISP_ARM_SYS_PWR_REG 0x1050
249#define EXYNOS3_DIS_IRQ_ISP_ARM_LOCAL_SYS_PWR_REG 0x1054
250#define EXYNOS3_DIS_IRQ_ISP_ARM_CENTRAL_SYS_PWR_REG 0x1058
251#define EXYNOS3_ARM_COMMON_SYS_PWR_REG 0x1080
252#define EXYNOS3_ARM_L2_SYS_PWR_REG 0x10C0
253#define EXYNOS3_CMU_ACLKSTOP_SYS_PWR_REG 0x1100
254#define EXYNOS3_CMU_SCLKSTOP_SYS_PWR_REG 0x1104
255#define EXYNOS3_CMU_RESET_SYS_PWR_REG 0x110C
256#define EXYNOS3_CMU_ACLKSTOP_COREBLK_SYS_PWR_REG 0x1110
257#define EXYNOS3_CMU_SCLKSTOP_COREBLK_SYS_PWR_REG 0x1114
258#define EXYNOS3_CMU_RESET_COREBLK_SYS_PWR_REG 0x111C
259#define EXYNOS3_APLL_SYSCLK_SYS_PWR_REG 0x1120
260#define EXYNOS3_MPLL_SYSCLK_SYS_PWR_REG 0x1124
261#define EXYNOS3_VPLL_SYSCLK_SYS_PWR_REG 0x1128
262#define EXYNOS3_EPLL_SYSCLK_SYS_PWR_REG 0x112C
263#define EXYNOS3_MPLLUSER_SYSCLK_SYS_PWR_REG 0x1130
264#define EXYNOS3_BPLLUSER_SYSCLK_SYS_PWR_REG 0x1134
265#define EXYNOS3_EPLLUSER_SYSCLK_SYS_PWR_REG 0x1138
266#define EXYNOS3_CMU_CLKSTOP_CAM_SYS_PWR_REG 0x1140
267#define EXYNOS3_CMU_CLKSTOP_MFC_SYS_PWR_REG 0x1148
268#define EXYNOS3_CMU_CLKSTOP_G3D_SYS_PWR_REG 0x114C
269#define EXYNOS3_CMU_CLKSTOP_LCD0_SYS_PWR_REG 0x1150
270#define EXYNOS3_CMU_CLKSTOP_ISP_SYS_PWR_REG 0x1154
271#define EXYNOS3_CMU_CLKSTOP_MAUDIO_SYS_PWR_REG 0x1158
272#define EXYNOS3_CMU_RESET_CAM_SYS_PWR_REG 0x1160
273#define EXYNOS3_CMU_RESET_MFC_SYS_PWR_REG 0x1168
274#define EXYNOS3_CMU_RESET_G3D_SYS_PWR_REG 0x116C
275#define EXYNOS3_CMU_RESET_LCD0_SYS_PWR_REG 0x1170
276#define EXYNOS3_CMU_RESET_ISP_SYS_PWR_REG 0x1174
277#define EXYNOS3_CMU_RESET_MAUDIO_SYS_PWR_REG 0x1178
278#define EXYNOS3_TOP_BUS_SYS_PWR_REG 0x1180
279#define EXYNOS3_TOP_RETENTION_SYS_PWR_REG 0x1184
280#define EXYNOS3_TOP_PWR_SYS_PWR_REG 0x1188
281#define EXYNOS3_TOP_BUS_COREBLK_SYS_PWR_REG 0x1190
282#define EXYNOS3_TOP_RETENTION_COREBLK_SYS_PWR_REG 0x1194
283#define EXYNOS3_TOP_PWR_COREBLK_SYS_PWR_REG 0x1198
284#define EXYNOS3_LOGIC_RESET_SYS_PWR_REG 0x11A0
285#define EXYNOS3_OSCCLK_GATE_SYS_PWR_REG 0x11A4
286#define EXYNOS3_LOGIC_RESET_COREBLK_SYS_PWR_REG 0x11B0
287#define EXYNOS3_OSCCLK_GATE_COREBLK_SYS_PWR_REG 0x11B4
288#define EXYNOS3_PAD_RETENTION_DRAM_SYS_PWR_REG 0x1200
289#define EXYNOS3_PAD_RETENTION_MAUDIO_SYS_PWR_REG 0x1204
290#define EXYNOS3_PAD_RETENTION_SPI_SYS_PWR_REG 0x1208
291#define EXYNOS3_PAD_RETENTION_MMC2_SYS_PWR_REG 0x1218
292#define EXYNOS3_PAD_RETENTION_GPIO_SYS_PWR_REG 0x1220
293#define EXYNOS3_PAD_RETENTION_UART_SYS_PWR_REG 0x1224
294#define EXYNOS3_PAD_RETENTION_MMC0_SYS_PWR_REG 0x1228
295#define EXYNOS3_PAD_RETENTION_MMC1_SYS_PWR_REG 0x122C
296#define EXYNOS3_PAD_RETENTION_EBIA_SYS_PWR_REG 0x1230
297#define EXYNOS3_PAD_RETENTION_EBIB_SYS_PWR_REG 0x1234
298#define EXYNOS3_PAD_RETENTION_JTAG_SYS_PWR_REG 0x1238
299#define EXYNOS3_PAD_ISOLATION_SYS_PWR_REG 0x1240
300#define EXYNOS3_PAD_ALV_SEL_SYS_PWR_REG 0x1260
301#define EXYNOS3_XUSBXTI_SYS_PWR_REG 0x1280
302#define EXYNOS3_XXTI_SYS_PWR_REG 0x1284
303#define EXYNOS3_EXT_REGULATOR_SYS_PWR_REG 0x12C0
304#define EXYNOS3_EXT_REGULATOR_COREBLK_SYS_PWR_REG 0x12C4
305#define EXYNOS3_GPIO_MODE_SYS_PWR_REG 0x1300
306#define EXYNOS3_GPIO_MODE_MAUDIO_SYS_PWR_REG 0x1340
307#define EXYNOS3_TOP_ASB_RESET_SYS_PWR_REG 0x1344
308#define EXYNOS3_TOP_ASB_ISOLATION_SYS_PWR_REG 0x1348
309#define EXYNOS3_TOP_ASB_RESET_COREBLK_SYS_PWR_REG 0x1350
310#define EXYNOS3_TOP_ASB_ISOLATION_COREBLK_SYS_PWR_REG 0x1354
311#define EXYNOS3_CAM_SYS_PWR_REG 0x1380
312#define EXYNOS3_MFC_SYS_PWR_REG 0x1388
313#define EXYNOS3_G3D_SYS_PWR_REG 0x138C
314#define EXYNOS3_LCD0_SYS_PWR_REG 0x1390
315#define EXYNOS3_ISP_SYS_PWR_REG 0x1394
316#define EXYNOS3_MAUDIO_SYS_PWR_REG 0x1398
317#define EXYNOS3_DRAM_FREQ_DOWN_SYS_PWR_REG 0x13B0
318#define EXYNOS3_DDRPHY_DLLOFF_SYS_PWR_REG 0x13B4
319#define EXYNOS3_CMU_SYSCLK_ISP_SYS_PWR_REG 0x13B8
320#define EXYNOS3_LPDDR_PHY_DLL_LOCK_SYS_PWR_REG 0x13C0
321#define EXYNOS3_BPLL_SYSCLK_SYS_PWR_REG 0x13C4
322#define EXYNOS3_UPLL_SYSCLK_SYS_PWR_REG 0x13C8
323
324#define EXYNOS3_ARM_CORE0_OPTION 0x2008
325#define EXYNOS3_ARM_CORE_OPTION(_nr) \
326 (EXYNOS3_ARM_CORE0_OPTION + ((_nr) * 0x80))
327
328#define EXYNOS3_ARM_COMMON_OPTION 0x2408
329#define EXYNOS3_TOP_PWR_OPTION 0x2C48
330#define EXYNOS3_CORE_TOP_PWR_OPTION 0x2CA8
331#define EXYNOS3_XUSBXTI_DURATION 0x341C
332#define EXYNOS3_XXTI_DURATION 0x343C
333#define EXYNOS3_EXT_REGULATOR_DURATION 0x361C
334#define EXYNOS3_EXT_REGULATOR_COREBLK_DURATION 0x363C
335#define XUSBXTI_DURATION 0x00000BB8
336#define XXTI_DURATION XUSBXTI_DURATION
337#define EXT_REGULATOR_DURATION 0x00001D4C
338#define EXT_REGULATOR_COREBLK_DURATION EXT_REGULATOR_DURATION
339
340/* for XXX_OPTION */
341#define EXYNOS3_OPTION_USE_SC_COUNTER (1 << 0)
342#define EXYNOS3_OPTION_USE_SC_FEEDBACK (1 << 1)
343#define EXYNOS3_OPTION_SKIP_DEACTIVATE_ACEACP_IN_PWDN (1 << 7)
344
188/* For EXYNOS5 */ 345/* For EXYNOS5 */
189 346
190#define EXYNOS5_AUTO_WDTRESET_DISABLE 0x0408 347#define EXYNOS5_AUTO_WDTRESET_DISABLE 0x0408
191#define EXYNOS5_MASK_WDTRESET_REQUEST 0x040C 348#define EXYNOS5_MASK_WDTRESET_REQUEST 0x040C
192 349
350#define EXYNOS5_USE_RETENTION BIT(4)
193#define EXYNOS5_SYS_WDTRESET (1 << 20) 351#define EXYNOS5_SYS_WDTRESET (1 << 20)
194 352
195#define EXYNOS5_ARM_CORE0_SYS_PWR_REG 0x1000 353#define EXYNOS5_ARM_CORE0_SYS_PWR_REG 0x1000
@@ -329,4 +487,204 @@ static inline unsigned int exynos_pmu_cpunr(unsigned int mpidr)
329 + MPIDR_AFFINITY_LEVEL(mpidr, 0)); 487 + MPIDR_AFFINITY_LEVEL(mpidr, 0));
330} 488}
331 489
490/* Only for EXYNOS5420 */
491#define EXYNOS5420_ISP_ARM_OPTION 0x2488
492#define EXYNOS5420_L2RSTDISABLE_VALUE BIT(3)
493
494#define EXYNOS5420_LPI_MASK 0x0004
495#define EXYNOS5420_LPI_MASK1 0x0008
496#define EXYNOS5420_UFS BIT(8)
497#define EXYNOS5420_ATB_KFC BIT(13)
498#define EXYNOS5420_ATB_ISP_ARM BIT(19)
499#define EXYNOS5420_EMULATION BIT(31)
500#define ATB_ISP_ARM BIT(12)
501#define ATB_KFC BIT(13)
502#define ATB_NOC BIT(14)
503
504#define EXYNOS5420_ARM_INTR_SPREAD_ENABLE 0x0100
505#define EXYNOS5420_ARM_INTR_SPREAD_USE_STANDBYWFI 0x0104
506#define EXYNOS5420_UP_SCHEDULER 0x0120
507#define SPREAD_ENABLE 0xF
508#define SPREAD_USE_STANDWFI 0xF
509
510#define EXYNOS5420_BB_CON1 0x0784
511#define EXYNOS5420_BB_SEL_EN BIT(31)
512#define EXYNOS5420_BB_PMOS_EN BIT(7)
513#define EXYNOS5420_BB_1300X 0XF
514
515#define EXYNOS5420_ARM_CORE2_SYS_PWR_REG 0x1020
516#define EXYNOS5420_DIS_IRQ_ARM_CORE2_LOCAL_SYS_PWR_REG 0x1024
517#define EXYNOS5420_DIS_IRQ_ARM_CORE2_CENTRAL_SYS_PWR_REG 0x1028
518#define EXYNOS5420_ARM_CORE3_SYS_PWR_REG 0x1030
519#define EXYNOS5420_DIS_IRQ_ARM_CORE3_LOCAL_SYS_PWR_REG 0x1034
520#define EXYNOS5420_DIS_IRQ_ARM_CORE3_CENTRAL_SYS_PWR_REG 0x1038
521#define EXYNOS5420_KFC_CORE0_SYS_PWR_REG 0x1040
522#define EXYNOS5420_DIS_IRQ_KFC_CORE0_LOCAL_SYS_PWR_REG 0x1044
523#define EXYNOS5420_DIS_IRQ_KFC_CORE0_CENTRAL_SYS_PWR_REG 0x1048
524#define EXYNOS5420_KFC_CORE1_SYS_PWR_REG 0x1050
525#define EXYNOS5420_DIS_IRQ_KFC_CORE1_LOCAL_SYS_PWR_REG 0x1054
526#define EXYNOS5420_DIS_IRQ_KFC_CORE1_CENTRAL_SYS_PWR_REG 0x1058
527#define EXYNOS5420_KFC_CORE2_SYS_PWR_REG 0x1060
528#define EXYNOS5420_DIS_IRQ_KFC_CORE2_LOCAL_SYS_PWR_REG 0x1064
529#define EXYNOS5420_DIS_IRQ_KFC_CORE2_CENTRAL_SYS_PWR_REG 0x1068
530#define EXYNOS5420_KFC_CORE3_SYS_PWR_REG 0x1070
531#define EXYNOS5420_DIS_IRQ_KFC_CORE3_LOCAL_SYS_PWR_REG 0x1074
532#define EXYNOS5420_DIS_IRQ_KFC_CORE3_CENTRAL_SYS_PWR_REG 0x1078
533#define EXYNOS5420_ISP_ARM_SYS_PWR_REG 0x1090
534#define EXYNOS5420_DIS_IRQ_ISP_ARM_LOCAL_SYS_PWR_REG 0x1094
535#define EXYNOS5420_DIS_IRQ_ISP_ARM_CENTRAL_SYS_PWR_REG 0x1098
536#define EXYNOS5420_ARM_COMMON_SYS_PWR_REG 0x10A0
537#define EXYNOS5420_KFC_COMMON_SYS_PWR_REG 0x10B0
538#define EXYNOS5420_KFC_L2_SYS_PWR_REG 0x10D0
539#define EXYNOS5420_DPLL_SYSCLK_SYS_PWR_REG 0x1158
540#define EXYNOS5420_IPLL_SYSCLK_SYS_PWR_REG 0x115C
541#define EXYNOS5420_KPLL_SYSCLK_SYS_PWR_REG 0x1160
542#define EXYNOS5420_RPLL_SYSCLK_SYS_PWR_REG 0x1174
543#define EXYNOS5420_SPLL_SYSCLK_SYS_PWR_REG 0x1178
544#define EXYNOS5420_INTRAM_MEM_SYS_PWR_REG 0x11B8
545#define EXYNOS5420_INTROM_MEM_SYS_PWR_REG 0x11BC
546#define EXYNOS5420_ONENANDXL_MEM_SYS_PWR 0x11C0
547#define EXYNOS5420_USBDEV_MEM_SYS_PWR 0x11CC
548#define EXYNOS5420_USBDEV1_MEM_SYS_PWR 0x11D0
549#define EXYNOS5420_SDMMC_MEM_SYS_PWR 0x11D4
550#define EXYNOS5420_CSSYS_MEM_SYS_PWR 0x11D8
551#define EXYNOS5420_SECSS_MEM_SYS_PWR 0x11DC
552#define EXYNOS5420_ROTATOR_MEM_SYS_PWR 0x11E0
553#define EXYNOS5420_INTRAM_MEM_SYS_PWR 0x11E4
554#define EXYNOS5420_INTROM_MEM_SYS_PWR 0x11E8
555#define EXYNOS5420_PAD_RETENTION_JTAG_SYS_PWR_REG 0x1208
556#define EXYNOS5420_PAD_RETENTION_DRAM_SYS_PWR_REG 0x1210
557#define EXYNOS5420_PAD_RETENTION_UART_SYS_PWR_REG 0x1214
558#define EXYNOS5420_PAD_RETENTION_MMC0_SYS_PWR_REG 0x1218
559#define EXYNOS5420_PAD_RETENTION_MMC1_SYS_PWR_REG 0x121C
560#define EXYNOS5420_PAD_RETENTION_MMC2_SYS_PWR_REG 0x1220
561#define EXYNOS5420_PAD_RETENTION_HSI_SYS_PWR_REG 0x1224
562#define EXYNOS5420_PAD_RETENTION_EBIA_SYS_PWR_REG 0x1228
563#define EXYNOS5420_PAD_RETENTION_EBIB_SYS_PWR_REG 0x122C
564#define EXYNOS5420_PAD_RETENTION_SPI_SYS_PWR_REG 0x1230
565#define EXYNOS5420_PAD_RETENTION_DRAM_COREBLK_SYS_PWR_REG 0x1234
566#define EXYNOS5420_DISP1_SYS_PWR_REG 0x1410
567#define EXYNOS5420_MAU_SYS_PWR_REG 0x1414
568#define EXYNOS5420_G2D_SYS_PWR_REG 0x1418
569#define EXYNOS5420_MSC_SYS_PWR_REG 0x141C
570#define EXYNOS5420_FSYS_SYS_PWR_REG 0x1420
571#define EXYNOS5420_FSYS2_SYS_PWR_REG 0x1424
572#define EXYNOS5420_PSGEN_SYS_PWR_REG 0x1428
573#define EXYNOS5420_PERIC_SYS_PWR_REG 0x142C
574#define EXYNOS5420_WCORE_SYS_PWR_REG 0x1430
575#define EXYNOS5420_CMU_CLKSTOP_DISP1_SYS_PWR_REG 0x1490
576#define EXYNOS5420_CMU_CLKSTOP_MAU_SYS_PWR_REG 0x1494
577#define EXYNOS5420_CMU_CLKSTOP_G2D_SYS_PWR_REG 0x1498
578#define EXYNOS5420_CMU_CLKSTOP_MSC_SYS_PWR_REG 0x149C
579#define EXYNOS5420_CMU_CLKSTOP_FSYS_SYS_PWR_REG 0x14A0
580#define EXYNOS5420_CMU_CLKSTOP_FSYS2_SYS_PWR_REG 0x14A4
581#define EXYNOS5420_CMU_CLKSTOP_PSGEN_SYS_PWR_REG 0x14A8
582#define EXYNOS5420_CMU_CLKSTOP_PERIC_SYS_PWR_REG 0x14AC
583#define EXYNOS5420_CMU_CLKSTOP_WCORE_SYS_PWR_REG 0x14B0
584#define EXYNOS5420_CMU_SYSCLK_TOPPWR_SYS_PWR_REG 0x14BC
585#define EXYNOS5420_CMU_SYSCLK_DISP1_SYS_PWR_REG 0x14D0
586#define EXYNOS5420_CMU_SYSCLK_MAU_SYS_PWR_REG 0x14D4
587#define EXYNOS5420_CMU_SYSCLK_G2D_SYS_PWR_REG 0x14D8
588#define EXYNOS5420_CMU_SYSCLK_MSC_SYS_PWR_REG 0x14DC
589#define EXYNOS5420_CMU_SYSCLK_FSYS_SYS_PWR_REG 0x14E0
590#define EXYNOS5420_CMU_SYSCLK_FSYS2_SYS_PWR_REG 0x14E4
591#define EXYNOS5420_CMU_SYSCLK_PSGEN_SYS_PWR_REG 0x14E8
592#define EXYNOS5420_CMU_SYSCLK_PERIC_SYS_PWR_REG 0x14EC
593#define EXYNOS5420_CMU_SYSCLK_WCORE_SYS_PWR_REG 0x14F0
594#define EXYNOS5420_CMU_SYSCLK_SYSMEM_TOPPWR_SYS_PWR_REG 0x14F4
595#define EXYNOS5420_CMU_RESET_FSYS2_SYS_PWR_REG 0x1570
596#define EXYNOS5420_CMU_RESET_PSGEN_SYS_PWR_REG 0x1574
597#define EXYNOS5420_CMU_RESET_PERIC_SYS_PWR_REG 0x1578
598#define EXYNOS5420_CMU_RESET_WCORE_SYS_PWR_REG 0x157C
599#define EXYNOS5420_CMU_RESET_DISP1_SYS_PWR_REG 0x1590
600#define EXYNOS5420_CMU_RESET_MAU_SYS_PWR_REG 0x1594
601#define EXYNOS5420_CMU_RESET_G2D_SYS_PWR_REG 0x1598
602#define EXYNOS5420_CMU_RESET_MSC_SYS_PWR_REG 0x159C
603#define EXYNOS5420_CMU_RESET_FSYS_SYS_PWR_REG 0x15A0
604#define EXYNOS5420_SFR_AXI_CGDIS1 0x15E4
605#define EXYNOS_ARM_CORE2_CONFIGURATION 0x2100
606#define EXYNOS5420_ARM_CORE2_OPTION 0x2108
607#define EXYNOS_ARM_CORE3_CONFIGURATION 0x2180
608#define EXYNOS5420_ARM_CORE3_OPTION 0x2188
609#define EXYNOS5420_ARM_COMMON_STATUS 0x2504
610#define EXYNOS5420_ARM_COMMON_OPTION 0x2508
611#define EXYNOS5420_KFC_COMMON_STATUS 0x2584
612#define EXYNOS5420_KFC_COMMON_OPTION 0x2588
613#define EXYNOS5420_LOGIC_RESET_DURATION3 0x2D1C
614
615#define EXYNOS5420_PAD_RET_GPIO_OPTION 0x30C8
616#define EXYNOS5420_PAD_RET_UART_OPTION 0x30E8
617#define EXYNOS5420_PAD_RET_MMCA_OPTION 0x3108
618#define EXYNOS5420_PAD_RET_MMCB_OPTION 0x3128
619#define EXYNOS5420_PAD_RET_MMCC_OPTION 0x3148
620#define EXYNOS5420_PAD_RET_HSI_OPTION 0x3168
621#define EXYNOS5420_PAD_RET_SPI_OPTION 0x31C8
622#define EXYNOS5420_PAD_RET_DRAM_COREBLK_OPTION 0x31E8
623#define EXYNOS_PAD_RET_DRAM_OPTION 0x3008
624#define EXYNOS_PAD_RET_MAUDIO_OPTION 0x3028
625#define EXYNOS_PAD_RET_JTAG_OPTION 0x3048
626#define EXYNOS_PAD_RET_GPIO_OPTION 0x3108
627#define EXYNOS_PAD_RET_UART_OPTION 0x3128
628#define EXYNOS_PAD_RET_MMCA_OPTION 0x3148
629#define EXYNOS_PAD_RET_MMCB_OPTION 0x3168
630#define EXYNOS_PAD_RET_EBIA_OPTION 0x3188
631#define EXYNOS_PAD_RET_EBIB_OPTION 0x31A8
632
633#define EXYNOS_PS_HOLD_CONTROL 0x330C
634
635/* For SYS_PWR_REG */
636#define EXYNOS_SYS_PWR_CFG BIT(0)
637
638#define EXYNOS5420_MFC_CONFIGURATION 0x4060
639#define EXYNOS5420_MFC_STATUS 0x4064
640#define EXYNOS5420_MFC_OPTION 0x4068
641#define EXYNOS5420_G3D_CONFIGURATION 0x4080
642#define EXYNOS5420_G3D_STATUS 0x4084
643#define EXYNOS5420_G3D_OPTION 0x4088
644#define EXYNOS5420_DISP0_CONFIGURATION 0x40A0
645#define EXYNOS5420_DISP0_STATUS 0x40A4
646#define EXYNOS5420_DISP0_OPTION 0x40A8
647#define EXYNOS5420_DISP1_CONFIGURATION 0x40C0
648#define EXYNOS5420_DISP1_STATUS 0x40C4
649#define EXYNOS5420_DISP1_OPTION 0x40C8
650#define EXYNOS5420_MAU_CONFIGURATION 0x40E0
651#define EXYNOS5420_MAU_STATUS 0x40E4
652#define EXYNOS5420_MAU_OPTION 0x40E8
653#define EXYNOS5420_FSYS2_OPTION 0x4168
654#define EXYNOS5420_PSGEN_OPTION 0x4188
655
656/* For EXYNOS_CENTRAL_SEQ_OPTION */
657#define EXYNOS5_USE_STANDBYWFI_ARM_CORE0 BIT(16)
658#define EXYNOS5_USE_STANDBYWFI_ARM_CORE1 BUT(17)
659#define EXYNOS5_USE_STANDBYWFE_ARM_CORE0 BIT(24)
660#define EXYNOS5_USE_STANDBYWFE_ARM_CORE1 BIT(25)
661
662#define EXYNOS5420_ARM_USE_STANDBY_WFI0 BIT(4)
663#define EXYNOS5420_ARM_USE_STANDBY_WFI1 BIT(5)
664#define EXYNOS5420_ARM_USE_STANDBY_WFI2 BIT(6)
665#define EXYNOS5420_ARM_USE_STANDBY_WFI3 BIT(7)
666#define EXYNOS5420_KFC_USE_STANDBY_WFI0 BIT(8)
667#define EXYNOS5420_KFC_USE_STANDBY_WFI1 BIT(9)
668#define EXYNOS5420_KFC_USE_STANDBY_WFI2 BIT(10)
669#define EXYNOS5420_KFC_USE_STANDBY_WFI3 BIT(11)
670#define EXYNOS5420_ARM_USE_STANDBY_WFE0 BIT(16)
671#define EXYNOS5420_ARM_USE_STANDBY_WFE1 BIT(17)
672#define EXYNOS5420_ARM_USE_STANDBY_WFE2 BIT(18)
673#define EXYNOS5420_ARM_USE_STANDBY_WFE3 BIT(19)
674#define EXYNOS5420_KFC_USE_STANDBY_WFE0 BIT(20)
675#define EXYNOS5420_KFC_USE_STANDBY_WFE1 BIT(21)
676#define EXYNOS5420_KFC_USE_STANDBY_WFE2 BIT(22)
677#define EXYNOS5420_KFC_USE_STANDBY_WFE3 BIT(23)
678
679#define DUR_WAIT_RESET 0xF
680
681#define EXYNOS5420_USE_STANDBY_WFI_ALL (EXYNOS5420_ARM_USE_STANDBY_WFI0 \
682 | EXYNOS5420_ARM_USE_STANDBY_WFI1 \
683 | EXYNOS5420_ARM_USE_STANDBY_WFI2 \
684 | EXYNOS5420_ARM_USE_STANDBY_WFI3 \
685 | EXYNOS5420_KFC_USE_STANDBY_WFI0 \
686 | EXYNOS5420_KFC_USE_STANDBY_WFI1 \
687 | EXYNOS5420_KFC_USE_STANDBY_WFI2 \
688 | EXYNOS5420_KFC_USE_STANDBY_WFI3)
689
332#endif /* __ASM_ARCH_REGS_PMU_H */ 690#endif /* __ASM_ARCH_REGS_PMU_H */
diff --git a/arch/arm/mach-exynos/sleep.S b/arch/arm/mach-exynos/sleep.S
index 108a45f4bb62..e3c373082bbe 100644
--- a/arch/arm/mach-exynos/sleep.S
+++ b/arch/arm/mach-exynos/sleep.S
@@ -16,6 +16,7 @@
16 */ 16 */
17 17
18#include <linux/linkage.h> 18#include <linux/linkage.h>
19#include "smc.h"
19 20
20#define CPU_MASK 0xff0ffff0 21#define CPU_MASK 0xff0ffff0
21#define CPU_CORTEX_A9 0x410fc090 22#define CPU_CORTEX_A9 0x410fc090
@@ -55,3 +56,30 @@ ENTRY(exynos_cpu_resume)
55#endif 56#endif
56 b cpu_resume 57 b cpu_resume
57ENDPROC(exynos_cpu_resume) 58ENDPROC(exynos_cpu_resume)
59
60 .align
61
62ENTRY(exynos_cpu_resume_ns)
63 mrc p15, 0, r0, c0, c0, 0
64 ldr r1, =CPU_MASK
65 and r0, r0, r1
66 ldr r1, =CPU_CORTEX_A9
67 cmp r0, r1
68 bne skip_cp15
69
70 adr r0, cp15_save_power
71 ldr r1, [r0]
72 adr r0, cp15_save_diag
73 ldr r2, [r0]
74 mov r0, #SMC_CMD_C15RESUME
75 dsb
76 smc #0
77skip_cp15:
78 b cpu_resume
79ENDPROC(exynos_cpu_resume_ns)
80 .globl cp15_save_diag
81cp15_save_diag:
82 .long 0 @ cp15 diagnostic
83 .globl cp15_save_power
84cp15_save_power:
85 .long 0 @ cp15 power control
diff --git a/arch/arm/mach-exynos/smc.h b/arch/arm/mach-exynos/smc.h
index 13a1dc8ecbf2..f7b82f9c1e21 100644
--- a/arch/arm/mach-exynos/smc.h
+++ b/arch/arm/mach-exynos/smc.h
@@ -26,6 +26,10 @@
26#define SMC_CMD_L2X0INVALL (-24) 26#define SMC_CMD_L2X0INVALL (-24)
27#define SMC_CMD_L2X0DEBUG (-25) 27#define SMC_CMD_L2X0DEBUG (-25)
28 28
29#ifndef __ASSEMBLY__
30
29extern void exynos_smc(u32 cmd, u32 arg1, u32 arg2, u32 arg3); 31extern void exynos_smc(u32 cmd, u32 arg1, u32 arg2, u32 arg3);
30 32
33#endif /* __ASSEMBLY__ */
34
31#endif 35#endif
diff --git a/arch/arm/mach-exynos/suspend.c b/arch/arm/mach-exynos/suspend.c
new file mode 100644
index 000000000000..f8e7dcd17055
--- /dev/null
+++ b/arch/arm/mach-exynos/suspend.c
@@ -0,0 +1,566 @@
1/*
2 * Copyright (c) 2011-2014 Samsung Electronics Co., Ltd.
3 * http://www.samsung.com
4 *
5 * EXYNOS - Suspend support
6 *
7 * Based on arch/arm/mach-s3c2410/pm.c
8 * Copyright (c) 2006 Simtec Electronics
9 * Ben Dooks <ben@simtec.co.uk>
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License version 2 as
13 * published by the Free Software Foundation.
14 */
15
16#include <linux/init.h>
17#include <linux/suspend.h>
18#include <linux/syscore_ops.h>
19#include <linux/cpu_pm.h>
20#include <linux/io.h>
21#include <linux/irqchip/arm-gic.h>
22#include <linux/err.h>
23#include <linux/regulator/machine.h>
24
25#include <asm/cacheflush.h>
26#include <asm/hardware/cache-l2x0.h>
27#include <asm/firmware.h>
28#include <asm/mcpm.h>
29#include <asm/smp_scu.h>
30#include <asm/suspend.h>
31
32#include <plat/pm-common.h>
33#include <plat/regs-srom.h>
34
35#include "common.h"
36#include "regs-pmu.h"
37#include "regs-sys.h"
38#include "exynos-pmu.h"
39
40#define S5P_CHECK_SLEEP 0x00000BAD
41
42#define REG_TABLE_END (-1U)
43
44#define EXYNOS5420_CPU_STATE 0x28
45
46/**
47 * struct exynos_wkup_irq - Exynos GIC to PMU IRQ mapping
48 * @hwirq: Hardware IRQ signal of the GIC
49 * @mask: Mask in PMU wake-up mask register
50 */
51struct exynos_wkup_irq {
52 unsigned int hwirq;
53 u32 mask;
54};
55
56static struct sleep_save exynos5_sys_save[] = {
57 SAVE_ITEM(EXYNOS5_SYS_I2C_CFG),
58};
59
60static struct sleep_save exynos_core_save[] = {
61 /* SROM side */
62 SAVE_ITEM(S5P_SROM_BW),
63 SAVE_ITEM(S5P_SROM_BC0),
64 SAVE_ITEM(S5P_SROM_BC1),
65 SAVE_ITEM(S5P_SROM_BC2),
66 SAVE_ITEM(S5P_SROM_BC3),
67};
68
69struct exynos_pm_data {
70 const struct exynos_wkup_irq *wkup_irq;
71 struct sleep_save *extra_save;
72 int num_extra_save;
73 unsigned int wake_disable_mask;
74 unsigned int *release_ret_regs;
75
76 void (*pm_prepare)(void);
77 void (*pm_resume_prepare)(void);
78 void (*pm_resume)(void);
79 int (*pm_suspend)(void);
80 int (*cpu_suspend)(unsigned long);
81};
82
83struct exynos_pm_data *pm_data;
84
85static int exynos5420_cpu_state;
86static unsigned int exynos_pmu_spare3;
87
88/*
89 * GIC wake-up support
90 */
91
92static u32 exynos_irqwake_intmask = 0xffffffff;
93
94static const struct exynos_wkup_irq exynos4_wkup_irq[] = {
95 { 76, BIT(1) }, /* RTC alarm */
96 { 77, BIT(2) }, /* RTC tick */
97 { /* sentinel */ },
98};
99
100static const struct exynos_wkup_irq exynos5250_wkup_irq[] = {
101 { 75, BIT(1) }, /* RTC alarm */
102 { 76, BIT(2) }, /* RTC tick */
103 { /* sentinel */ },
104};
105
106unsigned int exynos_release_ret_regs[] = {
107 S5P_PAD_RET_MAUDIO_OPTION,
108 S5P_PAD_RET_GPIO_OPTION,
109 S5P_PAD_RET_UART_OPTION,
110 S5P_PAD_RET_MMCA_OPTION,
111 S5P_PAD_RET_MMCB_OPTION,
112 S5P_PAD_RET_EBIA_OPTION,
113 S5P_PAD_RET_EBIB_OPTION,
114 REG_TABLE_END,
115};
116
117unsigned int exynos5420_release_ret_regs[] = {
118 EXYNOS_PAD_RET_DRAM_OPTION,
119 EXYNOS_PAD_RET_MAUDIO_OPTION,
120 EXYNOS_PAD_RET_JTAG_OPTION,
121 EXYNOS5420_PAD_RET_GPIO_OPTION,
122 EXYNOS5420_PAD_RET_UART_OPTION,
123 EXYNOS5420_PAD_RET_MMCA_OPTION,
124 EXYNOS5420_PAD_RET_MMCB_OPTION,
125 EXYNOS5420_PAD_RET_MMCC_OPTION,
126 EXYNOS5420_PAD_RET_HSI_OPTION,
127 EXYNOS_PAD_RET_EBIA_OPTION,
128 EXYNOS_PAD_RET_EBIB_OPTION,
129 EXYNOS5420_PAD_RET_SPI_OPTION,
130 EXYNOS5420_PAD_RET_DRAM_COREBLK_OPTION,
131 REG_TABLE_END,
132};
133
134static int exynos_irq_set_wake(struct irq_data *data, unsigned int state)
135{
136 const struct exynos_wkup_irq *wkup_irq;
137
138 if (!pm_data->wkup_irq)
139 return -ENOENT;
140 wkup_irq = pm_data->wkup_irq;
141
142 while (wkup_irq->mask) {
143 if (wkup_irq->hwirq == data->hwirq) {
144 if (!state)
145 exynos_irqwake_intmask |= wkup_irq->mask;
146 else
147 exynos_irqwake_intmask &= ~wkup_irq->mask;
148 return 0;
149 }
150 ++wkup_irq;
151 }
152
153 return -ENOENT;
154}
155
156static int exynos_cpu_do_idle(void)
157{
158 /* issue the standby signal into the pm unit. */
159 cpu_do_idle();
160
161 pr_info("Failed to suspend the system\n");
162 return 1; /* Aborting suspend */
163}
164static void exynos_flush_cache_all(void)
165{
166 flush_cache_all();
167 outer_flush_all();
168}
169
170static int exynos_cpu_suspend(unsigned long arg)
171{
172 exynos_flush_cache_all();
173 return exynos_cpu_do_idle();
174}
175
176static int exynos5420_cpu_suspend(unsigned long arg)
177{
178 /* MCPM works with HW CPU identifiers */
179 unsigned int mpidr = read_cpuid_mpidr();
180 unsigned int cluster = MPIDR_AFFINITY_LEVEL(mpidr, 1);
181 unsigned int cpu = MPIDR_AFFINITY_LEVEL(mpidr, 0);
182
183 __raw_writel(0x0, sysram_base_addr + EXYNOS5420_CPU_STATE);
184
185 if (IS_ENABLED(CONFIG_EXYNOS5420_MCPM)) {
186 mcpm_set_entry_vector(cpu, cluster, exynos_cpu_resume);
187
188 /*
189 * Residency value passed to mcpm_cpu_suspend back-end
190 * has to be given clear semantics. Set to 0 as a
191 * temporary value.
192 */
193 mcpm_cpu_suspend(0);
194 }
195
196 pr_info("Failed to suspend the system\n");
197
198 /* return value != 0 means failure */
199 return 1;
200}
201
202static void exynos_pm_set_wakeup_mask(void)
203{
204 /* Set wake-up mask registers */
205 pmu_raw_writel(exynos_get_eint_wake_mask(), S5P_EINT_WAKEUP_MASK);
206 pmu_raw_writel(exynos_irqwake_intmask & ~(1 << 31), S5P_WAKEUP_MASK);
207}
208
209static void exynos_pm_enter_sleep_mode(void)
210{
211 /* Set value of power down register for sleep mode */
212 exynos_sys_powerdown_conf(SYS_SLEEP);
213 pmu_raw_writel(S5P_CHECK_SLEEP, S5P_INFORM1);
214}
215
216static void exynos_pm_prepare(void)
217{
218 /* Set wake-up mask registers */
219 exynos_pm_set_wakeup_mask();
220
221 s3c_pm_do_save(exynos_core_save, ARRAY_SIZE(exynos_core_save));
222
223 if (pm_data->extra_save)
224 s3c_pm_do_save(pm_data->extra_save,
225 pm_data->num_extra_save);
226
227 exynos_pm_enter_sleep_mode();
228
229 /* ensure at least INFORM0 has the resume address */
230 pmu_raw_writel(virt_to_phys(exynos_cpu_resume), S5P_INFORM0);
231}
232
233static void exynos5420_pm_prepare(void)
234{
235 unsigned int tmp;
236
237 /* Set wake-up mask registers */
238 exynos_pm_set_wakeup_mask();
239
240 s3c_pm_do_save(exynos_core_save, ARRAY_SIZE(exynos_core_save));
241
242 exynos_pmu_spare3 = pmu_raw_readl(S5P_PMU_SPARE3);
243 /*
244 * The cpu state needs to be saved and restored so that the
245 * secondary CPUs will enter low power start. Though the U-Boot
246 * is setting the cpu state with low power flag, the kernel
247 * needs to restore it back in case, the primary cpu fails to
248 * suspend for any reason.
249 */
250 exynos5420_cpu_state = __raw_readl(sysram_base_addr +
251 EXYNOS5420_CPU_STATE);
252
253 exynos_pm_enter_sleep_mode();
254
255 /* ensure at least INFORM0 has the resume address */
256 if (IS_ENABLED(CONFIG_EXYNOS5420_MCPM))
257 pmu_raw_writel(virt_to_phys(mcpm_entry_point), S5P_INFORM0);
258
259 tmp = pmu_raw_readl(EXYNOS5_ARM_L2_OPTION);
260 tmp &= ~EXYNOS5_USE_RETENTION;
261 pmu_raw_writel(tmp, EXYNOS5_ARM_L2_OPTION);
262
263 tmp = pmu_raw_readl(EXYNOS5420_SFR_AXI_CGDIS1);
264 tmp |= EXYNOS5420_UFS;
265 pmu_raw_writel(tmp, EXYNOS5420_SFR_AXI_CGDIS1);
266
267 tmp = pmu_raw_readl(EXYNOS5420_ARM_COMMON_OPTION);
268 tmp &= ~EXYNOS5420_L2RSTDISABLE_VALUE;
269 pmu_raw_writel(tmp, EXYNOS5420_ARM_COMMON_OPTION);
270
271 tmp = pmu_raw_readl(EXYNOS5420_FSYS2_OPTION);
272 tmp |= EXYNOS5420_EMULATION;
273 pmu_raw_writel(tmp, EXYNOS5420_FSYS2_OPTION);
274
275 tmp = pmu_raw_readl(EXYNOS5420_PSGEN_OPTION);
276 tmp |= EXYNOS5420_EMULATION;
277 pmu_raw_writel(tmp, EXYNOS5420_PSGEN_OPTION);
278}
279
280
281static int exynos_pm_suspend(void)
282{
283 exynos_pm_central_suspend();
284
285 if (read_cpuid_part() == ARM_CPU_PART_CORTEX_A9)
286 exynos_cpu_save_register();
287
288 return 0;
289}
290
291static int exynos5420_pm_suspend(void)
292{
293 u32 this_cluster;
294
295 exynos_pm_central_suspend();
296
297 /* Setting SEQ_OPTION register */
298
299 this_cluster = MPIDR_AFFINITY_LEVEL(read_cpuid_mpidr(), 1);
300 if (!this_cluster)
301 pmu_raw_writel(EXYNOS5420_ARM_USE_STANDBY_WFI0,
302 S5P_CENTRAL_SEQ_OPTION);
303 else
304 pmu_raw_writel(EXYNOS5420_KFC_USE_STANDBY_WFI0,
305 S5P_CENTRAL_SEQ_OPTION);
306 return 0;
307}
308
309static void exynos_pm_release_retention(void)
310{
311 unsigned int i;
312
313 for (i = 0; (pm_data->release_ret_regs[i] != REG_TABLE_END); i++)
314 pmu_raw_writel(EXYNOS_WAKEUP_FROM_LOWPWR,
315 pm_data->release_ret_regs[i]);
316}
317
318static void exynos_pm_resume(void)
319{
320 u32 cpuid = read_cpuid_part();
321
322 if (exynos_pm_central_resume())
323 goto early_wakeup;
324
325 /* For release retention */
326 exynos_pm_release_retention();
327
328 if (pm_data->extra_save)
329 s3c_pm_do_restore_core(pm_data->extra_save,
330 pm_data->num_extra_save);
331
332 s3c_pm_do_restore_core(exynos_core_save, ARRAY_SIZE(exynos_core_save));
333
334 if (cpuid == ARM_CPU_PART_CORTEX_A9)
335 scu_enable(S5P_VA_SCU);
336
337 if (call_firmware_op(resume) == -ENOSYS
338 && cpuid == ARM_CPU_PART_CORTEX_A9)
339 exynos_cpu_restore_register();
340
341early_wakeup:
342
343 /* Clear SLEEP mode set in INFORM1 */
344 pmu_raw_writel(0x0, S5P_INFORM1);
345}
346
347static void exynos5420_prepare_pm_resume(void)
348{
349 if (IS_ENABLED(CONFIG_EXYNOS5420_MCPM))
350 WARN_ON(mcpm_cpu_powered_up());
351}
352
353static void exynos5420_pm_resume(void)
354{
355 unsigned long tmp;
356
357 /* Restore the CPU0 low power state register */
358 tmp = pmu_raw_readl(EXYNOS5_ARM_CORE0_SYS_PWR_REG);
359 pmu_raw_writel(tmp | S5P_CORE_LOCAL_PWR_EN,
360 EXYNOS5_ARM_CORE0_SYS_PWR_REG);
361
362 /* Restore the sysram cpu state register */
363 __raw_writel(exynos5420_cpu_state,
364 sysram_base_addr + EXYNOS5420_CPU_STATE);
365
366 pmu_raw_writel(EXYNOS5420_USE_STANDBY_WFI_ALL,
367 S5P_CENTRAL_SEQ_OPTION);
368
369 if (exynos_pm_central_resume())
370 goto early_wakeup;
371
372 /* For release retention */
373 exynos_pm_release_retention();
374
375 pmu_raw_writel(exynos_pmu_spare3, S5P_PMU_SPARE3);
376
377 s3c_pm_do_restore_core(exynos_core_save, ARRAY_SIZE(exynos_core_save));
378
379early_wakeup:
380
381 tmp = pmu_raw_readl(EXYNOS5420_SFR_AXI_CGDIS1);
382 tmp &= ~EXYNOS5420_UFS;
383 pmu_raw_writel(tmp, EXYNOS5420_SFR_AXI_CGDIS1);
384
385 tmp = pmu_raw_readl(EXYNOS5420_FSYS2_OPTION);
386 tmp &= ~EXYNOS5420_EMULATION;
387 pmu_raw_writel(tmp, EXYNOS5420_FSYS2_OPTION);
388
389 tmp = pmu_raw_readl(EXYNOS5420_PSGEN_OPTION);
390 tmp &= ~EXYNOS5420_EMULATION;
391 pmu_raw_writel(tmp, EXYNOS5420_PSGEN_OPTION);
392
393 /* Clear SLEEP mode set in INFORM1 */
394 pmu_raw_writel(0x0, S5P_INFORM1);
395}
396
397/*
398 * Suspend Ops
399 */
400
401static int exynos_suspend_enter(suspend_state_t state)
402{
403 int ret;
404
405 s3c_pm_debug_init();
406
407 S3C_PMDBG("%s: suspending the system...\n", __func__);
408
409 S3C_PMDBG("%s: wakeup masks: %08x,%08x\n", __func__,
410 exynos_irqwake_intmask, exynos_get_eint_wake_mask());
411
412 if (exynos_irqwake_intmask == -1U
413 && exynos_get_eint_wake_mask() == -1U) {
414 pr_err("%s: No wake-up sources!\n", __func__);
415 pr_err("%s: Aborting sleep\n", __func__);
416 return -EINVAL;
417 }
418
419 s3c_pm_save_uarts();
420 if (pm_data->pm_prepare)
421 pm_data->pm_prepare();
422 flush_cache_all();
423 s3c_pm_check_store();
424
425 ret = call_firmware_op(suspend);
426 if (ret == -ENOSYS)
427 ret = cpu_suspend(0, pm_data->cpu_suspend);
428 if (ret)
429 return ret;
430
431 if (pm_data->pm_resume_prepare)
432 pm_data->pm_resume_prepare();
433 s3c_pm_restore_uarts();
434
435 S3C_PMDBG("%s: wakeup stat: %08x\n", __func__,
436 pmu_raw_readl(S5P_WAKEUP_STAT));
437
438 s3c_pm_check_restore();
439
440 S3C_PMDBG("%s: resuming the system...\n", __func__);
441
442 return 0;
443}
444
445static int exynos_suspend_prepare(void)
446{
447 int ret;
448
449 /*
450 * REVISIT: It would be better if struct platform_suspend_ops
451 * .prepare handler get the suspend_state_t as a parameter to
452 * avoid hard-coding the suspend to mem state. It's safe to do
453 * it now only because the suspend_valid_only_mem function is
454 * used as the .valid callback used to check if a given state
455 * is supported by the platform anyways.
456 */
457 ret = regulator_suspend_prepare(PM_SUSPEND_MEM);
458 if (ret) {
459 pr_err("Failed to prepare regulators for suspend (%d)\n", ret);
460 return ret;
461 }
462
463 s3c_pm_check_prepare();
464
465 return 0;
466}
467
468static void exynos_suspend_finish(void)
469{
470 int ret;
471
472 s3c_pm_check_cleanup();
473
474 ret = regulator_suspend_finish();
475 if (ret)
476 pr_warn("Failed to resume regulators from suspend (%d)\n", ret);
477}
478
479static const struct platform_suspend_ops exynos_suspend_ops = {
480 .enter = exynos_suspend_enter,
481 .prepare = exynos_suspend_prepare,
482 .finish = exynos_suspend_finish,
483 .valid = suspend_valid_only_mem,
484};
485
486static const struct exynos_pm_data exynos4_pm_data = {
487 .wkup_irq = exynos4_wkup_irq,
488 .wake_disable_mask = ((0xFF << 8) | (0x1F << 1)),
489 .release_ret_regs = exynos_release_ret_regs,
490 .pm_suspend = exynos_pm_suspend,
491 .pm_resume = exynos_pm_resume,
492 .pm_prepare = exynos_pm_prepare,
493 .cpu_suspend = exynos_cpu_suspend,
494};
495
496static const struct exynos_pm_data exynos5250_pm_data = {
497 .wkup_irq = exynos5250_wkup_irq,
498 .wake_disable_mask = ((0xFF << 8) | (0x1F << 1)),
499 .release_ret_regs = exynos_release_ret_regs,
500 .extra_save = exynos5_sys_save,
501 .num_extra_save = ARRAY_SIZE(exynos5_sys_save),
502 .pm_suspend = exynos_pm_suspend,
503 .pm_resume = exynos_pm_resume,
504 .pm_prepare = exynos_pm_prepare,
505 .cpu_suspend = exynos_cpu_suspend,
506};
507
508static struct exynos_pm_data exynos5420_pm_data = {
509 .wkup_irq = exynos5250_wkup_irq,
510 .wake_disable_mask = (0x7F << 7) | (0x1F << 1),
511 .release_ret_regs = exynos5420_release_ret_regs,
512 .pm_resume_prepare = exynos5420_prepare_pm_resume,
513 .pm_resume = exynos5420_pm_resume,
514 .pm_suspend = exynos5420_pm_suspend,
515 .pm_prepare = exynos5420_pm_prepare,
516 .cpu_suspend = exynos5420_cpu_suspend,
517};
518
519static struct of_device_id exynos_pmu_of_device_ids[] = {
520 {
521 .compatible = "samsung,exynos4210-pmu",
522 .data = &exynos4_pm_data,
523 }, {
524 .compatible = "samsung,exynos4212-pmu",
525 .data = &exynos4_pm_data,
526 }, {
527 .compatible = "samsung,exynos4412-pmu",
528 .data = &exynos4_pm_data,
529 }, {
530 .compatible = "samsung,exynos5250-pmu",
531 .data = &exynos5250_pm_data,
532 }, {
533 .compatible = "samsung,exynos5420-pmu",
534 .data = &exynos5420_pm_data,
535 },
536 { /*sentinel*/ },
537};
538
539static struct syscore_ops exynos_pm_syscore_ops;
540
541void __init exynos_pm_init(void)
542{
543 const struct of_device_id *match;
544 u32 tmp;
545
546 of_find_matching_node_and_match(NULL, exynos_pmu_of_device_ids, &match);
547 if (!match) {
548 pr_err("Failed to find PMU node\n");
549 return;
550 }
551 pm_data = (struct exynos_pm_data *) match->data;
552
553 /* Platform-specific GIC callback */
554 gic_arch_extn.irq_set_wake = exynos_irq_set_wake;
555
556 /* All wakeup disable */
557 tmp = pmu_raw_readl(S5P_WAKEUP_MASK);
558 tmp |= pm_data->wake_disable_mask;
559 pmu_raw_writel(tmp, S5P_WAKEUP_MASK);
560
561 exynos_pm_syscore_ops.suspend = pm_data->pm_suspend;
562 exynos_pm_syscore_ops.resume = pm_data->pm_resume;
563
564 register_syscore_ops(&exynos_pm_syscore_ops);
565 suspend_set_ops(&exynos_suspend_ops);
566}
diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig
index 11b2957f792b..e8627e04e1e6 100644
--- a/arch/arm/mach-imx/Kconfig
+++ b/arch/arm/mach-imx/Kconfig
@@ -633,12 +633,41 @@ config SOC_VF610
633 bool "Vybrid Family VF610 support" 633 bool "Vybrid Family VF610 support"
634 select ARM_GIC 634 select ARM_GIC
635 select PINCTRL_VF610 635 select PINCTRL_VF610
636 select VF_PIT_TIMER
637 select PL310_ERRATA_769419 if CACHE_L2X0 636 select PL310_ERRATA_769419 if CACHE_L2X0
638 637
639 help 638 help
640 This enable support for Freescale Vybrid VF610 processor. 639 This enable support for Freescale Vybrid VF610 processor.
641 640
641choice
642 prompt "Clocksource for scheduler clock"
643 depends on SOC_VF610
644 default VF_USE_ARM_GLOBAL_TIMER
645
646 config VF_USE_ARM_GLOBAL_TIMER
647 bool "Use ARM Global Timer"
648 select ARM_GLOBAL_TIMER
649 select CLKSRC_ARM_GLOBAL_TIMER_SCHED_CLOCK
650 help
651 Use the ARM Global Timer as clocksource
652
653 config VF_USE_PIT_TIMER
654 bool "Use PIT timer"
655 select VF_PIT_TIMER
656 help
657 Use SoC Periodic Interrupt Timer (PIT) as clocksource
658
659endchoice
660
661config SOC_LS1021A
662 bool "Freescale LS1021A support"
663 select ARM_GIC
664 select HAVE_ARM_ARCH_TIMER
665 select PCI_DOMAINS if PCI
666 select ZONE_DMA if ARM_LPAE
667
668 help
669 This enable support for Freescale LS1021A processor.
670
642endif 671endif
643 672
644source "arch/arm/mach-imx/devices/Kconfig" 673source "arch/arm/mach-imx/devices/Kconfig"
diff --git a/arch/arm/mach-imx/Makefile b/arch/arm/mach-imx/Makefile
index 6e4fcd8339cd..f5ac685a29fc 100644
--- a/arch/arm/mach-imx/Makefile
+++ b/arch/arm/mach-imx/Makefile
@@ -12,7 +12,7 @@ obj-$(CONFIG_SOC_IMX31) += mm-imx3.o cpu-imx31.o clk-imx31.o iomux-imx31.o ehci-
12obj-$(CONFIG_SOC_IMX35) += mm-imx3.o cpu-imx35.o clk-imx35.o ehci-imx35.o pm-imx3.o 12obj-$(CONFIG_SOC_IMX35) += mm-imx3.o cpu-imx35.o clk-imx35.o ehci-imx35.o pm-imx3.o
13 13
14imx5-pm-$(CONFIG_PM) += pm-imx5.o 14imx5-pm-$(CONFIG_PM) += pm-imx5.o
15obj-$(CONFIG_SOC_IMX5) += cpu-imx5.o clk-imx51-imx53.o $(imx5-pm-y) 15obj-$(CONFIG_SOC_IMX5) += cpu-imx5.o clk-imx51-imx53.o clk-cpu.o $(imx5-pm-y)
16 16
17obj-$(CONFIG_COMMON_CLK) += clk-pllv1.o clk-pllv2.o clk-pllv3.o clk-gate2.o \ 17obj-$(CONFIG_COMMON_CLK) += clk-pllv1.o clk-pllv2.o clk-pllv3.o clk-gate2.o \
18 clk-pfd.o clk-busy.o clk.o \ 18 clk-pfd.o clk-busy.o clk.o \
@@ -89,7 +89,7 @@ obj-$(CONFIG_HAVE_IMX_ANATOP) += anatop.o
89obj-$(CONFIG_HAVE_IMX_GPC) += gpc.o 89obj-$(CONFIG_HAVE_IMX_GPC) += gpc.o
90obj-$(CONFIG_HAVE_IMX_MMDC) += mmdc.o 90obj-$(CONFIG_HAVE_IMX_MMDC) += mmdc.o
91obj-$(CONFIG_HAVE_IMX_SRC) += src.o 91obj-$(CONFIG_HAVE_IMX_SRC) += src.o
92ifdef CONFIG_SOC_IMX6 92ifneq ($(CONFIG_SOC_IMX6)$(CONFIG_SOC_LS1021A),)
93AFLAGS_headsmp.o :=-Wa,-march=armv7-a 93AFLAGS_headsmp.o :=-Wa,-march=armv7-a
94obj-$(CONFIG_SMP) += headsmp.o platsmp.o 94obj-$(CONFIG_SMP) += headsmp.o platsmp.o
95obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o 95obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o
@@ -110,4 +110,6 @@ obj-$(CONFIG_SOC_IMX53) += mach-imx53.o
110 110
111obj-$(CONFIG_SOC_VF610) += clk-vf610.o mach-vf610.o 111obj-$(CONFIG_SOC_VF610) += clk-vf610.o mach-vf610.o
112 112
113obj-$(CONFIG_SOC_LS1021A) += mach-ls1021a.o
114
113obj-y += devices/ 115obj-y += devices/
diff --git a/arch/arm/mach-imx/anatop.c b/arch/arm/mach-imx/anatop.c
index 8259a625a920..7f262fe4ba77 100644
--- a/arch/arm/mach-imx/anatop.c
+++ b/arch/arm/mach-imx/anatop.c
@@ -30,8 +30,11 @@
30#define ANADIG_DIGPROG_IMX6SL 0x280 30#define ANADIG_DIGPROG_IMX6SL 0x280
31 31
32#define BM_ANADIG_REG_2P5_ENABLE_WEAK_LINREG 0x40000 32#define BM_ANADIG_REG_2P5_ENABLE_WEAK_LINREG 0x40000
33#define BM_ANADIG_REG_2P5_ENABLE_PULLDOWN 0x8
33#define BM_ANADIG_REG_CORE_FET_ODRIVE 0x20000000 34#define BM_ANADIG_REG_CORE_FET_ODRIVE 0x20000000
34#define BM_ANADIG_ANA_MISC0_STOP_MODE_CONFIG 0x1000 35#define BM_ANADIG_ANA_MISC0_STOP_MODE_CONFIG 0x1000
36/* Below MISC0_DISCON_HIGH_SNVS is only for i.MX6SL */
37#define BM_ANADIG_ANA_MISC0_DISCON_HIGH_SNVS 0x2000
35#define BM_ANADIG_USB_CHRG_DETECT_CHK_CHRG_B 0x80000 38#define BM_ANADIG_USB_CHRG_DETECT_CHK_CHRG_B 0x80000
36#define BM_ANADIG_USB_CHRG_DETECT_EN_B 0x100000 39#define BM_ANADIG_USB_CHRG_DETECT_EN_B 0x100000
37 40
@@ -56,16 +59,43 @@ static void imx_anatop_enable_fet_odrive(bool enable)
56 BM_ANADIG_REG_CORE_FET_ODRIVE); 59 BM_ANADIG_REG_CORE_FET_ODRIVE);
57} 60}
58 61
62static inline void imx_anatop_enable_2p5_pulldown(bool enable)
63{
64 regmap_write(anatop, ANADIG_REG_2P5 + (enable ? REG_SET : REG_CLR),
65 BM_ANADIG_REG_2P5_ENABLE_PULLDOWN);
66}
67
68static inline void imx_anatop_disconnect_high_snvs(bool enable)
69{
70 regmap_write(anatop, ANADIG_ANA_MISC0 + (enable ? REG_SET : REG_CLR),
71 BM_ANADIG_ANA_MISC0_DISCON_HIGH_SNVS);
72}
73
59void imx_anatop_pre_suspend(void) 74void imx_anatop_pre_suspend(void)
60{ 75{
61 imx_anatop_enable_weak2p5(true); 76 if (imx_mmdc_get_ddr_type() == IMX_DDR_TYPE_LPDDR2)
77 imx_anatop_enable_2p5_pulldown(true);
78 else
79 imx_anatop_enable_weak2p5(true);
80
62 imx_anatop_enable_fet_odrive(true); 81 imx_anatop_enable_fet_odrive(true);
82
83 if (cpu_is_imx6sl())
84 imx_anatop_disconnect_high_snvs(true);
63} 85}
64 86
65void imx_anatop_post_resume(void) 87void imx_anatop_post_resume(void)
66{ 88{
89 if (imx_mmdc_get_ddr_type() == IMX_DDR_TYPE_LPDDR2)
90 imx_anatop_enable_2p5_pulldown(false);
91 else
92 imx_anatop_enable_weak2p5(false);
93
67 imx_anatop_enable_fet_odrive(false); 94 imx_anatop_enable_fet_odrive(false);
68 imx_anatop_enable_weak2p5(false); 95
96 if (cpu_is_imx6sl())
97 imx_anatop_disconnect_high_snvs(false);
98
69} 99}
70 100
71static void imx_anatop_usb_chrg_detect_disable(void) 101static void imx_anatop_usb_chrg_detect_disable(void)
diff --git a/arch/arm/mach-imx/clk-cpu.c b/arch/arm/mach-imx/clk-cpu.c
new file mode 100644
index 000000000000..aa1c345e2a19
--- /dev/null
+++ b/arch/arm/mach-imx/clk-cpu.c
@@ -0,0 +1,107 @@
1/*
2 * Copyright (c) 2014 Lucas Stach <l.stach@pengutronix.de>, Pengutronix
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 *
8 * http://www.opensource.org/licenses/gpl-license.html
9 * http://www.gnu.org/copyleft/gpl.html
10 */
11
12#include <linux/clk.h>
13#include <linux/clk-provider.h>
14#include <linux/slab.h>
15
16struct clk_cpu {
17 struct clk_hw hw;
18 struct clk *div;
19 struct clk *mux;
20 struct clk *pll;
21 struct clk *step;
22};
23
24static inline struct clk_cpu *to_clk_cpu(struct clk_hw *hw)
25{
26 return container_of(hw, struct clk_cpu, hw);
27}
28
29static unsigned long clk_cpu_recalc_rate(struct clk_hw *hw,
30 unsigned long parent_rate)
31{
32 struct clk_cpu *cpu = to_clk_cpu(hw);
33
34 return clk_get_rate(cpu->div);
35}
36
37static long clk_cpu_round_rate(struct clk_hw *hw, unsigned long rate,
38 unsigned long *prate)
39{
40 struct clk_cpu *cpu = to_clk_cpu(hw);
41
42 return clk_round_rate(cpu->pll, rate);
43}
44
45static int clk_cpu_set_rate(struct clk_hw *hw, unsigned long rate,
46 unsigned long parent_rate)
47{
48 struct clk_cpu *cpu = to_clk_cpu(hw);
49 int ret;
50
51 /* switch to PLL bypass clock */
52 ret = clk_set_parent(cpu->mux, cpu->step);
53 if (ret)
54 return ret;
55
56 /* reprogram PLL */
57 ret = clk_set_rate(cpu->pll, rate);
58 if (ret) {
59 clk_set_parent(cpu->mux, cpu->pll);
60 return ret;
61 }
62 /* switch back to PLL clock */
63 clk_set_parent(cpu->mux, cpu->pll);
64
65 /* Ensure the divider is what we expect */
66 clk_set_rate(cpu->div, rate);
67
68 return 0;
69}
70
71static const struct clk_ops clk_cpu_ops = {
72 .recalc_rate = clk_cpu_recalc_rate,
73 .round_rate = clk_cpu_round_rate,
74 .set_rate = clk_cpu_set_rate,
75};
76
77struct clk *imx_clk_cpu(const char *name, const char *parent_name,
78 struct clk *div, struct clk *mux, struct clk *pll,
79 struct clk *step)
80{
81 struct clk_cpu *cpu;
82 struct clk *clk;
83 struct clk_init_data init;
84
85 cpu = kzalloc(sizeof(*cpu), GFP_KERNEL);
86 if (!cpu)
87 return ERR_PTR(-ENOMEM);
88
89 cpu->div = div;
90 cpu->mux = mux;
91 cpu->pll = pll;
92 cpu->step = step;
93
94 init.name = name;
95 init.ops = &clk_cpu_ops;
96 init.flags = 0;
97 init.parent_names = &parent_name;
98 init.num_parents = 1;
99
100 cpu->hw.init = &init;
101
102 clk = clk_register(NULL, &cpu->hw);
103 if (IS_ERR(clk))
104 kfree(cpu);
105
106 return clk;
107}
diff --git a/arch/arm/mach-imx/clk-imx51-imx53.c b/arch/arm/mach-imx/clk-imx51-imx53.c
index 72d65214223e..0f7e536147cb 100644
--- a/arch/arm/mach-imx/clk-imx51-imx53.c
+++ b/arch/arm/mach-imx/clk-imx51-imx53.c
@@ -125,6 +125,8 @@ static const char *mx53_spdif_xtal_sel[] = { "osc", "ckih", "ckih2", "pll4_sw",
125static const char *spdif_sel[] = { "pll1_sw", "pll2_sw", "pll3_sw", "spdif_xtal_sel", }; 125static const char *spdif_sel[] = { "pll1_sw", "pll2_sw", "pll3_sw", "spdif_xtal_sel", };
126static const char *spdif0_com_sel[] = { "spdif0_podf", "ssi1_root_gate", }; 126static const char *spdif0_com_sel[] = { "spdif0_podf", "ssi1_root_gate", };
127static const char *mx51_spdif1_com_sel[] = { "spdif1_podf", "ssi2_root_gate", }; 127static const char *mx51_spdif1_com_sel[] = { "spdif1_podf", "ssi2_root_gate", };
128static const char *step_sels[] = { "lp_apm", };
129static const char *cpu_podf_sels[] = { "pll1_sw", "step_sel" };
128 130
129static struct clk *clk[IMX5_CLK_END]; 131static struct clk *clk[IMX5_CLK_END];
130static struct clk_onecell_data clk_data; 132static struct clk_onecell_data clk_data;
@@ -193,7 +195,9 @@ static void __init mx5_clocks_common_init(void __iomem *ccm_base)
193 clk[IMX5_CLK_USB_PHY_PODF] = imx_clk_divider("usb_phy_podf", "usb_phy_pred", MXC_CCM_CDCDR, 0, 3); 195 clk[IMX5_CLK_USB_PHY_PODF] = imx_clk_divider("usb_phy_podf", "usb_phy_pred", MXC_CCM_CDCDR, 0, 3);
194 clk[IMX5_CLK_USB_PHY_SEL] = imx_clk_mux("usb_phy_sel", MXC_CCM_CSCMR1, 26, 1, 196 clk[IMX5_CLK_USB_PHY_SEL] = imx_clk_mux("usb_phy_sel", MXC_CCM_CSCMR1, 26, 1,
195 usb_phy_sel_str, ARRAY_SIZE(usb_phy_sel_str)); 197 usb_phy_sel_str, ARRAY_SIZE(usb_phy_sel_str));
196 clk[IMX5_CLK_CPU_PODF] = imx_clk_divider("cpu_podf", "pll1_sw", MXC_CCM_CACRR, 0, 3); 198 clk[IMX5_CLK_STEP_SEL] = imx_clk_mux("step_sel", MXC_CCM_CCSR, 7, 2, step_sels, ARRAY_SIZE(step_sels));
199 clk[IMX5_CLK_CPU_PODF_SEL] = imx_clk_mux("cpu_podf_sel", MXC_CCM_CCSR, 2, 1, cpu_podf_sels, ARRAY_SIZE(cpu_podf_sels));
200 clk[IMX5_CLK_CPU_PODF] = imx_clk_divider("cpu_podf", "cpu_podf_sel", MXC_CCM_CACRR, 0, 3);
197 clk[IMX5_CLK_DI_PRED] = imx_clk_divider("di_pred", "pll3_sw", MXC_CCM_CDCDR, 6, 3); 201 clk[IMX5_CLK_DI_PRED] = imx_clk_divider("di_pred", "pll3_sw", MXC_CCM_CDCDR, 6, 3);
198 clk[IMX5_CLK_IIM_GATE] = imx_clk_gate2("iim_gate", "ipg", MXC_CCM_CCGR0, 30); 202 clk[IMX5_CLK_IIM_GATE] = imx_clk_gate2("iim_gate", "ipg", MXC_CCM_CCGR0, 30);
199 clk[IMX5_CLK_UART1_IPG_GATE] = imx_clk_gate2("uart1_ipg_gate", "ipg", MXC_CCM_CCGR1, 6); 203 clk[IMX5_CLK_UART1_IPG_GATE] = imx_clk_gate2("uart1_ipg_gate", "ipg", MXC_CCM_CCGR1, 6);
@@ -537,6 +541,11 @@ static void __init mx53_clocks_init(struct device_node *np)
537 clk[IMX5_CLK_CKO2] = imx_clk_gate2("cko2", "cko2_podf", MXC_CCM_CCOSR, 24); 541 clk[IMX5_CLK_CKO2] = imx_clk_gate2("cko2", "cko2_podf", MXC_CCM_CCOSR, 24);
538 clk[IMX5_CLK_SPDIF_XTAL_SEL] = imx_clk_mux("spdif_xtal_sel", MXC_CCM_CSCMR1, 2, 2, 542 clk[IMX5_CLK_SPDIF_XTAL_SEL] = imx_clk_mux("spdif_xtal_sel", MXC_CCM_CSCMR1, 2, 2,
539 mx53_spdif_xtal_sel, ARRAY_SIZE(mx53_spdif_xtal_sel)); 543 mx53_spdif_xtal_sel, ARRAY_SIZE(mx53_spdif_xtal_sel));
544 clk[IMX5_CLK_ARM] = imx_clk_cpu("arm", "cpu_podf",
545 clk[IMX5_CLK_CPU_PODF],
546 clk[IMX5_CLK_CPU_PODF_SEL],
547 clk[IMX5_CLK_PLL1_SW],
548 clk[IMX5_CLK_STEP_SEL]);
540 549
541 imx_check_clocks(clk, ARRAY_SIZE(clk)); 550 imx_check_clocks(clk, ARRAY_SIZE(clk));
542 551
@@ -551,6 +560,9 @@ static void __init mx53_clocks_init(struct device_node *np)
551 /* move can bus clk to 24MHz */ 560 /* move can bus clk to 24MHz */
552 clk_set_parent(clk[IMX5_CLK_CAN_SEL], clk[IMX5_CLK_LP_APM]); 561 clk_set_parent(clk[IMX5_CLK_CAN_SEL], clk[IMX5_CLK_LP_APM]);
553 562
563 /* make sure step clock is running from 24MHz */
564 clk_set_parent(clk[IMX5_CLK_STEP_SEL], clk[IMX5_CLK_LP_APM]);
565
554 clk_prepare_enable(clk[IMX5_CLK_IIM_GATE]); 566 clk_prepare_enable(clk[IMX5_CLK_IIM_GATE]);
555 imx_print_silicon_rev("i.MX53", mx53_revision()); 567 imx_print_silicon_rev("i.MX53", mx53_revision());
556 clk_disable_unprepare(clk[IMX5_CLK_IIM_GATE]); 568 clk_disable_unprepare(clk[IMX5_CLK_IIM_GATE]);
diff --git a/arch/arm/mach-imx/clk-vf610.c b/arch/arm/mach-imx/clk-vf610.c
index 409637254594..5937ddee1a99 100644
--- a/arch/arm/mach-imx/clk-vf610.c
+++ b/arch/arm/mach-imx/clk-vf610.c
@@ -120,6 +120,17 @@ static unsigned int const clks_init_on[] __initconst = {
120 VF610_CLK_DDR_SEL, 120 VF610_CLK_DDR_SEL,
121}; 121};
122 122
123static struct clk * __init vf610_get_fixed_clock(
124 struct device_node *ccm_node, const char *name)
125{
126 struct clk *clk = of_clk_get_by_name(ccm_node, name);
127
128 /* Backward compatibility if device tree is missing clks assignments */
129 if (IS_ERR(clk))
130 clk = imx_obtain_fixed_clock(name, 0);
131 return clk;
132};
133
123static void __init vf610_clocks_init(struct device_node *ccm_node) 134static void __init vf610_clocks_init(struct device_node *ccm_node)
124{ 135{
125 struct device_node *np; 136 struct device_node *np;
@@ -130,13 +141,13 @@ static void __init vf610_clocks_init(struct device_node *ccm_node)
130 clk[VF610_CLK_SIRC_32K] = imx_clk_fixed("sirc_32k", 32000); 141 clk[VF610_CLK_SIRC_32K] = imx_clk_fixed("sirc_32k", 32000);
131 clk[VF610_CLK_FIRC] = imx_clk_fixed("firc", 24000000); 142 clk[VF610_CLK_FIRC] = imx_clk_fixed("firc", 24000000);
132 143
133 clk[VF610_CLK_SXOSC] = imx_obtain_fixed_clock("sxosc", 0); 144 clk[VF610_CLK_SXOSC] = vf610_get_fixed_clock(ccm_node, "sxosc");
134 clk[VF610_CLK_FXOSC] = imx_obtain_fixed_clock("fxosc", 0); 145 clk[VF610_CLK_FXOSC] = vf610_get_fixed_clock(ccm_node, "fxosc");
135 clk[VF610_CLK_AUDIO_EXT] = imx_obtain_fixed_clock("audio_ext", 0); 146 clk[VF610_CLK_AUDIO_EXT] = vf610_get_fixed_clock(ccm_node, "audio_ext");
136 clk[VF610_CLK_ENET_EXT] = imx_obtain_fixed_clock("enet_ext", 0); 147 clk[VF610_CLK_ENET_EXT] = vf610_get_fixed_clock(ccm_node, "enet_ext");
137 148
138 /* Clock source from external clock via LVDs PAD */ 149 /* Clock source from external clock via LVDs PAD */
139 clk[VF610_CLK_ANACLK1] = imx_obtain_fixed_clock("anaclk1", 0); 150 clk[VF610_CLK_ANACLK1] = vf610_get_fixed_clock(ccm_node, "anaclk1");
140 151
141 clk[VF610_CLK_FXOSC_HALF] = imx_clk_fixed_factor("fxosc_half", "fxosc", 1, 2); 152 clk[VF610_CLK_FXOSC_HALF] = imx_clk_fixed_factor("fxosc_half", "fxosc", 1, 2);
142 153
diff --git a/arch/arm/mach-imx/clk.h b/arch/arm/mach-imx/clk.h
index 4cdf8b6a74e8..5ef82e2f8fc5 100644
--- a/arch/arm/mach-imx/clk.h
+++ b/arch/arm/mach-imx/clk.h
@@ -131,4 +131,8 @@ static inline struct clk *imx_clk_fixed_factor(const char *name,
131 CLK_SET_RATE_PARENT, mult, div); 131 CLK_SET_RATE_PARENT, mult, div);
132} 132}
133 133
134struct clk *imx_clk_cpu(const char *name, const char *parent_name,
135 struct clk *div, struct clk *mux, struct clk *pll,
136 struct clk *step);
137
134#endif 138#endif
diff --git a/arch/arm/mach-imx/common.h b/arch/arm/mach-imx/common.h
index 3d383cb5e6d1..cfcdb623d78f 100644
--- a/arch/arm/mach-imx/common.h
+++ b/arch/arm/mach-imx/common.h
@@ -115,6 +115,7 @@ void imx_anatop_post_resume(void);
115int imx6q_set_lpm(enum mxc_cpu_pwr_mode mode); 115int imx6q_set_lpm(enum mxc_cpu_pwr_mode mode);
116void imx6q_set_int_mem_clk_lpm(bool enable); 116void imx6q_set_int_mem_clk_lpm(bool enable);
117void imx6sl_set_wait_clk(bool enter); 117void imx6sl_set_wait_clk(bool enter);
118int imx_mmdc_get_ddr_type(void);
118 119
119void imx_cpu_die(unsigned int cpu); 120void imx_cpu_die(unsigned int cpu);
120int imx_cpu_kill(unsigned int cpu); 121int imx_cpu_kill(unsigned int cpu);
@@ -156,5 +157,6 @@ static inline void imx_init_l2cache(void) {}
156#endif 157#endif
157 158
158extern struct smp_operations imx_smp_ops; 159extern struct smp_operations imx_smp_ops;
160extern struct smp_operations ls1021a_smp_ops;
159 161
160#endif 162#endif
diff --git a/arch/arm/mach-imx/mach-imx53.c b/arch/arm/mach-imx/mach-imx53.c
index 18b5c5c136db..86316a979297 100644
--- a/arch/arm/mach-imx/mach-imx53.c
+++ b/arch/arm/mach-imx/mach-imx53.c
@@ -40,6 +40,8 @@ static void __init imx53_dt_init(void)
40static void __init imx53_init_late(void) 40static void __init imx53_init_late(void)
41{ 41{
42 imx53_pm_init(); 42 imx53_pm_init();
43
44 platform_device_register_simple("cpufreq-dt", -1, NULL, 0);
43} 45}
44 46
45static const char * const imx53_dt_board_compat[] __initconst = { 47static const char * const imx53_dt_board_compat[] __initconst = {
diff --git a/arch/arm/mach-imx/mach-imx6sx.c b/arch/arm/mach-imx/mach-imx6sx.c
index 4111c0fa8d09..7a96c6577234 100644
--- a/arch/arm/mach-imx/mach-imx6sx.c
+++ b/arch/arm/mach-imx/mach-imx6sx.c
@@ -8,12 +8,62 @@
8 8
9#include <linux/irqchip.h> 9#include <linux/irqchip.h>
10#include <linux/of_platform.h> 10#include <linux/of_platform.h>
11#include <linux/phy.h>
12#include <linux/regmap.h>
13#include <linux/mfd/syscon.h>
14#include <linux/mfd/syscon/imx6q-iomuxc-gpr.h>
11#include <asm/mach/arch.h> 15#include <asm/mach/arch.h>
12#include <asm/mach/map.h> 16#include <asm/mach/map.h>
13 17
14#include "common.h" 18#include "common.h"
15#include "cpuidle.h" 19#include "cpuidle.h"
16 20
21static int ar8031_phy_fixup(struct phy_device *dev)
22{
23 u16 val;
24
25 /* Set RGMII IO voltage to 1.8V */
26 phy_write(dev, 0x1d, 0x1f);
27 phy_write(dev, 0x1e, 0x8);
28
29 /* introduce tx clock delay */
30 phy_write(dev, 0x1d, 0x5);
31 val = phy_read(dev, 0x1e);
32 val |= 0x0100;
33 phy_write(dev, 0x1e, val);
34
35 return 0;
36}
37
38#define PHY_ID_AR8031 0x004dd074
39static void __init imx6sx_enet_phy_init(void)
40{
41 if (IS_BUILTIN(CONFIG_PHYLIB))
42 phy_register_fixup_for_uid(PHY_ID_AR8031, 0xffffffff,
43 ar8031_phy_fixup);
44}
45
46static void __init imx6sx_enet_clk_sel(void)
47{
48 struct regmap *gpr;
49
50 gpr = syscon_regmap_lookup_by_compatible("fsl,imx6sx-iomuxc-gpr");
51 if (!IS_ERR(gpr)) {
52 regmap_update_bits(gpr, IOMUXC_GPR1,
53 IMX6SX_GPR1_FEC_CLOCK_MUX_SEL_MASK, 0);
54 regmap_update_bits(gpr, IOMUXC_GPR1,
55 IMX6SX_GPR1_FEC_CLOCK_PAD_DIR_MASK, 0);
56 } else {
57 pr_err("failed to find fsl,imx6sx-iomux-gpr regmap\n");
58 }
59}
60
61static inline void imx6sx_enet_init(void)
62{
63 imx6sx_enet_phy_init();
64 imx6sx_enet_clk_sel();
65}
66
17static void __init imx6sx_init_machine(void) 67static void __init imx6sx_init_machine(void)
18{ 68{
19 struct device *parent; 69 struct device *parent;
@@ -24,6 +74,7 @@ static void __init imx6sx_init_machine(void)
24 74
25 of_platform_populate(NULL, of_default_bus_match_table, NULL, parent); 75 of_platform_populate(NULL, of_default_bus_match_table, NULL, parent);
26 76
77 imx6sx_enet_init();
27 imx_anatop_init(); 78 imx_anatop_init();
28 imx6sx_pm_init(); 79 imx6sx_pm_init();
29} 80}
diff --git a/arch/arm/mach-imx/mach-ls1021a.c b/arch/arm/mach-imx/mach-ls1021a.c
new file mode 100644
index 000000000000..b89c858ebfd6
--- /dev/null
+++ b/arch/arm/mach-imx/mach-ls1021a.c
@@ -0,0 +1,22 @@
1/*
2 * Copyright 2013-2014 Freescale Semiconductor, Inc.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 */
9
10#include <asm/mach/arch.h>
11
12#include "common.h"
13
14static const char * const ls1021a_dt_compat[] __initconst = {
15 "fsl,ls1021a",
16 NULL,
17};
18
19DT_MACHINE_START(LS1021A, "Freescale LS1021A")
20 .smp = smp_ops(ls1021a_smp_ops),
21 .dt_compat = ls1021a_dt_compat,
22MACHINE_END
diff --git a/arch/arm/mach-imx/mmdc.c b/arch/arm/mach-imx/mmdc.c
index 7a9686ad994c..3729d90cfa46 100644
--- a/arch/arm/mach-imx/mmdc.c
+++ b/arch/arm/mach-imx/mmdc.c
@@ -21,6 +21,12 @@
21#define BP_MMDC_MAPSR_PSD 0 21#define BP_MMDC_MAPSR_PSD 0
22#define BP_MMDC_MAPSR_PSS 4 22#define BP_MMDC_MAPSR_PSS 4
23 23
24#define MMDC_MDMISC 0x18
25#define BM_MMDC_MDMISC_DDR_TYPE 0x18
26#define BP_MMDC_MDMISC_DDR_TYPE 0x3
27
28static int ddr_type;
29
24static int imx_mmdc_probe(struct platform_device *pdev) 30static int imx_mmdc_probe(struct platform_device *pdev)
25{ 31{
26 struct device_node *np = pdev->dev.of_node; 32 struct device_node *np = pdev->dev.of_node;
@@ -31,6 +37,12 @@ static int imx_mmdc_probe(struct platform_device *pdev)
31 mmdc_base = of_iomap(np, 0); 37 mmdc_base = of_iomap(np, 0);
32 WARN_ON(!mmdc_base); 38 WARN_ON(!mmdc_base);
33 39
40 reg = mmdc_base + MMDC_MDMISC;
41 /* Get ddr type */
42 val = readl_relaxed(reg);
43 ddr_type = (val & BM_MMDC_MDMISC_DDR_TYPE) >>
44 BP_MMDC_MDMISC_DDR_TYPE;
45
34 reg = mmdc_base + MMDC_MAPSR; 46 reg = mmdc_base + MMDC_MAPSR;
35 47
36 /* Enable automatic power saving */ 48 /* Enable automatic power saving */
@@ -51,6 +63,11 @@ static int imx_mmdc_probe(struct platform_device *pdev)
51 return 0; 63 return 0;
52} 64}
53 65
66int imx_mmdc_get_ddr_type(void)
67{
68 return ddr_type;
69}
70
54static struct of_device_id imx_mmdc_dt_ids[] = { 71static struct of_device_id imx_mmdc_dt_ids[] = {
55 { .compatible = "fsl,imx6q-mmdc", }, 72 { .compatible = "fsl,imx6q-mmdc", },
56 { /* sentinel */ } 73 { /* sentinel */ }
diff --git a/arch/arm/mach-imx/mxc.h b/arch/arm/mach-imx/mxc.h
index 17a41ca65acf..4c1343df2ba4 100644
--- a/arch/arm/mach-imx/mxc.h
+++ b/arch/arm/mach-imx/mxc.h
@@ -55,6 +55,8 @@
55#define IMX_CHIP_REVISION_3_3 0x33 55#define IMX_CHIP_REVISION_3_3 0x33
56#define IMX_CHIP_REVISION_UNKNOWN 0xff 56#define IMX_CHIP_REVISION_UNKNOWN 0xff
57 57
58#define IMX_DDR_TYPE_LPDDR2 1
59
58#ifndef __ASSEMBLY__ 60#ifndef __ASSEMBLY__
59extern unsigned int __mxc_cpu_type; 61extern unsigned int __mxc_cpu_type;
60#endif 62#endif
diff --git a/arch/arm/mach-imx/platsmp.c b/arch/arm/mach-imx/platsmp.c
index 771bd25c1025..7f270015fe58 100644
--- a/arch/arm/mach-imx/platsmp.c
+++ b/arch/arm/mach-imx/platsmp.c
@@ -11,7 +11,10 @@
11 */ 11 */
12 12
13#include <linux/init.h> 13#include <linux/init.h>
14#include <linux/of_address.h>
15#include <linux/of.h>
14#include <linux/smp.h> 16#include <linux/smp.h>
17
15#include <asm/cacheflush.h> 18#include <asm/cacheflush.h>
16#include <asm/page.h> 19#include <asm/page.h>
17#include <asm/smp_scu.h> 20#include <asm/smp_scu.h>
@@ -94,3 +97,33 @@ struct smp_operations imx_smp_ops __initdata = {
94 .cpu_kill = imx_cpu_kill, 97 .cpu_kill = imx_cpu_kill,
95#endif 98#endif
96}; 99};
100
101#define DCFG_CCSR_SCRATCHRW1 0x200
102
103static int ls1021a_boot_secondary(unsigned int cpu, struct task_struct *idle)
104{
105 arch_send_wakeup_ipi_mask(cpumask_of(cpu));
106
107 return 0;
108}
109
110static void __init ls1021a_smp_prepare_cpus(unsigned int max_cpus)
111{
112 struct device_node *np;
113 void __iomem *dcfg_base;
114 unsigned long paddr;
115
116 np = of_find_compatible_node(NULL, NULL, "fsl,ls1021a-dcfg");
117 dcfg_base = of_iomap(np, 0);
118 BUG_ON(!dcfg_base);
119
120 paddr = virt_to_phys(secondary_startup);
121 writel_relaxed(cpu_to_be32(paddr), dcfg_base + DCFG_CCSR_SCRATCHRW1);
122
123 iounmap(dcfg_base);
124}
125
126struct smp_operations ls1021a_smp_ops __initdata = {
127 .smp_prepare_cpus = ls1021a_smp_prepare_cpus,
128 .smp_boot_secondary = ls1021a_boot_secondary,
129};
diff --git a/arch/arm/mach-imx/pm-imx6.c b/arch/arm/mach-imx/pm-imx6.c
index d815d1ba27a5..5d2c1bd5f5ef 100644
--- a/arch/arm/mach-imx/pm-imx6.c
+++ b/arch/arm/mach-imx/pm-imx6.c
@@ -88,7 +88,7 @@ struct imx6_pm_base {
88}; 88};
89 89
90struct imx6_pm_socdata { 90struct imx6_pm_socdata {
91 u32 cpu_type; 91 u32 ddr_type;
92 const char *mmdc_compat; 92 const char *mmdc_compat;
93 const char *src_compat; 93 const char *src_compat;
94 const char *iomuxc_compat; 94 const char *iomuxc_compat;
@@ -138,7 +138,6 @@ static const u32 imx6sx_mmdc_io_offset[] __initconst = {
138}; 138};
139 139
140static const struct imx6_pm_socdata imx6q_pm_data __initconst = { 140static const struct imx6_pm_socdata imx6q_pm_data __initconst = {
141 .cpu_type = MXC_CPU_IMX6Q,
142 .mmdc_compat = "fsl,imx6q-mmdc", 141 .mmdc_compat = "fsl,imx6q-mmdc",
143 .src_compat = "fsl,imx6q-src", 142 .src_compat = "fsl,imx6q-src",
144 .iomuxc_compat = "fsl,imx6q-iomuxc", 143 .iomuxc_compat = "fsl,imx6q-iomuxc",
@@ -148,7 +147,6 @@ static const struct imx6_pm_socdata imx6q_pm_data __initconst = {
148}; 147};
149 148
150static const struct imx6_pm_socdata imx6dl_pm_data __initconst = { 149static const struct imx6_pm_socdata imx6dl_pm_data __initconst = {
151 .cpu_type = MXC_CPU_IMX6DL,
152 .mmdc_compat = "fsl,imx6q-mmdc", 150 .mmdc_compat = "fsl,imx6q-mmdc",
153 .src_compat = "fsl,imx6q-src", 151 .src_compat = "fsl,imx6q-src",
154 .iomuxc_compat = "fsl,imx6dl-iomuxc", 152 .iomuxc_compat = "fsl,imx6dl-iomuxc",
@@ -158,7 +156,6 @@ static const struct imx6_pm_socdata imx6dl_pm_data __initconst = {
158}; 156};
159 157
160static const struct imx6_pm_socdata imx6sl_pm_data __initconst = { 158static const struct imx6_pm_socdata imx6sl_pm_data __initconst = {
161 .cpu_type = MXC_CPU_IMX6SL,
162 .mmdc_compat = "fsl,imx6sl-mmdc", 159 .mmdc_compat = "fsl,imx6sl-mmdc",
163 .src_compat = "fsl,imx6sl-src", 160 .src_compat = "fsl,imx6sl-src",
164 .iomuxc_compat = "fsl,imx6sl-iomuxc", 161 .iomuxc_compat = "fsl,imx6sl-iomuxc",
@@ -168,7 +165,6 @@ static const struct imx6_pm_socdata imx6sl_pm_data __initconst = {
168}; 165};
169 166
170static const struct imx6_pm_socdata imx6sx_pm_data __initconst = { 167static const struct imx6_pm_socdata imx6sx_pm_data __initconst = {
171 .cpu_type = MXC_CPU_IMX6SX,
172 .mmdc_compat = "fsl,imx6sx-mmdc", 168 .mmdc_compat = "fsl,imx6sx-mmdc",
173 .src_compat = "fsl,imx6sx-src", 169 .src_compat = "fsl,imx6sx-src",
174 .iomuxc_compat = "fsl,imx6sx-iomuxc", 170 .iomuxc_compat = "fsl,imx6sx-iomuxc",
@@ -187,7 +183,7 @@ static const struct imx6_pm_socdata imx6sx_pm_data __initconst = {
187struct imx6_cpu_pm_info { 183struct imx6_cpu_pm_info {
188 phys_addr_t pbase; /* The physical address of pm_info. */ 184 phys_addr_t pbase; /* The physical address of pm_info. */
189 phys_addr_t resume_addr; /* The physical resume address for asm code */ 185 phys_addr_t resume_addr; /* The physical resume address for asm code */
190 u32 cpu_type; 186 u32 ddr_type;
191 u32 pm_info_size; /* Size of pm_info. */ 187 u32 pm_info_size; /* Size of pm_info. */
192 struct imx6_pm_base mmdc_base; 188 struct imx6_pm_base mmdc_base;
193 struct imx6_pm_base src_base; 189 struct imx6_pm_base src_base;
@@ -521,7 +517,7 @@ static int __init imx6q_suspend_init(const struct imx6_pm_socdata *socdata)
521 goto pl310_cache_map_failed; 517 goto pl310_cache_map_failed;
522 } 518 }
523 519
524 pm_info->cpu_type = socdata->cpu_type; 520 pm_info->ddr_type = imx_mmdc_get_ddr_type();
525 pm_info->mmdc_io_num = socdata->mmdc_io_num; 521 pm_info->mmdc_io_num = socdata->mmdc_io_num;
526 mmdc_offset_array = socdata->mmdc_io_offset; 522 mmdc_offset_array = socdata->mmdc_io_offset;
527 523
diff --git a/arch/arm/mach-imx/suspend-imx6.S b/arch/arm/mach-imx/suspend-imx6.S
index ca4ea2daf25b..b99987b023fa 100644
--- a/arch/arm/mach-imx/suspend-imx6.S
+++ b/arch/arm/mach-imx/suspend-imx6.S
@@ -45,7 +45,7 @@
45 */ 45 */
46#define PM_INFO_PBASE_OFFSET 0x0 46#define PM_INFO_PBASE_OFFSET 0x0
47#define PM_INFO_RESUME_ADDR_OFFSET 0x4 47#define PM_INFO_RESUME_ADDR_OFFSET 0x4
48#define PM_INFO_CPU_TYPE_OFFSET 0x8 48#define PM_INFO_DDR_TYPE_OFFSET 0x8
49#define PM_INFO_PM_INFO_SIZE_OFFSET 0xC 49#define PM_INFO_PM_INFO_SIZE_OFFSET 0xC
50#define PM_INFO_MX6Q_MMDC_P_OFFSET 0x10 50#define PM_INFO_MX6Q_MMDC_P_OFFSET 0x10
51#define PM_INFO_MX6Q_MMDC_V_OFFSET 0x14 51#define PM_INFO_MX6Q_MMDC_V_OFFSET 0x14
@@ -110,7 +110,7 @@
110 ldreq r11, [r0, #PM_INFO_MX6Q_MMDC_V_OFFSET] 110 ldreq r11, [r0, #PM_INFO_MX6Q_MMDC_V_OFFSET]
111 ldrne r11, [r0, #PM_INFO_MX6Q_MMDC_P_OFFSET] 111 ldrne r11, [r0, #PM_INFO_MX6Q_MMDC_P_OFFSET]
112 112
113 cmp r3, #MXC_CPU_IMX6SL 113 cmp r3, #IMX_DDR_TYPE_LPDDR2
114 bne 4f 114 bne 4f
115 115
116 /* reset read FIFO, RST_RD_FIFO */ 116 /* reset read FIFO, RST_RD_FIFO */
@@ -151,7 +151,7 @@
151ENTRY(imx6_suspend) 151ENTRY(imx6_suspend)
152 ldr r1, [r0, #PM_INFO_PBASE_OFFSET] 152 ldr r1, [r0, #PM_INFO_PBASE_OFFSET]
153 ldr r2, [r0, #PM_INFO_RESUME_ADDR_OFFSET] 153 ldr r2, [r0, #PM_INFO_RESUME_ADDR_OFFSET]
154 ldr r3, [r0, #PM_INFO_CPU_TYPE_OFFSET] 154 ldr r3, [r0, #PM_INFO_DDR_TYPE_OFFSET]
155 ldr r4, [r0, #PM_INFO_PM_INFO_SIZE_OFFSET] 155 ldr r4, [r0, #PM_INFO_PM_INFO_SIZE_OFFSET]
156 156
157 /* 157 /*
@@ -209,8 +209,8 @@ poll_dvfs_set:
209 ldr r7, [r0, #PM_INFO_MMDC_IO_NUM_OFFSET] 209 ldr r7, [r0, #PM_INFO_MMDC_IO_NUM_OFFSET]
210 ldr r8, =PM_INFO_MMDC_IO_VAL_OFFSET 210 ldr r8, =PM_INFO_MMDC_IO_VAL_OFFSET
211 add r8, r8, r0 211 add r8, r8, r0
212 /* i.MX6SL's last 3 IOs need special setting */ 212 /* LPDDR2's last 3 IOs need special setting */
213 cmp r3, #MXC_CPU_IMX6SL 213 cmp r3, #IMX_DDR_TYPE_LPDDR2
214 subeq r7, r7, #0x3 214 subeq r7, r7, #0x3
215set_mmdc_io_lpm: 215set_mmdc_io_lpm:
216 ldr r9, [r8], #0x8 216 ldr r9, [r8], #0x8
@@ -218,7 +218,7 @@ set_mmdc_io_lpm:
218 subs r7, r7, #0x1 218 subs r7, r7, #0x1
219 bne set_mmdc_io_lpm 219 bne set_mmdc_io_lpm
220 220
221 cmp r3, #MXC_CPU_IMX6SL 221 cmp r3, #IMX_DDR_TYPE_LPDDR2
222 bne set_mmdc_io_lpm_done 222 bne set_mmdc_io_lpm_done
223 ldr r6, =0x1000 223 ldr r6, =0x1000
224 ldr r9, [r8], #0x8 224 ldr r9, [r8], #0x8
@@ -324,7 +324,7 @@ resume:
324 str r7, [r11, #MX6Q_SRC_GPR1] 324 str r7, [r11, #MX6Q_SRC_GPR1]
325 str r7, [r11, #MX6Q_SRC_GPR2] 325 str r7, [r11, #MX6Q_SRC_GPR2]
326 326
327 ldr r3, [r0, #PM_INFO_CPU_TYPE_OFFSET] 327 ldr r3, [r0, #PM_INFO_DDR_TYPE_OFFSET]
328 mov r5, #0x1 328 mov r5, #0x1
329 resume_mmdc 329 resume_mmdc
330 330
diff --git a/arch/arm/mach-integrator/Kconfig b/arch/arm/mach-integrator/Kconfig
index c455e974bbfe..02d083489a26 100644
--- a/arch/arm/mach-integrator/Kconfig
+++ b/arch/arm/mach-integrator/Kconfig
@@ -1,3 +1,26 @@
1config ARCH_INTEGRATOR
2 bool "ARM Ltd. Integrator family" if (ARCH_MULTI_V4T || ARCH_MULTI_V5 || ARCH_MULTI_V6)
3 select ARM_AMBA
4 select ARM_PATCH_PHYS_VIRT if MMU
5 select AUTO_ZRELADDR
6 select COMMON_CLK
7 select COMMON_CLK_VERSATILE
8 select GENERIC_CLOCKEVENTS
9 select HAVE_TCM
10 select ICST
11 select MFD_SYSCON
12 select MULTI_IRQ_HANDLER
13 select PLAT_VERSATILE
14 select POWER_RESET
15 select POWER_RESET_VERSATILE
16 select POWER_SUPPLY
17 select SOC_INTEGRATOR_CM
18 select SPARSE_IRQ
19 select USE_OF
20 select VERSATILE_FPGA_IRQ
21 help
22 Support for ARM's Integrator platform.
23
1if ARCH_INTEGRATOR 24if ARCH_INTEGRATOR
2 25
3menu "Integrator Options" 26menu "Integrator Options"
diff --git a/arch/arm/mach-integrator/Makefile b/arch/arm/mach-integrator/Makefile
index ec759ded7b60..1ebe45356b09 100644
--- a/arch/arm/mach-integrator/Makefile
+++ b/arch/arm/mach-integrator/Makefile
@@ -4,7 +4,7 @@
4 4
5# Object file lists. 5# Object file lists.
6 6
7obj-y := core.o lm.o leds.o 7obj-y := core.o lm.o
8obj-$(CONFIG_ARCH_INTEGRATOR_AP) += integrator_ap.o 8obj-$(CONFIG_ARCH_INTEGRATOR_AP) += integrator_ap.o
9obj-$(CONFIG_ARCH_INTEGRATOR_CP) += integrator_cp.o 9obj-$(CONFIG_ARCH_INTEGRATOR_CP) += integrator_cp.o
10 10
diff --git a/arch/arm/mach-integrator/cm.h b/arch/arm/mach-integrator/cm.h
index 4ecff7bff482..5b8ba8247f45 100644
--- a/arch/arm/mach-integrator/cm.h
+++ b/arch/arm/mach-integrator/cm.h
@@ -11,7 +11,6 @@ void cm_clear_irqs(void);
11#define CM_CTRL_LED (1 << 0) 11#define CM_CTRL_LED (1 << 0)
12#define CM_CTRL_nMBDET (1 << 1) 12#define CM_CTRL_nMBDET (1 << 1)
13#define CM_CTRL_REMAP (1 << 2) 13#define CM_CTRL_REMAP (1 << 2)
14#define CM_CTRL_RESET (1 << 3)
15 14
16/* 15/*
17 * Integrator/AP,PP2 specific 16 * Integrator/AP,PP2 specific
diff --git a/arch/arm/mach-integrator/common.h b/arch/arm/mach-integrator/common.h
index ad0ac5547b2c..96c9dc56cabf 100644
--- a/arch/arm/mach-integrator/common.h
+++ b/arch/arm/mach-integrator/common.h
@@ -4,5 +4,3 @@ extern struct amba_pl010_data ap_uart_data;
4void integrator_init_early(void); 4void integrator_init_early(void);
5int integrator_init(bool is_cp); 5int integrator_init(bool is_cp);
6void integrator_reserve(void); 6void integrator_reserve(void);
7void integrator_restart(enum reboot_mode, const char *);
8void integrator_init_sysfs(struct device *parent, u32 id);
diff --git a/arch/arm/mach-integrator/core.c b/arch/arm/mach-integrator/core.c
index e3f3aca43efb..948872a419c1 100644
--- a/arch/arm/mach-integrator/core.c
+++ b/arch/arm/mach-integrator/core.c
@@ -60,40 +60,6 @@ void cm_control(u32 mask, u32 set)
60 raw_spin_unlock_irqrestore(&cm_lock, flags); 60 raw_spin_unlock_irqrestore(&cm_lock, flags);
61} 61}
62 62
63static const char *integrator_arch_str(u32 id)
64{
65 switch ((id >> 16) & 0xff) {
66 case 0x00:
67 return "ASB little-endian";
68 case 0x01:
69 return "AHB little-endian";
70 case 0x03:
71 return "AHB-Lite system bus, bi-endian";
72 case 0x04:
73 return "AHB";
74 case 0x08:
75 return "AHB system bus, ASB processor bus";
76 default:
77 return "Unknown";
78 }
79}
80
81static const char *integrator_fpga_str(u32 id)
82{
83 switch ((id >> 12) & 0xf) {
84 case 0x01:
85 return "XC4062";
86 case 0x02:
87 return "XC4085";
88 case 0x03:
89 return "XVC600";
90 case 0x04:
91 return "EPM7256AE (Altera PLD)";
92 default:
93 return "Unknown";
94 }
95}
96
97void cm_clear_irqs(void) 63void cm_clear_irqs(void)
98{ 64{
99 /* disable core module IRQs */ 65 /* disable core module IRQs */
@@ -109,7 +75,6 @@ static const struct of_device_id cm_match[] = {
109void cm_init(void) 75void cm_init(void)
110{ 76{
111 struct device_node *cm = of_find_matching_node(NULL, cm_match); 77 struct device_node *cm = of_find_matching_node(NULL, cm_match);
112 u32 val;
113 78
114 if (!cm) { 79 if (!cm) {
115 pr_crit("no core module node found in device tree\n"); 80 pr_crit("no core module node found in device tree\n");
@@ -121,13 +86,6 @@ void cm_init(void)
121 return; 86 return;
122 } 87 }
123 cm_clear_irqs(); 88 cm_clear_irqs();
124 val = readl(cm_base + INTEGRATOR_HDR_ID_OFFSET);
125 pr_info("Detected ARM core module:\n");
126 pr_info(" Manufacturer: %02x\n", (val >> 24));
127 pr_info(" Architecture: %s\n", integrator_arch_str(val));
128 pr_info(" FPGA: %s\n", integrator_fpga_str(val));
129 pr_info(" Build: %02x\n", (val >> 4) & 0xFF);
130 pr_info(" Rev: %c\n", ('A' + (val & 0x03)));
131} 89}
132 90
133/* 91/*
@@ -139,64 +97,3 @@ void __init integrator_reserve(void)
139{ 97{
140 memblock_reserve(PHYS_OFFSET, __pa(swapper_pg_dir) - PHYS_OFFSET); 98 memblock_reserve(PHYS_OFFSET, __pa(swapper_pg_dir) - PHYS_OFFSET);
141} 99}
142
143/*
144 * To reset, we hit the on-board reset register in the system FPGA
145 */
146void integrator_restart(enum reboot_mode mode, const char *cmd)
147{
148 cm_control(CM_CTRL_RESET, CM_CTRL_RESET);
149}
150
151static u32 integrator_id;
152
153static ssize_t intcp_get_manf(struct device *dev,
154 struct device_attribute *attr,
155 char *buf)
156{
157 return sprintf(buf, "%02x\n", integrator_id >> 24);
158}
159
160static struct device_attribute intcp_manf_attr =
161 __ATTR(manufacturer, S_IRUGO, intcp_get_manf, NULL);
162
163static ssize_t intcp_get_arch(struct device *dev,
164 struct device_attribute *attr,
165 char *buf)
166{
167 return sprintf(buf, "%s\n", integrator_arch_str(integrator_id));
168}
169
170static struct device_attribute intcp_arch_attr =
171 __ATTR(architecture, S_IRUGO, intcp_get_arch, NULL);
172
173static ssize_t intcp_get_fpga(struct device *dev,
174 struct device_attribute *attr,
175 char *buf)
176{
177 return sprintf(buf, "%s\n", integrator_fpga_str(integrator_id));
178}
179
180static struct device_attribute intcp_fpga_attr =
181 __ATTR(fpga, S_IRUGO, intcp_get_fpga, NULL);
182
183static ssize_t intcp_get_build(struct device *dev,
184 struct device_attribute *attr,
185 char *buf)
186{
187 return sprintf(buf, "%02x\n", (integrator_id >> 4) & 0xFF);
188}
189
190static struct device_attribute intcp_build_attr =
191 __ATTR(build, S_IRUGO, intcp_get_build, NULL);
192
193
194
195void integrator_init_sysfs(struct device *parent, u32 id)
196{
197 integrator_id = id;
198 device_create_file(parent, &intcp_manf_attr);
199 device_create_file(parent, &intcp_arch_attr);
200 device_create_file(parent, &intcp_fpga_attr);
201 device_create_file(parent, &intcp_build_attr);
202}
diff --git a/arch/arm/mach-integrator/include/mach/uncompress.h b/arch/arm/mach-integrator/include/mach/uncompress.h
deleted file mode 100644
index 8f3cc9954c16..000000000000
--- a/arch/arm/mach-integrator/include/mach/uncompress.h
+++ /dev/null
@@ -1,48 +0,0 @@
1/*
2 * arch/arm/mach-integrator/include/mach/uncompress.h
3 *
4 * Copyright (C) 1999 ARM Limited
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20
21#define AMBA_UART_DR (*(volatile unsigned char *)0x16000000)
22#define AMBA_UART_LCRH (*(volatile unsigned char *)0x16000008)
23#define AMBA_UART_LCRM (*(volatile unsigned char *)0x1600000c)
24#define AMBA_UART_LCRL (*(volatile unsigned char *)0x16000010)
25#define AMBA_UART_CR (*(volatile unsigned char *)0x16000014)
26#define AMBA_UART_FR (*(volatile unsigned char *)0x16000018)
27
28/*
29 * This does not append a newline
30 */
31static void putc(int c)
32{
33 while (AMBA_UART_FR & (1 << 5))
34 barrier();
35
36 AMBA_UART_DR = c;
37}
38
39static inline void flush(void)
40{
41 while (AMBA_UART_FR & (1 << 3))
42 barrier();
43}
44
45/*
46 * nothing to do
47 */
48#define arch_decomp_setup()
diff --git a/arch/arm/mach-integrator/integrator_ap.c b/arch/arm/mach-integrator/integrator_ap.c
index 8ca290b479b1..30003ba447a5 100644
--- a/arch/arm/mach-integrator/integrator_ap.c
+++ b/arch/arm/mach-integrator/integrator_ap.c
@@ -27,22 +27,15 @@
27#include <linux/syscore_ops.h> 27#include <linux/syscore_ops.h>
28#include <linux/amba/bus.h> 28#include <linux/amba/bus.h>
29#include <linux/amba/kmi.h> 29#include <linux/amba/kmi.h>
30#include <linux/clocksource.h>
31#include <linux/clockchips.h>
32#include <linux/interrupt.h>
33#include <linux/io.h> 30#include <linux/io.h>
34#include <linux/irqchip.h> 31#include <linux/irqchip.h>
35#include <linux/mtd/physmap.h> 32#include <linux/mtd/physmap.h>
36#include <linux/clk.h>
37#include <linux/platform_data/clk-integrator.h> 33#include <linux/platform_data/clk-integrator.h>
38#include <linux/of_irq.h> 34#include <linux/of_irq.h>
39#include <linux/of_address.h> 35#include <linux/of_address.h>
40#include <linux/of_platform.h> 36#include <linux/of_platform.h>
41#include <linux/stat.h> 37#include <linux/stat.h>
42#include <linux/sys_soc.h>
43#include <linux/termios.h> 38#include <linux/termios.h>
44#include <linux/sched_clock.h>
45#include <linux/clk-provider.h>
46 39
47#include <asm/hardware/arm_timer.h> 40#include <asm/hardware/arm_timer.h>
48#include <asm/setup.h> 41#include <asm/setup.h>
@@ -89,11 +82,6 @@ static void __iomem *ebi_base;
89 82
90static struct map_desc ap_io_desc[] __initdata __maybe_unused = { 83static struct map_desc ap_io_desc[] __initdata __maybe_unused = {
91 { 84 {
92 .virtual = IO_ADDRESS(INTEGRATOR_CT_BASE),
93 .pfn = __phys_to_pfn(INTEGRATOR_CT_BASE),
94 .length = SZ_4K,
95 .type = MT_DEVICE
96 }, {
97 .virtual = IO_ADDRESS(INTEGRATOR_IC_BASE), 85 .virtual = IO_ADDRESS(INTEGRATOR_IC_BASE),
98 .pfn = __phys_to_pfn(INTEGRATOR_IC_BASE), 86 .pfn = __phys_to_pfn(INTEGRATOR_IC_BASE),
99 .length = SZ_4K, 87 .length = SZ_4K,
@@ -257,188 +245,10 @@ struct amba_pl010_data ap_uart_data = {
257 .set_mctrl = integrator_uart_set_mctrl, 245 .set_mctrl = integrator_uart_set_mctrl,
258}; 246};
259 247
260/*
261 * Where is the timer (VA)?
262 */
263#define TIMER0_VA_BASE __io_address(INTEGRATOR_TIMER0_BASE)
264#define TIMER1_VA_BASE __io_address(INTEGRATOR_TIMER1_BASE)
265#define TIMER2_VA_BASE __io_address(INTEGRATOR_TIMER2_BASE)
266
267static unsigned long timer_reload;
268
269static u64 notrace integrator_read_sched_clock(void)
270{
271 return -readl((void __iomem *) TIMER2_VA_BASE + TIMER_VALUE);
272}
273
274static void integrator_clocksource_init(unsigned long inrate,
275 void __iomem *base)
276{
277 u32 ctrl = TIMER_CTRL_ENABLE | TIMER_CTRL_PERIODIC;
278 unsigned long rate = inrate;
279
280 if (rate >= 1500000) {
281 rate /= 16;
282 ctrl |= TIMER_CTRL_DIV16;
283 }
284
285 writel(0xffff, base + TIMER_LOAD);
286 writel(ctrl, base + TIMER_CTRL);
287
288 clocksource_mmio_init(base + TIMER_VALUE, "timer2",
289 rate, 200, 16, clocksource_mmio_readl_down);
290 sched_clock_register(integrator_read_sched_clock, 16, rate);
291}
292
293static void __iomem * clkevt_base;
294
295/*
296 * IRQ handler for the timer
297 */
298static irqreturn_t integrator_timer_interrupt(int irq, void *dev_id)
299{
300 struct clock_event_device *evt = dev_id;
301
302 /* clear the interrupt */
303 writel(1, clkevt_base + TIMER_INTCLR);
304
305 evt->event_handler(evt);
306
307 return IRQ_HANDLED;
308}
309
310static void clkevt_set_mode(enum clock_event_mode mode, struct clock_event_device *evt)
311{
312 u32 ctrl = readl(clkevt_base + TIMER_CTRL) & ~TIMER_CTRL_ENABLE;
313
314 /* Disable timer */
315 writel(ctrl, clkevt_base + TIMER_CTRL);
316
317 switch (mode) {
318 case CLOCK_EVT_MODE_PERIODIC:
319 /* Enable the timer and start the periodic tick */
320 writel(timer_reload, clkevt_base + TIMER_LOAD);
321 ctrl |= TIMER_CTRL_PERIODIC | TIMER_CTRL_ENABLE;
322 writel(ctrl, clkevt_base + TIMER_CTRL);
323 break;
324 case CLOCK_EVT_MODE_ONESHOT:
325 /* Leave the timer disabled, .set_next_event will enable it */
326 ctrl &= ~TIMER_CTRL_PERIODIC;
327 writel(ctrl, clkevt_base + TIMER_CTRL);
328 break;
329 case CLOCK_EVT_MODE_UNUSED:
330 case CLOCK_EVT_MODE_SHUTDOWN:
331 case CLOCK_EVT_MODE_RESUME:
332 default:
333 /* Just leave in disabled state */
334 break;
335 }
336
337}
338
339static int clkevt_set_next_event(unsigned long next, struct clock_event_device *evt)
340{
341 unsigned long ctrl = readl(clkevt_base + TIMER_CTRL);
342
343 writel(ctrl & ~TIMER_CTRL_ENABLE, clkevt_base + TIMER_CTRL);
344 writel(next, clkevt_base + TIMER_LOAD);
345 writel(ctrl | TIMER_CTRL_ENABLE, clkevt_base + TIMER_CTRL);
346
347 return 0;
348}
349
350static struct clock_event_device integrator_clockevent = {
351 .name = "timer1",
352 .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
353 .set_mode = clkevt_set_mode,
354 .set_next_event = clkevt_set_next_event,
355 .rating = 300,
356};
357
358static struct irqaction integrator_timer_irq = {
359 .name = "timer",
360 .flags = IRQF_TIMER | IRQF_IRQPOLL,
361 .handler = integrator_timer_interrupt,
362 .dev_id = &integrator_clockevent,
363};
364
365static void integrator_clockevent_init(unsigned long inrate,
366 void __iomem *base, int irq)
367{
368 unsigned long rate = inrate;
369 unsigned int ctrl = 0;
370
371 clkevt_base = base;
372 /* Calculate and program a divisor */
373 if (rate > 0x100000 * HZ) {
374 rate /= 256;
375 ctrl |= TIMER_CTRL_DIV256;
376 } else if (rate > 0x10000 * HZ) {
377 rate /= 16;
378 ctrl |= TIMER_CTRL_DIV16;
379 }
380 timer_reload = rate / HZ;
381 writel(ctrl, clkevt_base + TIMER_CTRL);
382
383 setup_irq(irq, &integrator_timer_irq);
384 clockevents_config_and_register(&integrator_clockevent,
385 rate,
386 1,
387 0xffffU);
388}
389
390void __init ap_init_early(void) 248void __init ap_init_early(void)
391{ 249{
392} 250}
393 251
394static void __init ap_of_timer_init(void)
395{
396 struct device_node *node;
397 const char *path;
398 void __iomem *base;
399 int err;
400 int irq;
401 struct clk *clk;
402 unsigned long rate;
403
404 of_clk_init(NULL);
405
406 err = of_property_read_string(of_aliases,
407 "arm,timer-primary", &path);
408 if (WARN_ON(err))
409 return;
410 node = of_find_node_by_path(path);
411 base = of_iomap(node, 0);
412 if (WARN_ON(!base))
413 return;
414
415 clk = of_clk_get(node, 0);
416 BUG_ON(IS_ERR(clk));
417 clk_prepare_enable(clk);
418 rate = clk_get_rate(clk);
419
420 writel(0, base + TIMER_CTRL);
421 integrator_clocksource_init(rate, base);
422
423 err = of_property_read_string(of_aliases,
424 "arm,timer-secondary", &path);
425 if (WARN_ON(err))
426 return;
427 node = of_find_node_by_path(path);
428 base = of_iomap(node, 0);
429 if (WARN_ON(!base))
430 return;
431 irq = irq_of_parse_and_map(node, 0);
432
433 clk = of_clk_get(node, 0);
434 BUG_ON(IS_ERR(clk));
435 clk_prepare_enable(clk);
436 rate = clk_get_rate(clk);
437
438 writel(0, base + TIMER_CTRL);
439 integrator_clockevent_init(rate, base, irq);
440}
441
442static void __init ap_init_irq_of(void) 252static void __init ap_init_irq_of(void)
443{ 253{
444 cm_init(); 254 cm_init();
@@ -477,10 +287,6 @@ static void __init ap_init_of(void)
477 unsigned long sc_dec; 287 unsigned long sc_dec;
478 struct device_node *syscon; 288 struct device_node *syscon;
479 struct device_node *ebi; 289 struct device_node *ebi;
480 struct device *parent;
481 struct soc_device *soc_dev;
482 struct soc_device_attribute *soc_dev_attr;
483 u32 ap_sc_id;
484 int i; 290 int i;
485 291
486 syscon = of_find_matching_node(NULL, ap_syscon_match); 292 syscon = of_find_matching_node(NULL, ap_syscon_match);
@@ -500,28 +306,6 @@ static void __init ap_init_of(void)
500 of_platform_populate(NULL, of_default_bus_match_table, 306 of_platform_populate(NULL, of_default_bus_match_table,
501 ap_auxdata_lookup, NULL); 307 ap_auxdata_lookup, NULL);
502 308
503 ap_sc_id = readl(ap_syscon_base);
504
505 soc_dev_attr = kzalloc(sizeof(*soc_dev_attr), GFP_KERNEL);
506 if (!soc_dev_attr)
507 return;
508
509 soc_dev_attr->soc_id = "XVC";
510 soc_dev_attr->machine = "Integrator/AP";
511 soc_dev_attr->family = "Integrator";
512 soc_dev_attr->revision = kasprintf(GFP_KERNEL, "%c",
513 'A' + (ap_sc_id & 0x0f));
514
515 soc_dev = soc_device_register(soc_dev_attr);
516 if (IS_ERR(soc_dev)) {
517 kfree(soc_dev_attr->revision);
518 kfree(soc_dev_attr);
519 return;
520 }
521
522 parent = soc_device_to_device(soc_dev);
523 integrator_init_sysfs(parent, ap_sc_id);
524
525 sc_dec = readl(ap_syscon_base + INTEGRATOR_SC_DEC_OFFSET); 309 sc_dec = readl(ap_syscon_base + INTEGRATOR_SC_DEC_OFFSET);
526 for (i = 0; i < 4; i++) { 310 for (i = 0; i < 4; i++) {
527 struct lm_device *lmdev; 311 struct lm_device *lmdev;
@@ -553,8 +337,6 @@ DT_MACHINE_START(INTEGRATOR_AP_DT, "ARM Integrator/AP (Device Tree)")
553 .map_io = ap_map_io, 337 .map_io = ap_map_io,
554 .init_early = ap_init_early, 338 .init_early = ap_init_early,
555 .init_irq = ap_init_irq_of, 339 .init_irq = ap_init_irq_of,
556 .init_time = ap_of_timer_init,
557 .init_machine = ap_init_of, 340 .init_machine = ap_init_of,
558 .restart = integrator_restart,
559 .dt_compat = ap_dt_board_compat, 341 .dt_compat = ap_dt_board_compat,
560MACHINE_END 342MACHINE_END
diff --git a/arch/arm/mach-integrator/integrator_cp.c b/arch/arm/mach-integrator/integrator_cp.c
index cca02eb75eb5..b5fb71a36ee6 100644
--- a/arch/arm/mach-integrator/integrator_cp.c
+++ b/arch/arm/mach-integrator/integrator_cp.c
@@ -27,7 +27,6 @@
27#include <linux/of_irq.h> 27#include <linux/of_irq.h>
28#include <linux/of_address.h> 28#include <linux/of_address.h>
29#include <linux/of_platform.h> 29#include <linux/of_platform.h>
30#include <linux/sys_soc.h>
31#include <linux/sched_clock.h> 30#include <linux/sched_clock.h>
32 31
33#include <asm/setup.h> 32#include <asm/setup.h>
@@ -274,10 +273,6 @@ static const struct of_device_id intcp_syscon_match[] = {
274static void __init intcp_init_of(void) 273static void __init intcp_init_of(void)
275{ 274{
276 struct device_node *cpcon; 275 struct device_node *cpcon;
277 struct device *parent;
278 struct soc_device *soc_dev;
279 struct soc_device_attribute *soc_dev_attr;
280 u32 intcp_sc_id;
281 276
282 cpcon = of_find_matching_node(NULL, intcp_syscon_match); 277 cpcon = of_find_matching_node(NULL, intcp_syscon_match);
283 if (!cpcon) 278 if (!cpcon)
@@ -289,28 +284,6 @@ static void __init intcp_init_of(void)
289 284
290 of_platform_populate(NULL, of_default_bus_match_table, 285 of_platform_populate(NULL, of_default_bus_match_table,
291 intcp_auxdata_lookup, NULL); 286 intcp_auxdata_lookup, NULL);
292
293 intcp_sc_id = readl(intcp_con_base);
294
295 soc_dev_attr = kzalloc(sizeof(*soc_dev_attr), GFP_KERNEL);
296 if (!soc_dev_attr)
297 return;
298
299 soc_dev_attr->soc_id = "XCV";
300 soc_dev_attr->machine = "Integrator/CP";
301 soc_dev_attr->family = "Integrator";
302 soc_dev_attr->revision = kasprintf(GFP_KERNEL, "%c",
303 'A' + (intcp_sc_id & 0x0f));
304
305 soc_dev = soc_device_register(soc_dev_attr);
306 if (IS_ERR(soc_dev)) {
307 kfree(soc_dev_attr->revision);
308 kfree(soc_dev_attr);
309 return;
310 }
311
312 parent = soc_device_to_device(soc_dev);
313 integrator_init_sysfs(parent, intcp_sc_id);
314} 287}
315 288
316static const char * intcp_dt_board_compat[] = { 289static const char * intcp_dt_board_compat[] = {
@@ -324,6 +297,5 @@ DT_MACHINE_START(INTEGRATOR_CP_DT, "ARM Integrator/CP (Device Tree)")
324 .init_early = intcp_init_early, 297 .init_early = intcp_init_early,
325 .init_irq = intcp_init_irq_of, 298 .init_irq = intcp_init_irq_of,
326 .init_machine = intcp_init_of, 299 .init_machine = intcp_init_of,
327 .restart = integrator_restart,
328 .dt_compat = intcp_dt_board_compat, 300 .dt_compat = intcp_dt_board_compat,
329MACHINE_END 301MACHINE_END
diff --git a/arch/arm/mach-integrator/leds.c b/arch/arm/mach-integrator/leds.c
deleted file mode 100644
index f1dcb57a59e2..000000000000
--- a/arch/arm/mach-integrator/leds.c
+++ /dev/null
@@ -1,124 +0,0 @@
1/*
2 * Driver for the 4 user LEDs found on the Integrator AP/CP baseboard
3 * Based on Versatile and RealView machine LED code
4 *
5 * License terms: GNU General Public License (GPL) version 2
6 * Author: Bryan Wu <bryan.wu@canonical.com>
7 */
8#include <linux/kernel.h>
9#include <linux/init.h>
10#include <linux/io.h>
11#include <linux/slab.h>
12#include <linux/leds.h>
13
14#include "hardware.h"
15#include "cm.h"
16
17#if defined(CONFIG_NEW_LEDS) && defined(CONFIG_LEDS_CLASS)
18
19#define ALPHA_REG __io_address(INTEGRATOR_DBG_BASE)
20#define LEDREG (__io_address(INTEGRATOR_DBG_BASE) + INTEGRATOR_DBG_LEDS_OFFSET)
21
22struct integrator_led {
23 struct led_classdev cdev;
24 u8 mask;
25};
26
27/*
28 * The triggers lines up below will only be used if the
29 * LED triggers are compiled in.
30 */
31static const struct {
32 const char *name;
33 const char *trigger;
34} integrator_leds[] = {
35 { "integrator:green0", "heartbeat", },
36 { "integrator:yellow", },
37 { "integrator:red", },
38 { "integrator:green1", },
39 { "integrator:core_module", "cpu0", },
40};
41
42static void integrator_led_set(struct led_classdev *cdev,
43 enum led_brightness b)
44{
45 struct integrator_led *led = container_of(cdev,
46 struct integrator_led, cdev);
47 u32 reg = __raw_readl(LEDREG);
48
49 if (b != LED_OFF)
50 reg |= led->mask;
51 else
52 reg &= ~led->mask;
53
54 while (__raw_readl(ALPHA_REG) & 1)
55 cpu_relax();
56
57 __raw_writel(reg, LEDREG);
58}
59
60static enum led_brightness integrator_led_get(struct led_classdev *cdev)
61{
62 struct integrator_led *led = container_of(cdev,
63 struct integrator_led, cdev);
64 u32 reg = __raw_readl(LEDREG);
65
66 return (reg & led->mask) ? LED_FULL : LED_OFF;
67}
68
69static void cm_led_set(struct led_classdev *cdev,
70 enum led_brightness b)
71{
72 if (b != LED_OFF)
73 cm_control(CM_CTRL_LED, CM_CTRL_LED);
74 else
75 cm_control(CM_CTRL_LED, 0);
76}
77
78static enum led_brightness cm_led_get(struct led_classdev *cdev)
79{
80 u32 reg = cm_get();
81
82 return (reg & CM_CTRL_LED) ? LED_FULL : LED_OFF;
83}
84
85static int __init integrator_leds_init(void)
86{
87 int i;
88
89 for (i = 0; i < ARRAY_SIZE(integrator_leds); i++) {
90 struct integrator_led *led;
91
92 led = kzalloc(sizeof(*led), GFP_KERNEL);
93 if (!led)
94 break;
95
96
97 led->cdev.name = integrator_leds[i].name;
98
99 if (i == 4) { /* Setting for LED in core module */
100 led->cdev.brightness_set = cm_led_set;
101 led->cdev.brightness_get = cm_led_get;
102 } else {
103 led->cdev.brightness_set = integrator_led_set;
104 led->cdev.brightness_get = integrator_led_get;
105 }
106
107 led->cdev.default_trigger = integrator_leds[i].trigger;
108 led->mask = BIT(i);
109
110 if (led_classdev_register(NULL, &led->cdev) < 0) {
111 kfree(led);
112 break;
113 }
114 }
115
116 return 0;
117}
118
119/*
120 * Since we may have triggers on any subsystem, defer registration
121 * until after subsystem_init.
122 */
123fs_initcall(integrator_leds_init);
124#endif
diff --git a/arch/arm/mach-mediatek/Kconfig b/arch/arm/mach-mediatek/Kconfig
index 2c043a210db0..f73f588f649c 100644
--- a/arch/arm/mach-mediatek/Kconfig
+++ b/arch/arm/mach-mediatek/Kconfig
@@ -1,6 +1,6 @@
1config ARCH_MEDIATEK 1config ARCH_MEDIATEK
2 bool "Mediatek MT6589 SoC" if ARCH_MULTI_V7 2 bool "Mediatek MT65xx & MT81xx SoC" if ARCH_MULTI_V7
3 select ARM_GIC 3 select ARM_GIC
4 select MTK_TIMER 4 select MTK_TIMER
5 help 5 help
6 Support for Mediatek Cortex-A7 Quad-Core-SoC MT6589. 6 Support for Mediatek MT65xx & MT81xx SoCs
diff --git a/arch/arm/mach-meson/Kconfig b/arch/arm/mach-meson/Kconfig
index 2c1154e1794a..18301dc9d2e7 100644
--- a/arch/arm/mach-meson/Kconfig
+++ b/arch/arm/mach-meson/Kconfig
@@ -2,6 +2,7 @@ menuconfig ARCH_MESON
2 bool "Amlogic Meson SoCs" if ARCH_MULTI_V7 2 bool "Amlogic Meson SoCs" if ARCH_MULTI_V7
3 select GENERIC_IRQ_CHIP 3 select GENERIC_IRQ_CHIP
4 select ARM_GIC 4 select ARM_GIC
5 select CACHE_L2X0
5 6
6if ARCH_MESON 7if ARCH_MESON
7 8
@@ -10,4 +11,9 @@ config MACH_MESON6
10 default ARCH_MESON 11 default ARCH_MESON
11 select MESON6_TIMER 12 select MESON6_TIMER
12 13
14config MACH_MESON8
15 bool "Amlogic Meson8 SoCs support"
16 default ARCH_MESON
17 select MESON6_TIMER
18
13endif 19endif
diff --git a/arch/arm/mach-meson/meson.c b/arch/arm/mach-meson/meson.c
index 5ee064f5a89f..5d6affe6a694 100644
--- a/arch/arm/mach-meson/meson.c
+++ b/arch/arm/mach-meson/meson.c
@@ -16,12 +16,14 @@
16#include <linux/of_platform.h> 16#include <linux/of_platform.h>
17#include <asm/mach/arch.h> 17#include <asm/mach/arch.h>
18 18
19static const char * const m6_common_board_compat[] = { 19static const char * const meson_common_board_compat[] = {
20 "amlogic,meson6", 20 "amlogic,meson6",
21 "amlogic,meson8",
21 NULL, 22 NULL,
22}; 23};
23 24
24DT_MACHINE_START(AML8726_MX, "Amlogic Meson6 platform") 25DT_MACHINE_START(MESON, "Amlogic Meson platform")
25 .dt_compat = m6_common_board_compat, 26 .dt_compat = meson_common_board_compat,
27 .l2c_aux_val = 0,
28 .l2c_aux_mask = ~0,
26MACHINE_END 29MACHINE_END
27
diff --git a/arch/arm/mach-mvebu/Makefile b/arch/arm/mach-mvebu/Makefile
index e24136b42765..b4f01497ce0b 100644
--- a/arch/arm/mach-mvebu/Makefile
+++ b/arch/arm/mach-mvebu/Makefile
@@ -7,7 +7,7 @@ CFLAGS_pmsu.o := -march=armv7-a
7obj-$(CONFIG_MACH_MVEBU_ANY) += system-controller.o mvebu-soc-id.o 7obj-$(CONFIG_MACH_MVEBU_ANY) += system-controller.o mvebu-soc-id.o
8 8
9ifeq ($(CONFIG_MACH_MVEBU_V7),y) 9ifeq ($(CONFIG_MACH_MVEBU_V7),y)
10obj-y += cpu-reset.o board-v7.o coherency.o coherency_ll.o pmsu.o pmsu_ll.o 10obj-y += cpu-reset.o board-v7.o coherency.o coherency_ll.o pmsu.o pmsu_ll.o pm.o pm-board.o
11obj-$(CONFIG_SMP) += platsmp.o headsmp.o platsmp-a9.o headsmp-a9.o 11obj-$(CONFIG_SMP) += platsmp.o headsmp.o platsmp-a9.o headsmp-a9.o
12endif 12endif
13 13
diff --git a/arch/arm/mach-mvebu/armada-370-xp.h b/arch/arm/mach-mvebu/armada-370-xp.h
index 84cd90d9b860..c55bbf81de0e 100644
--- a/arch/arm/mach-mvebu/armada-370-xp.h
+++ b/arch/arm/mach-mvebu/armada-370-xp.h
@@ -16,14 +16,8 @@
16#define __MACH_ARMADA_370_XP_H 16#define __MACH_ARMADA_370_XP_H
17 17
18#ifdef CONFIG_SMP 18#ifdef CONFIG_SMP
19#include <linux/cpumask.h>
20
21#define ARMADA_XP_MAX_CPUS 4
22
23void armada_xp_secondary_startup(void); 19void armada_xp_secondary_startup(void);
24extern struct smp_operations armada_xp_smp_ops; 20extern struct smp_operations armada_xp_smp_ops;
25#endif 21#endif
26 22
27int armada_370_xp_pmsu_idle_enter(unsigned long deepidle);
28
29#endif /* __MACH_ARMADA_370_XP_H */ 23#endif /* __MACH_ARMADA_370_XP_H */
diff --git a/arch/arm/mach-mvebu/board-v7.c b/arch/arm/mach-mvebu/board-v7.c
index d0d39f150fab..89a139ed7d5b 100644
--- a/arch/arm/mach-mvebu/board-v7.c
+++ b/arch/arm/mach-mvebu/board-v7.c
@@ -16,10 +16,12 @@
16#include <linux/init.h> 16#include <linux/init.h>
17#include <linux/clk-provider.h> 17#include <linux/clk-provider.h>
18#include <linux/of_address.h> 18#include <linux/of_address.h>
19#include <linux/of_fdt.h>
19#include <linux/of_platform.h> 20#include <linux/of_platform.h>
20#include <linux/io.h> 21#include <linux/io.h>
21#include <linux/clocksource.h> 22#include <linux/clocksource.h>
22#include <linux/dma-mapping.h> 23#include <linux/dma-mapping.h>
24#include <linux/memblock.h>
23#include <linux/mbus.h> 25#include <linux/mbus.h>
24#include <linux/signal.h> 26#include <linux/signal.h>
25#include <linux/slab.h> 27#include <linux/slab.h>
@@ -57,6 +59,54 @@ void __iomem *mvebu_get_scu_base(void)
57} 59}
58 60
59/* 61/*
62 * When returning from suspend, the platform goes through the
63 * bootloader, which executes its DDR3 training code. This code has
64 * the unfortunate idea of using the first 10 KB of each DRAM bank to
65 * exercise the RAM and calculate the optimal timings. Therefore, this
66 * area of RAM is overwritten, and shouldn't be used by the kernel if
67 * suspend/resume is supported.
68 */
69
70#ifdef CONFIG_SUSPEND
71#define MVEBU_DDR_TRAINING_AREA_SZ (10 * SZ_1K)
72static int __init mvebu_scan_mem(unsigned long node, const char *uname,
73 int depth, void *data)
74{
75 const char *type = of_get_flat_dt_prop(node, "device_type", NULL);
76 const __be32 *reg, *endp;
77 int l;
78
79 if (type == NULL || strcmp(type, "memory"))
80 return 0;
81
82 reg = of_get_flat_dt_prop(node, "linux,usable-memory", &l);
83 if (reg == NULL)
84 reg = of_get_flat_dt_prop(node, "reg", &l);
85 if (reg == NULL)
86 return 0;
87
88 endp = reg + (l / sizeof(__be32));
89 while ((endp - reg) >= (dt_root_addr_cells + dt_root_size_cells)) {
90 u64 base, size;
91
92 base = dt_mem_next_cell(dt_root_addr_cells, &reg);
93 size = dt_mem_next_cell(dt_root_size_cells, &reg);
94
95 memblock_reserve(base, MVEBU_DDR_TRAINING_AREA_SZ);
96 }
97
98 return 0;
99}
100
101static void __init mvebu_memblock_reserve(void)
102{
103 of_scan_flat_dt(mvebu_scan_mem, NULL);
104}
105#else
106static void __init mvebu_memblock_reserve(void) {}
107#endif
108
109/*
60 * Early versions of Armada 375 SoC have a bug where the BootROM 110 * Early versions of Armada 375 SoC have a bug where the BootROM
61 * leaves an external data abort pending. The kernel is hit by this 111 * leaves an external data abort pending. The kernel is hit by this
62 * data abort as soon as it enters userspace, because it unmasks the 112 * data abort as soon as it enters userspace, because it unmasks the
@@ -124,76 +174,12 @@ static void __init i2c_quirk(void)
124 return; 174 return;
125} 175}
126 176
127#define A375_Z1_THERMAL_FIXUP_OFFSET 0xc
128
129static void __init thermal_quirk(void)
130{
131 struct device_node *np;
132 u32 dev, rev;
133 int res;
134
135 /*
136 * The early SoC Z1 revision needs a quirk to be applied in order
137 * for the thermal controller to work properly. This quirk breaks
138 * the thermal support if applied on a SoC that doesn't need it,
139 * so we enforce the SoC revision to be known.
140 */
141 res = mvebu_get_soc_id(&dev, &rev);
142 if (res < 0 || (res == 0 && rev > ARMADA_375_Z1_REV))
143 return;
144
145 for_each_compatible_node(np, NULL, "marvell,armada375-thermal") {
146 struct property *prop;
147 __be32 newval, *newprop, *oldprop;
148 int len;
149
150 /*
151 * The register offset is at a wrong location. This quirk
152 * creates a new reg property as a clone of the previous
153 * one and corrects the offset.
154 */
155 oldprop = (__be32 *)of_get_property(np, "reg", &len);
156 if (!oldprop)
157 continue;
158
159 /* Create a duplicate of the 'reg' property */
160 prop = kzalloc(sizeof(*prop), GFP_KERNEL);
161 prop->length = len;
162 prop->name = kstrdup("reg", GFP_KERNEL);
163 prop->value = kzalloc(len, GFP_KERNEL);
164 memcpy(prop->value, oldprop, len);
165
166 /* Fixup the register offset of the second entry */
167 oldprop += 2;
168 newprop = (__be32 *)prop->value + 2;
169 newval = cpu_to_be32(be32_to_cpu(*oldprop) -
170 A375_Z1_THERMAL_FIXUP_OFFSET);
171 *newprop = newval;
172 of_update_property(np, prop);
173
174 /*
175 * The thermal controller needs some quirk too, so let's change
176 * the compatible string to reflect this and allow the driver
177 * the take the necessary action.
178 */
179 prop = kzalloc(sizeof(*prop), GFP_KERNEL);
180 prop->name = kstrdup("compatible", GFP_KERNEL);
181 prop->length = sizeof("marvell,armada375-z1-thermal");
182 prop->value = kstrdup("marvell,armada375-z1-thermal",
183 GFP_KERNEL);
184 of_update_property(np, prop);
185 }
186 return;
187}
188
189static void __init mvebu_dt_init(void) 177static void __init mvebu_dt_init(void)
190{ 178{
191 if (of_machine_is_compatible("marvell,armadaxp")) 179 if (of_machine_is_compatible("marvell,armadaxp"))
192 i2c_quirk(); 180 i2c_quirk();
193 if (of_machine_is_compatible("marvell,a375-db")) { 181 if (of_machine_is_compatible("marvell,a375-db"))
194 external_abort_quirk(); 182 external_abort_quirk();
195 thermal_quirk();
196 }
197 183
198 of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); 184 of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
199} 185}
@@ -206,10 +192,16 @@ static const char * const armada_370_xp_dt_compat[] = {
206DT_MACHINE_START(ARMADA_370_XP_DT, "Marvell Armada 370/XP (Device Tree)") 192DT_MACHINE_START(ARMADA_370_XP_DT, "Marvell Armada 370/XP (Device Tree)")
207 .l2c_aux_val = 0, 193 .l2c_aux_val = 0,
208 .l2c_aux_mask = ~0, 194 .l2c_aux_mask = ~0,
195/*
196 * The following field (.smp) is still needed to ensure backward
197 * compatibility with old Device Trees that were not specifying the
198 * cpus enable-method property.
199 */
209 .smp = smp_ops(armada_xp_smp_ops), 200 .smp = smp_ops(armada_xp_smp_ops),
210 .init_machine = mvebu_dt_init, 201 .init_machine = mvebu_dt_init,
211 .init_irq = mvebu_init_irq, 202 .init_irq = mvebu_init_irq,
212 .restart = mvebu_restart, 203 .restart = mvebu_restart,
204 .reserve = mvebu_memblock_reserve,
213 .dt_compat = armada_370_xp_dt_compat, 205 .dt_compat = armada_370_xp_dt_compat,
214MACHINE_END 206MACHINE_END
215 207
diff --git a/arch/arm/mach-mvebu/coherency.c b/arch/arm/mach-mvebu/coherency.c
index 044b51185fcc..3585cb394e9b 100644
--- a/arch/arm/mach-mvebu/coherency.c
+++ b/arch/arm/mach-mvebu/coherency.c
@@ -1,5 +1,6 @@
1/* 1/*
2 * Coherency fabric (Aurora) support for Armada 370 and XP platforms. 2 * Coherency fabric (Aurora) support for Armada 370, 375, 38x and XP
3 * platforms.
3 * 4 *
4 * Copyright (C) 2012 Marvell 5 * Copyright (C) 2012 Marvell
5 * 6 *
@@ -11,7 +12,7 @@
11 * License version 2. This program is licensed "as is" without any 12 * License version 2. This program is licensed "as is" without any
12 * warranty of any kind, whether express or implied. 13 * warranty of any kind, whether express or implied.
13 * 14 *
14 * The Armada 370 and Armada XP SOCs have a coherency fabric which is 15 * The Armada 370, 375, 38x and XP SOCs have a coherency fabric which is
15 * responsible for ensuring hardware coherency between all CPUs and between 16 * responsible for ensuring hardware coherency between all CPUs and between
16 * CPUs and I/O masters. This file initializes the coherency fabric and 17 * CPUs and I/O masters. This file initializes the coherency fabric and
17 * supplies basic routines for configuring and controlling hardware coherency 18 * supplies basic routines for configuring and controlling hardware coherency
@@ -28,12 +29,10 @@
28#include <linux/platform_device.h> 29#include <linux/platform_device.h>
29#include <linux/slab.h> 30#include <linux/slab.h>
30#include <linux/mbus.h> 31#include <linux/mbus.h>
31#include <linux/clk.h>
32#include <linux/pci.h> 32#include <linux/pci.h>
33#include <asm/smp_plat.h> 33#include <asm/smp_plat.h>
34#include <asm/cacheflush.h> 34#include <asm/cacheflush.h>
35#include <asm/mach/map.h> 35#include <asm/mach/map.h>
36#include "armada-370-xp.h"
37#include "coherency.h" 36#include "coherency.h"
38#include "mvebu-soc-id.h" 37#include "mvebu-soc-id.h"
39 38
@@ -42,8 +41,6 @@ void __iomem *coherency_base;
42static void __iomem *coherency_cpu_base; 41static void __iomem *coherency_cpu_base;
43 42
44/* Coherency fabric registers */ 43/* Coherency fabric registers */
45#define COHERENCY_FABRIC_CFG_OFFSET 0x4
46
47#define IO_SYNC_BARRIER_CTL_OFFSET 0x0 44#define IO_SYNC_BARRIER_CTL_OFFSET 0x0
48 45
49enum { 46enum {
@@ -79,157 +76,8 @@ int set_cpu_coherent(void)
79 return ll_enable_coherency(); 76 return ll_enable_coherency();
80} 77}
81 78
82/*
83 * The below code implements the I/O coherency workaround on Armada
84 * 375. This workaround consists in using the two channels of the
85 * first XOR engine to trigger a XOR transaction that serves as the
86 * I/O coherency barrier.
87 */
88
89static void __iomem *xor_base, *xor_high_base;
90static dma_addr_t coherency_wa_buf_phys[CONFIG_NR_CPUS];
91static void *coherency_wa_buf[CONFIG_NR_CPUS];
92static bool coherency_wa_enabled;
93
94#define XOR_CONFIG(chan) (0x10 + (chan * 4))
95#define XOR_ACTIVATION(chan) (0x20 + (chan * 4))
96#define WINDOW_BAR_ENABLE(chan) (0x240 + ((chan) << 2))
97#define WINDOW_BASE(w) (0x250 + ((w) << 2))
98#define WINDOW_SIZE(w) (0x270 + ((w) << 2))
99#define WINDOW_REMAP_HIGH(w) (0x290 + ((w) << 2))
100#define WINDOW_OVERRIDE_CTRL(chan) (0x2A0 + ((chan) << 2))
101#define XOR_DEST_POINTER(chan) (0x2B0 + (chan * 4))
102#define XOR_BLOCK_SIZE(chan) (0x2C0 + (chan * 4))
103#define XOR_INIT_VALUE_LOW 0x2E0
104#define XOR_INIT_VALUE_HIGH 0x2E4
105
106static inline void mvebu_hwcc_armada375_sync_io_barrier_wa(void)
107{
108 int idx = smp_processor_id();
109
110 /* Write '1' to the first word of the buffer */
111 writel(0x1, coherency_wa_buf[idx]);
112
113 /* Wait until the engine is idle */
114 while ((readl(xor_base + XOR_ACTIVATION(idx)) >> 4) & 0x3)
115 ;
116
117 dmb();
118
119 /* Trigger channel */
120 writel(0x1, xor_base + XOR_ACTIVATION(idx));
121
122 /* Poll the data until it is cleared by the XOR transaction */
123 while (readl(coherency_wa_buf[idx]))
124 ;
125}
126
127static void __init armada_375_coherency_init_wa(void)
128{
129 const struct mbus_dram_target_info *dram;
130 struct device_node *xor_node;
131 struct property *xor_status;
132 struct clk *xor_clk;
133 u32 win_enable = 0;
134 int i;
135
136 pr_warn("enabling coherency workaround for Armada 375 Z1, one XOR engine disabled\n");
137
138 /*
139 * Since the workaround uses one XOR engine, we grab a
140 * reference to its Device Tree node first.
141 */
142 xor_node = of_find_compatible_node(NULL, NULL, "marvell,orion-xor");
143 BUG_ON(!xor_node);
144
145 /*
146 * Then we mark it as disabled so that the real XOR driver
147 * will not use it.
148 */
149 xor_status = kzalloc(sizeof(struct property), GFP_KERNEL);
150 BUG_ON(!xor_status);
151
152 xor_status->value = kstrdup("disabled", GFP_KERNEL);
153 BUG_ON(!xor_status->value);
154
155 xor_status->length = 8;
156 xor_status->name = kstrdup("status", GFP_KERNEL);
157 BUG_ON(!xor_status->name);
158
159 of_update_property(xor_node, xor_status);
160
161 /*
162 * And we remap the registers, get the clock, and do the
163 * initial configuration of the XOR engine.
164 */
165 xor_base = of_iomap(xor_node, 0);
166 xor_high_base = of_iomap(xor_node, 1);
167
168 xor_clk = of_clk_get_by_name(xor_node, NULL);
169 BUG_ON(!xor_clk);
170
171 clk_prepare_enable(xor_clk);
172
173 dram = mv_mbus_dram_info();
174
175 for (i = 0; i < 8; i++) {
176 writel(0, xor_base + WINDOW_BASE(i));
177 writel(0, xor_base + WINDOW_SIZE(i));
178 if (i < 4)
179 writel(0, xor_base + WINDOW_REMAP_HIGH(i));
180 }
181
182 for (i = 0; i < dram->num_cs; i++) {
183 const struct mbus_dram_window *cs = dram->cs + i;
184 writel((cs->base & 0xffff0000) |
185 (cs->mbus_attr << 8) |
186 dram->mbus_dram_target_id, xor_base + WINDOW_BASE(i));
187 writel((cs->size - 1) & 0xffff0000, xor_base + WINDOW_SIZE(i));
188
189 win_enable |= (1 << i);
190 win_enable |= 3 << (16 + (2 * i));
191 }
192
193 writel(win_enable, xor_base + WINDOW_BAR_ENABLE(0));
194 writel(win_enable, xor_base + WINDOW_BAR_ENABLE(1));
195 writel(0, xor_base + WINDOW_OVERRIDE_CTRL(0));
196 writel(0, xor_base + WINDOW_OVERRIDE_CTRL(1));
197
198 for (i = 0; i < CONFIG_NR_CPUS; i++) {
199 coherency_wa_buf[i] = kzalloc(PAGE_SIZE, GFP_KERNEL);
200 BUG_ON(!coherency_wa_buf[i]);
201
202 /*
203 * We can't use the DMA mapping API, since we don't
204 * have a valid 'struct device' pointer
205 */
206 coherency_wa_buf_phys[i] =
207 virt_to_phys(coherency_wa_buf[i]);
208 BUG_ON(!coherency_wa_buf_phys[i]);
209
210 /*
211 * Configure the XOR engine for memset operation, with
212 * a 128 bytes block size
213 */
214 writel(0x444, xor_base + XOR_CONFIG(i));
215 writel(128, xor_base + XOR_BLOCK_SIZE(i));
216 writel(coherency_wa_buf_phys[i],
217 xor_base + XOR_DEST_POINTER(i));
218 }
219
220 writel(0x0, xor_base + XOR_INIT_VALUE_LOW);
221 writel(0x0, xor_base + XOR_INIT_VALUE_HIGH);
222
223 coherency_wa_enabled = true;
224}
225
226static inline void mvebu_hwcc_sync_io_barrier(void) 79static inline void mvebu_hwcc_sync_io_barrier(void)
227{ 80{
228 if (coherency_wa_enabled) {
229 mvebu_hwcc_armada375_sync_io_barrier_wa();
230 return;
231 }
232
233 writel(0x1, coherency_cpu_base + IO_SYNC_BARRIER_CTL_OFFSET); 81 writel(0x1, coherency_cpu_base + IO_SYNC_BARRIER_CTL_OFFSET);
234 while (readl(coherency_cpu_base + IO_SYNC_BARRIER_CTL_OFFSET) & 0x1); 82 while (readl(coherency_cpu_base + IO_SYNC_BARRIER_CTL_OFFSET) & 0x1);
235} 83}
@@ -361,25 +209,41 @@ static int coherency_type(void)
361{ 209{
362 struct device_node *np; 210 struct device_node *np;
363 const struct of_device_id *match; 211 const struct of_device_id *match;
212 int type;
364 213
365 np = of_find_matching_node_and_match(NULL, of_coherency_table, &match); 214 /*
366 if (np) { 215 * The coherency fabric is needed:
367 int type = (int) match->data; 216 * - For coherency between processors on Armada XP, so only
217 * when SMP is enabled.
218 * - For coherency between the processor and I/O devices, but
219 * this coherency requires many pre-requisites (write
220 * allocate cache policy, shareable pages, SMP bit set) that
221 * are only meant in SMP situations.
222 *
223 * Note that this means that on Armada 370, there is currently
224 * no way to use hardware I/O coherency, because even when
225 * CONFIG_SMP is enabled, is_smp() returns false due to the
226 * Armada 370 being a single-core processor. To lift this
227 * limitation, we would have to find a way to make the cache
228 * policy set to write-allocate (on all Armada SoCs), and to
229 * set the shareable attribute in page tables (on all Armada
230 * SoCs except the Armada 370). Unfortunately, such decisions
231 * are taken very early in the kernel boot process, at a point
232 * where we don't know yet on which SoC we are running.
368 233
369 /* Armada 370/XP coherency works in both UP and SMP */ 234 */
370 if (type == COHERENCY_FABRIC_TYPE_ARMADA_370_XP) 235 if (!is_smp())
371 return type; 236 return COHERENCY_FABRIC_TYPE_NONE;
372 237
373 /* Armada 375 coherency works only on SMP */ 238 np = of_find_matching_node_and_match(NULL, of_coherency_table, &match);
374 else if (type == COHERENCY_FABRIC_TYPE_ARMADA_375 && is_smp()) 239 if (!np)
375 return type; 240 return COHERENCY_FABRIC_TYPE_NONE;
376 241
377 /* Armada 380 coherency works only on SMP */ 242 type = (int) match->data;
378 else if (type == COHERENCY_FABRIC_TYPE_ARMADA_380 && is_smp())
379 return type;
380 }
381 243
382 return COHERENCY_FABRIC_TYPE_NONE; 244 of_node_put(np);
245
246 return type;
383} 247}
384 248
385int coherency_available(void) 249int coherency_available(void)
@@ -407,22 +271,9 @@ int __init coherency_init(void)
407 271
408static int __init coherency_late_init(void) 272static int __init coherency_late_init(void)
409{ 273{
410 int type = coherency_type(); 274 if (coherency_available())
411 275 bus_register_notifier(&platform_bus_type,
412 if (type == COHERENCY_FABRIC_TYPE_NONE) 276 &mvebu_hwcc_nb);
413 return 0;
414
415 if (type == COHERENCY_FABRIC_TYPE_ARMADA_375) {
416 u32 dev, rev;
417
418 if (mvebu_get_soc_id(&dev, &rev) == 0 &&
419 rev == ARMADA_375_Z1_REV)
420 armada_375_coherency_init_wa();
421 }
422
423 bus_register_notifier(&platform_bus_type,
424 &mvebu_hwcc_nb);
425
426 return 0; 277 return 0;
427} 278}
428 279
diff --git a/arch/arm/mach-mvebu/coherency_ll.S b/arch/arm/mach-mvebu/coherency_ll.S
index f5d881b5d0f7..8b2fbc8b6bc6 100644
--- a/arch/arm/mach-mvebu/coherency_ll.S
+++ b/arch/arm/mach-mvebu/coherency_ll.S
@@ -24,7 +24,10 @@
24#include <asm/cp15.h> 24#include <asm/cp15.h>
25 25
26 .text 26 .text
27/* Returns the coherency base address in r1 (r0 is untouched) */ 27/*
28 * Returns the coherency base address in r1 (r0 is untouched), or 0 if
29 * the coherency fabric is not enabled.
30 */
28ENTRY(ll_get_coherency_base) 31ENTRY(ll_get_coherency_base)
29 mrc p15, 0, r1, c1, c0, 0 32 mrc p15, 0, r1, c1, c0, 0
30 tst r1, #CR_M @ Check MMU bit enabled 33 tst r1, #CR_M @ Check MMU bit enabled
@@ -32,8 +35,13 @@ ENTRY(ll_get_coherency_base)
32 35
33 /* 36 /*
34 * MMU is disabled, use the physical address of the coherency 37 * MMU is disabled, use the physical address of the coherency
35 * base address. 38 * base address. However, if the coherency fabric isn't mapped
39 * (i.e its virtual address is zero), it means coherency is
40 * not enabled, so we return 0.
36 */ 41 */
42 ldr r1, =coherency_base
43 cmp r1, #0
44 beq 2f
37 adr r1, 3f 45 adr r1, 3f
38 ldr r3, [r1] 46 ldr r3, [r1]
39 ldr r1, [r1, r3] 47 ldr r1, [r1, r3]
@@ -85,6 +93,9 @@ ENTRY(ll_add_cpu_to_smp_group)
85 */ 93 */
86 mov r0, lr 94 mov r0, lr
87 bl ll_get_coherency_base 95 bl ll_get_coherency_base
96 /* Bail out if the coherency is not enabled */
97 cmp r1, #0
98 reteq r0
88 bl ll_get_coherency_cpumask 99 bl ll_get_coherency_cpumask
89 mov lr, r0 100 mov lr, r0
90 add r0, r1, #ARMADA_XP_CFB_CFG_REG_OFFSET 101 add r0, r1, #ARMADA_XP_CFB_CFG_REG_OFFSET
@@ -107,6 +118,9 @@ ENTRY(ll_enable_coherency)
107 */ 118 */
108 mov r0, lr 119 mov r0, lr
109 bl ll_get_coherency_base 120 bl ll_get_coherency_base
121 /* Bail out if the coherency is not enabled */
122 cmp r1, #0
123 reteq r0
110 bl ll_get_coherency_cpumask 124 bl ll_get_coherency_cpumask
111 mov lr, r0 125 mov lr, r0
112 add r0, r1, #ARMADA_XP_CFB_CTL_REG_OFFSET 126 add r0, r1, #ARMADA_XP_CFB_CTL_REG_OFFSET
@@ -131,6 +145,9 @@ ENTRY(ll_disable_coherency)
131 */ 145 */
132 mov r0, lr 146 mov r0, lr
133 bl ll_get_coherency_base 147 bl ll_get_coherency_base
148 /* Bail out if the coherency is not enabled */
149 cmp r1, #0
150 reteq r0
134 bl ll_get_coherency_cpumask 151 bl ll_get_coherency_cpumask
135 mov lr, r0 152 mov lr, r0
136 add r0, r1, #ARMADA_XP_CFB_CTL_REG_OFFSET 153 add r0, r1, #ARMADA_XP_CFB_CTL_REG_OFFSET
diff --git a/arch/arm/mach-mvebu/common.h b/arch/arm/mach-mvebu/common.h
index 3ccb40c3bf94..3e0aca1f288a 100644
--- a/arch/arm/mach-mvebu/common.h
+++ b/arch/arm/mach-mvebu/common.h
@@ -25,4 +25,6 @@ int mvebu_system_controller_get_soc_id(u32 *dev, u32 *rev);
25 25
26void __iomem *mvebu_get_scu_base(void); 26void __iomem *mvebu_get_scu_base(void);
27 27
28int mvebu_pm_init(void (*board_pm_enter)(void __iomem *sdram_reg, u32 srcmd));
29
28#endif 30#endif
diff --git a/arch/arm/mach-mvebu/cpu-reset.c b/arch/arm/mach-mvebu/cpu-reset.c
index 60fb53787004..4a2cadd6b48e 100644
--- a/arch/arm/mach-mvebu/cpu-reset.c
+++ b/arch/arm/mach-mvebu/cpu-reset.c
@@ -15,7 +15,6 @@
15#include <linux/of_address.h> 15#include <linux/of_address.h>
16#include <linux/io.h> 16#include <linux/io.h>
17#include <linux/resource.h> 17#include <linux/resource.h>
18#include "armada-370-xp.h"
19 18
20static void __iomem *cpu_reset_base; 19static void __iomem *cpu_reset_base;
21static size_t cpu_reset_size; 20static size_t cpu_reset_size;
diff --git a/arch/arm/mach-mvebu/headsmp-a9.S b/arch/arm/mach-mvebu/headsmp-a9.S
index be51c998c0cd..08d5ed46b996 100644
--- a/arch/arm/mach-mvebu/headsmp-a9.S
+++ b/arch/arm/mach-mvebu/headsmp-a9.S
@@ -22,5 +22,6 @@
22ENTRY(mvebu_cortex_a9_secondary_startup) 22ENTRY(mvebu_cortex_a9_secondary_startup)
23ARM_BE8(setend be) 23ARM_BE8(setend be)
24 bl v7_invalidate_l1 24 bl v7_invalidate_l1
25 bl armada_38x_scu_power_up
25 b secondary_startup 26 b secondary_startup
26ENDPROC(mvebu_cortex_a9_secondary_startup) 27ENDPROC(mvebu_cortex_a9_secondary_startup)
diff --git a/arch/arm/mach-mvebu/platsmp-a9.c b/arch/arm/mach-mvebu/platsmp-a9.c
index 47a71a924b96..2ec1a42b4321 100644
--- a/arch/arm/mach-mvebu/platsmp-a9.c
+++ b/arch/arm/mach-mvebu/platsmp-a9.c
@@ -43,21 +43,70 @@ static int __cpuinit mvebu_cortex_a9_boot_secondary(unsigned int cpu,
43 else 43 else
44 mvebu_pmsu_set_cpu_boot_addr(hw_cpu, mvebu_cortex_a9_secondary_startup); 44 mvebu_pmsu_set_cpu_boot_addr(hw_cpu, mvebu_cortex_a9_secondary_startup);
45 smp_wmb(); 45 smp_wmb();
46
47 /*
48 * Doing this before deasserting the CPUs is needed to wake up CPUs
49 * in the offline state after using CPU hotplug.
50 */
51 arch_send_wakeup_ipi_mask(cpumask_of(cpu));
52
46 ret = mvebu_cpu_reset_deassert(hw_cpu); 53 ret = mvebu_cpu_reset_deassert(hw_cpu);
47 if (ret) { 54 if (ret) {
48 pr_err("Could not start the secondary CPU: %d\n", ret); 55 pr_err("Could not start the secondary CPU: %d\n", ret);
49 return ret; 56 return ret;
50 } 57 }
51 arch_send_wakeup_ipi_mask(cpumask_of(cpu));
52 58
53 return 0; 59 return 0;
54} 60}
61/*
62 * When a CPU is brought back online, either through CPU hotplug, or
63 * because of the boot of a kexec'ed kernel, the PMSU configuration
64 * for this CPU might be in the deep idle state, preventing this CPU
65 * from receiving interrupts. Here, we therefore take out the current
66 * CPU from this state, which was entered by armada_38x_cpu_die()
67 * below.
68 */
69static void armada_38x_secondary_init(unsigned int cpu)
70{
71 mvebu_v7_pmsu_idle_exit();
72}
73
74#ifdef CONFIG_HOTPLUG_CPU
75static void armada_38x_cpu_die(unsigned int cpu)
76{
77 /*
78 * CPU hotplug is implemented by putting offline CPUs into the
79 * deep idle sleep state.
80 */
81 armada_38x_do_cpu_suspend(true);
82}
83
84/*
85 * We need a dummy function, so that platform_can_cpu_hotplug() knows
86 * we support CPU hotplug. However, the function does not need to do
87 * anything, because CPUs going offline can enter the deep idle state
88 * by themselves, without any help from a still alive CPU.
89 */
90static int armada_38x_cpu_kill(unsigned int cpu)
91{
92 return 1;
93}
94#endif
55 95
56static struct smp_operations mvebu_cortex_a9_smp_ops __initdata = { 96static struct smp_operations mvebu_cortex_a9_smp_ops __initdata = {
57 .smp_boot_secondary = mvebu_cortex_a9_boot_secondary, 97 .smp_boot_secondary = mvebu_cortex_a9_boot_secondary,
58}; 98};
59 99
100static struct smp_operations armada_38x_smp_ops __initdata = {
101 .smp_boot_secondary = mvebu_cortex_a9_boot_secondary,
102 .smp_secondary_init = armada_38x_secondary_init,
103#ifdef CONFIG_HOTPLUG_CPU
104 .cpu_die = armada_38x_cpu_die,
105 .cpu_kill = armada_38x_cpu_kill,
106#endif
107};
108
60CPU_METHOD_OF_DECLARE(mvebu_armada_375_smp, "marvell,armada-375-smp", 109CPU_METHOD_OF_DECLARE(mvebu_armada_375_smp, "marvell,armada-375-smp",
61 &mvebu_cortex_a9_smp_ops); 110 &mvebu_cortex_a9_smp_ops);
62CPU_METHOD_OF_DECLARE(mvebu_armada_380_smp, "marvell,armada-380-smp", 111CPU_METHOD_OF_DECLARE(mvebu_armada_380_smp, "marvell,armada-380-smp",
63 &mvebu_cortex_a9_smp_ops); 112 &armada_38x_smp_ops);
diff --git a/arch/arm/mach-mvebu/platsmp.c b/arch/arm/mach-mvebu/platsmp.c
index 895dc373c8a1..58cc8c1575eb 100644
--- a/arch/arm/mach-mvebu/platsmp.c
+++ b/arch/arm/mach-mvebu/platsmp.c
@@ -30,10 +30,12 @@
30#include "pmsu.h" 30#include "pmsu.h"
31#include "coherency.h" 31#include "coherency.h"
32 32
33#define ARMADA_XP_MAX_CPUS 4
34
33#define AXP_BOOTROM_BASE 0xfff00000 35#define AXP_BOOTROM_BASE 0xfff00000
34#define AXP_BOOTROM_SIZE 0x100000 36#define AXP_BOOTROM_SIZE 0x100000
35 37
36static struct clk *__init get_cpu_clk(int cpu) 38static struct clk *get_cpu_clk(int cpu)
37{ 39{
38 struct clk *cpu_clk; 40 struct clk *cpu_clk;
39 struct device_node *np = of_get_cpu_node(cpu, NULL); 41 struct device_node *np = of_get_cpu_node(cpu, NULL);
@@ -46,29 +48,28 @@ static struct clk *__init get_cpu_clk(int cpu)
46 return cpu_clk; 48 return cpu_clk;
47} 49}
48 50
49static void __init set_secondary_cpus_clock(void) 51static void set_secondary_cpu_clock(unsigned int cpu)
50{ 52{
51 int thiscpu, cpu; 53 int thiscpu;
52 unsigned long rate; 54 unsigned long rate;
53 struct clk *cpu_clk; 55 struct clk *cpu_clk;
54 56
55 thiscpu = smp_processor_id(); 57 thiscpu = get_cpu();
58
56 cpu_clk = get_cpu_clk(thiscpu); 59 cpu_clk = get_cpu_clk(thiscpu);
57 if (!cpu_clk) 60 if (!cpu_clk)
58 return; 61 goto out;
59 clk_prepare_enable(cpu_clk); 62 clk_prepare_enable(cpu_clk);
60 rate = clk_get_rate(cpu_clk); 63 rate = clk_get_rate(cpu_clk);
61 64
62 /* set all the other CPU clk to the same rate than the boot CPU */ 65 cpu_clk = get_cpu_clk(cpu);
63 for_each_possible_cpu(cpu) { 66 if (!cpu_clk)
64 if (cpu == thiscpu) 67 goto out;
65 continue; 68 clk_set_rate(cpu_clk, rate);
66 cpu_clk = get_cpu_clk(cpu); 69 clk_prepare_enable(cpu_clk);
67 if (!cpu_clk) 70
68 return; 71out:
69 clk_set_rate(cpu_clk, rate); 72 put_cpu();
70 clk_prepare_enable(cpu_clk);
71 }
72} 73}
73 74
74static int armada_xp_boot_secondary(unsigned int cpu, struct task_struct *idle) 75static int armada_xp_boot_secondary(unsigned int cpu, struct task_struct *idle)
@@ -78,6 +79,7 @@ static int armada_xp_boot_secondary(unsigned int cpu, struct task_struct *idle)
78 pr_info("Booting CPU %d\n", cpu); 79 pr_info("Booting CPU %d\n", cpu);
79 80
80 hw_cpu = cpu_logical_map(cpu); 81 hw_cpu = cpu_logical_map(cpu);
82 set_secondary_cpu_clock(hw_cpu);
81 mvebu_pmsu_set_cpu_boot_addr(hw_cpu, armada_xp_secondary_startup); 83 mvebu_pmsu_set_cpu_boot_addr(hw_cpu, armada_xp_secondary_startup);
82 84
83 /* 85 /*
@@ -126,7 +128,6 @@ static void __init armada_xp_smp_prepare_cpus(unsigned int max_cpus)
126 struct resource res; 128 struct resource res;
127 int err; 129 int err;
128 130
129 set_secondary_cpus_clock();
130 flush_cache_all(); 131 flush_cache_all();
131 set_cpu_coherent(); 132 set_cpu_coherent();
132 133
diff --git a/arch/arm/mach-mvebu/pm-board.c b/arch/arm/mach-mvebu/pm-board.c
new file mode 100644
index 000000000000..6dfd4ab97b2a
--- /dev/null
+++ b/arch/arm/mach-mvebu/pm-board.c
@@ -0,0 +1,141 @@
1/*
2 * Board-level suspend/resume support.
3 *
4 * Copyright (C) 2014 Marvell
5 *
6 * Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
7 *
8 * This file is licensed under the terms of the GNU General Public
9 * License version 2. This program is licensed "as is" without any
10 * warranty of any kind, whether express or implied.
11 */
12
13#include <linux/delay.h>
14#include <linux/gpio.h>
15#include <linux/init.h>
16#include <linux/io.h>
17#include <linux/of.h>
18#include <linux/of_address.h>
19#include <linux/of_gpio.h>
20#include <linux/slab.h>
21#include "common.h"
22
23#define ARMADA_XP_GP_PIC_NR_GPIOS 3
24
25static void __iomem *gpio_ctrl;
26static int pic_gpios[ARMADA_XP_GP_PIC_NR_GPIOS];
27static int pic_raw_gpios[ARMADA_XP_GP_PIC_NR_GPIOS];
28
29static void mvebu_armada_xp_gp_pm_enter(void __iomem *sdram_reg, u32 srcmd)
30{
31 u32 reg, ackcmd;
32 int i;
33
34 /* Put 001 as value on the GPIOs */
35 reg = readl(gpio_ctrl);
36 for (i = 0; i < ARMADA_XP_GP_PIC_NR_GPIOS; i++)
37 reg &= ~BIT(pic_raw_gpios[i]);
38 reg |= BIT(pic_raw_gpios[0]);
39 writel(reg, gpio_ctrl);
40
41 /* Prepare writing 111 to the GPIOs */
42 ackcmd = readl(gpio_ctrl);
43 for (i = 0; i < ARMADA_XP_GP_PIC_NR_GPIOS; i++)
44 ackcmd |= BIT(pic_raw_gpios[i]);
45
46 /*
47 * Wait a while, the PIC needs quite a bit of time between the
48 * two GPIO commands.
49 */
50 mdelay(3000);
51
52 asm volatile (
53 /* Align to a cache line */
54 ".balign 32\n\t"
55
56 /* Enter self refresh */
57 "str %[srcmd], [%[sdram_reg]]\n\t"
58
59 /*
60 * Wait 100 cycles for DDR to enter self refresh, by
61 * doing 50 times two instructions.
62 */
63 "mov r1, #50\n\t"
64 "1: subs r1, r1, #1\n\t"
65 "bne 1b\n\t"
66
67 /* Issue the command ACK */
68 "str %[ackcmd], [%[gpio_ctrl]]\n\t"
69
70 /* Trap the processor */
71 "b .\n\t"
72 : : [srcmd] "r" (srcmd), [sdram_reg] "r" (sdram_reg),
73 [ackcmd] "r" (ackcmd), [gpio_ctrl] "r" (gpio_ctrl) : "r1");
74}
75
76static int mvebu_armada_xp_gp_pm_init(void)
77{
78 struct device_node *np;
79 struct device_node *gpio_ctrl_np;
80 int ret = 0, i;
81
82 if (!of_machine_is_compatible("marvell,axp-gp"))
83 return -ENODEV;
84
85 np = of_find_node_by_name(NULL, "pm_pic");
86 if (!np)
87 return -ENODEV;
88
89 for (i = 0; i < ARMADA_XP_GP_PIC_NR_GPIOS; i++) {
90 char *name;
91 struct of_phandle_args args;
92
93 pic_gpios[i] = of_get_named_gpio(np, "ctrl-gpios", i);
94 if (pic_gpios[i] < 0) {
95 ret = -ENODEV;
96 goto out;
97 }
98
99 name = kasprintf(GFP_KERNEL, "pic-pin%d", i);
100 if (!name) {
101 ret = -ENOMEM;
102 goto out;
103 }
104
105 ret = gpio_request(pic_gpios[i], name);
106 if (ret < 0) {
107 kfree(name);
108 goto out;
109 }
110
111 ret = gpio_direction_output(pic_gpios[i], 0);
112 if (ret < 0) {
113 gpio_free(pic_gpios[i]);
114 kfree(name);
115 goto out;
116 }
117
118 ret = of_parse_phandle_with_fixed_args(np, "ctrl-gpios", 2,
119 i, &args);
120 if (ret < 0) {
121 gpio_free(pic_gpios[i]);
122 kfree(name);
123 goto out;
124 }
125
126 gpio_ctrl_np = args.np;
127 pic_raw_gpios[i] = args.args[0];
128 }
129
130 gpio_ctrl = of_iomap(gpio_ctrl_np, 0);
131 if (!gpio_ctrl)
132 return -ENOMEM;
133
134 mvebu_pm_init(mvebu_armada_xp_gp_pm_enter);
135
136out:
137 of_node_put(np);
138 return ret;
139}
140
141late_initcall(mvebu_armada_xp_gp_pm_init);
diff --git a/arch/arm/mach-mvebu/pm.c b/arch/arm/mach-mvebu/pm.c
new file mode 100644
index 000000000000..6573a8f11f70
--- /dev/null
+++ b/arch/arm/mach-mvebu/pm.c
@@ -0,0 +1,218 @@
1/*
2 * Suspend/resume support. Currently supporting Armada XP only.
3 *
4 * Copyright (C) 2014 Marvell
5 *
6 * Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
7 *
8 * This file is licensed under the terms of the GNU General Public
9 * License version 2. This program is licensed "as is" without any
10 * warranty of any kind, whether express or implied.
11 */
12
13#include <linux/cpu_pm.h>
14#include <linux/delay.h>
15#include <linux/gpio.h>
16#include <linux/io.h>
17#include <linux/kernel.h>
18#include <linux/mbus.h>
19#include <linux/of_address.h>
20#include <linux/suspend.h>
21#include <asm/cacheflush.h>
22#include <asm/outercache.h>
23#include <asm/suspend.h>
24
25#include "coherency.h"
26#include "pmsu.h"
27
28#define SDRAM_CONFIG_OFFS 0x0
29#define SDRAM_CONFIG_SR_MODE_BIT BIT(24)
30#define SDRAM_OPERATION_OFFS 0x18
31#define SDRAM_OPERATION_SELF_REFRESH 0x7
32#define SDRAM_DLB_EVICTION_OFFS 0x30c
33#define SDRAM_DLB_EVICTION_THRESHOLD_MASK 0xff
34
35static void (*mvebu_board_pm_enter)(void __iomem *sdram_reg, u32 srcmd);
36static void __iomem *sdram_ctrl;
37
38static int mvebu_pm_powerdown(unsigned long data)
39{
40 u32 reg, srcmd;
41
42 flush_cache_all();
43 outer_flush_all();
44
45 /*
46 * Issue a Data Synchronization Barrier instruction to ensure
47 * that all state saving has been completed.
48 */
49 dsb();
50
51 /* Flush the DLB and wait ~7 usec */
52 reg = readl(sdram_ctrl + SDRAM_DLB_EVICTION_OFFS);
53 reg &= ~SDRAM_DLB_EVICTION_THRESHOLD_MASK;
54 writel(reg, sdram_ctrl + SDRAM_DLB_EVICTION_OFFS);
55
56 udelay(7);
57
58 /* Set DRAM in battery backup mode */
59 reg = readl(sdram_ctrl + SDRAM_CONFIG_OFFS);
60 reg &= ~SDRAM_CONFIG_SR_MODE_BIT;
61 writel(reg, sdram_ctrl + SDRAM_CONFIG_OFFS);
62
63 /* Prepare to go to self-refresh */
64
65 srcmd = readl(sdram_ctrl + SDRAM_OPERATION_OFFS);
66 srcmd &= ~0x1F;
67 srcmd |= SDRAM_OPERATION_SELF_REFRESH;
68
69 mvebu_board_pm_enter(sdram_ctrl + SDRAM_OPERATION_OFFS, srcmd);
70
71 return 0;
72}
73
74#define BOOT_INFO_ADDR 0x3000
75#define BOOT_MAGIC_WORD 0xdeadb002
76#define BOOT_MAGIC_LIST_END 0xffffffff
77
78/*
79 * Those registers are accessed before switching the internal register
80 * base, which is why we hardcode the 0xd0000000 base address, the one
81 * used by the SoC out of reset.
82 */
83#define MBUS_WINDOW_12_CTRL 0xd00200b0
84#define MBUS_INTERNAL_REG_ADDRESS 0xd0020080
85
86#define SDRAM_WIN_BASE_REG(x) (0x20180 + (0x8*x))
87#define SDRAM_WIN_CTRL_REG(x) (0x20184 + (0x8*x))
88
89static phys_addr_t mvebu_internal_reg_base(void)
90{
91 struct device_node *np;
92 __be32 in_addr[2];
93
94 np = of_find_node_by_name(NULL, "internal-regs");
95 BUG_ON(!np);
96
97 /*
98 * Ask the DT what is the internal register address on this
99 * platform. In the mvebu-mbus DT binding, 0xf0010000
100 * corresponds to the internal register window.
101 */
102 in_addr[0] = cpu_to_be32(0xf0010000);
103 in_addr[1] = 0x0;
104
105 return of_translate_address(np, in_addr);
106}
107
108static void mvebu_pm_store_bootinfo(void)
109{
110 u32 *store_addr;
111 phys_addr_t resume_pc;
112
113 store_addr = phys_to_virt(BOOT_INFO_ADDR);
114 resume_pc = virt_to_phys(armada_370_xp_cpu_resume);
115
116 /*
117 * The bootloader expects the first two words to be a magic
118 * value (BOOT_MAGIC_WORD), followed by the address of the
119 * resume code to jump to. Then, it expects a sequence of
120 * (address, value) pairs, which can be used to restore the
121 * value of certain registers. This sequence must end with the
122 * BOOT_MAGIC_LIST_END magic value.
123 */
124
125 writel(BOOT_MAGIC_WORD, store_addr++);
126 writel(resume_pc, store_addr++);
127
128 /*
129 * Some platforms remap their internal register base address
130 * to 0xf1000000. However, out of reset, window 12 starts at
131 * 0xf0000000 and ends at 0xf7ffffff, which would overlap with
132 * the internal registers. Therefore, disable window 12.
133 */
134 writel(MBUS_WINDOW_12_CTRL, store_addr++);
135 writel(0x0, store_addr++);
136
137 /*
138 * Set the internal register base address to the value
139 * expected by Linux, as read from the Device Tree.
140 */
141 writel(MBUS_INTERNAL_REG_ADDRESS, store_addr++);
142 writel(mvebu_internal_reg_base(), store_addr++);
143
144 /*
145 * Ask the mvebu-mbus driver to store the SDRAM window
146 * configuration, which has to be restored by the bootloader
147 * before re-entering the kernel on resume.
148 */
149 store_addr += mvebu_mbus_save_cpu_target(store_addr);
150
151 writel(BOOT_MAGIC_LIST_END, store_addr);
152}
153
154static int mvebu_pm_enter(suspend_state_t state)
155{
156 if (state != PM_SUSPEND_MEM)
157 return -EINVAL;
158
159 cpu_pm_enter();
160
161 mvebu_pm_store_bootinfo();
162 cpu_suspend(0, mvebu_pm_powerdown);
163
164 outer_resume();
165
166 mvebu_v7_pmsu_idle_exit();
167
168 set_cpu_coherent();
169
170 cpu_pm_exit();
171
172 return 0;
173}
174
175static const struct platform_suspend_ops mvebu_pm_ops = {
176 .enter = mvebu_pm_enter,
177 .valid = suspend_valid_only_mem,
178};
179
180int mvebu_pm_init(void (*board_pm_enter)(void __iomem *sdram_reg, u32 srcmd))
181{
182 struct device_node *np;
183 struct resource res;
184
185 if (!of_machine_is_compatible("marvell,armadaxp"))
186 return -ENODEV;
187
188 np = of_find_compatible_node(NULL, NULL,
189 "marvell,armada-xp-sdram-controller");
190 if (!np)
191 return -ENODEV;
192
193 if (of_address_to_resource(np, 0, &res)) {
194 of_node_put(np);
195 return -ENODEV;
196 }
197
198 if (!request_mem_region(res.start, resource_size(&res),
199 np->full_name)) {
200 of_node_put(np);
201 return -EBUSY;
202 }
203
204 sdram_ctrl = ioremap(res.start, resource_size(&res));
205 if (!sdram_ctrl) {
206 release_mem_region(res.start, resource_size(&res));
207 of_node_put(np);
208 return -ENOMEM;
209 }
210
211 of_node_put(np);
212
213 mvebu_board_pm_enter = board_pm_enter;
214
215 suspend_set_ops(&mvebu_pm_ops);
216
217 return 0;
218}
diff --git a/arch/arm/mach-mvebu/pmsu.c b/arch/arm/mach-mvebu/pmsu.c
index bbd8664d1bac..d8ab605a44fa 100644
--- a/arch/arm/mach-mvebu/pmsu.c
+++ b/arch/arm/mach-mvebu/pmsu.c
@@ -20,6 +20,7 @@
20 20
21#include <linux/clk.h> 21#include <linux/clk.h>
22#include <linux/cpu_pm.h> 22#include <linux/cpu_pm.h>
23#include <linux/cpufreq-dt.h>
23#include <linux/delay.h> 24#include <linux/delay.h>
24#include <linux/init.h> 25#include <linux/init.h>
25#include <linux/io.h> 26#include <linux/io.h>
@@ -39,7 +40,6 @@
39#include <asm/suspend.h> 40#include <asm/suspend.h>
40#include <asm/tlbflush.h> 41#include <asm/tlbflush.h>
41#include "common.h" 42#include "common.h"
42#include "armada-370-xp.h"
43 43
44 44
45#define PMSU_BASE_OFFSET 0x100 45#define PMSU_BASE_OFFSET 0x100
@@ -312,7 +312,7 @@ static int armada_370_xp_cpu_suspend(unsigned long deepidle)
312 return cpu_suspend(deepidle, armada_370_xp_pmsu_idle_enter); 312 return cpu_suspend(deepidle, armada_370_xp_pmsu_idle_enter);
313} 313}
314 314
315static int armada_38x_do_cpu_suspend(unsigned long deepidle) 315int armada_38x_do_cpu_suspend(unsigned long deepidle)
316{ 316{
317 unsigned long flags = 0; 317 unsigned long flags = 0;
318 318
@@ -572,6 +572,10 @@ int mvebu_pmsu_dfs_request(int cpu)
572 return 0; 572 return 0;
573} 573}
574 574
575struct cpufreq_dt_platform_data cpufreq_dt_pd = {
576 .independent_clocks = true,
577};
578
575static int __init armada_xp_pmsu_cpufreq_init(void) 579static int __init armada_xp_pmsu_cpufreq_init(void)
576{ 580{
577 struct device_node *np; 581 struct device_node *np;
@@ -644,7 +648,8 @@ static int __init armada_xp_pmsu_cpufreq_init(void)
644 } 648 }
645 } 649 }
646 650
647 platform_device_register_simple("cpufreq-dt", -1, NULL, 0); 651 platform_device_register_data(NULL, "cpufreq-dt", -1,
652 &cpufreq_dt_pd, sizeof(cpufreq_dt_pd));
648 return 0; 653 return 0;
649} 654}
650 655
diff --git a/arch/arm/mach-mvebu/pmsu.h b/arch/arm/mach-mvebu/pmsu.h
index 6b58c1fe2b0d..ea79269c2702 100644
--- a/arch/arm/mach-mvebu/pmsu.h
+++ b/arch/arm/mach-mvebu/pmsu.h
@@ -17,5 +17,8 @@ int mvebu_setup_boot_addr_wa(unsigned int crypto_eng_target,
17 phys_addr_t resume_addr_reg); 17 phys_addr_t resume_addr_reg);
18 18
19void mvebu_v7_pmsu_idle_exit(void); 19void mvebu_v7_pmsu_idle_exit(void);
20void armada_370_xp_cpu_resume(void);
20 21
22int armada_370_xp_pmsu_idle_enter(unsigned long deepidle);
23int armada_38x_do_cpu_suspend(unsigned long deepidle);
21#endif /* __MACH_370_XP_PMSU_H */ 24#endif /* __MACH_370_XP_PMSU_H */
diff --git a/arch/arm/mach-mvebu/pmsu_ll.S b/arch/arm/mach-mvebu/pmsu_ll.S
index a945756cfb45..88651221dbdd 100644
--- a/arch/arm/mach-mvebu/pmsu_ll.S
+++ b/arch/arm/mach-mvebu/pmsu_ll.S
@@ -12,12 +12,32 @@
12#include <linux/linkage.h> 12#include <linux/linkage.h>
13#include <asm/assembler.h> 13#include <asm/assembler.h>
14 14
15
16ENTRY(armada_38x_scu_power_up)
17 mrc p15, 4, r1, c15, c0 @ get SCU base address
18 orr r1, r1, #0x8 @ SCU CPU Power Status Register
19 mrc 15, 0, r0, cr0, cr0, 5 @ get the CPU ID
20 and r0, r0, #15
21 add r1, r1, r0
22 mov r0, #0x0
23 strb r0, [r1] @ switch SCU power state to Normal mode
24 ret lr
25ENDPROC(armada_38x_scu_power_up)
26
15/* 27/*
16 * This is the entry point through which CPUs exiting cpuidle deep 28 * This is the entry point through which CPUs exiting cpuidle deep
17 * idle state are going. 29 * idle state are going.
18 */ 30 */
19ENTRY(armada_370_xp_cpu_resume) 31ENTRY(armada_370_xp_cpu_resume)
20ARM_BE8(setend be ) @ go BE8 if entered LE 32ARM_BE8(setend be ) @ go BE8 if entered LE
33 /*
34 * Disable the MMU that might have been enabled in BootROM if
35 * this code is used in the resume path of a suspend/resume
36 * cycle.
37 */
38 mrc p15, 0, r1, c1, c0, 0
39 bic r1, #1
40 mcr p15, 0, r1, c1, c0, 0
21 bl ll_add_cpu_to_smp_group 41 bl ll_add_cpu_to_smp_group
22 bl ll_enable_coherency 42 bl ll_enable_coherency
23 b cpu_resume 43 b cpu_resume
@@ -27,13 +47,7 @@ ENTRY(armada_38x_cpu_resume)
27 /* do we need it for Armada 38x*/ 47 /* do we need it for Armada 38x*/
28ARM_BE8(setend be ) @ go BE8 if entered LE 48ARM_BE8(setend be ) @ go BE8 if entered LE
29 bl v7_invalidate_l1 49 bl v7_invalidate_l1
30 mrc p15, 4, r1, c15, c0 @ get SCU base address 50 bl armada_38x_scu_power_up
31 orr r1, r1, #0x8 @ SCU CPU Power Status Register
32 mrc 15, 0, r0, cr0, cr0, 5 @ get the CPU ID
33 and r0, r0, #15
34 add r1, r1, r0
35 mov r0, #0x0
36 strb r0, [r1] @ switch SCU power state to Normal mode
37 b cpu_resume 51 b cpu_resume
38ENDPROC(armada_38x_cpu_resume) 52ENDPROC(armada_38x_cpu_resume)
39 53
diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile
index d9e94122073e..3b653b3ac268 100644
--- a/arch/arm/mach-omap2/Makefile
+++ b/arch/arm/mach-omap2/Makefile
@@ -113,7 +113,7 @@ obj-y += prm_common.o cm_common.o
113obj-$(CONFIG_ARCH_OMAP2) += prm2xxx_3xxx.o prm2xxx.o cm2xxx.o 113obj-$(CONFIG_ARCH_OMAP2) += prm2xxx_3xxx.o prm2xxx.o cm2xxx.o
114obj-$(CONFIG_ARCH_OMAP3) += prm2xxx_3xxx.o prm3xxx.o cm3xxx.o 114obj-$(CONFIG_ARCH_OMAP3) += prm2xxx_3xxx.o prm3xxx.o cm3xxx.o
115obj-$(CONFIG_ARCH_OMAP3) += vc3xxx_data.o vp3xxx_data.o 115obj-$(CONFIG_ARCH_OMAP3) += vc3xxx_data.o vp3xxx_data.o
116omap-prcm-4-5-common = cminst44xx.o cm44xx.o prm44xx.o \ 116omap-prcm-4-5-common = cminst44xx.o prm44xx.o \
117 prcm_mpu44xx.o prminst44xx.o \ 117 prcm_mpu44xx.o prminst44xx.o \
118 vc44xx_data.o vp44xx_data.o 118 vc44xx_data.o vp44xx_data.o
119obj-$(CONFIG_ARCH_OMAP4) += $(omap-prcm-4-5-common) 119obj-$(CONFIG_ARCH_OMAP4) += $(omap-prcm-4-5-common)
diff --git a/arch/arm/mach-omap2/am33xx-restart.c b/arch/arm/mach-omap2/am33xx-restart.c
index c88d8df753c2..5bace6a45ffb 100644
--- a/arch/arm/mach-omap2/am33xx-restart.c
+++ b/arch/arm/mach-omap2/am33xx-restart.c
@@ -9,8 +9,7 @@
9#include <linux/reboot.h> 9#include <linux/reboot.h>
10 10
11#include "common.h" 11#include "common.h"
12#include "prm-regbits-33xx.h" 12#include "prm.h"
13#include "prm33xx.h"
14 13
15/** 14/**
16 * am3xx_restart - trigger a software restart of the SoC 15 * am3xx_restart - trigger a software restart of the SoC
@@ -24,12 +23,5 @@ void am33xx_restart(enum reboot_mode mode, const char *cmd)
24{ 23{
25 /* TODO: Handle mode and cmd if necessary */ 24 /* TODO: Handle mode and cmd if necessary */
26 25
27 am33xx_prm_rmw_reg_bits(AM33XX_RST_GLOBAL_WARM_SW_MASK, 26 omap_prm_reset_system();
28 AM33XX_RST_GLOBAL_WARM_SW_MASK,
29 AM33XX_PRM_DEVICE_MOD,
30 AM33XX_PRM_RSTCTRL_OFFSET);
31
32 /* OCP barrier */
33 (void)am33xx_prm_read_reg(AM33XX_PRM_DEVICE_MOD,
34 AM33XX_PRM_RSTCTRL_OFFSET);
35} 27}
diff --git a/arch/arm/mach-omap2/cclock3xxx_data.c b/arch/arm/mach-omap2/cclock3xxx_data.c
index eb8c75ec3b1a..5c5ebb4db5f7 100644
--- a/arch/arm/mach-omap2/cclock3xxx_data.c
+++ b/arch/arm/mach-omap2/cclock3xxx_data.c
@@ -257,6 +257,9 @@ static const struct clk_ops dpll1_ck_ops = {
257 .get_parent = &omap2_init_dpll_parent, 257 .get_parent = &omap2_init_dpll_parent,
258 .recalc_rate = &omap3_dpll_recalc, 258 .recalc_rate = &omap3_dpll_recalc,
259 .set_rate = &omap3_noncore_dpll_set_rate, 259 .set_rate = &omap3_noncore_dpll_set_rate,
260 .set_parent = &omap3_noncore_dpll_set_parent,
261 .set_rate_and_parent = &omap3_noncore_dpll_set_rate_and_parent,
262 .determine_rate = &omap3_noncore_dpll_determine_rate,
260 .round_rate = &omap2_dpll_round_rate, 263 .round_rate = &omap2_dpll_round_rate,
261}; 264};
262 265
@@ -367,6 +370,9 @@ static const struct clk_ops dpll4_ck_ops = {
367 .get_parent = &omap2_init_dpll_parent, 370 .get_parent = &omap2_init_dpll_parent,
368 .recalc_rate = &omap3_dpll_recalc, 371 .recalc_rate = &omap3_dpll_recalc,
369 .set_rate = &omap3_dpll4_set_rate, 372 .set_rate = &omap3_dpll4_set_rate,
373 .set_parent = &omap3_noncore_dpll_set_parent,
374 .set_rate_and_parent = &omap3_dpll4_set_rate_and_parent,
375 .determine_rate = &omap3_noncore_dpll_determine_rate,
370 .round_rate = &omap2_dpll_round_rate, 376 .round_rate = &omap2_dpll_round_rate,
371}; 377};
372 378
diff --git a/arch/arm/mach-omap2/clock.c b/arch/arm/mach-omap2/clock.c
index 500530d1364a..6ad5b4dbd33e 100644
--- a/arch/arm/mach-omap2/clock.c
+++ b/arch/arm/mach-omap2/clock.c
@@ -171,7 +171,8 @@ static void _omap2_module_wait_ready(struct clk_hw_omap *clk)
171 _wait_idlest_generic(clk, idlest_reg, (1 << idlest_bit), 171 _wait_idlest_generic(clk, idlest_reg, (1 << idlest_bit),
172 idlest_val, __clk_get_name(clk->hw.clk)); 172 idlest_val, __clk_get_name(clk->hw.clk));
173 } else { 173 } else {
174 cm_wait_module_ready(prcm_mod, idlest_reg_id, idlest_bit); 174 omap_cm_wait_module_ready(0, prcm_mod, idlest_reg_id,
175 idlest_bit);
175 }; 176 };
176} 177}
177 178
@@ -771,4 +772,8 @@ void __init ti_clk_init_features(void)
771 ti_clk_features.cm_idlest_val = OMAP24XX_CM_IDLEST_VAL; 772 ti_clk_features.cm_idlest_val = OMAP24XX_CM_IDLEST_VAL;
772 else if (cpu_is_omap34xx()) 773 else if (cpu_is_omap34xx())
773 ti_clk_features.cm_idlest_val = OMAP34XX_CM_IDLEST_VAL; 774 ti_clk_features.cm_idlest_val = OMAP34XX_CM_IDLEST_VAL;
775
776 /* On OMAP3430 ES1.0, DPLL4 can't be re-programmed */
777 if (omap_rev() == OMAP3430_REV_ES1_0)
778 ti_clk_features.flags |= TI_CLK_DPLL4_DENY_REPROGRAM;
774} 779}
diff --git a/arch/arm/mach-omap2/clock.h b/arch/arm/mach-omap2/clock.h
index 4592a2762592..641337c6cde9 100644
--- a/arch/arm/mach-omap2/clock.h
+++ b/arch/arm/mach-omap2/clock.h
@@ -234,6 +234,7 @@ struct ti_clk_features {
234}; 234};
235 235
236#define TI_CLK_DPLL_HAS_FREQSEL (1 << 0) 236#define TI_CLK_DPLL_HAS_FREQSEL (1 << 0)
237#define TI_CLK_DPLL4_DENY_REPROGRAM (1 << 1)
237 238
238extern struct ti_clk_features ti_clk_features; 239extern struct ti_clk_features ti_clk_features;
239 240
diff --git a/arch/arm/mach-omap2/clock3xxx.c b/arch/arm/mach-omap2/clock3xxx.c
index 0b02b4161d71..a9e86db5daf9 100644
--- a/arch/arm/mach-omap2/clock3xxx.c
+++ b/arch/arm/mach-omap2/clock3xxx.c
@@ -38,6 +38,18 @@
38 38
39/* needed by omap3_core_dpll_m2_set_rate() */ 39/* needed by omap3_core_dpll_m2_set_rate() */
40struct clk *sdrc_ick_p, *arm_fck_p; 40struct clk *sdrc_ick_p, *arm_fck_p;
41
42/**
43 * omap3_dpll4_set_rate - set rate for omap3 per-dpll
44 * @hw: clock to change
45 * @rate: target rate for clock
46 * @parent_rate: rate of the parent clock
47 *
48 * Check if the current SoC supports the per-dpll reprogram operation
49 * or not, and then do the rate change if supported. Returns -EINVAL
50 * if not supported, 0 for success, and potential error codes from the
51 * clock rate change.
52 */
41int omap3_dpll4_set_rate(struct clk_hw *hw, unsigned long rate, 53int omap3_dpll4_set_rate(struct clk_hw *hw, unsigned long rate,
42 unsigned long parent_rate) 54 unsigned long parent_rate)
43{ 55{
@@ -46,7 +58,7 @@ int omap3_dpll4_set_rate(struct clk_hw *hw, unsigned long rate,
46 * on 3430ES1 prevents us from changing DPLL multipliers or dividers 58 * on 3430ES1 prevents us from changing DPLL multipliers or dividers
47 * on DPLL4. 59 * on DPLL4.
48 */ 60 */
49 if (omap_rev() == OMAP3430_REV_ES1_0) { 61 if (ti_clk_features.flags & TI_CLK_DPLL4_DENY_REPROGRAM) {
50 pr_err("clock: DPLL4 cannot change rate due to silicon 'Limitation 2.5' on 3430ES1.\n"); 62 pr_err("clock: DPLL4 cannot change rate due to silicon 'Limitation 2.5' on 3430ES1.\n");
51 return -EINVAL; 63 return -EINVAL;
52 } 64 }
@@ -54,6 +66,30 @@ int omap3_dpll4_set_rate(struct clk_hw *hw, unsigned long rate,
54 return omap3_noncore_dpll_set_rate(hw, rate, parent_rate); 66 return omap3_noncore_dpll_set_rate(hw, rate, parent_rate);
55} 67}
56 68
69/**
70 * omap3_dpll4_set_rate_and_parent - set rate and parent for omap3 per-dpll
71 * @hw: clock to change
72 * @rate: target rate for clock
73 * @parent_rate: rate of the parent clock
74 * @index: parent index, 0 - reference clock, 1 - bypass clock
75 *
76 * Check if the current SoC support the per-dpll reprogram operation
77 * or not, and then do the rate + parent change if supported. Returns
78 * -EINVAL if not supported, 0 for success, and potential error codes
79 * from the clock rate change.
80 */
81int omap3_dpll4_set_rate_and_parent(struct clk_hw *hw, unsigned long rate,
82 unsigned long parent_rate, u8 index)
83{
84 if (ti_clk_features.flags & TI_CLK_DPLL4_DENY_REPROGRAM) {
85 pr_err("clock: DPLL4 cannot change rate due to silicon 'Limitation 2.5' on 3430ES1.\n");
86 return -EINVAL;
87 }
88
89 return omap3_noncore_dpll_set_rate_and_parent(hw, rate, parent_rate,
90 index);
91}
92
57void __init omap3_clk_lock_dpll5(void) 93void __init omap3_clk_lock_dpll5(void)
58{ 94{
59 struct clk *dpll5_clk; 95 struct clk *dpll5_clk;
diff --git a/arch/arm/mach-omap2/cm.h b/arch/arm/mach-omap2/cm.h
index 93473f9a551c..6222e87a79b6 100644
--- a/arch/arm/mach-omap2/cm.h
+++ b/arch/arm/mach-omap2/cm.h
@@ -45,17 +45,29 @@ extern void omap2_set_globals_cm(void __iomem *cm, void __iomem *cm2);
45 * struct cm_ll_data - fn ptrs to per-SoC CM function implementations 45 * struct cm_ll_data - fn ptrs to per-SoC CM function implementations
46 * @split_idlest_reg: ptr to the SoC CM-specific split_idlest_reg impl 46 * @split_idlest_reg: ptr to the SoC CM-specific split_idlest_reg impl
47 * @wait_module_ready: ptr to the SoC CM-specific wait_module_ready impl 47 * @wait_module_ready: ptr to the SoC CM-specific wait_module_ready impl
48 * @wait_module_idle: ptr to the SoC CM-specific wait_module_idle impl
49 * @module_enable: ptr to the SoC CM-specific module_enable impl
50 * @module_disable: ptr to the SoC CM-specific module_disable impl
48 */ 51 */
49struct cm_ll_data { 52struct cm_ll_data {
50 int (*split_idlest_reg)(void __iomem *idlest_reg, s16 *prcm_inst, 53 int (*split_idlest_reg)(void __iomem *idlest_reg, s16 *prcm_inst,
51 u8 *idlest_reg_id); 54 u8 *idlest_reg_id);
52 int (*wait_module_ready)(s16 prcm_mod, u8 idlest_id, u8 idlest_shift); 55 int (*wait_module_ready)(u8 part, s16 prcm_mod, u16 idlest_reg,
56 u8 idlest_shift);
57 int (*wait_module_idle)(u8 part, s16 prcm_mod, u16 idlest_reg,
58 u8 idlest_shift);
59 void (*module_enable)(u8 mode, u8 part, u16 inst, u16 clkctrl_offs);
60 void (*module_disable)(u8 part, u16 inst, u16 clkctrl_offs);
53}; 61};
54 62
55extern int cm_split_idlest_reg(void __iomem *idlest_reg, s16 *prcm_inst, 63extern int cm_split_idlest_reg(void __iomem *idlest_reg, s16 *prcm_inst,
56 u8 *idlest_reg_id); 64 u8 *idlest_reg_id);
57extern int cm_wait_module_ready(s16 prcm_mod, u8 idlest_id, u8 idlest_shift); 65int omap_cm_wait_module_ready(u8 part, s16 prcm_mod, u16 idlest_reg,
58 66 u8 idlest_shift);
67int omap_cm_wait_module_idle(u8 part, s16 prcm_mod, u16 idlest_reg,
68 u8 idlest_shift);
69int omap_cm_module_enable(u8 mode, u8 part, u16 inst, u16 clkctrl_offs);
70int omap_cm_module_disable(u8 part, u16 inst, u16 clkctrl_offs);
59extern int cm_register(struct cm_ll_data *cld); 71extern int cm_register(struct cm_ll_data *cld);
60extern int cm_unregister(struct cm_ll_data *cld); 72extern int cm_unregister(struct cm_ll_data *cld);
61 73
diff --git a/arch/arm/mach-omap2/cm1_44xx.h b/arch/arm/mach-omap2/cm1_44xx.h
index 5ae8fe39d6ee..a5949927b661 100644
--- a/arch/arm/mach-omap2/cm1_44xx.h
+++ b/arch/arm/mach-omap2/cm1_44xx.h
@@ -25,8 +25,6 @@
25#ifndef __ARCH_ARM_MACH_OMAP2_CM1_44XX_H 25#ifndef __ARCH_ARM_MACH_OMAP2_CM1_44XX_H
26#define __ARCH_ARM_MACH_OMAP2_CM1_44XX_H 26#define __ARCH_ARM_MACH_OMAP2_CM1_44XX_H
27 27
28#include "cm_44xx_54xx.h"
29
30/* CM1 base address */ 28/* CM1 base address */
31#define OMAP4430_CM1_BASE 0x4a004000 29#define OMAP4430_CM1_BASE 0x4a004000
32 30
diff --git a/arch/arm/mach-omap2/cm1_54xx.h b/arch/arm/mach-omap2/cm1_54xx.h
index 90b3348e6672..fd245dfa7391 100644
--- a/arch/arm/mach-omap2/cm1_54xx.h
+++ b/arch/arm/mach-omap2/cm1_54xx.h
@@ -22,8 +22,6 @@
22#ifndef __ARCH_ARM_MACH_OMAP2_CM1_54XX_H 22#ifndef __ARCH_ARM_MACH_OMAP2_CM1_54XX_H
23#define __ARCH_ARM_MACH_OMAP2_CM1_54XX_H 23#define __ARCH_ARM_MACH_OMAP2_CM1_54XX_H
24 24
25#include "cm_44xx_54xx.h"
26
27/* CM1 base address */ 25/* CM1 base address */
28#define OMAP54XX_CM_CORE_AON_BASE 0x4a004000 26#define OMAP54XX_CM_CORE_AON_BASE 0x4a004000
29 27
diff --git a/arch/arm/mach-omap2/cm1_7xx.h b/arch/arm/mach-omap2/cm1_7xx.h
index ca6fa1febaac..2f1c09eea021 100644
--- a/arch/arm/mach-omap2/cm1_7xx.h
+++ b/arch/arm/mach-omap2/cm1_7xx.h
@@ -23,8 +23,6 @@
23#ifndef __ARCH_ARM_MACH_OMAP2_CM1_7XX_H 23#ifndef __ARCH_ARM_MACH_OMAP2_CM1_7XX_H
24#define __ARCH_ARM_MACH_OMAP2_CM1_7XX_H 24#define __ARCH_ARM_MACH_OMAP2_CM1_7XX_H
25 25
26#include "cm_44xx_54xx.h"
27
28/* CM1 base address */ 26/* CM1 base address */
29#define DRA7XX_CM_CORE_AON_BASE 0x4a005000 27#define DRA7XX_CM_CORE_AON_BASE 0x4a005000
30 28
diff --git a/arch/arm/mach-omap2/cm2_44xx.h b/arch/arm/mach-omap2/cm2_44xx.h
index ee5136d7cdda..7521abf3d830 100644
--- a/arch/arm/mach-omap2/cm2_44xx.h
+++ b/arch/arm/mach-omap2/cm2_44xx.h
@@ -25,8 +25,6 @@
25#ifndef __ARCH_ARM_MACH_OMAP2_CM2_44XX_H 25#ifndef __ARCH_ARM_MACH_OMAP2_CM2_44XX_H
26#define __ARCH_ARM_MACH_OMAP2_CM2_44XX_H 26#define __ARCH_ARM_MACH_OMAP2_CM2_44XX_H
27 27
28#include "cm_44xx_54xx.h"
29
30/* CM2 base address */ 28/* CM2 base address */
31#define OMAP4430_CM2_BASE 0x4a008000 29#define OMAP4430_CM2_BASE 0x4a008000
32 30
diff --git a/arch/arm/mach-omap2/cm2_54xx.h b/arch/arm/mach-omap2/cm2_54xx.h
index 2683231b299b..ff4040c196d8 100644
--- a/arch/arm/mach-omap2/cm2_54xx.h
+++ b/arch/arm/mach-omap2/cm2_54xx.h
@@ -21,8 +21,6 @@
21#ifndef __ARCH_ARM_MACH_OMAP2_CM2_54XX_H 21#ifndef __ARCH_ARM_MACH_OMAP2_CM2_54XX_H
22#define __ARCH_ARM_MACH_OMAP2_CM2_54XX_H 22#define __ARCH_ARM_MACH_OMAP2_CM2_54XX_H
23 23
24#include "cm_44xx_54xx.h"
25
26/* CM2 base address */ 24/* CM2 base address */
27#define OMAP54XX_CM_CORE_BASE 0x4a008000 25#define OMAP54XX_CM_CORE_BASE 0x4a008000
28 26
diff --git a/arch/arm/mach-omap2/cm2_7xx.h b/arch/arm/mach-omap2/cm2_7xx.h
index e966e3a3c931..ce63fdb68056 100644
--- a/arch/arm/mach-omap2/cm2_7xx.h
+++ b/arch/arm/mach-omap2/cm2_7xx.h
@@ -22,8 +22,6 @@
22#ifndef __ARCH_ARM_MACH_OMAP2_CM2_7XX_H 22#ifndef __ARCH_ARM_MACH_OMAP2_CM2_7XX_H
23#define __ARCH_ARM_MACH_OMAP2_CM2_7XX_H 23#define __ARCH_ARM_MACH_OMAP2_CM2_7XX_H
24 24
25#include "cm_44xx_54xx.h"
26
27/* CM2 base address */ 25/* CM2 base address */
28#define DRA7XX_CM_CORE_BASE 0x4a008000 26#define DRA7XX_CM_CORE_BASE 0x4a008000
29 27
diff --git a/arch/arm/mach-omap2/cm2xxx.c b/arch/arm/mach-omap2/cm2xxx.c
index 8be6ea50c092..a96d901b1d5d 100644
--- a/arch/arm/mach-omap2/cm2xxx.c
+++ b/arch/arm/mach-omap2/cm2xxx.c
@@ -53,7 +53,7 @@ static void _write_clktrctrl(u8 c, s16 module, u32 mask)
53 omap2_cm_write_mod_reg(v, module, OMAP2_CM_CLKSTCTRL); 53 omap2_cm_write_mod_reg(v, module, OMAP2_CM_CLKSTCTRL);
54} 54}
55 55
56bool omap2xxx_cm_is_clkdm_in_hwsup(s16 module, u32 mask) 56static bool omap2xxx_cm_is_clkdm_in_hwsup(s16 module, u32 mask)
57{ 57{
58 u32 v; 58 u32 v;
59 59
@@ -64,12 +64,12 @@ bool omap2xxx_cm_is_clkdm_in_hwsup(s16 module, u32 mask)
64 return (v == OMAP24XX_CLKSTCTRL_ENABLE_AUTO) ? 1 : 0; 64 return (v == OMAP24XX_CLKSTCTRL_ENABLE_AUTO) ? 1 : 0;
65} 65}
66 66
67void omap2xxx_cm_clkdm_enable_hwsup(s16 module, u32 mask) 67static void omap2xxx_cm_clkdm_enable_hwsup(s16 module, u32 mask)
68{ 68{
69 _write_clktrctrl(OMAP24XX_CLKSTCTRL_ENABLE_AUTO, module, mask); 69 _write_clktrctrl(OMAP24XX_CLKSTCTRL_ENABLE_AUTO, module, mask);
70} 70}
71 71
72void omap2xxx_cm_clkdm_disable_hwsup(s16 module, u32 mask) 72static void omap2xxx_cm_clkdm_disable_hwsup(s16 module, u32 mask)
73{ 73{
74 _write_clktrctrl(OMAP24XX_CLKSTCTRL_DISABLE_AUTO, module, mask); 74 _write_clktrctrl(OMAP24XX_CLKSTCTRL_DISABLE_AUTO, module, mask);
75} 75}
@@ -150,7 +150,7 @@ static int _omap2xxx_apll_enable(u8 enable_bit, u8 status_bit)
150 v |= m; 150 v |= m;
151 omap2_cm_write_mod_reg(v, PLL_MOD, CM_CLKEN); 151 omap2_cm_write_mod_reg(v, PLL_MOD, CM_CLKEN);
152 152
153 omap2xxx_cm_wait_module_ready(PLL_MOD, 1, status_bit); 153 omap2xxx_cm_wait_module_ready(0, PLL_MOD, 1, status_bit);
154 154
155 /* 155 /*
156 * REVISIT: Should we return an error code if 156 * REVISIT: Should we return an error code if
@@ -204,8 +204,9 @@ void omap2xxx_cm_apll96_disable(void)
204 * XXX This function is only needed until absolute register addresses are 204 * XXX This function is only needed until absolute register addresses are
205 * removed from the OMAP struct clk records. 205 * removed from the OMAP struct clk records.
206 */ 206 */
207int omap2xxx_cm_split_idlest_reg(void __iomem *idlest_reg, s16 *prcm_inst, 207static int omap2xxx_cm_split_idlest_reg(void __iomem *idlest_reg,
208 u8 *idlest_reg_id) 208 s16 *prcm_inst,
209 u8 *idlest_reg_id)
209{ 210{
210 unsigned long offs; 211 unsigned long offs;
211 u8 idlest_offs; 212 u8 idlest_offs;
@@ -238,6 +239,7 @@ int omap2xxx_cm_split_idlest_reg(void __iomem *idlest_reg, s16 *prcm_inst,
238 239
239/** 240/**
240 * omap2xxx_cm_wait_module_ready - wait for a module to leave idle or standby 241 * omap2xxx_cm_wait_module_ready - wait for a module to leave idle or standby
242 * @part: PRCM partition, ignored for OMAP2
241 * @prcm_mod: PRCM module offset 243 * @prcm_mod: PRCM module offset
242 * @idlest_id: CM_IDLESTx register ID (i.e., x = 1, 2, 3) 244 * @idlest_id: CM_IDLESTx register ID (i.e., x = 1, 2, 3)
243 * @idlest_shift: shift of the bit in the CM_IDLEST* register to check 245 * @idlest_shift: shift of the bit in the CM_IDLEST* register to check
@@ -246,7 +248,8 @@ int omap2xxx_cm_split_idlest_reg(void __iomem *idlest_reg, s16 *prcm_inst,
246 * (@prcm_mod, @idlest_id, @idlest_shift) is clocked. Return 0 upon 248 * (@prcm_mod, @idlest_id, @idlest_shift) is clocked. Return 0 upon
247 * success or -EBUSY if the module doesn't enable in time. 249 * success or -EBUSY if the module doesn't enable in time.
248 */ 250 */
249int omap2xxx_cm_wait_module_ready(s16 prcm_mod, u8 idlest_id, u8 idlest_shift) 251int omap2xxx_cm_wait_module_ready(u8 part, s16 prcm_mod, u16 idlest_id,
252 u8 idlest_shift)
250{ 253{
251 int ena = 0, i = 0; 254 int ena = 0, i = 0;
252 u8 cm_idlest_reg; 255 u8 cm_idlest_reg;
diff --git a/arch/arm/mach-omap2/cm2xxx.h b/arch/arm/mach-omap2/cm2xxx.h
index 891d81c3c8f4..c89502b168ae 100644
--- a/arch/arm/mach-omap2/cm2xxx.h
+++ b/arch/arm/mach-omap2/cm2xxx.h
@@ -46,9 +46,6 @@
46 46
47#ifndef __ASSEMBLER__ 47#ifndef __ASSEMBLER__
48 48
49extern void omap2xxx_cm_clkdm_enable_hwsup(s16 module, u32 mask);
50extern void omap2xxx_cm_clkdm_disable_hwsup(s16 module, u32 mask);
51
52extern void omap2xxx_cm_set_dpll_disable_autoidle(void); 49extern void omap2xxx_cm_set_dpll_disable_autoidle(void);
53extern void omap2xxx_cm_set_dpll_auto_low_power_stop(void); 50extern void omap2xxx_cm_set_dpll_auto_low_power_stop(void);
54 51
@@ -57,11 +54,8 @@ extern void omap2xxx_cm_set_apll54_auto_low_power_stop(void);
57extern void omap2xxx_cm_set_apll96_disable_autoidle(void); 54extern void omap2xxx_cm_set_apll96_disable_autoidle(void);
58extern void omap2xxx_cm_set_apll96_auto_low_power_stop(void); 55extern void omap2xxx_cm_set_apll96_auto_low_power_stop(void);
59 56
60extern bool omap2xxx_cm_is_clkdm_in_hwsup(s16 module, u32 mask); 57int omap2xxx_cm_wait_module_ready(u8 part, s16 prcm_mod, u16 idlest_id,
61extern int omap2xxx_cm_wait_module_ready(s16 prcm_mod, u8 idlest_id, 58 u8 idlest_shift);
62 u8 idlest_shift);
63extern int omap2xxx_cm_split_idlest_reg(void __iomem *idlest_reg,
64 s16 *prcm_inst, u8 *idlest_reg_id);
65extern int omap2xxx_cm_fclks_active(void); 59extern int omap2xxx_cm_fclks_active(void);
66extern int omap2xxx_cm_mpu_retention_allowed(void); 60extern int omap2xxx_cm_mpu_retention_allowed(void);
67extern u32 omap2xxx_cm_get_core_clk_src(void); 61extern u32 omap2xxx_cm_get_core_clk_src(void);
diff --git a/arch/arm/mach-omap2/cm33xx.c b/arch/arm/mach-omap2/cm33xx.c
index b3f99e93def0..b9ad463a368a 100644
--- a/arch/arm/mach-omap2/cm33xx.c
+++ b/arch/arm/mach-omap2/cm33xx.c
@@ -96,13 +96,12 @@ static inline u32 am33xx_cm_read_reg_bits(u16 inst, s16 idx, u32 mask)
96/** 96/**
97 * _clkctrl_idlest - read a CM_*_CLKCTRL register; mask & shift IDLEST bitfield 97 * _clkctrl_idlest - read a CM_*_CLKCTRL register; mask & shift IDLEST bitfield
98 * @inst: CM instance register offset (*_INST macro) 98 * @inst: CM instance register offset (*_INST macro)
99 * @cdoffs: Clockdomain register offset (*_CDOFFS macro)
100 * @clkctrl_offs: Module clock control register offset (*_CLKCTRL macro) 99 * @clkctrl_offs: Module clock control register offset (*_CLKCTRL macro)
101 * 100 *
102 * Return the IDLEST bitfield of a CM_*_CLKCTRL register, shifted down to 101 * Return the IDLEST bitfield of a CM_*_CLKCTRL register, shifted down to
103 * bit 0. 102 * bit 0.
104 */ 103 */
105static u32 _clkctrl_idlest(u16 inst, s16 cdoffs, u16 clkctrl_offs) 104static u32 _clkctrl_idlest(u16 inst, u16 clkctrl_offs)
106{ 105{
107 u32 v = am33xx_cm_read_reg(inst, clkctrl_offs); 106 u32 v = am33xx_cm_read_reg(inst, clkctrl_offs);
108 v &= AM33XX_IDLEST_MASK; 107 v &= AM33XX_IDLEST_MASK;
@@ -113,17 +112,16 @@ static u32 _clkctrl_idlest(u16 inst, s16 cdoffs, u16 clkctrl_offs)
113/** 112/**
114 * _is_module_ready - can module registers be accessed without causing an abort? 113 * _is_module_ready - can module registers be accessed without causing an abort?
115 * @inst: CM instance register offset (*_INST macro) 114 * @inst: CM instance register offset (*_INST macro)
116 * @cdoffs: Clockdomain register offset (*_CDOFFS macro)
117 * @clkctrl_offs: Module clock control register offset (*_CLKCTRL macro) 115 * @clkctrl_offs: Module clock control register offset (*_CLKCTRL macro)
118 * 116 *
119 * Returns true if the module's CM_*_CLKCTRL.IDLEST bitfield is either 117 * Returns true if the module's CM_*_CLKCTRL.IDLEST bitfield is either
120 * *FUNCTIONAL or *INTERFACE_IDLE; false otherwise. 118 * *FUNCTIONAL or *INTERFACE_IDLE; false otherwise.
121 */ 119 */
122static bool _is_module_ready(u16 inst, s16 cdoffs, u16 clkctrl_offs) 120static bool _is_module_ready(u16 inst, u16 clkctrl_offs)
123{ 121{
124 u32 v; 122 u32 v;
125 123
126 v = _clkctrl_idlest(inst, cdoffs, clkctrl_offs); 124 v = _clkctrl_idlest(inst, clkctrl_offs);
127 125
128 return (v == CLKCTRL_IDLEST_FUNCTIONAL || 126 return (v == CLKCTRL_IDLEST_FUNCTIONAL ||
129 v == CLKCTRL_IDLEST_INTERFACE_IDLE) ? true : false; 127 v == CLKCTRL_IDLEST_INTERFACE_IDLE) ? true : false;
@@ -158,7 +156,7 @@ static void _clktrctrl_write(u8 c, u16 inst, u16 cdoffs)
158 * Returns true if the clockdomain referred to by (@inst, @cdoffs) 156 * Returns true if the clockdomain referred to by (@inst, @cdoffs)
159 * is in hardware-supervised idle mode, or 0 otherwise. 157 * is in hardware-supervised idle mode, or 0 otherwise.
160 */ 158 */
161bool am33xx_cm_is_clkdm_in_hwsup(u16 inst, u16 cdoffs) 159static bool am33xx_cm_is_clkdm_in_hwsup(u16 inst, u16 cdoffs)
162{ 160{
163 u32 v; 161 u32 v;
164 162
@@ -177,7 +175,7 @@ bool am33xx_cm_is_clkdm_in_hwsup(u16 inst, u16 cdoffs)
177 * Put a clockdomain referred to by (@inst, @cdoffs) into 175 * Put a clockdomain referred to by (@inst, @cdoffs) into
178 * hardware-supervised idle mode. No return value. 176 * hardware-supervised idle mode. No return value.
179 */ 177 */
180void am33xx_cm_clkdm_enable_hwsup(u16 inst, u16 cdoffs) 178static void am33xx_cm_clkdm_enable_hwsup(u16 inst, u16 cdoffs)
181{ 179{
182 _clktrctrl_write(OMAP34XX_CLKSTCTRL_ENABLE_AUTO, inst, cdoffs); 180 _clktrctrl_write(OMAP34XX_CLKSTCTRL_ENABLE_AUTO, inst, cdoffs);
183} 181}
@@ -191,7 +189,7 @@ void am33xx_cm_clkdm_enable_hwsup(u16 inst, u16 cdoffs)
191 * software-supervised idle mode, i.e., controlled manually by the 189 * software-supervised idle mode, i.e., controlled manually by the
192 * Linux OMAP clockdomain code. No return value. 190 * Linux OMAP clockdomain code. No return value.
193 */ 191 */
194void am33xx_cm_clkdm_disable_hwsup(u16 inst, u16 cdoffs) 192static void am33xx_cm_clkdm_disable_hwsup(u16 inst, u16 cdoffs)
195{ 193{
196 _clktrctrl_write(OMAP34XX_CLKSTCTRL_DISABLE_AUTO, inst, cdoffs); 194 _clktrctrl_write(OMAP34XX_CLKSTCTRL_DISABLE_AUTO, inst, cdoffs);
197} 195}
@@ -204,7 +202,7 @@ void am33xx_cm_clkdm_disable_hwsup(u16 inst, u16 cdoffs)
204 * Put a clockdomain referred to by (@inst, @cdoffs) into idle 202 * Put a clockdomain referred to by (@inst, @cdoffs) into idle
205 * No return value. 203 * No return value.
206 */ 204 */
207void am33xx_cm_clkdm_force_sleep(u16 inst, u16 cdoffs) 205static void am33xx_cm_clkdm_force_sleep(u16 inst, u16 cdoffs)
208{ 206{
209 _clktrctrl_write(OMAP34XX_CLKSTCTRL_FORCE_SLEEP, inst, cdoffs); 207 _clktrctrl_write(OMAP34XX_CLKSTCTRL_FORCE_SLEEP, inst, cdoffs);
210} 208}
@@ -217,7 +215,7 @@ void am33xx_cm_clkdm_force_sleep(u16 inst, u16 cdoffs)
217 * Take a clockdomain referred to by (@inst, @cdoffs) out of idle, 215 * Take a clockdomain referred to by (@inst, @cdoffs) out of idle,
218 * waking it up. No return value. 216 * waking it up. No return value.
219 */ 217 */
220void am33xx_cm_clkdm_force_wakeup(u16 inst, u16 cdoffs) 218static void am33xx_cm_clkdm_force_wakeup(u16 inst, u16 cdoffs)
221{ 219{
222 _clktrctrl_write(OMAP34XX_CLKSTCTRL_FORCE_WAKEUP, inst, cdoffs); 220 _clktrctrl_write(OMAP34XX_CLKSTCTRL_FORCE_WAKEUP, inst, cdoffs);
223} 221}
@@ -228,20 +226,22 @@ void am33xx_cm_clkdm_force_wakeup(u16 inst, u16 cdoffs)
228 226
229/** 227/**
230 * am33xx_cm_wait_module_ready - wait for a module to be in 'func' state 228 * am33xx_cm_wait_module_ready - wait for a module to be in 'func' state
229 * @part: PRCM partition, ignored for AM33xx
231 * @inst: CM instance register offset (*_INST macro) 230 * @inst: CM instance register offset (*_INST macro)
232 * @cdoffs: Clockdomain register offset (*_CDOFFS macro)
233 * @clkctrl_offs: Module clock control register offset (*_CLKCTRL macro) 231 * @clkctrl_offs: Module clock control register offset (*_CLKCTRL macro)
232 * @bit_shift: bit shift for the register, ignored for AM33xx
234 * 233 *
235 * Wait for the module IDLEST to be functional. If the idle state is in any 234 * Wait for the module IDLEST to be functional. If the idle state is in any
236 * the non functional state (trans, idle or disabled), module and thus the 235 * the non functional state (trans, idle or disabled), module and thus the
237 * sysconfig cannot be accessed and will probably lead to an "imprecise 236 * sysconfig cannot be accessed and will probably lead to an "imprecise
238 * external abort" 237 * external abort"
239 */ 238 */
240int am33xx_cm_wait_module_ready(u16 inst, s16 cdoffs, u16 clkctrl_offs) 239static int am33xx_cm_wait_module_ready(u8 part, s16 inst, u16 clkctrl_offs,
240 u8 bit_shift)
241{ 241{
242 int i = 0; 242 int i = 0;
243 243
244 omap_test_timeout(_is_module_ready(inst, cdoffs, clkctrl_offs), 244 omap_test_timeout(_is_module_ready(inst, clkctrl_offs),
245 MAX_MODULE_READY_TIME, i); 245 MAX_MODULE_READY_TIME, i);
246 246
247 return (i < MAX_MODULE_READY_TIME) ? 0 : -EBUSY; 247 return (i < MAX_MODULE_READY_TIME) ? 0 : -EBUSY;
@@ -250,22 +250,24 @@ int am33xx_cm_wait_module_ready(u16 inst, s16 cdoffs, u16 clkctrl_offs)
250/** 250/**
251 * am33xx_cm_wait_module_idle - wait for a module to be in 'disabled' 251 * am33xx_cm_wait_module_idle - wait for a module to be in 'disabled'
252 * state 252 * state
253 * @part: CM partition, ignored for AM33xx
253 * @inst: CM instance register offset (*_INST macro) 254 * @inst: CM instance register offset (*_INST macro)
254 * @cdoffs: Clockdomain register offset (*_CDOFFS macro)
255 * @clkctrl_offs: Module clock control register offset (*_CLKCTRL macro) 255 * @clkctrl_offs: Module clock control register offset (*_CLKCTRL macro)
256 * @bit_shift: bit shift for the register, ignored for AM33xx
256 * 257 *
257 * Wait for the module IDLEST to be disabled. Some PRCM transition, 258 * Wait for the module IDLEST to be disabled. Some PRCM transition,
258 * like reset assertion or parent clock de-activation must wait the 259 * like reset assertion or parent clock de-activation must wait the
259 * module to be fully disabled. 260 * module to be fully disabled.
260 */ 261 */
261int am33xx_cm_wait_module_idle(u16 inst, s16 cdoffs, u16 clkctrl_offs) 262static int am33xx_cm_wait_module_idle(u8 part, s16 inst, u16 clkctrl_offs,
263 u8 bit_shift)
262{ 264{
263 int i = 0; 265 int i = 0;
264 266
265 if (!clkctrl_offs) 267 if (!clkctrl_offs)
266 return 0; 268 return 0;
267 269
268 omap_test_timeout((_clkctrl_idlest(inst, cdoffs, clkctrl_offs) == 270 omap_test_timeout((_clkctrl_idlest(inst, clkctrl_offs) ==
269 CLKCTRL_IDLEST_DISABLED), 271 CLKCTRL_IDLEST_DISABLED),
270 MAX_MODULE_READY_TIME, i); 272 MAX_MODULE_READY_TIME, i);
271 273
@@ -275,13 +277,14 @@ int am33xx_cm_wait_module_idle(u16 inst, s16 cdoffs, u16 clkctrl_offs)
275/** 277/**
276 * am33xx_cm_module_enable - Enable the modulemode inside CLKCTRL 278 * am33xx_cm_module_enable - Enable the modulemode inside CLKCTRL
277 * @mode: Module mode (SW or HW) 279 * @mode: Module mode (SW or HW)
280 * @part: CM partition, ignored for AM33xx
278 * @inst: CM instance register offset (*_INST macro) 281 * @inst: CM instance register offset (*_INST macro)
279 * @cdoffs: Clockdomain register offset (*_CDOFFS macro)
280 * @clkctrl_offs: Module clock control register offset (*_CLKCTRL macro) 282 * @clkctrl_offs: Module clock control register offset (*_CLKCTRL macro)
281 * 283 *
282 * No return value. 284 * No return value.
283 */ 285 */
284void am33xx_cm_module_enable(u8 mode, u16 inst, s16 cdoffs, u16 clkctrl_offs) 286static void am33xx_cm_module_enable(u8 mode, u8 part, u16 inst,
287 u16 clkctrl_offs)
285{ 288{
286 u32 v; 289 u32 v;
287 290
@@ -293,13 +296,13 @@ void am33xx_cm_module_enable(u8 mode, u16 inst, s16 cdoffs, u16 clkctrl_offs)
293 296
294/** 297/**
295 * am33xx_cm_module_disable - Disable the module inside CLKCTRL 298 * am33xx_cm_module_disable - Disable the module inside CLKCTRL
299 * @part: CM partition, ignored for AM33xx
296 * @inst: CM instance register offset (*_INST macro) 300 * @inst: CM instance register offset (*_INST macro)
297 * @cdoffs: Clockdomain register offset (*_CDOFFS macro)
298 * @clkctrl_offs: Module clock control register offset (*_CLKCTRL macro) 301 * @clkctrl_offs: Module clock control register offset (*_CLKCTRL macro)
299 * 302 *
300 * No return value. 303 * No return value.
301 */ 304 */
302void am33xx_cm_module_disable(u16 inst, s16 cdoffs, u16 clkctrl_offs) 305static void am33xx_cm_module_disable(u8 part, u16 inst, u16 clkctrl_offs)
303{ 306{
304 u32 v; 307 u32 v;
305 308
@@ -362,3 +365,21 @@ struct clkdm_ops am33xx_clkdm_operations = {
362 .clkdm_clk_enable = am33xx_clkdm_clk_enable, 365 .clkdm_clk_enable = am33xx_clkdm_clk_enable,
363 .clkdm_clk_disable = am33xx_clkdm_clk_disable, 366 .clkdm_clk_disable = am33xx_clkdm_clk_disable,
364}; 367};
368
369static struct cm_ll_data am33xx_cm_ll_data = {
370 .wait_module_ready = &am33xx_cm_wait_module_ready,
371 .wait_module_idle = &am33xx_cm_wait_module_idle,
372 .module_enable = &am33xx_cm_module_enable,
373 .module_disable = &am33xx_cm_module_disable,
374};
375
376int __init am33xx_cm_init(void)
377{
378 return cm_register(&am33xx_cm_ll_data);
379}
380
381static void __exit am33xx_cm_exit(void)
382{
383 cm_unregister(&am33xx_cm_ll_data);
384}
385__exitcall(am33xx_cm_exit);
diff --git a/arch/arm/mach-omap2/cm33xx.h b/arch/arm/mach-omap2/cm33xx.h
index bd2441790779..046b4b2bc9d9 100644
--- a/arch/arm/mach-omap2/cm33xx.h
+++ b/arch/arm/mach-omap2/cm33xx.h
@@ -374,41 +374,6 @@
374 374
375 375
376#ifndef __ASSEMBLER__ 376#ifndef __ASSEMBLER__
377bool am33xx_cm_is_clkdm_in_hwsup(u16 inst, u16 cdoffs); 377int am33xx_cm_init(void);
378void am33xx_cm_clkdm_enable_hwsup(u16 inst, u16 cdoffs);
379void am33xx_cm_clkdm_disable_hwsup(u16 inst, u16 cdoffs);
380void am33xx_cm_clkdm_force_sleep(u16 inst, u16 cdoffs);
381void am33xx_cm_clkdm_force_wakeup(u16 inst, u16 cdoffs);
382
383#if defined(CONFIG_SOC_AM33XX) || defined(CONFIG_SOC_AM43XX)
384extern int am33xx_cm_wait_module_idle(u16 inst, s16 cdoffs,
385 u16 clkctrl_offs);
386extern void am33xx_cm_module_enable(u8 mode, u16 inst, s16 cdoffs,
387 u16 clkctrl_offs);
388extern void am33xx_cm_module_disable(u16 inst, s16 cdoffs,
389 u16 clkctrl_offs);
390extern int am33xx_cm_wait_module_ready(u16 inst, s16 cdoffs,
391 u16 clkctrl_offs);
392#else
393static inline int am33xx_cm_wait_module_idle(u16 inst, s16 cdoffs,
394 u16 clkctrl_offs)
395{
396 return 0;
397}
398static inline void am33xx_cm_module_enable(u8 mode, u16 inst, s16 cdoffs,
399 u16 clkctrl_offs)
400{
401}
402static inline void am33xx_cm_module_disable(u16 inst, s16 cdoffs,
403 u16 clkctrl_offs)
404{
405}
406static inline int am33xx_cm_wait_module_ready(u16 inst, s16 cdoffs,
407 u16 clkctrl_offs)
408{
409 return 0;
410}
411#endif
412
413#endif /* ASSEMBLER */ 378#endif /* ASSEMBLER */
414#endif 379#endif
diff --git a/arch/arm/mach-omap2/cm3xxx.c b/arch/arm/mach-omap2/cm3xxx.c
index 129a4e7f6ef5..ebead8f035f9 100644
--- a/arch/arm/mach-omap2/cm3xxx.c
+++ b/arch/arm/mach-omap2/cm3xxx.c
@@ -42,7 +42,7 @@ static void _write_clktrctrl(u8 c, s16 module, u32 mask)
42 omap2_cm_write_mod_reg(v, module, OMAP2_CM_CLKSTCTRL); 42 omap2_cm_write_mod_reg(v, module, OMAP2_CM_CLKSTCTRL);
43} 43}
44 44
45bool omap3xxx_cm_is_clkdm_in_hwsup(s16 module, u32 mask) 45static bool omap3xxx_cm_is_clkdm_in_hwsup(s16 module, u32 mask)
46{ 46{
47 u32 v; 47 u32 v;
48 48
@@ -53,22 +53,22 @@ bool omap3xxx_cm_is_clkdm_in_hwsup(s16 module, u32 mask)
53 return (v == OMAP34XX_CLKSTCTRL_ENABLE_AUTO) ? 1 : 0; 53 return (v == OMAP34XX_CLKSTCTRL_ENABLE_AUTO) ? 1 : 0;
54} 54}
55 55
56void omap3xxx_cm_clkdm_enable_hwsup(s16 module, u32 mask) 56static void omap3xxx_cm_clkdm_enable_hwsup(s16 module, u32 mask)
57{ 57{
58 _write_clktrctrl(OMAP34XX_CLKSTCTRL_ENABLE_AUTO, module, mask); 58 _write_clktrctrl(OMAP34XX_CLKSTCTRL_ENABLE_AUTO, module, mask);
59} 59}
60 60
61void omap3xxx_cm_clkdm_disable_hwsup(s16 module, u32 mask) 61static void omap3xxx_cm_clkdm_disable_hwsup(s16 module, u32 mask)
62{ 62{
63 _write_clktrctrl(OMAP34XX_CLKSTCTRL_DISABLE_AUTO, module, mask); 63 _write_clktrctrl(OMAP34XX_CLKSTCTRL_DISABLE_AUTO, module, mask);
64} 64}
65 65
66void omap3xxx_cm_clkdm_force_sleep(s16 module, u32 mask) 66static void omap3xxx_cm_clkdm_force_sleep(s16 module, u32 mask)
67{ 67{
68 _write_clktrctrl(OMAP34XX_CLKSTCTRL_FORCE_SLEEP, module, mask); 68 _write_clktrctrl(OMAP34XX_CLKSTCTRL_FORCE_SLEEP, module, mask);
69} 69}
70 70
71void omap3xxx_cm_clkdm_force_wakeup(s16 module, u32 mask) 71static void omap3xxx_cm_clkdm_force_wakeup(s16 module, u32 mask)
72{ 72{
73 _write_clktrctrl(OMAP34XX_CLKSTCTRL_FORCE_WAKEUP, module, mask); 73 _write_clktrctrl(OMAP34XX_CLKSTCTRL_FORCE_WAKEUP, module, mask);
74} 74}
@@ -79,6 +79,7 @@ void omap3xxx_cm_clkdm_force_wakeup(s16 module, u32 mask)
79 79
80/** 80/**
81 * omap3xxx_cm_wait_module_ready - wait for a module to leave idle or standby 81 * omap3xxx_cm_wait_module_ready - wait for a module to leave idle or standby
82 * @part: PRCM partition, ignored for OMAP3
82 * @prcm_mod: PRCM module offset 83 * @prcm_mod: PRCM module offset
83 * @idlest_id: CM_IDLESTx register ID (i.e., x = 1, 2, 3) 84 * @idlest_id: CM_IDLESTx register ID (i.e., x = 1, 2, 3)
84 * @idlest_shift: shift of the bit in the CM_IDLEST* register to check 85 * @idlest_shift: shift of the bit in the CM_IDLEST* register to check
@@ -87,7 +88,8 @@ void omap3xxx_cm_clkdm_force_wakeup(s16 module, u32 mask)
87 * (@prcm_mod, @idlest_id, @idlest_shift) is clocked. Return 0 upon 88 * (@prcm_mod, @idlest_id, @idlest_shift) is clocked. Return 0 upon
88 * success or -EBUSY if the module doesn't enable in time. 89 * success or -EBUSY if the module doesn't enable in time.
89 */ 90 */
90int omap3xxx_cm_wait_module_ready(s16 prcm_mod, u8 idlest_id, u8 idlest_shift) 91static int omap3xxx_cm_wait_module_ready(u8 part, s16 prcm_mod, u16 idlest_id,
92 u8 idlest_shift)
91{ 93{
92 int ena = 0, i = 0; 94 int ena = 0, i = 0;
93 u8 cm_idlest_reg; 95 u8 cm_idlest_reg;
@@ -116,8 +118,9 @@ int omap3xxx_cm_wait_module_ready(s16 prcm_mod, u8 idlest_id, u8 idlest_shift)
116 * XXX This function is only needed until absolute register addresses are 118 * XXX This function is only needed until absolute register addresses are
117 * removed from the OMAP struct clk records. 119 * removed from the OMAP struct clk records.
118 */ 120 */
119int omap3xxx_cm_split_idlest_reg(void __iomem *idlest_reg, s16 *prcm_inst, 121static int omap3xxx_cm_split_idlest_reg(void __iomem *idlest_reg,
120 u8 *idlest_reg_id) 122 s16 *prcm_inst,
123 u8 *idlest_reg_id)
121{ 124{
122 unsigned long offs; 125 unsigned long offs;
123 u8 idlest_offs; 126 u8 idlest_offs;
diff --git a/arch/arm/mach-omap2/cm3xxx.h b/arch/arm/mach-omap2/cm3xxx.h
index 7a16b5598127..734a8581c0c4 100644
--- a/arch/arm/mach-omap2/cm3xxx.h
+++ b/arch/arm/mach-omap2/cm3xxx.h
@@ -68,18 +68,6 @@
68 68
69#ifndef __ASSEMBLER__ 69#ifndef __ASSEMBLER__
70 70
71extern void omap3xxx_cm_clkdm_enable_hwsup(s16 module, u32 mask);
72extern void omap3xxx_cm_clkdm_disable_hwsup(s16 module, u32 mask);
73extern void omap3xxx_cm_clkdm_force_sleep(s16 module, u32 mask);
74extern void omap3xxx_cm_clkdm_force_wakeup(s16 module, u32 mask);
75
76extern bool omap3xxx_cm_is_clkdm_in_hwsup(s16 module, u32 mask);
77extern int omap3xxx_cm_wait_module_ready(s16 prcm_mod, u8 idlest_id,
78 u8 idlest_shift);
79
80extern int omap3xxx_cm_split_idlest_reg(void __iomem *idlest_reg,
81 s16 *prcm_inst, u8 *idlest_reg_id);
82
83extern void omap3_cm_save_context(void); 71extern void omap3_cm_save_context(void);
84extern void omap3_cm_restore_context(void); 72extern void omap3_cm_restore_context(void);
85extern void omap3_cm_save_scratchpad_contents(u32 *ptr); 73extern void omap3_cm_save_scratchpad_contents(u32 *ptr);
diff --git a/arch/arm/mach-omap2/cm44xx.c b/arch/arm/mach-omap2/cm44xx.c
deleted file mode 100644
index fe5cc7bae489..000000000000
--- a/arch/arm/mach-omap2/cm44xx.c
+++ /dev/null
@@ -1,49 +0,0 @@
1/*
2 * OMAP4 CM1, CM2 module low-level functions
3 *
4 * Copyright (C) 2010 Nokia Corporation
5 * Paul Walmsley
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 *
11 * These functions are intended to be used only by the cminst44xx.c file.
12 * XXX Perhaps we should just move them there and make them static.
13 */
14
15#include <linux/kernel.h>
16#include <linux/types.h>
17#include <linux/errno.h>
18#include <linux/err.h>
19#include <linux/io.h>
20
21#include "cm.h"
22#include "cm1_44xx.h"
23#include "cm2_44xx.h"
24
25/* CM1 hardware module low-level functions */
26
27/* Read a register in CM1 */
28u32 omap4_cm1_read_inst_reg(s16 inst, u16 reg)
29{
30 return readl_relaxed(cm_base + inst + reg);
31}
32
33/* Write into a register in CM1 */
34void omap4_cm1_write_inst_reg(u32 val, s16 inst, u16 reg)
35{
36 writel_relaxed(val, cm_base + inst + reg);
37}
38
39/* Read a register in CM2 */
40u32 omap4_cm2_read_inst_reg(s16 inst, u16 reg)
41{
42 return readl_relaxed(cm2_base + inst + reg);
43}
44
45/* Write into a register in CM2 */
46void omap4_cm2_write_inst_reg(u32 val, s16 inst, u16 reg)
47{
48 writel_relaxed(val, cm2_base + inst + reg);
49}
diff --git a/arch/arm/mach-omap2/cm44xx.h b/arch/arm/mach-omap2/cm44xx.h
index 3380beeace6e..728d06a4af19 100644
--- a/arch/arm/mach-omap2/cm44xx.h
+++ b/arch/arm/mach-omap2/cm44xx.h
@@ -23,4 +23,7 @@
23#define OMAP4_CM_CLKSTCTRL 0x0000 23#define OMAP4_CM_CLKSTCTRL 0x0000
24#define OMAP4_CM_STATICDEP 0x0004 24#define OMAP4_CM_STATICDEP 0x0004
25 25
26void omap_cm_base_init(void);
27int omap4_cm_init(void);
28
26#endif 29#endif
diff --git a/arch/arm/mach-omap2/cm_44xx_54xx.h b/arch/arm/mach-omap2/cm_44xx_54xx.h
deleted file mode 100644
index cbb211690321..000000000000
--- a/arch/arm/mach-omap2/cm_44xx_54xx.h
+++ /dev/null
@@ -1,36 +0,0 @@
1/*
2 * OMAP44xx and OMAP54xx CM1/CM2 function prototypes
3 *
4 * Copyright (C) 2009-2013 Texas Instruments, Inc.
5 * Copyright (C) 2009-2010 Nokia Corporation
6 *
7 * Paul Walmsley (paul@pwsan.com)
8 * Rajendra Nayak (rnayak@ti.com)
9 * Benoit Cousson (b-cousson@ti.com)
10 *
11 * This file is automatically generated from the OMAP hardware databases.
12 * We respectfully ask that any modifications to this file be coordinated
13 * with the public linux-omap@vger.kernel.org mailing list and the
14 * authors above to ensure that the autogeneration scripts are kept
15 * up-to-date with the file contents.
16 *
17 * This program is free software; you can redistribute it and/or modify
18 * it under the terms of the GNU General Public License version 2 as
19 * published by the Free Software Foundation.
20 *
21 */
22
23#ifndef __ARCH_ARM_MACH_OMAP2_CM_44XX_54XX_H
24#define __ARCH_ARM_MACH_OMAP2_CM_44XX_55XX_H
25
26/* CM1 Function prototypes */
27extern u32 omap4_cm1_read_inst_reg(s16 inst, u16 idx);
28extern void omap4_cm1_write_inst_reg(u32 val, s16 inst, u16 idx);
29extern u32 omap4_cm1_rmw_inst_reg_bits(u32 mask, u32 bits, s16 inst, s16 idx);
30
31/* CM2 Function prototypes */
32extern u32 omap4_cm2_read_inst_reg(s16 inst, u16 idx);
33extern void omap4_cm2_write_inst_reg(u32 val, s16 inst, u16 idx);
34extern u32 omap4_cm2_rmw_inst_reg_bits(u32 mask, u32 bits, s16 inst, s16 idx);
35
36#endif
diff --git a/arch/arm/mach-omap2/cm_common.c b/arch/arm/mach-omap2/cm_common.c
index 8f6c4710877e..8fe02fcedc48 100644
--- a/arch/arm/mach-omap2/cm_common.c
+++ b/arch/arm/mach-omap2/cm_common.c
@@ -72,9 +72,10 @@ int cm_split_idlest_reg(void __iomem *idlest_reg, s16 *prcm_inst,
72} 72}
73 73
74/** 74/**
75 * cm_wait_module_ready - wait for a module to leave idle or standby 75 * omap_cm_wait_module_ready - wait for a module to leave idle or standby
76 * @part: PRCM partition
76 * @prcm_mod: PRCM module offset 77 * @prcm_mod: PRCM module offset
77 * @idlest_id: CM_IDLESTx register ID (i.e., x = 1, 2, 3) 78 * @idlest_reg: CM_IDLESTx register
78 * @idlest_shift: shift of the bit in the CM_IDLEST* register to check 79 * @idlest_shift: shift of the bit in the CM_IDLEST* register to check
79 * 80 *
80 * Wait for the PRCM to indicate that the module identified by 81 * Wait for the PRCM to indicate that the module identified by
@@ -83,7 +84,8 @@ int cm_split_idlest_reg(void __iomem *idlest_reg, s16 *prcm_inst,
83 * no per-SoC wait_module_ready() function pointer has been registered 84 * no per-SoC wait_module_ready() function pointer has been registered
84 * or if the idlest register is unknown on the SoC. 85 * or if the idlest register is unknown on the SoC.
85 */ 86 */
86int cm_wait_module_ready(s16 prcm_mod, u8 idlest_id, u8 idlest_shift) 87int omap_cm_wait_module_ready(u8 part, s16 prcm_mod, u16 idlest_reg,
88 u8 idlest_shift)
87{ 89{
88 if (!cm_ll_data->wait_module_ready) { 90 if (!cm_ll_data->wait_module_ready) {
89 WARN_ONCE(1, "cm: %s: no low-level function defined\n", 91 WARN_ONCE(1, "cm: %s: no low-level function defined\n",
@@ -91,7 +93,79 @@ int cm_wait_module_ready(s16 prcm_mod, u8 idlest_id, u8 idlest_shift)
91 return -EINVAL; 93 return -EINVAL;
92 } 94 }
93 95
94 return cm_ll_data->wait_module_ready(prcm_mod, idlest_id, idlest_shift); 96 return cm_ll_data->wait_module_ready(part, prcm_mod, idlest_reg,
97 idlest_shift);
98}
99
100/**
101 * omap_cm_wait_module_idle - wait for a module to enter idle or standby
102 * @part: PRCM partition
103 * @prcm_mod: PRCM module offset
104 * @idlest_reg: CM_IDLESTx register
105 * @idlest_shift: shift of the bit in the CM_IDLEST* register to check
106 *
107 * Wait for the PRCM to indicate that the module identified by
108 * (@prcm_mod, @idlest_id, @idlest_shift) is no longer clocked. Return
109 * 0 upon success, -EBUSY if the module doesn't enable in time, or
110 * -EINVAL if no per-SoC wait_module_idle() function pointer has been
111 * registered or if the idlest register is unknown on the SoC.
112 */
113int omap_cm_wait_module_idle(u8 part, s16 prcm_mod, u16 idlest_reg,
114 u8 idlest_shift)
115{
116 if (!cm_ll_data->wait_module_idle) {
117 WARN_ONCE(1, "cm: %s: no low-level function defined\n",
118 __func__);
119 return -EINVAL;
120 }
121
122 return cm_ll_data->wait_module_idle(part, prcm_mod, idlest_reg,
123 idlest_shift);
124}
125
126/**
127 * omap_cm_module_enable - enable a module
128 * @mode: target mode for the module
129 * @part: PRCM partition
130 * @inst: PRCM instance
131 * @clkctrl_offs: CM_CLKCTRL register offset for the module
132 *
133 * Enables clocks for a module identified by (@part, @inst, @clkctrl_offs)
134 * making its IO space accessible. Return 0 upon success, -EINVAL if no
135 * per-SoC module_enable() function pointer has been registered.
136 */
137int omap_cm_module_enable(u8 mode, u8 part, u16 inst, u16 clkctrl_offs)
138{
139 if (!cm_ll_data->module_enable) {
140 WARN_ONCE(1, "cm: %s: no low-level function defined\n",
141 __func__);
142 return -EINVAL;
143 }
144
145 cm_ll_data->module_enable(mode, part, inst, clkctrl_offs);
146 return 0;
147}
148
149/**
150 * omap_cm_module_disable - disable a module
151 * @part: PRCM partition
152 * @inst: PRCM instance
153 * @clkctrl_offs: CM_CLKCTRL register offset for the module
154 *
155 * Disables clocks for a module identified by (@part, @inst, @clkctrl_offs)
156 * makings its IO space inaccessible. Return 0 upon success, -EINVAL if
157 * no per-SoC module_disable() function pointer has been registered.
158 */
159int omap_cm_module_disable(u8 part, u16 inst, u16 clkctrl_offs)
160{
161 if (!cm_ll_data->module_disable) {
162 WARN_ONCE(1, "cm: %s: no low-level function defined\n",
163 __func__);
164 return -EINVAL;
165 }
166
167 cm_ll_data->module_disable(part, inst, clkctrl_offs);
168 return 0;
95} 169}
96 170
97/** 171/**
diff --git a/arch/arm/mach-omap2/cminst44xx.c b/arch/arm/mach-omap2/cminst44xx.c
index 12aca56942c0..95a8cff66aff 100644
--- a/arch/arm/mach-omap2/cminst44xx.c
+++ b/arch/arm/mach-omap2/cminst44xx.c
@@ -26,7 +26,6 @@
26#include "cm1_44xx.h" 26#include "cm1_44xx.h"
27#include "cm2_44xx.h" 27#include "cm2_44xx.h"
28#include "cm44xx.h" 28#include "cm44xx.h"
29#include "cminst44xx.h"
30#include "cm-regbits-34xx.h" 29#include "cm-regbits-34xx.h"
31#include "prcm44xx.h" 30#include "prcm44xx.h"
32#include "prm44xx.h" 31#include "prm44xx.h"
@@ -74,17 +73,18 @@ void omap_cm_base_init(void)
74 73
75/* Private functions */ 74/* Private functions */
76 75
76static u32 omap4_cminst_read_inst_reg(u8 part, u16 inst, u16 idx);
77
77/** 78/**
78 * _clkctrl_idlest - read a CM_*_CLKCTRL register; mask & shift IDLEST bitfield 79 * _clkctrl_idlest - read a CM_*_CLKCTRL register; mask & shift IDLEST bitfield
79 * @part: PRCM partition ID that the CM_CLKCTRL register exists in 80 * @part: PRCM partition ID that the CM_CLKCTRL register exists in
80 * @inst: CM instance register offset (*_INST macro) 81 * @inst: CM instance register offset (*_INST macro)
81 * @cdoffs: Clockdomain register offset (*_CDOFFS macro)
82 * @clkctrl_offs: Module clock control register offset (*_CLKCTRL macro) 82 * @clkctrl_offs: Module clock control register offset (*_CLKCTRL macro)
83 * 83 *
84 * Return the IDLEST bitfield of a CM_*_CLKCTRL register, shifted down to 84 * Return the IDLEST bitfield of a CM_*_CLKCTRL register, shifted down to
85 * bit 0. 85 * bit 0.
86 */ 86 */
87static u32 _clkctrl_idlest(u8 part, u16 inst, s16 cdoffs, u16 clkctrl_offs) 87static u32 _clkctrl_idlest(u8 part, u16 inst, u16 clkctrl_offs)
88{ 88{
89 u32 v = omap4_cminst_read_inst_reg(part, inst, clkctrl_offs); 89 u32 v = omap4_cminst_read_inst_reg(part, inst, clkctrl_offs);
90 v &= OMAP4430_IDLEST_MASK; 90 v &= OMAP4430_IDLEST_MASK;
@@ -96,26 +96,23 @@ static u32 _clkctrl_idlest(u8 part, u16 inst, s16 cdoffs, u16 clkctrl_offs)
96 * _is_module_ready - can module registers be accessed without causing an abort? 96 * _is_module_ready - can module registers be accessed without causing an abort?
97 * @part: PRCM partition ID that the CM_CLKCTRL register exists in 97 * @part: PRCM partition ID that the CM_CLKCTRL register exists in
98 * @inst: CM instance register offset (*_INST macro) 98 * @inst: CM instance register offset (*_INST macro)
99 * @cdoffs: Clockdomain register offset (*_CDOFFS macro)
100 * @clkctrl_offs: Module clock control register offset (*_CLKCTRL macro) 99 * @clkctrl_offs: Module clock control register offset (*_CLKCTRL macro)
101 * 100 *
102 * Returns true if the module's CM_*_CLKCTRL.IDLEST bitfield is either 101 * Returns true if the module's CM_*_CLKCTRL.IDLEST bitfield is either
103 * *FUNCTIONAL or *INTERFACE_IDLE; false otherwise. 102 * *FUNCTIONAL or *INTERFACE_IDLE; false otherwise.
104 */ 103 */
105static bool _is_module_ready(u8 part, u16 inst, s16 cdoffs, u16 clkctrl_offs) 104static bool _is_module_ready(u8 part, u16 inst, u16 clkctrl_offs)
106{ 105{
107 u32 v; 106 u32 v;
108 107
109 v = _clkctrl_idlest(part, inst, cdoffs, clkctrl_offs); 108 v = _clkctrl_idlest(part, inst, clkctrl_offs);
110 109
111 return (v == CLKCTRL_IDLEST_FUNCTIONAL || 110 return (v == CLKCTRL_IDLEST_FUNCTIONAL ||
112 v == CLKCTRL_IDLEST_INTERFACE_IDLE) ? true : false; 111 v == CLKCTRL_IDLEST_INTERFACE_IDLE) ? true : false;
113} 112}
114 113
115/* Public functions */
116
117/* Read a register in a CM instance */ 114/* Read a register in a CM instance */
118u32 omap4_cminst_read_inst_reg(u8 part, u16 inst, u16 idx) 115static u32 omap4_cminst_read_inst_reg(u8 part, u16 inst, u16 idx)
119{ 116{
120 BUG_ON(part >= OMAP4_MAX_PRCM_PARTITIONS || 117 BUG_ON(part >= OMAP4_MAX_PRCM_PARTITIONS ||
121 part == OMAP4430_INVALID_PRCM_PARTITION || 118 part == OMAP4430_INVALID_PRCM_PARTITION ||
@@ -124,7 +121,7 @@ u32 omap4_cminst_read_inst_reg(u8 part, u16 inst, u16 idx)
124} 121}
125 122
126/* Write into a register in a CM instance */ 123/* Write into a register in a CM instance */
127void omap4_cminst_write_inst_reg(u32 val, u8 part, u16 inst, u16 idx) 124static void omap4_cminst_write_inst_reg(u32 val, u8 part, u16 inst, u16 idx)
128{ 125{
129 BUG_ON(part >= OMAP4_MAX_PRCM_PARTITIONS || 126 BUG_ON(part >= OMAP4_MAX_PRCM_PARTITIONS ||
130 part == OMAP4430_INVALID_PRCM_PARTITION || 127 part == OMAP4430_INVALID_PRCM_PARTITION ||
@@ -133,8 +130,8 @@ void omap4_cminst_write_inst_reg(u32 val, u8 part, u16 inst, u16 idx)
133} 130}
134 131
135/* Read-modify-write a register in CM1. Caller must lock */ 132/* Read-modify-write a register in CM1. Caller must lock */
136u32 omap4_cminst_rmw_inst_reg_bits(u32 mask, u32 bits, u8 part, u16 inst, 133static u32 omap4_cminst_rmw_inst_reg_bits(u32 mask, u32 bits, u8 part, u16 inst,
137 s16 idx) 134 s16 idx)
138{ 135{
139 u32 v; 136 u32 v;
140 137
@@ -146,17 +143,18 @@ u32 omap4_cminst_rmw_inst_reg_bits(u32 mask, u32 bits, u8 part, u16 inst,
146 return v; 143 return v;
147} 144}
148 145
149u32 omap4_cminst_set_inst_reg_bits(u32 bits, u8 part, u16 inst, s16 idx) 146static u32 omap4_cminst_set_inst_reg_bits(u32 bits, u8 part, u16 inst, s16 idx)
150{ 147{
151 return omap4_cminst_rmw_inst_reg_bits(bits, bits, part, inst, idx); 148 return omap4_cminst_rmw_inst_reg_bits(bits, bits, part, inst, idx);
152} 149}
153 150
154u32 omap4_cminst_clear_inst_reg_bits(u32 bits, u8 part, u16 inst, s16 idx) 151static u32 omap4_cminst_clear_inst_reg_bits(u32 bits, u8 part, u16 inst,
152 s16 idx)
155{ 153{
156 return omap4_cminst_rmw_inst_reg_bits(bits, 0x0, part, inst, idx); 154 return omap4_cminst_rmw_inst_reg_bits(bits, 0x0, part, inst, idx);
157} 155}
158 156
159u32 omap4_cminst_read_inst_reg_bits(u8 part, u16 inst, s16 idx, u32 mask) 157static u32 omap4_cminst_read_inst_reg_bits(u8 part, u16 inst, s16 idx, u32 mask)
160{ 158{
161 u32 v; 159 u32 v;
162 160
@@ -200,7 +198,7 @@ static void _clktrctrl_write(u8 c, u8 part, u16 inst, u16 cdoffs)
200 * Returns true if the clockdomain referred to by (@part, @inst, @cdoffs) 198 * Returns true if the clockdomain referred to by (@part, @inst, @cdoffs)
201 * is in hardware-supervised idle mode, or 0 otherwise. 199 * is in hardware-supervised idle mode, or 0 otherwise.
202 */ 200 */
203bool omap4_cminst_is_clkdm_in_hwsup(u8 part, u16 inst, u16 cdoffs) 201static bool omap4_cminst_is_clkdm_in_hwsup(u8 part, u16 inst, u16 cdoffs)
204{ 202{
205 u32 v; 203 u32 v;
206 204
@@ -220,7 +218,7 @@ bool omap4_cminst_is_clkdm_in_hwsup(u8 part, u16 inst, u16 cdoffs)
220 * Put a clockdomain referred to by (@part, @inst, @cdoffs) into 218 * Put a clockdomain referred to by (@part, @inst, @cdoffs) into
221 * hardware-supervised idle mode. No return value. 219 * hardware-supervised idle mode. No return value.
222 */ 220 */
223void omap4_cminst_clkdm_enable_hwsup(u8 part, u16 inst, u16 cdoffs) 221static void omap4_cminst_clkdm_enable_hwsup(u8 part, u16 inst, u16 cdoffs)
224{ 222{
225 _clktrctrl_write(OMAP34XX_CLKSTCTRL_ENABLE_AUTO, part, inst, cdoffs); 223 _clktrctrl_write(OMAP34XX_CLKSTCTRL_ENABLE_AUTO, part, inst, cdoffs);
226} 224}
@@ -235,7 +233,7 @@ void omap4_cminst_clkdm_enable_hwsup(u8 part, u16 inst, u16 cdoffs)
235 * software-supervised idle mode, i.e., controlled manually by the 233 * software-supervised idle mode, i.e., controlled manually by the
236 * Linux OMAP clockdomain code. No return value. 234 * Linux OMAP clockdomain code. No return value.
237 */ 235 */
238void omap4_cminst_clkdm_disable_hwsup(u8 part, u16 inst, u16 cdoffs) 236static void omap4_cminst_clkdm_disable_hwsup(u8 part, u16 inst, u16 cdoffs)
239{ 237{
240 _clktrctrl_write(OMAP34XX_CLKSTCTRL_DISABLE_AUTO, part, inst, cdoffs); 238 _clktrctrl_write(OMAP34XX_CLKSTCTRL_DISABLE_AUTO, part, inst, cdoffs);
241} 239}
@@ -249,7 +247,7 @@ void omap4_cminst_clkdm_disable_hwsup(u8 part, u16 inst, u16 cdoffs)
249 * Take a clockdomain referred to by (@part, @inst, @cdoffs) out of idle, 247 * Take a clockdomain referred to by (@part, @inst, @cdoffs) out of idle,
250 * waking it up. No return value. 248 * waking it up. No return value.
251 */ 249 */
252void omap4_cminst_clkdm_force_wakeup(u8 part, u16 inst, u16 cdoffs) 250static void omap4_cminst_clkdm_force_wakeup(u8 part, u16 inst, u16 cdoffs)
253{ 251{
254 _clktrctrl_write(OMAP34XX_CLKSTCTRL_FORCE_WAKEUP, part, inst, cdoffs); 252 _clktrctrl_write(OMAP34XX_CLKSTCTRL_FORCE_WAKEUP, part, inst, cdoffs);
255} 253}
@@ -258,7 +256,7 @@ void omap4_cminst_clkdm_force_wakeup(u8 part, u16 inst, u16 cdoffs)
258 * 256 *
259 */ 257 */
260 258
261void omap4_cminst_clkdm_force_sleep(u8 part, u16 inst, u16 cdoffs) 259static void omap4_cminst_clkdm_force_sleep(u8 part, u16 inst, u16 cdoffs)
262{ 260{
263 _clktrctrl_write(OMAP34XX_CLKSTCTRL_FORCE_SLEEP, part, inst, cdoffs); 261 _clktrctrl_write(OMAP34XX_CLKSTCTRL_FORCE_SLEEP, part, inst, cdoffs);
264} 262}
@@ -267,23 +265,23 @@ void omap4_cminst_clkdm_force_sleep(u8 part, u16 inst, u16 cdoffs)
267 * omap4_cminst_wait_module_ready - wait for a module to be in 'func' state 265 * omap4_cminst_wait_module_ready - wait for a module to be in 'func' state
268 * @part: PRCM partition ID that the CM_CLKCTRL register exists in 266 * @part: PRCM partition ID that the CM_CLKCTRL register exists in
269 * @inst: CM instance register offset (*_INST macro) 267 * @inst: CM instance register offset (*_INST macro)
270 * @cdoffs: Clockdomain register offset (*_CDOFFS macro)
271 * @clkctrl_offs: Module clock control register offset (*_CLKCTRL macro) 268 * @clkctrl_offs: Module clock control register offset (*_CLKCTRL macro)
269 * @bit_shift: bit shift for the register, ignored for OMAP4+
272 * 270 *
273 * Wait for the module IDLEST to be functional. If the idle state is in any 271 * Wait for the module IDLEST to be functional. If the idle state is in any
274 * the non functional state (trans, idle or disabled), module and thus the 272 * the non functional state (trans, idle or disabled), module and thus the
275 * sysconfig cannot be accessed and will probably lead to an "imprecise 273 * sysconfig cannot be accessed and will probably lead to an "imprecise
276 * external abort" 274 * external abort"
277 */ 275 */
278int omap4_cminst_wait_module_ready(u8 part, u16 inst, s16 cdoffs, 276static int omap4_cminst_wait_module_ready(u8 part, s16 inst, u16 clkctrl_offs,
279 u16 clkctrl_offs) 277 u8 bit_shift)
280{ 278{
281 int i = 0; 279 int i = 0;
282 280
283 if (!clkctrl_offs) 281 if (!clkctrl_offs)
284 return 0; 282 return 0;
285 283
286 omap_test_timeout(_is_module_ready(part, inst, cdoffs, clkctrl_offs), 284 omap_test_timeout(_is_module_ready(part, inst, clkctrl_offs),
287 MAX_MODULE_READY_TIME, i); 285 MAX_MODULE_READY_TIME, i);
288 286
289 return (i < MAX_MODULE_READY_TIME) ? 0 : -EBUSY; 287 return (i < MAX_MODULE_READY_TIME) ? 0 : -EBUSY;
@@ -294,21 +292,22 @@ int omap4_cminst_wait_module_ready(u8 part, u16 inst, s16 cdoffs,
294 * state 292 * state
295 * @part: PRCM partition ID that the CM_CLKCTRL register exists in 293 * @part: PRCM partition ID that the CM_CLKCTRL register exists in
296 * @inst: CM instance register offset (*_INST macro) 294 * @inst: CM instance register offset (*_INST macro)
297 * @cdoffs: Clockdomain register offset (*_CDOFFS macro)
298 * @clkctrl_offs: Module clock control register offset (*_CLKCTRL macro) 295 * @clkctrl_offs: Module clock control register offset (*_CLKCTRL macro)
296 * @bit_shift: Bit shift for the register, ignored for OMAP4+
299 * 297 *
300 * Wait for the module IDLEST to be disabled. Some PRCM transition, 298 * Wait for the module IDLEST to be disabled. Some PRCM transition,
301 * like reset assertion or parent clock de-activation must wait the 299 * like reset assertion or parent clock de-activation must wait the
302 * module to be fully disabled. 300 * module to be fully disabled.
303 */ 301 */
304int omap4_cminst_wait_module_idle(u8 part, u16 inst, s16 cdoffs, u16 clkctrl_offs) 302static int omap4_cminst_wait_module_idle(u8 part, s16 inst, u16 clkctrl_offs,
303 u8 bit_shift)
305{ 304{
306 int i = 0; 305 int i = 0;
307 306
308 if (!clkctrl_offs) 307 if (!clkctrl_offs)
309 return 0; 308 return 0;
310 309
311 omap_test_timeout((_clkctrl_idlest(part, inst, cdoffs, clkctrl_offs) == 310 omap_test_timeout((_clkctrl_idlest(part, inst, clkctrl_offs) ==
312 CLKCTRL_IDLEST_DISABLED), 311 CLKCTRL_IDLEST_DISABLED),
313 MAX_MODULE_DISABLE_TIME, i); 312 MAX_MODULE_DISABLE_TIME, i);
314 313
@@ -320,13 +319,12 @@ int omap4_cminst_wait_module_idle(u8 part, u16 inst, s16 cdoffs, u16 clkctrl_off
320 * @mode: Module mode (SW or HW) 319 * @mode: Module mode (SW or HW)
321 * @part: PRCM partition ID that the CM_CLKCTRL register exists in 320 * @part: PRCM partition ID that the CM_CLKCTRL register exists in
322 * @inst: CM instance register offset (*_INST macro) 321 * @inst: CM instance register offset (*_INST macro)
323 * @cdoffs: Clockdomain register offset (*_CDOFFS macro)
324 * @clkctrl_offs: Module clock control register offset (*_CLKCTRL macro) 322 * @clkctrl_offs: Module clock control register offset (*_CLKCTRL macro)
325 * 323 *
326 * No return value. 324 * No return value.
327 */ 325 */
328void omap4_cminst_module_enable(u8 mode, u8 part, u16 inst, s16 cdoffs, 326static void omap4_cminst_module_enable(u8 mode, u8 part, u16 inst,
329 u16 clkctrl_offs) 327 u16 clkctrl_offs)
330{ 328{
331 u32 v; 329 u32 v;
332 330
@@ -340,13 +338,11 @@ void omap4_cminst_module_enable(u8 mode, u8 part, u16 inst, s16 cdoffs,
340 * omap4_cminst_module_disable - Disable the module inside CLKCTRL 338 * omap4_cminst_module_disable - Disable the module inside CLKCTRL
341 * @part: PRCM partition ID that the CM_CLKCTRL register exists in 339 * @part: PRCM partition ID that the CM_CLKCTRL register exists in
342 * @inst: CM instance register offset (*_INST macro) 340 * @inst: CM instance register offset (*_INST macro)
343 * @cdoffs: Clockdomain register offset (*_CDOFFS macro)
344 * @clkctrl_offs: Module clock control register offset (*_CLKCTRL macro) 341 * @clkctrl_offs: Module clock control register offset (*_CLKCTRL macro)
345 * 342 *
346 * No return value. 343 * No return value.
347 */ 344 */
348void omap4_cminst_module_disable(u8 part, u16 inst, s16 cdoffs, 345static void omap4_cminst_module_disable(u8 part, u16 inst, u16 clkctrl_offs)
349 u16 clkctrl_offs)
350{ 346{
351 u32 v; 347 u32 v;
352 348
@@ -510,3 +506,21 @@ struct clkdm_ops am43xx_clkdm_operations = {
510 .clkdm_clk_enable = omap4_clkdm_clk_enable, 506 .clkdm_clk_enable = omap4_clkdm_clk_enable,
511 .clkdm_clk_disable = omap4_clkdm_clk_disable, 507 .clkdm_clk_disable = omap4_clkdm_clk_disable,
512}; 508};
509
510static struct cm_ll_data omap4xxx_cm_ll_data = {
511 .wait_module_ready = &omap4_cminst_wait_module_ready,
512 .wait_module_idle = &omap4_cminst_wait_module_idle,
513 .module_enable = &omap4_cminst_module_enable,
514 .module_disable = &omap4_cminst_module_disable,
515};
516
517int __init omap4_cm_init(void)
518{
519 return cm_register(&omap4xxx_cm_ll_data);
520}
521
522static void __exit omap4_cm_exit(void)
523{
524 cm_unregister(&omap4xxx_cm_ll_data);
525}
526__exitcall(omap4_cm_exit);
diff --git a/arch/arm/mach-omap2/cminst44xx.h b/arch/arm/mach-omap2/cminst44xx.h
deleted file mode 100644
index 7f56ea444bc4..000000000000
--- a/arch/arm/mach-omap2/cminst44xx.h
+++ /dev/null
@@ -1,43 +0,0 @@
1/*
2 * OMAP4 Clock Management (CM) function prototypes
3 *
4 * Copyright (C) 2010 Nokia Corporation
5 * Paul Walmsley
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11#ifndef __ARCH_ASM_MACH_OMAP2_CMINST44XX_H
12#define __ARCH_ASM_MACH_OMAP2_CMINST44XX_H
13
14bool omap4_cminst_is_clkdm_in_hwsup(u8 part, u16 inst, u16 cdoffs);
15void omap4_cminst_clkdm_enable_hwsup(u8 part, u16 inst, u16 cdoffs);
16void omap4_cminst_clkdm_disable_hwsup(u8 part, u16 inst, u16 cdoffs);
17void omap4_cminst_clkdm_force_sleep(u8 part, u16 inst, u16 cdoffs);
18void omap4_cminst_clkdm_force_wakeup(u8 part, u16 inst, u16 cdoffs);
19extern int omap4_cminst_wait_module_ready(u8 part, u16 inst, s16 cdoffs, u16 clkctrl_offs);
20extern int omap4_cminst_wait_module_idle(u8 part, u16 inst, s16 cdoffs,
21 u16 clkctrl_offs);
22extern void omap4_cminst_module_enable(u8 mode, u8 part, u16 inst, s16 cdoffs,
23 u16 clkctrl_offs);
24extern void omap4_cminst_module_disable(u8 part, u16 inst, s16 cdoffs,
25 u16 clkctrl_offs);
26/*
27 * In an ideal world, we would not export these low-level functions,
28 * but this will probably take some time to fix properly
29 */
30u32 omap4_cminst_read_inst_reg(u8 part, u16 inst, u16 idx);
31void omap4_cminst_write_inst_reg(u32 val, u8 part, u16 inst, u16 idx);
32u32 omap4_cminst_rmw_inst_reg_bits(u32 mask, u32 bits, u8 part,
33 u16 inst, s16 idx);
34u32 omap4_cminst_set_inst_reg_bits(u32 bits, u8 part, u16 inst,
35 s16 idx);
36u32 omap4_cminst_clear_inst_reg_bits(u32 bits, u8 part, u16 inst,
37 s16 idx);
38extern u32 omap4_cminst_read_inst_reg_bits(u8 part, u16 inst, s16 idx,
39 u32 mask);
40
41extern void omap_cm_base_init(void);
42
43#endif
diff --git a/arch/arm/mach-omap2/dpll3xxx.c b/arch/arm/mach-omap2/dpll3xxx.c
index ac3d789ac3cd..20e120d071dd 100644
--- a/arch/arm/mach-omap2/dpll3xxx.c
+++ b/arch/arm/mach-omap2/dpll3xxx.c
@@ -460,25 +460,24 @@ void omap3_noncore_dpll_disable(struct clk_hw *hw)
460/* Non-CORE DPLL rate set code */ 460/* Non-CORE DPLL rate set code */
461 461
462/** 462/**
463 * omap3_noncore_dpll_set_rate - set non-core DPLL rate 463 * omap3_noncore_dpll_determine_rate - determine rate for a DPLL
464 * @clk: struct clk * of DPLL to set 464 * @hw: pointer to the clock to determine rate for
465 * @rate: rounded target rate 465 * @rate: target rate for the DPLL
466 * @best_parent_rate: pointer for returning best parent rate
467 * @best_parent_clk: pointer for returning best parent clock
466 * 468 *
467 * Set the DPLL CLKOUT to the target rate. If the DPLL can enter 469 * Determines which DPLL mode to use for reaching a desired target rate.
468 * low-power bypass, and the target rate is the bypass source clock 470 * Checks whether the DPLL shall be in bypass or locked mode, and if
469 * rate, then configure the DPLL for bypass. Otherwise, round the 471 * locked, calculates the M,N values for the DPLL via round-rate.
470 * target rate if it hasn't been done already, then program and lock 472 * Returns a positive clock rate with success, negative error value
471 * the DPLL. Returns -EINVAL upon error, or 0 upon success. 473 * in failure.
472 */ 474 */
473int omap3_noncore_dpll_set_rate(struct clk_hw *hw, unsigned long rate, 475long omap3_noncore_dpll_determine_rate(struct clk_hw *hw, unsigned long rate,
474 unsigned long parent_rate) 476 unsigned long *best_parent_rate,
477 struct clk **best_parent_clk)
475{ 478{
476 struct clk_hw_omap *clk = to_clk_hw_omap(hw); 479 struct clk_hw_omap *clk = to_clk_hw_omap(hw);
477 struct clk *new_parent = NULL;
478 unsigned long rrate;
479 u16 freqsel = 0;
480 struct dpll_data *dd; 480 struct dpll_data *dd;
481 int ret;
482 481
483 if (!hw || !rate) 482 if (!hw || !rate)
484 return -EINVAL; 483 return -EINVAL;
@@ -489,61 +488,121 @@ int omap3_noncore_dpll_set_rate(struct clk_hw *hw, unsigned long rate,
489 488
490 if (__clk_get_rate(dd->clk_bypass) == rate && 489 if (__clk_get_rate(dd->clk_bypass) == rate &&
491 (dd->modes & (1 << DPLL_LOW_POWER_BYPASS))) { 490 (dd->modes & (1 << DPLL_LOW_POWER_BYPASS))) {
492 pr_debug("%s: %s: set rate: entering bypass.\n", 491 *best_parent_clk = dd->clk_bypass;
493 __func__, __clk_get_name(hw->clk)); 492 } else {
493 rate = omap2_dpll_round_rate(hw, rate, best_parent_rate);
494 *best_parent_clk = dd->clk_ref;
495 }
496
497 *best_parent_rate = rate;
498
499 return rate;
500}
501
502/**
503 * omap3_noncore_dpll_set_parent - set parent for a DPLL clock
504 * @hw: pointer to the clock to set parent for
505 * @index: parent index to select
506 *
507 * Sets parent for a DPLL clock. This sets the DPLL into bypass or
508 * locked mode. Returns 0 with success, negative error value otherwise.
509 */
510int omap3_noncore_dpll_set_parent(struct clk_hw *hw, u8 index)
511{
512 struct clk_hw_omap *clk = to_clk_hw_omap(hw);
513 int ret;
494 514
495 __clk_prepare(dd->clk_bypass); 515 if (!hw)
496 clk_enable(dd->clk_bypass); 516 return -EINVAL;
517
518 if (index)
497 ret = _omap3_noncore_dpll_bypass(clk); 519 ret = _omap3_noncore_dpll_bypass(clk);
498 if (!ret) 520 else
499 new_parent = dd->clk_bypass; 521 ret = _omap3_noncore_dpll_lock(clk);
500 clk_disable(dd->clk_bypass);
501 __clk_unprepare(dd->clk_bypass);
502 } else {
503 __clk_prepare(dd->clk_ref);
504 clk_enable(dd->clk_ref);
505
506 /* XXX this check is probably pointless in the CCF context */
507 if (dd->last_rounded_rate != rate) {
508 rrate = __clk_round_rate(hw->clk, rate);
509 if (rrate != rate) {
510 pr_warn("%s: %s: final rate %lu does not match desired rate %lu\n",
511 __func__, __clk_get_name(hw->clk),
512 rrate, rate);
513 rate = rrate;
514 }
515 }
516 522
517 if (dd->last_rounded_rate == 0) 523 return ret;
518 return -EINVAL; 524}
519 525
520 /* Freqsel is available only on OMAP343X devices */ 526/**
521 if (ti_clk_features.flags & TI_CLK_DPLL_HAS_FREQSEL) { 527 * omap3_noncore_dpll_set_rate - set rate for a DPLL clock
522 freqsel = _omap3_dpll_compute_freqsel(clk, 528 * @hw: pointer to the clock to set parent for
523 dd->last_rounded_n); 529 * @rate: target rate for the clock
524 WARN_ON(!freqsel); 530 * @parent_rate: rate of the parent clock
525 } 531 *
532 * Sets rate for a DPLL clock. First checks if the clock parent is
533 * reference clock (in bypass mode, the rate of the clock can't be
534 * changed) and proceeds with the rate change operation. Returns 0
535 * with success, negative error value otherwise.
536 */
537int omap3_noncore_dpll_set_rate(struct clk_hw *hw, unsigned long rate,
538 unsigned long parent_rate)
539{
540 struct clk_hw_omap *clk = to_clk_hw_omap(hw);
541 struct dpll_data *dd;
542 u16 freqsel = 0;
543 int ret;
544
545 if (!hw || !rate)
546 return -EINVAL;
547
548 dd = clk->dpll_data;
549 if (!dd)
550 return -EINVAL;
526 551
527 pr_debug("%s: %s: set rate: locking rate to %lu.\n", 552 if (__clk_get_parent(hw->clk) != dd->clk_ref)
528 __func__, __clk_get_name(hw->clk), rate); 553 return -EINVAL;
554
555 if (dd->last_rounded_rate == 0)
556 return -EINVAL;
529 557
530 ret = omap3_noncore_dpll_program(clk, freqsel); 558 /* Freqsel is available only on OMAP343X devices */
531 if (!ret) 559 if (ti_clk_features.flags & TI_CLK_DPLL_HAS_FREQSEL) {
532 new_parent = dd->clk_ref; 560 freqsel = _omap3_dpll_compute_freqsel(clk, dd->last_rounded_n);
533 clk_disable(dd->clk_ref); 561 WARN_ON(!freqsel);
534 __clk_unprepare(dd->clk_ref);
535 } 562 }
536 /*
537 * FIXME - this is all wrong. common code handles reparenting and
538 * migrating prepare/enable counts. dplls should be a multiplexer
539 * clock and this should be a set_parent operation so that all of that
540 * stuff is inherited for free
541 */
542 563
543 if (!ret && clk_get_parent(hw->clk) != new_parent) 564 pr_debug("%s: %s: set rate: locking rate to %lu.\n", __func__,
544 __clk_reparent(hw->clk, new_parent); 565 __clk_get_name(hw->clk), rate);
545 566
546 return 0; 567 ret = omap3_noncore_dpll_program(clk, freqsel);
568
569 return ret;
570}
571
572/**
573 * omap3_noncore_dpll_set_rate_and_parent - set rate and parent for a DPLL clock
574 * @hw: pointer to the clock to set rate and parent for
575 * @rate: target rate for the DPLL
576 * @parent_rate: clock rate of the DPLL parent
577 * @index: new parent index for the DPLL, 0 - reference, 1 - bypass
578 *
579 * Sets rate and parent for a DPLL clock. If new parent is the bypass
580 * clock, only selects the parent. Otherwise proceeds with a rate
581 * change, as this will effectively also change the parent as the
582 * DPLL is put into locked mode. Returns 0 with success, negative error
583 * value otherwise.
584 */
585int omap3_noncore_dpll_set_rate_and_parent(struct clk_hw *hw,
586 unsigned long rate,
587 unsigned long parent_rate,
588 u8 index)
589{
590 int ret;
591
592 if (!hw || !rate)
593 return -EINVAL;
594
595 /*
596 * clk-ref at index[0], in which case we only need to set rate,
597 * the parent will be changed automatically with the lock sequence.
598 * With clk-bypass case we only need to change parent.
599 */
600 if (index)
601 ret = omap3_noncore_dpll_set_parent(hw, index);
602 else
603 ret = omap3_noncore_dpll_set_rate(hw, rate, parent_rate);
604
605 return ret;
547} 606}
548 607
549/* DPLL autoidle read/set code */ 608/* DPLL autoidle read/set code */
diff --git a/arch/arm/mach-omap2/dpll44xx.c b/arch/arm/mach-omap2/dpll44xx.c
index 4613f1e86988..535822fcf4bb 100644
--- a/arch/arm/mach-omap2/dpll44xx.c
+++ b/arch/arm/mach-omap2/dpll44xx.c
@@ -207,3 +207,44 @@ out:
207 207
208 return dd->last_rounded_rate; 208 return dd->last_rounded_rate;
209} 209}
210
211/**
212 * omap4_dpll_regm4xen_determine_rate - determine rate for a DPLL
213 * @hw: pointer to the clock to determine rate for
214 * @rate: target rate for the DPLL
215 * @best_parent_rate: pointer for returning best parent rate
216 * @best_parent_clk: pointer for returning best parent clock
217 *
218 * Determines which DPLL mode to use for reaching a desired rate.
219 * Checks whether the DPLL shall be in bypass or locked mode, and if
220 * locked, calculates the M,N values for the DPLL via round-rate.
221 * Returns a positive clock rate with success, negative error value
222 * in failure.
223 */
224long omap4_dpll_regm4xen_determine_rate(struct clk_hw *hw, unsigned long rate,
225 unsigned long *best_parent_rate,
226 struct clk **best_parent_clk)
227{
228 struct clk_hw_omap *clk = to_clk_hw_omap(hw);
229 struct dpll_data *dd;
230
231 if (!hw || !rate)
232 return -EINVAL;
233
234 dd = clk->dpll_data;
235 if (!dd)
236 return -EINVAL;
237
238 if (__clk_get_rate(dd->clk_bypass) == rate &&
239 (dd->modes & (1 << DPLL_LOW_POWER_BYPASS))) {
240 *best_parent_clk = dd->clk_bypass;
241 } else {
242 rate = omap4_dpll_regm4xen_round_rate(hw, rate,
243 best_parent_rate);
244 *best_parent_clk = dd->clk_ref;
245 }
246
247 *best_parent_rate = rate;
248
249 return rate;
250}
diff --git a/arch/arm/mach-omap2/io.c b/arch/arm/mach-omap2/io.c
index 03cbb16898a3..4fc838354e31 100644
--- a/arch/arm/mach-omap2/io.c
+++ b/arch/arm/mach-omap2/io.c
@@ -45,13 +45,15 @@
45#include "sram.h" 45#include "sram.h"
46#include "cm2xxx.h" 46#include "cm2xxx.h"
47#include "cm3xxx.h" 47#include "cm3xxx.h"
48#include "cm33xx.h"
49#include "cm44xx.h"
48#include "prm.h" 50#include "prm.h"
49#include "cm.h" 51#include "cm.h"
50#include "prcm_mpu44xx.h" 52#include "prcm_mpu44xx.h"
51#include "prminst44xx.h" 53#include "prminst44xx.h"
52#include "cminst44xx.h"
53#include "prm2xxx.h" 54#include "prm2xxx.h"
54#include "prm3xxx.h" 55#include "prm3xxx.h"
56#include "prm33xx.h"
55#include "prm44xx.h" 57#include "prm44xx.h"
56#include "opp2xxx.h" 58#include "opp2xxx.h"
57 59
@@ -565,6 +567,8 @@ void __init am33xx_init_early(void)
565 omap2_set_globals_cm(AM33XX_L4_WK_IO_ADDRESS(AM33XX_PRCM_BASE), NULL); 567 omap2_set_globals_cm(AM33XX_L4_WK_IO_ADDRESS(AM33XX_PRCM_BASE), NULL);
566 omap3xxx_check_revision(); 568 omap3xxx_check_revision();
567 am33xx_check_features(); 569 am33xx_check_features();
570 am33xx_prm_init();
571 am33xx_cm_init();
568 am33xx_powerdomains_init(); 572 am33xx_powerdomains_init();
569 am33xx_clockdomains_init(); 573 am33xx_clockdomains_init();
570 am33xx_hwmod_init(); 574 am33xx_hwmod_init();
@@ -591,6 +595,8 @@ void __init am43xx_init_early(void)
591 omap_cm_base_init(); 595 omap_cm_base_init();
592 omap3xxx_check_revision(); 596 omap3xxx_check_revision();
593 am33xx_check_features(); 597 am33xx_check_features();
598 omap44xx_prm_init();
599 omap4_cm_init();
594 am43xx_powerdomains_init(); 600 am43xx_powerdomains_init();
595 am43xx_clockdomains_init(); 601 am43xx_clockdomains_init();
596 am43xx_hwmod_init(); 602 am43xx_hwmod_init();
@@ -620,6 +626,7 @@ void __init omap4430_init_early(void)
620 omap_cm_base_init(); 626 omap_cm_base_init();
621 omap4xxx_check_revision(); 627 omap4xxx_check_revision();
622 omap4xxx_check_features(); 628 omap4xxx_check_features();
629 omap4_cm_init();
623 omap4_pm_init_early(); 630 omap4_pm_init_early();
624 omap44xx_prm_init(); 631 omap44xx_prm_init();
625 omap44xx_voltagedomains_init(); 632 omap44xx_voltagedomains_init();
@@ -655,6 +662,7 @@ void __init omap5_init_early(void)
655 omap_cm_base_init(); 662 omap_cm_base_init();
656 omap44xx_prm_init(); 663 omap44xx_prm_init();
657 omap5xxx_check_revision(); 664 omap5xxx_check_revision();
665 omap4_cm_init();
658 omap54xx_voltagedomains_init(); 666 omap54xx_voltagedomains_init();
659 omap54xx_powerdomains_init(); 667 omap54xx_powerdomains_init();
660 omap54xx_clockdomains_init(); 668 omap54xx_clockdomains_init();
@@ -686,6 +694,7 @@ void __init dra7xx_init_early(void)
686 omap_cm_base_init(); 694 omap_cm_base_init();
687 omap44xx_prm_init(); 695 omap44xx_prm_init();
688 dra7xxx_check_revision(); 696 dra7xxx_check_revision();
697 omap4_cm_init();
689 dra7xx_powerdomains_init(); 698 dra7xx_powerdomains_init();
690 dra7xx_clockdomains_init(); 699 dra7xx_clockdomains_init();
691 dra7xx_hwmod_init(); 700 dra7xx_hwmod_init();
diff --git a/arch/arm/mach-omap2/omap-mpuss-lowpower.c b/arch/arm/mach-omap2/omap-mpuss-lowpower.c
index 6944ae3674e8..79f49d904a06 100644
--- a/arch/arm/mach-omap2/omap-mpuss-lowpower.c
+++ b/arch/arm/mach-omap2/omap-mpuss-lowpower.c
@@ -227,7 +227,7 @@ static void __init save_l2x0_context(void)
227int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state) 227int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state)
228{ 228{
229 struct omap4_cpu_pm_info *pm_info = &per_cpu(omap4_pm_info, cpu); 229 struct omap4_cpu_pm_info *pm_info = &per_cpu(omap4_pm_info, cpu);
230 unsigned int save_state = 0; 230 unsigned int save_state = 0, cpu_logic_state = PWRDM_POWER_RET;
231 unsigned int wakeup_cpu; 231 unsigned int wakeup_cpu;
232 232
233 if (omap_rev() == OMAP4430_REV_ES1_0) 233 if (omap_rev() == OMAP4430_REV_ES1_0)
@@ -239,6 +239,7 @@ int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state)
239 save_state = 0; 239 save_state = 0;
240 break; 240 break;
241 case PWRDM_POWER_OFF: 241 case PWRDM_POWER_OFF:
242 cpu_logic_state = PWRDM_POWER_OFF;
242 save_state = 1; 243 save_state = 1;
243 break; 244 break;
244 case PWRDM_POWER_RET: 245 case PWRDM_POWER_RET:
@@ -270,6 +271,7 @@ int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state)
270 271
271 cpu_clear_prev_logic_pwrst(cpu); 272 cpu_clear_prev_logic_pwrst(cpu);
272 pwrdm_set_next_pwrst(pm_info->pwrdm, power_state); 273 pwrdm_set_next_pwrst(pm_info->pwrdm, power_state);
274 pwrdm_set_logic_retst(pm_info->pwrdm, cpu_logic_state);
273 set_cpu_wakeup_addr(cpu, virt_to_phys(omap_pm_ops.resume)); 275 set_cpu_wakeup_addr(cpu, virt_to_phys(omap_pm_ops.resume));
274 omap_pm_ops.scu_prepare(cpu, power_state); 276 omap_pm_ops.scu_prepare(cpu, power_state);
275 l2x0_pwrst_prepare(cpu, save_state); 277 l2x0_pwrst_prepare(cpu, save_state);
diff --git a/arch/arm/mach-omap2/omap2-restart.c b/arch/arm/mach-omap2/omap2-restart.c
index 68423e26399d..d937b2e4040b 100644
--- a/arch/arm/mach-omap2/omap2-restart.c
+++ b/arch/arm/mach-omap2/omap2-restart.c
@@ -15,7 +15,7 @@
15 15
16#include "soc.h" 16#include "soc.h"
17#include "common.h" 17#include "common.h"
18#include "prm2xxx.h" 18#include "prm.h"
19 19
20/* 20/*
21 * reset_virt_prcm_set_ck, reset_sys_ck: pointers to the virt_prcm_set 21 * reset_virt_prcm_set_ck, reset_sys_ck: pointers to the virt_prcm_set
@@ -40,8 +40,7 @@ void omap2xxx_restart(enum reboot_mode mode, const char *cmd)
40 40
41 /* XXX Should save the cmd argument for use after the reboot */ 41 /* XXX Should save the cmd argument for use after the reboot */
42 42
43 omap2xxx_prm_dpll_reset(); /* never returns */ 43 omap_prm_reset_system();
44 while (1);
45} 44}
46 45
47/** 46/**
diff --git a/arch/arm/mach-omap2/omap3-restart.c b/arch/arm/mach-omap2/omap3-restart.c
index 5de2a0c2979d..103a49f68bcb 100644
--- a/arch/arm/mach-omap2/omap3-restart.c
+++ b/arch/arm/mach-omap2/omap3-restart.c
@@ -14,10 +14,8 @@
14#include <linux/init.h> 14#include <linux/init.h>
15#include <linux/reboot.h> 15#include <linux/reboot.h>
16 16
17#include "iomap.h"
18#include "common.h"
19#include "control.h" 17#include "control.h"
20#include "prm3xxx.h" 18#include "prm.h"
21 19
22/* Global address base setup code */ 20/* Global address base setup code */
23 21
@@ -32,6 +30,5 @@
32void omap3xxx_restart(enum reboot_mode mode, const char *cmd) 30void omap3xxx_restart(enum reboot_mode mode, const char *cmd)
33{ 31{
34 omap3_ctrl_write_boot_mode((cmd ? (u8)*cmd : 0)); 32 omap3_ctrl_write_boot_mode((cmd ? (u8)*cmd : 0));
35 omap3xxx_prm_dpll3_reset(); /* never returns */ 33 omap_prm_reset_system();
36 while (1);
37} 34}
diff --git a/arch/arm/mach-omap2/omap4-restart.c b/arch/arm/mach-omap2/omap4-restart.c
index 41dfd7da8170..a99e7f7fb5be 100644
--- a/arch/arm/mach-omap2/omap4-restart.c
+++ b/arch/arm/mach-omap2/omap4-restart.c
@@ -9,7 +9,7 @@
9 9
10#include <linux/types.h> 10#include <linux/types.h>
11#include <linux/reboot.h> 11#include <linux/reboot.h>
12#include "prminst44xx.h" 12#include "prm.h"
13 13
14/** 14/**
15 * omap44xx_restart - trigger a software restart of the SoC 15 * omap44xx_restart - trigger a software restart of the SoC
@@ -22,7 +22,5 @@
22void omap44xx_restart(enum reboot_mode mode, const char *cmd) 22void omap44xx_restart(enum reboot_mode mode, const char *cmd)
23{ 23{
24 /* XXX Should save 'cmd' into scratchpad for use after reboot */ 24 /* XXX Should save 'cmd' into scratchpad for use after reboot */
25 omap4_prminst_global_warm_sw_reset(); /* never returns */ 25 omap_prm_reset_system();
26 while (1)
27 ;
28} 26}
diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c
index 716247ed9e0c..cbb908dc5cf0 100644
--- a/arch/arm/mach-omap2/omap_hwmod.c
+++ b/arch/arm/mach-omap2/omap_hwmod.c
@@ -153,7 +153,6 @@
153#include "powerdomain.h" 153#include "powerdomain.h"
154#include "cm2xxx.h" 154#include "cm2xxx.h"
155#include "cm3xxx.h" 155#include "cm3xxx.h"
156#include "cminst44xx.h"
157#include "cm33xx.h" 156#include "cm33xx.h"
158#include "prm.h" 157#include "prm.h"
159#include "prm3xxx.h" 158#include "prm3xxx.h"
@@ -979,31 +978,9 @@ static void _omap4_enable_module(struct omap_hwmod *oh)
979 pr_debug("omap_hwmod: %s: %s: %d\n", 978 pr_debug("omap_hwmod: %s: %s: %d\n",
980 oh->name, __func__, oh->prcm.omap4.modulemode); 979 oh->name, __func__, oh->prcm.omap4.modulemode);
981 980
982 omap4_cminst_module_enable(oh->prcm.omap4.modulemode, 981 omap_cm_module_enable(oh->prcm.omap4.modulemode,
983 oh->clkdm->prcm_partition, 982 oh->clkdm->prcm_partition,
984 oh->clkdm->cm_inst, 983 oh->clkdm->cm_inst, oh->prcm.omap4.clkctrl_offs);
985 oh->clkdm->clkdm_offs,
986 oh->prcm.omap4.clkctrl_offs);
987}
988
989/**
990 * _am33xx_enable_module - enable CLKCTRL modulemode on AM33XX
991 * @oh: struct omap_hwmod *
992 *
993 * Enables the PRCM module mode related to the hwmod @oh.
994 * No return value.
995 */
996static void _am33xx_enable_module(struct omap_hwmod *oh)
997{
998 if (!oh->clkdm || !oh->prcm.omap4.modulemode)
999 return;
1000
1001 pr_debug("omap_hwmod: %s: %s: %d\n",
1002 oh->name, __func__, oh->prcm.omap4.modulemode);
1003
1004 am33xx_cm_module_enable(oh->prcm.omap4.modulemode, oh->clkdm->cm_inst,
1005 oh->clkdm->clkdm_offs,
1006 oh->prcm.omap4.clkctrl_offs);
1007} 984}
1008 985
1009/** 986/**
@@ -1026,35 +1003,9 @@ static int _omap4_wait_target_disable(struct omap_hwmod *oh)
1026 if (oh->flags & HWMOD_NO_IDLEST) 1003 if (oh->flags & HWMOD_NO_IDLEST)
1027 return 0; 1004 return 0;
1028 1005
1029 return omap4_cminst_wait_module_idle(oh->clkdm->prcm_partition, 1006 return omap_cm_wait_module_idle(oh->clkdm->prcm_partition,
1030 oh->clkdm->cm_inst, 1007 oh->clkdm->cm_inst,
1031 oh->clkdm->clkdm_offs, 1008 oh->prcm.omap4.clkctrl_offs, 0);
1032 oh->prcm.omap4.clkctrl_offs);
1033}
1034
1035/**
1036 * _am33xx_wait_target_disable - wait for a module to be disabled on AM33XX
1037 * @oh: struct omap_hwmod *
1038 *
1039 * Wait for a module @oh to enter slave idle. Returns 0 if the module
1040 * does not have an IDLEST bit or if the module successfully enters
1041 * slave idle; otherwise, pass along the return value of the
1042 * appropriate *_cm*_wait_module_idle() function.
1043 */
1044static int _am33xx_wait_target_disable(struct omap_hwmod *oh)
1045{
1046 if (!oh)
1047 return -EINVAL;
1048
1049 if (oh->_int_flags & _HWMOD_NO_MPU_PORT)
1050 return 0;
1051
1052 if (oh->flags & HWMOD_NO_IDLEST)
1053 return 0;
1054
1055 return am33xx_cm_wait_module_idle(oh->clkdm->cm_inst,
1056 oh->clkdm->clkdm_offs,
1057 oh->prcm.omap4.clkctrl_offs);
1058} 1009}
1059 1010
1060/** 1011/**
@@ -1859,10 +1810,8 @@ static int _omap4_disable_module(struct omap_hwmod *oh)
1859 1810
1860 pr_debug("omap_hwmod: %s: %s\n", oh->name, __func__); 1811 pr_debug("omap_hwmod: %s: %s\n", oh->name, __func__);
1861 1812
1862 omap4_cminst_module_disable(oh->clkdm->prcm_partition, 1813 omap_cm_module_disable(oh->clkdm->prcm_partition, oh->clkdm->cm_inst,
1863 oh->clkdm->cm_inst, 1814 oh->prcm.omap4.clkctrl_offs);
1864 oh->clkdm->clkdm_offs,
1865 oh->prcm.omap4.clkctrl_offs);
1866 1815
1867 v = _omap4_wait_target_disable(oh); 1816 v = _omap4_wait_target_disable(oh);
1868 if (v) 1817 if (v)
@@ -1873,36 +1822,6 @@ static int _omap4_disable_module(struct omap_hwmod *oh)
1873} 1822}
1874 1823
1875/** 1824/**
1876 * _am33xx_disable_module - enable CLKCTRL modulemode on AM33XX
1877 * @oh: struct omap_hwmod *
1878 *
1879 * Disable the PRCM module mode related to the hwmod @oh.
1880 * Return EINVAL if the modulemode is not supported and 0 in case of success.
1881 */
1882static int _am33xx_disable_module(struct omap_hwmod *oh)
1883{
1884 int v;
1885
1886 if (!oh->clkdm || !oh->prcm.omap4.modulemode)
1887 return -EINVAL;
1888
1889 pr_debug("omap_hwmod: %s: %s\n", oh->name, __func__);
1890
1891 if (_are_any_hardreset_lines_asserted(oh))
1892 return 0;
1893
1894 am33xx_cm_module_disable(oh->clkdm->cm_inst, oh->clkdm->clkdm_offs,
1895 oh->prcm.omap4.clkctrl_offs);
1896
1897 v = _am33xx_wait_target_disable(oh);
1898 if (v)
1899 pr_warn("omap_hwmod: %s: _wait_target_disable failed\n",
1900 oh->name);
1901
1902 return 0;
1903}
1904
1905/**
1906 * _ocp_softreset - reset an omap_hwmod via the OCP_SYSCONFIG bit 1825 * _ocp_softreset - reset an omap_hwmod via the OCP_SYSCONFIG bit
1907 * @oh: struct omap_hwmod * 1826 * @oh: struct omap_hwmod *
1908 * 1827 *
@@ -2065,10 +1984,7 @@ static void _reconfigure_io_chain(void)
2065 1984
2066 spin_lock_irqsave(&io_chain_lock, flags); 1985 spin_lock_irqsave(&io_chain_lock, flags);
2067 1986
2068 if (cpu_is_omap34xx()) 1987 omap_prm_reconfigure_io_chain();
2069 omap3xxx_prm_reconfigure_io_chain();
2070 else if (cpu_is_omap44xx())
2071 omap44xx_prm_reconfigure_io_chain();
2072 1988
2073 spin_unlock_irqrestore(&io_chain_lock, flags); 1989 spin_unlock_irqrestore(&io_chain_lock, flags);
2074} 1990}
@@ -2719,11 +2635,33 @@ static int __init _setup(struct omap_hwmod *oh, void *data)
2719 if (oh->_state != _HWMOD_STATE_INITIALIZED) 2635 if (oh->_state != _HWMOD_STATE_INITIALIZED)
2720 return 0; 2636 return 0;
2721 2637
2638 if (oh->parent_hwmod) {
2639 int r;
2640
2641 r = _enable(oh->parent_hwmod);
2642 WARN(r, "hwmod: %s: setup: failed to enable parent hwmod %s\n",
2643 oh->name, oh->parent_hwmod->name);
2644 }
2645
2722 _setup_iclk_autoidle(oh); 2646 _setup_iclk_autoidle(oh);
2723 2647
2724 if (!_setup_reset(oh)) 2648 if (!_setup_reset(oh))
2725 _setup_postsetup(oh); 2649 _setup_postsetup(oh);
2726 2650
2651 if (oh->parent_hwmod) {
2652 u8 postsetup_state;
2653
2654 postsetup_state = oh->parent_hwmod->_postsetup_state;
2655
2656 if (postsetup_state == _HWMOD_STATE_IDLE)
2657 _idle(oh->parent_hwmod);
2658 else if (postsetup_state == _HWMOD_STATE_DISABLED)
2659 _shutdown(oh->parent_hwmod);
2660 else if (postsetup_state != _HWMOD_STATE_ENABLED)
2661 WARN(1, "hwmod: %s: unknown postsetup state %d! defaulting to enabled\n",
2662 oh->parent_hwmod->name, postsetup_state);
2663 }
2664
2727 return 0; 2665 return 0;
2728} 2666}
2729 2667
@@ -2832,12 +2770,10 @@ static int __init _add_link(struct omap_hwmod_ocp_if *oi)
2832 _alloc_links(&ml, &sl); 2770 _alloc_links(&ml, &sl);
2833 2771
2834 ml->ocp_if = oi; 2772 ml->ocp_if = oi;
2835 INIT_LIST_HEAD(&ml->node);
2836 list_add(&ml->node, &oi->master->master_ports); 2773 list_add(&ml->node, &oi->master->master_ports);
2837 oi->master->masters_cnt++; 2774 oi->master->masters_cnt++;
2838 2775
2839 sl->ocp_if = oi; 2776 sl->ocp_if = oi;
2840 INIT_LIST_HEAD(&sl->node);
2841 list_add(&sl->node, &oi->slave->slave_ports); 2777 list_add(&sl->node, &oi->slave->slave_ports);
2842 oi->slave->slaves_cnt++; 2778 oi->slave->slaves_cnt++;
2843 2779
@@ -2927,34 +2863,7 @@ static int __init _alloc_linkspace(struct omap_hwmod_ocp_if **ois)
2927/* Static functions intended only for use in soc_ops field function pointers */ 2863/* Static functions intended only for use in soc_ops field function pointers */
2928 2864
2929/** 2865/**
2930 * _omap2xxx_wait_target_ready - wait for a module to leave slave idle 2866 * _omap2xxx_3xxx_wait_target_ready - wait for a module to leave slave idle
2931 * @oh: struct omap_hwmod *
2932 *
2933 * Wait for a module @oh to leave slave idle. Returns 0 if the module
2934 * does not have an IDLEST bit or if the module successfully leaves
2935 * slave idle; otherwise, pass along the return value of the
2936 * appropriate *_cm*_wait_module_ready() function.
2937 */
2938static int _omap2xxx_wait_target_ready(struct omap_hwmod *oh)
2939{
2940 if (!oh)
2941 return -EINVAL;
2942
2943 if (oh->flags & HWMOD_NO_IDLEST)
2944 return 0;
2945
2946 if (!_find_mpu_rt_port(oh))
2947 return 0;
2948
2949 /* XXX check module SIDLEMODE, hardreset status, enabled clocks */
2950
2951 return omap2xxx_cm_wait_module_ready(oh->prcm.omap2.module_offs,
2952 oh->prcm.omap2.idlest_reg_id,
2953 oh->prcm.omap2.idlest_idle_bit);
2954}
2955
2956/**
2957 * _omap3xxx_wait_target_ready - wait for a module to leave slave idle
2958 * @oh: struct omap_hwmod * 2867 * @oh: struct omap_hwmod *
2959 * 2868 *
2960 * Wait for a module @oh to leave slave idle. Returns 0 if the module 2869 * Wait for a module @oh to leave slave idle. Returns 0 if the module
@@ -2962,7 +2871,7 @@ static int _omap2xxx_wait_target_ready(struct omap_hwmod *oh)
2962 * slave idle; otherwise, pass along the return value of the 2871 * slave idle; otherwise, pass along the return value of the
2963 * appropriate *_cm*_wait_module_ready() function. 2872 * appropriate *_cm*_wait_module_ready() function.
2964 */ 2873 */
2965static int _omap3xxx_wait_target_ready(struct omap_hwmod *oh) 2874static int _omap2xxx_3xxx_wait_target_ready(struct omap_hwmod *oh)
2966{ 2875{
2967 if (!oh) 2876 if (!oh)
2968 return -EINVAL; 2877 return -EINVAL;
@@ -2975,9 +2884,9 @@ static int _omap3xxx_wait_target_ready(struct omap_hwmod *oh)
2975 2884
2976 /* XXX check module SIDLEMODE, hardreset status, enabled clocks */ 2885 /* XXX check module SIDLEMODE, hardreset status, enabled clocks */
2977 2886
2978 return omap3xxx_cm_wait_module_ready(oh->prcm.omap2.module_offs, 2887 return omap_cm_wait_module_ready(0, oh->prcm.omap2.module_offs,
2979 oh->prcm.omap2.idlest_reg_id, 2888 oh->prcm.omap2.idlest_reg_id,
2980 oh->prcm.omap2.idlest_idle_bit); 2889 oh->prcm.omap2.idlest_idle_bit);
2981} 2890}
2982 2891
2983/** 2892/**
@@ -3002,37 +2911,9 @@ static int _omap4_wait_target_ready(struct omap_hwmod *oh)
3002 2911
3003 /* XXX check module SIDLEMODE, hardreset status */ 2912 /* XXX check module SIDLEMODE, hardreset status */
3004 2913
3005 return omap4_cminst_wait_module_ready(oh->clkdm->prcm_partition, 2914 return omap_cm_wait_module_ready(oh->clkdm->prcm_partition,
3006 oh->clkdm->cm_inst, 2915 oh->clkdm->cm_inst,
3007 oh->clkdm->clkdm_offs, 2916 oh->prcm.omap4.clkctrl_offs, 0);
3008 oh->prcm.omap4.clkctrl_offs);
3009}
3010
3011/**
3012 * _am33xx_wait_target_ready - wait for a module to leave slave idle
3013 * @oh: struct omap_hwmod *
3014 *
3015 * Wait for a module @oh to leave slave idle. Returns 0 if the module
3016 * does not have an IDLEST bit or if the module successfully leaves
3017 * slave idle; otherwise, pass along the return value of the
3018 * appropriate *_cm*_wait_module_ready() function.
3019 */
3020static int _am33xx_wait_target_ready(struct omap_hwmod *oh)
3021{
3022 if (!oh || !oh->clkdm)
3023 return -EINVAL;
3024
3025 if (oh->flags & HWMOD_NO_IDLEST)
3026 return 0;
3027
3028 if (!_find_mpu_rt_port(oh))
3029 return 0;
3030
3031 /* XXX check module SIDLEMODE, hardreset status */
3032
3033 return am33xx_cm_wait_module_ready(oh->clkdm->cm_inst,
3034 oh->clkdm->clkdm_offs,
3035 oh->prcm.omap4.clkctrl_offs);
3036} 2917}
3037 2918
3038/** 2919/**
@@ -3049,8 +2930,8 @@ static int _am33xx_wait_target_ready(struct omap_hwmod *oh)
3049static int _omap2_assert_hardreset(struct omap_hwmod *oh, 2930static int _omap2_assert_hardreset(struct omap_hwmod *oh,
3050 struct omap_hwmod_rst_info *ohri) 2931 struct omap_hwmod_rst_info *ohri)
3051{ 2932{
3052 return omap2_prm_assert_hardreset(oh->prcm.omap2.module_offs, 2933 return omap_prm_assert_hardreset(ohri->rst_shift, 0,
3053 ohri->rst_shift); 2934 oh->prcm.omap2.module_offs, 0);
3054} 2935}
3055 2936
3056/** 2937/**
@@ -3067,9 +2948,8 @@ static int _omap2_assert_hardreset(struct omap_hwmod *oh,
3067static int _omap2_deassert_hardreset(struct omap_hwmod *oh, 2948static int _omap2_deassert_hardreset(struct omap_hwmod *oh,
3068 struct omap_hwmod_rst_info *ohri) 2949 struct omap_hwmod_rst_info *ohri)
3069{ 2950{
3070 return omap2_prm_deassert_hardreset(oh->prcm.omap2.module_offs, 2951 return omap_prm_deassert_hardreset(ohri->rst_shift, ohri->st_shift, 0,
3071 ohri->rst_shift, 2952 oh->prcm.omap2.module_offs, 0, 0);
3072 ohri->st_shift);
3073} 2953}
3074 2954
3075/** 2955/**
@@ -3087,8 +2967,8 @@ static int _omap2_deassert_hardreset(struct omap_hwmod *oh,
3087static int _omap2_is_hardreset_asserted(struct omap_hwmod *oh, 2967static int _omap2_is_hardreset_asserted(struct omap_hwmod *oh,
3088 struct omap_hwmod_rst_info *ohri) 2968 struct omap_hwmod_rst_info *ohri)
3089{ 2969{
3090 return omap2_prm_is_hardreset_asserted(oh->prcm.omap2.module_offs, 2970 return omap_prm_is_hardreset_asserted(ohri->st_shift, 0,
3091 ohri->st_shift); 2971 oh->prcm.omap2.module_offs, 0);
3092} 2972}
3093 2973
3094/** 2974/**
@@ -3109,10 +2989,10 @@ static int _omap4_assert_hardreset(struct omap_hwmod *oh,
3109 if (!oh->clkdm) 2989 if (!oh->clkdm)
3110 return -EINVAL; 2990 return -EINVAL;
3111 2991
3112 return omap4_prminst_assert_hardreset(ohri->rst_shift, 2992 return omap_prm_assert_hardreset(ohri->rst_shift,
3113 oh->clkdm->pwrdm.ptr->prcm_partition, 2993 oh->clkdm->pwrdm.ptr->prcm_partition,
3114 oh->clkdm->pwrdm.ptr->prcm_offs, 2994 oh->clkdm->pwrdm.ptr->prcm_offs,
3115 oh->prcm.omap4.rstctrl_offs); 2995 oh->prcm.omap4.rstctrl_offs);
3116} 2996}
3117 2997
3118/** 2998/**
@@ -3136,10 +3016,10 @@ static int _omap4_deassert_hardreset(struct omap_hwmod *oh,
3136 if (ohri->st_shift) 3016 if (ohri->st_shift)
3137 pr_err("omap_hwmod: %s: %s: hwmod data error: OMAP4 does not support st_shift\n", 3017 pr_err("omap_hwmod: %s: %s: hwmod data error: OMAP4 does not support st_shift\n",
3138 oh->name, ohri->name); 3018 oh->name, ohri->name);
3139 return omap4_prminst_deassert_hardreset(ohri->rst_shift, 3019 return omap_prm_deassert_hardreset(ohri->rst_shift, 0,
3140 oh->clkdm->pwrdm.ptr->prcm_partition, 3020 oh->clkdm->pwrdm.ptr->prcm_partition,
3141 oh->clkdm->pwrdm.ptr->prcm_offs, 3021 oh->clkdm->pwrdm.ptr->prcm_offs,
3142 oh->prcm.omap4.rstctrl_offs); 3022 oh->prcm.omap4.rstctrl_offs, 0);
3143} 3023}
3144 3024
3145/** 3025/**
@@ -3160,10 +3040,11 @@ static int _omap4_is_hardreset_asserted(struct omap_hwmod *oh,
3160 if (!oh->clkdm) 3040 if (!oh->clkdm)
3161 return -EINVAL; 3041 return -EINVAL;
3162 3042
3163 return omap4_prminst_is_hardreset_asserted(ohri->rst_shift, 3043 return omap_prm_is_hardreset_asserted(ohri->rst_shift,
3164 oh->clkdm->pwrdm.ptr->prcm_partition, 3044 oh->clkdm->pwrdm.ptr->
3165 oh->clkdm->pwrdm.ptr->prcm_offs, 3045 prcm_partition,
3166 oh->prcm.omap4.rstctrl_offs); 3046 oh->clkdm->pwrdm.ptr->prcm_offs,
3047 oh->prcm.omap4.rstctrl_offs);
3167} 3048}
3168 3049
3169/** 3050/**
@@ -3182,9 +3063,9 @@ static int _am33xx_assert_hardreset(struct omap_hwmod *oh,
3182 struct omap_hwmod_rst_info *ohri) 3063 struct omap_hwmod_rst_info *ohri)
3183 3064
3184{ 3065{
3185 return am33xx_prm_assert_hardreset(ohri->rst_shift, 3066 return omap_prm_assert_hardreset(ohri->rst_shift, 0,
3186 oh->clkdm->pwrdm.ptr->prcm_offs, 3067 oh->clkdm->pwrdm.ptr->prcm_offs,
3187 oh->prcm.omap4.rstctrl_offs); 3068 oh->prcm.omap4.rstctrl_offs);
3188} 3069}
3189 3070
3190/** 3071/**
@@ -3202,11 +3083,10 @@ static int _am33xx_assert_hardreset(struct omap_hwmod *oh,
3202static int _am33xx_deassert_hardreset(struct omap_hwmod *oh, 3083static int _am33xx_deassert_hardreset(struct omap_hwmod *oh,
3203 struct omap_hwmod_rst_info *ohri) 3084 struct omap_hwmod_rst_info *ohri)
3204{ 3085{
3205 return am33xx_prm_deassert_hardreset(ohri->rst_shift, 3086 return omap_prm_deassert_hardreset(ohri->rst_shift, ohri->st_shift, 0,
3206 ohri->st_shift, 3087 oh->clkdm->pwrdm.ptr->prcm_offs,
3207 oh->clkdm->pwrdm.ptr->prcm_offs, 3088 oh->prcm.omap4.rstctrl_offs,
3208 oh->prcm.omap4.rstctrl_offs, 3089 oh->prcm.omap4.rstst_offs);
3209 oh->prcm.omap4.rstst_offs);
3210} 3090}
3211 3091
3212/** 3092/**
@@ -3224,9 +3104,9 @@ static int _am33xx_deassert_hardreset(struct omap_hwmod *oh,
3224static int _am33xx_is_hardreset_asserted(struct omap_hwmod *oh, 3104static int _am33xx_is_hardreset_asserted(struct omap_hwmod *oh,
3225 struct omap_hwmod_rst_info *ohri) 3105 struct omap_hwmod_rst_info *ohri)
3226{ 3106{
3227 return am33xx_prm_is_hardreset_asserted(ohri->rst_shift, 3107 return omap_prm_is_hardreset_asserted(ohri->rst_shift, 0,
3228 oh->clkdm->pwrdm.ptr->prcm_offs, 3108 oh->clkdm->pwrdm.ptr->prcm_offs,
3229 oh->prcm.omap4.rstctrl_offs); 3109 oh->prcm.omap4.rstctrl_offs);
3230} 3110}
3231 3111
3232/* Public functions */ 3112/* Public functions */
@@ -4234,12 +4114,12 @@ int omap_hwmod_pad_route_irq(struct omap_hwmod *oh, int pad_idx, int irq_idx)
4234void __init omap_hwmod_init(void) 4114void __init omap_hwmod_init(void)
4235{ 4115{
4236 if (cpu_is_omap24xx()) { 4116 if (cpu_is_omap24xx()) {
4237 soc_ops.wait_target_ready = _omap2xxx_wait_target_ready; 4117 soc_ops.wait_target_ready = _omap2xxx_3xxx_wait_target_ready;
4238 soc_ops.assert_hardreset = _omap2_assert_hardreset; 4118 soc_ops.assert_hardreset = _omap2_assert_hardreset;
4239 soc_ops.deassert_hardreset = _omap2_deassert_hardreset; 4119 soc_ops.deassert_hardreset = _omap2_deassert_hardreset;
4240 soc_ops.is_hardreset_asserted = _omap2_is_hardreset_asserted; 4120 soc_ops.is_hardreset_asserted = _omap2_is_hardreset_asserted;
4241 } else if (cpu_is_omap34xx()) { 4121 } else if (cpu_is_omap34xx()) {
4242 soc_ops.wait_target_ready = _omap3xxx_wait_target_ready; 4122 soc_ops.wait_target_ready = _omap2xxx_3xxx_wait_target_ready;
4243 soc_ops.assert_hardreset = _omap2_assert_hardreset; 4123 soc_ops.assert_hardreset = _omap2_assert_hardreset;
4244 soc_ops.deassert_hardreset = _omap2_deassert_hardreset; 4124 soc_ops.deassert_hardreset = _omap2_deassert_hardreset;
4245 soc_ops.is_hardreset_asserted = _omap2_is_hardreset_asserted; 4125 soc_ops.is_hardreset_asserted = _omap2_is_hardreset_asserted;
@@ -4258,14 +4138,14 @@ void __init omap_hwmod_init(void)
4258 soc_ops.enable_module = _omap4_enable_module; 4138 soc_ops.enable_module = _omap4_enable_module;
4259 soc_ops.disable_module = _omap4_disable_module; 4139 soc_ops.disable_module = _omap4_disable_module;
4260 soc_ops.wait_target_ready = _omap4_wait_target_ready; 4140 soc_ops.wait_target_ready = _omap4_wait_target_ready;
4261 soc_ops.assert_hardreset = _am33xx_assert_hardreset; 4141 soc_ops.assert_hardreset = _omap4_assert_hardreset;
4262 soc_ops.deassert_hardreset = _am33xx_deassert_hardreset; 4142 soc_ops.deassert_hardreset = _omap4_deassert_hardreset;
4263 soc_ops.is_hardreset_asserted = _am33xx_is_hardreset_asserted; 4143 soc_ops.is_hardreset_asserted = _omap4_is_hardreset_asserted;
4264 soc_ops.init_clkdm = _init_clkdm; 4144 soc_ops.init_clkdm = _init_clkdm;
4265 } else if (soc_is_am33xx()) { 4145 } else if (soc_is_am33xx()) {
4266 soc_ops.enable_module = _am33xx_enable_module; 4146 soc_ops.enable_module = _omap4_enable_module;
4267 soc_ops.disable_module = _am33xx_disable_module; 4147 soc_ops.disable_module = _omap4_disable_module;
4268 soc_ops.wait_target_ready = _am33xx_wait_target_ready; 4148 soc_ops.wait_target_ready = _omap4_wait_target_ready;
4269 soc_ops.assert_hardreset = _am33xx_assert_hardreset; 4149 soc_ops.assert_hardreset = _am33xx_assert_hardreset;
4270 soc_ops.deassert_hardreset = _am33xx_deassert_hardreset; 4150 soc_ops.deassert_hardreset = _am33xx_deassert_hardreset;
4271 soc_ops.is_hardreset_asserted = _am33xx_is_hardreset_asserted; 4151 soc_ops.is_hardreset_asserted = _am33xx_is_hardreset_asserted;
diff --git a/arch/arm/mach-omap2/omap_hwmod.h b/arch/arm/mach-omap2/omap_hwmod.h
index 512f809a3f4d..35ca6efbec31 100644
--- a/arch/arm/mach-omap2/omap_hwmod.h
+++ b/arch/arm/mach-omap2/omap_hwmod.h
@@ -633,6 +633,7 @@ struct omap_hwmod_link {
633 * @flags: hwmod flags (documented below) 633 * @flags: hwmod flags (documented below)
634 * @_lock: spinlock serializing operations on this hwmod 634 * @_lock: spinlock serializing operations on this hwmod
635 * @node: list node for hwmod list (internal use) 635 * @node: list node for hwmod list (internal use)
636 * @parent_hwmod: (temporary) a pointer to the hierarchical parent of this hwmod
636 * 637 *
637 * @main_clk refers to this module's "main clock," which for our 638 * @main_clk refers to this module's "main clock," which for our
638 * purposes is defined as "the functional clock needed for register 639 * purposes is defined as "the functional clock needed for register
@@ -643,6 +644,12 @@ struct omap_hwmod_link {
643 * the omap_hwmod code and should not be set during initialization. 644 * the omap_hwmod code and should not be set during initialization.
644 * 645 *
645 * @masters and @slaves are now deprecated. 646 * @masters and @slaves are now deprecated.
647 *
648 * @parent_hwmod is temporary; there should be no need for it, as this
649 * information should already be expressed in the OCP interface
650 * structures. @parent_hwmod is present as a workaround until we improve
651 * handling for hwmods with multiple parents (e.g., OMAP4+ DSS with
652 * multiple register targets across different interconnects).
646 */ 653 */
647struct omap_hwmod { 654struct omap_hwmod {
648 const char *name; 655 const char *name;
@@ -680,6 +687,7 @@ struct omap_hwmod {
680 u8 _int_flags; 687 u8 _int_flags;
681 u8 _state; 688 u8 _state;
682 u8 _postsetup_state; 689 u8 _postsetup_state;
690 struct omap_hwmod *parent_hwmod;
683}; 691};
684 692
685struct omap_hwmod *omap_hwmod_lookup(const char *name); 693struct omap_hwmod *omap_hwmod_lookup(const char *name);
diff --git a/arch/arm/mach-omap2/omap_hwmod_43xx_data.c b/arch/arm/mach-omap2/omap_hwmod_43xx_data.c
index fea01aa3ef42..5c6c8410160e 100644
--- a/arch/arm/mach-omap2/omap_hwmod_43xx_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_43xx_data.c
@@ -417,6 +417,37 @@ static struct omap_hwmod am43xx_qspi_hwmod = {
417 }, 417 },
418}; 418};
419 419
420/*
421 * 'adc/tsc' class
422 * TouchScreen Controller (Analog-To-Digital Converter)
423 */
424static struct omap_hwmod_class_sysconfig am43xx_adc_tsc_sysc = {
425 .rev_offs = 0x00,
426 .sysc_offs = 0x10,
427 .sysc_flags = SYSC_HAS_SIDLEMODE,
428 .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART |
429 SIDLE_SMART_WKUP),
430 .sysc_fields = &omap_hwmod_sysc_type2,
431};
432
433static struct omap_hwmod_class am43xx_adc_tsc_hwmod_class = {
434 .name = "adc_tsc",
435 .sysc = &am43xx_adc_tsc_sysc,
436};
437
438static struct omap_hwmod am43xx_adc_tsc_hwmod = {
439 .name = "adc_tsc",
440 .class = &am43xx_adc_tsc_hwmod_class,
441 .clkdm_name = "l3s_tsc_clkdm",
442 .main_clk = "adc_tsc_fck",
443 .prcm = {
444 .omap4 = {
445 .clkctrl_offs = AM43XX_CM_WKUP_ADC_TSC_CLKCTRL_OFFSET,
446 .modulemode = MODULEMODE_SWCTRL,
447 },
448 },
449};
450
420/* dss */ 451/* dss */
421 452
422static struct omap_hwmod am43xx_dss_core_hwmod = { 453static struct omap_hwmod am43xx_dss_core_hwmod = {
@@ -547,6 +578,13 @@ static struct omap_hwmod_ocp_if am43xx_l4_wkup__gpio0 = {
547 .user = OCP_USER_MPU | OCP_USER_SDMA, 578 .user = OCP_USER_MPU | OCP_USER_SDMA,
548}; 579};
549 580
581static struct omap_hwmod_ocp_if am43xx_l4_wkup__adc_tsc = {
582 .master = &am33xx_l4_wkup_hwmod,
583 .slave = &am43xx_adc_tsc_hwmod,
584 .clk = "dpll_core_m4_div2_ck",
585 .user = OCP_USER_MPU,
586};
587
550static struct omap_hwmod_ocp_if am43xx_l4_hs__cpgmac0 = { 588static struct omap_hwmod_ocp_if am43xx_l4_hs__cpgmac0 = {
551 .master = &am43xx_l4_hs_hwmod, 589 .master = &am43xx_l4_hs_hwmod,
552 .slave = &am33xx_cpgmac0_hwmod, 590 .slave = &am33xx_cpgmac0_hwmod,
@@ -789,6 +827,7 @@ static struct omap_hwmod_ocp_if *am43xx_hwmod_ocp_ifs[] __initdata = {
789 &am43xx_l4_wkup__i2c1, 827 &am43xx_l4_wkup__i2c1,
790 &am43xx_l4_wkup__gpio0, 828 &am43xx_l4_wkup__gpio0,
791 &am43xx_l4_wkup__wd_timer1, 829 &am43xx_l4_wkup__wd_timer1,
830 &am43xx_l4_wkup__adc_tsc,
792 &am43xx_l3_s__qspi, 831 &am43xx_l3_s__qspi,
793 &am33xx_l4_per__dcan0, 832 &am33xx_l4_per__dcan0,
794 &am33xx_l4_per__dcan1, 833 &am33xx_l4_per__dcan1,
diff --git a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
index d8a3cf1c1787..c314b3c31117 100644
--- a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
@@ -589,6 +589,7 @@ static struct omap_hwmod omap44xx_dss_hwmod = {
589 .omap4 = { 589 .omap4 = {
590 .clkctrl_offs = OMAP4_CM_DSS_DSS_CLKCTRL_OFFSET, 590 .clkctrl_offs = OMAP4_CM_DSS_DSS_CLKCTRL_OFFSET,
591 .context_offs = OMAP4_RM_DSS_DSS_CONTEXT_OFFSET, 591 .context_offs = OMAP4_RM_DSS_DSS_CONTEXT_OFFSET,
592 .modulemode = MODULEMODE_SWCTRL,
592 }, 593 },
593 }, 594 },
594 .opt_clks = dss_opt_clks, 595 .opt_clks = dss_opt_clks,
@@ -647,7 +648,8 @@ static struct omap_hwmod omap44xx_dss_dispc_hwmod = {
647 .context_offs = OMAP4_RM_DSS_DSS_CONTEXT_OFFSET, 648 .context_offs = OMAP4_RM_DSS_DSS_CONTEXT_OFFSET,
648 }, 649 },
649 }, 650 },
650 .dev_attr = &omap44xx_dss_dispc_dev_attr 651 .dev_attr = &omap44xx_dss_dispc_dev_attr,
652 .parent_hwmod = &omap44xx_dss_hwmod,
651}; 653};
652 654
653/* 655/*
@@ -701,6 +703,7 @@ static struct omap_hwmod omap44xx_dss_dsi1_hwmod = {
701 }, 703 },
702 .opt_clks = dss_dsi1_opt_clks, 704 .opt_clks = dss_dsi1_opt_clks,
703 .opt_clks_cnt = ARRAY_SIZE(dss_dsi1_opt_clks), 705 .opt_clks_cnt = ARRAY_SIZE(dss_dsi1_opt_clks),
706 .parent_hwmod = &omap44xx_dss_hwmod,
704}; 707};
705 708
706/* dss_dsi2 */ 709/* dss_dsi2 */
@@ -733,6 +736,7 @@ static struct omap_hwmod omap44xx_dss_dsi2_hwmod = {
733 }, 736 },
734 .opt_clks = dss_dsi2_opt_clks, 737 .opt_clks = dss_dsi2_opt_clks,
735 .opt_clks_cnt = ARRAY_SIZE(dss_dsi2_opt_clks), 738 .opt_clks_cnt = ARRAY_SIZE(dss_dsi2_opt_clks),
739 .parent_hwmod = &omap44xx_dss_hwmod,
736}; 740};
737 741
738/* 742/*
@@ -790,6 +794,7 @@ static struct omap_hwmod omap44xx_dss_hdmi_hwmod = {
790 }, 794 },
791 .opt_clks = dss_hdmi_opt_clks, 795 .opt_clks = dss_hdmi_opt_clks,
792 .opt_clks_cnt = ARRAY_SIZE(dss_hdmi_opt_clks), 796 .opt_clks_cnt = ARRAY_SIZE(dss_hdmi_opt_clks),
797 .parent_hwmod = &omap44xx_dss_hwmod,
793}; 798};
794 799
795/* 800/*
@@ -819,7 +824,7 @@ static struct omap_hwmod_dma_info omap44xx_dss_rfbi_sdma_reqs[] = {
819}; 824};
820 825
821static struct omap_hwmod_opt_clk dss_rfbi_opt_clks[] = { 826static struct omap_hwmod_opt_clk dss_rfbi_opt_clks[] = {
822 { .role = "ick", .clk = "dss_fck" }, 827 { .role = "ick", .clk = "l3_div_ck" },
823}; 828};
824 829
825static struct omap_hwmod omap44xx_dss_rfbi_hwmod = { 830static struct omap_hwmod omap44xx_dss_rfbi_hwmod = {
@@ -836,6 +841,7 @@ static struct omap_hwmod omap44xx_dss_rfbi_hwmod = {
836 }, 841 },
837 .opt_clks = dss_rfbi_opt_clks, 842 .opt_clks = dss_rfbi_opt_clks,
838 .opt_clks_cnt = ARRAY_SIZE(dss_rfbi_opt_clks), 843 .opt_clks_cnt = ARRAY_SIZE(dss_rfbi_opt_clks),
844 .parent_hwmod = &omap44xx_dss_hwmod,
839}; 845};
840 846
841/* 847/*
@@ -859,6 +865,7 @@ static struct omap_hwmod omap44xx_dss_venc_hwmod = {
859 .context_offs = OMAP4_RM_DSS_DSS_CONTEXT_OFFSET, 865 .context_offs = OMAP4_RM_DSS_DSS_CONTEXT_OFFSET,
860 }, 866 },
861 }, 867 },
868 .parent_hwmod = &omap44xx_dss_hwmod,
862}; 869};
863 870
864/* 871/*
@@ -3671,7 +3678,7 @@ static struct omap_hwmod_addr_space omap44xx_dss_dma_addrs[] = {
3671static struct omap_hwmod_ocp_if omap44xx_l3_main_2__dss = { 3678static struct omap_hwmod_ocp_if omap44xx_l3_main_2__dss = {
3672 .master = &omap44xx_l3_main_2_hwmod, 3679 .master = &omap44xx_l3_main_2_hwmod,
3673 .slave = &omap44xx_dss_hwmod, 3680 .slave = &omap44xx_dss_hwmod,
3674 .clk = "dss_fck", 3681 .clk = "l3_div_ck",
3675 .addr = omap44xx_dss_dma_addrs, 3682 .addr = omap44xx_dss_dma_addrs,
3676 .user = OCP_USER_SDMA, 3683 .user = OCP_USER_SDMA,
3677}; 3684};
@@ -3707,7 +3714,7 @@ static struct omap_hwmod_addr_space omap44xx_dss_dispc_dma_addrs[] = {
3707static struct omap_hwmod_ocp_if omap44xx_l3_main_2__dss_dispc = { 3714static struct omap_hwmod_ocp_if omap44xx_l3_main_2__dss_dispc = {
3708 .master = &omap44xx_l3_main_2_hwmod, 3715 .master = &omap44xx_l3_main_2_hwmod,
3709 .slave = &omap44xx_dss_dispc_hwmod, 3716 .slave = &omap44xx_dss_dispc_hwmod,
3710 .clk = "dss_fck", 3717 .clk = "l3_div_ck",
3711 .addr = omap44xx_dss_dispc_dma_addrs, 3718 .addr = omap44xx_dss_dispc_dma_addrs,
3712 .user = OCP_USER_SDMA, 3719 .user = OCP_USER_SDMA,
3713}; 3720};
@@ -3743,7 +3750,7 @@ static struct omap_hwmod_addr_space omap44xx_dss_dsi1_dma_addrs[] = {
3743static struct omap_hwmod_ocp_if omap44xx_l3_main_2__dss_dsi1 = { 3750static struct omap_hwmod_ocp_if omap44xx_l3_main_2__dss_dsi1 = {
3744 .master = &omap44xx_l3_main_2_hwmod, 3751 .master = &omap44xx_l3_main_2_hwmod,
3745 .slave = &omap44xx_dss_dsi1_hwmod, 3752 .slave = &omap44xx_dss_dsi1_hwmod,
3746 .clk = "dss_fck", 3753 .clk = "l3_div_ck",
3747 .addr = omap44xx_dss_dsi1_dma_addrs, 3754 .addr = omap44xx_dss_dsi1_dma_addrs,
3748 .user = OCP_USER_SDMA, 3755 .user = OCP_USER_SDMA,
3749}; 3756};
@@ -3779,7 +3786,7 @@ static struct omap_hwmod_addr_space omap44xx_dss_dsi2_dma_addrs[] = {
3779static struct omap_hwmod_ocp_if omap44xx_l3_main_2__dss_dsi2 = { 3786static struct omap_hwmod_ocp_if omap44xx_l3_main_2__dss_dsi2 = {
3780 .master = &omap44xx_l3_main_2_hwmod, 3787 .master = &omap44xx_l3_main_2_hwmod,
3781 .slave = &omap44xx_dss_dsi2_hwmod, 3788 .slave = &omap44xx_dss_dsi2_hwmod,
3782 .clk = "dss_fck", 3789 .clk = "l3_div_ck",
3783 .addr = omap44xx_dss_dsi2_dma_addrs, 3790 .addr = omap44xx_dss_dsi2_dma_addrs,
3784 .user = OCP_USER_SDMA, 3791 .user = OCP_USER_SDMA,
3785}; 3792};
@@ -3815,7 +3822,7 @@ static struct omap_hwmod_addr_space omap44xx_dss_hdmi_dma_addrs[] = {
3815static struct omap_hwmod_ocp_if omap44xx_l3_main_2__dss_hdmi = { 3822static struct omap_hwmod_ocp_if omap44xx_l3_main_2__dss_hdmi = {
3816 .master = &omap44xx_l3_main_2_hwmod, 3823 .master = &omap44xx_l3_main_2_hwmod,
3817 .slave = &omap44xx_dss_hdmi_hwmod, 3824 .slave = &omap44xx_dss_hdmi_hwmod,
3818 .clk = "dss_fck", 3825 .clk = "l3_div_ck",
3819 .addr = omap44xx_dss_hdmi_dma_addrs, 3826 .addr = omap44xx_dss_hdmi_dma_addrs,
3820 .user = OCP_USER_SDMA, 3827 .user = OCP_USER_SDMA,
3821}; 3828};
@@ -3851,7 +3858,7 @@ static struct omap_hwmod_addr_space omap44xx_dss_rfbi_dma_addrs[] = {
3851static struct omap_hwmod_ocp_if omap44xx_l3_main_2__dss_rfbi = { 3858static struct omap_hwmod_ocp_if omap44xx_l3_main_2__dss_rfbi = {
3852 .master = &omap44xx_l3_main_2_hwmod, 3859 .master = &omap44xx_l3_main_2_hwmod,
3853 .slave = &omap44xx_dss_rfbi_hwmod, 3860 .slave = &omap44xx_dss_rfbi_hwmod,
3854 .clk = "dss_fck", 3861 .clk = "l3_div_ck",
3855 .addr = omap44xx_dss_rfbi_dma_addrs, 3862 .addr = omap44xx_dss_rfbi_dma_addrs,
3856 .user = OCP_USER_SDMA, 3863 .user = OCP_USER_SDMA,
3857}; 3864};
@@ -3887,7 +3894,7 @@ static struct omap_hwmod_addr_space omap44xx_dss_venc_dma_addrs[] = {
3887static struct omap_hwmod_ocp_if omap44xx_l3_main_2__dss_venc = { 3894static struct omap_hwmod_ocp_if omap44xx_l3_main_2__dss_venc = {
3888 .master = &omap44xx_l3_main_2_hwmod, 3895 .master = &omap44xx_l3_main_2_hwmod,
3889 .slave = &omap44xx_dss_venc_hwmod, 3896 .slave = &omap44xx_dss_venc_hwmod,
3890 .clk = "dss_fck", 3897 .clk = "l3_div_ck",
3891 .addr = omap44xx_dss_venc_dma_addrs, 3898 .addr = omap44xx_dss_venc_dma_addrs,
3892 .user = OCP_USER_SDMA, 3899 .user = OCP_USER_SDMA,
3893}; 3900};
diff --git a/arch/arm/mach-omap2/omap_hwmod_54xx_data.c b/arch/arm/mach-omap2/omap_hwmod_54xx_data.c
index 5ec786a76d3c..3e9523084b2a 100644
--- a/arch/arm/mach-omap2/omap_hwmod_54xx_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_54xx_data.c
@@ -421,6 +421,7 @@ static struct omap_hwmod omap54xx_dss_dispc_hwmod = {
421 .opt_clks = dss_dispc_opt_clks, 421 .opt_clks = dss_dispc_opt_clks,
422 .opt_clks_cnt = ARRAY_SIZE(dss_dispc_opt_clks), 422 .opt_clks_cnt = ARRAY_SIZE(dss_dispc_opt_clks),
423 .dev_attr = &dss_dispc_dev_attr, 423 .dev_attr = &dss_dispc_dev_attr,
424 .parent_hwmod = &omap54xx_dss_hwmod,
424}; 425};
425 426
426/* 427/*
@@ -462,6 +463,7 @@ static struct omap_hwmod omap54xx_dss_dsi1_a_hwmod = {
462 }, 463 },
463 .opt_clks = dss_dsi1_a_opt_clks, 464 .opt_clks = dss_dsi1_a_opt_clks,
464 .opt_clks_cnt = ARRAY_SIZE(dss_dsi1_a_opt_clks), 465 .opt_clks_cnt = ARRAY_SIZE(dss_dsi1_a_opt_clks),
466 .parent_hwmod = &omap54xx_dss_hwmod,
465}; 467};
466 468
467/* dss_dsi1_c */ 469/* dss_dsi1_c */
@@ -482,6 +484,7 @@ static struct omap_hwmod omap54xx_dss_dsi1_c_hwmod = {
482 }, 484 },
483 .opt_clks = dss_dsi1_c_opt_clks, 485 .opt_clks = dss_dsi1_c_opt_clks,
484 .opt_clks_cnt = ARRAY_SIZE(dss_dsi1_c_opt_clks), 486 .opt_clks_cnt = ARRAY_SIZE(dss_dsi1_c_opt_clks),
487 .parent_hwmod = &omap54xx_dss_hwmod,
485}; 488};
486 489
487/* 490/*
@@ -521,6 +524,7 @@ static struct omap_hwmod omap54xx_dss_hdmi_hwmod = {
521 }, 524 },
522 .opt_clks = dss_hdmi_opt_clks, 525 .opt_clks = dss_hdmi_opt_clks,
523 .opt_clks_cnt = ARRAY_SIZE(dss_hdmi_opt_clks), 526 .opt_clks_cnt = ARRAY_SIZE(dss_hdmi_opt_clks),
527 .parent_hwmod = &omap54xx_dss_hwmod,
524}; 528};
525 529
526/* 530/*
@@ -560,6 +564,7 @@ static struct omap_hwmod omap54xx_dss_rfbi_hwmod = {
560 }, 564 },
561 .opt_clks = dss_rfbi_opt_clks, 565 .opt_clks = dss_rfbi_opt_clks,
562 .opt_clks_cnt = ARRAY_SIZE(dss_rfbi_opt_clks), 566 .opt_clks_cnt = ARRAY_SIZE(dss_rfbi_opt_clks),
567 .parent_hwmod = &omap54xx_dss_hwmod,
563}; 568};
564 569
565/* 570/*
diff --git a/arch/arm/mach-omap2/omap_hwmod_7xx_data.c b/arch/arm/mach-omap2/omap_hwmod_7xx_data.c
index 711c97e90990..ffd6604cd546 100644
--- a/arch/arm/mach-omap2/omap_hwmod_7xx_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_7xx_data.c
@@ -2075,6 +2075,70 @@ static struct omap_hwmod dra7xx_uart6_hwmod = {
2075 }, 2075 },
2076}; 2076};
2077 2077
2078/* uart7 */
2079static struct omap_hwmod dra7xx_uart7_hwmod = {
2080 .name = "uart7",
2081 .class = &dra7xx_uart_hwmod_class,
2082 .clkdm_name = "l4per2_clkdm",
2083 .main_clk = "uart7_gfclk_mux",
2084 .flags = HWMOD_SWSUP_SIDLE_ACT,
2085 .prcm = {
2086 .omap4 = {
2087 .clkctrl_offs = DRA7XX_CM_L4PER2_UART7_CLKCTRL_OFFSET,
2088 .context_offs = DRA7XX_RM_L4PER2_UART7_CONTEXT_OFFSET,
2089 .modulemode = MODULEMODE_SWCTRL,
2090 },
2091 },
2092};
2093
2094/* uart8 */
2095static struct omap_hwmod dra7xx_uart8_hwmod = {
2096 .name = "uart8",
2097 .class = &dra7xx_uart_hwmod_class,
2098 .clkdm_name = "l4per2_clkdm",
2099 .main_clk = "uart8_gfclk_mux",
2100 .flags = HWMOD_SWSUP_SIDLE_ACT,
2101 .prcm = {
2102 .omap4 = {
2103 .clkctrl_offs = DRA7XX_CM_L4PER2_UART8_CLKCTRL_OFFSET,
2104 .context_offs = DRA7XX_RM_L4PER2_UART8_CONTEXT_OFFSET,
2105 .modulemode = MODULEMODE_SWCTRL,
2106 },
2107 },
2108};
2109
2110/* uart9 */
2111static struct omap_hwmod dra7xx_uart9_hwmod = {
2112 .name = "uart9",
2113 .class = &dra7xx_uart_hwmod_class,
2114 .clkdm_name = "l4per2_clkdm",
2115 .main_clk = "uart9_gfclk_mux",
2116 .flags = HWMOD_SWSUP_SIDLE_ACT,
2117 .prcm = {
2118 .omap4 = {
2119 .clkctrl_offs = DRA7XX_CM_L4PER2_UART9_CLKCTRL_OFFSET,
2120 .context_offs = DRA7XX_RM_L4PER2_UART9_CONTEXT_OFFSET,
2121 .modulemode = MODULEMODE_SWCTRL,
2122 },
2123 },
2124};
2125
2126/* uart10 */
2127static struct omap_hwmod dra7xx_uart10_hwmod = {
2128 .name = "uart10",
2129 .class = &dra7xx_uart_hwmod_class,
2130 .clkdm_name = "wkupaon_clkdm",
2131 .main_clk = "uart10_gfclk_mux",
2132 .flags = HWMOD_SWSUP_SIDLE_ACT,
2133 .prcm = {
2134 .omap4 = {
2135 .clkctrl_offs = DRA7XX_CM_WKUPAON_UART10_CLKCTRL_OFFSET,
2136 .context_offs = DRA7XX_RM_WKUPAON_UART10_CONTEXT_OFFSET,
2137 .modulemode = MODULEMODE_SWCTRL,
2138 },
2139 },
2140};
2141
2078/* 2142/*
2079 * 'usb_otg_ss' class 2143 * 'usb_otg_ss' class
2080 * 2144 *
@@ -3095,6 +3159,38 @@ static struct omap_hwmod_ocp_if dra7xx_l4_per1__uart6 = {
3095 .user = OCP_USER_MPU | OCP_USER_SDMA, 3159 .user = OCP_USER_MPU | OCP_USER_SDMA,
3096}; 3160};
3097 3161
3162/* l4_per2 -> uart7 */
3163static struct omap_hwmod_ocp_if dra7xx_l4_per2__uart7 = {
3164 .master = &dra7xx_l4_per2_hwmod,
3165 .slave = &dra7xx_uart7_hwmod,
3166 .clk = "l3_iclk_div",
3167 .user = OCP_USER_MPU | OCP_USER_SDMA,
3168};
3169
3170/* l4_per2 -> uart8 */
3171static struct omap_hwmod_ocp_if dra7xx_l4_per2__uart8 = {
3172 .master = &dra7xx_l4_per2_hwmod,
3173 .slave = &dra7xx_uart8_hwmod,
3174 .clk = "l3_iclk_div",
3175 .user = OCP_USER_MPU | OCP_USER_SDMA,
3176};
3177
3178/* l4_per2 -> uart9 */
3179static struct omap_hwmod_ocp_if dra7xx_l4_per2__uart9 = {
3180 .master = &dra7xx_l4_per2_hwmod,
3181 .slave = &dra7xx_uart9_hwmod,
3182 .clk = "l3_iclk_div",
3183 .user = OCP_USER_MPU | OCP_USER_SDMA,
3184};
3185
3186/* l4_wkup -> uart10 */
3187static struct omap_hwmod_ocp_if dra7xx_l4_wkup__uart10 = {
3188 .master = &dra7xx_l4_wkup_hwmod,
3189 .slave = &dra7xx_uart10_hwmod,
3190 .clk = "wkupaon_iclk_mux",
3191 .user = OCP_USER_MPU | OCP_USER_SDMA,
3192};
3193
3098/* l4_per3 -> usb_otg_ss1 */ 3194/* l4_per3 -> usb_otg_ss1 */
3099static struct omap_hwmod_ocp_if dra7xx_l4_per3__usb_otg_ss1 = { 3195static struct omap_hwmod_ocp_if dra7xx_l4_per3__usb_otg_ss1 = {
3100 .master = &dra7xx_l4_per3_hwmod, 3196 .master = &dra7xx_l4_per3_hwmod,
@@ -3259,6 +3355,10 @@ static struct omap_hwmod_ocp_if *dra7xx_hwmod_ocp_ifs[] __initdata = {
3259 &dra7xx_l4_per1__uart4, 3355 &dra7xx_l4_per1__uart4,
3260 &dra7xx_l4_per1__uart5, 3356 &dra7xx_l4_per1__uart5,
3261 &dra7xx_l4_per1__uart6, 3357 &dra7xx_l4_per1__uart6,
3358 &dra7xx_l4_per2__uart7,
3359 &dra7xx_l4_per2__uart8,
3360 &dra7xx_l4_per2__uart9,
3361 &dra7xx_l4_wkup__uart10,
3262 &dra7xx_l4_per3__usb_otg_ss1, 3362 &dra7xx_l4_per3__usb_otg_ss1,
3263 &dra7xx_l4_per3__usb_otg_ss2, 3363 &dra7xx_l4_per3__usb_otg_ss2,
3264 &dra7xx_l4_per3__usb_otg_ss3, 3364 &dra7xx_l4_per3__usb_otg_ss3,
diff --git a/arch/arm/mach-omap2/pm44xx.c b/arch/arm/mach-omap2/pm44xx.c
index 503097c72b82..d697cecf762b 100644
--- a/arch/arm/mach-omap2/pm44xx.c
+++ b/arch/arm/mach-omap2/pm44xx.c
@@ -37,6 +37,16 @@ struct power_state {
37 struct list_head node; 37 struct list_head node;
38}; 38};
39 39
40/**
41 * struct static_dep_map - Static dependency map
42 * @from: from clockdomain
43 * @to: to clockdomain
44 */
45struct static_dep_map {
46 const char *from;
47 const char *to;
48};
49
40static u32 cpu_suspend_state = PWRDM_POWER_OFF; 50static u32 cpu_suspend_state = PWRDM_POWER_OFF;
41 51
42static LIST_HEAD(pwrst_list); 52static LIST_HEAD(pwrst_list);
@@ -148,94 +158,61 @@ static void omap_default_idle(void)
148 omap_do_wfi(); 158 omap_do_wfi();
149} 159}
150 160
151/** 161/*
152 * omap4_init_static_deps - Add OMAP4 static dependencies 162 * The dynamic dependency between MPUSS -> MEMIF and
153 * 163 * MPUSS -> L4_PER/L3_* and DUCATI -> L3_* doesn't work as
154 * Add needed static clockdomain dependencies on OMAP4 devices. 164 * expected. The hardware recommendation is to enable static
155 * Return: 0 on success or 'err' on failures 165 * dependencies for these to avoid system lock ups or random crashes.
166 * The L4 wakeup depedency is added to workaround the OCP sync hardware
167 * BUG with 32K synctimer which lead to incorrect timer value read
168 * from the 32K counter. The BUG applies for GPTIMER1 and WDT2 which
169 * are part of L4 wakeup clockdomain.
156 */ 170 */
157static inline int omap4_init_static_deps(void) 171static const struct static_dep_map omap4_static_dep_map[] = {
158{ 172 {.from = "mpuss_clkdm", .to = "l3_emif_clkdm"},
159 struct clockdomain *emif_clkdm, *mpuss_clkdm, *l3_1_clkdm; 173 {.from = "mpuss_clkdm", .to = "l3_1_clkdm"},
160 struct clockdomain *ducati_clkdm, *l3_2_clkdm; 174 {.from = "mpuss_clkdm", .to = "l3_2_clkdm"},
161 int ret = 0; 175 {.from = "ducati_clkdm", .to = "l3_1_clkdm"},
162 176 {.from = "ducati_clkdm", .to = "l3_2_clkdm"},
163 if (omap_rev() == OMAP4430_REV_ES1_0) { 177 {.from = NULL} /* TERMINATION */
164 WARN(1, "Power Management not supported on OMAP4430 ES1.0\n"); 178};
165 return -ENODEV;
166 }
167
168 pr_err("Power Management for TI OMAP4.\n");
169 /*
170 * OMAP4 chip PM currently works only with certain (newer)
171 * versions of bootloaders. This is due to missing code in the
172 * kernel to properly reset and initialize some devices.
173 * http://www.spinics.net/lists/arm-kernel/msg218641.html
174 */
175 pr_warn("OMAP4 PM: u-boot >= v2012.07 is required for full PM support\n");
176
177 ret = pwrdm_for_each(pwrdms_setup, NULL);
178 if (ret) {
179 pr_err("Failed to setup powerdomains\n");
180 return ret;
181 }
182
183 /*
184 * The dynamic dependency between MPUSS -> MEMIF and
185 * MPUSS -> L4_PER/L3_* and DUCATI -> L3_* doesn't work as
186 * expected. The hardware recommendation is to enable static
187 * dependencies for these to avoid system lock ups or random crashes.
188 * The L4 wakeup depedency is added to workaround the OCP sync hardware
189 * BUG with 32K synctimer which lead to incorrect timer value read
190 * from the 32K counter. The BUG applies for GPTIMER1 and WDT2 which
191 * are part of L4 wakeup clockdomain.
192 */
193 mpuss_clkdm = clkdm_lookup("mpuss_clkdm");
194 emif_clkdm = clkdm_lookup("l3_emif_clkdm");
195 l3_1_clkdm = clkdm_lookup("l3_1_clkdm");
196 l3_2_clkdm = clkdm_lookup("l3_2_clkdm");
197 ducati_clkdm = clkdm_lookup("ducati_clkdm");
198 if ((!mpuss_clkdm) || (!emif_clkdm) || (!l3_1_clkdm) ||
199 (!l3_2_clkdm) || (!ducati_clkdm))
200 return -EINVAL;
201
202 ret = clkdm_add_wkdep(mpuss_clkdm, emif_clkdm);
203 ret |= clkdm_add_wkdep(mpuss_clkdm, l3_1_clkdm);
204 ret |= clkdm_add_wkdep(mpuss_clkdm, l3_2_clkdm);
205 ret |= clkdm_add_wkdep(ducati_clkdm, l3_1_clkdm);
206 ret |= clkdm_add_wkdep(ducati_clkdm, l3_2_clkdm);
207 if (ret) {
208 pr_err("Failed to add MPUSS -> L3/EMIF/L4PER, DUCATI -> L3 wakeup dependency\n");
209 return -EINVAL;
210 }
211 179
212 return ret; 180static const struct static_dep_map omap5_dra7_static_dep_map[] = {
213} 181 {.from = "mpu_clkdm", .to = "emif_clkdm"},
182 {.from = NULL} /* TERMINATION */
183};
214 184
215/** 185/**
216 * omap5_dra7_init_static_deps - Init static clkdm dependencies on OMAP5 and 186 * omap4plus_init_static_deps() - Initialize a static dependency map
217 * DRA7 187 * @map: Mapping of clock domains
218 *
219 * The dynamic dependency between MPUSS -> EMIF is broken and has
220 * not worked as expected. The hardware recommendation is to
221 * enable static dependencies for these to avoid system
222 * lock ups or random crashes.
223 */ 188 */
224static inline int omap5_dra7_init_static_deps(void) 189static inline int omap4plus_init_static_deps(const struct static_dep_map *map)
225{ 190{
226 struct clockdomain *mpuss_clkdm, *emif_clkdm;
227 int ret; 191 int ret;
192 struct clockdomain *from, *to;
193
194 if (!map)
195 return 0;
228 196
229 mpuss_clkdm = clkdm_lookup("mpu_clkdm"); 197 while (map->from) {
230 emif_clkdm = clkdm_lookup("emif_clkdm"); 198 from = clkdm_lookup(map->from);
231 if (!mpuss_clkdm || !emif_clkdm) 199 to = clkdm_lookup(map->to);
232 return -EINVAL; 200 if (!from || !to) {
201 pr_err("Failed lookup %s or %s for wakeup dependency\n",
202 map->from, map->to);
203 return -EINVAL;
204 }
205 ret = clkdm_add_wkdep(from, to);
206 if (ret) {
207 pr_err("Failed to add %s -> %s wakeup dependency(%d)\n",
208 map->from, map->to, ret);
209 return ret;
210 }
233 211
234 ret = clkdm_add_wkdep(mpuss_clkdm, emif_clkdm); 212 map++;
235 if (ret) 213 };
236 pr_err("Failed to add MPUSS -> EMIF wakeup dependency\n");
237 214
238 return ret; 215 return 0;
239} 216}
240 217
241/** 218/**
@@ -272,6 +249,15 @@ int __init omap4_pm_init(void)
272 249
273 pr_info("Power Management for TI OMAP4+ devices.\n"); 250 pr_info("Power Management for TI OMAP4+ devices.\n");
274 251
252 /*
253 * OMAP4 chip PM currently works only with certain (newer)
254 * versions of bootloaders. This is due to missing code in the
255 * kernel to properly reset and initialize some devices.
256 * http://www.spinics.net/lists/arm-kernel/msg218641.html
257 */
258 if (cpu_is_omap44xx())
259 pr_warn("OMAP4 PM: u-boot >= v2012.07 is required for full PM support\n");
260
275 ret = pwrdm_for_each(pwrdms_setup, NULL); 261 ret = pwrdm_for_each(pwrdms_setup, NULL);
276 if (ret) { 262 if (ret) {
277 pr_err("Failed to setup powerdomains.\n"); 263 pr_err("Failed to setup powerdomains.\n");
@@ -279,9 +265,9 @@ int __init omap4_pm_init(void)
279 } 265 }
280 266
281 if (cpu_is_omap44xx()) 267 if (cpu_is_omap44xx())
282 ret = omap4_init_static_deps(); 268 ret = omap4plus_init_static_deps(omap4_static_dep_map);
283 else if (soc_is_omap54xx() || soc_is_dra7xx()) 269 else if (soc_is_omap54xx() || soc_is_dra7xx())
284 ret = omap5_dra7_init_static_deps(); 270 ret = omap4plus_init_static_deps(omap5_dra7_static_dep_map);
285 271
286 if (ret) { 272 if (ret) {
287 pr_err("Failed to initialise static dependencies.\n"); 273 pr_err("Failed to initialise static dependencies.\n");
diff --git a/arch/arm/mach-omap2/prm.h b/arch/arm/mach-omap2/prm.h
index 48480d557b61..77752e49d8d4 100644
--- a/arch/arm/mach-omap2/prm.h
+++ b/arch/arm/mach-omap2/prm.h
@@ -29,6 +29,7 @@ int of_prcm_init(void);
29 * PRM_HAS_VOLTAGE: has voltage domains 29 * PRM_HAS_VOLTAGE: has voltage domains
30 */ 30 */
31#define PRM_HAS_IO_WAKEUP (1 << 0) 31#define PRM_HAS_IO_WAKEUP (1 << 0)
32#define PRM_HAS_VOLTAGE (1 << 1)
32 33
33/* 34/*
34 * MAX_MODULE_SOFTRESET_WAIT: Maximum microseconds to wait for OMAP 35 * MAX_MODULE_SOFTRESET_WAIT: Maximum microseconds to wait for OMAP
@@ -127,6 +128,8 @@ struct prm_reset_src_map {
127 * @was_any_context_lost_old: ptr to the SoC PRM context loss test fn 128 * @was_any_context_lost_old: ptr to the SoC PRM context loss test fn
128 * @clear_context_loss_flags_old: ptr to the SoC PRM context loss flag clear fn 129 * @clear_context_loss_flags_old: ptr to the SoC PRM context loss flag clear fn
129 * @late_init: ptr to the late init function 130 * @late_init: ptr to the late init function
131 * @assert_hardreset: ptr to the SoC PRM hardreset assert impl
132 * @deassert_hardreset: ptr to the SoC PRM hardreset deassert impl
130 * 133 *
131 * XXX @was_any_context_lost_old and @clear_context_loss_flags_old are 134 * XXX @was_any_context_lost_old and @clear_context_loss_flags_old are
132 * deprecated. 135 * deprecated.
@@ -136,14 +139,27 @@ struct prm_ll_data {
136 bool (*was_any_context_lost_old)(u8 part, s16 inst, u16 idx); 139 bool (*was_any_context_lost_old)(u8 part, s16 inst, u16 idx);
137 void (*clear_context_loss_flags_old)(u8 part, s16 inst, u16 idx); 140 void (*clear_context_loss_flags_old)(u8 part, s16 inst, u16 idx);
138 int (*late_init)(void); 141 int (*late_init)(void);
142 int (*assert_hardreset)(u8 shift, u8 part, s16 prm_mod, u16 offset);
143 int (*deassert_hardreset)(u8 shift, u8 st_shift, u8 part, s16 prm_mod,
144 u16 offset, u16 st_offset);
145 int (*is_hardreset_asserted)(u8 shift, u8 part, s16 prm_mod,
146 u16 offset);
147 void (*reset_system)(void);
139}; 148};
140 149
141extern int prm_register(struct prm_ll_data *pld); 150extern int prm_register(struct prm_ll_data *pld);
142extern int prm_unregister(struct prm_ll_data *pld); 151extern int prm_unregister(struct prm_ll_data *pld);
143 152
153int omap_prm_assert_hardreset(u8 shift, u8 part, s16 prm_mod, u16 offset);
154int omap_prm_deassert_hardreset(u8 shift, u8 st_shift, u8 part, s16 prm_mod,
155 u16 offset, u16 st_offset);
156int omap_prm_is_hardreset_asserted(u8 shift, u8 part, s16 prm_mod, u16 offset);
144extern u32 prm_read_reset_sources(void); 157extern u32 prm_read_reset_sources(void);
145extern bool prm_was_any_context_lost_old(u8 part, s16 inst, u16 idx); 158extern bool prm_was_any_context_lost_old(u8 part, s16 inst, u16 idx);
146extern void prm_clear_context_loss_flags_old(u8 part, s16 inst, u16 idx); 159extern void prm_clear_context_loss_flags_old(u8 part, s16 inst, u16 idx);
160void omap_prm_reset_system(void);
161
162void omap_prm_reconfigure_io_chain(void);
147 163
148#endif 164#endif
149 165
diff --git a/arch/arm/mach-omap2/prm2xxx.c b/arch/arm/mach-omap2/prm2xxx.c
index 86958050547a..af0f15278fc2 100644
--- a/arch/arm/mach-omap2/prm2xxx.c
+++ b/arch/arm/mach-omap2/prm2xxx.c
@@ -106,7 +106,7 @@ static int omap2xxx_pwrst_to_common_pwrst(u8 omap2xxx_pwrst)
106 * Set the DPLL reset bit, which should reboot the SoC. This is the 106 * Set the DPLL reset bit, which should reboot the SoC. This is the
107 * recommended way to restart the SoC. No return value. 107 * recommended way to restart the SoC. No return value.
108 */ 108 */
109void omap2xxx_prm_dpll_reset(void) 109static void omap2xxx_prm_dpll_reset(void)
110{ 110{
111 omap2_prm_set_mod_reg_bits(OMAP_RST_DPLL3_MASK, WKUP_MOD, 111 omap2_prm_set_mod_reg_bits(OMAP_RST_DPLL3_MASK, WKUP_MOD,
112 OMAP2_RM_RSTCTRL); 112 OMAP2_RM_RSTCTRL);
@@ -212,6 +212,10 @@ struct pwrdm_ops omap2_pwrdm_operations = {
212 212
213static struct prm_ll_data omap2xxx_prm_ll_data = { 213static struct prm_ll_data omap2xxx_prm_ll_data = {
214 .read_reset_sources = &omap2xxx_prm_read_reset_sources, 214 .read_reset_sources = &omap2xxx_prm_read_reset_sources,
215 .assert_hardreset = &omap2_prm_assert_hardreset,
216 .deassert_hardreset = &omap2_prm_deassert_hardreset,
217 .is_hardreset_asserted = &omap2_prm_is_hardreset_asserted,
218 .reset_system = &omap2xxx_prm_dpll_reset,
215}; 219};
216 220
217int __init omap2xxx_prm_init(void) 221int __init omap2xxx_prm_init(void)
diff --git a/arch/arm/mach-omap2/prm2xxx.h b/arch/arm/mach-omap2/prm2xxx.h
index d73414139292..1d51643062f7 100644
--- a/arch/arm/mach-omap2/prm2xxx.h
+++ b/arch/arm/mach-omap2/prm2xxx.h
@@ -124,7 +124,6 @@
124extern int omap2xxx_clkdm_sleep(struct clockdomain *clkdm); 124extern int omap2xxx_clkdm_sleep(struct clockdomain *clkdm);
125extern int omap2xxx_clkdm_wakeup(struct clockdomain *clkdm); 125extern int omap2xxx_clkdm_wakeup(struct clockdomain *clkdm);
126 126
127extern void omap2xxx_prm_dpll_reset(void);
128void omap2xxx_prm_clear_mod_irqs(s16 module, u8 regs, u32 wkst_mask); 127void omap2xxx_prm_clear_mod_irqs(s16 module, u8 regs, u32 wkst_mask);
129 128
130extern int __init omap2xxx_prm_init(void); 129extern int __init omap2xxx_prm_init(void);
diff --git a/arch/arm/mach-omap2/prm2xxx_3xxx.c b/arch/arm/mach-omap2/prm2xxx_3xxx.c
index c13b4e293ffa..cc3341f263cd 100644
--- a/arch/arm/mach-omap2/prm2xxx_3xxx.c
+++ b/arch/arm/mach-omap2/prm2xxx_3xxx.c
@@ -24,14 +24,16 @@
24/** 24/**
25 * omap2_prm_is_hardreset_asserted - read the HW reset line state of 25 * omap2_prm_is_hardreset_asserted - read the HW reset line state of
26 * submodules contained in the hwmod module 26 * submodules contained in the hwmod module
27 * @prm_mod: PRM submodule base (e.g. CORE_MOD)
28 * @shift: register bit shift corresponding to the reset line to check 27 * @shift: register bit shift corresponding to the reset line to check
28 * @part: PRM partition, ignored for OMAP2
29 * @prm_mod: PRM submodule base (e.g. CORE_MOD)
30 * @offset: register offset, ignored for OMAP2
29 * 31 *
30 * Returns 1 if the (sub)module hardreset line is currently asserted, 32 * Returns 1 if the (sub)module hardreset line is currently asserted,
31 * 0 if the (sub)module hardreset line is not currently asserted, or 33 * 0 if the (sub)module hardreset line is not currently asserted, or
32 * -EINVAL if called while running on a non-OMAP2/3 chip. 34 * -EINVAL if called while running on a non-OMAP2/3 chip.
33 */ 35 */
34int omap2_prm_is_hardreset_asserted(s16 prm_mod, u8 shift) 36int omap2_prm_is_hardreset_asserted(u8 shift, u8 part, s16 prm_mod, u16 offset)
35{ 37{
36 return omap2_prm_read_mod_bits_shift(prm_mod, OMAP2_RM_RSTCTRL, 38 return omap2_prm_read_mod_bits_shift(prm_mod, OMAP2_RM_RSTCTRL,
37 (1 << shift)); 39 (1 << shift));
@@ -39,8 +41,10 @@ int omap2_prm_is_hardreset_asserted(s16 prm_mod, u8 shift)
39 41
40/** 42/**
41 * omap2_prm_assert_hardreset - assert the HW reset line of a submodule 43 * omap2_prm_assert_hardreset - assert the HW reset line of a submodule
42 * @prm_mod: PRM submodule base (e.g. CORE_MOD)
43 * @shift: register bit shift corresponding to the reset line to assert 44 * @shift: register bit shift corresponding to the reset line to assert
45 * @part: PRM partition, ignored for OMAP2
46 * @prm_mod: PRM submodule base (e.g. CORE_MOD)
47 * @offset: register offset, ignored for OMAP2
44 * 48 *
45 * Some IPs like dsp or iva contain processors that require an HW 49 * Some IPs like dsp or iva contain processors that require an HW
46 * reset line to be asserted / deasserted in order to fully enable the 50 * reset line to be asserted / deasserted in order to fully enable the
@@ -49,7 +53,7 @@ int omap2_prm_is_hardreset_asserted(s16 prm_mod, u8 shift)
49 * place the submodule into reset. Returns 0 upon success or -EINVAL 53 * place the submodule into reset. Returns 0 upon success or -EINVAL
50 * upon an argument error. 54 * upon an argument error.
51 */ 55 */
52int omap2_prm_assert_hardreset(s16 prm_mod, u8 shift) 56int omap2_prm_assert_hardreset(u8 shift, u8 part, s16 prm_mod, u16 offset)
53{ 57{
54 u32 mask; 58 u32 mask;
55 59
@@ -64,6 +68,10 @@ int omap2_prm_assert_hardreset(s16 prm_mod, u8 shift)
64 * @prm_mod: PRM submodule base (e.g. CORE_MOD) 68 * @prm_mod: PRM submodule base (e.g. CORE_MOD)
65 * @rst_shift: register bit shift corresponding to the reset line to deassert 69 * @rst_shift: register bit shift corresponding to the reset line to deassert
66 * @st_shift: register bit shift for the status of the deasserted submodule 70 * @st_shift: register bit shift for the status of the deasserted submodule
71 * @part: PRM partition, not used for OMAP2
72 * @prm_mod: PRM submodule base (e.g. CORE_MOD)
73 * @rst_offset: reset register offset, not used for OMAP2
74 * @st_offset: reset status register offset, not used for OMAP2
67 * 75 *
68 * Some IPs like dsp or iva contain processors that require an HW 76 * Some IPs like dsp or iva contain processors that require an HW
69 * reset line to be asserted / deasserted in order to fully enable the 77 * reset line to be asserted / deasserted in order to fully enable the
@@ -74,7 +82,8 @@ int omap2_prm_assert_hardreset(s16 prm_mod, u8 shift)
74 * -EINVAL upon an argument error, -EEXIST if the submodule was already out 82 * -EINVAL upon an argument error, -EEXIST if the submodule was already out
75 * of reset, or -EBUSY if the submodule did not exit reset promptly. 83 * of reset, or -EBUSY if the submodule did not exit reset promptly.
76 */ 84 */
77int omap2_prm_deassert_hardreset(s16 prm_mod, u8 rst_shift, u8 st_shift) 85int omap2_prm_deassert_hardreset(u8 rst_shift, u8 st_shift, u8 part,
86 s16 prm_mod, u16 rst_offset, u16 st_offset)
78{ 87{
79 u32 rst, st; 88 u32 rst, st;
80 int c; 89 int c;
diff --git a/arch/arm/mach-omap2/prm2xxx_3xxx.h b/arch/arm/mach-omap2/prm2xxx_3xxx.h
index 1a3a96392b97..f57e29b0e041 100644
--- a/arch/arm/mach-omap2/prm2xxx_3xxx.h
+++ b/arch/arm/mach-omap2/prm2xxx_3xxx.h
@@ -100,9 +100,12 @@ static inline u32 omap2_prm_clear_mod_reg_bits(u32 bits, s16 module, s16 idx)
100} 100}
101 101
102/* These omap2_ PRM functions apply to both OMAP2 and 3 */ 102/* These omap2_ PRM functions apply to both OMAP2 and 3 */
103extern int omap2_prm_is_hardreset_asserted(s16 prm_mod, u8 shift); 103int omap2_prm_is_hardreset_asserted(u8 shift, u8 part, s16 prm_mod, u16 offset);
104extern int omap2_prm_assert_hardreset(s16 prm_mod, u8 shift); 104int omap2_prm_assert_hardreset(u8 shift, u8 part, s16 prm_mod,
105extern int omap2_prm_deassert_hardreset(s16 prm_mod, u8 rst_shift, u8 st_shift); 105 u16 offset);
106int omap2_prm_deassert_hardreset(u8 rst_shift, u8 st_shift, u8 part,
107 s16 prm_mod, u16 reset_offset,
108 u16 st_offset);
106 109
107extern int omap2_pwrdm_set_next_pwrst(struct powerdomain *pwrdm, u8 pwrst); 110extern int omap2_pwrdm_set_next_pwrst(struct powerdomain *pwrdm, u8 pwrst);
108extern int omap2_pwrdm_read_next_pwrst(struct powerdomain *pwrdm); 111extern int omap2_pwrdm_read_next_pwrst(struct powerdomain *pwrdm);
diff --git a/arch/arm/mach-omap2/prm33xx.c b/arch/arm/mach-omap2/prm33xx.c
index 62709cd2f9c5..02f628601b09 100644
--- a/arch/arm/mach-omap2/prm33xx.c
+++ b/arch/arm/mach-omap2/prm33xx.c
@@ -23,20 +23,24 @@
23#include "prm33xx.h" 23#include "prm33xx.h"
24#include "prm-regbits-33xx.h" 24#include "prm-regbits-33xx.h"
25 25
26#define AM33XX_PRM_RSTCTRL_OFFSET 0x0000
27
28#define AM33XX_RST_GLOBAL_WARM_SW_MASK (1 << 0)
29
26/* Read a register in a PRM instance */ 30/* Read a register in a PRM instance */
27u32 am33xx_prm_read_reg(s16 inst, u16 idx) 31static u32 am33xx_prm_read_reg(s16 inst, u16 idx)
28{ 32{
29 return readl_relaxed(prm_base + inst + idx); 33 return readl_relaxed(prm_base + inst + idx);
30} 34}
31 35
32/* Write into a register in a PRM instance */ 36/* Write into a register in a PRM instance */
33void am33xx_prm_write_reg(u32 val, s16 inst, u16 idx) 37static void am33xx_prm_write_reg(u32 val, s16 inst, u16 idx)
34{ 38{
35 writel_relaxed(val, prm_base + inst + idx); 39 writel_relaxed(val, prm_base + inst + idx);
36} 40}
37 41
38/* Read-modify-write a register in PRM. Caller must lock */ 42/* Read-modify-write a register in PRM. Caller must lock */
39u32 am33xx_prm_rmw_reg_bits(u32 mask, u32 bits, s16 inst, s16 idx) 43static u32 am33xx_prm_rmw_reg_bits(u32 mask, u32 bits, s16 inst, s16 idx)
40{ 44{
41 u32 v; 45 u32 v;
42 46
@@ -52,6 +56,7 @@ u32 am33xx_prm_rmw_reg_bits(u32 mask, u32 bits, s16 inst, s16 idx)
52 * am33xx_prm_is_hardreset_asserted - read the HW reset line state of 56 * am33xx_prm_is_hardreset_asserted - read the HW reset line state of
53 * submodules contained in the hwmod module 57 * submodules contained in the hwmod module
54 * @shift: register bit shift corresponding to the reset line to check 58 * @shift: register bit shift corresponding to the reset line to check
59 * @part: PRM partition, ignored for AM33xx
55 * @inst: CM instance register offset (*_INST macro) 60 * @inst: CM instance register offset (*_INST macro)
56 * @rstctrl_offs: RM_RSTCTRL register address offset for this module 61 * @rstctrl_offs: RM_RSTCTRL register address offset for this module
57 * 62 *
@@ -59,7 +64,8 @@ u32 am33xx_prm_rmw_reg_bits(u32 mask, u32 bits, s16 inst, s16 idx)
59 * 0 if the (sub)module hardreset line is not currently asserted, or 64 * 0 if the (sub)module hardreset line is not currently asserted, or
60 * -EINVAL upon parameter error. 65 * -EINVAL upon parameter error.
61 */ 66 */
62int am33xx_prm_is_hardreset_asserted(u8 shift, s16 inst, u16 rstctrl_offs) 67static int am33xx_prm_is_hardreset_asserted(u8 shift, u8 part, s16 inst,
68 u16 rstctrl_offs)
63{ 69{
64 u32 v; 70 u32 v;
65 71
@@ -73,6 +79,7 @@ int am33xx_prm_is_hardreset_asserted(u8 shift, s16 inst, u16 rstctrl_offs)
73/** 79/**
74 * am33xx_prm_assert_hardreset - assert the HW reset line of a submodule 80 * am33xx_prm_assert_hardreset - assert the HW reset line of a submodule
75 * @shift: register bit shift corresponding to the reset line to assert 81 * @shift: register bit shift corresponding to the reset line to assert
82 * @part: CM partition, ignored for AM33xx
76 * @inst: CM instance register offset (*_INST macro) 83 * @inst: CM instance register offset (*_INST macro)
77 * @rstctrl_reg: RM_RSTCTRL register address for this module 84 * @rstctrl_reg: RM_RSTCTRL register address for this module
78 * 85 *
@@ -83,7 +90,8 @@ int am33xx_prm_is_hardreset_asserted(u8 shift, s16 inst, u16 rstctrl_offs)
83 * place the submodule into reset. Returns 0 upon success or -EINVAL 90 * place the submodule into reset. Returns 0 upon success or -EINVAL
84 * upon an argument error. 91 * upon an argument error.
85 */ 92 */
86int am33xx_prm_assert_hardreset(u8 shift, s16 inst, u16 rstctrl_offs) 93static int am33xx_prm_assert_hardreset(u8 shift, u8 part, s16 inst,
94 u16 rstctrl_offs)
87{ 95{
88 u32 mask = 1 << shift; 96 u32 mask = 1 << shift;
89 97
@@ -96,6 +104,8 @@ int am33xx_prm_assert_hardreset(u8 shift, s16 inst, u16 rstctrl_offs)
96 * am33xx_prm_deassert_hardreset - deassert a submodule hardreset line and 104 * am33xx_prm_deassert_hardreset - deassert a submodule hardreset line and
97 * wait 105 * wait
98 * @shift: register bit shift corresponding to the reset line to deassert 106 * @shift: register bit shift corresponding to the reset line to deassert
107 * @st_shift: reset status register bit shift corresponding to the reset line
108 * @part: PRM partition, not used for AM33xx
99 * @inst: CM instance register offset (*_INST macro) 109 * @inst: CM instance register offset (*_INST macro)
100 * @rstctrl_reg: RM_RSTCTRL register address for this module 110 * @rstctrl_reg: RM_RSTCTRL register address for this module
101 * @rstst_reg: RM_RSTST register address for this module 111 * @rstst_reg: RM_RSTST register address for this module
@@ -109,14 +119,15 @@ int am33xx_prm_assert_hardreset(u8 shift, s16 inst, u16 rstctrl_offs)
109 * -EINVAL upon an argument error, -EEXIST if the submodule was already out 119 * -EINVAL upon an argument error, -EEXIST if the submodule was already out
110 * of reset, or -EBUSY if the submodule did not exit reset promptly. 120 * of reset, or -EBUSY if the submodule did not exit reset promptly.
111 */ 121 */
112int am33xx_prm_deassert_hardreset(u8 shift, u8 st_shift, s16 inst, 122static int am33xx_prm_deassert_hardreset(u8 shift, u8 st_shift, u8 part,
113 u16 rstctrl_offs, u16 rstst_offs) 123 s16 inst, u16 rstctrl_offs,
124 u16 rstst_offs)
114{ 125{
115 int c; 126 int c;
116 u32 mask = 1 << st_shift; 127 u32 mask = 1 << st_shift;
117 128
118 /* Check the current status to avoid de-asserting the line twice */ 129 /* Check the current status to avoid de-asserting the line twice */
119 if (am33xx_prm_is_hardreset_asserted(shift, inst, rstctrl_offs) == 0) 130 if (am33xx_prm_is_hardreset_asserted(shift, 0, inst, rstctrl_offs) == 0)
120 return -EEXIST; 131 return -EEXIST;
121 132
122 /* Clear the reset status by writing 1 to the status bit */ 133 /* Clear the reset status by writing 1 to the status bit */
@@ -128,7 +139,7 @@ int am33xx_prm_deassert_hardreset(u8 shift, u8 st_shift, s16 inst,
128 am33xx_prm_rmw_reg_bits(mask, 0, inst, rstctrl_offs); 139 am33xx_prm_rmw_reg_bits(mask, 0, inst, rstctrl_offs);
129 140
130 /* wait the status to be set */ 141 /* wait the status to be set */
131 omap_test_timeout(am33xx_prm_is_hardreset_asserted(st_shift, inst, 142 omap_test_timeout(am33xx_prm_is_hardreset_asserted(st_shift, 0, inst,
132 rstst_offs), 143 rstst_offs),
133 MAX_MODULE_HARDRESET_WAIT, c); 144 MAX_MODULE_HARDRESET_WAIT, c);
134 145
@@ -325,6 +336,23 @@ static int am33xx_check_vcvp(void)
325 return 0; 336 return 0;
326} 337}
327 338
339/**
340 * am33xx_prm_global_warm_sw_reset - reboot the device via warm reset
341 *
342 * Immediately reboots the device through warm reset.
343 */
344static void am33xx_prm_global_warm_sw_reset(void)
345{
346 am33xx_prm_rmw_reg_bits(AM33XX_RST_GLOBAL_WARM_SW_MASK,
347 AM33XX_RST_GLOBAL_WARM_SW_MASK,
348 AM33XX_PRM_DEVICE_MOD,
349 AM33XX_PRM_RSTCTRL_OFFSET);
350
351 /* OCP barrier */
352 (void)am33xx_prm_read_reg(AM33XX_PRM_DEVICE_MOD,
353 AM33XX_PRM_RSTCTRL_OFFSET);
354}
355
328struct pwrdm_ops am33xx_pwrdm_operations = { 356struct pwrdm_ops am33xx_pwrdm_operations = {
329 .pwrdm_set_next_pwrst = am33xx_pwrdm_set_next_pwrst, 357 .pwrdm_set_next_pwrst = am33xx_pwrdm_set_next_pwrst,
330 .pwrdm_read_next_pwrst = am33xx_pwrdm_read_next_pwrst, 358 .pwrdm_read_next_pwrst = am33xx_pwrdm_read_next_pwrst,
@@ -342,3 +370,21 @@ struct pwrdm_ops am33xx_pwrdm_operations = {
342 .pwrdm_wait_transition = am33xx_pwrdm_wait_transition, 370 .pwrdm_wait_transition = am33xx_pwrdm_wait_transition,
343 .pwrdm_has_voltdm = am33xx_check_vcvp, 371 .pwrdm_has_voltdm = am33xx_check_vcvp,
344}; 372};
373
374static struct prm_ll_data am33xx_prm_ll_data = {
375 .assert_hardreset = am33xx_prm_assert_hardreset,
376 .deassert_hardreset = am33xx_prm_deassert_hardreset,
377 .is_hardreset_asserted = am33xx_prm_is_hardreset_asserted,
378 .reset_system = am33xx_prm_global_warm_sw_reset,
379};
380
381int __init am33xx_prm_init(void)
382{
383 return prm_register(&am33xx_prm_ll_data);
384}
385
386static void __exit am33xx_prm_exit(void)
387{
388 prm_unregister(&am33xx_prm_ll_data);
389}
390__exitcall(am33xx_prm_exit);
diff --git a/arch/arm/mach-omap2/prm33xx.h b/arch/arm/mach-omap2/prm33xx.h
index 9b9918dfb119..98ac41f271da 100644
--- a/arch/arm/mach-omap2/prm33xx.h
+++ b/arch/arm/mach-omap2/prm33xx.h
@@ -118,14 +118,7 @@
118#define AM33XX_PM_CEFUSE_PWRSTST AM33XX_PRM_REGADDR(AM33XX_PRM_CEFUSE_MOD, 0x0004) 118#define AM33XX_PM_CEFUSE_PWRSTST AM33XX_PRM_REGADDR(AM33XX_PRM_CEFUSE_MOD, 0x0004)
119 119
120#ifndef __ASSEMBLER__ 120#ifndef __ASSEMBLER__
121extern u32 am33xx_prm_read_reg(s16 inst, u16 idx); 121int am33xx_prm_init(void);
122extern void am33xx_prm_write_reg(u32 val, s16 inst, u16 idx); 122
123extern u32 am33xx_prm_rmw_reg_bits(u32 mask, u32 bits, s16 inst, s16 idx);
124extern void am33xx_prm_global_warm_sw_reset(void);
125extern int am33xx_prm_is_hardreset_asserted(u8 shift, s16 inst,
126 u16 rstctrl_offs);
127extern int am33xx_prm_assert_hardreset(u8 shift, s16 inst, u16 rstctrl_offs);
128extern int am33xx_prm_deassert_hardreset(u8 shift, u8 st_shift, s16 inst,
129 u16 rstctrl_offs, u16 rstst_offs);
130#endif /* ASSEMBLER */ 123#endif /* ASSEMBLER */
131#endif 124#endif
diff --git a/arch/arm/mach-omap2/prm3xxx.c b/arch/arm/mach-omap2/prm3xxx.c
index ff08da385a2d..c5e00c6714b1 100644
--- a/arch/arm/mach-omap2/prm3xxx.c
+++ b/arch/arm/mach-omap2/prm3xxx.c
@@ -30,6 +30,11 @@
30#include "cm3xxx.h" 30#include "cm3xxx.h"
31#include "cm-regbits-34xx.h" 31#include "cm-regbits-34xx.h"
32 32
33static void omap3xxx_prm_read_pending_irqs(unsigned long *events);
34static void omap3xxx_prm_ocp_barrier(void);
35static void omap3xxx_prm_save_and_clear_irqen(u32 *saved_mask);
36static void omap3xxx_prm_restore_irqen(u32 *saved_mask);
37
33static const struct omap_prcm_irq omap3_prcm_irqs[] = { 38static const struct omap_prcm_irq omap3_prcm_irqs[] = {
34 OMAP_PRCM_IRQ("wkup", 0, 0), 39 OMAP_PRCM_IRQ("wkup", 0, 0),
35 OMAP_PRCM_IRQ("io", 9, 1), 40 OMAP_PRCM_IRQ("io", 9, 1),
@@ -131,7 +136,7 @@ u32 omap3_prm_vcvp_rmw(u32 mask, u32 bits, u8 offset)
131 * recommended way to restart the SoC, considering Errata i520. No 136 * recommended way to restart the SoC, considering Errata i520. No
132 * return value. 137 * return value.
133 */ 138 */
134void omap3xxx_prm_dpll3_reset(void) 139static void omap3xxx_prm_dpll3_reset(void)
135{ 140{
136 omap2_prm_set_mod_reg_bits(OMAP_RST_DPLL3_MASK, OMAP3430_GR_MOD, 141 omap2_prm_set_mod_reg_bits(OMAP_RST_DPLL3_MASK, OMAP3430_GR_MOD,
137 OMAP2_RM_RSTCTRL); 142 OMAP2_RM_RSTCTRL);
@@ -147,7 +152,7 @@ void omap3xxx_prm_dpll3_reset(void)
147 * MPU IRQs, and store the result into the u32 pointed to by @events. 152 * MPU IRQs, and store the result into the u32 pointed to by @events.
148 * No return value. 153 * No return value.
149 */ 154 */
150void omap3xxx_prm_read_pending_irqs(unsigned long *events) 155static void omap3xxx_prm_read_pending_irqs(unsigned long *events)
151{ 156{
152 u32 mask, st; 157 u32 mask, st;
153 158
@@ -166,7 +171,7 @@ void omap3xxx_prm_read_pending_irqs(unsigned long *events)
166 * block, to avoid race conditions after acknowledging or clearing IRQ 171 * block, to avoid race conditions after acknowledging or clearing IRQ
167 * bits. No return value. 172 * bits. No return value.
168 */ 173 */
169void omap3xxx_prm_ocp_barrier(void) 174static void omap3xxx_prm_ocp_barrier(void)
170{ 175{
171 omap2_prm_read_mod_reg(OCP_MOD, OMAP3_PRM_REVISION_OFFSET); 176 omap2_prm_read_mod_reg(OCP_MOD, OMAP3_PRM_REVISION_OFFSET);
172} 177}
@@ -182,7 +187,7 @@ void omap3xxx_prm_ocp_barrier(void)
182 * returning; otherwise, spurious interrupts might occur. No return 187 * returning; otherwise, spurious interrupts might occur. No return
183 * value. 188 * value.
184 */ 189 */
185void omap3xxx_prm_save_and_clear_irqen(u32 *saved_mask) 190static void omap3xxx_prm_save_and_clear_irqen(u32 *saved_mask)
186{ 191{
187 saved_mask[0] = omap2_prm_read_mod_reg(OCP_MOD, 192 saved_mask[0] = omap2_prm_read_mod_reg(OCP_MOD,
188 OMAP3_PRM_IRQENABLE_MPU_OFFSET); 193 OMAP3_PRM_IRQENABLE_MPU_OFFSET);
@@ -202,7 +207,7 @@ void omap3xxx_prm_save_and_clear_irqen(u32 *saved_mask)
202 * barrier should be needed here; any pending PRM interrupts will fire 207 * barrier should be needed here; any pending PRM interrupts will fire
203 * once the writes reach the PRM. No return value. 208 * once the writes reach the PRM. No return value.
204 */ 209 */
205void omap3xxx_prm_restore_irqen(u32 *saved_mask) 210static void omap3xxx_prm_restore_irqen(u32 *saved_mask)
206{ 211{
207 omap2_prm_write_mod_reg(saved_mask[0], OCP_MOD, 212 omap2_prm_write_mod_reg(saved_mask[0], OCP_MOD,
208 OMAP3_PRM_IRQENABLE_MPU_OFFSET); 213 OMAP3_PRM_IRQENABLE_MPU_OFFSET);
@@ -375,7 +380,7 @@ void __init omap3_prm_init_pm(bool has_uart4, bool has_iva)
375 * The ST_IO_CHAIN bit does not exist in 3430 before es3.1. The only 380 * The ST_IO_CHAIN bit does not exist in 3430 before es3.1. The only
376 * thing we can do is toggle EN_IO bit for earlier omaps. 381 * thing we can do is toggle EN_IO bit for earlier omaps.
377 */ 382 */
378void omap3430_pre_es3_1_reconfigure_io_chain(void) 383static void omap3430_pre_es3_1_reconfigure_io_chain(void)
379{ 384{
380 omap2_prm_clear_mod_reg_bits(OMAP3430_EN_IO_MASK, WKUP_MOD, 385 omap2_prm_clear_mod_reg_bits(OMAP3430_EN_IO_MASK, WKUP_MOD,
381 PM_WKEN); 386 PM_WKEN);
@@ -393,7 +398,7 @@ void omap3430_pre_es3_1_reconfigure_io_chain(void)
393 * deasserting WUCLKIN and clearing the ST_IO_CHAIN WKST bit. No 398 * deasserting WUCLKIN and clearing the ST_IO_CHAIN WKST bit. No
394 * return value. These registers are only available in 3430 es3.1 and later. 399 * return value. These registers are only available in 3430 es3.1 and later.
395 */ 400 */
396void omap3_prm_reconfigure_io_chain(void) 401static void omap3_prm_reconfigure_io_chain(void)
397{ 402{
398 int i = 0; 403 int i = 0;
399 404
@@ -416,15 +421,6 @@ void omap3_prm_reconfigure_io_chain(void)
416} 421}
417 422
418/** 423/**
419 * omap3xxx_prm_reconfigure_io_chain - reconfigure I/O chain
420 */
421void omap3xxx_prm_reconfigure_io_chain(void)
422{
423 if (omap3_prcm_irq_setup.reconfigure_io_chain)
424 omap3_prcm_irq_setup.reconfigure_io_chain();
425}
426
427/**
428 * omap3xxx_prm_enable_io_wakeup - enable wakeup events from I/O wakeup latches 424 * omap3xxx_prm_enable_io_wakeup - enable wakeup events from I/O wakeup latches
429 * 425 *
430 * Activates the I/O wakeup event latches and allows events logged by 426 * Activates the I/O wakeup event latches and allows events logged by
@@ -664,6 +660,10 @@ static int omap3xxx_prm_late_init(void);
664static struct prm_ll_data omap3xxx_prm_ll_data = { 660static struct prm_ll_data omap3xxx_prm_ll_data = {
665 .read_reset_sources = &omap3xxx_prm_read_reset_sources, 661 .read_reset_sources = &omap3xxx_prm_read_reset_sources,
666 .late_init = &omap3xxx_prm_late_init, 662 .late_init = &omap3xxx_prm_late_init,
663 .assert_hardreset = &omap2_prm_assert_hardreset,
664 .deassert_hardreset = &omap2_prm_deassert_hardreset,
665 .is_hardreset_asserted = &omap2_prm_is_hardreset_asserted,
666 .reset_system = &omap3xxx_prm_dpll3_reset,
667}; 667};
668 668
669int __init omap3xxx_prm_init(void) 669int __init omap3xxx_prm_init(void)
diff --git a/arch/arm/mach-omap2/prm3xxx.h b/arch/arm/mach-omap2/prm3xxx.h
index bc37d42a8704..cfde3f4a03cc 100644
--- a/arch/arm/mach-omap2/prm3xxx.h
+++ b/arch/arm/mach-omap2/prm3xxx.h
@@ -144,22 +144,6 @@ extern u32 omap3_prm_vcvp_read(u8 offset);
144extern void omap3_prm_vcvp_write(u32 val, u8 offset); 144extern void omap3_prm_vcvp_write(u32 val, u8 offset);
145extern u32 omap3_prm_vcvp_rmw(u32 mask, u32 bits, u8 offset); 145extern u32 omap3_prm_vcvp_rmw(u32 mask, u32 bits, u8 offset);
146 146
147#ifdef CONFIG_ARCH_OMAP3
148void omap3xxx_prm_reconfigure_io_chain(void);
149#else
150static inline void omap3xxx_prm_reconfigure_io_chain(void)
151{
152}
153#endif
154
155/* PRM interrupt-related functions */
156extern void omap3xxx_prm_read_pending_irqs(unsigned long *events);
157extern void omap3xxx_prm_ocp_barrier(void);
158extern void omap3xxx_prm_save_and_clear_irqen(u32 *saved_mask);
159extern void omap3xxx_prm_restore_irqen(u32 *saved_mask);
160
161extern void omap3xxx_prm_dpll3_reset(void);
162
163extern int __init omap3xxx_prm_init(void); 147extern int __init omap3xxx_prm_init(void);
164extern u32 omap3xxx_prm_get_reset_sources(void); 148extern u32 omap3xxx_prm_get_reset_sources(void);
165int omap3xxx_prm_clear_mod_irqs(s16 module, u8 regs, u32 ignore_bits); 149int omap3xxx_prm_clear_mod_irqs(s16 module, u8 regs, u32 ignore_bits);
diff --git a/arch/arm/mach-omap2/prm44xx.c b/arch/arm/mach-omap2/prm44xx.c
index 0958d070d3db..cc170fb81ff7 100644
--- a/arch/arm/mach-omap2/prm44xx.c
+++ b/arch/arm/mach-omap2/prm44xx.c
@@ -32,6 +32,12 @@
32 32
33/* Static data */ 33/* Static data */
34 34
35static void omap44xx_prm_read_pending_irqs(unsigned long *events);
36static void omap44xx_prm_ocp_barrier(void);
37static void omap44xx_prm_save_and_clear_irqen(u32 *saved_mask);
38static void omap44xx_prm_restore_irqen(u32 *saved_mask);
39static void omap44xx_prm_reconfigure_io_chain(void);
40
35static const struct omap_prcm_irq omap4_prcm_irqs[] = { 41static const struct omap_prcm_irq omap4_prcm_irqs[] = {
36 OMAP_PRCM_IRQ("io", 9, 1), 42 OMAP_PRCM_IRQ("io", 9, 1),
37}; 43};
@@ -80,19 +86,19 @@ static struct prm_reset_src_map omap44xx_prm_reset_src_map[] = {
80/* PRM low-level functions */ 86/* PRM low-level functions */
81 87
82/* Read a register in a CM/PRM instance in the PRM module */ 88/* Read a register in a CM/PRM instance in the PRM module */
83u32 omap4_prm_read_inst_reg(s16 inst, u16 reg) 89static u32 omap4_prm_read_inst_reg(s16 inst, u16 reg)
84{ 90{
85 return readl_relaxed(prm_base + inst + reg); 91 return readl_relaxed(prm_base + inst + reg);
86} 92}
87 93
88/* Write into a register in a CM/PRM instance in the PRM module */ 94/* Write into a register in a CM/PRM instance in the PRM module */
89void omap4_prm_write_inst_reg(u32 val, s16 inst, u16 reg) 95static void omap4_prm_write_inst_reg(u32 val, s16 inst, u16 reg)
90{ 96{
91 writel_relaxed(val, prm_base + inst + reg); 97 writel_relaxed(val, prm_base + inst + reg);
92} 98}
93 99
94/* Read-modify-write a register in a PRM module. Caller must lock */ 100/* Read-modify-write a register in a PRM module. Caller must lock */
95u32 omap4_prm_rmw_inst_reg_bits(u32 mask, u32 bits, s16 inst, s16 reg) 101static u32 omap4_prm_rmw_inst_reg_bits(u32 mask, u32 bits, s16 inst, s16 reg)
96{ 102{
97 u32 v; 103 u32 v;
98 104
@@ -207,7 +213,7 @@ static inline u32 _read_pending_irq_reg(u16 irqen_offs, u16 irqst_offs)
207 * MPU IRQs, and store the result into the two u32s pointed to by @events. 213 * MPU IRQs, and store the result into the two u32s pointed to by @events.
208 * No return value. 214 * No return value.
209 */ 215 */
210void omap44xx_prm_read_pending_irqs(unsigned long *events) 216static void omap44xx_prm_read_pending_irqs(unsigned long *events)
211{ 217{
212 events[0] = _read_pending_irq_reg(OMAP4_PRM_IRQENABLE_MPU_OFFSET, 218 events[0] = _read_pending_irq_reg(OMAP4_PRM_IRQENABLE_MPU_OFFSET,
213 OMAP4_PRM_IRQSTATUS_MPU_OFFSET); 219 OMAP4_PRM_IRQSTATUS_MPU_OFFSET);
@@ -224,7 +230,7 @@ void omap44xx_prm_read_pending_irqs(unsigned long *events)
224 * block, to avoid race conditions after acknowledging or clearing IRQ 230 * block, to avoid race conditions after acknowledging or clearing IRQ
225 * bits. No return value. 231 * bits. No return value.
226 */ 232 */
227void omap44xx_prm_ocp_barrier(void) 233static void omap44xx_prm_ocp_barrier(void)
228{ 234{
229 omap4_prm_read_inst_reg(OMAP4430_PRM_OCP_SOCKET_INST, 235 omap4_prm_read_inst_reg(OMAP4430_PRM_OCP_SOCKET_INST,
230 OMAP4_REVISION_PRM_OFFSET); 236 OMAP4_REVISION_PRM_OFFSET);
@@ -241,7 +247,7 @@ void omap44xx_prm_ocp_barrier(void)
241 * interrupts reaches the PRM before returning; otherwise, spurious 247 * interrupts reaches the PRM before returning; otherwise, spurious
242 * interrupts might occur. No return value. 248 * interrupts might occur. No return value.
243 */ 249 */
244void omap44xx_prm_save_and_clear_irqen(u32 *saved_mask) 250static void omap44xx_prm_save_and_clear_irqen(u32 *saved_mask)
245{ 251{
246 saved_mask[0] = 252 saved_mask[0] =
247 omap4_prm_read_inst_reg(OMAP4430_PRM_OCP_SOCKET_INST, 253 omap4_prm_read_inst_reg(OMAP4430_PRM_OCP_SOCKET_INST,
@@ -270,7 +276,7 @@ void omap44xx_prm_save_and_clear_irqen(u32 *saved_mask)
270 * No OCP barrier should be needed here; any pending PRM interrupts will fire 276 * No OCP barrier should be needed here; any pending PRM interrupts will fire
271 * once the writes reach the PRM. No return value. 277 * once the writes reach the PRM. No return value.
272 */ 278 */
273void omap44xx_prm_restore_irqen(u32 *saved_mask) 279static void omap44xx_prm_restore_irqen(u32 *saved_mask)
274{ 280{
275 omap4_prm_write_inst_reg(saved_mask[0], OMAP4430_PRM_OCP_SOCKET_INST, 281 omap4_prm_write_inst_reg(saved_mask[0], OMAP4430_PRM_OCP_SOCKET_INST,
276 OMAP4_PRM_IRQENABLE_MPU_OFFSET); 282 OMAP4_PRM_IRQENABLE_MPU_OFFSET);
@@ -287,7 +293,7 @@ void omap44xx_prm_restore_irqen(u32 *saved_mask)
287 * deasserting WUCLKIN and waiting for WUCLKOUT to be deasserted. 293 * deasserting WUCLKIN and waiting for WUCLKOUT to be deasserted.
288 * No return value. XXX Are the final two steps necessary? 294 * No return value. XXX Are the final two steps necessary?
289 */ 295 */
290void omap44xx_prm_reconfigure_io_chain(void) 296static void omap44xx_prm_reconfigure_io_chain(void)
291{ 297{
292 int i = 0; 298 int i = 0;
293 s32 inst = omap4_prmst_get_prm_dev_inst(); 299 s32 inst = omap4_prmst_get_prm_dev_inst();
@@ -652,11 +658,10 @@ static int omap4_pwrdm_wait_transition(struct powerdomain *pwrdm)
652 658
653static int omap4_check_vcvp(void) 659static int omap4_check_vcvp(void)
654{ 660{
655 /* No VC/VP on dra7xx devices */ 661 if (prm_features & PRM_HAS_VOLTAGE)
656 if (soc_is_dra7xx()) 662 return 1;
657 return 0;
658 663
659 return 1; 664 return 0;
660} 665}
661 666
662struct pwrdm_ops omap4_pwrdm_operations = { 667struct pwrdm_ops omap4_pwrdm_operations = {
@@ -689,6 +694,10 @@ static struct prm_ll_data omap44xx_prm_ll_data = {
689 .was_any_context_lost_old = &omap44xx_prm_was_any_context_lost_old, 694 .was_any_context_lost_old = &omap44xx_prm_was_any_context_lost_old,
690 .clear_context_loss_flags_old = &omap44xx_prm_clear_context_loss_flags_old, 695 .clear_context_loss_flags_old = &omap44xx_prm_clear_context_loss_flags_old,
691 .late_init = &omap44xx_prm_late_init, 696 .late_init = &omap44xx_prm_late_init,
697 .assert_hardreset = omap4_prminst_assert_hardreset,
698 .deassert_hardreset = omap4_prminst_deassert_hardreset,
699 .is_hardreset_asserted = omap4_prminst_is_hardreset_asserted,
700 .reset_system = omap4_prminst_global_warm_sw_reset,
692}; 701};
693 702
694int __init omap44xx_prm_init(void) 703int __init omap44xx_prm_init(void)
@@ -696,6 +705,9 @@ int __init omap44xx_prm_init(void)
696 if (cpu_is_omap44xx() || soc_is_omap54xx() || soc_is_dra7xx()) 705 if (cpu_is_omap44xx() || soc_is_omap54xx() || soc_is_dra7xx())
697 prm_features |= PRM_HAS_IO_WAKEUP; 706 prm_features |= PRM_HAS_IO_WAKEUP;
698 707
708 if (!soc_is_dra7xx())
709 prm_features |= PRM_HAS_VOLTAGE;
710
699 return prm_register(&omap44xx_prm_ll_data); 711 return prm_register(&omap44xx_prm_ll_data);
700} 712}
701 713
diff --git a/arch/arm/mach-omap2/prm44xx_54xx.h b/arch/arm/mach-omap2/prm44xx_54xx.h
index 8d95aa543ef5..f7512515fde5 100644
--- a/arch/arm/mach-omap2/prm44xx_54xx.h
+++ b/arch/arm/mach-omap2/prm44xx_54xx.h
@@ -26,10 +26,6 @@
26/* Function prototypes */ 26/* Function prototypes */
27#ifndef __ASSEMBLER__ 27#ifndef __ASSEMBLER__
28 28
29extern u32 omap4_prm_read_inst_reg(s16 inst, u16 idx);
30extern void omap4_prm_write_inst_reg(u32 val, s16 inst, u16 idx);
31extern u32 omap4_prm_rmw_inst_reg_bits(u32 mask, u32 bits, s16 inst, s16 idx);
32
33/* OMAP4/OMAP5-specific VP functions */ 29/* OMAP4/OMAP5-specific VP functions */
34u32 omap4_prm_vp_check_txdone(u8 vp_id); 30u32 omap4_prm_vp_check_txdone(u8 vp_id);
35void omap4_prm_vp_clear_txdone(u8 vp_id); 31void omap4_prm_vp_clear_txdone(u8 vp_id);
@@ -42,21 +38,6 @@ extern u32 omap4_prm_vcvp_read(u8 offset);
42extern void omap4_prm_vcvp_write(u32 val, u8 offset); 38extern void omap4_prm_vcvp_write(u32 val, u8 offset);
43extern u32 omap4_prm_vcvp_rmw(u32 mask, u32 bits, u8 offset); 39extern u32 omap4_prm_vcvp_rmw(u32 mask, u32 bits, u8 offset);
44 40
45#if defined(CONFIG_ARCH_OMAP4) || defined(CONFIG_SOC_OMAP5) || \
46 defined(CONFIG_SOC_DRA7XX) || defined(CONFIG_SOC_AM43XX)
47void omap44xx_prm_reconfigure_io_chain(void);
48#else
49static inline void omap44xx_prm_reconfigure_io_chain(void)
50{
51}
52#endif
53
54/* PRM interrupt-related functions */
55extern void omap44xx_prm_read_pending_irqs(unsigned long *events);
56extern void omap44xx_prm_ocp_barrier(void);
57extern void omap44xx_prm_save_and_clear_irqen(u32 *saved_mask);
58extern void omap44xx_prm_restore_irqen(u32 *saved_mask);
59
60extern int __init omap44xx_prm_init(void); 41extern int __init omap44xx_prm_init(void);
61extern u32 omap44xx_prm_get_reset_sources(void); 42extern u32 omap44xx_prm_get_reset_sources(void);
62 43
diff --git a/arch/arm/mach-omap2/prm_common.c b/arch/arm/mach-omap2/prm_common.c
index ee2b5222eac0..779940cb6e56 100644
--- a/arch/arm/mach-omap2/prm_common.c
+++ b/arch/arm/mach-omap2/prm_common.c
@@ -423,6 +423,105 @@ void prm_clear_context_loss_flags_old(u8 part, s16 inst, u16 idx)
423} 423}
424 424
425/** 425/**
426 * omap_prm_assert_hardreset - assert hardreset for an IP block
427 * @shift: register bit shift corresponding to the reset line
428 * @part: PRM partition
429 * @prm_mod: PRM submodule base or instance offset
430 * @offset: register offset
431 *
432 * Asserts a hardware reset line for an IP block.
433 */
434int omap_prm_assert_hardreset(u8 shift, u8 part, s16 prm_mod, u16 offset)
435{
436 if (!prm_ll_data->assert_hardreset) {
437 WARN_ONCE(1, "prm: %s: no mapping function defined\n",
438 __func__);
439 return -EINVAL;
440 }
441
442 return prm_ll_data->assert_hardreset(shift, part, prm_mod, offset);
443}
444
445/**
446 * omap_prm_deassert_hardreset - deassert hardreset for an IP block
447 * @shift: register bit shift corresponding to the reset line
448 * @st_shift: reset status bit shift corresponding to the reset line
449 * @part: PRM partition
450 * @prm_mod: PRM submodule base or instance offset
451 * @offset: register offset
452 * @st_offset: status register offset
453 *
454 * Deasserts a hardware reset line for an IP block.
455 */
456int omap_prm_deassert_hardreset(u8 shift, u8 st_shift, u8 part, s16 prm_mod,
457 u16 offset, u16 st_offset)
458{
459 if (!prm_ll_data->deassert_hardreset) {
460 WARN_ONCE(1, "prm: %s: no mapping function defined\n",
461 __func__);
462 return -EINVAL;
463 }
464
465 return prm_ll_data->deassert_hardreset(shift, st_shift, part, prm_mod,
466 offset, st_offset);
467}
468
469/**
470 * omap_prm_is_hardreset_asserted - check the hardreset status for an IP block
471 * @shift: register bit shift corresponding to the reset line
472 * @part: PRM partition
473 * @prm_mod: PRM submodule base or instance offset
474 * @offset: register offset
475 *
476 * Checks if a hardware reset line for an IP block is enabled or not.
477 */
478int omap_prm_is_hardreset_asserted(u8 shift, u8 part, s16 prm_mod, u16 offset)
479{
480 if (!prm_ll_data->is_hardreset_asserted) {
481 WARN_ONCE(1, "prm: %s: no mapping function defined\n",
482 __func__);
483 return -EINVAL;
484 }
485
486 return prm_ll_data->is_hardreset_asserted(shift, part, prm_mod, offset);
487}
488
489/**
490 * omap_prm_reconfigure_io_chain - clear latches and reconfigure I/O chain
491 *
492 * Clear any previously-latched I/O wakeup events and ensure that the
493 * I/O wakeup gates are aligned with the current mux settings.
494 * Calls SoC specific I/O chain reconfigure function if available,
495 * otherwise does nothing.
496 */
497void omap_prm_reconfigure_io_chain(void)
498{
499 if (!prcm_irq_setup || !prcm_irq_setup->reconfigure_io_chain)
500 return;
501
502 prcm_irq_setup->reconfigure_io_chain();
503}
504
505/**
506 * omap_prm_reset_system - trigger global SW reset
507 *
508 * Triggers SoC specific global warm reset to reboot the device.
509 */
510void omap_prm_reset_system(void)
511{
512 if (!prm_ll_data->reset_system) {
513 WARN_ONCE(1, "prm: %s: no mapping function defined\n",
514 __func__);
515 return;
516 }
517
518 prm_ll_data->reset_system();
519
520 while (1)
521 cpu_relax();
522}
523
524/**
426 * prm_register - register per-SoC low-level data with the PRM 525 * prm_register - register per-SoC low-level data with the PRM
427 * @pld: low-level per-SoC OMAP PRM data & function pointers to register 526 * @pld: low-level per-SoC OMAP PRM data & function pointers to register
428 * 527 *
diff --git a/arch/arm/mach-omap2/prminst44xx.c b/arch/arm/mach-omap2/prminst44xx.c
index 225e0258d76d..8adf7b1a1dce 100644
--- a/arch/arm/mach-omap2/prminst44xx.c
+++ b/arch/arm/mach-omap2/prminst44xx.c
@@ -148,8 +148,12 @@ int omap4_prminst_assert_hardreset(u8 shift, u8 part, s16 inst,
148/** 148/**
149 * omap4_prminst_deassert_hardreset - deassert a submodule hardreset line and 149 * omap4_prminst_deassert_hardreset - deassert a submodule hardreset line and
150 * wait 150 * wait
151 * @rstctrl_reg: RM_RSTCTRL register address for this module
152 * @shift: register bit shift corresponding to the reset line to deassert 151 * @shift: register bit shift corresponding to the reset line to deassert
152 * @st_shift: status bit offset, not used for OMAP4+
153 * @part: PRM partition
154 * @inst: PRM instance offset
155 * @rstctrl_offs: reset register offset
156 * @st_offs: reset status register offset, not used for OMAP4+
153 * 157 *
154 * Some IPs like dsp, ipu or iva contain processors that require an HW 158 * Some IPs like dsp, ipu or iva contain processors that require an HW
155 * reset line to be asserted / deasserted in order to fully enable the 159 * reset line to be asserted / deasserted in order to fully enable the
@@ -160,8 +164,8 @@ int omap4_prminst_assert_hardreset(u8 shift, u8 part, s16 inst,
160 * -EINVAL upon an argument error, -EEXIST if the submodule was already out 164 * -EINVAL upon an argument error, -EEXIST if the submodule was already out
161 * of reset, or -EBUSY if the submodule did not exit reset promptly. 165 * of reset, or -EBUSY if the submodule did not exit reset promptly.
162 */ 166 */
163int omap4_prminst_deassert_hardreset(u8 shift, u8 part, s16 inst, 167int omap4_prminst_deassert_hardreset(u8 shift, u8 st_shift, u8 part, s16 inst,
164 u16 rstctrl_offs) 168 u16 rstctrl_offs, u16 st_offs)
165{ 169{
166 int c; 170 int c;
167 u32 mask = 1 << shift; 171 u32 mask = 1 << shift;
diff --git a/arch/arm/mach-omap2/prminst44xx.h b/arch/arm/mach-omap2/prminst44xx.h
index 583aa3774571..fb1c9d7a2f9d 100644
--- a/arch/arm/mach-omap2/prminst44xx.h
+++ b/arch/arm/mach-omap2/prminst44xx.h
@@ -30,8 +30,9 @@ extern int omap4_prminst_is_hardreset_asserted(u8 shift, u8 part, s16 inst,
30 u16 rstctrl_offs); 30 u16 rstctrl_offs);
31extern int omap4_prminst_assert_hardreset(u8 shift, u8 part, s16 inst, 31extern int omap4_prminst_assert_hardreset(u8 shift, u8 part, s16 inst,
32 u16 rstctrl_offs); 32 u16 rstctrl_offs);
33extern int omap4_prminst_deassert_hardreset(u8 shift, u8 part, s16 inst, 33int omap4_prminst_deassert_hardreset(u8 shift, u8 st_shift, u8 part,
34 u16 rstctrl_offs); 34 s16 inst, u16 rstctrl_offs,
35 u16 rstst_offs);
35 36
36extern void omap_prm_base_init(void); 37extern void omap_prm_base_init(void);
37 38
diff --git a/arch/arm/mach-pxa/Kconfig b/arch/arm/mach-pxa/Kconfig
index e6690a44917d..83efe914bf7d 100644
--- a/arch/arm/mach-pxa/Kconfig
+++ b/arch/arm/mach-pxa/Kconfig
@@ -4,6 +4,17 @@ menu "Intel PXA2xx/PXA3xx Implementations"
4 4
5comment "Intel/Marvell Dev Platforms (sorted by hardware release time)" 5comment "Intel/Marvell Dev Platforms (sorted by hardware release time)"
6 6
7config MACH_PXA27X_DT
8 bool "Support PXA27x platforms from device tree"
9 select CPU_PXA27x
10 select POWER_SUPPLY
11 select PXA27x
12 select USE_OF
13 help
14 Include support for Marvell PXA27x based platforms using
15 the device tree. Needn't select any other machine while
16 MACH_PXA27X_DT is enabled.
17
7config MACH_PXA3XX_DT 18config MACH_PXA3XX_DT
8 bool "Support PXA3xx platforms from device tree" 19 bool "Support PXA3xx platforms from device tree"
9 select CPU_PXA300 20 select CPU_PXA300
diff --git a/arch/arm/mach-pxa/Makefile b/arch/arm/mach-pxa/Makefile
index 2fe1824c6dcb..eb0bf7678a99 100644
--- a/arch/arm/mach-pxa/Makefile
+++ b/arch/arm/mach-pxa/Makefile
@@ -21,6 +21,7 @@ obj-$(CONFIG_CPU_PXA930) += pxa930.o
21 21
22# Device Tree support 22# Device Tree support
23obj-$(CONFIG_MACH_PXA3XX_DT) += pxa-dt.o 23obj-$(CONFIG_MACH_PXA3XX_DT) += pxa-dt.o
24obj-$(CONFIG_MACH_PXA27X_DT) += pxa-dt.o
24 25
25# Intel/Marvell Dev Platforms 26# Intel/Marvell Dev Platforms
26obj-$(CONFIG_ARCH_LUBBOCK) += lubbock.o 27obj-$(CONFIG_ARCH_LUBBOCK) += lubbock.o
diff --git a/arch/arm/mach-pxa/em-x270.c b/arch/arm/mach-pxa/em-x270.c
index 6915a9f6b3a3..51531ecffca8 100644
--- a/arch/arm/mach-pxa/em-x270.c
+++ b/arch/arm/mach-pxa/em-x270.c
@@ -378,7 +378,7 @@ static void __init em_x270_init_nand(void)
378 378
379 err = gpio_request(GPIO11_NAND_CS, "NAND CS"); 379 err = gpio_request(GPIO11_NAND_CS, "NAND CS");
380 if (err) { 380 if (err) {
381 pr_warning("EM-X270: failed to request NAND CS gpio\n"); 381 pr_warn("EM-X270: failed to request NAND CS gpio\n");
382 return; 382 return;
383 } 383 }
384 384
@@ -386,7 +386,7 @@ static void __init em_x270_init_nand(void)
386 386
387 err = gpio_request(nand_rb, "NAND R/B"); 387 err = gpio_request(nand_rb, "NAND R/B");
388 if (err) { 388 if (err) {
389 pr_warning("EM-X270: failed to request NAND R/B gpio\n"); 389 pr_warn("EM-X270: failed to request NAND R/B gpio\n");
390 gpio_free(GPIO11_NAND_CS); 390 gpio_free(GPIO11_NAND_CS);
391 return; 391 return;
392 } 392 }
diff --git a/arch/arm/mach-pxa/generic.h b/arch/arm/mach-pxa/generic.h
index 8963984d1f43..7a9fa1aa4e41 100644
--- a/arch/arm/mach-pxa/generic.h
+++ b/arch/arm/mach-pxa/generic.h
@@ -13,11 +13,11 @@
13 13
14struct irq_data; 14struct irq_data;
15 15
16extern void pxa_timer_init(void);
17
18extern void __init pxa_map_io(void);
19
20extern unsigned int get_clk_frequency_khz(int info); 16extern unsigned int get_clk_frequency_khz(int info);
17extern void __init pxa_dt_irq_init(int (*fn)(struct irq_data *,
18 unsigned int));
19extern void __init pxa_map_io(void);
20extern void pxa_timer_init(void);
21 21
22#define SET_BANK(__nr,__start,__size) \ 22#define SET_BANK(__nr,__start,__size) \
23 mi->bank[__nr].start = (__start), \ 23 mi->bank[__nr].start = (__start), \
@@ -25,6 +25,43 @@ extern unsigned int get_clk_frequency_khz(int info);
25 25
26#define ARRAY_AND_SIZE(x) (x), ARRAY_SIZE(x) 26#define ARRAY_AND_SIZE(x) (x), ARRAY_SIZE(x)
27 27
28#define pxa25x_handle_irq icip_handle_irq
29extern void __init pxa25x_init_irq(void);
30extern void __init pxa25x_map_io(void);
31extern void __init pxa26x_init_irq(void);
32
33#define pxa27x_handle_irq ichp_handle_irq
34extern void __init pxa27x_dt_init_irq(void);
35extern unsigned pxa27x_get_clk_frequency_khz(int);
36extern void __init pxa27x_init_irq(void);
37extern void __init pxa27x_map_io(void);
38
39#define pxa3xx_handle_irq ichp_handle_irq
40extern void __init pxa3xx_dt_init_irq(void);
41extern void __init pxa3xx_init_irq(void);
42extern void __init pxa3xx_map_io(void);
43
44extern struct syscore_ops pxa_irq_syscore_ops;
45extern struct syscore_ops pxa2xx_mfp_syscore_ops;
46extern struct syscore_ops pxa3xx_mfp_syscore_ops;
47
48void __init pxa_set_ffuart_info(void *info);
49void __init pxa_set_btuart_info(void *info);
50void __init pxa_set_stuart_info(void *info);
51void __init pxa_set_hwuart_info(void *info);
52
53void pxa_restart(enum reboot_mode, const char *);
54
55#if defined(CONFIG_PXA25x) || defined(CONFIG_PXA27x)
56extern void pxa2xx_clear_reset_status(unsigned int);
57#else
58static inline void pxa2xx_clear_reset_status(unsigned int mask) {}
59#endif
60
61/*
62 * Once fully converted to the clock framework, all these functions should be
63 * removed, and replaced with a clk_get(NULL, "core").
64 */
28#ifdef CONFIG_PXA25x 65#ifdef CONFIG_PXA25x
29extern unsigned pxa25x_get_clk_frequency_khz(int); 66extern unsigned pxa25x_get_clk_frequency_khz(int);
30#else 67#else
@@ -32,30 +69,12 @@ extern unsigned pxa25x_get_clk_frequency_khz(int);
32#endif 69#endif
33 70
34#ifdef CONFIG_PXA27x 71#ifdef CONFIG_PXA27x
35extern unsigned pxa27x_get_clk_frequency_khz(int);
36#else 72#else
37#define pxa27x_get_clk_frequency_khz(x) (0) 73#define pxa27x_get_clk_frequency_khz(x) (0)
38#endif 74#endif
39 75
40#if defined(CONFIG_PXA25x) || defined(CONFIG_PXA27x)
41extern void pxa2xx_clear_reset_status(unsigned int);
42#else
43static inline void pxa2xx_clear_reset_status(unsigned int mask) {}
44#endif
45
46#ifdef CONFIG_PXA3xx 76#ifdef CONFIG_PXA3xx
47extern unsigned pxa3xx_get_clk_frequency_khz(int); 77extern unsigned pxa3xx_get_clk_frequency_khz(int);
48#else 78#else
49#define pxa3xx_get_clk_frequency_khz(x) (0) 79#define pxa3xx_get_clk_frequency_khz(x) (0)
50#endif 80#endif
51
52extern struct syscore_ops pxa_irq_syscore_ops;
53extern struct syscore_ops pxa2xx_mfp_syscore_ops;
54extern struct syscore_ops pxa3xx_mfp_syscore_ops;
55
56void __init pxa_set_ffuart_info(void *info);
57void __init pxa_set_btuart_info(void *info);
58void __init pxa_set_stuart_info(void *info);
59void __init pxa_set_hwuart_info(void *info);
60
61void pxa_restart(enum reboot_mode, const char *);
diff --git a/arch/arm/mach-pxa/gumstix.c b/arch/arm/mach-pxa/gumstix.c
index 00b92dad7b81..f6c76a3ee3b2 100644
--- a/arch/arm/mach-pxa/gumstix.c
+++ b/arch/arm/mach-pxa/gumstix.c
@@ -140,8 +140,7 @@ static void gumstix_setup_bt_clock(void)
140 int timeout = 500; 140 int timeout = 500;
141 141
142 if (!(OSCC & OSCC_OOK)) 142 if (!(OSCC & OSCC_OOK))
143 pr_warning("32kHz clock was not on. Bootloader may need to " 143 pr_warn("32kHz clock was not on. Bootloader may need to be updated\n");
144 "be updated\n");
145 else 144 else
146 return; 145 return;
147 146
diff --git a/arch/arm/mach-pxa/include/mach/pxa25x.h b/arch/arm/mach-pxa/include/mach/pxa25x.h
index 3ac0baac7350..5a341752e32c 100644
--- a/arch/arm/mach-pxa/include/mach/pxa25x.h
+++ b/arch/arm/mach-pxa/include/mach/pxa25x.h
@@ -6,12 +6,4 @@
6#include <mach/mfp-pxa25x.h> 6#include <mach/mfp-pxa25x.h>
7#include <mach/irqs.h> 7#include <mach/irqs.h>
8 8
9extern void __init pxa25x_map_io(void);
10extern void __init pxa25x_init_irq(void);
11#ifdef CONFIG_CPU_PXA26x
12extern void __init pxa26x_init_irq(void);
13#endif
14
15#define pxa25x_handle_irq icip_handle_irq
16
17#endif /* __MACH_PXA25x_H */ 9#endif /* __MACH_PXA25x_H */
diff --git a/arch/arm/mach-pxa/include/mach/pxa27x.h b/arch/arm/mach-pxa/include/mach/pxa27x.h
index 7cff640582b8..599b925a657c 100644
--- a/arch/arm/mach-pxa/include/mach/pxa27x.h
+++ b/arch/arm/mach-pxa/include/mach/pxa27x.h
@@ -19,11 +19,7 @@
19#define ARB_CORE_PARK (1<<24) /* Be parked with core when idle */ 19#define ARB_CORE_PARK (1<<24) /* Be parked with core when idle */
20#define ARB_LOCK_FLAG (1<<23) /* Only Locking masters gain access to the bus */ 20#define ARB_LOCK_FLAG (1<<23) /* Only Locking masters gain access to the bus */
21 21
22extern void __init pxa27x_map_io(void);
23extern void __init pxa27x_init_irq(void);
24extern int __init pxa27x_set_pwrmode(unsigned int mode); 22extern int __init pxa27x_set_pwrmode(unsigned int mode);
25extern void pxa27x_cpu_pm_enter(suspend_state_t state); 23extern void pxa27x_cpu_pm_enter(suspend_state_t state);
26 24
27#define pxa27x_handle_irq ichp_handle_irq
28
29#endif /* __MACH_PXA27x_H */ 25#endif /* __MACH_PXA27x_H */
diff --git a/arch/arm/mach-pxa/include/mach/pxa3xx.h b/arch/arm/mach-pxa/include/mach/pxa3xx.h
index 6dd7fa163e29..b4143fb6631f 100644
--- a/arch/arm/mach-pxa/include/mach/pxa3xx.h
+++ b/arch/arm/mach-pxa/include/mach/pxa3xx.h
@@ -5,9 +5,4 @@
5#include <mach/pxa3xx-regs.h> 5#include <mach/pxa3xx-regs.h>
6#include <mach/irqs.h> 6#include <mach/irqs.h>
7 7
8extern void __init pxa3xx_map_io(void);
9extern void __init pxa3xx_init_irq(void);
10
11#define pxa3xx_handle_irq ichp_handle_irq
12
13#endif /* __MACH_PXA3XX_H */ 8#endif /* __MACH_PXA3XX_H */
diff --git a/arch/arm/mach-pxa/mfp-pxa2xx.c b/arch/arm/mach-pxa/mfp-pxa2xx.c
index ef0426a159d4..666b78972c40 100644
--- a/arch/arm/mach-pxa/mfp-pxa2xx.c
+++ b/arch/arm/mach-pxa/mfp-pxa2xx.c
@@ -93,8 +93,8 @@ static int __mfp_config_gpio(unsigned gpio, unsigned long c)
93 break; 93 break;
94 default: 94 default:
95 /* warning and fall through, treat as MFP_LPM_DEFAULT */ 95 /* warning and fall through, treat as MFP_LPM_DEFAULT */
96 pr_warning("%s: GPIO%d: unsupported low power mode\n", 96 pr_warn("%s: GPIO%d: unsupported low power mode\n",
97 __func__, gpio); 97 __func__, gpio);
98 break; 98 break;
99 } 99 }
100 100
@@ -107,14 +107,12 @@ static int __mfp_config_gpio(unsigned gpio, unsigned long c)
107 * configurations of those pins not able to wakeup 107 * configurations of those pins not able to wakeup
108 */ 108 */
109 if ((c & MFP_LPM_CAN_WAKEUP) && !gpio_desc[gpio].can_wakeup) { 109 if ((c & MFP_LPM_CAN_WAKEUP) && !gpio_desc[gpio].can_wakeup) {
110 pr_warning("%s: GPIO%d unable to wakeup\n", 110 pr_warn("%s: GPIO%d unable to wakeup\n", __func__, gpio);
111 __func__, gpio);
112 return -EINVAL; 111 return -EINVAL;
113 } 112 }
114 113
115 if ((c & MFP_LPM_CAN_WAKEUP) && is_out) { 114 if ((c & MFP_LPM_CAN_WAKEUP) && is_out) {
116 pr_warning("%s: output GPIO%d unable to wakeup\n", 115 pr_warn("%s: output GPIO%d unable to wakeup\n", __func__, gpio);
117 __func__, gpio);
118 return -EINVAL; 116 return -EINVAL;
119 } 117 }
120 118
@@ -126,7 +124,7 @@ static inline int __mfp_validate(int mfp)
126 int gpio = mfp_to_gpio(mfp); 124 int gpio = mfp_to_gpio(mfp);
127 125
128 if ((mfp > MFP_PIN_GPIO127) || !gpio_desc[gpio].valid) { 126 if ((mfp > MFP_PIN_GPIO127) || !gpio_desc[gpio].valid) {
129 pr_warning("%s: GPIO%d is invalid pin\n", __func__, gpio); 127 pr_warn("%s: GPIO%d is invalid pin\n", __func__, gpio);
130 return -1; 128 return -1;
131 } 129 }
132 130
diff --git a/arch/arm/mach-pxa/poodle.c b/arch/arm/mach-pxa/poodle.c
index 131991629116..29019beae591 100644
--- a/arch/arm/mach-pxa/poodle.c
+++ b/arch/arm/mach-pxa/poodle.c
@@ -446,7 +446,7 @@ static void __init poodle_init(void)
446 446
447 ret = platform_add_devices(devices, ARRAY_SIZE(devices)); 447 ret = platform_add_devices(devices, ARRAY_SIZE(devices));
448 if (ret) 448 if (ret)
449 pr_warning("poodle: Unable to register LoCoMo device\n"); 449 pr_warn("poodle: Unable to register LoCoMo device\n");
450 450
451 pxa_set_fb_info(&poodle_locomo_device.dev, &poodle_fb_info); 451 pxa_set_fb_info(&poodle_locomo_device.dev, &poodle_fb_info);
452 pxa_set_udc_info(&udc_info); 452 pxa_set_udc_info(&udc_info);
diff --git a/arch/arm/mach-pxa/pxa-dt.c b/arch/arm/mach-pxa/pxa-dt.c
index f6a2c4b1c1dc..7e0e5bd0c9de 100644
--- a/arch/arm/mach-pxa/pxa-dt.c
+++ b/arch/arm/mach-pxa/pxa-dt.c
@@ -15,13 +15,10 @@
15#include <asm/mach/arch.h> 15#include <asm/mach/arch.h>
16#include <asm/mach/time.h> 16#include <asm/mach/time.h>
17#include <mach/irqs.h> 17#include <mach/irqs.h>
18#include <mach/pxa3xx.h>
19 18
20#include "generic.h" 19#include "generic.h"
21 20
22#ifdef CONFIG_PXA3xx 21#ifdef CONFIG_PXA3xx
23extern void __init pxa3xx_dt_init_irq(void);
24
25static const struct of_dev_auxdata pxa3xx_auxdata_lookup[] __initconst = { 22static const struct of_dev_auxdata pxa3xx_auxdata_lookup[] __initconst = {
26 OF_DEV_AUXDATA("mrvl,pxa-uart", 0x40100000, "pxa2xx-uart.0", NULL), 23 OF_DEV_AUXDATA("mrvl,pxa-uart", 0x40100000, "pxa2xx-uart.0", NULL),
27 OF_DEV_AUXDATA("mrvl,pxa-uart", 0x40200000, "pxa2xx-uart.1", NULL), 24 OF_DEV_AUXDATA("mrvl,pxa-uart", 0x40200000, "pxa2xx-uart.1", NULL),
@@ -61,3 +58,18 @@ DT_MACHINE_START(PXA_DT, "Marvell PXA3xx (Device Tree Support)")
61 .dt_compat = pxa3xx_dt_board_compat, 58 .dt_compat = pxa3xx_dt_board_compat,
62MACHINE_END 59MACHINE_END
63#endif 60#endif
61
62#ifdef CONFIG_PXA27x
63static const char * const pxa27x_dt_board_compat[] __initconst = {
64 "marvell,pxa270",
65 NULL,
66};
67
68DT_MACHINE_START(PXA27X_DT, "Marvell PXA2xx (Device Tree Support)")
69 .map_io = pxa27x_map_io,
70 .init_irq = pxa27x_dt_init_irq,
71 .handle_irq = pxa27x_handle_irq,
72 .restart = pxa_restart,
73 .dt_compat = pxa27x_dt_board_compat,
74MACHINE_END
75#endif
diff --git a/arch/arm/mach-pxa/pxa27x.c b/arch/arm/mach-pxa/pxa27x.c
index b040d7d14888..af423a48c2e3 100644
--- a/arch/arm/mach-pxa/pxa27x.c
+++ b/arch/arm/mach-pxa/pxa27x.c
@@ -398,6 +398,12 @@ void __init pxa27x_init_irq(void)
398 pxa_init_irq(34, pxa27x_set_wake); 398 pxa_init_irq(34, pxa27x_set_wake);
399} 399}
400 400
401void __init pxa27x_dt_init_irq(void)
402{
403 if (IS_ENABLED(CONFIG_OF))
404 pxa_dt_irq_init(pxa27x_set_wake);
405}
406
401static struct map_desc pxa27x_io_desc[] __initdata = { 407static struct map_desc pxa27x_io_desc[] __initdata = {
402 { /* Mem Ctl */ 408 { /* Mem Ctl */
403 .virtual = (unsigned long)SMEMC_VIRT, 409 .virtual = (unsigned long)SMEMC_VIRT,
diff --git a/arch/arm/mach-pxa/pxa3xx-ulpi.c b/arch/arm/mach-pxa/pxa3xx-ulpi.c
index e329ccefd364..614003e8b081 100644
--- a/arch/arm/mach-pxa/pxa3xx-ulpi.c
+++ b/arch/arm/mach-pxa/pxa3xx-ulpi.c
@@ -74,7 +74,7 @@ static int pxa310_ulpi_poll(void)
74 cpu_relax(); 74 cpu_relax();
75 } 75 }
76 76
77 pr_warning("%s: ULPI access timed out!\n", __func__); 77 pr_warn("%s: ULPI access timed out!\n", __func__);
78 78
79 return -ETIMEDOUT; 79 return -ETIMEDOUT;
80} 80}
@@ -84,7 +84,7 @@ static int pxa310_ulpi_read(struct usb_phy *otg, u32 reg)
84 int err; 84 int err;
85 85
86 if (pxa310_ulpi_get_phymode() != SYNCH) { 86 if (pxa310_ulpi_get_phymode() != SYNCH) {
87 pr_warning("%s: PHY is not in SYNCH mode!\n", __func__); 87 pr_warn("%s: PHY is not in SYNCH mode!\n", __func__);
88 return -EBUSY; 88 return -EBUSY;
89 } 89 }
90 90
@@ -101,7 +101,7 @@ static int pxa310_ulpi_read(struct usb_phy *otg, u32 reg)
101static int pxa310_ulpi_write(struct usb_phy *otg, u32 val, u32 reg) 101static int pxa310_ulpi_write(struct usb_phy *otg, u32 val, u32 reg)
102{ 102{
103 if (pxa310_ulpi_get_phymode() != SYNCH) { 103 if (pxa310_ulpi_get_phymode() != SYNCH) {
104 pr_warning("%s: PHY is not in SYNCH mode!\n", __func__); 104 pr_warn("%s: PHY is not in SYNCH mode!\n", __func__);
105 return -EBUSY; 105 return -EBUSY;
106 } 106 }
107 107
diff --git a/arch/arm/mach-pxa/raumfeld.c b/arch/arm/mach-pxa/raumfeld.c
index 8386dc30b3e4..a762b23ac830 100644
--- a/arch/arm/mach-pxa/raumfeld.c
+++ b/arch/arm/mach-pxa/raumfeld.c
@@ -521,7 +521,7 @@ static void __init raumfeld_w1_init(void)
521 "W1 external pullup enable"); 521 "W1 external pullup enable");
522 522
523 if (ret < 0) 523 if (ret < 0)
524 pr_warning("Unable to request GPIO_W1_PULLUP_ENABLE\n"); 524 pr_warn("Unable to request GPIO_W1_PULLUP_ENABLE\n");
525 else 525 else
526 gpio_direction_output(GPIO_W1_PULLUP_ENABLE, 0); 526 gpio_direction_output(GPIO_W1_PULLUP_ENABLE, 0);
527 527
@@ -600,7 +600,7 @@ static void __init raumfeld_lcd_init(void)
600 600
601 ret = gpio_request(GPIO_TFT_VA_EN, "display VA enable"); 601 ret = gpio_request(GPIO_TFT_VA_EN, "display VA enable");
602 if (ret < 0) 602 if (ret < 0)
603 pr_warning("Unable to request GPIO_TFT_VA_EN\n"); 603 pr_warn("Unable to request GPIO_TFT_VA_EN\n");
604 else 604 else
605 gpio_direction_output(GPIO_TFT_VA_EN, 1); 605 gpio_direction_output(GPIO_TFT_VA_EN, 1);
606 606
@@ -608,7 +608,7 @@ static void __init raumfeld_lcd_init(void)
608 608
609 ret = gpio_request(GPIO_DISPLAY_ENABLE, "display enable"); 609 ret = gpio_request(GPIO_DISPLAY_ENABLE, "display enable");
610 if (ret < 0) 610 if (ret < 0)
611 pr_warning("Unable to request GPIO_DISPLAY_ENABLE\n"); 611 pr_warn("Unable to request GPIO_DISPLAY_ENABLE\n");
612 else 612 else
613 gpio_direction_output(GPIO_DISPLAY_ENABLE, 1); 613 gpio_direction_output(GPIO_DISPLAY_ENABLE, 1);
614 614
@@ -814,17 +814,17 @@ static void __init raumfeld_power_init(void)
814 /* Set PEN2 high to enable maximum charge current */ 814 /* Set PEN2 high to enable maximum charge current */
815 ret = gpio_request(GPIO_CHRG_PEN2, "CHRG_PEN2"); 815 ret = gpio_request(GPIO_CHRG_PEN2, "CHRG_PEN2");
816 if (ret < 0) 816 if (ret < 0)
817 pr_warning("Unable to request GPIO_CHRG_PEN2\n"); 817 pr_warn("Unable to request GPIO_CHRG_PEN2\n");
818 else 818 else
819 gpio_direction_output(GPIO_CHRG_PEN2, 1); 819 gpio_direction_output(GPIO_CHRG_PEN2, 1);
820 820
821 ret = gpio_request(GPIO_CHARGE_DC_OK, "CABLE_DC_OK"); 821 ret = gpio_request(GPIO_CHARGE_DC_OK, "CABLE_DC_OK");
822 if (ret < 0) 822 if (ret < 0)
823 pr_warning("Unable to request GPIO_CHARGE_DC_OK\n"); 823 pr_warn("Unable to request GPIO_CHARGE_DC_OK\n");
824 824
825 ret = gpio_request(GPIO_CHARGE_USB_SUSP, "CHARGE_USB_SUSP"); 825 ret = gpio_request(GPIO_CHARGE_USB_SUSP, "CHARGE_USB_SUSP");
826 if (ret < 0) 826 if (ret < 0)
827 pr_warning("Unable to request GPIO_CHARGE_USB_SUSP\n"); 827 pr_warn("Unable to request GPIO_CHARGE_USB_SUSP\n");
828 else 828 else
829 gpio_direction_output(GPIO_CHARGE_USB_SUSP, 0); 829 gpio_direction_output(GPIO_CHARGE_USB_SUSP, 0);
830 830
@@ -976,19 +976,19 @@ static void __init raumfeld_audio_init(void)
976 976
977 ret = gpio_request(GPIO_CODEC_RESET, "cs4270 reset"); 977 ret = gpio_request(GPIO_CODEC_RESET, "cs4270 reset");
978 if (ret < 0) 978 if (ret < 0)
979 pr_warning("unable to request GPIO_CODEC_RESET\n"); 979 pr_warn("unable to request GPIO_CODEC_RESET\n");
980 else 980 else
981 gpio_direction_output(GPIO_CODEC_RESET, 1); 981 gpio_direction_output(GPIO_CODEC_RESET, 1);
982 982
983 ret = gpio_request(GPIO_SPDIF_RESET, "ak4104 s/pdif reset"); 983 ret = gpio_request(GPIO_SPDIF_RESET, "ak4104 s/pdif reset");
984 if (ret < 0) 984 if (ret < 0)
985 pr_warning("unable to request GPIO_SPDIF_RESET\n"); 985 pr_warn("unable to request GPIO_SPDIF_RESET\n");
986 else 986 else
987 gpio_direction_output(GPIO_SPDIF_RESET, 1); 987 gpio_direction_output(GPIO_SPDIF_RESET, 1);
988 988
989 ret = gpio_request(GPIO_MCLK_RESET, "MCLK reset"); 989 ret = gpio_request(GPIO_MCLK_RESET, "MCLK reset");
990 if (ret < 0) 990 if (ret < 0)
991 pr_warning("unable to request GPIO_MCLK_RESET\n"); 991 pr_warn("unable to request GPIO_MCLK_RESET\n");
992 else 992 else
993 gpio_direction_output(GPIO_MCLK_RESET, 1); 993 gpio_direction_output(GPIO_MCLK_RESET, 1);
994 994
@@ -1019,20 +1019,20 @@ static void __init raumfeld_common_init(void)
1019 1019
1020 ret = gpio_request(GPIO_W2W_RESET, "Wi2Wi reset"); 1020 ret = gpio_request(GPIO_W2W_RESET, "Wi2Wi reset");
1021 if (ret < 0) 1021 if (ret < 0)
1022 pr_warning("Unable to request GPIO_W2W_RESET\n"); 1022 pr_warn("Unable to request GPIO_W2W_RESET\n");
1023 else 1023 else
1024 gpio_direction_output(GPIO_W2W_RESET, 0); 1024 gpio_direction_output(GPIO_W2W_RESET, 0);
1025 1025
1026 ret = gpio_request(GPIO_W2W_PDN, "Wi2Wi powerup"); 1026 ret = gpio_request(GPIO_W2W_PDN, "Wi2Wi powerup");
1027 if (ret < 0) 1027 if (ret < 0)
1028 pr_warning("Unable to request GPIO_W2W_PDN\n"); 1028 pr_warn("Unable to request GPIO_W2W_PDN\n");
1029 else 1029 else
1030 gpio_direction_output(GPIO_W2W_PDN, 0); 1030 gpio_direction_output(GPIO_W2W_PDN, 0);
1031 1031
1032 /* this can be used to switch off the device */ 1032 /* this can be used to switch off the device */
1033 ret = gpio_request(GPIO_SHUTDOWN_SUPPLY, "supply shutdown"); 1033 ret = gpio_request(GPIO_SHUTDOWN_SUPPLY, "supply shutdown");
1034 if (ret < 0) 1034 if (ret < 0)
1035 pr_warning("Unable to request GPIO_SHUTDOWN_SUPPLY\n"); 1035 pr_warn("Unable to request GPIO_SHUTDOWN_SUPPLY\n");
1036 else 1036 else
1037 gpio_direction_output(GPIO_SHUTDOWN_SUPPLY, 0); 1037 gpio_direction_output(GPIO_SHUTDOWN_SUPPLY, 0);
1038 1038
@@ -1051,7 +1051,7 @@ static void __init raumfeld_controller_init(void)
1051 1051
1052 ret = gpio_request(GPIO_SHUTDOWN_BATT, "battery shutdown"); 1052 ret = gpio_request(GPIO_SHUTDOWN_BATT, "battery shutdown");
1053 if (ret < 0) 1053 if (ret < 0)
1054 pr_warning("Unable to request GPIO_SHUTDOWN_BATT\n"); 1054 pr_warn("Unable to request GPIO_SHUTDOWN_BATT\n");
1055 else 1055 else
1056 gpio_direction_output(GPIO_SHUTDOWN_BATT, 0); 1056 gpio_direction_output(GPIO_SHUTDOWN_BATT, 0);
1057 1057
diff --git a/arch/arm/mach-pxa/tosa.c b/arch/arm/mach-pxa/tosa.c
index c158a6e3e0aa..7780d1faa06f 100644
--- a/arch/arm/mach-pxa/tosa.c
+++ b/arch/arm/mach-pxa/tosa.c
@@ -30,7 +30,7 @@
30#include <linux/gpio_keys.h> 30#include <linux/gpio_keys.h>
31#include <linux/input.h> 31#include <linux/input.h>
32#include <linux/gpio.h> 32#include <linux/gpio.h>
33#include <linux/pda_power.h> 33#include <linux/power/gpio-charger.h>
34#include <linux/spi/spi.h> 34#include <linux/spi/spi.h>
35#include <linux/spi/pxa2xx_spi.h> 35#include <linux/spi/pxa2xx_spi.h>
36#include <linux/input/matrix_keypad.h> 36#include <linux/input/matrix_keypad.h>
@@ -361,44 +361,17 @@ static struct pxaficp_platform_data tosa_ficp_platform_data = {
361/* 361/*
362 * Tosa AC IN 362 * Tosa AC IN
363 */ 363 */
364static int tosa_power_init(struct device *dev)
365{
366 int ret = gpio_request(TOSA_GPIO_AC_IN, "ac in");
367 if (ret)
368 goto err_gpio_req;
369
370 ret = gpio_direction_input(TOSA_GPIO_AC_IN);
371 if (ret)
372 goto err_gpio_in;
373
374 return 0;
375
376err_gpio_in:
377 gpio_free(TOSA_GPIO_AC_IN);
378err_gpio_req:
379 return ret;
380}
381
382static void tosa_power_exit(struct device *dev)
383{
384 gpio_free(TOSA_GPIO_AC_IN);
385}
386
387static int tosa_power_ac_online(void)
388{
389 return gpio_get_value(TOSA_GPIO_AC_IN) == 0;
390}
391
392static char *tosa_ac_supplied_to[] = { 364static char *tosa_ac_supplied_to[] = {
393 "main-battery", 365 "main-battery",
394 "backup-battery", 366 "backup-battery",
395 "jacket-battery", 367 "jacket-battery",
396}; 368};
397 369
398static struct pda_power_pdata tosa_power_data = { 370static struct gpio_charger_platform_data tosa_power_data = {
399 .init = tosa_power_init, 371 .name = "charger",
400 .is_ac_online = tosa_power_ac_online, 372 .type = POWER_SUPPLY_TYPE_MAINS,
401 .exit = tosa_power_exit, 373 .gpio = TOSA_GPIO_AC_IN,
374 .gpio_active_low = 1,
402 .supplied_to = tosa_ac_supplied_to, 375 .supplied_to = tosa_ac_supplied_to,
403 .num_supplicants = ARRAY_SIZE(tosa_ac_supplied_to), 376 .num_supplicants = ARRAY_SIZE(tosa_ac_supplied_to),
404}; 377};
@@ -415,7 +388,7 @@ static struct resource tosa_power_resource[] = {
415}; 388};
416 389
417static struct platform_device tosa_power_device = { 390static struct platform_device tosa_power_device = {
418 .name = "pda-power", 391 .name = "gpio-charger",
419 .id = -1, 392 .id = -1,
420 .dev.platform_data = &tosa_power_data, 393 .dev.platform_data = &tosa_power_data,
421 .resource = tosa_power_resource, 394 .resource = tosa_power_resource,
diff --git a/arch/arm/mach-rockchip/headsmp.S b/arch/arm/mach-rockchip/headsmp.S
index 73206e360e31..46c22dedf632 100644
--- a/arch/arm/mach-rockchip/headsmp.S
+++ b/arch/arm/mach-rockchip/headsmp.S
@@ -16,7 +16,10 @@
16#include <linux/init.h> 16#include <linux/init.h>
17 17
18ENTRY(rockchip_secondary_startup) 18ENTRY(rockchip_secondary_startup)
19 bl v7_invalidate_l1 19 mrc p15, 0, r0, c0, c0, 0 @ read main ID register
20 ldr r1, =0x00000c09 @ Cortex-A9 primary part number
21 teq r0, r1
22 beq v7_invalidate_l1
20 b secondary_startup 23 b secondary_startup
21ENDPROC(rockchip_secondary_startup) 24ENDPROC(rockchip_secondary_startup)
22 25
diff --git a/arch/arm/mach-rockchip/platsmp.c b/arch/arm/mach-rockchip/platsmp.c
index 189684f55927..f26fcdca2445 100644
--- a/arch/arm/mach-rockchip/platsmp.c
+++ b/arch/arm/mach-rockchip/platsmp.c
@@ -19,7 +19,11 @@
19#include <linux/io.h> 19#include <linux/io.h>
20#include <linux/of.h> 20#include <linux/of.h>
21#include <linux/of_address.h> 21#include <linux/of_address.h>
22#include <linux/regmap.h>
23#include <linux/mfd/syscon.h>
22 24
25#include <linux/reset.h>
26#include <linux/cpu.h>
23#include <asm/cacheflush.h> 27#include <asm/cacheflush.h>
24#include <asm/cp15.h> 28#include <asm/cp15.h>
25#include <asm/smp_scu.h> 29#include <asm/smp_scu.h>
@@ -37,23 +41,78 @@ static int ncores;
37 41
38#define PMU_PWRDN_SCU 4 42#define PMU_PWRDN_SCU 4
39 43
40static void __iomem *pmu_base_addr; 44static struct regmap *pmu;
41 45
42static inline bool pmu_power_domain_is_on(int pd) 46static int pmu_power_domain_is_on(int pd)
43{ 47{
44 return !(readl_relaxed(pmu_base_addr + PMU_PWRDN_ST) & BIT(pd)); 48 u32 val;
49 int ret;
50
51 ret = regmap_read(pmu, PMU_PWRDN_ST, &val);
52 if (ret < 0)
53 return ret;
54
55 return !(val & BIT(pd));
45} 56}
46 57
47static void pmu_set_power_domain(int pd, bool on) 58struct reset_control *rockchip_get_core_reset(int cpu)
48{ 59{
49 u32 val = readl_relaxed(pmu_base_addr + PMU_PWRDN_CON); 60 struct device *dev = get_cpu_device(cpu);
50 if (on) 61 struct device_node *np;
51 val &= ~BIT(pd); 62
63 /* The cpu device is only available after the initial core bringup */
64 if (dev)
65 np = dev->of_node;
52 else 66 else
53 val |= BIT(pd); 67 np = of_get_cpu_node(cpu, 0);
54 writel(val, pmu_base_addr + PMU_PWRDN_CON);
55 68
56 while (pmu_power_domain_is_on(pd) != on) { } 69 return of_reset_control_get(np, NULL);
70}
71
72static int pmu_set_power_domain(int pd, bool on)
73{
74 u32 val = (on) ? 0 : BIT(pd);
75 int ret;
76
77 /*
78 * We need to soft reset the cpu when we turn off the cpu power domain,
79 * or else the active processors might be stalled when the individual
80 * processor is powered down.
81 */
82 if (read_cpuid_part() != ARM_CPU_PART_CORTEX_A9) {
83 struct reset_control *rstc = rockchip_get_core_reset(pd);
84
85 if (IS_ERR(rstc)) {
86 pr_err("%s: could not get reset control for core %d\n",
87 __func__, pd);
88 return PTR_ERR(rstc);
89 }
90
91 if (on)
92 reset_control_deassert(rstc);
93 else
94 reset_control_assert(rstc);
95
96 reset_control_put(rstc);
97 }
98
99 ret = regmap_update_bits(pmu, PMU_PWRDN_CON, BIT(pd), val);
100 if (ret < 0) {
101 pr_err("%s: could not update power domain\n", __func__);
102 return ret;
103 }
104
105 ret = -1;
106 while (ret != on) {
107 ret = pmu_power_domain_is_on(pd);
108 if (ret < 0) {
109 pr_err("%s: could not read power domain state\n",
110 __func__);
111 return ret;
112 }
113 }
114
115 return 0;
57} 116}
58 117
59/* 118/*
@@ -63,7 +122,9 @@ static void pmu_set_power_domain(int pd, bool on)
63static int __cpuinit rockchip_boot_secondary(unsigned int cpu, 122static int __cpuinit rockchip_boot_secondary(unsigned int cpu,
64 struct task_struct *idle) 123 struct task_struct *idle)
65{ 124{
66 if (!sram_base_addr || !pmu_base_addr) { 125 int ret;
126
127 if (!sram_base_addr || !pmu) {
67 pr_err("%s: sram or pmu missing for cpu boot\n", __func__); 128 pr_err("%s: sram or pmu missing for cpu boot\n", __func__);
68 return -ENXIO; 129 return -ENXIO;
69 } 130 }
@@ -75,7 +136,24 @@ static int __cpuinit rockchip_boot_secondary(unsigned int cpu,
75 } 136 }
76 137
77 /* start the core */ 138 /* start the core */
78 pmu_set_power_domain(0 + cpu, true); 139 ret = pmu_set_power_domain(0 + cpu, true);
140 if (ret < 0)
141 return ret;
142
143 if (read_cpuid_part() != ARM_CPU_PART_CORTEX_A9) {
144 /* We communicate with the bootrom to active the cpus other
145 * than cpu0, after a blob of initialize code, they will
146 * stay at wfe state, once they are actived, they will check
147 * the mailbox:
148 * sram_base_addr + 4: 0xdeadbeaf
149 * sram_base_addr + 8: start address for pc
150 * */
151 udelay(10);
152 writel(virt_to_phys(rockchip_secondary_startup),
153 sram_base_addr + 8);
154 writel(0xDEADBEAF, sram_base_addr + 4);
155 dsb_sev();
156 }
79 157
80 return 0; 158 return 0;
81} 159}
@@ -110,8 +188,6 @@ static int __init rockchip_smp_prepare_sram(struct device_node *node)
110 return -EINVAL; 188 return -EINVAL;
111 } 189 }
112 190
113 sram_base_addr = of_iomap(node, 0);
114
115 /* set the boot function for the sram code */ 191 /* set the boot function for the sram code */
116 rockchip_boot_fn = virt_to_phys(rockchip_secondary_startup); 192 rockchip_boot_fn = virt_to_phys(rockchip_secondary_startup);
117 193
@@ -125,54 +201,115 @@ static int __init rockchip_smp_prepare_sram(struct device_node *node)
125 return 0; 201 return 0;
126} 202}
127 203
128static void __init rockchip_smp_prepare_cpus(unsigned int max_cpus) 204static struct regmap_config rockchip_pmu_regmap_config = {
205 .reg_bits = 32,
206 .val_bits = 32,
207 .reg_stride = 4,
208};
209
210static int __init rockchip_smp_prepare_pmu(void)
129{ 211{
130 struct device_node *node; 212 struct device_node *node;
131 unsigned int i; 213 void __iomem *pmu_base;
132 214
133 node = of_find_compatible_node(NULL, NULL, "arm,cortex-a9-scu"); 215 /*
216 * This function is only called via smp_ops->smp_prepare_cpu().
217 * That only happens if a "/cpus" device tree node exists
218 * and has an "enable-method" property that selects the SMP
219 * operations defined herein.
220 */
221 node = of_find_node_by_path("/cpus");
222
223 pmu = syscon_regmap_lookup_by_phandle(node, "rockchip,pmu");
224 of_node_put(node);
225 if (!IS_ERR(pmu))
226 return 0;
227
228 pmu = syscon_regmap_lookup_by_compatible("rockchip,rk3066-pmu");
229 if (!IS_ERR(pmu))
230 return 0;
231
232 /* fallback, create our own regmap for the pmu area */
233 pmu = NULL;
234 node = of_find_compatible_node(NULL, NULL, "rockchip,rk3066-pmu");
134 if (!node) { 235 if (!node) {
135 pr_err("%s: missing scu\n", __func__); 236 pr_err("%s: could not find pmu dt node\n", __func__);
136 return; 237 return -ENODEV;
137 } 238 }
138 239
139 scu_base_addr = of_iomap(node, 0); 240 pmu_base = of_iomap(node, 0);
140 if (!scu_base_addr) { 241 if (!pmu_base) {
141 pr_err("%s: could not map scu registers\n", __func__); 242 pr_err("%s: could not map pmu registers\n", __func__);
142 return; 243 return -ENOMEM;
143 } 244 }
144 245
145 node = of_find_compatible_node(NULL, NULL, "rockchip,rk3066-smp-sram"); 246 pmu = regmap_init_mmio(NULL, pmu_base, &rockchip_pmu_regmap_config);
146 if (!node) { 247 if (IS_ERR(pmu)) {
147 pr_err("%s: could not find sram dt node\n", __func__); 248 int ret = PTR_ERR(pmu);
148 return; 249
250 iounmap(pmu_base);
251 pmu = NULL;
252 pr_err("%s: regmap init failed\n", __func__);
253 return ret;
149 } 254 }
150 255
151 if (rockchip_smp_prepare_sram(node)) 256 return 0;
152 return; 257}
153 258
154 node = of_find_compatible_node(NULL, NULL, "rockchip,rk3066-pmu"); 259static void __init rockchip_smp_prepare_cpus(unsigned int max_cpus)
260{
261 struct device_node *node;
262 unsigned int i;
263
264 node = of_find_compatible_node(NULL, NULL, "rockchip,rk3066-smp-sram");
155 if (!node) { 265 if (!node) {
156 pr_err("%s: could not find pmu dt node\n", __func__); 266 pr_err("%s: could not find sram dt node\n", __func__);
157 return; 267 return;
158 } 268 }
159 269
160 pmu_base_addr = of_iomap(node, 0); 270 sram_base_addr = of_iomap(node, 0);
161 if (!pmu_base_addr) { 271 if (!sram_base_addr) {
162 pr_err("%s: could not map pmu registers\n", __func__); 272 pr_err("%s: could not map sram registers\n", __func__);
163 return; 273 return;
164 } 274 }
165 275
166 /* enable the SCU power domain */ 276 if (rockchip_smp_prepare_pmu())
167 pmu_set_power_domain(PMU_PWRDN_SCU, true); 277 return;
168
169 /*
170 * While the number of cpus is gathered from dt, also get the number
171 * of cores from the scu to verify this value when booting the cores.
172 */
173 ncores = scu_get_core_count(scu_base_addr);
174 278
175 scu_enable(scu_base_addr); 279 if (read_cpuid_part() == ARM_CPU_PART_CORTEX_A9) {
280 if (rockchip_smp_prepare_sram(node))
281 return;
282
283 /* enable the SCU power domain */
284 pmu_set_power_domain(PMU_PWRDN_SCU, true);
285
286 node = of_find_compatible_node(NULL, NULL, "arm,cortex-a9-scu");
287 if (!node) {
288 pr_err("%s: missing scu\n", __func__);
289 return;
290 }
291
292 scu_base_addr = of_iomap(node, 0);
293 if (!scu_base_addr) {
294 pr_err("%s: could not map scu registers\n", __func__);
295 return;
296 }
297
298 /*
299 * While the number of cpus is gathered from dt, also get the
300 * number of cores from the scu to verify this value when
301 * booting the cores.
302 */
303 ncores = scu_get_core_count(scu_base_addr);
304 pr_err("%s: ncores %d\n", __func__, ncores);
305
306 scu_enable(scu_base_addr);
307 } else {
308 unsigned int l2ctlr;
309
310 asm ("mrc p15, 1, %0, c9, c0, 2\n" : "=r" (l2ctlr));
311 ncores = ((l2ctlr >> 24) & 0x3) + 1;
312 }
176 313
177 /* Make sure that all cores except the first are really off */ 314 /* Make sure that all cores except the first are really off */
178 for (i = 1; i < ncores; i++) 315 for (i = 1; i < ncores; i++)
diff --git a/arch/arm/mach-rockchip/rockchip.c b/arch/arm/mach-rockchip/rockchip.c
index 8ab9e0e7ff04..d226b71d21d5 100644
--- a/arch/arm/mach-rockchip/rockchip.c
+++ b/arch/arm/mach-rockchip/rockchip.c
@@ -24,6 +24,12 @@
24#include <asm/hardware/cache-l2x0.h> 24#include <asm/hardware/cache-l2x0.h>
25#include "core.h" 25#include "core.h"
26 26
27static void __init rockchip_dt_init(void)
28{
29 of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
30 platform_device_register_simple("cpufreq-dt", 0, NULL, 0);
31}
32
27static const char * const rockchip_board_dt_compat[] = { 33static const char * const rockchip_board_dt_compat[] = {
28 "rockchip,rk2928", 34 "rockchip,rk2928",
29 "rockchip,rk3066a", 35 "rockchip,rk3066a",
@@ -37,4 +43,5 @@ DT_MACHINE_START(ROCKCHIP_DT, "Rockchip Cortex-A9 (Device Tree)")
37 .l2c_aux_val = 0, 43 .l2c_aux_val = 0,
38 .l2c_aux_mask = ~0, 44 .l2c_aux_mask = ~0,
39 .dt_compat = rockchip_board_dt_compat, 45 .dt_compat = rockchip_board_dt_compat,
46 .init_machine = rockchip_dt_init,
40MACHINE_END 47MACHINE_END
diff --git a/arch/arm/mach-shmobile/Kconfig b/arch/arm/mach-shmobile/Kconfig
index 0f2539550f1b..1b4fafe524ff 100644
--- a/arch/arm/mach-shmobile/Kconfig
+++ b/arch/arm/mach-shmobile/Kconfig
@@ -1,5 +1,6 @@
1config ARCH_SHMOBILE 1config ARCH_SHMOBILE
2 bool 2 bool
3 select ZONE_DMA if ARM_LPAE
3 4
4config PM_RCAR 5config PM_RCAR
5 bool 6 bool
@@ -18,6 +19,7 @@ config ARCH_RCAR_GEN2
18 select PM_RCAR if PM || SMP 19 select PM_RCAR if PM || SMP
19 select RENESAS_IRQC 20 select RENESAS_IRQC
20 select SYS_SUPPORTS_SH_CMT 21 select SYS_SUPPORTS_SH_CMT
22 select PCI_DOMAINS if PCI
21 23
22config ARCH_RMOBILE 24config ARCH_RMOBILE
23 bool 25 bool
diff --git a/arch/arm/mach-shmobile/Makefile b/arch/arm/mach-shmobile/Makefile
index 7d68eba53be3..b55cac0e5b2b 100644
--- a/arch/arm/mach-shmobile/Makefile
+++ b/arch/arm/mach-shmobile/Makefile
@@ -35,6 +35,7 @@ cpu-y := platsmp.o headsmp.o
35 35
36# Shared SoC family objects 36# Shared SoC family objects
37obj-$(CONFIG_ARCH_RCAR_GEN2) += setup-rcar-gen2.o platsmp-apmu.o $(cpu-y) 37obj-$(CONFIG_ARCH_RCAR_GEN2) += setup-rcar-gen2.o platsmp-apmu.o $(cpu-y)
38CFLAGS_setup-rcar-gen2.o += -march=armv7-a
38 39
39# SMP objects 40# SMP objects
40smp-y := $(cpu-y) 41smp-y := $(cpu-y)
diff --git a/arch/arm/mach-shmobile/board-armadillo800eva.c b/arch/arm/mach-shmobile/board-armadillo800eva.c
index de95181c7de4..6d949f1c850b 100644
--- a/arch/arm/mach-shmobile/board-armadillo800eva.c
+++ b/arch/arm/mach-shmobile/board-armadillo800eva.c
@@ -1229,8 +1229,15 @@ static void __init eva_init(void)
1229 static struct pm_domain_device domain_devices[] __initdata = { 1229 static struct pm_domain_device domain_devices[] __initdata = {
1230 { "A4LC", &lcdc0_device }, 1230 { "A4LC", &lcdc0_device },
1231 { "A4LC", &hdmi_lcdc_device }, 1231 { "A4LC", &hdmi_lcdc_device },
1232 { "A4MP", &hdmi_device },
1233 { "A4MP", &fsi_device },
1234 { "A4R", &ceu0_device },
1235 { "A4S", &sh_eth_device },
1236 { "A3SP", &pwm_device },
1237 { "A3SP", &sdhi0_device },
1238 { "A3SP", &sh_mmcif_device },
1232 }; 1239 };
1233 struct platform_device *usb = NULL; 1240 struct platform_device *usb = NULL, *sdhi1 = NULL;
1234 1241
1235 regulator_register_always_on(0, "fixed-3.3V", fixed3v3_power_consumers, 1242 regulator_register_always_on(0, "fixed-3.3V", fixed3v3_power_consumers,
1236 ARRAY_SIZE(fixed3v3_power_consumers), 3300000); 1243 ARRAY_SIZE(fixed3v3_power_consumers), 3300000);
@@ -1299,6 +1306,7 @@ static void __init eva_init(void)
1299 1306
1300 platform_device_register(&vcc_sdhi1); 1307 platform_device_register(&vcc_sdhi1);
1301 platform_device_register(&sdhi1_device); 1308 platform_device_register(&sdhi1_device);
1309 sdhi1 = &sdhi1_device;
1302 } 1310 }
1303 1311
1304 1312
@@ -1319,6 +1327,8 @@ static void __init eva_init(void)
1319 ARRAY_SIZE(domain_devices)); 1327 ARRAY_SIZE(domain_devices));
1320 if (usb) 1328 if (usb)
1321 rmobile_add_device_to_domain("A3SP", usb); 1329 rmobile_add_device_to_domain("A3SP", usb);
1330 if (sdhi1)
1331 rmobile_add_device_to_domain("A3SP", sdhi1);
1322 1332
1323 r8a7740_pm_init(); 1333 r8a7740_pm_init();
1324} 1334}
diff --git a/arch/arm/mach-shmobile/board-kzm9g-reference.c b/arch/arm/mach-shmobile/board-kzm9g-reference.c
index f2ef759b6e96..2e82e44ab852 100644
--- a/arch/arm/mach-shmobile/board-kzm9g-reference.c
+++ b/arch/arm/mach-shmobile/board-kzm9g-reference.c
@@ -39,6 +39,13 @@ static void __init kzm_init(void)
39#endif 39#endif
40} 40}
41 41
42#define RESCNT2 IOMEM(0xe6188020)
43static void kzm9g_restart(enum reboot_mode mode, const char *cmd)
44{
45 /* Do soft power on reset */
46 writel((1 << 31), RESCNT2);
47}
48
42static const char *kzm9g_boards_compat_dt[] __initdata = { 49static const char *kzm9g_boards_compat_dt[] __initdata = {
43 "renesas,kzm9g-reference", 50 "renesas,kzm9g-reference",
44 NULL, 51 NULL,
@@ -50,5 +57,6 @@ DT_MACHINE_START(KZM9G_DT, "kzm9g-reference")
50 .init_early = shmobile_init_delay, 57 .init_early = shmobile_init_delay,
51 .init_machine = kzm_init, 58 .init_machine = kzm_init,
52 .init_late = shmobile_init_late, 59 .init_late = shmobile_init_late,
60 .restart = kzm9g_restart,
53 .dt_compat = kzm9g_boards_compat_dt, 61 .dt_compat = kzm9g_boards_compat_dt,
54MACHINE_END 62MACHINE_END
diff --git a/arch/arm/mach-shmobile/common.h b/arch/arm/mach-shmobile/common.h
index 72087c79ad7b..309025efd4cf 100644
--- a/arch/arm/mach-shmobile/common.h
+++ b/arch/arm/mach-shmobile/common.h
@@ -19,11 +19,6 @@ extern void shmobile_boot_scu(void);
19extern void shmobile_smp_scu_prepare_cpus(unsigned int max_cpus); 19extern void shmobile_smp_scu_prepare_cpus(unsigned int max_cpus);
20extern void shmobile_smp_scu_cpu_die(unsigned int cpu); 20extern void shmobile_smp_scu_cpu_die(unsigned int cpu);
21extern int shmobile_smp_scu_cpu_kill(unsigned int cpu); 21extern int shmobile_smp_scu_cpu_kill(unsigned int cpu);
22extern void shmobile_smp_apmu_prepare_cpus(unsigned int max_cpus);
23extern int shmobile_smp_apmu_boot_secondary(unsigned int cpu,
24 struct task_struct *idle);
25extern void shmobile_smp_apmu_cpu_die(unsigned int cpu);
26extern int shmobile_smp_apmu_cpu_kill(unsigned int cpu);
27struct clk; 22struct clk;
28extern int shmobile_clk_init(void); 23extern int shmobile_clk_init(void);
29extern void shmobile_handle_irq_intc(struct pt_regs *); 24extern void shmobile_handle_irq_intc(struct pt_regs *);
diff --git a/arch/arm/mach-shmobile/platsmp-apmu.c b/arch/arm/mach-shmobile/platsmp-apmu.c
index 2c06810d3a70..f483b560b066 100644
--- a/arch/arm/mach-shmobile/platsmp-apmu.c
+++ b/arch/arm/mach-shmobile/platsmp-apmu.c
@@ -1,6 +1,7 @@
1/* 1/*
2 * SMP support for SoCs with APMU 2 * SMP support for SoCs with APMU
3 * 3 *
4 * Copyright (C) 2014 Renesas Electronics Corporation
4 * Copyright (C) 2013 Magnus Damm 5 * Copyright (C) 2013 Magnus Damm
5 * 6 *
6 * This program is free software; you can redistribute it and/or modify 7 * This program is free software; you can redistribute it and/or modify
@@ -22,6 +23,7 @@
22#include <asm/smp_plat.h> 23#include <asm/smp_plat.h>
23#include <asm/suspend.h> 24#include <asm/suspend.h>
24#include "common.h" 25#include "common.h"
26#include "platsmp-apmu.h"
25 27
26static struct { 28static struct {
27 void __iomem *iomem; 29 void __iomem *iomem;
@@ -83,28 +85,15 @@ static void apmu_init_cpu(struct resource *res, int cpu, int bit)
83 pr_debug("apmu ioremap %d %d %pr\n", cpu, bit, res); 85 pr_debug("apmu ioremap %d %d %pr\n", cpu, bit, res);
84} 86}
85 87
86static struct { 88static void apmu_parse_cfg(void (*fn)(struct resource *res, int cpu, int bit),
87 struct resource iomem; 89 struct rcar_apmu_config *apmu_config, int num)
88 int cpus[4];
89} apmu_config[] = {
90 {
91 .iomem = DEFINE_RES_MEM(0xe6152000, 0x88),
92 .cpus = { 0, 1, 2, 3 },
93 },
94 {
95 .iomem = DEFINE_RES_MEM(0xe6151000, 0x88),
96 .cpus = { 0x100, 0x101, 0x102, 0x103 },
97 }
98};
99
100static void apmu_parse_cfg(void (*fn)(struct resource *res, int cpu, int bit))
101{ 90{
102 u32 id; 91 u32 id;
103 int k; 92 int k;
104 int bit, index; 93 int bit, index;
105 bool is_allowed; 94 bool is_allowed;
106 95
107 for (k = 0; k < ARRAY_SIZE(apmu_config); k++) { 96 for (k = 0; k < num; k++) {
108 /* only enable the cluster that includes the boot CPU */ 97 /* only enable the cluster that includes the boot CPU */
109 is_allowed = false; 98 is_allowed = false;
110 for (bit = 0; bit < ARRAY_SIZE(apmu_config[k].cpus); bit++) { 99 for (bit = 0; bit < ARRAY_SIZE(apmu_config[k].cpus); bit++) {
@@ -128,14 +117,16 @@ static void apmu_parse_cfg(void (*fn)(struct resource *res, int cpu, int bit))
128 } 117 }
129} 118}
130 119
131void __init shmobile_smp_apmu_prepare_cpus(unsigned int max_cpus) 120void __init shmobile_smp_apmu_prepare_cpus(unsigned int max_cpus,
121 struct rcar_apmu_config *apmu_config,
122 int num)
132{ 123{
133 /* install boot code shared by all CPUs */ 124 /* install boot code shared by all CPUs */
134 shmobile_boot_fn = virt_to_phys(shmobile_smp_boot); 125 shmobile_boot_fn = virt_to_phys(shmobile_smp_boot);
135 shmobile_boot_arg = MPIDR_HWID_BITMASK; 126 shmobile_boot_arg = MPIDR_HWID_BITMASK;
136 127
137 /* perform per-cpu setup */ 128 /* perform per-cpu setup */
138 apmu_parse_cfg(apmu_init_cpu); 129 apmu_parse_cfg(apmu_init_cpu, apmu_config, num);
139} 130}
140 131
141#ifdef CONFIG_SMP 132#ifdef CONFIG_SMP
diff --git a/arch/arm/mach-shmobile/platsmp-apmu.h b/arch/arm/mach-shmobile/platsmp-apmu.h
new file mode 100644
index 000000000000..76512c9a2545
--- /dev/null
+++ b/arch/arm/mach-shmobile/platsmp-apmu.h
@@ -0,0 +1,32 @@
1/*
2 * rmobile apmu definition
3 *
4 * Copyright (C) 2014 Renesas Electronics Corporation
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; version 2 of the License.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 */
15
16#ifndef PLATSMP_APMU_H
17#define PLATSMP_APMU_H
18
19struct rcar_apmu_config {
20 struct resource iomem;
21 int cpus[4];
22};
23
24extern void shmobile_smp_apmu_prepare_cpus(unsigned int max_cpus,
25 struct rcar_apmu_config *apmu_config,
26 int num);
27extern int shmobile_smp_apmu_boot_secondary(unsigned int cpu,
28 struct task_struct *idle);
29extern void shmobile_smp_apmu_cpu_die(unsigned int cpu);
30extern int shmobile_smp_apmu_cpu_kill(unsigned int cpu);
31
32#endif /* PLATSMP_APMU_H */
diff --git a/arch/arm/mach-shmobile/pm-r8a7740.c b/arch/arm/mach-shmobile/pm-r8a7740.c
index e3f146448237..ac2eecd6f5ea 100644
--- a/arch/arm/mach-shmobile/pm-r8a7740.c
+++ b/arch/arm/mach-shmobile/pm-r8a7740.c
@@ -14,10 +14,10 @@
14#include "pm-rmobile.h" 14#include "pm-rmobile.h"
15 15
16#if defined(CONFIG_PM) && !defined(CONFIG_ARCH_MULTIPLATFORM) 16#if defined(CONFIG_PM) && !defined(CONFIG_ARCH_MULTIPLATFORM)
17static int r8a7740_pd_a4s_suspend(void) 17static int r8a7740_pd_a3sm_suspend(void)
18{ 18{
19 /* 19 /*
20 * The A4S domain contains the CPU core and therefore it should 20 * The A3SM domain contains the CPU core and therefore it should
21 * only be turned off if the CPU is not in use. 21 * only be turned off if the CPU is not in use.
22 */ 22 */
23 return -EBUSY; 23 return -EBUSY;
@@ -32,29 +32,65 @@ static int r8a7740_pd_a3sp_suspend(void)
32 return console_suspend_enabled ? 0 : -EBUSY; 32 return console_suspend_enabled ? 0 : -EBUSY;
33} 33}
34 34
35static int r8a7740_pd_d4_suspend(void)
36{
37 /*
38 * The D4 domain contains the Coresight-ETM hardware block and
39 * therefore it should only be turned off if the debug module is
40 * not in use.
41 */
42 return -EBUSY;
43}
44
35static struct rmobile_pm_domain r8a7740_pm_domains[] = { 45static struct rmobile_pm_domain r8a7740_pm_domains[] = {
36 { 46 {
37 .genpd.name = "A4LC", 47 .genpd.name = "A4LC",
38 .bit_shift = 1, 48 .bit_shift = 1,
39 }, { 49 }, {
50 .genpd.name = "A4MP",
51 .bit_shift = 2,
52 }, {
53 .genpd.name = "D4",
54 .bit_shift = 3,
55 .gov = &pm_domain_always_on_gov,
56 .suspend = r8a7740_pd_d4_suspend,
57 }, {
58 .genpd.name = "A4R",
59 .bit_shift = 5,
60 }, {
61 .genpd.name = "A3RV",
62 .bit_shift = 6,
63 }, {
40 .genpd.name = "A4S", 64 .genpd.name = "A4S",
41 .bit_shift = 10, 65 .bit_shift = 10,
42 .gov = &pm_domain_always_on_gov,
43 .no_debug = true, 66 .no_debug = true,
44 .suspend = r8a7740_pd_a4s_suspend,
45 }, { 67 }, {
46 .genpd.name = "A3SP", 68 .genpd.name = "A3SP",
47 .bit_shift = 11, 69 .bit_shift = 11,
48 .gov = &pm_domain_always_on_gov, 70 .gov = &pm_domain_always_on_gov,
49 .no_debug = true, 71 .no_debug = true,
50 .suspend = r8a7740_pd_a3sp_suspend, 72 .suspend = r8a7740_pd_a3sp_suspend,
73 }, {
74 .genpd.name = "A3SM",
75 .bit_shift = 12,
76 .gov = &pm_domain_always_on_gov,
77 .suspend = r8a7740_pd_a3sm_suspend,
78 }, {
79 .genpd.name = "A3SG",
80 .bit_shift = 13,
81 }, {
82 .genpd.name = "A4SU",
83 .bit_shift = 20,
51 }, 84 },
52}; 85};
53 86
54void __init r8a7740_init_pm_domains(void) 87void __init r8a7740_init_pm_domains(void)
55{ 88{
56 rmobile_init_domains(r8a7740_pm_domains, ARRAY_SIZE(r8a7740_pm_domains)); 89 rmobile_init_domains(r8a7740_pm_domains, ARRAY_SIZE(r8a7740_pm_domains));
90 pm_genpd_add_subdomain_names("A4R", "A3RV");
57 pm_genpd_add_subdomain_names("A4S", "A3SP"); 91 pm_genpd_add_subdomain_names("A4S", "A3SP");
92 pm_genpd_add_subdomain_names("A4S", "A3SM");
93 pm_genpd_add_subdomain_names("A4S", "A3SG");
58} 94}
59#endif /* CONFIG_PM && !CONFIG_ARCH_MULTIPLATFORM */ 95#endif /* CONFIG_PM && !CONFIG_ARCH_MULTIPLATFORM */
60 96
diff --git a/arch/arm/mach-shmobile/setup-r8a7740.c b/arch/arm/mach-shmobile/setup-r8a7740.c
index fe15dd26d15d..79ad93dfdae4 100644
--- a/arch/arm/mach-shmobile/setup-r8a7740.c
+++ b/arch/arm/mach-shmobile/setup-r8a7740.c
@@ -67,6 +67,7 @@ static struct map_desc r8a7740_io_desc[] __initdata = {
67 67
68void __init r8a7740_map_io(void) 68void __init r8a7740_map_io(void)
69{ 69{
70 debug_ll_io_init();
70 iotable_init(r8a7740_io_desc, ARRAY_SIZE(r8a7740_io_desc)); 71 iotable_init(r8a7740_io_desc, ARRAY_SIZE(r8a7740_io_desc));
71} 72}
72 73
@@ -742,6 +743,12 @@ static void r8a7740_i2c_workaround(struct platform_device *pdev)
742void __init r8a7740_add_standard_devices(void) 743void __init r8a7740_add_standard_devices(void)
743{ 744{
744 static struct pm_domain_device domain_devices[] __initdata = { 745 static struct pm_domain_device domain_devices[] __initdata = {
746 { "A4R", &tmu0_device },
747 { "A4R", &i2c0_device },
748 { "A4S", &irqpin0_device },
749 { "A4S", &irqpin1_device },
750 { "A4S", &irqpin2_device },
751 { "A4S", &irqpin3_device },
745 { "A3SP", &scif0_device }, 752 { "A3SP", &scif0_device },
746 { "A3SP", &scif1_device }, 753 { "A3SP", &scif1_device },
747 { "A3SP", &scif2_device }, 754 { "A3SP", &scif2_device },
@@ -752,6 +759,11 @@ void __init r8a7740_add_standard_devices(void)
752 { "A3SP", &scif7_device }, 759 { "A3SP", &scif7_device },
753 { "A3SP", &scif8_device }, 760 { "A3SP", &scif8_device },
754 { "A3SP", &i2c1_device }, 761 { "A3SP", &i2c1_device },
762 { "A3SP", &ipmmu_device },
763 { "A3SP", &dma0_device },
764 { "A3SP", &dma1_device },
765 { "A3SP", &dma2_device },
766 { "A3SP", &usb_dma_device },
755 }; 767 };
756 768
757 /* I2C work-around */ 769 /* I2C work-around */
diff --git a/arch/arm/mach-shmobile/setup-r8a7779.c b/arch/arm/mach-shmobile/setup-r8a7779.c
index 645d7cca6238..6156d172cf31 100644
--- a/arch/arm/mach-shmobile/setup-r8a7779.c
+++ b/arch/arm/mach-shmobile/setup-r8a7779.c
@@ -66,6 +66,7 @@ static struct map_desc r8a7779_io_desc[] __initdata = {
66 66
67void __init r8a7779_map_io(void) 67void __init r8a7779_map_io(void)
68{ 68{
69 debug_ll_io_init();
69 iotable_init(r8a7779_io_desc, ARRAY_SIZE(r8a7779_io_desc)); 70 iotable_init(r8a7779_io_desc, ARRAY_SIZE(r8a7779_io_desc));
70} 71}
71 72
diff --git a/arch/arm/mach-shmobile/setup-rcar-gen2.c b/arch/arm/mach-shmobile/setup-rcar-gen2.c
index a669377aea57..3dd6edd9bd1d 100644
--- a/arch/arm/mach-shmobile/setup-rcar-gen2.c
+++ b/arch/arm/mach-shmobile/setup-rcar-gen2.c
@@ -3,6 +3,7 @@
3 * 3 *
4 * Copyright (C) 2013 Renesas Solutions Corp. 4 * Copyright (C) 2013 Renesas Solutions Corp.
5 * Copyright (C) 2013 Magnus Damm 5 * Copyright (C) 2013 Magnus Damm
6 * Copyright (C) 2014 Ulrich Hecht
6 * 7 *
7 * This program is free software; you can redistribute it and/or modify 8 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by 9 * it under the terms of the GNU General Public License as published by
@@ -20,6 +21,7 @@
20#include <linux/dma-contiguous.h> 21#include <linux/dma-contiguous.h>
21#include <linux/io.h> 22#include <linux/io.h>
22#include <linux/kernel.h> 23#include <linux/kernel.h>
24#include <linux/of.h>
23#include <linux/of_fdt.h> 25#include <linux/of_fdt.h>
24#include <asm/mach/arch.h> 26#include <asm/mach/arch.h>
25#include "common.h" 27#include "common.h"
@@ -50,37 +52,61 @@ void __init rcar_gen2_timer_init(void)
50{ 52{
51#if defined(CONFIG_ARM_ARCH_TIMER) || defined(CONFIG_COMMON_CLK) 53#if defined(CONFIG_ARM_ARCH_TIMER) || defined(CONFIG_COMMON_CLK)
52 u32 mode = rcar_gen2_read_mode_pins(); 54 u32 mode = rcar_gen2_read_mode_pins();
55 bool is_e2 = (bool)of_find_compatible_node(NULL, NULL,
56 "renesas,r8a7794");
53#endif 57#endif
54#ifdef CONFIG_ARM_ARCH_TIMER 58#ifdef CONFIG_ARM_ARCH_TIMER
55 void __iomem *base; 59 void __iomem *base;
56 int extal_mhz = 0; 60 int extal_mhz = 0;
57 u32 freq; 61 u32 freq;
58 62
59 /* At Linux boot time the r8a7790 arch timer comes up 63 if (is_e2) {
60 * with the counter disabled. Moreover, it may also report 64 freq = 260000000 / 8; /* ZS / 8 */
61 * a potentially incorrect fixed 13 MHz frequency. To be 65 /* CNTVOFF has to be initialized either from non-secure
62 * correct these registers need to be updated to use the 66 * Hypervisor mode or secure Monitor mode with SCR.NS==1.
63 * frequency EXTAL / 2 which can be determined by the MD pins. 67 * If TrustZone is enabled then it should be handled by the
64 */ 68 * secure code.
65 69 */
66 switch (mode & (MD(14) | MD(13))) { 70 asm volatile(
67 case 0: 71 " cps 0x16\n"
68 extal_mhz = 15; 72 " mrc p15, 0, r1, c1, c1, 0\n"
69 break; 73 " orr r0, r1, #1\n"
70 case MD(13): 74 " mcr p15, 0, r0, c1, c1, 0\n"
71 extal_mhz = 20; 75 " isb\n"
72 break; 76 " mov r0, #0\n"
73 case MD(14): 77 " mcrr p15, 4, r0, r0, c14\n"
74 extal_mhz = 26; 78 " isb\n"
75 break; 79 " mcr p15, 0, r1, c1, c1, 0\n"
76 case MD(13) | MD(14): 80 " isb\n"
77 extal_mhz = 30; 81 " cps 0x13\n"
78 break; 82 : : : "r0", "r1");
83 } else {
84 /* At Linux boot time the r8a7790 arch timer comes up
85 * with the counter disabled. Moreover, it may also report
86 * a potentially incorrect fixed 13 MHz frequency. To be
87 * correct these registers need to be updated to use the
88 * frequency EXTAL / 2 which can be determined by the MD pins.
89 */
90
91 switch (mode & (MD(14) | MD(13))) {
92 case 0:
93 extal_mhz = 15;
94 break;
95 case MD(13):
96 extal_mhz = 20;
97 break;
98 case MD(14):
99 extal_mhz = 26;
100 break;
101 case MD(13) | MD(14):
102 extal_mhz = 30;
103 break;
104 }
105
106 /* The arch timer frequency equals EXTAL / 2 */
107 freq = extal_mhz * (1000000 / 2);
79 } 108 }
80 109
81 /* The arch timer frequency equals EXTAL / 2 */
82 freq = extal_mhz * (1000000 / 2);
83
84 /* Remap "armgcnt address map" space */ 110 /* Remap "armgcnt address map" space */
85 base = ioremap(0xe6080000, PAGE_SIZE); 111 base = ioremap(0xe6080000, PAGE_SIZE);
86 112
diff --git a/arch/arm/mach-shmobile/setup-sh7372.c b/arch/arm/mach-shmobile/setup-sh7372.c
index ca2b80b9bc90..458a2cfad417 100644
--- a/arch/arm/mach-shmobile/setup-sh7372.c
+++ b/arch/arm/mach-shmobile/setup-sh7372.c
@@ -56,6 +56,7 @@ static struct map_desc sh7372_io_desc[] __initdata = {
56 56
57void __init sh7372_map_io(void) 57void __init sh7372_map_io(void)
58{ 58{
59 debug_ll_io_init();
59 iotable_init(sh7372_io_desc, ARRAY_SIZE(sh7372_io_desc)); 60 iotable_init(sh7372_io_desc, ARRAY_SIZE(sh7372_io_desc));
60} 61}
61 62
@@ -1008,6 +1009,7 @@ DT_MACHINE_START(SH7372_DT, "Generic SH7372 (Flattened Device Tree)")
1008 .init_irq = sh7372_init_irq, 1009 .init_irq = sh7372_init_irq,
1009 .handle_irq = shmobile_handle_irq_intc, 1010 .handle_irq = shmobile_handle_irq_intc,
1010 .init_machine = sh7372_add_standard_devices_dt, 1011 .init_machine = sh7372_add_standard_devices_dt,
1012 .init_late = shmobile_init_late,
1011 .dt_compat = sh7372_boards_compat_dt, 1013 .dt_compat = sh7372_boards_compat_dt,
1012MACHINE_END 1014MACHINE_END
1013 1015
diff --git a/arch/arm/mach-shmobile/setup-sh73a0.c b/arch/arm/mach-shmobile/setup-sh73a0.c
index 1ff4bd65e647..93ebe3430bfe 100644
--- a/arch/arm/mach-shmobile/setup-sh73a0.c
+++ b/arch/arm/mach-shmobile/setup-sh73a0.c
@@ -55,6 +55,7 @@ static struct map_desc sh73a0_io_desc[] __initdata = {
55 55
56void __init sh73a0_map_io(void) 56void __init sh73a0_map_io(void)
57{ 57{
58 debug_ll_io_init();
58 iotable_init(sh73a0_io_desc, ARRAY_SIZE(sh73a0_io_desc)); 59 iotable_init(sh73a0_io_desc, ARRAY_SIZE(sh73a0_io_desc));
59} 60}
60 61
@@ -786,6 +787,13 @@ void __init sh73a0_add_standard_devices_dt(void)
786 of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); 787 of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
787} 788}
788 789
790#define RESCNT2 IOMEM(0xe6188020)
791static void sh73a0_restart(enum reboot_mode mode, const char *cmd)
792{
793 /* Do soft power on reset */
794 writel((1 << 31), RESCNT2);
795}
796
789static const char *sh73a0_boards_compat_dt[] __initdata = { 797static const char *sh73a0_boards_compat_dt[] __initdata = {
790 "renesas,sh73a0", 798 "renesas,sh73a0",
791 NULL, 799 NULL,
@@ -797,6 +805,7 @@ DT_MACHINE_START(SH73A0_DT, "Generic SH73A0 (Flattened Device Tree)")
797 .init_early = shmobile_init_delay, 805 .init_early = shmobile_init_delay,
798 .init_machine = sh73a0_add_standard_devices_dt, 806 .init_machine = sh73a0_add_standard_devices_dt,
799 .init_late = shmobile_init_late, 807 .init_late = shmobile_init_late,
808 .restart = sh73a0_restart,
800 .dt_compat = sh73a0_boards_compat_dt, 809 .dt_compat = sh73a0_boards_compat_dt,
801MACHINE_END 810MACHINE_END
802#endif /* CONFIG_USE_OF */ 811#endif /* CONFIG_USE_OF */
diff --git a/arch/arm/mach-shmobile/smp-r8a7790.c b/arch/arm/mach-shmobile/smp-r8a7790.c
index 2311694636e1..9c3da1345b8b 100644
--- a/arch/arm/mach-shmobile/smp-r8a7790.c
+++ b/arch/arm/mach-shmobile/smp-r8a7790.c
@@ -21,6 +21,7 @@
21#include <asm/smp_plat.h> 21#include <asm/smp_plat.h>
22 22
23#include "common.h" 23#include "common.h"
24#include "platsmp-apmu.h"
24#include "pm-rcar.h" 25#include "pm-rcar.h"
25#include "r8a7790.h" 26#include "r8a7790.h"
26 27
@@ -34,10 +35,23 @@ static struct rcar_sysc_ch r8a7790_ca7_scu = {
34 .isr_bit = 21, /* CA7-SCU */ 35 .isr_bit = 21, /* CA7-SCU */
35}; 36};
36 37
38static struct rcar_apmu_config r8a7790_apmu_config[] = {
39 {
40 .iomem = DEFINE_RES_MEM(0xe6152000, 0x88),
41 .cpus = { 0, 1, 2, 3 },
42 },
43 {
44 .iomem = DEFINE_RES_MEM(0xe6151000, 0x88),
45 .cpus = { 0x100, 0x0101, 0x102, 0x103 },
46 }
47};
48
37static void __init r8a7790_smp_prepare_cpus(unsigned int max_cpus) 49static void __init r8a7790_smp_prepare_cpus(unsigned int max_cpus)
38{ 50{
39 /* let APMU code install data related to shmobile_boot_vector */ 51 /* let APMU code install data related to shmobile_boot_vector */
40 shmobile_smp_apmu_prepare_cpus(max_cpus); 52 shmobile_smp_apmu_prepare_cpus(max_cpus,
53 r8a7790_apmu_config,
54 ARRAY_SIZE(r8a7790_apmu_config));
41 55
42 /* turn on power to SCU */ 56 /* turn on power to SCU */
43 r8a7790_pm_init(); 57 r8a7790_pm_init();
diff --git a/arch/arm/mach-shmobile/smp-r8a7791.c b/arch/arm/mach-shmobile/smp-r8a7791.c
index f743386166fb..7e49e0a52e32 100644
--- a/arch/arm/mach-shmobile/smp-r8a7791.c
+++ b/arch/arm/mach-shmobile/smp-r8a7791.c
@@ -21,13 +21,23 @@
21#include <asm/smp_plat.h> 21#include <asm/smp_plat.h>
22 22
23#include "common.h" 23#include "common.h"
24#include "platsmp-apmu.h"
24#include "r8a7791.h" 25#include "r8a7791.h"
25#include "rcar-gen2.h" 26#include "rcar-gen2.h"
26 27
28static struct rcar_apmu_config r8a7791_apmu_config[] = {
29 {
30 .iomem = DEFINE_RES_MEM(0xe6152000, 0x88),
31 .cpus = { 0, 1 },
32 }
33};
34
27static void __init r8a7791_smp_prepare_cpus(unsigned int max_cpus) 35static void __init r8a7791_smp_prepare_cpus(unsigned int max_cpus)
28{ 36{
29 /* let APMU code install data related to shmobile_boot_vector */ 37 /* let APMU code install data related to shmobile_boot_vector */
30 shmobile_smp_apmu_prepare_cpus(max_cpus); 38 shmobile_smp_apmu_prepare_cpus(max_cpus,
39 r8a7791_apmu_config,
40 ARRAY_SIZE(r8a7791_apmu_config));
31 41
32 r8a7791_pm_init(); 42 r8a7791_pm_init();
33} 43}
diff --git a/arch/arm/mach-shmobile/timer.c b/arch/arm/mach-shmobile/timer.c
index 1081b763e0f3..f1d027aa7a81 100644
--- a/arch/arm/mach-shmobile/timer.c
+++ b/arch/arm/mach-shmobile/timer.c
@@ -40,6 +40,7 @@ void __init shmobile_init_delay(void)
40 struct device_node *np, *cpus; 40 struct device_node *np, *cpus;
41 bool is_a7_a8_a9 = false; 41 bool is_a7_a8_a9 = false;
42 bool is_a15 = false; 42 bool is_a15 = false;
43 bool has_arch_timer = false;
43 u32 max_freq = 0; 44 u32 max_freq = 0;
44 45
45 cpus = of_find_node_by_path("/cpus"); 46 cpus = of_find_node_by_path("/cpus");
@@ -52,12 +53,16 @@ void __init shmobile_init_delay(void)
52 if (!of_property_read_u32(np, "clock-frequency", &freq)) 53 if (!of_property_read_u32(np, "clock-frequency", &freq))
53 max_freq = max(max_freq, freq); 54 max_freq = max(max_freq, freq);
54 55
55 if (of_device_is_compatible(np, "arm,cortex-a7") || 56 if (of_device_is_compatible(np, "arm,cortex-a8") ||
56 of_device_is_compatible(np, "arm,cortex-a8") || 57 of_device_is_compatible(np, "arm,cortex-a9")) {
57 of_device_is_compatible(np, "arm,cortex-a9"))
58 is_a7_a8_a9 = true; 58 is_a7_a8_a9 = true;
59 else if (of_device_is_compatible(np, "arm,cortex-a15")) 59 } else if (of_device_is_compatible(np, "arm,cortex-a7")) {
60 is_a7_a8_a9 = true;
61 has_arch_timer = true;
62 } else if (of_device_is_compatible(np, "arm,cortex-a15")) {
60 is_a15 = true; 63 is_a15 = true;
64 has_arch_timer = true;
65 }
61 } 66 }
62 67
63 of_node_put(cpus); 68 of_node_put(cpus);
@@ -65,10 +70,12 @@ void __init shmobile_init_delay(void)
65 if (!max_freq) 70 if (!max_freq)
66 return; 71 return;
67 72
68 if (is_a7_a8_a9) 73 if (!has_arch_timer || !IS_ENABLED(CONFIG_ARM_ARCH_TIMER)) {
69 shmobile_setup_delay_hz(max_freq, 1, 3); 74 if (is_a7_a8_a9)
70 else if (is_a15 && !IS_ENABLED(CONFIG_ARM_ARCH_TIMER)) 75 shmobile_setup_delay_hz(max_freq, 1, 3);
71 shmobile_setup_delay_hz(max_freq, 2, 4); 76 else if (is_a15)
77 shmobile_setup_delay_hz(max_freq, 2, 4);
78 }
72} 79}
73 80
74static void __init shmobile_late_time_init(void) 81static void __init shmobile_late_time_init(void)
diff --git a/arch/arm/mach-socfpga/core.h b/arch/arm/mach-socfpga/core.h
index 60c443dadb58..483cb467bf65 100644
--- a/arch/arm/mach-socfpga/core.h
+++ b/arch/arm/mach-socfpga/core.h
@@ -21,6 +21,7 @@
21#define __MACH_CORE_H 21#define __MACH_CORE_H
22 22
23#define SOCFPGA_RSTMGR_CTRL 0x04 23#define SOCFPGA_RSTMGR_CTRL 0x04
24#define SOCFPGA_RSTMGR_MODMPURST 0x10
24#define SOCFPGA_RSTMGR_MODPERRST 0x14 25#define SOCFPGA_RSTMGR_MODPERRST 0x14
25#define SOCFPGA_RSTMGR_BRGMODRST 0x1c 26#define SOCFPGA_RSTMGR_BRGMODRST 0x1c
26 27
@@ -28,6 +29,8 @@
28#define RSTMGR_CTRL_SWCOLDRSTREQ 0x1 /* Cold Reset */ 29#define RSTMGR_CTRL_SWCOLDRSTREQ 0x1 /* Cold Reset */
29#define RSTMGR_CTRL_SWWARMRSTREQ 0x2 /* Warm Reset */ 30#define RSTMGR_CTRL_SWWARMRSTREQ 0x2 /* Warm Reset */
30 31
32#define RSTMGR_MPUMODRST_CPU1 0x2 /* CPU1 Reset */
33
31extern void socfpga_secondary_startup(void); 34extern void socfpga_secondary_startup(void);
32extern void __iomem *socfpga_scu_base_addr; 35extern void __iomem *socfpga_scu_base_addr;
33 36
diff --git a/arch/arm/mach-socfpga/platsmp.c b/arch/arm/mach-socfpga/platsmp.c
index 16ca97b039f9..c64d89b7c0ca 100644
--- a/arch/arm/mach-socfpga/platsmp.c
+++ b/arch/arm/mach-socfpga/platsmp.c
@@ -34,17 +34,21 @@ static int socfpga_boot_secondary(unsigned int cpu, struct task_struct *idle)
34 int trampoline_size = &secondary_trampoline_end - &secondary_trampoline; 34 int trampoline_size = &secondary_trampoline_end - &secondary_trampoline;
35 35
36 if (socfpga_cpu1start_addr) { 36 if (socfpga_cpu1start_addr) {
37 /* This will put CPU #1 into reset. */
38 writel(RSTMGR_MPUMODRST_CPU1,
39 rst_manager_base_addr + SOCFPGA_RSTMGR_MODMPURST);
40
37 memcpy(phys_to_virt(0), &secondary_trampoline, trampoline_size); 41 memcpy(phys_to_virt(0), &secondary_trampoline, trampoline_size);
38 42
39 __raw_writel(virt_to_phys(socfpga_secondary_startup), 43 writel(virt_to_phys(socfpga_secondary_startup),
40 (sys_manager_base_addr + (socfpga_cpu1start_addr & 0x000000ff))); 44 sys_manager_base_addr + (socfpga_cpu1start_addr & 0x000000ff));
41 45
42 flush_cache_all(); 46 flush_cache_all();
43 smp_wmb(); 47 smp_wmb();
44 outer_clean_range(0, trampoline_size); 48 outer_clean_range(0, trampoline_size);
45 49
46 /* This will release CPU #1 out of reset.*/ 50 /* This will release CPU #1 out of reset. */
47 __raw_writel(0, rst_manager_base_addr + 0x10); 51 writel(0, rst_manager_base_addr + SOCFPGA_RSTMGR_MODMPURST);
48 } 52 }
49 53
50 return 0; 54 return 0;
@@ -86,10 +90,9 @@ static void __init socfpga_smp_prepare_cpus(unsigned int max_cpus)
86 */ 90 */
87static void socfpga_cpu_die(unsigned int cpu) 91static void socfpga_cpu_die(unsigned int cpu)
88{ 92{
89 cpu_do_idle(); 93 /* Do WFI. If we wake up early, go back into WFI */
90 94 while (1)
91 /* We should have never returned from idle */ 95 cpu_do_idle();
92 panic("cpu %d unexpectedly exit from shutdown\n", cpu);
93} 96}
94 97
95struct smp_operations socfpga_smp_ops __initdata = { 98struct smp_operations socfpga_smp_ops __initdata = {
diff --git a/arch/arm/mach-sunxi/Kconfig b/arch/arm/mach-sunxi/Kconfig
index 1aaa1e15ef70..a77604fbaf25 100644
--- a/arch/arm/mach-sunxi/Kconfig
+++ b/arch/arm/mach-sunxi/Kconfig
@@ -42,4 +42,11 @@ config MACH_SUN8I
42 select MFD_SUN6I_PRCM 42 select MFD_SUN6I_PRCM
43 select RESET_CONTROLLER 43 select RESET_CONTROLLER
44 44
45config MACH_SUN9I
46 bool "Allwinner (sun9i) SoCs support"
47 default ARCH_SUNXI
48 select ARCH_HAS_RESET_CONTROLLER
49 select ARM_GIC
50 select RESET_CONTROLLER
51
45endif 52endif
diff --git a/arch/arm/mach-sunxi/platsmp.c b/arch/arm/mach-sunxi/platsmp.c
index c53077bb8c3f..e44d028555a4 100644
--- a/arch/arm/mach-sunxi/platsmp.c
+++ b/arch/arm/mach-sunxi/platsmp.c
@@ -116,7 +116,7 @@ static int sun6i_smp_boot_secondary(unsigned int cpu,
116 return 0; 116 return 0;
117} 117}
118 118
119struct smp_operations sun6i_smp_ops __initdata = { 119static struct smp_operations sun6i_smp_ops __initdata = {
120 .smp_prepare_cpus = sun6i_smp_prepare_cpus, 120 .smp_prepare_cpus = sun6i_smp_prepare_cpus,
121 .smp_boot_secondary = sun6i_smp_boot_secondary, 121 .smp_boot_secondary = sun6i_smp_boot_secondary,
122}; 122};
diff --git a/arch/arm/mach-sunxi/sunxi.c b/arch/arm/mach-sunxi/sunxi.c
index d7598aeed803..1f986758784a 100644
--- a/arch/arm/mach-sunxi/sunxi.c
+++ b/arch/arm/mach-sunxi/sunxi.c
@@ -63,3 +63,12 @@ static const char * const sun8i_board_dt_compat[] = {
63DT_MACHINE_START(SUN8I_DT, "Allwinner sun8i (A23) Family") 63DT_MACHINE_START(SUN8I_DT, "Allwinner sun8i (A23) Family")
64 .dt_compat = sun8i_board_dt_compat, 64 .dt_compat = sun8i_board_dt_compat,
65MACHINE_END 65MACHINE_END
66
67static const char * const sun9i_board_dt_compat[] = {
68 "allwinner,sun9i-a80",
69 NULL,
70};
71
72DT_MACHINE_START(SUN9I_DT, "Allwinner sun9i Family")
73 .dt_compat = sun9i_board_dt_compat,
74MACHINE_END
diff --git a/arch/arm/mach-tegra/cpuidle-tegra114.c b/arch/arm/mach-tegra/cpuidle-tegra114.c
index e3ebdce3e71f..425b6c8f0cb0 100644
--- a/arch/arm/mach-tegra/cpuidle-tegra114.c
+++ b/arch/arm/mach-tegra/cpuidle-tegra114.c
@@ -49,7 +49,7 @@ static int tegra114_idle_power_down(struct cpuidle_device *dev,
49 call_firmware_op(prepare_idle); 49 call_firmware_op(prepare_idle);
50 50
51 /* Do suspend by ourselves if the firmware does not implement it */ 51 /* Do suspend by ourselves if the firmware does not implement it */
52 if (call_firmware_op(do_idle) == -ENOSYS) 52 if (call_firmware_op(do_idle, 0) == -ENOSYS)
53 cpu_suspend(0, tegra30_sleep_cpu_secondary_finish); 53 cpu_suspend(0, tegra30_sleep_cpu_secondary_finish);
54 54
55 clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_EXIT, &dev->cpu); 55 clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_EXIT, &dev->cpu);
diff --git a/arch/arm/mach-u300/dummyspichip.c b/arch/arm/mach-u300/dummyspichip.c
index ec0283cf9a32..131996805690 100644
--- a/arch/arm/mach-u300/dummyspichip.c
+++ b/arch/arm/mach-u300/dummyspichip.c
@@ -80,8 +80,8 @@ static ssize_t dummy_looptest(struct device *dev,
80 "in 8bit mode\n"); 80 "in 8bit mode\n");
81 status = spi_w8r8(spi, 0xAA); 81 status = spi_w8r8(spi, 0xAA);
82 if (status < 0) 82 if (status < 0)
83 pr_warning("Siple test 1: FAILURE: spi_write_then_read " 83 pr_warn("Simple test 1: FAILURE: spi_write_then_read failed with status %d\n",
84 "failed with status %d\n", status); 84 status);
85 else 85 else
86 pr_info("Simple test 1: SUCCESS!\n"); 86 pr_info("Simple test 1: SUCCESS!\n");
87 87
@@ -89,8 +89,8 @@ static ssize_t dummy_looptest(struct device *dev,
89 "in 8bit mode (full FIFO)\n"); 89 "in 8bit mode (full FIFO)\n");
90 status = spi_write_then_read(spi, &txbuf[0], 8, &rxbuf[0], 8); 90 status = spi_write_then_read(spi, &txbuf[0], 8, &rxbuf[0], 8);
91 if (status < 0) 91 if (status < 0)
92 pr_warning("Simple test 2: FAILURE: spi_write_then_read() " 92 pr_warn("Simple test 2: FAILURE: spi_write_then_read() failed with status %d\n",
93 "failed with status %d\n", status); 93 status);
94 else 94 else
95 pr_info("Simple test 2: SUCCESS!\n"); 95 pr_info("Simple test 2: SUCCESS!\n");
96 96
@@ -98,8 +98,8 @@ static ssize_t dummy_looptest(struct device *dev,
98 "in 8bit mode (see if we overflow FIFO)\n"); 98 "in 8bit mode (see if we overflow FIFO)\n");
99 status = spi_write_then_read(spi, &txbuf[0], 14, &rxbuf[0], 14); 99 status = spi_write_then_read(spi, &txbuf[0], 14, &rxbuf[0], 14);
100 if (status < 0) 100 if (status < 0)
101 pr_warning("Simple test 3: FAILURE: failed with status %d " 101 pr_warn("Simple test 3: FAILURE: failed with status %d (probably FIFO overrun)\n",
102 "(probably FIFO overrun)\n", status); 102 status);
103 else 103 else
104 pr_info("Simple test 3: SUCCESS!\n"); 104 pr_info("Simple test 3: SUCCESS!\n");
105 105
@@ -107,14 +107,14 @@ static ssize_t dummy_looptest(struct device *dev,
107 "bytes garbage with spi_read() in 8bit mode\n"); 107 "bytes garbage with spi_read() in 8bit mode\n");
108 status = spi_write(spi, &txbuf[0], 8); 108 status = spi_write(spi, &txbuf[0], 8);
109 if (status < 0) 109 if (status < 0)
110 pr_warning("Simple test 4 step 1: FAILURE: spi_write() " 110 pr_warn("Simple test 4 step 1: FAILURE: spi_write() failed with status %d\n",
111 "failed with status %d\n", status); 111 status);
112 else 112 else
113 pr_info("Simple test 4 step 1: SUCCESS!\n"); 113 pr_info("Simple test 4 step 1: SUCCESS!\n");
114 status = spi_read(spi, &rxbuf[0], 8); 114 status = spi_read(spi, &rxbuf[0], 8);
115 if (status < 0) 115 if (status < 0)
116 pr_warning("Simple test 4 step 2: FAILURE: spi_read() " 116 pr_warn("Simple test 4 step 2: FAILURE: spi_read() failed with status %d\n",
117 "failed with status %d\n", status); 117 status);
118 else 118 else
119 pr_info("Simple test 4 step 2: SUCCESS!\n"); 119 pr_info("Simple test 4 step 2: SUCCESS!\n");
120 120
@@ -122,16 +122,14 @@ static ssize_t dummy_looptest(struct device *dev,
122 "14 bytes garbage with spi_read() in 8bit mode\n"); 122 "14 bytes garbage with spi_read() in 8bit mode\n");
123 status = spi_write(spi, &txbuf[0], 14); 123 status = spi_write(spi, &txbuf[0], 14);
124 if (status < 0) 124 if (status < 0)
125 pr_warning("Simple test 5 step 1: FAILURE: spi_write() " 125 pr_warn("Simple test 5 step 1: FAILURE: spi_write() failed with status %d (probably FIFO overrun)\n",
126 "failed with status %d (probably FIFO overrun)\n", 126 status);
127 status);
128 else 127 else
129 pr_info("Simple test 5 step 1: SUCCESS!\n"); 128 pr_info("Simple test 5 step 1: SUCCESS!\n");
130 status = spi_read(spi, &rxbuf[0], 14); 129 status = spi_read(spi, &rxbuf[0], 14);
131 if (status < 0) 130 if (status < 0)
132 pr_warning("Simple test 5 step 2: FAILURE: spi_read() " 131 pr_warn("Simple test 5 step 2: FAILURE: spi_read() failed with status %d (probably FIFO overrun)\n",
133 "failed with status %d (probably FIFO overrun)\n", 132 status);
134 status);
135 else 133 else
136 pr_info("Simple test 5: SUCCESS!\n"); 134 pr_info("Simple test 5: SUCCESS!\n");
137 135
@@ -140,16 +138,14 @@ static ssize_t dummy_looptest(struct device *dev,
140 DMA_TEST_SIZE, DMA_TEST_SIZE); 138 DMA_TEST_SIZE, DMA_TEST_SIZE);
141 status = spi_write(spi, &bigtxbuf_virtual[0], DMA_TEST_SIZE); 139 status = spi_write(spi, &bigtxbuf_virtual[0], DMA_TEST_SIZE);
142 if (status < 0) 140 if (status < 0)
143 pr_warning("Simple test 6 step 1: FAILURE: spi_write() " 141 pr_warn("Simple test 6 step 1: FAILURE: spi_write() failed with status %d (probably FIFO overrun)\n",
144 "failed with status %d (probably FIFO overrun)\n", 142 status);
145 status);
146 else 143 else
147 pr_info("Simple test 6 step 1: SUCCESS!\n"); 144 pr_info("Simple test 6 step 1: SUCCESS!\n");
148 status = spi_read(spi, &bigrxbuf_virtual[0], DMA_TEST_SIZE); 145 status = spi_read(spi, &bigrxbuf_virtual[0], DMA_TEST_SIZE);
149 if (status < 0) 146 if (status < 0)
150 pr_warning("Simple test 6 step 2: FAILURE: spi_read() " 147 pr_warn("Simple test 6 step 2: FAILURE: spi_read() failed with status %d (probably FIFO overrun)\n",
151 "failed with status %d (probably FIFO overrun)\n", 148 status);
152 status);
153 else 149 else
154 pr_info("Simple test 6: SUCCESS!\n"); 150 pr_info("Simple test 6: SUCCESS!\n");
155 151
@@ -169,18 +165,17 @@ static ssize_t dummy_looptest(struct device *dev,
169 pr_info("Simple test 7: SUCCESS! (expected failure with " 165 pr_info("Simple test 7: SUCCESS! (expected failure with "
170 "status EIO)\n"); 166 "status EIO)\n");
171 else if (status < 0) 167 else if (status < 0)
172 pr_warning("Siple test 7: FAILURE: spi_write_then_read " 168 pr_warn("Simple test 7: FAILURE: spi_write_then_read failed with status %d\n",
173 "failed with status %d\n", status); 169 status);
174 else 170 else
175 pr_warning("Siple test 7: FAILURE: spi_write_then_read " 171 pr_warn("Simple test 7: FAILURE: spi_write_then_read succeeded but it was expected to fail!\n");
176 "succeeded but it was expected to fail!\n");
177 172
178 pr_info("Simple test 8: write 8 bytes, read back 8 bytes garbage " 173 pr_info("Simple test 8: write 8 bytes, read back 8 bytes garbage "
179 "in 16bit mode (full FIFO)\n"); 174 "in 16bit mode (full FIFO)\n");
180 status = spi_write_then_read(spi, &txbuf[0], 8, &rxbuf[0], 8); 175 status = spi_write_then_read(spi, &txbuf[0], 8, &rxbuf[0], 8);
181 if (status < 0) 176 if (status < 0)
182 pr_warning("Simple test 8: FAILURE: spi_write_then_read() " 177 pr_warn("Simple test 8: FAILURE: spi_write_then_read() failed with status %d\n",
183 "failed with status %d\n", status); 178 status);
184 else 179 else
185 pr_info("Simple test 8: SUCCESS!\n"); 180 pr_info("Simple test 8: SUCCESS!\n");
186 181
@@ -188,8 +183,8 @@ static ssize_t dummy_looptest(struct device *dev,
188 "in 16bit mode (see if we overflow FIFO)\n"); 183 "in 16bit mode (see if we overflow FIFO)\n");
189 status = spi_write_then_read(spi, &txbuf[0], 14, &rxbuf[0], 14); 184 status = spi_write_then_read(spi, &txbuf[0], 14, &rxbuf[0], 14);
190 if (status < 0) 185 if (status < 0)
191 pr_warning("Simple test 9: FAILURE: failed with status %d " 186 pr_warn("Simple test 9: FAILURE: failed with status %d (probably FIFO overrun)\n",
192 "(probably FIFO overrun)\n", status); 187 status);
193 else 188 else
194 pr_info("Simple test 9: SUCCESS!\n"); 189 pr_info("Simple test 9: SUCCESS!\n");
195 190
@@ -198,17 +193,15 @@ static ssize_t dummy_looptest(struct device *dev,
198 DMA_TEST_SIZE, DMA_TEST_SIZE); 193 DMA_TEST_SIZE, DMA_TEST_SIZE);
199 status = spi_write(spi, &bigtxbuf_virtual[0], DMA_TEST_SIZE); 194 status = spi_write(spi, &bigtxbuf_virtual[0], DMA_TEST_SIZE);
200 if (status < 0) 195 if (status < 0)
201 pr_warning("Simple test 10 step 1: FAILURE: spi_write() " 196 pr_warn("Simple test 10 step 1: FAILURE: spi_write() failed with status %d (probably FIFO overrun)\n",
202 "failed with status %d (probably FIFO overrun)\n", 197 status);
203 status);
204 else 198 else
205 pr_info("Simple test 10 step 1: SUCCESS!\n"); 199 pr_info("Simple test 10 step 1: SUCCESS!\n");
206 200
207 status = spi_read(spi, &bigrxbuf_virtual[0], DMA_TEST_SIZE); 201 status = spi_read(spi, &bigrxbuf_virtual[0], DMA_TEST_SIZE);
208 if (status < 0) 202 if (status < 0)
209 pr_warning("Simple test 10 step 2: FAILURE: spi_read() " 203 pr_warn("Simple test 10 step 2: FAILURE: spi_read() failed with status %d (probably FIFO overrun)\n",
210 "failed with status %d (probably FIFO overrun)\n", 204 status);
211 status);
212 else 205 else
213 pr_info("Simple test 10: SUCCESS!\n"); 206 pr_info("Simple test 10: SUCCESS!\n");
214 207
diff --git a/arch/arm/mach-ux500/Kconfig b/arch/arm/mach-ux500/Kconfig
index 699e8601dbf0..c9ac19b24e5a 100644
--- a/arch/arm/mach-ux500/Kconfig
+++ b/arch/arm/mach-ux500/Kconfig
@@ -32,6 +32,7 @@ config UX500_SOC_DB8500
32 select PINCTRL_AB8540 32 select PINCTRL_AB8540
33 select REGULATOR 33 select REGULATOR
34 select REGULATOR_DB8500_PRCMU 34 select REGULATOR_DB8500_PRCMU
35 select PM_GENERIC_DOMAINS if PM
35 36
36config MACH_MOP500 37config MACH_MOP500
37 bool "U8500 Development platform, MOP500 versions" 38 bool "U8500 Development platform, MOP500 versions"
diff --git a/arch/arm/mach-ux500/Makefile b/arch/arm/mach-ux500/Makefile
index 9741de956b3e..4418a5078833 100644
--- a/arch/arm/mach-ux500/Makefile
+++ b/arch/arm/mach-ux500/Makefile
@@ -9,5 +9,6 @@ obj-$(CONFIG_MACH_MOP500) += board-mop500-regulators.o \
9 board-mop500-audio.o 9 board-mop500-audio.o
10obj-$(CONFIG_SMP) += platsmp.o headsmp.o 10obj-$(CONFIG_SMP) += platsmp.o headsmp.o
11obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o 11obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o
12obj-$(CONFIG_PM_GENERIC_DOMAINS) += pm_domains.o
12 13
13CFLAGS_hotplug.o += -march=armv7-a 14CFLAGS_hotplug.o += -march=armv7-a
diff --git a/arch/arm/mach-ux500/pm.c b/arch/arm/mach-ux500/pm.c
index b80a9a2e356e..2cb587b50905 100644
--- a/arch/arm/mach-ux500/pm.c
+++ b/arch/arm/mach-ux500/pm.c
@@ -17,6 +17,7 @@
17#include <linux/platform_data/arm-ux500-pm.h> 17#include <linux/platform_data/arm-ux500-pm.h>
18 18
19#include "db8500-regs.h" 19#include "db8500-regs.h"
20#include "pm_domains.h"
20 21
21/* ARM WFI Standby signal register */ 22/* ARM WFI Standby signal register */
22#define PRCM_ARM_WFI_STANDBY (prcmu_base + 0x130) 23#define PRCM_ARM_WFI_STANDBY (prcmu_base + 0x130)
@@ -191,4 +192,7 @@ void __init ux500_pm_init(u32 phy_base, u32 size)
191 192
192 /* Set up ux500 suspend callbacks. */ 193 /* Set up ux500 suspend callbacks. */
193 suspend_set_ops(UX500_SUSPEND_OPS); 194 suspend_set_ops(UX500_SUSPEND_OPS);
195
196 /* Initialize ux500 power domains */
197 ux500_pm_domains_init();
194} 198}
diff --git a/arch/arm/mach-ux500/pm_domains.c b/arch/arm/mach-ux500/pm_domains.c
new file mode 100644
index 000000000000..0d4b5b46f15b
--- /dev/null
+++ b/arch/arm/mach-ux500/pm_domains.c
@@ -0,0 +1,79 @@
1/*
2 * Copyright (C) 2014 Linaro Ltd.
3 *
4 * Author: Ulf Hansson <ulf.hansson@linaro.org>
5 * License terms: GNU General Public License (GPL) version 2
6 *
7 * Implements PM domains using the generic PM domain for ux500.
8 */
9#include <linux/printk.h>
10#include <linux/slab.h>
11#include <linux/err.h>
12#include <linux/of.h>
13#include <linux/pm_domain.h>
14
15#include <dt-bindings/arm/ux500_pm_domains.h>
16#include "pm_domains.h"
17
18static int pd_power_off(struct generic_pm_domain *domain)
19{
20 /*
21 * Handle the gating of the PM domain regulator here.
22 *
23 * Drivers/subsystems handling devices in the PM domain needs to perform
24 * register context save/restore from their respective runtime PM
25 * callbacks, to be able to enable PM domain gating/ungating.
26 */
27 return 0;
28}
29
30static int pd_power_on(struct generic_pm_domain *domain)
31{
32 /*
33 * Handle the ungating of the PM domain regulator here.
34 *
35 * Drivers/subsystems handling devices in the PM domain needs to perform
36 * register context save/restore from their respective runtime PM
37 * callbacks, to be able to enable PM domain gating/ungating.
38 */
39 return 0;
40}
41
42static struct generic_pm_domain ux500_pm_domain_vape = {
43 .name = "VAPE",
44 .power_off = pd_power_off,
45 .power_on = pd_power_on,
46};
47
48static struct generic_pm_domain *ux500_pm_domains[NR_DOMAINS] = {
49 [DOMAIN_VAPE] = &ux500_pm_domain_vape,
50};
51
52static struct of_device_id ux500_pm_domain_matches[] = {
53 { .compatible = "stericsson,ux500-pm-domains", },
54 { },
55};
56
57int __init ux500_pm_domains_init(void)
58{
59 struct device_node *np;
60 struct genpd_onecell_data *genpd_data;
61 int i;
62
63 np = of_find_matching_node(NULL, ux500_pm_domain_matches);
64 if (!np)
65 return -ENODEV;
66
67 genpd_data = kzalloc(sizeof(*genpd_data), GFP_KERNEL);
68 if (!genpd_data)
69 return -ENOMEM;
70
71 genpd_data->domains = ux500_pm_domains;
72 genpd_data->num_domains = ARRAY_SIZE(ux500_pm_domains);
73
74 for (i = 0; i < ARRAY_SIZE(ux500_pm_domains); ++i)
75 pm_genpd_init(ux500_pm_domains[i], NULL, false);
76
77 of_genpd_add_provider_onecell(np, genpd_data);
78 return 0;
79}
diff --git a/arch/arm/mach-ux500/pm_domains.h b/arch/arm/mach-ux500/pm_domains.h
new file mode 100644
index 000000000000..263d3ba97177
--- /dev/null
+++ b/arch/arm/mach-ux500/pm_domains.h
@@ -0,0 +1,17 @@
1/*
2 * Copyright (C) 2014 Linaro Ltd.
3 *
4 * Author: Ulf Hansson <ulf.hansson@linaro.org>
5 * License terms: GNU General Public License (GPL) version 2
6 */
7
8#ifndef __MACH_UX500_PM_DOMAINS_H
9#define __MACH_UX500_PM_DOMAINS_H
10
11#ifdef CONFIG_PM_GENERIC_DOMAINS
12extern int __init ux500_pm_domains_init(void);
13#else
14static inline int ux500_pm_domains_init(void) { return 0; }
15#endif
16
17#endif
diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig
index 7eb94e6fc376..ab906b801047 100644
--- a/arch/arm/mm/Kconfig
+++ b/arch/arm/mm/Kconfig
@@ -21,7 +21,7 @@ config CPU_ARM7TDMI
21 21
22# ARM720T 22# ARM720T
23config CPU_ARM720T 23config CPU_ARM720T
24 bool "Support ARM720T processor" if ARCH_INTEGRATOR 24 bool "Support ARM720T processor" if (ARCH_MULTI_V4T && ARCH_INTEGRATOR)
25 select CPU_32v4T 25 select CPU_32v4T
26 select CPU_ABRT_LV4T 26 select CPU_ABRT_LV4T
27 select CPU_CACHE_V4 27 select CPU_CACHE_V4
@@ -39,7 +39,7 @@ config CPU_ARM720T
39 39
40# ARM740T 40# ARM740T
41config CPU_ARM740T 41config CPU_ARM740T
42 bool "Support ARM740T processor" if ARCH_INTEGRATOR 42 bool "Support ARM740T processor" if (ARCH_MULTI_V4T && ARCH_INTEGRATOR)
43 depends on !MMU 43 depends on !MMU
44 select CPU_32v4T 44 select CPU_32v4T
45 select CPU_ABRT_LV4T 45 select CPU_ABRT_LV4T
@@ -71,7 +71,7 @@ config CPU_ARM9TDMI
71 71
72# ARM920T 72# ARM920T
73config CPU_ARM920T 73config CPU_ARM920T
74 bool "Support ARM920T processor" if ARCH_INTEGRATOR 74 bool "Support ARM920T processor" if (ARCH_MULTI_V4T && ARCH_INTEGRATOR)
75 select CPU_32v4T 75 select CPU_32v4T
76 select CPU_ABRT_EV4T 76 select CPU_ABRT_EV4T
77 select CPU_CACHE_V4WT 77 select CPU_CACHE_V4WT
@@ -89,7 +89,7 @@ config CPU_ARM920T
89 89
90# ARM922T 90# ARM922T
91config CPU_ARM922T 91config CPU_ARM922T
92 bool "Support ARM922T processor" if ARCH_INTEGRATOR 92 bool "Support ARM922T processor" if (ARCH_MULTI_V4T && ARCH_INTEGRATOR)
93 select CPU_32v4T 93 select CPU_32v4T
94 select CPU_ABRT_EV4T 94 select CPU_ABRT_EV4T
95 select CPU_CACHE_V4WT 95 select CPU_CACHE_V4WT
@@ -127,7 +127,7 @@ config CPU_ARM925T
127 127
128# ARM926T 128# ARM926T
129config CPU_ARM926T 129config CPU_ARM926T
130 bool "Support ARM926T processor" if ARCH_INTEGRATOR || MACH_REALVIEW_EB 130 bool "Support ARM926T processor" if (!ARCH_MULTIPLATFORM || ARCH_MULTI_V5) && (ARCH_INTEGRATOR || MACH_REALVIEW_EB)
131 select CPU_32v5 131 select CPU_32v5
132 select CPU_ABRT_EV5TJ 132 select CPU_ABRT_EV5TJ
133 select CPU_CACHE_VIVT 133 select CPU_CACHE_VIVT
@@ -163,7 +163,7 @@ config CPU_FA526
163 163
164# ARM940T 164# ARM940T
165config CPU_ARM940T 165config CPU_ARM940T
166 bool "Support ARM940T processor" if ARCH_INTEGRATOR 166 bool "Support ARM940T processor" if (ARCH_MULTI_V4T && ARCH_INTEGRATOR)
167 depends on !MMU 167 depends on !MMU
168 select CPU_32v4T 168 select CPU_32v4T
169 select CPU_ABRT_NOMMU 169 select CPU_ABRT_NOMMU
@@ -181,7 +181,7 @@ config CPU_ARM940T
181 181
182# ARM946E-S 182# ARM946E-S
183config CPU_ARM946E 183config CPU_ARM946E
184 bool "Support ARM946E-S processor" if ARCH_INTEGRATOR 184 bool "Support ARM946E-S processor" if (ARCH_MULTI_V5 && ARCH_INTEGRATOR)
185 depends on !MMU 185 depends on !MMU
186 select CPU_32v5 186 select CPU_32v5
187 select CPU_ABRT_NOMMU 187 select CPU_ABRT_NOMMU
@@ -198,7 +198,7 @@ config CPU_ARM946E
198 198
199# ARM1020 - needs validating 199# ARM1020 - needs validating
200config CPU_ARM1020 200config CPU_ARM1020
201 bool "Support ARM1020T (rev 0) processor" if ARCH_INTEGRATOR 201 bool "Support ARM1020T (rev 0) processor" if (ARCH_MULTI_V5 && ARCH_INTEGRATOR)
202 select CPU_32v5 202 select CPU_32v5
203 select CPU_ABRT_EV4T 203 select CPU_ABRT_EV4T
204 select CPU_CACHE_V4WT 204 select CPU_CACHE_V4WT
@@ -216,7 +216,7 @@ config CPU_ARM1020
216 216
217# ARM1020E - needs validating 217# ARM1020E - needs validating
218config CPU_ARM1020E 218config CPU_ARM1020E
219 bool "Support ARM1020E processor" if ARCH_INTEGRATOR 219 bool "Support ARM1020E processor" if (ARCH_MULTI_V5 && ARCH_INTEGRATOR)
220 depends on n 220 depends on n
221 select CPU_32v5 221 select CPU_32v5
222 select CPU_ABRT_EV4T 222 select CPU_ABRT_EV4T
@@ -229,7 +229,7 @@ config CPU_ARM1020E
229 229
230# ARM1022E 230# ARM1022E
231config CPU_ARM1022 231config CPU_ARM1022
232 bool "Support ARM1022E processor" if ARCH_INTEGRATOR 232 bool "Support ARM1022E processor" if (ARCH_MULTI_V5 && ARCH_INTEGRATOR)
233 select CPU_32v5 233 select CPU_32v5
234 select CPU_ABRT_EV4T 234 select CPU_ABRT_EV4T
235 select CPU_CACHE_VIVT 235 select CPU_CACHE_VIVT
@@ -247,7 +247,7 @@ config CPU_ARM1022
247 247
248# ARM1026EJ-S 248# ARM1026EJ-S
249config CPU_ARM1026 249config CPU_ARM1026
250 bool "Support ARM1026EJ-S processor" if ARCH_INTEGRATOR 250 bool "Support ARM1026EJ-S processor" if (ARCH_MULTI_V5 && ARCH_INTEGRATOR)
251 select CPU_32v5 251 select CPU_32v5
252 select CPU_ABRT_EV5T # But need Jazelle, but EV5TJ ignores bit 10 252 select CPU_ABRT_EV5T # But need Jazelle, but EV5TJ ignores bit 10
253 select CPU_CACHE_VIVT 253 select CPU_CACHE_VIVT
@@ -358,7 +358,7 @@ config CPU_PJ4B
358 358
359# ARMv6 359# ARMv6
360config CPU_V6 360config CPU_V6
361 bool "Support ARM V6 processor" if ARCH_INTEGRATOR || MACH_REALVIEW_EB || MACH_REALVIEW_PBX 361 bool "Support ARM V6 processor" if (!ARCH_MULTIPLATFORM || ARCH_MULTI_V6) && (ARCH_INTEGRATOR || MACH_REALVIEW_EB || MACH_REALVIEW_PBX)
362 select CPU_32v6 362 select CPU_32v6
363 select CPU_ABRT_EV6 363 select CPU_ABRT_EV6
364 select CPU_CACHE_V6 364 select CPU_CACHE_V6
@@ -371,7 +371,7 @@ config CPU_V6
371 371
372# ARMv6k 372# ARMv6k
373config CPU_V6K 373config CPU_V6K
374 bool "Support ARM V6K processor" if ARCH_INTEGRATOR || MACH_REALVIEW_EB || MACH_REALVIEW_PBX 374 bool "Support ARM V6K processor" if (!ARCH_MULTIPLATFORM || ARCH_MULTI_V6) && (ARCH_INTEGRATOR || MACH_REALVIEW_EB || MACH_REALVIEW_PBX)
375 select CPU_32v6 375 select CPU_32v6
376 select CPU_32v6K 376 select CPU_32v6K
377 select CPU_ABRT_EV6 377 select CPU_ABRT_EV6
@@ -385,7 +385,7 @@ config CPU_V6K
385 385
386# ARMv7 386# ARMv7
387config CPU_V7 387config CPU_V7
388 bool "Support ARM V7 processor" if ARCH_INTEGRATOR || MACH_REALVIEW_EB || MACH_REALVIEW_PBX 388 bool "Support ARM V7 processor" if (!ARCH_MULTIPLATFORM || ARCH_MULTI_V7) && (ARCH_INTEGRATOR || MACH_REALVIEW_EB || MACH_REALVIEW_PBX)
389 select CPU_32v6K 389 select CPU_32v6K
390 select CPU_32v7 390 select CPU_32v7
391 select CPU_ABRT_EV7 391 select CPU_ABRT_EV7
diff --git a/arch/arm/plat-samsung/Makefile b/arch/arm/plat-samsung/Makefile
index f0a008496993..87746c37f030 100644
--- a/arch/arm/plat-samsung/Makefile
+++ b/arch/arm/plat-samsung/Makefile
@@ -35,6 +35,7 @@ obj-$(CONFIG_SAMSUNG_DMADEV) += dma-ops.o
35# PM support 35# PM support
36 36
37obj-$(CONFIG_PM_SLEEP) += pm-common.o 37obj-$(CONFIG_PM_SLEEP) += pm-common.o
38obj-$(CONFIG_EXYNOS_CPU_SUSPEND) += pm-common.o
38obj-$(CONFIG_SAMSUNG_PM) += pm.o 39obj-$(CONFIG_SAMSUNG_PM) += pm.o
39obj-$(CONFIG_SAMSUNG_PM_GPIO) += pm-gpio.o 40obj-$(CONFIG_SAMSUNG_PM_GPIO) += pm-gpio.o
40obj-$(CONFIG_SAMSUNG_PM_CHECK) += pm-check.o 41obj-$(CONFIG_SAMSUNG_PM_CHECK) += pm-check.o
diff --git a/drivers/bus/brcmstb_gisb.c b/drivers/bus/brcmstb_gisb.c
index f2cd6a2d40b4..e7ccd21a45c9 100644
--- a/drivers/bus/brcmstb_gisb.c
+++ b/drivers/bus/brcmstb_gisb.c
@@ -23,6 +23,7 @@
23#include <linux/list.h> 23#include <linux/list.h>
24#include <linux/of.h> 24#include <linux/of.h>
25#include <linux/bitops.h> 25#include <linux/bitops.h>
26#include <linux/pm.h>
26 27
27#include <asm/bug.h> 28#include <asm/bug.h>
28#include <asm/signal.h> 29#include <asm/signal.h>
@@ -48,6 +49,7 @@ struct brcmstb_gisb_arb_device {
48 struct list_head next; 49 struct list_head next;
49 u32 valid_mask; 50 u32 valid_mask;
50 const char *master_names[sizeof(u32) * BITS_PER_BYTE]; 51 const char *master_names[sizeof(u32) * BITS_PER_BYTE];
52 u32 saved_timeout;
51}; 53};
52 54
53static LIST_HEAD(brcmstb_gisb_arb_device_list); 55static LIST_HEAD(brcmstb_gisb_arb_device_list);
@@ -160,12 +162,6 @@ static int brcmstb_bus_error_handler(unsigned long addr, unsigned int fsr,
160 return ret; 162 return ret;
161} 163}
162 164
163void __init brcmstb_hook_fault_code(void)
164{
165 hook_fault_code(22, brcmstb_bus_error_handler, SIGBUS, 0,
166 "imprecise external abort");
167}
168
169static irqreturn_t brcmstb_gisb_timeout_handler(int irq, void *dev_id) 165static irqreturn_t brcmstb_gisb_timeout_handler(int irq, void *dev_id)
170{ 166{
171 brcmstb_gisb_arb_decode_addr(dev_id, "timeout"); 167 brcmstb_gisb_arb_decode_addr(dev_id, "timeout");
@@ -261,12 +257,48 @@ static int brcmstb_gisb_arb_probe(struct platform_device *pdev)
261 257
262 list_add_tail(&gdev->next, &brcmstb_gisb_arb_device_list); 258 list_add_tail(&gdev->next, &brcmstb_gisb_arb_device_list);
263 259
260 hook_fault_code(22, brcmstb_bus_error_handler, SIGBUS, 0,
261 "imprecise external abort");
262
264 dev_info(&pdev->dev, "registered mem: %p, irqs: %d, %d\n", 263 dev_info(&pdev->dev, "registered mem: %p, irqs: %d, %d\n",
265 gdev->base, timeout_irq, tea_irq); 264 gdev->base, timeout_irq, tea_irq);
266 265
267 return 0; 266 return 0;
268} 267}
269 268
269#ifdef CONFIG_PM_SLEEP
270static int brcmstb_gisb_arb_suspend(struct device *dev)
271{
272 struct platform_device *pdev = to_platform_device(dev);
273 struct brcmstb_gisb_arb_device *gdev = platform_get_drvdata(pdev);
274
275 gdev->saved_timeout = ioread32(gdev->base + ARB_TIMER);
276
277 return 0;
278}
279
280/* Make sure we provide the same timeout value that was configured before, and
281 * do this before the GISB timeout interrupt handler has any chance to run.
282 */
283static int brcmstb_gisb_arb_resume_noirq(struct device *dev)
284{
285 struct platform_device *pdev = to_platform_device(dev);
286 struct brcmstb_gisb_arb_device *gdev = platform_get_drvdata(pdev);
287
288 iowrite32(gdev->saved_timeout, gdev->base + ARB_TIMER);
289
290 return 0;
291}
292#else
293#define brcmstb_gisb_arb_suspend NULL
294#define brcmstb_gisb_arb_resume_noirq NULL
295#endif
296
297static const struct dev_pm_ops brcmstb_gisb_arb_pm_ops = {
298 .suspend = brcmstb_gisb_arb_suspend,
299 .resume_noirq = brcmstb_gisb_arb_resume_noirq,
300};
301
270static const struct of_device_id brcmstb_gisb_arb_of_match[] = { 302static const struct of_device_id brcmstb_gisb_arb_of_match[] = {
271 { .compatible = "brcm,gisb-arb" }, 303 { .compatible = "brcm,gisb-arb" },
272 { }, 304 { },
@@ -278,6 +310,7 @@ static struct platform_driver brcmstb_gisb_arb_driver = {
278 .name = "brcm-gisb-arb", 310 .name = "brcm-gisb-arb",
279 .owner = THIS_MODULE, 311 .owner = THIS_MODULE,
280 .of_match_table = brcmstb_gisb_arb_of_match, 312 .of_match_table = brcmstb_gisb_arb_of_match,
313 .pm = &brcmstb_gisb_arb_pm_ops,
281 }, 314 },
282}; 315};
283 316
diff --git a/drivers/bus/mvebu-mbus.c b/drivers/bus/mvebu-mbus.c
index 26c3779d871d..eb7682dc123b 100644
--- a/drivers/bus/mvebu-mbus.c
+++ b/drivers/bus/mvebu-mbus.c
@@ -57,6 +57,7 @@
57#include <linux/of_address.h> 57#include <linux/of_address.h>
58#include <linux/debugfs.h> 58#include <linux/debugfs.h>
59#include <linux/log2.h> 59#include <linux/log2.h>
60#include <linux/syscore_ops.h>
60 61
61/* 62/*
62 * DDR target is the same on all platforms. 63 * DDR target is the same on all platforms.
@@ -94,20 +95,42 @@
94 95
95#define DOVE_DDR_BASE_CS_OFF(n) ((n) << 4) 96#define DOVE_DDR_BASE_CS_OFF(n) ((n) << 4)
96 97
98/* Relative to mbusbridge_base */
99#define MBUS_BRIDGE_CTRL_OFF 0x0
100#define MBUS_BRIDGE_BASE_OFF 0x4
101
102/* Maximum number of windows, for all known platforms */
103#define MBUS_WINS_MAX 20
104
97struct mvebu_mbus_state; 105struct mvebu_mbus_state;
98 106
99struct mvebu_mbus_soc_data { 107struct mvebu_mbus_soc_data {
100 unsigned int num_wins; 108 unsigned int num_wins;
101 unsigned int num_remappable_wins; 109 unsigned int num_remappable_wins;
110 bool has_mbus_bridge;
102 unsigned int (*win_cfg_offset)(const int win); 111 unsigned int (*win_cfg_offset)(const int win);
103 void (*setup_cpu_target)(struct mvebu_mbus_state *s); 112 void (*setup_cpu_target)(struct mvebu_mbus_state *s);
113 int (*save_cpu_target)(struct mvebu_mbus_state *s,
114 u32 *store_addr);
104 int (*show_cpu_target)(struct mvebu_mbus_state *s, 115 int (*show_cpu_target)(struct mvebu_mbus_state *s,
105 struct seq_file *seq, void *v); 116 struct seq_file *seq, void *v);
106}; 117};
107 118
119/*
120 * Used to store the state of one MBus window accross suspend/resume.
121 */
122struct mvebu_mbus_win_data {
123 u32 ctrl;
124 u32 base;
125 u32 remap_lo;
126 u32 remap_hi;
127};
128
108struct mvebu_mbus_state { 129struct mvebu_mbus_state {
109 void __iomem *mbuswins_base; 130 void __iomem *mbuswins_base;
110 void __iomem *sdramwins_base; 131 void __iomem *sdramwins_base;
132 void __iomem *mbusbridge_base;
133 phys_addr_t sdramwins_phys_base;
111 struct dentry *debugfs_root; 134 struct dentry *debugfs_root;
112 struct dentry *debugfs_sdram; 135 struct dentry *debugfs_sdram;
113 struct dentry *debugfs_devs; 136 struct dentry *debugfs_devs;
@@ -115,6 +138,11 @@ struct mvebu_mbus_state {
115 struct resource pcie_io_aperture; 138 struct resource pcie_io_aperture;
116 const struct mvebu_mbus_soc_data *soc; 139 const struct mvebu_mbus_soc_data *soc;
117 int hw_io_coherency; 140 int hw_io_coherency;
141
142 /* Used during suspend/resume */
143 u32 mbus_bridge_ctrl;
144 u32 mbus_bridge_base;
145 struct mvebu_mbus_win_data wins[MBUS_WINS_MAX];
118}; 146};
119 147
120static struct mvebu_mbus_state mbus_state; 148static struct mvebu_mbus_state mbus_state;
@@ -516,6 +544,28 @@ mvebu_mbus_default_setup_cpu_target(struct mvebu_mbus_state *mbus)
516 mvebu_mbus_dram_info.num_cs = cs; 544 mvebu_mbus_dram_info.num_cs = cs;
517} 545}
518 546
547static int
548mvebu_mbus_default_save_cpu_target(struct mvebu_mbus_state *mbus,
549 u32 *store_addr)
550{
551 int i;
552
553 for (i = 0; i < 4; i++) {
554 u32 base = readl(mbus->sdramwins_base + DDR_BASE_CS_OFF(i));
555 u32 size = readl(mbus->sdramwins_base + DDR_SIZE_CS_OFF(i));
556
557 writel(mbus->sdramwins_phys_base + DDR_BASE_CS_OFF(i),
558 store_addr++);
559 writel(base, store_addr++);
560 writel(mbus->sdramwins_phys_base + DDR_SIZE_CS_OFF(i),
561 store_addr++);
562 writel(size, store_addr++);
563 }
564
565 /* We've written 16 words to the store address */
566 return 16;
567}
568
519static void __init 569static void __init
520mvebu_mbus_dove_setup_cpu_target(struct mvebu_mbus_state *mbus) 570mvebu_mbus_dove_setup_cpu_target(struct mvebu_mbus_state *mbus)
521{ 571{
@@ -546,10 +596,35 @@ mvebu_mbus_dove_setup_cpu_target(struct mvebu_mbus_state *mbus)
546 mvebu_mbus_dram_info.num_cs = cs; 596 mvebu_mbus_dram_info.num_cs = cs;
547} 597}
548 598
599static int
600mvebu_mbus_dove_save_cpu_target(struct mvebu_mbus_state *mbus,
601 u32 *store_addr)
602{
603 int i;
604
605 for (i = 0; i < 2; i++) {
606 u32 map = readl(mbus->sdramwins_base + DOVE_DDR_BASE_CS_OFF(i));
607
608 writel(mbus->sdramwins_phys_base + DOVE_DDR_BASE_CS_OFF(i),
609 store_addr++);
610 writel(map, store_addr++);
611 }
612
613 /* We've written 4 words to the store address */
614 return 4;
615}
616
617int mvebu_mbus_save_cpu_target(u32 *store_addr)
618{
619 return mbus_state.soc->save_cpu_target(&mbus_state, store_addr);
620}
621
549static const struct mvebu_mbus_soc_data armada_370_xp_mbus_data = { 622static const struct mvebu_mbus_soc_data armada_370_xp_mbus_data = {
550 .num_wins = 20, 623 .num_wins = 20,
551 .num_remappable_wins = 8, 624 .num_remappable_wins = 8,
625 .has_mbus_bridge = true,
552 .win_cfg_offset = armada_370_xp_mbus_win_offset, 626 .win_cfg_offset = armada_370_xp_mbus_win_offset,
627 .save_cpu_target = mvebu_mbus_default_save_cpu_target,
553 .setup_cpu_target = mvebu_mbus_default_setup_cpu_target, 628 .setup_cpu_target = mvebu_mbus_default_setup_cpu_target,
554 .show_cpu_target = mvebu_sdram_debug_show_orion, 629 .show_cpu_target = mvebu_sdram_debug_show_orion,
555}; 630};
@@ -558,6 +633,7 @@ static const struct mvebu_mbus_soc_data kirkwood_mbus_data = {
558 .num_wins = 8, 633 .num_wins = 8,
559 .num_remappable_wins = 4, 634 .num_remappable_wins = 4,
560 .win_cfg_offset = orion_mbus_win_offset, 635 .win_cfg_offset = orion_mbus_win_offset,
636 .save_cpu_target = mvebu_mbus_default_save_cpu_target,
561 .setup_cpu_target = mvebu_mbus_default_setup_cpu_target, 637 .setup_cpu_target = mvebu_mbus_default_setup_cpu_target,
562 .show_cpu_target = mvebu_sdram_debug_show_orion, 638 .show_cpu_target = mvebu_sdram_debug_show_orion,
563}; 639};
@@ -566,6 +642,7 @@ static const struct mvebu_mbus_soc_data dove_mbus_data = {
566 .num_wins = 8, 642 .num_wins = 8,
567 .num_remappable_wins = 4, 643 .num_remappable_wins = 4,
568 .win_cfg_offset = orion_mbus_win_offset, 644 .win_cfg_offset = orion_mbus_win_offset,
645 .save_cpu_target = mvebu_mbus_dove_save_cpu_target,
569 .setup_cpu_target = mvebu_mbus_dove_setup_cpu_target, 646 .setup_cpu_target = mvebu_mbus_dove_setup_cpu_target,
570 .show_cpu_target = mvebu_sdram_debug_show_dove, 647 .show_cpu_target = mvebu_sdram_debug_show_dove,
571}; 648};
@@ -578,6 +655,7 @@ static const struct mvebu_mbus_soc_data orion5x_4win_mbus_data = {
578 .num_wins = 8, 655 .num_wins = 8,
579 .num_remappable_wins = 4, 656 .num_remappable_wins = 4,
580 .win_cfg_offset = orion_mbus_win_offset, 657 .win_cfg_offset = orion_mbus_win_offset,
658 .save_cpu_target = mvebu_mbus_default_save_cpu_target,
581 .setup_cpu_target = mvebu_mbus_default_setup_cpu_target, 659 .setup_cpu_target = mvebu_mbus_default_setup_cpu_target,
582 .show_cpu_target = mvebu_sdram_debug_show_orion, 660 .show_cpu_target = mvebu_sdram_debug_show_orion,
583}; 661};
@@ -586,6 +664,7 @@ static const struct mvebu_mbus_soc_data orion5x_2win_mbus_data = {
586 .num_wins = 8, 664 .num_wins = 8,
587 .num_remappable_wins = 2, 665 .num_remappable_wins = 2,
588 .win_cfg_offset = orion_mbus_win_offset, 666 .win_cfg_offset = orion_mbus_win_offset,
667 .save_cpu_target = mvebu_mbus_default_save_cpu_target,
589 .setup_cpu_target = mvebu_mbus_default_setup_cpu_target, 668 .setup_cpu_target = mvebu_mbus_default_setup_cpu_target,
590 .show_cpu_target = mvebu_sdram_debug_show_orion, 669 .show_cpu_target = mvebu_sdram_debug_show_orion,
591}; 670};
@@ -594,6 +673,7 @@ static const struct mvebu_mbus_soc_data mv78xx0_mbus_data = {
594 .num_wins = 14, 673 .num_wins = 14,
595 .num_remappable_wins = 8, 674 .num_remappable_wins = 8,
596 .win_cfg_offset = mv78xx0_mbus_win_offset, 675 .win_cfg_offset = mv78xx0_mbus_win_offset,
676 .save_cpu_target = mvebu_mbus_default_save_cpu_target,
597 .setup_cpu_target = mvebu_mbus_default_setup_cpu_target, 677 .setup_cpu_target = mvebu_mbus_default_setup_cpu_target,
598 .show_cpu_target = mvebu_sdram_debug_show_orion, 678 .show_cpu_target = mvebu_sdram_debug_show_orion,
599}; 679};
@@ -698,11 +778,73 @@ static __init int mvebu_mbus_debugfs_init(void)
698} 778}
699fs_initcall(mvebu_mbus_debugfs_init); 779fs_initcall(mvebu_mbus_debugfs_init);
700 780
781static int mvebu_mbus_suspend(void)
782{
783 struct mvebu_mbus_state *s = &mbus_state;
784 int win;
785
786 if (!s->mbusbridge_base)
787 return -ENODEV;
788
789 for (win = 0; win < s->soc->num_wins; win++) {
790 void __iomem *addr = s->mbuswins_base +
791 s->soc->win_cfg_offset(win);
792
793 s->wins[win].base = readl(addr + WIN_BASE_OFF);
794 s->wins[win].ctrl = readl(addr + WIN_CTRL_OFF);
795
796 if (win >= s->soc->num_remappable_wins)
797 continue;
798
799 s->wins[win].remap_lo = readl(addr + WIN_REMAP_LO_OFF);
800 s->wins[win].remap_hi = readl(addr + WIN_REMAP_HI_OFF);
801 }
802
803 s->mbus_bridge_ctrl = readl(s->mbusbridge_base +
804 MBUS_BRIDGE_CTRL_OFF);
805 s->mbus_bridge_base = readl(s->mbusbridge_base +
806 MBUS_BRIDGE_BASE_OFF);
807
808 return 0;
809}
810
811static void mvebu_mbus_resume(void)
812{
813 struct mvebu_mbus_state *s = &mbus_state;
814 int win;
815
816 writel(s->mbus_bridge_ctrl,
817 s->mbusbridge_base + MBUS_BRIDGE_CTRL_OFF);
818 writel(s->mbus_bridge_base,
819 s->mbusbridge_base + MBUS_BRIDGE_BASE_OFF);
820
821 for (win = 0; win < s->soc->num_wins; win++) {
822 void __iomem *addr = s->mbuswins_base +
823 s->soc->win_cfg_offset(win);
824
825 writel(s->wins[win].base, addr + WIN_BASE_OFF);
826 writel(s->wins[win].ctrl, addr + WIN_CTRL_OFF);
827
828 if (win >= s->soc->num_remappable_wins)
829 continue;
830
831 writel(s->wins[win].remap_lo, addr + WIN_REMAP_LO_OFF);
832 writel(s->wins[win].remap_hi, addr + WIN_REMAP_HI_OFF);
833 }
834}
835
836struct syscore_ops mvebu_mbus_syscore_ops = {
837 .suspend = mvebu_mbus_suspend,
838 .resume = mvebu_mbus_resume,
839};
840
701static int __init mvebu_mbus_common_init(struct mvebu_mbus_state *mbus, 841static int __init mvebu_mbus_common_init(struct mvebu_mbus_state *mbus,
702 phys_addr_t mbuswins_phys_base, 842 phys_addr_t mbuswins_phys_base,
703 size_t mbuswins_size, 843 size_t mbuswins_size,
704 phys_addr_t sdramwins_phys_base, 844 phys_addr_t sdramwins_phys_base,
705 size_t sdramwins_size) 845 size_t sdramwins_size,
846 phys_addr_t mbusbridge_phys_base,
847 size_t mbusbridge_size)
706{ 848{
707 int win; 849 int win;
708 850
@@ -716,11 +858,26 @@ static int __init mvebu_mbus_common_init(struct mvebu_mbus_state *mbus,
716 return -ENOMEM; 858 return -ENOMEM;
717 } 859 }
718 860
861 mbus->sdramwins_phys_base = sdramwins_phys_base;
862
863 if (mbusbridge_phys_base) {
864 mbus->mbusbridge_base = ioremap(mbusbridge_phys_base,
865 mbusbridge_size);
866 if (!mbus->mbusbridge_base) {
867 iounmap(mbus->sdramwins_base);
868 iounmap(mbus->mbuswins_base);
869 return -ENOMEM;
870 }
871 } else
872 mbus->mbusbridge_base = NULL;
873
719 for (win = 0; win < mbus->soc->num_wins; win++) 874 for (win = 0; win < mbus->soc->num_wins; win++)
720 mvebu_mbus_disable_window(mbus, win); 875 mvebu_mbus_disable_window(mbus, win);
721 876
722 mbus->soc->setup_cpu_target(mbus); 877 mbus->soc->setup_cpu_target(mbus);
723 878
879 register_syscore_ops(&mvebu_mbus_syscore_ops);
880
724 return 0; 881 return 0;
725} 882}
726 883
@@ -746,7 +903,7 @@ int __init mvebu_mbus_init(const char *soc, phys_addr_t mbuswins_phys_base,
746 mbuswins_phys_base, 903 mbuswins_phys_base,
747 mbuswins_size, 904 mbuswins_size,
748 sdramwins_phys_base, 905 sdramwins_phys_base,
749 sdramwins_size); 906 sdramwins_size, 0, 0);
750} 907}
751 908
752#ifdef CONFIG_OF 909#ifdef CONFIG_OF
@@ -887,7 +1044,7 @@ static void __init mvebu_mbus_get_pcie_resources(struct device_node *np,
887 1044
888int __init mvebu_mbus_dt_init(bool is_coherent) 1045int __init mvebu_mbus_dt_init(bool is_coherent)
889{ 1046{
890 struct resource mbuswins_res, sdramwins_res; 1047 struct resource mbuswins_res, sdramwins_res, mbusbridge_res;
891 struct device_node *np, *controller; 1048 struct device_node *np, *controller;
892 const struct of_device_id *of_id; 1049 const struct of_device_id *of_id;
893 const __be32 *prop; 1050 const __be32 *prop;
@@ -923,6 +1080,19 @@ int __init mvebu_mbus_dt_init(bool is_coherent)
923 return -EINVAL; 1080 return -EINVAL;
924 } 1081 }
925 1082
1083 /*
1084 * Set the resource to 0 so that it can be left unmapped by
1085 * mvebu_mbus_common_init() if the DT doesn't carry the
1086 * necessary information. This is needed to preserve backward
1087 * compatibility.
1088 */
1089 memset(&mbusbridge_res, 0, sizeof(mbusbridge_res));
1090
1091 if (mbus_state.soc->has_mbus_bridge) {
1092 if (of_address_to_resource(controller, 2, &mbusbridge_res))
1093 pr_warn(FW_WARN "deprecated mbus-mvebu Device Tree, suspend/resume will not work\n");
1094 }
1095
926 mbus_state.hw_io_coherency = is_coherent; 1096 mbus_state.hw_io_coherency = is_coherent;
927 1097
928 /* Get optional pcie-{mem,io}-aperture properties */ 1098 /* Get optional pcie-{mem,io}-aperture properties */
@@ -933,7 +1103,9 @@ int __init mvebu_mbus_dt_init(bool is_coherent)
933 mbuswins_res.start, 1103 mbuswins_res.start,
934 resource_size(&mbuswins_res), 1104 resource_size(&mbuswins_res),
935 sdramwins_res.start, 1105 sdramwins_res.start,
936 resource_size(&sdramwins_res)); 1106 resource_size(&sdramwins_res),
1107 mbusbridge_res.start,
1108 resource_size(&mbusbridge_res));
937 if (ret) 1109 if (ret)
938 return ret; 1110 return ret;
939 1111
diff --git a/drivers/clk/mvebu/common.c b/drivers/clk/mvebu/common.c
index b7fcb469c87a..0d4d1216f2dd 100644
--- a/drivers/clk/mvebu/common.c
+++ b/drivers/clk/mvebu/common.c
@@ -19,6 +19,7 @@
19#include <linux/io.h> 19#include <linux/io.h>
20#include <linux/of.h> 20#include <linux/of.h>
21#include <linux/of_address.h> 21#include <linux/of_address.h>
22#include <linux/syscore_ops.h>
22 23
23#include "common.h" 24#include "common.h"
24 25
@@ -177,14 +178,17 @@ struct clk_gating_ctrl {
177 spinlock_t *lock; 178 spinlock_t *lock;
178 struct clk **gates; 179 struct clk **gates;
179 int num_gates; 180 int num_gates;
181 void __iomem *base;
182 u32 saved_reg;
180}; 183};
181 184
182#define to_clk_gate(_hw) container_of(_hw, struct clk_gate, hw) 185#define to_clk_gate(_hw) container_of(_hw, struct clk_gate, hw)
183 186
187static struct clk_gating_ctrl *ctrl;
188
184static struct clk *clk_gating_get_src( 189static struct clk *clk_gating_get_src(
185 struct of_phandle_args *clkspec, void *data) 190 struct of_phandle_args *clkspec, void *data)
186{ 191{
187 struct clk_gating_ctrl *ctrl = (struct clk_gating_ctrl *)data;
188 int n; 192 int n;
189 193
190 if (clkspec->args_count < 1) 194 if (clkspec->args_count < 1)
@@ -199,15 +203,35 @@ static struct clk *clk_gating_get_src(
199 return ERR_PTR(-ENODEV); 203 return ERR_PTR(-ENODEV);
200} 204}
201 205
206static int mvebu_clk_gating_suspend(void)
207{
208 ctrl->saved_reg = readl(ctrl->base);
209 return 0;
210}
211
212static void mvebu_clk_gating_resume(void)
213{
214 writel(ctrl->saved_reg, ctrl->base);
215}
216
217static struct syscore_ops clk_gate_syscore_ops = {
218 .suspend = mvebu_clk_gating_suspend,
219 .resume = mvebu_clk_gating_resume,
220};
221
202void __init mvebu_clk_gating_setup(struct device_node *np, 222void __init mvebu_clk_gating_setup(struct device_node *np,
203 const struct clk_gating_soc_desc *desc) 223 const struct clk_gating_soc_desc *desc)
204{ 224{
205 struct clk_gating_ctrl *ctrl;
206 struct clk *clk; 225 struct clk *clk;
207 void __iomem *base; 226 void __iomem *base;
208 const char *default_parent = NULL; 227 const char *default_parent = NULL;
209 int n; 228 int n;
210 229
230 if (ctrl) {
231 pr_err("mvebu-clk-gating: cannot instantiate more than one gatable clock device\n");
232 return;
233 }
234
211 base = of_iomap(np, 0); 235 base = of_iomap(np, 0);
212 if (WARN_ON(!base)) 236 if (WARN_ON(!base))
213 return; 237 return;
@@ -225,6 +249,8 @@ void __init mvebu_clk_gating_setup(struct device_node *np,
225 /* lock must already be initialized */ 249 /* lock must already be initialized */
226 ctrl->lock = &ctrl_gating_lock; 250 ctrl->lock = &ctrl_gating_lock;
227 251
252 ctrl->base = base;
253
228 /* Count, allocate, and register clock gates */ 254 /* Count, allocate, and register clock gates */
229 for (n = 0; desc[n].name;) 255 for (n = 0; desc[n].name;)
230 n++; 256 n++;
@@ -246,6 +272,8 @@ void __init mvebu_clk_gating_setup(struct device_node *np,
246 272
247 of_clk_add_provider(np, clk_gating_get_src, ctrl); 273 of_clk_add_provider(np, clk_gating_get_src, ctrl);
248 274
275 register_syscore_ops(&clk_gate_syscore_ops);
276
249 return; 277 return;
250gates_out: 278gates_out:
251 kfree(ctrl); 279 kfree(ctrl);
diff --git a/drivers/clk/samsung/clk-exynos5440.c b/drivers/clk/samsung/clk-exynos5440.c
index 00d1d00a41de..979e81389cdd 100644
--- a/drivers/clk/samsung/clk-exynos5440.c
+++ b/drivers/clk/samsung/clk-exynos5440.c
@@ -15,6 +15,8 @@
15#include <linux/clk-provider.h> 15#include <linux/clk-provider.h>
16#include <linux/of.h> 16#include <linux/of.h>
17#include <linux/of_address.h> 17#include <linux/of_address.h>
18#include <linux/notifier.h>
19#include <linux/reboot.h>
18 20
19#include "clk.h" 21#include "clk.h"
20#include "clk-pll.h" 22#include "clk-pll.h"
@@ -23,6 +25,8 @@
23#define CPU_CLK_STATUS 0xfc 25#define CPU_CLK_STATUS 0xfc
24#define MISC_DOUT1 0x558 26#define MISC_DOUT1 0x558
25 27
28static void __iomem *reg_base;
29
26/* parent clock name list */ 30/* parent clock name list */
27PNAME(mout_armclk_p) = { "cplla", "cpllb" }; 31PNAME(mout_armclk_p) = { "cplla", "cpllb" };
28PNAME(mout_spi_p) = { "div125", "div200" }; 32PNAME(mout_spi_p) = { "div125", "div200" };
@@ -89,10 +93,30 @@ static const struct of_device_id ext_clk_match[] __initconst = {
89 {}, 93 {},
90}; 94};
91 95
96static int exynos5440_clk_restart_notify(struct notifier_block *this,
97 unsigned long code, void *unused)
98{
99 u32 val, status;
100
101 status = readl_relaxed(reg_base + 0xbc);
102 val = readl_relaxed(reg_base + 0xcc);
103 val = (val & 0xffff0000) | (status & 0xffff);
104 writel_relaxed(val, reg_base + 0xcc);
105
106 return NOTIFY_DONE;
107}
108
109/*
110 * Exynos5440 Clock restart notifier, handles restart functionality
111 */
112static struct notifier_block exynos5440_clk_restart_handler = {
113 .notifier_call = exynos5440_clk_restart_notify,
114 .priority = 128,
115};
116
92/* register exynos5440 clocks */ 117/* register exynos5440 clocks */
93static void __init exynos5440_clk_init(struct device_node *np) 118static void __init exynos5440_clk_init(struct device_node *np)
94{ 119{
95 void __iomem *reg_base;
96 struct samsung_clk_provider *ctx; 120 struct samsung_clk_provider *ctx;
97 121
98 reg_base = of_iomap(np, 0); 122 reg_base = of_iomap(np, 0);
@@ -125,6 +149,9 @@ static void __init exynos5440_clk_init(struct device_node *np)
125 149
126 samsung_clk_of_add_provider(np, ctx); 150 samsung_clk_of_add_provider(np, ctx);
127 151
152 if (register_restart_handler(&exynos5440_clk_restart_handler))
153 pr_warn("exynos5440 clock can't register restart handler\n");
154
128 pr_info("Exynos5440: arm_clk = %ldHz\n", _get_rate("arm_clk")); 155 pr_info("Exynos5440: arm_clk = %ldHz\n", _get_rate("arm_clk"));
129 pr_info("exynos5440 clock initialization complete\n"); 156 pr_info("exynos5440 clock initialization complete\n");
130} 157}
diff --git a/drivers/clk/ti/dpll.c b/drivers/clk/ti/dpll.c
index 79791e1bf282..85ac0dd501de 100644
--- a/drivers/clk/ti/dpll.c
+++ b/drivers/clk/ti/dpll.c
@@ -33,6 +33,9 @@ static const struct clk_ops dpll_m4xen_ck_ops = {
33 .recalc_rate = &omap4_dpll_regm4xen_recalc, 33 .recalc_rate = &omap4_dpll_regm4xen_recalc,
34 .round_rate = &omap4_dpll_regm4xen_round_rate, 34 .round_rate = &omap4_dpll_regm4xen_round_rate,
35 .set_rate = &omap3_noncore_dpll_set_rate, 35 .set_rate = &omap3_noncore_dpll_set_rate,
36 .set_parent = &omap3_noncore_dpll_set_parent,
37 .set_rate_and_parent = &omap3_noncore_dpll_set_rate_and_parent,
38 .determine_rate = &omap4_dpll_regm4xen_determine_rate,
36 .get_parent = &omap2_init_dpll_parent, 39 .get_parent = &omap2_init_dpll_parent,
37}; 40};
38#else 41#else
@@ -53,6 +56,9 @@ static const struct clk_ops dpll_ck_ops = {
53 .recalc_rate = &omap3_dpll_recalc, 56 .recalc_rate = &omap3_dpll_recalc,
54 .round_rate = &omap2_dpll_round_rate, 57 .round_rate = &omap2_dpll_round_rate,
55 .set_rate = &omap3_noncore_dpll_set_rate, 58 .set_rate = &omap3_noncore_dpll_set_rate,
59 .set_parent = &omap3_noncore_dpll_set_parent,
60 .set_rate_and_parent = &omap3_noncore_dpll_set_rate_and_parent,
61 .determine_rate = &omap3_noncore_dpll_determine_rate,
56 .get_parent = &omap2_init_dpll_parent, 62 .get_parent = &omap2_init_dpll_parent,
57}; 63};
58 64
@@ -61,6 +67,9 @@ static const struct clk_ops dpll_no_gate_ck_ops = {
61 .get_parent = &omap2_init_dpll_parent, 67 .get_parent = &omap2_init_dpll_parent,
62 .round_rate = &omap2_dpll_round_rate, 68 .round_rate = &omap2_dpll_round_rate,
63 .set_rate = &omap3_noncore_dpll_set_rate, 69 .set_rate = &omap3_noncore_dpll_set_rate,
70 .set_parent = &omap3_noncore_dpll_set_parent,
71 .set_rate_and_parent = &omap3_noncore_dpll_set_rate_and_parent,
72 .determine_rate = &omap3_noncore_dpll_determine_rate,
64}; 73};
65#else 74#else
66static const struct clk_ops dpll_core_ck_ops = {}; 75static const struct clk_ops dpll_core_ck_ops = {};
@@ -97,6 +106,9 @@ static const struct clk_ops omap3_dpll_ck_ops = {
97 .get_parent = &omap2_init_dpll_parent, 106 .get_parent = &omap2_init_dpll_parent,
98 .recalc_rate = &omap3_dpll_recalc, 107 .recalc_rate = &omap3_dpll_recalc,
99 .set_rate = &omap3_noncore_dpll_set_rate, 108 .set_rate = &omap3_noncore_dpll_set_rate,
109 .set_parent = &omap3_noncore_dpll_set_parent,
110 .set_rate_and_parent = &omap3_noncore_dpll_set_rate_and_parent,
111 .determine_rate = &omap3_noncore_dpll_determine_rate,
100 .round_rate = &omap2_dpll_round_rate, 112 .round_rate = &omap2_dpll_round_rate,
101}; 113};
102 114
@@ -106,6 +118,9 @@ static const struct clk_ops omap3_dpll_per_ck_ops = {
106 .get_parent = &omap2_init_dpll_parent, 118 .get_parent = &omap2_init_dpll_parent,
107 .recalc_rate = &omap3_dpll_recalc, 119 .recalc_rate = &omap3_dpll_recalc,
108 .set_rate = &omap3_dpll4_set_rate, 120 .set_rate = &omap3_dpll4_set_rate,
121 .set_parent = &omap3_noncore_dpll_set_parent,
122 .set_rate_and_parent = &omap3_dpll4_set_rate_and_parent,
123 .determine_rate = &omap3_noncore_dpll_determine_rate,
109 .round_rate = &omap2_dpll_round_rate, 124 .round_rate = &omap2_dpll_round_rate,
110}; 125};
111#endif 126#endif
diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig
index 90420600e1eb..f657a48d20eb 100644
--- a/drivers/clocksource/Kconfig
+++ b/drivers/clocksource/Kconfig
@@ -32,6 +32,7 @@ config ARMADA_370_XP_TIMER
32 32
33config MESON6_TIMER 33config MESON6_TIMER
34 bool 34 bool
35 select CLKSRC_MMIO
35 36
36config ORION_TIMER 37config ORION_TIMER
37 select CLKSRC_OF 38 select CLKSRC_OF
diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile
index 756f6f10efa0..fae0435cc23d 100644
--- a/drivers/clocksource/Makefile
+++ b/drivers/clocksource/Makefile
@@ -45,4 +45,5 @@ obj-$(CONFIG_ARM_GLOBAL_TIMER) += arm_global_timer.o
45obj-$(CONFIG_CLKSRC_METAG_GENERIC) += metag_generic.o 45obj-$(CONFIG_CLKSRC_METAG_GENERIC) += metag_generic.o
46obj-$(CONFIG_ARCH_HAS_TICK_BROADCAST) += dummy_timer.o 46obj-$(CONFIG_ARCH_HAS_TICK_BROADCAST) += dummy_timer.o
47obj-$(CONFIG_ARCH_KEYSTONE) += timer-keystone.o 47obj-$(CONFIG_ARCH_KEYSTONE) += timer-keystone.o
48obj-$(CONFIG_ARCH_INTEGRATOR_AP) += timer-integrator-ap.o
48obj-$(CONFIG_CLKSRC_VERSATILE) += versatile.o 49obj-$(CONFIG_CLKSRC_VERSATILE) += versatile.o
diff --git a/drivers/clocksource/time-armada-370-xp.c b/drivers/clocksource/time-armada-370-xp.c
index 0451e62fac7a..ff37d3abb806 100644
--- a/drivers/clocksource/time-armada-370-xp.c
+++ b/drivers/clocksource/time-armada-370-xp.c
@@ -43,6 +43,7 @@
43#include <linux/module.h> 43#include <linux/module.h>
44#include <linux/sched_clock.h> 44#include <linux/sched_clock.h>
45#include <linux/percpu.h> 45#include <linux/percpu.h>
46#include <linux/syscore_ops.h>
46 47
47/* 48/*
48 * Timer block registers. 49 * Timer block registers.
@@ -223,6 +224,28 @@ static struct notifier_block armada_370_xp_timer_cpu_nb = {
223 .notifier_call = armada_370_xp_timer_cpu_notify, 224 .notifier_call = armada_370_xp_timer_cpu_notify,
224}; 225};
225 226
227static u32 timer0_ctrl_reg, timer0_local_ctrl_reg;
228
229static int armada_370_xp_timer_suspend(void)
230{
231 timer0_ctrl_reg = readl(timer_base + TIMER_CTRL_OFF);
232 timer0_local_ctrl_reg = readl(local_base + TIMER_CTRL_OFF);
233 return 0;
234}
235
236static void armada_370_xp_timer_resume(void)
237{
238 writel(0xffffffff, timer_base + TIMER0_VAL_OFF);
239 writel(0xffffffff, timer_base + TIMER0_RELOAD_OFF);
240 writel(timer0_ctrl_reg, timer_base + TIMER_CTRL_OFF);
241 writel(timer0_local_ctrl_reg, local_base + TIMER_CTRL_OFF);
242}
243
244struct syscore_ops armada_370_xp_timer_syscore_ops = {
245 .suspend = armada_370_xp_timer_suspend,
246 .resume = armada_370_xp_timer_resume,
247};
248
226static void __init armada_370_xp_timer_common_init(struct device_node *np) 249static void __init armada_370_xp_timer_common_init(struct device_node *np)
227{ 250{
228 u32 clr = 0, set = 0; 251 u32 clr = 0, set = 0;
@@ -285,6 +308,8 @@ static void __init armada_370_xp_timer_common_init(struct device_node *np)
285 /* Immediately configure the timer on the boot CPU */ 308 /* Immediately configure the timer on the boot CPU */
286 if (!res) 309 if (!res)
287 armada_370_xp_timer_setup(this_cpu_ptr(armada_370_xp_evt)); 310 armada_370_xp_timer_setup(this_cpu_ptr(armada_370_xp_evt));
311
312 register_syscore_ops(&armada_370_xp_timer_syscore_ops);
288} 313}
289 314
290static void __init armada_xp_timer_init(struct device_node *np) 315static void __init armada_xp_timer_init(struct device_node *np)
diff --git a/drivers/clocksource/timer-integrator-ap.c b/drivers/clocksource/timer-integrator-ap.c
new file mode 100644
index 000000000000..b9efd30513d5
--- /dev/null
+++ b/drivers/clocksource/timer-integrator-ap.c
@@ -0,0 +1,210 @@
1/*
2 * Integrator/AP timer driver
3 * Copyright (C) 2000-2003 Deep Blue Solutions Ltd
4 * Copyright (c) 2014, Linaro Limited
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20
21#include <linux/clk.h>
22#include <linux/clocksource.h>
23#include <linux/of_irq.h>
24#include <linux/of_address.h>
25#include <linux/of_platform.h>
26#include <linux/clockchips.h>
27#include <linux/interrupt.h>
28#include <linux/sched_clock.h>
29#include <asm/hardware/arm_timer.h>
30
31static void __iomem * sched_clk_base;
32
33static u64 notrace integrator_read_sched_clock(void)
34{
35 return -readl(sched_clk_base + TIMER_VALUE);
36}
37
38static void integrator_clocksource_init(unsigned long inrate,
39 void __iomem *base)
40{
41 u32 ctrl = TIMER_CTRL_ENABLE | TIMER_CTRL_PERIODIC;
42 unsigned long rate = inrate;
43
44 if (rate >= 1500000) {
45 rate /= 16;
46 ctrl |= TIMER_CTRL_DIV16;
47 }
48
49 writel(0xffff, base + TIMER_LOAD);
50 writel(ctrl, base + TIMER_CTRL);
51
52 clocksource_mmio_init(base + TIMER_VALUE, "timer2",
53 rate, 200, 16, clocksource_mmio_readl_down);
54
55 sched_clk_base = base;
56 sched_clock_register(integrator_read_sched_clock, 16, rate);
57}
58
59static unsigned long timer_reload;
60static void __iomem * clkevt_base;
61
62/*
63 * IRQ handler for the timer
64 */
65static irqreturn_t integrator_timer_interrupt(int irq, void *dev_id)
66{
67 struct clock_event_device *evt = dev_id;
68
69 /* clear the interrupt */
70 writel(1, clkevt_base + TIMER_INTCLR);
71
72 evt->event_handler(evt);
73
74 return IRQ_HANDLED;
75}
76
77static void clkevt_set_mode(enum clock_event_mode mode, struct clock_event_device *evt)
78{
79 u32 ctrl = readl(clkevt_base + TIMER_CTRL) & ~TIMER_CTRL_ENABLE;
80
81 /* Disable timer */
82 writel(ctrl, clkevt_base + TIMER_CTRL);
83
84 switch (mode) {
85 case CLOCK_EVT_MODE_PERIODIC:
86 /* Enable the timer and start the periodic tick */
87 writel(timer_reload, clkevt_base + TIMER_LOAD);
88 ctrl |= TIMER_CTRL_PERIODIC | TIMER_CTRL_ENABLE;
89 writel(ctrl, clkevt_base + TIMER_CTRL);
90 break;
91 case CLOCK_EVT_MODE_ONESHOT:
92 /* Leave the timer disabled, .set_next_event will enable it */
93 ctrl &= ~TIMER_CTRL_PERIODIC;
94 writel(ctrl, clkevt_base + TIMER_CTRL);
95 break;
96 case CLOCK_EVT_MODE_UNUSED:
97 case CLOCK_EVT_MODE_SHUTDOWN:
98 case CLOCK_EVT_MODE_RESUME:
99 default:
100 /* Just leave in disabled state */
101 break;
102 }
103
104}
105
106static int clkevt_set_next_event(unsigned long next, struct clock_event_device *evt)
107{
108 unsigned long ctrl = readl(clkevt_base + TIMER_CTRL);
109
110 writel(ctrl & ~TIMER_CTRL_ENABLE, clkevt_base + TIMER_CTRL);
111 writel(next, clkevt_base + TIMER_LOAD);
112 writel(ctrl | TIMER_CTRL_ENABLE, clkevt_base + TIMER_CTRL);
113
114 return 0;
115}
116
117static struct clock_event_device integrator_clockevent = {
118 .name = "timer1",
119 .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
120 .set_mode = clkevt_set_mode,
121 .set_next_event = clkevt_set_next_event,
122 .rating = 300,
123};
124
125static struct irqaction integrator_timer_irq = {
126 .name = "timer",
127 .flags = IRQF_TIMER | IRQF_IRQPOLL,
128 .handler = integrator_timer_interrupt,
129 .dev_id = &integrator_clockevent,
130};
131
132static void integrator_clockevent_init(unsigned long inrate,
133 void __iomem *base, int irq)
134{
135 unsigned long rate = inrate;
136 unsigned int ctrl = 0;
137
138 clkevt_base = base;
139 /* Calculate and program a divisor */
140 if (rate > 0x100000 * HZ) {
141 rate /= 256;
142 ctrl |= TIMER_CTRL_DIV256;
143 } else if (rate > 0x10000 * HZ) {
144 rate /= 16;
145 ctrl |= TIMER_CTRL_DIV16;
146 }
147 timer_reload = rate / HZ;
148 writel(ctrl, clkevt_base + TIMER_CTRL);
149
150 setup_irq(irq, &integrator_timer_irq);
151 clockevents_config_and_register(&integrator_clockevent,
152 rate,
153 1,
154 0xffffU);
155}
156
157static void __init integrator_ap_timer_init_of(struct device_node *node)
158{
159 const char *path;
160 void __iomem *base;
161 int err;
162 int irq;
163 struct clk *clk;
164 unsigned long rate;
165 struct device_node *pri_node;
166 struct device_node *sec_node;
167
168 base = of_io_request_and_map(node, 0, "integrator-timer");
169 if (!base)
170 return;
171
172 clk = of_clk_get(node, 0);
173 if (IS_ERR(clk)) {
174 pr_err("No clock for %s\n", node->name);
175 return;
176 }
177 clk_prepare_enable(clk);
178 rate = clk_get_rate(clk);
179 writel(0, base + TIMER_CTRL);
180
181 err = of_property_read_string(of_aliases,
182 "arm,timer-primary", &path);
183 if (WARN_ON(err))
184 return;
185 pri_node = of_find_node_by_path(path);
186 err = of_property_read_string(of_aliases,
187 "arm,timer-secondary", &path);
188 if (WARN_ON(err))
189 return;
190 sec_node = of_find_node_by_path(path);
191
192 if (node == pri_node) {
193 /* The primary timer lacks IRQ, use as clocksource */
194 integrator_clocksource_init(rate, base);
195 return;
196 }
197
198 if (node == sec_node) {
199 /* The secondary timer will drive the clock event */
200 irq = irq_of_parse_and_map(node, 0);
201 integrator_clockevent_init(rate, base, irq);
202 return;
203 }
204
205 pr_info("Timer @%p unused\n", base);
206 clk_disable_unprepare(clk);
207}
208
209CLOCKSOURCE_OF_DECLARE(integrator_ap_timer, "arm,integrator-timer",
210 integrator_ap_timer_init_of);
diff --git a/drivers/irqchip/irq-armada-370-xp.c b/drivers/irqchip/irq-armada-370-xp.c
index 6a2e168c3ab0..b907550ae9a5 100644
--- a/drivers/irqchip/irq-armada-370-xp.c
+++ b/drivers/irqchip/irq-armada-370-xp.c
@@ -26,6 +26,7 @@
26#include <linux/of_pci.h> 26#include <linux/of_pci.h>
27#include <linux/irqdomain.h> 27#include <linux/irqdomain.h>
28#include <linux/slab.h> 28#include <linux/slab.h>
29#include <linux/syscore_ops.h>
29#include <linux/msi.h> 30#include <linux/msi.h>
30#include <asm/mach/arch.h> 31#include <asm/mach/arch.h>
31#include <asm/exception.h> 32#include <asm/exception.h>
@@ -67,6 +68,7 @@
67static void __iomem *per_cpu_int_base; 68static void __iomem *per_cpu_int_base;
68static void __iomem *main_int_base; 69static void __iomem *main_int_base;
69static struct irq_domain *armada_370_xp_mpic_domain; 70static struct irq_domain *armada_370_xp_mpic_domain;
71static u32 doorbell_mask_reg;
70#ifdef CONFIG_PCI_MSI 72#ifdef CONFIG_PCI_MSI
71static struct irq_domain *armada_370_xp_msi_domain; 73static struct irq_domain *armada_370_xp_msi_domain;
72static DECLARE_BITMAP(msi_used, PCI_MSI_DOORBELL_NR); 74static DECLARE_BITMAP(msi_used, PCI_MSI_DOORBELL_NR);
@@ -485,6 +487,54 @@ armada_370_xp_handle_irq(struct pt_regs *regs)
485 } while (1); 487 } while (1);
486} 488}
487 489
490static int armada_370_xp_mpic_suspend(void)
491{
492 doorbell_mask_reg = readl(per_cpu_int_base +
493 ARMADA_370_XP_IN_DRBEL_MSK_OFFS);
494 return 0;
495}
496
497static void armada_370_xp_mpic_resume(void)
498{
499 int nirqs;
500 irq_hw_number_t irq;
501
502 /* Re-enable interrupts */
503 nirqs = (readl(main_int_base + ARMADA_370_XP_INT_CONTROL) >> 2) & 0x3ff;
504 for (irq = 0; irq < nirqs; irq++) {
505 struct irq_data *data;
506 int virq;
507
508 virq = irq_linear_revmap(armada_370_xp_mpic_domain, irq);
509 if (virq == 0)
510 continue;
511
512 if (irq != ARMADA_370_XP_TIMER0_PER_CPU_IRQ)
513 writel(irq, per_cpu_int_base +
514 ARMADA_370_XP_INT_CLEAR_MASK_OFFS);
515 else
516 writel(irq, main_int_base +
517 ARMADA_370_XP_INT_SET_ENABLE_OFFS);
518
519 data = irq_get_irq_data(virq);
520 if (!irqd_irq_disabled(data))
521 armada_370_xp_irq_unmask(data);
522 }
523
524 /* Reconfigure doorbells for IPIs and MSIs */
525 writel(doorbell_mask_reg,
526 per_cpu_int_base + ARMADA_370_XP_IN_DRBEL_MSK_OFFS);
527 if (doorbell_mask_reg & IPI_DOORBELL_MASK)
528 writel(0, per_cpu_int_base + ARMADA_370_XP_INT_CLEAR_MASK_OFFS);
529 if (doorbell_mask_reg & PCI_MSI_DOORBELL_MASK)
530 writel(1, per_cpu_int_base + ARMADA_370_XP_INT_CLEAR_MASK_OFFS);
531}
532
533struct syscore_ops armada_370_xp_mpic_syscore_ops = {
534 .suspend = armada_370_xp_mpic_suspend,
535 .resume = armada_370_xp_mpic_resume,
536};
537
488static int __init armada_370_xp_mpic_of_init(struct device_node *node, 538static int __init armada_370_xp_mpic_of_init(struct device_node *node,
489 struct device_node *parent) 539 struct device_node *parent)
490{ 540{
@@ -541,6 +591,8 @@ static int __init armada_370_xp_mpic_of_init(struct device_node *node,
541 armada_370_xp_mpic_handle_cascade_irq); 591 armada_370_xp_mpic_handle_cascade_irq);
542 } 592 }
543 593
594 register_syscore_ops(&armada_370_xp_mpic_syscore_ops);
595
544 return 0; 596 return 0;
545} 597}
546 598
diff --git a/drivers/power/reset/Kconfig b/drivers/power/reset/Kconfig
index f65ff49bb275..028e76504519 100644
--- a/drivers/power/reset/Kconfig
+++ b/drivers/power/reset/Kconfig
@@ -71,6 +71,15 @@ config POWER_RESET_HISI
71 help 71 help
72 Reboot support for Hisilicon boards. 72 Reboot support for Hisilicon boards.
73 73
74config POWER_RESET_IMX
75 bool "IMX6 power-off driver"
76 depends on POWER_RESET && SOC_IMX6
77 help
78 This driver support power off external PMIC by PMIC_ON_REQ on i.mx6
79 boards.If you want to use other pin to control external power,please
80 say N here or disable in dts to make sure pm_power_off never be
81 overwrote wrongly by this driver.
82
74config POWER_RESET_MSM 83config POWER_RESET_MSM
75 bool "Qualcomm MSM power-off driver" 84 bool "Qualcomm MSM power-off driver"
76 depends on ARCH_QCOM 85 depends on ARCH_QCOM
diff --git a/drivers/power/reset/Makefile b/drivers/power/reset/Makefile
index 76ce1c59469b..1d4804d6b323 100644
--- a/drivers/power/reset/Makefile
+++ b/drivers/power/reset/Makefile
@@ -6,6 +6,7 @@ obj-$(CONFIG_POWER_RESET_BRCMSTB) += brcmstb-reboot.o
6obj-$(CONFIG_POWER_RESET_GPIO) += gpio-poweroff.o 6obj-$(CONFIG_POWER_RESET_GPIO) += gpio-poweroff.o
7obj-$(CONFIG_POWER_RESET_GPIO_RESTART) += gpio-restart.o 7obj-$(CONFIG_POWER_RESET_GPIO_RESTART) += gpio-restart.o
8obj-$(CONFIG_POWER_RESET_HISI) += hisi-reboot.o 8obj-$(CONFIG_POWER_RESET_HISI) += hisi-reboot.o
9obj-$(CONFIG_POWER_RESET_IMX) += imx-snvs-poweroff.o
9obj-$(CONFIG_POWER_RESET_MSM) += msm-poweroff.o 10obj-$(CONFIG_POWER_RESET_MSM) += msm-poweroff.o
10obj-$(CONFIG_POWER_RESET_LTC2952) += ltc2952-poweroff.o 11obj-$(CONFIG_POWER_RESET_LTC2952) += ltc2952-poweroff.o
11obj-$(CONFIG_POWER_RESET_QNAP) += qnap-poweroff.o 12obj-$(CONFIG_POWER_RESET_QNAP) += qnap-poweroff.o
diff --git a/drivers/power/reset/imx-snvs-poweroff.c b/drivers/power/reset/imx-snvs-poweroff.c
new file mode 100644
index 000000000000..ad6ce5020ea7
--- /dev/null
+++ b/drivers/power/reset/imx-snvs-poweroff.c
@@ -0,0 +1,66 @@
1/* Power off driver for i.mx6
2 * Copyright (c) 2014, FREESCALE CORPORATION. All rights reserved.
3 *
4 * based on msm-poweroff.c
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 and
8 * only version 2 as published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 */
16
17#include <linux/err.h>
18#include <linux/init.h>
19#include <linux/io.h>
20#include <linux/kernel.h>
21#include <linux/module.h>
22#include <linux/of.h>
23#include <linux/of_address.h>
24#include <linux/platform_device.h>
25
26static void __iomem *snvs_base;
27
28static void do_imx_poweroff(void)
29{
30 u32 value = readl(snvs_base);
31
32 /* set TOP and DP_EN bit */
33 writel(value | 0x60, snvs_base);
34}
35
36static int imx_poweroff_probe(struct platform_device *pdev)
37{
38 snvs_base = of_iomap(pdev->dev.of_node, 0);
39 if (!snvs_base) {
40 dev_err(&pdev->dev, "failed to get memory\n");
41 return -ENODEV;
42 }
43
44 pm_power_off = do_imx_poweroff;
45 return 0;
46}
47
48static const struct of_device_id of_imx_poweroff_match[] = {
49 { .compatible = "fsl,sec-v4.0-poweroff", },
50 {},
51};
52MODULE_DEVICE_TABLE(of, of_imx_poweroff_match);
53
54static struct platform_driver imx_poweroff_driver = {
55 .probe = imx_poweroff_probe,
56 .driver = {
57 .name = "imx-snvs-poweroff",
58 .of_match_table = of_match_ptr(of_imx_poweroff_match),
59 },
60};
61
62static int __init imx_poweroff_init(void)
63{
64 return platform_driver_register(&imx_poweroff_driver);
65}
66device_initcall(imx_poweroff_init);
diff --git a/drivers/soc/versatile/Kconfig b/drivers/soc/versatile/Kconfig
index bf5ee9c85330..a928a7fc6be4 100644
--- a/drivers/soc/versatile/Kconfig
+++ b/drivers/soc/versatile/Kconfig
@@ -1,6 +1,15 @@
1# 1#
2# ARM Versatile SoC drivers 2# ARM Versatile SoC drivers
3# 3#
4config SOC_INTEGRATOR_CM
5 bool "SoC bus device for the ARM Integrator platform core modules"
6 depends on ARCH_INTEGRATOR
7 select SOC_BUS
8 help
9 Include support for the SoC bus on the ARM Integrator platform
10 core modules providing some sysfs information about the ASIC
11 variant.
12
4config SOC_REALVIEW 13config SOC_REALVIEW
5 bool "SoC bus device for the ARM RealView platforms" 14 bool "SoC bus device for the ARM RealView platforms"
6 depends on ARCH_REALVIEW 15 depends on ARCH_REALVIEW
diff --git a/drivers/soc/versatile/Makefile b/drivers/soc/versatile/Makefile
index ad547435648e..cf612fe3a659 100644
--- a/drivers/soc/versatile/Makefile
+++ b/drivers/soc/versatile/Makefile
@@ -1 +1,2 @@
1obj-$(CONFIG_SOC_INTEGRATOR_CM) += soc-integrator.o
1obj-$(CONFIG_SOC_REALVIEW) += soc-realview.o 2obj-$(CONFIG_SOC_REALVIEW) += soc-realview.o
diff --git a/drivers/soc/versatile/soc-integrator.c b/drivers/soc/versatile/soc-integrator.c
new file mode 100644
index 000000000000..a5d7d39ae0ad
--- /dev/null
+++ b/drivers/soc/versatile/soc-integrator.c
@@ -0,0 +1,155 @@
1/*
2 * Copyright (C) 2014 Linaro Ltd.
3 *
4 * Author: Linus Walleij <linus.walleij@linaro.org>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2, as
8 * published by the Free Software Foundation.
9 *
10 */
11#include <linux/init.h>
12#include <linux/io.h>
13#include <linux/slab.h>
14#include <linux/sys_soc.h>
15#include <linux/platform_device.h>
16#include <linux/mfd/syscon.h>
17#include <linux/regmap.h>
18#include <linux/of.h>
19
20#define INTEGRATOR_HDR_ID_OFFSET 0x00
21
22static u32 integrator_coreid;
23
24static const struct of_device_id integrator_cm_match[] = {
25 { .compatible = "arm,core-module-integrator", },
26 { }
27};
28
29static const char *integrator_arch_str(u32 id)
30{
31 switch ((id >> 16) & 0xff) {
32 case 0x00:
33 return "ASB little-endian";
34 case 0x01:
35 return "AHB little-endian";
36 case 0x03:
37 return "AHB-Lite system bus, bi-endian";
38 case 0x04:
39 return "AHB";
40 case 0x08:
41 return "AHB system bus, ASB processor bus";
42 default:
43 return "Unknown";
44 }
45}
46
47static const char *integrator_fpga_str(u32 id)
48{
49 switch ((id >> 12) & 0xf) {
50 case 0x01:
51 return "XC4062";
52 case 0x02:
53 return "XC4085";
54 case 0x03:
55 return "XVC600";
56 case 0x04:
57 return "EPM7256AE (Altera PLD)";
58 default:
59 return "Unknown";
60 }
61}
62
63static ssize_t integrator_get_manf(struct device *dev,
64 struct device_attribute *attr,
65 char *buf)
66{
67 return sprintf(buf, "%02x\n", integrator_coreid >> 24);
68}
69
70static struct device_attribute integrator_manf_attr =
71 __ATTR(manufacturer, S_IRUGO, integrator_get_manf, NULL);
72
73static ssize_t integrator_get_arch(struct device *dev,
74 struct device_attribute *attr,
75 char *buf)
76{
77 return sprintf(buf, "%s\n", integrator_arch_str(integrator_coreid));
78}
79
80static struct device_attribute integrator_arch_attr =
81 __ATTR(arch, S_IRUGO, integrator_get_arch, NULL);
82
83static ssize_t integrator_get_fpga(struct device *dev,
84 struct device_attribute *attr,
85 char *buf)
86{
87 return sprintf(buf, "%s\n", integrator_fpga_str(integrator_coreid));
88}
89
90static struct device_attribute integrator_fpga_attr =
91 __ATTR(fpga, S_IRUGO, integrator_get_fpga, NULL);
92
93static ssize_t integrator_get_build(struct device *dev,
94 struct device_attribute *attr,
95 char *buf)
96{
97 return sprintf(buf, "%02x\n", (integrator_coreid >> 4) & 0xFF);
98}
99
100static struct device_attribute integrator_build_attr =
101 __ATTR(build, S_IRUGO, integrator_get_build, NULL);
102
103static int __init integrator_soc_init(void)
104{
105 static struct regmap *syscon_regmap;
106 struct soc_device *soc_dev;
107 struct soc_device_attribute *soc_dev_attr;
108 struct device_node *np;
109 struct device *dev;
110 u32 val;
111 int ret;
112
113 np = of_find_matching_node(NULL, integrator_cm_match);
114 if (!np)
115 return -ENODEV;
116
117 syscon_regmap = syscon_node_to_regmap(np);
118 if (IS_ERR(syscon_regmap))
119 return PTR_ERR(syscon_regmap);
120
121 ret = regmap_read(syscon_regmap, INTEGRATOR_HDR_ID_OFFSET,
122 &val);
123 if (ret)
124 return -ENODEV;
125 integrator_coreid = val;
126
127 soc_dev_attr = kzalloc(sizeof(*soc_dev_attr), GFP_KERNEL);
128 if (!soc_dev_attr)
129 return -ENOMEM;
130
131 soc_dev_attr->soc_id = "Integrator";
132 soc_dev_attr->machine = "Integrator";
133 soc_dev_attr->family = "Versatile";
134 soc_dev = soc_device_register(soc_dev_attr);
135 if (IS_ERR(soc_dev)) {
136 kfree(soc_dev_attr);
137 return -ENODEV;
138 }
139 dev = soc_device_to_device(soc_dev);
140
141 device_create_file(dev, &integrator_manf_attr);
142 device_create_file(dev, &integrator_arch_attr);
143 device_create_file(dev, &integrator_fpga_attr);
144 device_create_file(dev, &integrator_build_attr);
145
146 dev_info(dev, "Detected ARM core module:\n");
147 dev_info(dev, " Manufacturer: %02x\n", (val >> 24));
148 dev_info(dev, " Architecture: %s\n", integrator_arch_str(val));
149 dev_info(dev, " FPGA: %s\n", integrator_fpga_str(val));
150 dev_info(dev, " Build: %02x\n", (val >> 4) & 0xFF);
151 dev_info(dev, " Rev: %c\n", ('A' + (val & 0x03)));
152
153 return 0;
154}
155device_initcall(integrator_soc_init);
diff --git a/include/dt-bindings/arm/ux500_pm_domains.h b/include/dt-bindings/arm/ux500_pm_domains.h
new file mode 100644
index 000000000000..398a6c0288d1
--- /dev/null
+++ b/include/dt-bindings/arm/ux500_pm_domains.h
@@ -0,0 +1,15 @@
1/*
2 * Copyright (C) 2014 Linaro Ltd.
3 *
4 * Author: Ulf Hansson <ulf.hansson@linaro.org>
5 * License terms: GNU General Public License (GPL) version 2
6 */
7#ifndef _DT_BINDINGS_ARM_UX500_PM_DOMAINS_H
8#define _DT_BINDINGS_ARM_UX500_PM_DOMAINS_H
9
10#define DOMAIN_VAPE 0
11
12/* Number of PM domains. */
13#define NR_DOMAINS (DOMAIN_VAPE + 1)
14
15#endif
diff --git a/include/dt-bindings/clock/imx5-clock.h b/include/dt-bindings/clock/imx5-clock.h
index 5f2667ecd98e..f4b7478e23c8 100644
--- a/include/dt-bindings/clock/imx5-clock.h
+++ b/include/dt-bindings/clock/imx5-clock.h
@@ -198,6 +198,9 @@
198#define IMX5_CLK_OCRAM 186 198#define IMX5_CLK_OCRAM 186
199#define IMX5_CLK_SAHARA_IPG_GATE 187 199#define IMX5_CLK_SAHARA_IPG_GATE 187
200#define IMX5_CLK_SATA_REF 188 200#define IMX5_CLK_SATA_REF 188
201#define IMX5_CLK_END 189 201#define IMX5_CLK_STEP_SEL 189
202#define IMX5_CLK_CPU_PODF_SEL 190
203#define IMX5_CLK_ARM 191
204#define IMX5_CLK_END 192
202 205
203#endif /* __DT_BINDINGS_CLOCK_IMX5_H */ 206#endif /* __DT_BINDINGS_CLOCK_IMX5_H */
diff --git a/include/linux/clk/ti.h b/include/linux/clk/ti.h
index f75acbf70e96..74e5341463c9 100644
--- a/include/linux/clk/ti.h
+++ b/include/linux/clk/ti.h
@@ -254,13 +254,26 @@ extern const struct clk_ops ti_clk_mux_ops;
254void omap2_init_clk_hw_omap_clocks(struct clk *clk); 254void omap2_init_clk_hw_omap_clocks(struct clk *clk);
255int omap3_noncore_dpll_enable(struct clk_hw *hw); 255int omap3_noncore_dpll_enable(struct clk_hw *hw);
256void omap3_noncore_dpll_disable(struct clk_hw *hw); 256void omap3_noncore_dpll_disable(struct clk_hw *hw);
257int omap3_noncore_dpll_set_parent(struct clk_hw *hw, u8 index);
257int omap3_noncore_dpll_set_rate(struct clk_hw *hw, unsigned long rate, 258int omap3_noncore_dpll_set_rate(struct clk_hw *hw, unsigned long rate,
258 unsigned long parent_rate); 259 unsigned long parent_rate);
260int omap3_noncore_dpll_set_rate_and_parent(struct clk_hw *hw,
261 unsigned long rate,
262 unsigned long parent_rate,
263 u8 index);
264long omap3_noncore_dpll_determine_rate(struct clk_hw *hw,
265 unsigned long rate,
266 unsigned long *best_parent_rate,
267 struct clk **best_parent_clk);
259unsigned long omap4_dpll_regm4xen_recalc(struct clk_hw *hw, 268unsigned long omap4_dpll_regm4xen_recalc(struct clk_hw *hw,
260 unsigned long parent_rate); 269 unsigned long parent_rate);
261long omap4_dpll_regm4xen_round_rate(struct clk_hw *hw, 270long omap4_dpll_regm4xen_round_rate(struct clk_hw *hw,
262 unsigned long target_rate, 271 unsigned long target_rate,
263 unsigned long *parent_rate); 272 unsigned long *parent_rate);
273long omap4_dpll_regm4xen_determine_rate(struct clk_hw *hw,
274 unsigned long rate,
275 unsigned long *best_parent_rate,
276 struct clk **best_parent_clk);
264u8 omap2_init_dpll_parent(struct clk_hw *hw); 277u8 omap2_init_dpll_parent(struct clk_hw *hw);
265unsigned long omap3_dpll_recalc(struct clk_hw *hw, unsigned long parent_rate); 278unsigned long omap3_dpll_recalc(struct clk_hw *hw, unsigned long parent_rate);
266long omap2_dpll_round_rate(struct clk_hw *hw, unsigned long target_rate, 279long omap2_dpll_round_rate(struct clk_hw *hw, unsigned long target_rate,
@@ -278,6 +291,8 @@ int omap2_clk_disable_autoidle_all(void);
278void omap2_clk_enable_init_clocks(const char **clk_names, u8 num_clocks); 291void omap2_clk_enable_init_clocks(const char **clk_names, u8 num_clocks);
279int omap3_dpll4_set_rate(struct clk_hw *clk, unsigned long rate, 292int omap3_dpll4_set_rate(struct clk_hw *clk, unsigned long rate,
280 unsigned long parent_rate); 293 unsigned long parent_rate);
294int omap3_dpll4_set_rate_and_parent(struct clk_hw *hw, unsigned long rate,
295 unsigned long parent_rate, u8 index);
281int omap2_dflt_clk_enable(struct clk_hw *hw); 296int omap2_dflt_clk_enable(struct clk_hw *hw);
282void omap2_dflt_clk_disable(struct clk_hw *hw); 297void omap2_dflt_clk_disable(struct clk_hw *hw);
283int omap2_dflt_clk_is_enabled(struct clk_hw *hw); 298int omap2_dflt_clk_is_enabled(struct clk_hw *hw);
diff --git a/include/linux/mbus.h b/include/linux/mbus.h
index 550c88fb0267..611b69fa8594 100644
--- a/include/linux/mbus.h
+++ b/include/linux/mbus.h
@@ -61,6 +61,7 @@ static inline const struct mbus_dram_target_info *mv_mbus_dram_info(void)
61} 61}
62#endif 62#endif
63 63
64int mvebu_mbus_save_cpu_target(u32 *store_addr);
64void mvebu_mbus_get_pcie_mem_aperture(struct resource *res); 65void mvebu_mbus_get_pcie_mem_aperture(struct resource *res);
65void mvebu_mbus_get_pcie_io_aperture(struct resource *res); 66void mvebu_mbus_get_pcie_io_aperture(struct resource *res);
66int mvebu_mbus_add_window_remap_by_id(unsigned int target, 67int mvebu_mbus_add_window_remap_by_id(unsigned int target,
diff --git a/include/linux/mfd/syscon/imx6q-iomuxc-gpr.h b/include/linux/mfd/syscon/imx6q-iomuxc-gpr.h
index ff44374a1a4e..c877cad61a13 100644
--- a/include/linux/mfd/syscon/imx6q-iomuxc-gpr.h
+++ b/include/linux/mfd/syscon/imx6q-iomuxc-gpr.h
@@ -395,4 +395,43 @@
395#define IMX6SL_GPR1_FEC_CLOCK_MUX1_SEL_MASK (0x3 << 17) 395#define IMX6SL_GPR1_FEC_CLOCK_MUX1_SEL_MASK (0x3 << 17)
396#define IMX6SL_GPR1_FEC_CLOCK_MUX2_SEL_MASK (0x1 << 14) 396#define IMX6SL_GPR1_FEC_CLOCK_MUX2_SEL_MASK (0x1 << 14)
397 397
398/* For imx6sx iomux gpr register field define */
399#define IMX6SX_GPR1_VDEC_SW_RST_MASK (0x1 << 20)
400#define IMX6SX_GPR1_VDEC_SW_RST_RESET (0x1 << 20)
401#define IMX6SX_GPR1_VDEC_SW_RST_RELEASE (0x0 << 20)
402#define IMX6SX_GPR1_VADC_SW_RST_MASK (0x1 << 19)
403#define IMX6SX_GPR1_VADC_SW_RST_RESET (0x1 << 19)
404#define IMX6SX_GPR1_VADC_SW_RST_RELEASE (0x0 << 19)
405#define IMX6SX_GPR1_FEC_CLOCK_MUX_SEL_MASK (0x3 << 13)
406#define IMX6SX_GPR1_FEC_CLOCK_PAD_DIR_MASK (0x3 << 17)
407#define IMX6SX_GPR1_FEC_CLOCK_MUX_SEL_EXT (0x3 << 13)
408
409#define IMX6SX_GPR4_FEC_ENET1_STOP_REQ (0x1 << 3)
410#define IMX6SX_GPR4_FEC_ENET2_STOP_REQ (0x1 << 4)
411
412#define IMX6SX_GPR5_DISP_MUX_LDB_CTRL_MASK (0x1 << 3)
413#define IMX6SX_GPR5_DISP_MUX_LDB_CTRL_LCDIF1 (0x0 << 3)
414#define IMX6SX_GPR5_DISP_MUX_LDB_CTRL_LCDIF2 (0x1 << 3)
415
416#define IMX6SX_GPR5_CSI2_MUX_CTRL_MASK (0x3 << 27)
417#define IMX6SX_GPR5_CSI2_MUX_CTRL_EXT_PIN (0x0 << 27)
418#define IMX6SX_GPR5_CSI2_MUX_CTRL_CVD (0x1 << 27)
419#define IMX6SX_GPR5_CSI2_MUX_CTRL_VDAC_TO_CSI (0x2 << 27)
420#define IMX6SX_GPR5_CSI2_MUX_CTRL_GND (0x3 << 27)
421#define IMX6SX_GPR5_VADC_TO_CSI_CAPTURE_EN_MASK (0x1 << 26)
422#define IMX6SX_GPR5_VADC_TO_CSI_CAPTURE_EN_ENABLE (0x1 << 26)
423#define IMX6SX_GPR5_VADC_TO_CSI_CAPTURE_EN_DISABLE (0x0 << 26)
424#define IMX6SX_GPR5_CSI1_MUX_CTRL_MASK (0x3 << 4)
425#define IMX6SX_GPR5_CSI1_MUX_CTRL_EXT_PIN (0x0 << 4)
426#define IMX6SX_GPR5_CSI1_MUX_CTRL_CVD (0x1 << 4)
427#define IMX6SX_GPR5_CSI1_MUX_CTRL_VDAC_TO_CSI (0x2 << 4)
428#define IMX6SX_GPR5_CSI1_MUX_CTRL_GND (0x3 << 4)
429
430#define IMX6SX_GPR5_DISP_MUX_DCIC2_LCDIF2 (0x0 << 2)
431#define IMX6SX_GPR5_DISP_MUX_DCIC2_LVDS (0x1 << 2)
432#define IMX6SX_GPR5_DISP_MUX_DCIC2_MASK (0x1 << 2)
433#define IMX6SX_GPR5_DISP_MUX_DCIC1_LCDIF1 (0x0 << 1)
434#define IMX6SX_GPR5_DISP_MUX_DCIC1_LVDS (0x1 << 1)
435#define IMX6SX_GPR5_DISP_MUX_DCIC1_MASK (0x1 << 1)
436
398#endif /* __LINUX_IMX6Q_IOMUXC_GPR_H */ 437#endif /* __LINUX_IMX6Q_IOMUXC_GPR_H */